第17章: 基于K8S构建Jenkins CICD平台
基于K8S构建Jenkins CICD平台
作者 |
刘畅 |
时间 |
2021-08-12 |
环境说明:
操作系统-CentOS7.5
主机名称 |
IP地址 |
备注 |
k8s_nfs [2核2G] |
172.16.1.60 |
nfs服务 |
k8s_harbor [2核2G] |
172.16.1.61 |
访问:http://172.16.1.61/ 用户:admin 密码:Harbor12345 项目:java(包含tomcat:v01的镜像) |
k8s_gitlab [2核4G] |
172.16.1.62 |
访问:http://172.16.1.62:9999/ 用户:root 密码:12345678 项目:dev/java |
k8s-admin [2核4G] |
172.16.1.70 |
kubernetes控制节点、nfs-utils、docker信任harbor仓库 |
k8s-node1 [4核8G] |
172.16.1.71 |
kubernetes从节点1、nfs-utils、docker信任harbor仓库 |
k8s-node2 [4核8G] |
172.16.1.72 |
kubernetes从节点2、nfs-utils、docker信任harbor仓库 |
说明: 本文主要关注k8s CICD平台的实现过程,有些步骤不会在本文中体现,需要自行搭建。
(1) k8s_nfs(172.16.1.60)节点: nfs的搭建过程不再赘述
(2) k8s_harbor(172.16.1.61)节点: harbor仓库的搭建、tomcat:v01镜像的构建及上传不再赘述。
(3) k8s_gitlab(172.16.1.62)节点: gitlib的搭建、项目创建、代码上传不再赘述。
(4) 在k8s(172.16.1.70-72)节点上安装nfs客户端nfs-utils,不然jenkins自动供给pv时无法使用nfs存储。
# yum install nfs-utils -y
(5) 在k8s(172.16.1.70-72)节点上配置docker信任harbor仓库,因为docker login到harobr仓库时默认使用的是https连接,如果不在docker中添加对harbor仓库的信任就无法登录到harbor仓库。
1) 添加信任
# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://b1cx9cn7.mirror.aliyuncs.com"],
"insecure-registries": ["172.16.1.61"]
}
# systemctl daemon-reload
# systemctl restart docker
2) 验证登录harbor仓库成功
[root@k8s-admin ~]# docker login 172.16.1.61
(6) 安装managed-nfs-storage插件(jenkins存储数据用,不赘述安装步骤)
1) 在k8s-admin节点上查看信息
[root@k8s-admin ~]# kubectl get deployment,pod,svc,sc -o wide
(7) 安装Ingress-Controller插件(web应用负载用,不赘述安装步骤)
1) 在k8s-admin节点上查看信息
[root@k8s-admin ~]# kubectl get daemonset,pod,svc -n ingress-nginx -o wide
2) 在k8s-node1节点上可以看到80、443端口
[root@k8s-node1 ~]# netstat -tunlp | egrep "443|80"
3) 在k8s-node2节点上可以看到80、443端口
[root@k8s-node2 ~]# netstat -tunlp | egrep -w "443|80"
目录
4.1 构建的jenkins agent镜像主要包括的功能(CI功能) 11
4.3 jenkins agent包启动脚本"jenkins-agent"下载 11
4.5 jenkins agent镜像构建文件dockerfile 11
4.7 将jenkins agent镜像推送到harbor仓库 12
5 Jenkins Pipeline构建流水线发布到k8s(CICD) 13
5.1 Jenkins安装Git、Pipeline、Kubernetes Continuous Deploy插件 13
5.2 jenkins保存harbor、gitlab、kubernetes访问凭据 15
5.3 使用pipeline语法工具生成pipeline脚本 18
5.6 将pipeline CICD脚本绑定到项目周期中 30
1 架构说明
1.1 持续集成(CI)持续部署/交付(CD)概述
1 持续集成(Continuous Integration)
代码合并、构建、部署、测试都在一起,不断执行这个过程,并对结果进行反馈。
2 持续部署(Continuous Deployment)
部署到测试环境、预生产环境、生产环境。
3 持续交付(Continuous Delivery)
将最终产品发布到生产环境,给用户使用。
4 K8S CICD架构图
1.2 Jenkins Master/Slave架构
说明: jenkins master接收到pipeline构建项目请求后,将任务交给jenkins slave处理,k8s会新
创建一个jenkins slave pod来接收此pipeline任务,等到pipeline任务结束后,jenkins slave pod
会被k8s回收掉。
2 在kubernetes中部署jenkins
在172.16.1.70节点上操作
# 架构图
2.1 下载Jenkins部署文件
访问gitlab地址"https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/kubernetes"
下载两个文件,jenkins.yml、service-account.yml
jenkins.yml部署文件包括StatefulSet、Service、Ingress配置
(1) StatefulSet配置
添加pv动态供给nfs存储类,storageClassName: "managed-nfs-storage"
(2) Service配置
使用satefulset只部署一个job,service使用"type: NodePort"、"nodePort: 30006"
(3) Ingress配置
使用satefulset只部署一个job,这里不需要Ingress的配置,注释掉
jenkins授权文件包括ServiceAccount、Role、RoleBinding配置
2.2 部署jenkins
1 部署
[root@k8s-admin jenkins]# kubectl apply -f .
statefulset.apps/jenkins created
service/jenkins created
serviceaccount/jenkins created
role.rbac.authorization.k8s.io/jenkins created
rolebinding.rbac.authorization.k8s.io/jenkins created
2 查看jenkins信息
[root@k8s-admin ~]# kubectl get statefulset,pod,svc -o wide
3 查看jenkins pvc,pv信息
[root@k8s-admin ~]# kubectl get pvc,pv
[root@k8s_nfs ~]# ls -l /ifs/kubernetes/
total 4
drwxrwxrwx 13 root root 4096 Aug 16 12:40 default-jenkins-home-jenkins-0-pvc-633f3c1f-1536-42d0-b725-c74cf952278c
2.3 登录jenkins
1 获取Administrator password
[root@k8s-admin ~]# kubectl logs pod/jenkins-0
2 访问http://172.16.1.70:30006/
(1) 输入管理员密码
(2) 选择自定义插件安装
(3) 不安装任何插件
(4) 设置登录用户名(admin)和密码(123456)
(5) 一路回车然后到jenkins主页面
至此,jenkins在k8s中的部署结束。
# jenkins重启方法
http://172.16.1.70:30006/restart
3 配置jenkins连接kubernetes
在jenkins UI界面中进行操作
3.1 jenkins中安装kubernetes插件
1 jenkins"kubernetes插件"官方文档地址
https://github.com/jenkinsci/kubernetes-plugin
# Jenkins在Kubernetes集群中运行动态代理的插件。
2 安装插件(系统管理->插件管理)
补充:
安装中文插件Locale plugin、Localization: Chinese (Simplified)
3 配置jenkins连接kubernetes
系统管理->系统配置->Cloud->Add a new cloue->kubernetes
(1) jenkins连接kubernetes配置
(2) jenkins slave连接jenkins master配置
(3) Pod Templates
用于定义jenkins-agent在k8s中启动pod的模板,我们不在这里进行定义,为了便于维护,
在pipeline脚本中进行定义。
4 构建jenkins agent镜像
在172.16.1.70节点上操作
4.1 构建的jenkins agent镜像主要包括的功能(CI功能)
1 代码的拉取(git)
2 单元测试(不擅长、放弃)
3 代码编译(maven)
4 构建镜像(将宿主机上的docker挂载到jenkins slave容器中)
4.2 jenkins agent包下载
http://172.16.1.70:30006/jnlpJars/agent.jar
4.3 jenkins agent包启动脚本"jenkins-agent"下载
1 已经弃用地址: https://github.com/jenkinsci/docker-jnlp-slave
2 新的下载地址: https://github.com/jenkinsci/docker-inbound-agent
4.4 下载maven,配置maven仓库
1 maven二进制包下载地址
https://dlcdn.apache.org/maven/maven-3/3.8.2/binaries/apache-maven-3.8.2-bin.tar.gz
2 settings.xml配置阿里云maven仓库
阿里云maven仓库配置官方文档: https://maven.aliyun.com/mvn/guide
4.5 jenkins agent镜像构建文件dockerfile
# cat Dockerfile
FROM centos:7
LABEL maintainer liuchang
RUN yum install -y java-1.8.0-openjdk maven curl git libtool-ltdl-devel && \
yum clean all && \
rm -rf /var/cache/yum/* && \
mkdir -p /usr/share/jenkins
COPY agent.jar /usr/share/jenkins/agent.jar
COPY jenkins-agent /usr/bin/jenkins-agent
COPY settings.xml /etc/maven/settings.xml
RUN chmod +x /usr/bin/jenkins-agent
ENTRYPOINT ["jenkins-agent"]
4.6 构建jenkins agent镜像
[root@k8s-admin jenkins-slave]# ls -l
total 1492
-rw-r--r-- 1 root root 1502119 Aug 16 16:22 agent.jar
-rw-r--r-- 1 root root 401 Aug 16 16:56 Dockerfile
-rw-r--r-- 1 root root 4514 Jul 2 01:37 jenkins-agent
-rw-r--r-- 1 root root 10950 Aug 16 16:35 settings.xml
# 镜像后面要推送到公共仓库library
[root@k8s-admin jenkins-slave]# docker build -t 172.16.1.61/library/jenkins-agent-jdk:1.8 .
……
Successfully built 852ee65ee988
Successfully tagged 172.16.1.61/library/jenkins-agent-jdk:1.8
4.7 将jenkins agent镜像推送到harbor仓库
1 登录到harbor仓库
[root@k8s-admin jenkins-slave]# docker login 172.16.1.61
# 需要输入用户名"admin"和密码"Harbor12345"
2 推送镜像
[root@k8s-admin jenkins-slave]# docker push 172.16.1.61/library/jenkins-agent-jdk:1.8
3 在镜像仓库中查看推送的"jenkins-agent-jdk:1.8"镜像
5 Jenkins Pipeline构建流水线发布到k8s(CICD)
在jenkins UI页面中进行操作
pipeline语法官方文档: https://www.jenkins.io/doc/book/pipeline/syntax/
(1) Jenkins Pipeline是一套插件,支持在Jenkins中实现集成和持续交付管道
(2) Pipeline通过特定语法对简单到复杂的传输管道进行建模
1) 声明式 #遵循与Groovy相同语法。pipeline { }
2) 脚本式 #支持Groovy大部分功能,也是非常表达和灵活的工具。
{
node("jenkins-agent"){
}
}
(3) Jenkins Pipeline的定义被写入一个文本文件,称为Jenkinsfile。
5.1 Jenkins安装Git、Pipeline、Kubernetes Continuous Deploy插件
1 安装git插件
用于从gitlab上拉取代码的插件。
2 安装pipeline插件
用于创建pipeline项目的插件。
3 安装Kubernetes Continuous Deploy插件
用于将资源配置部署到Kubernetes集群的Jenkins插件。插件官方文档: https://plugins.jenkins.io/kubernetes-cd
5.2 jenkins保存harbor、gitlab、kubernetes访问凭据
1 jenkins保存harbor访问凭据
2 jenkins保存gitlab访问凭据
3 jenkins保存kubernetes访问凭据
(1) 获取k8s认证证书
[root@k8s-admin ~]# cat /root/.kube/config
(2) 配置kubernetes凭据
5.3 使用pipeline语法工具生成pipeline脚本
1 创建java项目
2 添加字符参数(定义构建时的分支名称)
3 pipeline语法工具
4 定义pipeline变量和jenkins agent pod模板
(1) 定义pipeline变量
// 变量定义开始
// harbor仓库IP地址
def registry = "172.16.1.61"
// harbor仓库中的项目名称
def project = "java"
// 应用名称
def app_name = "java"
// harbor仓库中镜像的名称(地址),可以根据GitTag作为镜像标签,这里使用构建序列号作为镜像标签
def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"
// gitlab项目地址
def git_address = "http://172.16.1.62:9999/dev/java.git"
// K8S连接Harbor仓库认证凭据名称(k8s的secret保存)
def secret_name = "registry-pull-secret"
// harbor仓库认证凭据(jenkins保存)
def docker_registry_auth = "9cc87eac-8455-4a5f-bb4f-acf2c71f8e60"
// gitlab认证凭据(jenkins保存)
def git_auth = "fa81f5b4-1ed0-487c-9618-cfd7386bc1d6"
// k8s认证凭据(jenkins保存)
def k8s_auth = "d4cb81fb-99c2-4b7c-9453-a3812bc34ea9"
// k8s部署应用的yml文件名称(gitlab项目中保存)
def deploy_file = "deploy-java.yml"
// 变量定义结束
(2) jenkins agent pod模板
// jenkins-agent pod模板配置开始
podTemplate(label: 'jenkins-agent', cloud: 'kubernetes', containers: [
containerTemplate(
name: 'jnlp',
image: "${registry}/library/jenkins-agent-jdk:1.8"
),
],
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
hostPathVolume(mountPath: '/usr/bin/docker', hostPath: '/usr/bin/docker')
],
)
// jenkins-agent pod模板配置结束
5 第一步: 拉取代码
(1) 生成git拉取代码的pipeline脚本
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'fa81f5b4-1ed0-487c-9618-cfd7386bc1d6', url: 'http://172.16.1.62:9999/dev/java.git']]])
(2) pipeline脚本
// 第一步
stage('拉取代码'){
checkout([$class: 'GitSCM', branches: [[name: '${Branch}']], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
}
6 第二步: 代码编译
// 第二步
stage('代码编译'){
sh "mvn clean package -Dmaven.test.skip=true"
}
7 第三步: 构建镜像
(1) 将jenkins保存的harbor认证中的用户名、密码分别解析为username变量和password变量
withCredentials([usernamePassword(credentialsId: '9cc87eac-8455-4a5f-bb4f-acf2c71f8e60', passwordVariable: 'password', usernameVariable: 'username')]) {
// some block
}
(2) some block内容
1) 登录harbor仓库
2) 从harbor仓库下载基础镜像"172.16.1.61/java/tomcat:v01"
3) 将构建的war包打入基础镜像"172.16.1.61/java/tomcat:v01",生成新的镜像。
4) 上传新的镜像到harbor仓库
(3) pipeline脚本
// 第三步
stage('构建镜像'){
withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
sh """
docker login -u ${username} -p '${password}' ${registry}
echo '
FROM ${registry}/java/tomcat:v01
RUN rm -rf /usr/local/tomcat/webapps/*
COPY target/*.war /usr/local/tomcat/webapps/ROOT.war
' > Dockerfile
docker build -t ${image_name} .
docker push ${image_name}
"""
}
}
8 第四步: 部署到K8S平台
(1) 创建K8S连接Harbor仓库认证凭据
[root@k8s-admin ~]# kubectl create secret docker-registry registry-pull-secret --docker-server=172.16.1.61 --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@lc.com
[root@k8s-admin ~]# kubectl get secret | grep registry-pull-secret
registry-pull-secret kubernetes.io/dockerconfigjson 1 2m1s
(2) 在k8s中部署"deploy-java.yml"
kubernetesDeploy configs: 'deploy-java.yml', kubeConfig: [path: ''], kubeconfigId: 'd4cb81fb-99c2-4b7c-9453-a3812bc34ea9', secretName: '', ssh: [sshCredentialsId: '*', sshServer: ''], textCredentials: [certificateAuthorityData: '', clientCertificateData: '', clientKeyData: '', serverUrl: 'https://']
(3) pipeline脚本
// 第四步
stage('部署到K8S平台'){
sh """
sed -i 's#\$IMAGE_NAME#${image_name}#' ${deploy_file}
sed -i 's#\$SECRET_NAME#${secret_name}#' ${deploy_file}
"""
kubernetesDeploy configs: "${deploy_file}", kubeconfigId: "${k8s_auth}"
}
5.4 pipeline CICD脚本
Jenkinsfile文件
// 变量定义开始
// harbor仓库IP地址
def registry = "172.16.1.61"
// harbor仓库中的项目名称
def project = "java"
// 应用名称
def app_name = "java"
// harbor仓库中镜像的名称(地址),可以根据GitTag作为镜像标签,这里使用构建序列号作为镜像标签
def image_name = "${registry}/${project}/${app_name}:${BUILD_NUMBER}"
// gitlab项目地址
def git_address = "http://172.16.1.62:9999/dev/java.git"
// K8S连接Harbor仓库认证凭据名称(k8s的secret保存)
def secret_name = "registry-pull-secret"
// harbor仓库认证凭据(jenkins保存)
def docker_registry_auth = "9cc87eac-8455-4a5f-bb4f-acf2c71f8e60"
// gitlab认证凭据(jenkins保存)
def git_auth = "fa81f5b4-1ed0-487c-9618-cfd7386bc1d6"
// k8s认证凭据(jenkins保存)
def k8s_auth = "d4cb81fb-99c2-4b7c-9453-a3812bc34ea9"
// k8s部署应用的yml文件名称(gitlab项目中保存)
def deploy_file = "deploy-java.yml"
// 变量定义结束
// jenkins-agent pod模板配置开始
podTemplate(label: 'jenkins-agent', cloud: 'kubernetes', containers: [
containerTemplate(
name: 'jnlp',
image: "${registry}/library/jenkins-agent-jdk:1.8"
),
],
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
hostPathVolume(mountPath: '/usr/bin/docker', hostPath: '/usr/bin/docker')
],
)
// jenkins-agent pod模板配置结束
// 流水线步骤配置开始
{
node("jenkins-agent"){
// 第一步
stage('拉取代码'){
checkout([$class: 'GitSCM', branches: [[name: '${Branch}']], userRemoteConfigs: [[credentialsId: "${git_auth}", url: "${git_address}"]]])
}
// 第二步
stage('代码编译'){
sh "mvn clean package -Dmaven.test.skip=true"
}
// 第三步
stage('构建镜像'){
withCredentials([usernamePassword(credentialsId: "${docker_registry_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
sh """
docker login -u ${username} -p '${password}' ${registry}
echo '
FROM ${registry}/java/tomcat:v01
RUN rm -rf /usr/local/tomcat/webapps/*
COPY target/*.war /usr/local/tomcat/webapps/ROOT.war
' > Dockerfile
docker build -t ${image_name} .
docker push ${image_name}
"""
}
}
// 第四步
stage('部署到K8S平台'){
sh """
sed -i 's#\$IMAGE_NAME#${image_name}#' ${deploy_file}
sed -i 's#\$SECRET_NAME#${secret_name}#' ${deploy_file}
"""
kubernetesDeploy configs: "${deploy_file}", kubeconfigId: "${k8s_auth}"
}
}
}
// 流水线步骤配置结束
5.5 deploy-java.yml文件
# deployment config
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: java
labels:
app: java
spec:
replicas: 3
selector:
matchLabels:
project: java
app: java
template:
metadata:
labels:
project: java
app: java
spec:
imagePullSecrets:
- name: $SECRET_NAME
restartPolicy: Always
containers:
- name: java
image: $IMAGE_NAME
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: java
protocol: TCP
resources:
requests:
cpu: 0.5
memory: 1Gi
limits:
cpu: 1
memory: 2Gi
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 20
# service config
---
apiVersion: v1
kind: Service
metadata:
namespace: default
labels:
app: java
name: java
spec:
#type: NodePort
#sessionAffinity: ClientIP
#sessionAffinityConfig:
# clientIP:
# timeoutSeconds: 10800
ports:
- port: 80
protocol: TCP
targetPort: 8080
#nodePort: 30080
selector:
app: java
project: java
# ingress config
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: default
name: java
spec:
rules:
- host: java.lc.com
http:
paths:
- path: /
backend:
serviceName: java
servicePort: 80
5.6 将pipeline CICD脚本绑定到项目周期中
Jenkinsfile放到代码仓库,绑定到项目的生命周期中,比放到jenkins UI中更方便管理
1 将Jenkinsfile、deploy-java.yml文件上传到"http://172.16.1.62/dev/java.git"项目下
2 在pipeline项目中定义从gitlab中拉取Jenkinsfile
5.7 运行pipeline项目
1 选择代码分支后开始构建
2 在控制台查看构建日志输出
(1) 进入构建输出控制台
(2) 启动jenkins-agent模板
……(省略的日志内容)
# jenkins代理"jenkins-agent-cm1dh-8j2vj"动态创建成功,在k8s中查看pod
(3) 构建成功
……(省略的日志内容)
3 查看流水线构建"阶段视图"
# pipeline构建项目没有任何问题
4 在k8s中查看部署的项目
5 访问项目
(1) 在"C:\Windows\System32\drivers\etc\hosts"文件中添加dns解析指向ingress设置的域名
172.16.1.71 java.lc.com
# 172.16.1.72 java.lc.com
# 这个解析也是可以用的
# 补充: 可以在ingress中设置不同的域名解析service,达到对ingress负载均衡的目的。
(2) 访问
URL: http://java.lc.com
5.8 补充
1 以上部署的项目没有配置连接数据库,下面配置项目连接数据库
SQL文件: db/tables_ly_tomcat.sql 数据库连接:src/main/resources/application.yml
(1) 获取项目中的数据库表文件
[root@k8s-admin ~]# git clone http://172.16.1.62:9999/dev/java.git
[root@k8s-admin ~]# scp -p -P 22 /root/java/db/tables_ly_tomcat.sql root@172.16.1.60:/tmp/
(2) 创建数据库
[root@k8s_nfs ~]# docker run -d --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
[root@k8s_nfs ~]# docker cp /tmp/tables_ly_tomcat.sql mysql:/tmp/
[root@k8s_nfs ~]# docker exec -it mysql bash
root@cf2570f48bba:/# mysql -uroot -p$MYSQL_ROOT_PASSWORD
mysql> # create database test character set utf8 collate utf8_bin;
mysql> source /tmp/tables_ly_tomcat.sql;
mysql> grant all on test.* to java@'%' identified by '123456';
(3) 修改项目连接数据库配置
(4) 重新构建项目
# 此时deployment/java下的pod会被滚动更新
[root@k8s-admin ~]# kubectl get replicaset -n default -o wide
[root@k8s-admin ~]# kubectl describe deployment java
2 k8s滚动更新一次升级pod的个数策略
[root@k8s-admin ~]# kubectl get deployment/java -o yaml
……(省略的内容)
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: java
project: java
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
……(省略的内容)
6 Kubernetes项目发布方案
6.1 蓝绿发布
1 原理
(1) 蓝绿部署原理上很简单,就是通过冗余来解决问题。通常生产环境需要两组配置(蓝绿配置),
一组是active的生产环境的配置(绿配置),一组是inactive的配置(蓝配置)。用户访问的时候,
只会让用户访问active的服务器集群。在绿色环境(active)运行当前生产环境中的应用,也就
是旧版本应用version1。
(2) 当你想要升级到version2 ,在蓝色环境(inactive)中进行操作,即部署新版本应用,并进行测
试。如果测试没问题,就可以把负载均衡器/反向代理/路由指向蓝色环境了。随后需要监
测新版本应用,也就是version2是否有故障和异常。如果运行良好,就可以删除version1使
用的资源。如果运行出现了问题,可以通过负载均衡器指向快速回滚到绿色环境。
2 优点
(1) 策略简单
(2) 升级/回滚速度快
(3) 用户无感知,平滑过渡
3 缺点
(1) 需要两倍以上的服务器资源,比如日常运行时,需要10台服务器支撑业务,那么使用蓝
绿部署,你就需要购置二十台服务器。
(2) 短时间内浪费一定的资源成本
6.2 灰度发布
灰度发布也叫金丝雀发布,只升级部分服务,即让一部分用户继续用老版本,一部分用户开
始用新版本,如果用户对新版本没有什么意见,那么逐步扩大范围,把所有用户都迁移到新
版本上面来。
2 优点
(1) 保证整体系统的稳定性
(2) 用户无感知,平滑过渡
3 缺点
自动化要求高
4 kubernetes灰度发布方案
(1) kubernetes默认是滚动发布策略,不支持其它发布策略。
(2) 结合LB(负载均衡),2个deployment方案实现灰度发布。
6.3 滚动发布
1 原理
(1) 滚动发布能够解决掉蓝绿部署时对硬件要求增倍的问题。
(2) 滚动发布每次只升级一个或多个服务,升级完成后加入生产环境,不断执行这个过程,直到
集群中的全部旧版升级新版本。
(3) 所谓滚动升级,就是在升级过程中,并不一下子启动所有新版本,是先启动一台新版本,再
停止一台老版本,然后再启动一台新版本,再停止一台老版本,直到升级完成,这样的话,如果
日常需要3台服务器,那么升级过程中也就只需要4台就行了。
2 优点
用户无感知,平滑过渡
3 缺点
(1) 滚动升级有一个问题,在开始滚动升级后,流量会直接流向已经启动起来的新版本,但是这个
时候,新版本是不一定可用的,比如需要进一步的测试才能确认。那么在滚动升级期间,整个系
统就处于非常不稳定的状态,如果发现了问题,也比较难以确定是新版本还是老版本造成的问题。为了解决这个问题,我们需要为滚动升级实现健康检查能力。
(2) 部署周期长
(3) 发布策略较复杂
(4) 不易回滚
4 Kubernetes滚动发布实现原理
由调用ReplicaSet控制器实现。