什麼是CI/CD?
CI/CD即持續集成與持續交付持續部署。
持續集成注重將各個開發者的工作集合到一個代碼倉庫中,通常每天會進行幾次, 主要目的是儘早發現集成錯誤,使團隊更加緊密結合,更好地協作。
持續交付的目的是最小化部署或發佈過程中團隊固有的摩擦, 它的實現通常能夠將構建部署的每個步驟自動化,以便任何時刻能夠安全地完成代碼發佈(理想情況下)。
持續部署是一種更高程度的自動化,無論何時代碼有較大改動, 都會自動進行構建/部署。
參考文章:什麼是 CI/CD
CI/CD流程圖
本文將使用GitLab
+Jenkins
+Kubernetes
來實現CI/CD的簡單自動化發佈場景
1 環境準備
確保各個節點服務器防火牆、selinux都關閉,做好域名解析
10.0.0.200 master01 jenkins.rsq.com
10.0.0.201 node01
10.0.0.202 node02
10.0.0.203 gitlab.rsq.com
10.0.0.204 store.rsq.com
2 組件部署
2.1 jenkins快速部署
可以考慮helm部署,也可以單機部署,這裏我選擇了單機部署,比較方便一點
1、yum安裝jenkins
# 配置jenkins源
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
# yum安裝jenkins和java環境
yum install jenkins java java-1.8.0-openjdk-devel -y
2、修改配置
vim /etc/sysconfig/jenkins
# 監聽端口
JENKINS_PORT="8080"
# 爲了不因爲權限出現各種問題,這裏直接使用root用戶
$JENKINS_USER="root"
# 修改目錄權限
chown -R root:root /var/lib/jenkins
chown -R root:root /var/cache/jenkins
chown -R root:root /var/log/jenkins
# 啓動jenkins
systemctl start jenkins
2.2 gitlab快速部署
之前有用過helm部署gitlab-ce,但是發現被廢棄了,裏邊deployment的apiVersion還是extensions/v1beta1
,跟現有deployment的apps/v1
不相符,若要使用還需要修改postgresql
和redis chart
的deployment文件,添加selector
字段,遂放棄。
1、點擊下方下載鏈接選擇所需要的gitlab-ce版本rpm包
2、安裝gitlab-ce
# 安裝依賴文件
yum -y install policycoreutils openssh-server openssh-clients postfix
# 獲取rpm包並安裝
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.8.7-ce.0.el7.x86_64.rpm
rpm -ivh gitlab-ce-10.8.7-ce.0.el7.x86_64.rpm
# 修改gitlab配置文件指定服務器ip和自定義端口
vim /etc/gitlab/gitlab.rb
external_url 'http://gitlab.rsq.com'
# 注意這裏設置的端口不能被佔用,默認是80端口,如果80已經使用則需要替換成其它端口
# 重置配置並啓動gitlab
gitlab-ctl reconfigure # 第一次執行時間會久一點
gitlab-ctl restart # 出現全部 ok: run: 即代表gitlab啓動成功
顯示如下界面即成功
創建一個項目供代碼push上傳
名字自定義
在客戶端即K8s主節點上配置ssh-key免密鑰登錄
# 這裏的-C指定我們gitlab中創建的郵箱賬號
ssh-keygen -t rsa -C "[email protected]"
# 然後拷貝 ~/.ssh/id_rsa.pub 公鑰至gitlab中
找到SSH Keys
在K8s主節點上創建代碼倉庫
[root@master01 ~]# mkdir /home/rsq/www
[root@master01 ~]# cd /home/rsq/www
[root@master01 www]# git init
Initialized empty Git repository in /home/rsq/www/.git/
[root@master01 www]# git remote add origin [email protected]:rsq/www.git
[root@master01 www]# git add .
[root@master01 www]# git commit -m "init"
[root@master01 www]# git push -u origin master
The authenticity of host 'gitlab.rsq.com (10.0.0.205)' can't be established.
ECDSA key fingerprint is SHA256:Yg2SX+FS7+aEFjqCu5g4h4g98RVBacG3a669M8Bw8eA.
ECDSA key fingerprint is MD5:f5:cb:69:36:63:3d:92:da:c7:4d:7b:d7:df:ba:dc:e0.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitlab.rsq.com,10.0.0.205' (ECDSA) to the list of known hosts.
Counting objects: 3, done.
Writing objects: 100% (3/3), 237 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://[email protected]/rsq/www.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
參考文章:
2.3 harbor快速部署
1、獲取harbor安裝包
# 進入github選擇harbor所需release版本,我這裏用的v1.7.4
# 下載包有點慢
https://github.com/goharbor/harbor/releases
# 解壓縮至/usr/local/目錄下
tar -xf harbor-offline-installer-v1.7.4.tgz -C /usr/local/
2、修改harbor配置文件
vim /usr/local/harbor/harbor.cfg
hostname = store.rsq.com
harbor_admin_password = Harbor12345 # 初始密碼
db_password = root123 # 數據庫初始密碼
3、安裝之前需要用pip3安裝compose-harbor,否則會報錯
# yum安裝pip
yum -y install epel-release
yum install python3-pip
# 更新國內pip源
mkdir ~/.pip/
vim ~/.pip/pip.conf
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host=mirrors.aliyun.com
# 安裝docker-compose
pip3 install docker-compose
4、安裝harbor
cd /usr/local/harbor
./install.sh
3 CI/CD交付
接下來會按照上圖一步一步操作,當我們往gitlab上push代碼後,會自動觸發Jenkins的構建,這個實在gitlab上設置實現的。
jenkins中創建一個pip line
gitlab中調試
添加完Webhook之後可以進行測試
若通過,既可進行下一步構建代碼,不過這裏就不演示如何進行構建,直接貼上代碼
一個CI/CD簡單的groovy腳本
#!groovy
pipline {
agent any
environment {
REPOSITORY="ssh://[email protected]:2222/tom/gocode.git"
MODULE="user-edge-service" // 要更新的pod名字
SCRIPTS_PATH="/home/rsq/scripts" // 腳本都在這裏執行
}
stages {
stage('獲取代碼') {
steps {
echo "start fetch code from git:${REPOSITORY}"
deleteDir()
git "${REPOSITORY}"
}
}
stage('靜態分析') {
steps {
echo "start code check."
}
}
stage('編譯+單元測試') {
steps {
echo "start complie"
sh "mvn -U -pl ${MODULE} -am clean package"
}
}
stage('構建鏡像') {
steps {
echo "start build image"
sh "${SCRIPTS_PATH}/build-images.sh ${MODULE}"
}
}
stage('發佈系統') {
steps {
echo "start deploy"
sh "${SCRIPTS_PATH}/deploy.sh user-service-deployment ${MODULE}"
}
}
}
}
在K8s主節點的/home/rsq/scripts目錄下創建如下兩個bash腳本,供jenkins調用執行
build-images.sh
#!/bin/bash
MODULE=$1
TIME=`date "+%Y%m%d%H%M"`
GIT_REVERSION=`git log -1 --pretty=format:"%h"`
IMAGE_NAME=hub.rsq.com:8080/micro-service/${MODULE}:${TIME}-${GIT_REVERSION}
cd ${MODULE}
# 編譯鏡像
docker build -t ${IMAGE_NAME} .
cd -
# 推送代碼
docker push ${IMAGE_NAME}
# 把鏡像名字寫入文件,供 腳本獲取使用
echo ${IMAGE_NAME} > IMAGE_NAME
deploy.sh
#!/bin/bash
IMAGE=`cat IMAGE_NAME`
DEPLOYMENT=$1
MODULE=$2
echo "update image to:${IMAGE}"
kubectl set image deployments/${DEPLOYMENT} ${MODULE}=${IMAGE}
最後可以實現每當往gitlab中進行一次push代碼的操作,gitlab就會自動觸發後續操作,直到完成持續部署,代碼上線,這樣就實現了一個簡單的CI/CD流程,但是靜態分析的代碼需要自己根據實際代碼去編寫。