【k8s-king】3-基于Kubernetes构建CI/CD持续集成

举报
yd_232190478 发表于 2023/10/23 18:28:00 2023/10/23
【摘要】 1. 概述Kubernetes构建CI/CD的流程拓扑图如下:图1涉及到的工具与技术包括:GitLab:常用的源代码管理系统。Jenkins、Jenkins Pipeline:常用的自动化构建、部署工具,Pipeline以流水线的方式将构建、部署的各个步骤组织起来。Docker、Dockerfile:容器引擎,所有应用最终都要以Docker容器运行,Dockerfile是Docker镜像定义...

1. 概述

Kubernetes构建CI/CD的流程拓扑图如下:

1.png
图1

涉及到的工具与技术包括:

  • GitLab:常用的源代码管理系统。
  • Jenkins、Jenkins Pipeline:常用的自动化构建、部署工具,Pipeline以流水线的方式将构建、部署的各个步骤组织起来。
  • Docker、Dockerfile:容器引擎,所有应用最终都要以Docker容器运行,Dockerfile是Docker镜像定义文件。
  • Kubernetes:Google开源的容器编排管理系统。

2. 部署Harbor

(1)基础准备

下载软件包到本地:

[root@master ~]# curl -O 【软件包下载地址】

解压软件包:

[root@master ~]# tar -zxf BlueOcean.tar.gz

(2)部署Harbor

安装Docker Compose:

[root@master ~]# cp BlueOcean/tools/docker-compose-Linux-x86_64 /usr/bin/docker-compose
[root@master ~]# docker-compose version
docker-compose version 1.25.0, build 0a186604
docker-py version: 4.1.0
CPython version: 3.7.4
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

安装Harbor仓库:

[root@master ~]# tar -zxf BlueOcean/harbor-offline-installer.tar.gz -C /opt/
[root@master ~]# sh /opt/harbor/install.sh

部署完成后Harbor镜像仓库默认用户为admin,密码为Harbor12345。

(3)访问Harbor

在Web端使用火狐浏览器登录Harbor(http://【此处替换为masterIP】),登录成功后如图2所示:

2.png

图2

新建springcloud项目,访问级别设置为公开,如图3所示:

3.png

图3

创建完成后如图4所示:

4.png

图4

上传镜像到Harbor(IP替换为masterIP】):

[root@master ~]# docker login -uadmin -pHarbor12345 10.26.15.244
[root@master ~]# docker load -i BlueOcean/images/maven_latest.tar
[root@master ~]# docker tag maven 10.26.15.244/library/maven
[root@master ~]# docker push 10.26.15.244/library/maven
[root@master ~]# docker load -i BlueOcean/images/java_8-jre.tar
[root@master ~]# docker load -i BlueOcean/images/jenkins_jenkins_latest.tar
[root@master ~]# docker load -i BlueOcean/images/gitlab_gitlab-ce_latest.tar

3. 部署Jenkins

(1)安装Jenkins

新建命名空间:

[root@master ~]# kubectl create ns devops

部署Jenkins需要使用到一个拥有相关权限的serviceAccount,名称为jenkins-admin,可以给jenkins-admin赋予一些必要的权限,也可以直接绑定一个cluster-admin的集群角色权限,此处选择给予集群角色权限。编写Jenkins资源清单文件:

[root@master ~]# vi jenkins-deploy.yaml 
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  labels:
    app: jenkins
spec:
  type: NodePort
  ports:
  - name: http
    port: 8080
    targetPort: 8080
    nodePort: 30880
  - name: agent
    port: 50000
    targetPort: agent
    nodePort: 30850
  selector:
    app: jenkins

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  labels:
    app: jenkins
spec:
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      serviceAccountName: jenkins-admin
      containers:
      - name: jenkins
        image: jenkins/jenkins:latest
        imagePullPolicy: IfNotPresent
        securityContext: 
          runAsUser: 0
          privileged: true
        ports:
        - name: http
          containerPort: 8080
        volumeMounts:
        - mountPath: /var/jenkins_home
          name: jenkinshome
        - mountPath: /usr/bin/docker
          name: docker
        - mountPath: /var/run/docker.sock
          name: dockersock
        - mountPath: /usr/bin/kubectl
          name: kubectl
        - mountPath: /root/.kube
          name: kubeconfig
      volumes:
      - name: jenkinshome
        hostPath:
          path: /home/jenkins_home
      - name: docker
        hostPath:
          path: /usr/bin/docker
      - name: dockersock
        hostPath:
          path: /var/run/docker.sock
      - name: kubectl
        hostPath:
          path: /usr/bin/kubectl
      - name: kubeconfig
        hostPath:
          path: /root/.kube
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: jenkinshome
  annotations:
    volume.beta.kubernetes.io/storage-class: local-path
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1024Mi
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-admin
  labels:
    name: jenkins
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jenkins-admin
  labels:
    name: jenkins
subjects:
  - kind: ServiceAccount
    name: jenkins-admin
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

这里通过NodePort的形式来暴露了Jenkins的8080端口,另外还需要暴露一个agent的端口,这个端口主要用于Jenkins的Master和Slave之间的通信。

部署Jenkins:

[root@master ~]# kubectl -n devops apply -f jenkins-deploy.yaml

查看Pod:

[root@master ~]# kubectl -n devops get pods
NAME                   READY    STATUS  RESTARTS  AGE
jenkins-cc97fd4fc-v5dh2  1/1   Running  0         21s

将离线插件包拷贝到Jenkins:

[root@master ~]# kubectl -n devops cp BlueOcean/plugins/ jenkins-cc97fd4fc-v5dh2【这里替换成上一步命令输出的Name】:/var/jenkins_home

重启Jenkins:

[root@master ~]# kubectl -n devops rollout restart deployment jenkins

(2)访问Jenkins

查看Jenkins Service端口(非必要):

[root@master ~]# kubectl -n devops get svc
NAME     TYPE      CLUSTER-IP    EXTERNAL-IP  PORT(S)                         AGE
jenkins  NodePort  192.96.215.194  <none>     8080:30880/TCP,50000:30850/TCP  47s

在Web端使用浏览器访问Jenkins(http://【此处替换为masterIP】:30880),如图5所示:

5.png
图5

获取Jenkins密码:

[root@master ~]# kubectl -n devops exec deploy/jenkins -- cat /var/jenkins_home/secrets/initialAdminPassword
a3ac7ba3812746d0bc8ed40e122ba20b【此处是命令返回的密码,每个机器都有自己的密码,不能直接复制】

输入密码后单击“继续”按钮

选择“跳过插件安装”

tempsnip.png

安装完成后进入用户创建页面,创建一个用户jenkins,密码000000,其他项随便填,如图7所示:

捕获.JPG

图7

单击“保存并完成”按钮

继续单击“保存并完成”,如图9所示:

捕获.JPG



图9

单击“开始使用Jenkins”按钮并使用新创建的用户登录Jenkins,如图10所示:
10.png
图10


4. 部署GitLab

GitLab是利用Ruby on Rails一个开源的版本管理系统,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目。与GitHub类似,GitLab能够浏览源代码,管理缺陷和注释,可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库,团队成员可以利用内置的简单聊天程序(Wall)进行交流。GitLab还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。

本项目GitLab与Harbor共用一台服务器。

(1)部署GitLab

编写GitLab资源清单文件:

[root@master ~]# vi gitlab-deploy.yaml 
apiVersion: v1
kind: Service
metadata:
  name: gitlab
spec:
  type: NodePort
  ports:
  - port: 443
    nodePort: 30443
    targetPort: 443
    name: gitlab-443
  - port: 80
    nodePort: 30888
    targetPort: 80
    name: gitlab-80
  selector:
    app: gitlab
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab
spec:
  selector:
    matchLabels:
      app: gitlab
  revisionHistoryLimit: 2
  template:
    metadata:
      labels:
        app: gitlab
    spec:
      containers:
      - image: gitlab/gitlab-ce:latest
        name: gitlab
        imagePullPolicy: IfNotPresent
        env:
        - name: GITLAB_ROOT_PASSWORD  
          value: admin@123  # 此处为root用户对应的密码
        - name: GITLAB_PORT
          value: "80"
        ports:
        - containerPort: 443
          name: gitlab-443
        - containerPort: 80
          name: gitlab-80


部署GitLab:

[root@master ~]# kubectl -n devops apply -f gitlab-deploy.yaml

查看Pod:

[root@master ~]# kubectl -n devops get pods
NAME                    READY  STATUS  RESTARTS  AGE
gitlab-645dd88cd7-6vv2q  1/1   Running  0        29s
jenkins-cc97fd4fc-kmjtl  1/1   Running  0        7m20s

查看GitLab Service:

[root@master ~]# kubectl -n devops get svc
NAME    TYPE      CLUSTER-IP    EXTERNAL-IP  PORT(S)                          AGE
gitlab  NodePort  192.104.250.77  <none>    443:30443/TCP,80:30888/TCP        57s
jenkins NodePort  192.98.107.152  <none>    8080:30880/TCP,50000:30850/TCP  7m48s

GitLab启动较慢,可以通过“kubectl logs”查看其启动状态。启动完成后,在Web端访问GitLab(http://【此处替换为masterIP】:30888),如图11所示:
11.png
图11

输入默认用户名root  密码admin@123

登录GitLab,如图12所示:
12.png
图12

(2)创建项目

单击“New project”按钮,如图13所示:
13.png
图13

单击“Create blank project”按钮创建项目springcloud,可见等级选择“Public”,如图14所示:
14.png
图14

单击“Create project”按钮,进入项目,如图15所示:
15.png
图15

push源代码到GitLab的springcloud项目:

[root@master ~]# cd BlueOcean/springcloud/
[root@master springcloud]# git config --global user.name "administrator"
[root@master springcloud]# git config --global user.email "admin@example.com"
[root@master springcloud]# git remote remove origin
[root@master springcloud]# git remote add origin http://10.26.10.143:30888/root/springcloud.git
[root@master springcloud]# git add .
[root@master springcloud]# git commit -m "initial commit"
# On branch master
nothing to commit, working directory clean
[root@master springcloud]# git push -u origin master
Username for 'http://10.26.10.143:30888': root
Password for 'http://root@10.26.15.244:30888': 
Counting objects: 3192, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (1428/1428), done.
Writing objects: 100% (3192/3192), 1.40 MiB | 1.70 MiB/s, done.
Total 3192 (delta 1233), reused 3010 (delta 1207)
remote: Resolving deltas: 100% (1233/1233), done.
remote: 
remote: To create a merge request for master, visit:
remote:   http://gitlab-6778c45f9-xx5gs/root/springcloud/-/merge_requests/new?merge_request%5Bsource_branch%5D=master
remote: 
To http://10.26.15.244:30888/root/springcloud.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

刷新网页,springcloud项目master分支中的文件已经更新了(使用火狐浏览器打开网页),如图16所示:
16.png
图16

5. 配置Jenkins连接GitLab

(1)设置Outbound requests

登录Gitlab管理员界面(http://【此处替换为masterIP】:30888/admin),如图17所示:

17.png
图17

在左侧导航栏选择“Settings→Network”,设置“Outbound requests”,勾选“Allow requests to the local network from web hooks and services”复选框,如图18所示:
18.png
图18

配置完成后保存。

(2)创建GitLab API Token

单击GitLab用户头像图标,如图19所示:
19.png
图19

在左侧导航栏选择“Preferences”,如图20所示:
20.png
图20

在左侧导航栏选择“Access Tokens”添加Token,如21图所示:
21.png
图21

单击“Create personal access token”按钮生成Token,如图22所示:
22.png
图22

记录下Token(U6p_ubRixGSdRvs6MGft),后面配置Jenkins时会用到。

(3)设置Jenkins

登录Jenkins首页,选择“系统管理→系统配置”,配置GitLab信息,取消勾选“Enable authentiviion for ‘/project’ end-point”,输入“Connection name”和“Gitlab host URL”,如图23所示:
23.png
图23

添加Credentials,单击“添加”→“Jenkins”按钮添加认证信息,将Gitlab API Token填入,如图24所示:
24.png
图24

选择新添加的证书,然后单击“Test Connection”按钮,如图25所示:
25.png
图25

返回结果为Success,说明Jenkins可以正常连接GitLab。

6. Jenkinsfile

(1)新建任务

登录Jenkins首页,新建任务springcloud,任务类型选择“流水线”,如图26所示:
26.png
图26

单击“确定”按钮,配置构建触发器,如图27所示:
27.png
图27

记录下GitLab webhook URL的地址(http://10.26.15.244:30880/project/springcloud),后期配置webhook需要使用。

配置流水线,在定义域中选择“Pipeline script from SCM”,此选项指示Jenkins从源代码管理(SCM)仓库获取流水线。在SCM域中选择“Git”,然后输入“Repository URL”,如图28所示:
28.png
图28

在Credentials中选择“添加”,凭据类型选择“Username with password”,然后输入对应信息,如图29所示:

29.png

图29

单击“保存”按钮,回到流水线中,在Credentials域选择刚才添加的凭证,如图30所示:

30.png
图30

保存任务。

(2)编写流水线

Pipeline有两种创建方法——可以直接在Jenkins的Web UI界面中输入脚本;也可以通过创建一个Jenkinsfile脚本文件放入项目源码库中。

一般推荐在Jenkins中直接从源代码控制(SCMD)中直接载入Jenkinsfile Pipeline这种方法。

登录GitLab进入springcloud项目,选择新建文件,如图31所示:

31.png
图31

将流水线脚本输入到Jenkinsfile中,如图32所示:

32.png
图32

Pipeline包括声明式语法和脚本式语法。声明式和脚本式的流水线从根本上是不同的。声明式是Jenkins流水线更友好的特性。脚本式的流水线语法,提供更丰富的语法特性。声明式流水线使编写和读取流水线代码更容易设计。

此处选择声明式Pipeline,完整的流水线脚本如下:

pipeline{
    agent none
    stages{
        stage('mvn-build'){
            agent {
                docker {
                    image '10.26.15.244/library/maven'
                    args '-v /root/.m2:/root/.m2'
                }
            }
            steps{
                sh 'cp -rfv /opt/repository /root/.m2/ && ls -l /root/.m2/repository'
                sh 'mvn package -DskipTests'
                archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true 
            }
        }
        stage('image-build'){
            agent any
            steps{
                sh 'cd gateway && docker build -t 10.26.15.244/springcloud/gateway -f Dockerfile .'
                sh 'cd config && docker build -t 10.26.15.244/springcloud/config -f Dockerfile .'
                sh 'docker login 10.26.15.244 -u=admin -p=Harbor12345'
                sh 'docker push 10.26.15.244/springcloud/gateway'
                sh 'docker push 10.26.15.244/springcloud/config'
            }
        }
        stage('cloud-deploy'){
            agent any
            steps{
                sh 'sed -i "s/sqshq\\/piggymetrics-gateway/10.26.15.244\\/springcloud\\/gateway/g" yaml/deployment/gateway-deployment.yaml'
                sh 'sed -i "s/sqshq\\/piggymetrics-config/10.26.15.244\\/springcloud\\/config/g" yaml/deployment/config-deployment.yaml'
                sh 'kubectl create ns springcloud'
                sh 'kubectl apply -f yaml/deployment/gateway-deployment.yaml'
                sh 'kubectl apply -f yaml/deployment/config-deployment.yaml'
                sh 'kubectl apply -f yaml/svc/gateway-svc.yaml'
                sh 'kubectl apply -f yaml/svc/config-svc.yaml'
            }
        }
    }
}

(3)开启Jenkins匿名访问

登录Jenkins首页,选择“系统管理→全局安全配置”,授权策略选择“任何用户可以做任何事(没有任何限制)”,如图33所示。
33.png
图33

7. 构建CI/CD

(1)触发构建

在GitLab的项目中,通常会使用Webhook的各种事件来触发对应的构建,通常配置好后会向设定好的URL发送post请求。

登录GitLab,进入springcloud项目,现在左侧导航栏“Settings→Webhooks”,将前面记录的GitLab webhook URL地址填入URL处,禁用SSL认证,如图34所示。
34.png
图34

单击“Add webhook”按钮添加webhook,完成后如图35所示:
35.png
图35

单击“Test→Push events”按钮进行测试,如图36所示:
36.png
图36

结果返回HTTP 200则表明Webhook配置成功。

(2)Jenkins查看

登录Jenkins,可以看到springcloud项目已经开始构建,如图37所示:
37.png
图37

选择左侧导航栏“打开Blue Ocean”,如图38所示:
38.png
图38

Blue Ocean是pipeline的可视化UI,同时兼容经典的自由模式的job。Jenkins Pipeline从头开始设计,但仍与自由式作业兼容,Blue Ocean减少了经典模式下的混乱并为团队中的每个成员增加了清晰度。

单击项目名称springcloud,如图39所示:
39.png
图39

单击正在构建的pipeline可以查看阶段视图,如图40所示:
40.png
图40

单击任意“>”符号可查看每个Step的构建详情,如图41所示:
41.png
图41

若构建成功,Blue Ocean界面会变为绿色。构建完成后如图42所示:
42.png
图42

退出阶段试图界面,如图43所示:
43.png
图43

返回Jenkins首页,如图44所示:
44.png
图44

(3)Harbor查看

进入Harbor仓库springcloud项目查看镜像列表,可以看到已自动上传了一个gateway镜像,如图45所示:
45.png
图45

通过端口30010访问服务,如图46所示:
46.png
图46

至此,完整的CI/CD流程就完成了。

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。