一、概述

Git:一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。

Jenkins:一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作。

Maven:项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件。

Harbor:构建企业级私有Docker镜像的仓库的开源解决方案。

Kubernetes:一个开源的,用于管理云平台中多个主机上的容器化的应用。


二、Java镜像构建

启动脚本run.sh:

#!/bin/sh

java ${JVM_OPTS} ${JAVA_OPTS} -jar *.jar ${CLI_OPTS} 2>&1 | tee -a ${OUTPUT}

构建脚本Dockerfile:

# 基础镜像
FROM hub.jhmy.com/base/centos # 维护者
MAINTAINER leozhang # 切换目录
WORKDIR /root # 添加环境变量
ENV JDK_VERSION=jdk1.8.0_191
ENV JAVA_HOME=/usr/local/$JDK_VERSION
ENV PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/lib/ ENV JAVA_OPTS='' CLI_OPTS='' OUTPUT='logs/output.log'
ENV JVM_OPTS='-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2' # 设置时区语言
ENV TZ='Asia/Shanghai'
ENV LANG='C.UTF-8' LANGUAGE='C.UTF-8' LC_ALL='C.UTF-8' # 添加程序包
ADD $JDK_VERSION.tar.gz /usr/local/
COPY run.sh . # 执行命令
RUN chmod a+x run.sh && rm -rf `ls | grep -v "^run.sh$"` && mkdir -p /root/logs # 构建镜像示例
# docker build -t hub.jhmy.com/base/java:1.8 .
# 启动容器示例
# docker run -dit --name=java hub.jhmy.com/base/java:1.8

环境变量说明:

JDK_VERSION:用于指定jdk包版本(需要提前下载好jdk软件包,且保证解压后名称一致)
JVM_OPTS:用于指定jvm运行参数
JAVA_OPTS:用于指定java自定义参数
CLI_OPTS:用于指定其他命令行参数
OUTPUT:用于指定服务运行日志保存路径

注意:
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2
用于jvm自动识别容器内存限制以及自动分配内存大小(jdk10版本之后则不需要设置)

更多详情>>>容器中的JVM资源该如何被安全的限制?


三、Java项目镜像构建

增加项目依赖脚本addPlugins.py:

# -*- coding:utf-8 -*-
# ****************************
# Author :leozhang
# Date :2020/7/16
# File :addPlugins.py
# Description :增加POM文件依赖
# ****************************
import os
pomplug=os.environ["PLUGINS"] newpom = ""
with open("pom.xml", "r+") as fp:
for line in fp.readlines():
if(line.find("<build>") != -1):
line += "\n" + pomplug + "\n"
newpom += line with open("pom.xml", "r+") as f:
f.write(newpom)print(newpom)

构建脚本Dockerfile:

# 基础镜像
FROM hub.jhmy.com/base/java:1.8 # 维护者
MAINTAINER leozhang # 工作目录
WORKDIR /root # 复制文件到镜像
COPY *.jar .
COPY lib/ lib/ # 查看当前目录
RUN ls -l . # 容器启动时运行命令
CMD ["./run.sh"] # 构建镜像示例
# docker build -t hub.jhmy.com/test/appservice .
# 启动容器示例
# docker run -dit --name=appservice hub.jhmy.com/test/appservice

镜像构建脚本buildImage.sh:

#!/bin/sh
# creator: leozhang
# up-date: 2020/03/21
# description: buildImage.sh # 公共参数
env=$1
name=$2
tag=$3
file=$4 # 设置仓库地址和账户
harbor=hub.jhmy.com
username=jenkins
password=$(echo Q2hpc2NkY0AxMjMK | base64 -d) # 修改镜像名称为小写
image=${harbor}/${env}/$(echo ${name} | tr '[A-Z]' '[a-z]') # 默认名Dockerfile
if [ ! "${file}" ] ;then
file=Dockerfile
fi # 构建镜像
echo "************* build image ***************"
docker build -t ${image}:${tag} -f ${file} . echo "************* push image ***************"
# 登录仓库
docker login -u ${username} -p ${password} https://${harbor}
# 上传镜像
docker push ${image}:${tag} # 如果非latest标签,则更新latest标签镜像
if [ "${tag}" != "latest" ]; then
docker tag ${image}:${tag} ${image}:latest
docker push ${image}:latest
fi
# 登出仓库
docker logout https://${harbor}

四、Java项目容器化部署

Deployment文件:

apiVersion: apps/v1     # 资源版本
kind: Deployment #资源类型
metadata: #资源元数据:名称、命名空间等
name: appservice
namespace: default spec:
replicas: 3 #副本数
selector: #选择器
matchLabels:
app: appservice template: #Pod模板
metadata: #Pod元数据:标签、注解等
labels:
app: appservice
annotations:
version: "" spec: #Pod配置:名称、镜像、拉取策略、端口等
containers:
- name: appservice
image: hub.jhmy.com/test/appservice:latest
imagePullPolicy: Always env: #环境变量
- name: JAVA_OPTS
value: "-Dprops=/root/appservice.properties -Dlogpath=/root/logs"
ports:
- name: dubbo
containerPort: 20114 resources: #资源限制:cpu、mem
limits:
memory: 2Gi
cpu: 1 livenessProbe: #就绪检测&生存检测:初始时间、超时、检测方式等
initialDelaySeconds: 60
timeoutSeconds: 10
tcpSocket:
port: 20114
readinessProbe:
initialDelaySeconds: 20
timeoutSeconds: 10
tcpSocket:
port: 20114 volumeMounts: #存储挂载
- name: config
mountPath: /root/appservice.properties
subPath: appservice.properties
- name: log
mountPath: /root/logs volumes: #存储声明:服务配置、持久化存储请求、本地存储
- name: config
configMap:
name: appservice
- name: log
hostPath:
path: /home/ymt/logs/appservice
type: DirectoryOrCreate #affinity: #节点亲和性
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: app
# operator: In
# values:
# - appservice

ConfigMap文件:

apiVersion: v1
kind: ConfigMap
metadata:
name: appservice
namespace: default
data:
appservice.properties: |-
server.port=20114
   ......
......
......

Service文件:

apiVersion: v1
kind: Service
metadata:
name: apprestserver
namespace: default
spec:
selector:
app: apprestserver
ports:
- name: rest
port: 20114

五、Jenkins持续部署

Pipeline任务脚本:

def NOW = new Date().format("yyyyMMddHHmmss")
def SERVER = env.JOB_BASE_NAME.toLowerCase()
pipeline {
agent any
// parameters {
// string(name: 'TAG', defaultValue: 'latest', description: '镜像标签' )
// string(name: 'BRANCH', defaultValue: 'test_0629', description: '分支名称' )
// string(name: 'URL', defaultValue: 'http://10.88.88.226:8090/jhmy/source/wx_v1/appdataservicetemp.git', description: '项目地址' )
// string(name: 'PLUGINS', defaultValue: '<plugins> <plugin> ...... </plugin> </plugins> ', description: '相关依赖' )
// environment {
ENV="test"
MVN="/application/mvnBranch/bin/mvn"
SCRIPT="${JENKINS_HOME}/workspace/Docker/updateConfigs/script"
} stages {
stage('Git Clone') {
steps {
git branch: '${BRANCH}', credentialsId: 'yf3b_gitlab', url: '${URL}'
}
} stage('Clean Package') {
steps {
sh "python ${SCRIPT}/addPlugins.py"
sh "${MVN} clean package -Dmaven.test.skip=true"
}
post { success { archiveArtifacts "target/*.jar" } }
} stage('Build Image') {
steps {
dir('target') {
sh "cp ${SCRIPT}/Dockerfile-jar Dockerfile"
sh "sh ${SCRIPT}/buildImage.sh ${ENV} ${SERVER} ${TAG}"
}
}
} stage('Rolling Update') {
steps {
sh "kubectl config use-context k8s-ymt"
sh """kubectl patch deployment ${SERVER} --patch '{"spec":{"template":{"metadata":{"annotations":{"version":"${NOW}"}}}}}'"""
sh "sleep 30 && kubectl get pod -o wide | grep ${SERVER}"
}
} stage('Clean up') {
steps { deleteDir() }
}
}
}

作者:Leozhanggg

出处:https://www.cnblogs.com/leozhanggg/p/12069994.html

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

Kubernetes实战总结 - DevOps实现的更多相关文章

  1. Kubernetes实战 - 从零开始搭建微服务 - 1.5 提高可用性-发布多节点的Node/Express网络应用程序

    1.5 提高可用性-发布多节点的Node/Express网络应用程序 Kubernetes实战 - 从零开始搭建微服务 前言 在上一篇文章中,已经学习了如何简单地开发一个单层网络应用.[Kuberne ...

  2. 2020 最新 Kubernetes实战指南

    1.Kubernetes带来的变革   对于开发人员 由于公司业务多,开发环境.测试环境.预生产环境和生产环境都是隔离的,而且除了生产环境,为了节省成本,其他环境可能是没有日志收集的,在没有用k8s的 ...

  3. 新书推荐《再也不踩坑的Kubernetes实战指南》

      <再也不踩坑的Kubernetes实战指南>终于出版啦.目前可以在京东.天猫购买,京东自营和当当网预计一个星期左右上架. 本书贴合生产环境经验,解决在初次使用或者是构建集群中的痛点,帮 ...

  4. kubernetes实战(二十六):kubeadm 安装 高可用 k8s v1.16.x dashboard 2.x

    1.基本配置 基本配置.内核升级.基本服务安装参考https://www.cnblogs.com/dukuan/p/10278637.html,或者参考<再也不踩坑的Kubernetes实战指南 ...

  5. kubernetes实战(二十七):CentOS 8 二进制 高可用 安装 k8s 1.16.x

    1. 基本说明 本文章将演示CentOS 8二进制方式安装高可用k8s 1.16.x,相对于其他版本,二进制安装方式并无太大区别.CentOS 8相对于CentOS 7操作更加方便,比如一些服务的关闭 ...

  6. kubernetes实战(二十八):Kubernetes一键式资源管理平台Ratel安装及使用

    1. Ratel是什么? Ratel是一个Kubernetes资源平台,基于管理Kubernetes的资源开发,可以管理Kubernetes的Deployment.DaemonSet.Stateful ...

  7. kubernetes实战(二十九):Kubernetes RBAC实现不同用户在不同Namespace的不同权限

    1.基本说明 在生产环境使用k8s以后,大部分应用都实现了高可用,不仅降低了维护成本,也简化了很多应用的部署成本,但是同时也带来了诸多问题.比如开发可能需要查看自己的应用状态.连接信息.日志.执行命令 ...

  8. kubernetes实战(三十):CentOS 8 二进制 高可用 安装 k8s 1.17.x

    1. 基本说明 本文章将演示CentOS 8二进制方式安装高可用k8s 1.17.x,相对于其他版本,二进制安装方式并无太大区别. 2. 基本环境配置 主机信息 192.168.1.19 k8s-ma ...

  9. Kubernetes实战 - 从零开始搭建微服务 1 - 使用kind构建一个单层架构Node/Express网络应用程序

    使用kind构建一个单层架构Node/Express网络应用程序 Kubernetes实战-从零开始搭建微服务 1 前言 准备写一个Kubernetes实战系列教程,毕竟cnblogs作为国内最早的技 ...

随机推荐

  1. pikachu靶场-CSRF

    xss和csrf区别: CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限,然后实施破坏. PS: 由于之前将php5升级到php7,导致靶场环境出现以下问题 ...

  2. Spring系列.Bean简介

    Bean属性配置 Spring在读取配置文件中bean的metadata后会构造一个个BeanDefination对象.后面Spring会根据这些BeanDefinition创建对象.在配置一个bea ...

  3. python编码--解码

    在py3中只有两种数据类型:str  bytes str:  存unicode(万国码)编码--全球通用的 bytes:存的是16进制的 1.str s='ehllo 丽庆'  --->它存在内 ...

  4. 逻辑式编程语言极简实现(使用C#) - 3. 运行原理

    本系列前面的文章: 逻辑式编程语言极简实现(使用C#) - 1. 逻辑式编程语言介绍 逻辑式编程语言极简实现(使用C#) - 2. 一道逻辑题:谁是凶手 第二天,好为人师的老明继续开讲他的私人课堂. ...

  5. 化繁就简,如何利用Spring AOP快速实现系统日志

    1.引言 有关Spring AOP的概念就不细讲了,网上这样的文章一大堆,要讲我也不会比别人讲得更好,所以就不啰嗦了. 为什么要用Spring AOP呢?少写代码.专注自身业务逻辑实现(关注本身的业务 ...

  6. Vue中$nextTick的理解

    Vue中$nextTick的理解 Vue中$nextTick方法将回调延迟到下次DOM更新循环之后执行,也就是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后立即使用这个方法,能够获取更新后的 ...

  7. HDU-1051/POJ-1065 Wooden sticks 木棍子(动态规划 LIS 线型动归)

    嘤嘤嘤,实习半年多的小蒟蒻的第一篇博客(题解) 英文的: There is a pile of n wooden sticks. The length and weight of each stick ...

  8. web 部署专题(二):gunicore 并发部署(用gunicorn+gevent启动Flask项目)

    转自:https://blog.csdn.net/dutsoft/article/details/51452598 Flask,webpy,Django都带着 WSGI server,当然性能都不好, ...

  9. 06 flask源码剖析之路由加载

    06 Flask源码之:路由加载 目录 06 Flask源码之:路由加载 1.示例代码 2.路由加载源码分析 1.示例代码 from flask import Flask app = Flask(__ ...

  10. Vmware虚拟机下不能访问网络的解决办法之一

    Vmware虚拟机下不能访问网络的解决办法之一 1.这个是默认的网络设置 2.如果不能访问网络,看下VMware相关的服务有没有打开,win+R 3.找到VMware的相关选项,全部启用(当然网络可能 ...