Loading

第17章: 基于K8S构建Jenkins CICD平台

 

 

 

 

 

 

基于K8S构建Jenkins CICD平台

 

作者

刘畅

时间

2021-08-12

 

 

环境说明:

操作系统-CentOS7.5

主机名称

IP地址

备注

k8s_nfs

[22G]

172.16.1.60

nfs服务

k8s_harbor

[22G]

172.16.1.61

访问:http://172.16.1.61/ 用户:admin 密码:Harbor12345 项目:java(包含tomcat:v01的镜像)

k8s_gitlab

[24G]

172.16.1.62

访问:http://172.16.1.62:9999/ 用户:root 密码:12345678 项目:dev/java

k8s-admin

[24G]

172.16.1.70

kubernetes控制节点、nfs-utilsdocker信任harbor仓库

k8s-node1

[48G]

172.16.1.71

kubernetes从节点1nfs-utilsdocker信任harbor仓库

k8s-node2

[48G]

172.16.1.72

kubernetes从节点2nfs-utilsdocker信任harbor仓库

 

 

说明: 本文主要关注k8s CICD平台的实现过程,有些步骤不会在本文中体现,需要自行搭建。

(1) k8s_nfs(172.16.1.60)节点: nfs的搭建过程不再赘述

wps1 

 

(2) k8s_harbor(172.16.1.61)节点: harbor仓库的搭建、tomcat:v01镜像的构建及上传不再赘述。

wps2 

 

(3) k8s_gitlab(172.16.1.62)节点: gitlib的搭建、项目创建、代码上传不再赘述。

wps3 

 

(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 loginharobr仓库时默认使用的是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

wps4 

 

(6) 安装managed-nfs-storage插件(jenkins存储数据用,不赘述安装步骤)

1) k8s-admin节点上查看信息

[root@k8s-admin ~]# kubectl get deployment,pod,svc,sc -o wide

wps5 

 

(7) 安装Ingress-Controller插件(web应用负载用,不赘述安装步骤)

1) k8s-admin节点上查看信息

[root@k8s-admin ~]# kubectl get daemonset,pod,svc -n ingress-nginx -o wide

wps6 

2) k8s-node1节点上可以看到80443端口

[root@k8s-node1 ~]# netstat -tunlp | egrep "443|80"

wps7 

3) k8s-node2节点上可以看到80443端口

[root@k8s-node2 ~]# netstat -tunlp | egrep -w "443|80"

wps8 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

目录

1 架构说明 1

1.1 持续集成(CI)持续部署/交付(CD)概述 1

1.2 Jenkins Master/Slave架构 2

2 kubernetes中部署jenkins 3

2.1 下载Jenkins部署文件 3

2.2 部署jenkins 4

2.3 登录jenkins 5

3 配置jenkins连接kubernetes 8

3.1 jenkins中安装kubernetes插件 8

4 构建jenkins agent镜像 11

4.1 构建的jenkins agent镜像主要包括的功能(CI功能) 11

4.2 jenkins agent包下载 11

4.3 jenkins agent包启动脚本"jenkins-agent"下载 11

4.4 下载maven,配置maven仓库 11

4.5 jenkins agent镜像构建文件dockerfile 11

4.6 构建jenkins agent镜像 12

4.7 jenkins agent镜像推送到harbor仓库 12

5 Jenkins Pipeline构建流水线发布到k8s(CICD) 13

5.1 Jenkins安装GitPipelineKubernetes Continuous Deploy插件 13

5.2 jenkins保存harborgitlabkubernetes访问凭据 15

5.3 使用pipeline语法工具生成pipeline脚本 18

5.4 pipeline CICD脚本 25

5.5 deploy-java.yml文件 27

5.6 pipeline CICD脚本绑定到项目周期中 30

5.7 运行pipeline项目 32

5.8 补充 36

6 Kubernetes项目发布方案 39

6.1 蓝绿发布 39

6.2 灰度发布 40

6.3 滚动发布 41

 


1 架构说明

1.1 持续集成(CI)持续部署/交付(CD)概述

1 持续集成(Continuous Integration)

代码合并、构建、部署、测试都在一起,不断执行这个过程,并对结果进行反馈。

2 持续部署(Continuous Deployment)

部署到测试环境、预生产环境、生产环境。

3 持续交付(Continuous Delivery)

将最终产品发布到生产环境,给用户使用。

4 K8S CICD架构图

wps9 

wps10 

 

1.2 Jenkins Master/Slave架构

wps11 

wps12 

说明: jenkins master接收到pipeline构建项目请求后,将任务交给jenkins slave处理,k8s会新

创建一个jenkins slave pod来接收此pipeline任务,等到pipeline任务结束后,jenkins slave pod

会被k8s回收掉。

2 kubernetes中部署jenkins

172.16.1.70节点上操作

# 架构图

wps13 

2.1 下载Jenkins部署文件

访问gitlab地址"https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/kubernetes"

下载两个文件,jenkins.ymlservice-account.yml

 

1 jenkins.yml

jenkins.yml部署文件包括StatefulSetServiceIngress配置

(1) StatefulSet配置

添加pv动态供给nfs存储类,storageClassName: "managed-nfs-storage"

wps14 

 

(2) Service配置

使用satefulset只部署一个jobservice使用"type: NodePort""nodePort: 30006"

wps15 

 

(3) Ingress配置

使用satefulset只部署一个job,这里不需要Ingress的配置,注释掉

wps16 

 

2 service-account.yml

jenkins授权文件包括ServiceAccountRoleRoleBinding配置

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

wps17 

 

3 查看jenkins pvcpv信息

[root@k8s-admin ~]# kubectl get pvc,pv

wps18 

[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

wps19 

 

2 访问http://172.16.1.70:30006/

(1) 输入管理员密码

wps20 

 

(2) 选择自定义插件安装

wps21 

 

 

 

 

 

 

 

 

(3) 不安装任何插件

wps22 

 

(4) 设置登录用户名(admin)和密码(123456)

wps23 

 

 

 

 

 

 

 

(5) 一路回车然后到jenkins主页面

wps24 

至此,jenkinsk8s中的部署结束。

 

# 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

# JenkinsKubernetes集群中运行动态代理的插件。

 

2 安装插件(系统管理->插件管理)

wps25 

补充:

安装中文插件Locale pluginLocalization: Chinese (Simplified)

wps26 

 

3 配置jenkins连接kubernetes

系统管理->系统配置->Cloud->Add a new cloue->kubernetes

(1) jenkins连接kubernetes配置

wps27 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(2) jenkins slave连接jenkins master配置

wps28 

 

(3) Pod Templates

用于定义jenkins-agentk8s中启动pod的模板,我们不在这里进行定义,为了便于维护,

pipeline脚本中进行定义。

4 构建jenkins agent镜像

172.16.1.70节点上操作

4.1 构建的jenkins agent镜像主要包括的功能(CI功能)

wps29 

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"镜像

wps30 

5 Jenkins Pipeline构建流水线发布到k8s(CICD)

jenkins UI页面中进行操作

wps31 

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安装GitPipelineKubernetes Continuous Deploy插件

1 安装git插件

wps32 

用于从gitlab上拉取代码的插件。

2 安装pipeline插件

wps33 

用于创建pipeline项目的插件。

 

3 安装Kubernetes Continuous Deploy插件

wps34 

用于将资源配置部署到Kubernetes集群的Jenkins插件。插件官方文档: https://plugins.jenkins.io/kubernetes-cd

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.2 jenkins保存harborgitlabkubernetes访问凭据

1 jenkins保存harbor访问凭据

wps35 

 

wps36 

 

 

 

 

 

 

 

 

 

2 jenkins保存gitlab访问凭据

wps37 

 

wps38 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3 jenkins保存kubernetes访问凭据

(1) 获取k8s认证证书

[root@k8s-admin ~]# cat /root/.kube/config

 

(2) 配置kubernetes凭据

wps39 

 

wps40 

 

 

 

 

 

 

 

 

 

 

 

5.3 使用pipeline语法工具生成pipeline脚本

1 创建java项目

wps41 

 

2 添加字符参数(定义构建时的分支名称)

wps42 

 

 

3 pipeline语法工具

wps43 

 

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仓库认证凭据名称(k8ssecret保存)

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']]])

 

wps44 

 

(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

}

 

wps45 

 

(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://']

wps46 

 

(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仓库认证凭据名称(k8ssecret保存)

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 Jenkinsfiledeploy-java.yml文件上传到"http://172.16.1.62/dev/java.git"项目下

wps47 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2 pipeline项目中定义从gitlab中拉取Jenkinsfile

wps48 

5.7 运行pipeline项目

wps49 

 

1 选择代码分支后开始构建

wps50 

 

 

 

 

 

2 在控制台查看构建日志输出

(1) 进入构建输出控制台

wps51 

 

(2) 启动jenkins-agent模板

wps52 

……(省略的日志内容)

wps53 

# jenkins代理"jenkins-agent-cm1dh-8j2vj"动态创建成功,在k8s中查看pod

wps54 

 

 

 

 

 

 

 

 

 

 

(3) 构建成功

……(省略的日志内容)

wps55 

 

3 查看流水线构建"阶段视图"

wps56 

# pipeline构建项目没有任何问题

 

 

 

 

4 k8s中查看部署的项目

wps57 

 

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

wps58 

 

 

 

 

 

 

 

 

 

 

 

 

 

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) 修改项目连接数据库配置

wps59 

 

 

 

 

 

 

 

 

 

 

 

(4) 重新构建项目

wps60 

# 此时deployment/java下的pod会被滚动更新

 

[root@k8s-admin ~]# kubectl get replicaset -n default -o wide

wps61 

 

 

 

 

 

 

 

 

 

 

 

 

 

[root@k8s-admin ~]# kubectl describe deployment java

wps62 

 

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

wps63 

 

(2) 当你想要升级到version2 ,在蓝色环境(inactive)中进行操作,即部署新版本应用,并进行测

试。如果测试没问题,就可以把负载均衡器/反向代理/路由指向蓝色环境了。随后需要监

测新版本应用,也就是version2是否有故障和异常。如果运行良好,就可以删除version1使

用的资源。如果运行出现了问题,可以通过负载均衡器指向快速回滚到绿色环境。

wps64 

 

2 优点

(1) 策略简单

(2) 升级/回滚速度快

(3) 用户无感知,平滑过渡

 

3 缺点

(1) 需要两倍以上的服务器资源,比如日常运行时,需要10台服务器支撑业务,那么使用蓝

绿部署,你就需要购置二十台服务器。

(2) 短时间内浪费一定的资源成本

6.2 灰度发布

1 原理

灰度发布也叫金丝雀发布,只升级部分服务,即让一部分用户继续用老版本,一部分用户开

始用新版本,如果用户对新版本没有什么意见,那么逐步扩大范围,把所有用户都迁移到新

版本上面来。

wps65 

wps66 

 

2 优点

(1) 保证整体系统的稳定性

(2) 用户无感知,平滑过渡

 

3 缺点

自动化要求高

 

4 kubernetes灰度发布方案

(1) kubernetes默认是滚动发布策略,不支持其它发布策略。

(2) 结合LB(负载均衡)2deployment方案实现灰度发布。

wps67 

6.3 滚动发布

1 原理

(1) 滚动发布能够解决掉蓝绿部署时对硬件要求增倍的问题。

(2) 滚动发布每次只升级一个或多个服务,升级完成后加入生产环境,不断执行这个过程,直到

集群中的全部旧版升级新版本。

(3) 所谓滚动升级,就是在升级过程中,并不一下子启动所有新版本,是先启动一台新版本,再

停止一台老版本,然后再启动一台新版本,再停止一台老版本,直到升级完成,这样的话,如果

日常需要3台服务器,那么升级过程中也就只需要4台就行了。

wps68 

 

2 优点

用户无感知,平滑过渡

 

3 缺点

(1) 滚动升级有一个问题,在开始滚动升级后,流量会直接流向已经启动起来的新版本,但是这个

时候,新版本是不一定可用的,比如需要进一步的测试才能确认。那么在滚动升级期间,整个系

统就处于非常不稳定的状态,如果发现了问题,也比较难以确定是新版本还是老版本造成的问题。为了解决这个问题,我们需要为滚动升级实现健康检查能力。

(2) 部署周期长

(3) 发布策略较复杂

(4) 不易回滚

 

4 Kubernetes滚动发布实现原理

wps69 

由调用ReplicaSet控制器实现。

posted @ 2021-08-19 09:49  云起时。  阅读(853)  评论(0编辑  收藏  举报