DevOps實戰:使用GitLab+Jenkins+Kubernetes(k8s)建立CI/CD解決方案

2023-07-26 09:01:00

一.系統環境

本文主要基於Kubernetes1.21.9和Linux作業系統CentOS7.4。

伺服器版本 docker軟體版本 Kubernetes(k8s)叢集版本 CPU架構
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 x86_64

CI/CD解決方案架構圖:

CI/CD解決方案架構圖描述:

程式設計師寫好程式碼之後,向gitlab程式碼倉庫提交程式碼,gitlab檢測到變化之後,觸發CI/CD伺服器Jenkins,CI/CD伺服器

Jenkins構建映象,映象構建好之後推播到registry映象倉庫,最後使用新的映象在Kubernetes(k8s)環境部署。

CI/CD解決方案架構:k8scloude1作為Kubernetes(k8s)的master節點,k8scloude2,k8scloude3作為Kubernetes(k8s)的worker節點,由於機器有限,etcd1作為CI/CD伺服器,映象倉庫,程式碼倉庫。

伺服器 作業系統版本 CPU架構 程序 功能描述
etcd1/192.168.110.133 CentOS Linux release 7.4.1708 (Core) x86_64 docker,jenkins CI/CD伺服器
etcd1/192.168.110.133 CentOS Linux release 7.4.1708 (Core) x86_64 registry 映象倉庫
etcd1/192.168.110.133 CentOS Linux release 7.4.1708 (Core) x86_64 gitlab,Git 程式碼倉庫
k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master節點
k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker節點
k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker節點

二.前言

DevOps是一種將開發(Development)和運維(Operations)相結合的軟體開發方法論。它通過自動化和持續交付的方式,將軟體開發、測試和部署等環節緊密整合,以提高效率和產品質量。在本篇部落格中,我們將介紹如何使用GitLab、Jenkins和Kubernetes(k8s)來構建一個完整的CI/CD解決方案。

使用GitLab、Jenkins和Kubernetes(k8s)來構建CI/CD解決方案的前提是已經有一套可以正常執行的Kubernetes叢集,關於Kubernetes(k8s)叢集的安裝部署,可以檢視部落格《Centos7 安裝部署Kubernetes(k8s)叢集》https://www.cnblogs.com/renshengdezheli/p/16686769.html。

三.DevOps簡介

DevOps通過打破開發和運維之間的壁壘,促進了更緊密的合作和快速響應變化的能力。它強調團隊間的共同作業、自動化和持續改進。通過引入DevOps實踐,組織可以更快地交付軟體,並確保高質量的釋出。

四.CI/CD簡介

CI/CD代表持續整合(Continuous Integration)和持續交付(Continuous Delivery)。持續整合是指團隊成員將其工作頻繁地整合到共用儲存庫中,並進行自動化構建和測試,以減少整合問題。持續交付是指將應用程式更頻繁地交付給使用者,以便快速獲得反饋並提供新功能。本次使用的CI/CD工具為Jenkins。

五.安裝並設定docker引數

etcd1機器作為整合伺服器,需要下載大量映象,所以首先需要安裝docker,docker版本標識:社群版 docker-ce 和企業版 docker-ee。

[root@etcd1 ~]# yum -y install docker-ce

為了讓映象下載速度變快,需要設定映象加速器,關於docker更多詳細內容,請檢視部落格《一文搞懂docker容器基礎:docker映象管理,docker容器管理》。

[root@etcd1 ~]# vim /etc/docker/daemon.json

[root@etcd1 ~]# cat /etc/docker/daemon.json 
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"] 
}

重啟docker使設定生效。

[root@etcd1 ~]# systemctl restart docker

[root@etcd1 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since 六 2022-03-26 17:53:49 CST; 40s ago
     Docs: https://docs.docker.com
 Main PID: 1495 (dockerd)
   Memory: 32.9M
   CGroup: /system.slice/docker.service
           └─1495 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

設定docker開機自啟動

[root@etcd1 ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

修改docker啟動指令碼,--insecure-registry=192.168.110.133:5000是映象倉庫的地址, 我們使用registry搭建映象倉庫,新增了--insecure-registry=192.168.110.133:5000引數之後,就可以使用http的方式拉取映象,不然預設使用https的方式拉取映象。

jenkins需要做的工作:構建,編譯,推播,這些操作都需要藉助docker去完成,但是jenkins自身是沒有docker命令的,要讓jenkins連線到物理機的docker上,需要新增引數:-H tcp://0.0.0.0:2376。

[root@etcd1 ~]# vim /usr/lib/systemd/system/docker.service

[root@etcd1 ~]# cat /usr/lib/systemd/system/docker.service
.....
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.110.133:5000 -H tcp://0.0.0.0:2376  -H fd:// --containerd=/run/containerd/containerd.sock
.....

重新載入組態檔,重啟docker。

[root@etcd1 ~]# systemctl daemon-reload ;systemctl restart docker

檢視狀態可以發現:8083 /usr/bin/dockerd --insecure-registry=192.168.110.133:5000 -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock,修改引數成功。

[root@etcd1 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 二 2022-03-29 11:37:51 CST; 20s ago
     Docs: https://docs.docker.com
 Main PID: 8083 (dockerd)
   Memory: 36.8M
   CGroup: /system.slice/docker.service
           └─8083 /usr/bin/dockerd --insecure-registry=192.168.110.133:5000 -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock

我們把映象推播到registry映象倉庫之後,k8s叢集的worker節點會向registry映象倉庫拉取映象,預設使用https的方式從映象倉庫拉取映象,需要在k8s的worker節點修改docker啟動引數,新增--insecure-registry=192.168.110.133:5000,讓其使用http的方式從registry映象倉庫拉取映象。

[root@k8scloude2 ~]# vim /usr/lib/systemd/system/docker.service

[root@k8scloude2 ~]# cat /usr/lib/systemd/system/docker.service
......
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.110.133:5000  -H fd:// --containerd=/run/containerd/containerd.sock
......

[root@k8scloude2 ~]# grep ExecStart /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.110.133:5000  -H fd:// --containerd=/run/containerd/containerd.sock

重新載入組態檔,重啟docker。

[root@k8scloude2 ~]# systemctl daemon-reload ;systemctl restart docker

[root@k8scloude2 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 二 2022-03-29 11:51:36 CST; 4s ago
     Docs: https://docs.docker.com
 Main PID: 57510 (dockerd)
   Memory: 63.6M
   CGroup: /system.slice/docker.service
           ├─57510 /usr/bin/dockerd --insecure-registry=192.168.110.133:5000 -H fd:// --containerd=/run/containerd/containerd.sock
           ├─57759 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 80 -container-ip 172.17.0.2 -container-port 80
           └─57767 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 80 -container-ip 172.17.0.2 -container-port 80

k8scloude3節點也需要修改docker啟動引數,新增--insecure-registry=192.168.110.133:5000,讓其使用http的方式從registry映象倉庫拉取映象。

[root@k8scloude3 ~]# vim /usr/lib/systemd/system/docker.service

[root@k8scloude3 ~]# grep ExecStart /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd --insecure-registry=192.168.110.133:5000  -H fd:// --containerd=/run/containerd/containerd.sock

重新載入組態檔,重啟docker。

[root@k8scloude3 ~]# systemctl daemon-reload ;systemctl restart docker

[root@k8scloude3 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 二 2022-03-29 15:55:13 CST; 5s ago
     Docs: https://docs.docker.com
 Main PID: 9099 (dockerd)
   Memory: 43.1M
   CGroup: /system.slice/docker.service
           └─9099 /usr/bin/dockerd --insecure-registry=192.168.110.133:5000 -H fd:// --containerd=/run/containerd/containerd.sock

現在k8s叢集的所有worker節點都加上了--insecure-registry=192.168.110.133:5000引數。

在etcd1機器拉取nginx映象,之後做web容器的時候會用到。

[root@etcd1 ~]# docker pull nginx
Using default tag: latest
......
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

[root@etcd1 ~]# docker images | grep nginx
nginx                            latest                605c77e624dd   3 months ago   141MB

六.使用registry搭建映象倉庫

本次使用registry搭建映象倉庫,也可以使用harbor搭建映象倉庫,功能更豐富,關於harbor的詳細內容,請檢視部落格《搭建docker映象倉庫(二):使用harbor搭建本地映象倉庫》。

拉取registry映象

[root@etcd1 ~]# docker pull hub.c.163.com/library/registry:latest      

[root@etcd1 ~]# docker images | grep registry
hub.c.163.com/library/registry   latest                751f286bc25e   4 years ago    33.2MB

注意:registry的資料卷為:VOLUME [/var/lib/registry],不能是其他的。

建立registry容器,registry映象生成容器作為私有倉庫,-p 5000:5000做埠對映,物理機埠5000:容器埠5000,
-v /myregistry:/var/lib/registry資料卷掛載,物理機目錄/myregistry:容器目錄/var/lib/registry。

[root@etcd1 ~]# docker run -d --name registry -p 5000:5000 --restart=always -v /myregistry:/var/lib/registry hub.c.163.com/library/registry
3aa799d1974611fc403ce38aa19a156cb165a82573b84b16fde665d9e3b62eb0

現在registry映象倉庫就搭建好了。

[root@etcd1 ~]# docker ps | grep registry
3aa799d19746   hub.c.163.com/library/registry   "/entrypoint.sh /etc…"   8 seconds ago   Up 7 seconds           0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                                                                         registry

此時映象倉庫下還沒有任何檔案

[root@etcd1 ~]# ls /myregistry/

七.安裝部署gitlab程式碼倉庫

7.1 建立gitlab容器

在etcd1機器下載gitlab中文版映象

[root@etcd1 ~]# docker pull beginor/gitlab-ce     

[root@etcd1 ~]# docker images | grep gitlab
beginor/gitlab-ce                latest                5595d4ff803e   3 years ago    1.5GB

建立gitlab組態檔目錄,紀錄檔目錄,程式碼目錄

[root@etcd1 ~]# mkdir -p /data/gitlab/etc /data/gitlab/log /data/gitlab/data   

給gitlab組態檔目錄,紀錄檔目錄,程式碼目錄授予777許可權

[root@etcd1 ~]# chmod 777 /data/gitlab/etc /data/gitlab/log /data/gitlab/data   

建立gitlab容器,使用--privileged=true引數,使container內的root擁有真正的root許可權。否則,container內的root只是外部的一個普通使用者許可權。--privileged=true啟動的容器,可以看到很多host上的裝置,並且可以執行mount。甚至允許你在docker容器中啟動docker容器。

-v指定資料卷,gitlab容器的組態檔,紀錄檔檔案,資料檔案也都儲存到了物理機上,我們修改對應資料卷的內容,gitlab容器的相關內容也隨之改變。-p指定埠對映。

[root@etcd1 ~]# docker run -dit --name=gitlab --restart=always -p 8443:443 -p 80:80 -p 222:22 -v /data/gitlab/etc:/etc/gitlab -v /data/gitlab/log:/var/log/gitlab -v /data/gitlab/data:/var/opt/gitlab --privileged=true beginor/gitlab-ce      

檢視gitlab容器

[root@etcd1 ~]# docker ps | grep gitlab
d23f2df47e42   beginor/gitlab-ce                "/assets/wrapper"        22 hours ago    Up 6 hours (healthy)   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:222->22/tcp, :::222->22/tcp, 0.0.0.0:8443->443/tcp, :::8443->443/tcp   gitlab

現在gitlab組態檔目錄,紀錄檔目錄,程式碼目錄都有相關檔案了。

[root@etcd1 ~]# ls /data/gitlab/etc/
gitlab.rb  gitlab-secrets.json  ssh_host_ecdsa_key  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key  ssh_host_ed25519_key.pub  ssh_host_rsa_key  ssh_host_rsa_key.pub  trusted-certs

[root@etcd1 ~]# ls /data/gitlab/log/
gitaly  gitlab-monitor  gitlab-rails  gitlab-shell  gitlab-workhorse  logrotate  nginx  node-exporter  postgres-exporter  postgresql  prometheus  reconfigure  redis  redis-exporter  sidekiq  sshd  unicorn

[root@etcd1 ~]# ls /data/gitlab/data/
backups       gitaly    gitlab-ci       gitlab-rails  gitlab-workhorse  nginx          postgres-exporter  prometheus              redis
bootstrapped  git-data  gitlab-monitor  gitlab-shell  logrotate         node-exporter  postgresql         public_attributes.json  trusted-certs-directory-hash

7.2 修改gitlab容器組態檔

注意先讓gitlab容器執行一段時間,讓其資料進行初始化,然後再停止gitlab容器,修改組態檔。

[root@etcd1 ~]# docker stop gitlab   

下面開始修改gitlab的組態檔。

修改/data/gitlab/etc/gitlab.rb,external_url指的是gitlab所在的機器IP,gitlab_ssh_host指定gitlab所在的機器IP,gitlab_shell_ssh_port指定ssh埠,因為我們把gitlab容器的22埠對映為了222,所以gitlab_shell_ssh_port為222。

[root@etcd1 ~]# vim /data/gitlab/etc/gitlab.rb   

[root@etcd1 ~]# cat /data/gitlab/etc/gitlab.rb | egrep -v "^#" | egrep "external_url|gitlab_ssh_host|ssh_port"
external_url 'http://192.168.110.133'
gitlab_rails['gitlab_ssh_host'] = '192.168.110.133'
gitlab_rails['gitlab_shell_ssh_port'] = 222

修改/data/gitlab/data/gitlab-rails/etc/gitlab.yml,host指定gitlab所在的機器IP,埠為80,不使用https。

[root@etcd1 ~]# vim /data/gitlab/data/gitlab-rails/etc/gitlab.yml   

[root@etcd1 ~]# grep -A6 192.168.110.133 /data/gitlab/data/gitlab-rails/etc/gitlab.yml
    host: 192.168.110.133
    port: 80
    https: false

啟動gitlab容器。

[root@etcd1 ~]# docker start gitlab   

檢視gitlab容器。

[root@etcd1 ~]# docker ps | grep gitlab
d23f2df47e42   beginor/gitlab-ce                "/assets/wrapper"        22 hours ago     Up 6 hours (healthy)   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:222->22/tcp, :::222->22/tcp, 0.0.0.0:8443->443/tcp, :::8443->443/tcp   gitlab

7.3 存取gitlab web介面

瀏覽器存取gitlab所在機器的IP地址和80埠,即可存取gitlab web介面 。

存取gitlab介面http://192.168.110.133/,gitlab登入介面如下。

點選修改密碼,注意密碼如果太簡單會報錯。

設定賬號密碼:賬號為root,密碼為:mycoderepo123。

輸入賬號root,密碼:mycoderepo123登入gitlab介面。

登入gitlab之後,首頁如下。

可以看到gitlab版本為:GitLab 社群版 10.7.5。

7.4 建立專案

點選建立一個專案。

設定專案名稱為:my-project,專案描述(可選),可見等級設定為公開,點選建立專案。

選擇SSH的方式拉取和推播程式碼,點選新建SSH公鑰,否則無法通過SSH拉取和推播程式碼。

需要貼上SSH的公鑰,現在去程式碼上傳的機器上拿金鑰。

現在回到etcd1機器,建立SSH金鑰,複製公鑰資訊到Gitlab的金鑰裡。

現在還沒有SSH金鑰。

[root@etcd1 ~]# ls ~/.ssh/
 known_hosts

生成金鑰,-N ""表示提供一個新密語,密語為空。

[root@etcd1 ~]# ssh-keygen -N ""   

檢視生成的金鑰,id_rsa是私鑰 ,id_rsa.pub是公鑰。

[root@etcd1 ~]# ls ~/.ssh/
id_rsa  id_rsa.pub  known_hosts

檢視公鑰,並複製公鑰資訊到Gitlab的金鑰裡。

[root@etcd1 ~]# cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDGO+hg4j5pkEN/VrD/OOHFkEWvpyAYSmLnCL35MHnqSSshJA29ZPmBNByIMSTnhHU9j2oQ6RSh8YIgULnf8T7aQ+/ByTojhenbXjI7l47NkmWDVLE89rHY+fxWIy21sXrQLUNivbxfV+drQ47Kts4+PkeXxPpfFCjqPlk5VMQdSQGe9IvFUFKb46ctyzClUlXp1dGQbLHZaeZ/KzpCavRxvXRUECO8dCItoI1jFtLFy/+1uyXDLNe/38nwJuwa6J/KWAYB7gRwrRITvdOn+4L+iJFK5MPI6evdN6ZzGUTGkr3BgufrDpV3Tk0CMdAfNDvOfu2sg7mey4OiT+zvLn9 root@etcd1

複製公鑰資訊到Gitlab的金鑰裡,點選新增金鑰。

新增金鑰之後如下。

7.5 建立Git版本庫

點選專案--->您的專案。

找到我們的專案,點選進入。

根據命令列指令建立Git版本庫。

安裝Git

[root@etcd1 ~]# yum -y install git    

--global表示Git 全域性設定,設定使用者名稱和郵箱。

[root@etcd1 ~]# git config --global user.name "Administrator"   

[root@etcd1 ~]# git config --global user.email "[email protected]"    

把我們gitlab上的專案克隆下來。

[root@etcd1 ~]# git clone ssh://[email protected]:222/root/my-project.git     

[root@etcd1 ~]# ls my-project/
index.html

修改index.html首頁檔案。

[root@etcd1 ~]# cd my-project/

[root@etcd1 my-project]# vim index.html

[root@etcd1 my-project]# cat index.html
hello gitlab

在Git 1.0 中,git push 預設會把你原生的所有分支都上傳到遠端, push.default 的值是‘matching’,如果想始終保持以往的習慣就執行

git config --global push.default matching。

到了git 2.0,git push預設是把當前分支上傳到遠端而不是所有本地分支,push.default 的值是‘simple’,這樣比較保守也推薦這樣,git config --global push.default simple。

[root@etcd1 my-project]# git config --global push.default matching   

[root@etcd1 my-project]# git config --global push.default simple   

git add 命令可將該檔案新增到暫存區。

[root@etcd1 my-project]# git add index.html  

新增註釋

[root@etcd1 my-project]# git commit -m "add index.html"   

git push命令用於將本地分支的更新,推播到遠端主機。

[root@etcd1 my-project]# git push   

去gitlab介面上看檔案是否推播過去,可以看到index.html被推播到gitlab程式碼倉庫了。

自此gitlab程式碼倉庫設定完成,但是還缺觸發jenkins,等安裝好jenkins再設定。

八.安裝部署CI/CD伺服器jenkins

8.1 建立jenkins容器

拉取網易的jenkins映象。

[root@etcd1 my-project]# docker pull hub.c.163.com/library/jenkins:latest   

下載基於centos的jenkins映象。

[root@etcd1 my-project]# docker pull jenkins/jenkins:2.332.1-lts-centos7   

[root@etcd1 my-project]# docker images | grep jenkins
jenkins/jenkins                  2.332.1-lts-centos7   0dfc0feff986   2 weeks ago    503MB
hub.c.163.com/library/jenkins    latest                88d9d8a30b47   4 years ago    810MB

建立jenkins資料卷所需要的目錄,並把所有者和所屬組改為1000。

[root@etcd1 my-project]# mkdir /jenkins ; chown 1000:1000 /jenkins   

[root@etcd1 my-project]# ll -d /jenkins/
drwxr-xr-x 12 tom tom 4096 3月  30 15:59 /jenkins/

/jenkins的屬主UID要改成1000的原因為:容器裡是以jenkins使用者的身份去讀寫資料,而在容器裡 jenkins 的 uid 是 1000,可以看下此映象的 Dockerfile 內容。

通過jenkins映象的Dockerfile可以發現,使用者UID和使用者組GID為1000,HTTP埠為8080,代理埠為50000。

建立jenkins容器。

  • -dit: 在後臺以互動模式執行容器,並分配一個偽終端。
  • -p 8080:8080: 將主機的8080埠對映到容器的8080埠,允許通過主機的8080埠存取Jenkins的Web介面。
  • -p 50000:50000: 將主機的50000埠對映到容器的50000埠,用於Jenkins的代理節點通訊。
  • --name jenkins: 指定容器的名稱為"jenkins"。
  • --privileged=true: 啟用特權模式,允許容器內部的程序擁有更高階別的許可權。
  • --restart=always: 定義容器在退出或重啟之後應該自動重新啟動。
  • -v /jenkins:/var/jenkins_home: 將主機上的"/jenkins"目錄掛載到容器內部的"/var/jenkins_home"目錄,用於持久化Jenkins資料。
[root@etcd1 my-project]# docker run -dit -p 8080:8080 -p 50000:50000 --name jenkins --privileged=true --restart=always -v /jenkins:/var/jenkins_home jenkins/jenkins:2.332.1-lts-centos7   

8.2 修改Jenkins組態檔

讓jenkins容器執行一段時間之後,再存取jenkins web介面,瀏覽器存取:192.168.110.133:8080,即可存取jenkins的web介面,Jenkins登入介面如下:

下面需要修改jenkins容器的組態檔,因為jenkins容器使用了資料卷:-v /jenkins:/var/jenkins_home,我們修改物理機/jenkins下面的檔案,對應容器裡的檔案也就相應改變。

先停止容器,再修改組態檔。

[root@etcd1 my-project]# docker stop jenkins   

[root@etcd1 my-project]# docker ps -a | grep jenkins
99b1d931eaf4   jenkins/jenkins:2.332.1-lts-centos7   "/sbin/tini -- /usr/…"   5 hours ago      Exited (143) About an hour ago                                                                                                                     jenkins

檢視/jenkins/hudson.model.UpdateCenter.xml內容。

[root@etcd1 my-project]# ls /jenkins/
config.xml               hudson.model.UpdateCenter.xml  jenkins.telemetry.Correlator.xml  nodeMonitors.xml  plugins     secret.key.not-so-secret  updates      users
copy_reference_file.log  identity.key.enc               jobs                              nodes             secret.key  secrets                   userContent  war

[root@etcd1 my-project]# cat /jenkins/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>https://updates.jenkins.io/update-center.json</url>
  </site>
</sites>

https://updates.jenkins.io/update-center.json這個地址是用來更新jenkins和安裝jenkins外掛的網址,把該地址換為清華大學的地址,提高安裝jenkins外掛的下載速度。

[root@etcd1 my-project]# vim /jenkins/hudson.model.UpdateCenter.xml

[root@etcd1 my-project]# cat /jenkins/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?>
<sites>
  <site>
    <id>default</id>
    <url>http://mirrors.tuna.tsinghua.edu.cn/jenkins</url>
  </site>
</sites>

/jenkins/updates/default.json檔案的connectionCheckUrl修改為:"connectionCheckUrl":"http://www.baidu.com/" 。

[root@etcd1 my-project]# ll /jenkins/updates/default.json -h
-rw-r--r-- 1 tom tom 2.5M 3月  30 16:04 /jenkins/updates/default.json

[root@etcd1 my-project]# vim /jenkins/updates/default.json

啟動Jenkins。

[root@etcd1 my-project]# docker start jenkins 
jenkins

[root@etcd1 my-project]# docker ps | grep jenkins
99b1d931eaf4   jenkins/jenkins:2.332.1-lts-centos7   "/sbin/tini -- /usr/…"   5 hours ago      Up 9 seconds           0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp                          jenkins

8.3 檢視jenkins管理員密碼並登入

重新整理jenkins web頁面,登入Jenkins需要管理員密碼。

jenkins管理員密碼在/jenkins/secrets/initialAdminPassword檔案,檢視密碼。

[root@etcd1 my-project]# cat /jenkins/secrets/initialAdminPassword 
542e9af5e55f4543ae4fefee8bdd2d3c

把密碼複製到jenkins頁面。

8.4 安裝Jenkins外掛

點選安裝推薦的外掛。

現在外掛就開始安裝了。

部分外掛安裝失敗之後點選重試。

Jenkins外掛安裝完成之後,會出現建立管理員使用者介面。

建立管理員使用者:使用者名稱:jenkinsadmin 密碼:devopsjenkins123 全名:jenkinsadmin 電子郵箱地址:mailto:[email protected]。點選儲存並完成

範例設定:Jenkins URL 用於給各種Jenkins資源提供絕對路徑連結的根地址,Jenkins URL:http://192.168.110.133:8080/,點選儲存並完成。

此時jenkins就安裝完成了,點選開始使用。

jenkins主介面如下:

有些外掛沒安裝成功,點選糾正。

點選立即獲取。

報錯了,但是不影響,我們繼續。

jenkins需要連線我們物理機的docker,然後編譯構建映象,把映象推播到registry倉庫,所以jenkins需要安裝docker外掛,在jenkins主頁依次點選manage jenkins-->Manage Plugins-->可選外掛,搜尋docker,選擇 docker 和 docker-build-step安裝。

選中安裝完成後重啟jenkins(空閒時)。

在Jenkins web頁面重啟jenkins太慢了,我們手動重啟jenkins。

[root@etcd1 my-project]# docker restart jenkins 
jenkins

[root@etcd1 my-project]# docker ps | grep jenkins
99b1d931eaf4   jenkins/jenkins:2.332.1-lts-centos7   "/sbin/tini -- /usr/…"   7 hours ago    Up 12 seconds          0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp                          jenkins

重新整理jenkins頁面重新登入,使用者名稱:jenkinsadmin 密碼:devopsjenkins123。

在jenkins主頁依次點選系統管理-->外掛管理-->已安裝,搜尋docker,發現 docker 外掛和 docker-build-step外掛已經安裝好了。

8.5 設定Jenkins連線docker

在首頁依次點選系統管理-->節點管理-->configure Clouds,Add a new cloud選擇Docker。

點選Docker Cloud details。

Docker Host URI輸入連線docker的地址,此處為:tcp://192.168.110.133:2376,再點選test connection,如果出現docker的版本號,則jenkins連線docker成功,最後儲存即可。

在首頁點選系統管理-->系統設定,找到 Docker Builder,在docker URL裡輸入連線的docker地址:tcp://192.168.110.133:2376,點選 test connection,如果出現Connected to tcp://192.168.110.133:2376,這樣說明jenkins和docker就關聯起來了,最後點選儲存。

此時jenkins就能連線docker了。

8.6 安全設定

gitlab要觸發jenkins操作,需要做相關安全設定,首頁依次點選系統管理-->全域性安全設定-->授權策略,勾選"匿名使用者具有可讀許可權"。

注意下面的跨站請求偽造保護(CSFR)必須要關閉,但是在Jenkins版本自2.2xx版本之後,在 web 介面裡已經沒法關閉了,所以在當前 web 介面裡暫且不要管它,點選下面的儲存。

gitlab 要觸發 jenkins 的話,就必須要關閉跨站請求偽造保護,既然web 介面裡已經沒法關閉了,那麼我們在命令列裡操作。

檢視Jenkins容器,可以發現jenkins容器執行著/usr/local/bin/jenkins.sh指令碼。

[root@etcd1 ~]# docker ps -a | grep  jenkins 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
tom                 1590                1535                0                   3月30                pts/0               00:00:00            /sbin/tini -- /usr/local/bin/jenkins.sh
tom                 1682                1590                2                   3月30                pts/0               00:04:51            java -Duser.home=/var/jenkins_home -Djenkins.model.Jenkins.slaveAgentPort=50000 -jar /usr/share/jenkins/jenkins.war

進入jenkins容器。

[root@etcd1 ~]# docker exec -u root -it jenkins bash 

#/usr/local/bin/jenkins.sh指令碼中的exec java -Duser.home引數如下,我們需要修改exec java -Duser.home的值
[root@99b1d931eaf4 /]# egrep "exec java -Duser.home=" /usr/local/bin/jenkins.sh
  exec java -Duser.home="$JENKINS_HOME" ${FUTURE_OPTS} "${java_opts_array[@]}" -jar ${JENKINS_WAR} "${jenkins_opts_array[@]}" "$@"

[root@99b1d931eaf4 /]# vi /usr/local/bin/jenkins.sh

#修改後,exec java -Duser.home的值如下:
[root@99b1d931eaf4 /]# egrep "exec java -Duser.home=" /usr/local/bin/jenkins.sh
  exec java -Duser.home="$JENKINS_HOME" -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true  ${FUTURE_OPTS} "${java_opts_array[@]}" -jar ${JENKINS_WAR} "${jenkins_opts_array[@]}" "$@"

#退出jenkins容器
[root@99b1d931eaf4 /]# exit
exit

重啟Jenkins,使組態檔生效。

[root@etcd1 ~]# docker restart jenkins 
jenkins

[root@etcd1 ~]# docker ps | grep jenkins
99b1d931eaf4   jenkins/jenkins:2.332.1-lts-centos7   "/sbin/tini -- /usr/…"   13 hours ago   Up 10 seconds           0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp                          jenkins

重啟好jenkins之後,登入jenkins web介面。

首頁依次點選系統管理-->全域性安全設定,此時跨站請求偽造保護已經被關閉了。

8.7 設定Jenkins連線Kubernetes(k8s)叢集

jenkins需要把映象部署到Kubernetes(k8s)叢集,所以jenkins需要kubectl使用者端工具和kubeconfig檔案連線k8s環境,現在回到Kubernetes(k8s)叢集。

檢視kubectl的版本號。

[root@k8scloude1 ~]# rpm -qa | grep kubectl
kubectl-1.21.0-0.x86_64

直接拷貝一個kubectl檔案到Jenkins所在伺服器。

[root@k8scloude1 ~]# scp /usr/bin/kubectl 192.168.110.133:~/
[email protected]'s password: 
kubectl                                                           

或者直接下載一個kubectl檔案也可以。

[root@etcd1 ~]# wget https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kubectl
--2022-03-31 01:13:11--  https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/linux/amd64/kubectl
正在解析主機 storage.googleapis.com (storage.googleapis.com)... 142.251.43.16, 172.217.163.48, 142.251.42.240, ...
正在連線 storage.googleapis.com (storage.googleapis.com)|142.251.43.16|:443... 已連線。
已發出 HTTP 請求,正在等待迴應... 200 OK
長度:46436352 (44M) [application/octet-stream]
正在儲存至: 「kubectl.1」

100%[========================================================================================================================================================================>] 46,436,352  6.54MB/s 用時 6.6s   

2022-03-31 01:13:19 (6.71 MB/s) - 已儲存 「kubectl.1」 [46436352/46436352])

[root@etcd1 ~]# ll -h kubectl
-rwxr-xr-x 1 root root 45M 3月  31 01:10 kubectl

現在Jenkins正在執行。

[root@etcd1 ~]# docker ps | grep jenkins
99b1d931eaf4   jenkins/jenkins:2.332.1-lts-centos7   "/sbin/tini -- /usr/…"   14 hours ago   Up About an hour       0.0.0.0:8080->8080/tcp, :::8080->8080/tcp, 0.0.0.0:50000->50000/tcp, :::50000->50000/tcp                          jenkins

把kubectl檔案拷貝到jenkins容器。

[root@etcd1 ~]# docker cp kubectl jenkins:/

把kubeconfig檔案kctest拷貝到jenkins容器,kctest是我們自定義的kubeconfig檔案,關於自定義kubeconfig檔案的詳細內容,請檢視部落格《Kubernetes(k8s)存取控制:身份認證》。

[root@etcd1 ~]# docker cp kctest jenkins:/

以root身份進入jenkins容器。

[root@etcd1 ~]# docker exec -u root -it jenkins bash 

[root@99b1d931eaf4 /]# ls /
anaconda-post.log  bin  dev  etc  home  kctest  kubectl  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

#給kubectl和kctest授權
[root@99b1d931eaf4 /]# chmod +x kubectl 

[root@99b1d931eaf4 /]# chmod 644 kctest 

[root@99b1d931eaf4 /]# ll -h kctest kubectl 
-rw-r--r-- 1 root root 5.4K Mar 18 08:24 kctest
-rwxr-xr-x 1 root root  45M Mar 30 17:17 kubectl

#連線k8s叢集,檢視k8s叢集節點狀態,可以看到Jenkins成功連線k8s叢集,但是使用者test沒有檢視節點狀態的許可權。
[root@99b1d931eaf4 /]# ./kubectl --kubeconfig=kctest get nodes
Error from server (Forbidden): nodes is forbidden: User "test" cannot list resource "nodes" in API group "" at the cluster scope

#退出容器
[root@99b1d931eaf4 /]# exit
exit

對test使用者授予cluster-admin許可權,cluster-admin是叢集管理員許可權,許可權很大,關於授權的詳細內容,請檢視部落格《Kubernetes(k8s)存取控制:許可權管理之RBAC鑑權》。

[root@k8scloude1 ~]# kubectl create clusterrolebinding test --clusterrole=cluster-admin --user=test
clusterrolebinding.rbac.authorization.k8s.io/test created

再次以root身份進入jenkins容器。

[root@etcd1 ~]# docker exec -u root -it jenkins bash 

#給使用者test授權之後,jenkins能連線k8s叢集,並能檢視k8s叢集節點狀態。
[root@99b1d931eaf4 /]# ./kubectl --kubeconfig=kctest get node
NAME         STATUS   ROLES                  AGE   VERSION
k8scloude1   Ready    control-plane,master   80d   v1.21.0
k8scloude2   Ready    <none>                 80d   v1.21.0
k8scloude3   Ready    <none>                 80d   v1.21.0

#檢視k8s叢集safe名稱空間的pod
[root@99b1d931eaf4 /]# ./kubectl --kubeconfig=kctest get pod -n safe
No resources found in safe namespace.

#退出容器
[root@99b1d931eaf4 /]# exit
exit

自此,jenkins就可以遠端連線k8s環境了。

九.建立jenkins專案

首頁點選新建任務,任務名稱可以自定義,選擇構建一個自由風格的軟體專案,點選確定。

設定構建觸發器,這樣gitlab就可以觸發jenkins了,在構建觸發器那裡選中觸發遠端構建(例如,使用指令碼),身份驗證令牌自定義。

注意:連結 JENKINS_URL/job/devopsProject/build?token= TOKEN_NAME,這個連結用於 gitlab 在觸發 jenkins 時用到的連結,我們這裡,TOKEN_NAME 的值是connect123,JENKINS_URL 是 192.168.110.133:8080,所以整個連結為:
http://192.168.110.133:8080/job/devopsProject/build?token=connect123。

當gitlab程式碼倉庫內容變動之後,會去觸發jenkins,所以需要增加構建步驟。

點選構建-->增加構建步驟,選擇執行shell。

程式設計師提交了程式碼到gitlab之後,jenkins需要重新拉取新程式碼,這時要先刪除家目錄下的舊程式碼,再拉取新程式碼,不然會報錯。

對於jenkins容器來說,家目錄就是/var/jenkins_home,進入Jenkins容器。

[root@etcd1 ~]# docker exec -it jenkins bash

#cd ~表示進入家目錄
bash-4.2$ cd ~

#可以看到家目錄為/var/jenkins_home
bash-4.2$ pwd
/var/jenkins_home

#退出容器
bash-4.2$ exit
exit

在構建-->增加構建步驟-->執行shell裡輸入如下語句,意思為進入jenkins容器家目錄,刪除舊程式碼,拉取新程式碼。

cd ~
rm -rf my-project
git clone http://192.168.110.133/root/my-project.git

在構建-->增加構建步驟-->執行shell裡輸入如下語句。

Jenkins把新程式碼拉取下來之後,需要進行編譯,接下來繼續增加構建步驟,這次型別選擇Build/Publish Docker Image。

Build/Publish Docker Image-->Directory for Dockerfile裡填/var/jenkins_home/my-project/,jenkins拉取程式碼是放在家目錄下,Dockerfile也在家目錄/var/jenkins_home/my-project/下。

Cloud選擇docker,使用docker編譯Dockerfile。

Image填:192.168.110.133:5000/devopsproject/nginx:\({BUILD_NUMBER},表示把編譯好的映象推播到registry倉庫,因為程式碼會不斷更新,Dockerfile會被編譯好多次,所以使用\){BUILD_NUMBER}變數,讓映象不重複,本次程式碼變動主要是nginx,所以寫為nginx:${BUILD_NUMBER}。

選中Push image,把映象推播到映象倉庫。

把新程式碼拉取下來,Dockerfile被編譯好並推播到映象倉庫之後,需要把新映象部署到k8s環境,接下來繼續增加構建步驟,這次型別選擇執行shell。

執行shell裡輸入如下語句,解釋如下:

#export KUBECONFIG=/kctest定義KUBECONFIG,不然每次執行kubectl命令都要加上kubectl --kubeconfig=kctest
export KUBECONFIG=/kctest

#在devops名稱空間裡,替換deployment/nginx的映象為192.168.110.133:5000/devopsproject/nginx:${BUILD_NUMBER}
/kubectl set image deployment/nginx nginx="192.168.110.133:5000/devopsproject/nginx:${BUILD_NUMBER}" -n devops

最後點選儲存。

十.建立deployment

現在回到Kubernetes(k8s)叢集,因為jenkins把新映象部署到devops名稱空間下,所以建立一個名稱空間devops。

[root@k8scloude1 ~]# kubectl create namespace devops
namespace/devops created

切換名稱空間到devops。

[root@k8scloude1 ~]# kubens devops
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "devops".

現在沒有deploy。

[root@k8scloude1 ~]# kubectl get deploy
No resources found in devops namespace.

使用Nginx映象建立一個deploy,組態檔如下:

功能為:建立一個名為"nginx"的Deployment物件,Pod副本數為1。關於deployment的詳細內容,請檢視部落格《Kubernetes(k8s)控制器(一):deployment》。

[root@k8scloude1 ~]# vim nginx.yaml 

[root@k8scloude1 ~]# cat nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  #replicas: 1 指定需要執行的Pod副本數量為1個。
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      #當需要關閉容器時,立即殺死容器而不等待預設的30秒優雅停機時長。
      terminationGracePeriodSeconds: 0
      containers:
      #image: nginx: 指定要使用的映象為"nginx"。
      - image: nginx
        name: nginx
        #imagePullPolicy: IfNotPresent:表示如果本地已經存在該映象,則不重新下載;否則從遠端 Docker Hub 下載該映象
        imagePullPolicy: IfNotPresent
        resources: {}
status: {}

建立deploy。

[root@k8scloude1 ~]# kubectl apply -f nginx.yaml 
deployment.apps/nginx created

deployment建立成功。

[root@k8scloude1 ~]# kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6cf858f6cf-rltvh   1/1     Running   0          6s

[root@k8scloude1 ~]# kubectl get deploy
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           12s

給deploy建立一個名為nginxsvc的svc,埠為80,svc型別為NodePort,關於svc的詳細內容,請檢視部落格《Kubernetes(k8s)服務service:service的發現和service的釋出》。

[root@k8scloude1 ~]# kubectl expose --name=nginxsvc deploy nginx --port=80 --type=NodePort
service/nginxsvc exposed

檢視svc。

[root@k8scloude1 ~]# kubectl get svc
NAME       TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
nginxsvc   NodePort   10.107.202.119   <none>        80:30151/TCP   9s

在瀏覽器存取 192.168.110.130:30151,即可存取nginx介面。

十一.設定gitlab觸發jenkins

接下來回到gitlab,設定gitlab觸發jenkins。

gitlab首頁依次點選管理區域-->設定-->Outbound requests,展開Outbound requests,勾選允許勾點和服務存取本地網路,儲存修改,這樣jenkins才能存取gitlab程式碼倉庫。

首頁點選專案-->您的專案,點選進入my-project專案。

選擇設定-->整合。

注意:連結 JENKINS_URL/job/devopsProject/build?token= TOKEN_NAME,這個連結用於 gitlab 在觸發 jenkins 時用到的連結,我們這裡,TOKEN_NAME 的值是connect123,JENKINS_URL 是 192.168.110.133:8080,所以整個連結為:
http://192.168.110.133:8080/job/devopsProject/build?token=connect123

連結(URL)填入gitlab 觸發 jenkins 時用到的連結:http://192.168.110.133:8080/job/devopsProject/build?token=connect123

點選增加Web勾點。

Web勾點生成後進行測試,點選Test-->Push events。

如果看到如下,則test成功,gitlab能觸發jenkins了。

自此整個DevOps環境就搭建成功了。

十二.測試DevOps

DevOps環境搭建成功之後,我們需要來測試整個流程。

12.1 寫程式碼

進入專案。

[root@etcd1 ~]# cd my-project/

[root@etcd1 my-project]# ls
index.html

編寫Dockerfile檔案,關於Dockerfile詳細內容,請檢視部落格《構建自定義映象並優化dockerfile檔案》。

[root@etcd1 my-project]# vim Dockerfile 

[root@etcd1 my-project]# cat Dockerfile 
#FROM指定基礎映象為docker.io/nginx:latest
FROM docker.io/nginx:latest
#MAINTAINER指定作者為test
MAINTAINER test
#把index.html拷貝到容器裡的/usr/share/nginx/html/目錄
ADD index.html /usr/share/nginx/html/
#暴露80號埠    
EXPOSE 80
#執行Nginx
CMD ["nginx", "-g","daemon off;"]

更新首頁檔案。

[root@etcd1 my-project]# vim index.html 

[root@etcd1 my-project]# cat index.html 
hello everybody
XX同志提交了新程式碼
這是新映象部署的nginx web應用

12.2 上傳程式碼到gitlab

git add命令把Dockerfile和index.html新增到暫存區。

[root@etcd1 my-project]# pwd
/root/my-project

[root@etcd1 my-project]# ls
Dockerfile  index.html

[root@etcd1 my-project]# git add .

新增註釋。

[root@etcd1 my-project]# git commit -m 'today new file'
[master ebee76d] today new file
 2 files changed, 8 insertions(+), 1 deletion(-)
 create mode 100644 Dockerfile

git push命令用於將本地分支的更新,推播到遠端主機。

[root@etcd1 my-project]# git push 
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 493 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To ssh://[email protected]:222/root/my-project.git
   773973b..ebee76d  master -> master

去gitlab介面看檔案是否推播成功,可以看到git push成功。

12.3 Jenkins執行CI/CD(自動構建自動部署)流程

因為gitlab上的檔案發生變動,jenkins會拉取gitlab上的檔案,進行編譯,然後上傳新映象到registry倉庫,最後把新映象部署到k8s環境。

點選狀態,可以發現最新的#4已經構建成功,我們檢視控制檯輸出。

下面解釋了控制檯輸出的內容:

本來我們的nginx web介面是這樣的。

重新整理之後介面變為這樣子(中文亂碼了),說明DEVOPS流程成功。

12.4 再試一次

再次更新首頁檔案index.html。

[root@etcd1 my-project]# pwd
/root/my-project

[root@etcd1 my-project]# ls
Dockerfile  index.html

[root@etcd1 my-project]# vim index.html 

[root@etcd1 my-project]# cat index.html 
hello everybody
this is latest

提交程式碼到gitlab程式碼倉庫。

[root@etcd1 my-project]# git add .

[root@etcd1 my-project]# git commit -m "latest and last"
[master a08be73] latest and last
 1 file changed, 1 insertion(+), 2 deletions(-)

[root@etcd1 my-project]# git push 
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 314 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://[email protected]:222/root/my-project.git
   ebee76d..a08be73  master -> master

到gitlab介面上檢視新檔案。

jenkins最新的也構建成功。

重新整理nginx web介面,內容變為最新的了。

12.5 降低使用者許可權繼續測試CI/CD

需要注意的是前面我們給test使用者授予了cluster-admin的許可權,這個許可權很大,我們可以把許可權變小。

現在回到k8s環境給使用者test授權。

建立目錄存放yaml檔案。

[root@k8scloude1 ~]# mkdir devops

[root@k8scloude1 safe]# cd ~/devops/

檢視clusterrolebinding,可以看到給test使用者繫結了cluster-admin。

[root@k8scloude1 devops]# kubectl get clusterrolebinding | grep test
test                                                   ClusterRole/cluster-admin                                                          4h54m

編寫角色yaml檔案,檔案功能為:建立名為role1的角色,該角色對pod,svc,deploy具有get,list,create,delete許可權,對deploy具有get,list,create,delete,patch許可權,關於授權的詳細內容,請檢視部落格《Kubernetes(k8s)存取控制:許可權管理之RBAC鑑權》。

[root@k8scloude1 devops]# cat role1.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: role1
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - services
  - deployments
  verbs:
  - get
  - list
  - create
  - delete
- apiGroups:
  - "apps"
  resources:
  - deployments
  - deployments/scale
  verbs:
  - get
  - list
  - create
  - delete
  - patch

建立角色。

[root@k8scloude1 devops]# kubectl apply -f role1.yaml 
role.rbac.authorization.k8s.io/role1 created

檢視角色。

[root@k8scloude1 devops]# kubectl get role
NAME    CREATED AT
role1   2022-03-31T11:27:01Z

role1的許可權如下:

[root@k8scloude1 devops]# kubectl describe role role1 
Name:         role1
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources               Non-Resource URLs  Resource Names  Verbs
  ---------               -----------------  --------------  -----
  deployments.apps/scale  []                 []              [get list create delete patch]
  deployments.apps        []                 []              [get list create delete patch]
  deployments             []                 []              [get list create delete]
  pods                    []                 []              [get list create delete]
  services                []                 []              [get list create delete]

刪除叢集角色系結test。

[root@k8scloude1 devops]# kubectl delete clusterrolebinding test
clusterrolebinding.rbac.authorization.k8s.io "test" deleted

給使用者test授予role1許可權。

[root@k8scloude1 devops]# kubectl create rolebinding test --role=role1 --user=test
rolebinding.rbac.authorization.k8s.io/test created

把使用者test許可權變小之後,繼續更新首頁檔案index.html。

[root@etcd1 ~]# cd my-project/

[root@etcd1 my-project]# ls
Dockerfile  index.html

[root@etcd1 my-project]# vim index.html 

[root@etcd1 my-project]# cat index.html 
hello everybody
this is rolebinding not clusterrolebinding

上傳程式碼到gitlab。

[root@etcd1 my-project]# git add .

[root@etcd1 my-project]# git commit -m "rolebinding"
[master 78b946a] rolebinding
 1 file changed, 1 insertion(+), 1 deletion(-)

[root@etcd1 my-project]# git push 
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 330 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://[email protected]:222/root/my-project.git
   a08be73..78b946a  master -> master

把test使用者許可權變小之後,變動檔案,nginx web也變化為最新的了。

當然deploy的副本可以設定為大於1,這樣就可以實現負載均衡,更換映象的時候就不會出現不可用的情況,使用者無感知。

十三.總結

通過使用GitLab、Jenkins和Kubernetes,我們成功地建立了一個完整的CI/CD解決方案。DevOps實踐能夠極大地提高軟體開發和交付過程的效率和質量。持續整合和交付使團隊能夠更快地交付新功能並快速適應變化。

在實施CI/CD解決方案時,請根據您的專案需求和團隊能力進行適當的調整和客製化。

持續學習和實踐是提高DevOps技能的關鍵。通過實戰和不斷探索,您將能夠建立強大的CI/CD流程,提高軟體交付的速度和質量。