一.系統環境
本文主要基于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 EngineLoaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)Active: active (running) since 六 2022-03-26 17:53:49 CST; 40s agoDocs: https://docs.docker.comMain PID: 1495 (dockerd)Memory: 32.9MCGroup: /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 EngineLoaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)Active: active (running) since 二 2022-03-29 11:37:51 CST; 20s agoDocs: https://docs.docker.comMain PID: 8083 (dockerd)Memory: 36.8MCGroup: /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 EngineLoaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)Active: active (running) since 二 2022-03-29 11:51:36 CST; 4s agoDocs: https://docs.docker.comMain PID: 57510 (dockerd)Memory: 63.6MCGroup: /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 EngineLoaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)Active: active (running) since 二 2022-03-29 15:55:13 CST; 5s agoDocs: https://docs.docker.comMain PID: 9099 (dockerd)Memory: 43.1MCGroup: /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&#x