(1) nfs存儲
(2) harbor鏡像倉庫
(3) gitlab代碼倉庫
(4) ingress-nginx
(5) nfs-subdir-external-provisioner
1 部署Jenkins
1.1 配置說明
1 Jenkins是一款開源的CI&CD系統,用於自動化各種任務,包括構建、測試和部署。
2 Jenkins官方提供了鏡像"https://hub.docker.com/r/jenkins/jenkins"。
3 在"default"命名空間下使用"Deployment"方式來部署這個鏡像,"kind: Service"使用"type: NodePort"暴露端口,Web內部訪問端口80,
Web外部訪問端口30006,Slave內部通信端口5000,容器啟動后Jenkins數據存儲在"/var/jenkins_home"目錄,所以需要將該目錄使用PV持久化
存儲。
1.2 Jenkins.yml配置文件
[root@k8s-master1 ms_jenkins]# cat jenkins.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins
labels:
name: jenkins
spec:
replicas: 1
selector:
matchLabels:
name: jenkins
template:
metadata:
name: jenkins
labels:
name: jenkins
spec:
terminationGracePeriodSeconds: 10
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins
imagePullPolicy: Always
ports:
- containerPort: 8080
- containerPort: 50000
resources:
limits:
cpu: 1
memory: 1Gi
requests:
cpu: 0.2
memory: 200Mi
env:
- name: JAVA_OPTS
value: -Xmx1g
volumeMounts:
- name: jenkins-home
mountPath: /var/jenkins_home
securityContext:
fsGroup: 1000
runAsUser: 0
volumes:
- name: jenkins-home
persistentVolumeClaim:
claimName: jenkins-home
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-home
spec:
storageClassName: "managed-nfs-storage"
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
name: jenkins
spec:
selector:
name: jenkins
type: NodePort
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
nodePort: 30006
- name: agent
port: 50000
protocol: TCP
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins
rules:
- apiGroups: [""]
resources: ["pods","events"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create","delete","get","list","patch","update","watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["secrets","events"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: jenkins
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
[root@k8s-master1 ms_jenkins]#
1.3 部署Jenkins
# kubectl apply -f jenkins.yml
# kubectl get pod -l name=jenkins -n default
# kubectl get svc/jenkins -n default
# kubectl get ep/jenkins -n default
#
# kubectl get pv
# kubectl get pvc -n default
1.4 Jenkins UI界面安裝步驟
1 獲取Jenkins初始化安裝密碼
# kubectl logs -f pod/jenkins-578b57ddcb-dzn7n -n default
......(省略的內容)
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
72c0bc4c4a6748aba3fa39b0797eb08c
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
......(省略的內容)
2 解鎖Jenkins
3 選擇插件來安裝
4 不安裝任何的插件
5 創建管理員
6 Jenkins URL
7 Jenkins安裝完成
8 Jenkins首頁
1.5 安裝插件
Manage Jenkins -> System Configuration -> Manage Plugins -> Available -> 分別搜索
Chinese/Git/Git Parameter/Pipeline/kubernetes/Config File Provider/Extended Choice Parameter -> 選中后點擊
Install without restart
1 Chinese # 中文字體
2 Git # 拉取代碼
3 Git Parameter # Git參數化構建
4 Pipeline # 流水線
5 kubernetes # 連接Kubernetes動態創建Slave代理
6 Config File Provider # 存儲配置文件
7 Extended Choice Parameter # 擴展選擇框參數,支持多選
插件安裝完成后必須重啟Jenkins,否則安裝的插件無法正常使用,重啟Jenkins的方法為: http://172.16.1.81:30006/restart
提示: Jenkins的UI界面上可能會提示Jenkins版本升級和一些警告信息,忽略即可。
2 Jenkins在kubernetes中動態創建代理
2.1 Jenkins主從架構介紹
1 Jenkins Master/Slave架構
Master(Jenkins本身)提供Web頁面讓用戶來管理項目和從節點(Slave),項目任務可以運行在Master本機或者分配到從節點運行,一個Master可以關聯多個Slave,這樣的好處是可以讓Slave分擔Master工作壓力和隔離構建環境。
2 當觸發Jenkins任務時,Jenkins會調用Kubernetes API創建Slave Pod,Pod啟動后會連接Jenkins,接受任務並處理。
2.2 kubernetes插件配置
1 kubernetes插件介紹
Kubernetes插件用於Jenkins在Kubernetes集群中運行動態代理,插件介紹"https://github.com/jenkinsci/kubernetes-plugin"。
2 配置插件
系統管理 -> 系統配置 -> 節點管理 -> Configure Clouds -> 配置集群 -> Add a new cloud -> Kubernetes ->
Kubernetes Cloud details
(1) Jenkins連接k8s配置
(2) jenkins slave連接jenkins master配置
2.3 自定義Jenkins Slave鏡像
1 編排 jenkins slave 鏡像所需的配置文件
[root@k8s-master1 ms_jenkins]# mkdir -p jenkins-slave/
[root@k8s-master1 ms_jenkins]# cd jenkins-slave/
(1) Dockerfile
# cat Dockerfile
FROM centos:7
LABEL maintainer lc
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
COPY helm kubectl /usr/bin/
ENTRYPOINT ["jenkins-agent"]
(2) helm
下載地址: https://get.helm.sh/helm-v3.4.2-linux-amd64.tar.gz
# chmod +x helm
(3) jenkins-agent
github開源地址: https://github.com/jenkinsci/docker-inbound-agent
下載代碼庫: https://github.com/jenkinsci/docker-inbound-agent/archive/refs/heads/master.zip
使用 "jenkins-agent" shell 腳本文件。
(4) kubectl
# cp -a /usr/bin/kubectl /root/ms_jenkins/jenkins-slave/
# chmod +x /root/ms_jenkins/jenkins-slave/kubectl
(5) settings.xml
下載地址: http://archive.apache.org/dist/maven/maven-3/3.5.0/binaries/apache-maven-3.5.0-bin.tar.gz
配置文檔: https://developer.aliyun.com/article/512821
在 setttins.xml 文件中找到 <mirrors></mirrors> 標簽對,添加如下內容:
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
(6) agent.jar
# wget http://172.16.1.81:30006/jnlpJars/agent.jar
2 編排 jenkins slave 鏡像所需的配置文件說明
[root@k8s-master1 jenkins-slave]# ls -l
total 81428
-rw-r--r-- 1 root root 1522173 Feb 10 10:00 agent.jar # jenkins agent 程序,接受 master 下發的任務
-rw-r--r-- 1 root root 423 Feb 10 17:02 Dockerfile # jenkins slave 鏡像編排文件
-rwxr-xr-x 1 root root 41603072 Dec 9 2020 helm # helm 二進制文件,客戶端工具
-rw-r--r-- 1 root root 5390 Feb 10 17:16 jenkins-agent # shell 腳本用於啟動 agent.jar
-rwxr-xr-x 1 root root 40230912 Dec 9 2020 kubectl # kubectl 二進制文件,客戶端工具
-rw-r--r-- 1 root root 10406 Feb 10 17:36 settings.xml # maven 配置文件
3 構建 jenkins slave 鏡像並推送到鏡像倉庫
說明: 構建的 jenkins slave 鏡像作為中間件鏡像使用,因此將其放到公開項目 library 下
(1) 構建鏡像
[root@k8s-master1 jenkins-slave]# docker build -t 172.16.1.61/library/jenkins-slave-jdk:1.8 .
(2) 推送到鏡像倉庫
[root@k8s-master1 jenkins-slave]# docker push 172.16.1.61/library/jenkins-slave-jdk:1.8
(3) 查看推送的鏡像
2.4 測試Jenkins主從架構
1 新建項目 -> 項目名(jenkins-slave-test) -> 流水線 -> Pipeline script -> 生成示例[Declarative(Kubernetes)] 2 生成示例[Declarative(Kubernetes)] pipeline { agent { kubernetes { // 定義pod名稱的前綴,如果不定義,pod名稱的前綴為項目名 label "jenkins-agent" yaml ''' apiVersion: v1 kind: Pod spec: containers: # 這里容器名必須定義為jnlp - name: jnlp image: 172.16.1.61/library/jenkins-slave-jdk:1.8 ''' } } stages { stage('Main') { steps { sh 'hostname' } } } } 3 查看構建輸出 pipeline 項目在執行的過程中會在 k8s 集群中創建 Jenkins slave pod,pipeline 項目運行結束后會自動銷毀創建的 pod。 [root@k8s-master1 ~]# kubectl get pod -n default NAME READY STATUS RESTARTS AGE jenkins-578b57ddcb-6lfbw 1/1 Running 0 3h30m jenkins-agent-bddp0-q5pnh 1/1 Running 0 9s
3 Jenkins Pipeline流水線
3.1 Pipeline介紹
Jenkins Pipeline是一套運行工作流框架,將原本獨立運行單個或者多個節點的任務鏈接起來,實現單個任務難以完成的復雜流程編排和可視化。
1 Jenkins Pipeline 是一套插件,支持在 Jenkins 中實現持續集成和持續交付。
2 Pipeline 通過特定語法對簡單到復雜的傳輸管道進行建模。
3 Jenkins Pipeline 的定義被寫入一個文本文件,稱為Jenkinsfile。
3.2 Pipeline語法
pipeline 語法包括聲明式和腳本式兩種。
1 聲明式
支持大部分Groovy,具有豐富的語法特性,易於編寫和設計,pipeline {}
2 腳本式
遵循與Groovy相同的語法,node {}
3.3 Pipeline示例
1 jenkins example pipeline { agent any stages { stage('Build') { steps { echo 'build......' } } stage('Test') { steps { echo 'Test......' } } stage('Deploy') { steps { echo 'deploy......' } } } } 2 參數說明 (1) "stages" 是 Pipeline 中最主要的組成部分,Jenkins 將會按照 stages 中描述的順序從上往下的執行。 (2) "stage" 是一個 Pipeline 可以划分為若干個 stage,每個 stage 代表一組操作,比如: Build、Test、Deploy。 (3) "steps" 步驟,steps 是最基本的操作單元,可以是打印一句話,也可以是構建一個 Docker 鏡像,由各類 Jenkins 插件提供,比如命令: sh 'mvn',就相當於我們平時 shell 終端中執行 mvn 命令一樣。
4 流水線自動發布微服務項目
4.1 發布需求
1 將微服務項目自動化部署到K8s平台的需求
(1) 盡量完全自動化部署,無需過多人工干預。
(2) 可以選擇升級某個、某些微服務。
(3) 在部署、升級微服務時,可對微服務某些特性做配置,例如命名空間、副本數量。
2 發布過程
拉取代碼 -> 代碼編譯 -> 構建鏡像 -> 部署到 kubernetes -> 測試
4.2 實現思路
在微服務架構中,會涉及幾個、幾十個微服務,如果每個服務都創建一個item,會增加維護的成本,因此需要編寫一個通用的Pipeline腳本,將這些
微服務部署差異化的部分使用Jenkins參數化,然后由人工交互確認發布微服務、環境配置等。但這只是解決了用戶的交互層面,在K8s實際部署項目
時用YAML創建對應的資源,現在的問題是如何接收用戶的交互參數,自動化生成 YAML 文件,這就會用到 Helm 完成 YAML 文件的高效復用和微服
務部署。
4.3 gitlab、harbor認證添加
1 啟用 Harbor 的 Chart 倉庫服務
[root@k8s_harbor ~]# cd /usr/local/harbor/
[root@k8s_harbor harbor]# ./install.sh --with-chartmuseum
# 啟用后,默認創建的項目就帶有 helm charts 功能了,不需要重啟 harbor 服務。
2 推送微服務代碼到 gitlab 的 microservice 倉庫
[root@k8s-master1 ms_jenkins]# unzip simple-microservice.zip
[root@k8s-master1 ms_jenkins]# cd simple-microservice/
[root@k8s-master1 simple-microservice]# git config --global user.name "Administrator"
[root@k8s-master1 simple-microservice]# git config --global user.email "admin@example.com"
[root@k8s-master1 simple-microservice]# git init
Initialized empty Git repository in /root/ms_jenkins/simple-microservice/.git/
[root@k8s-master1 simple-microservice]# git remote add origin http://172.16.1.62:9999/dev/microservice.git
[root@k8s-master1 simple-microservice]# git add .
[root@k8s-master1 simple-microservice]# git commit -m "Initial commit"
[root@k8s-master1 simple-microservice]# git push -u origin master
Username for 'http://172.16.1.62:9999': root
Password for 'http://root@172.16.1.62:9999': # 密碼: 12345678
3 將 gitlab 認證和 harbor 認證保存到 Jenkins 憑據
系統管理 -> 安全 -> 管理憑據 -> Jenkins -> 全局憑據(添加憑據) -> 類型(Username with password)
分別添加連接 gitlab 和 harbor 的用戶名、密碼到 Jenkins 憑據,然后獲取該憑據 ID 替換到腳本中 git_auth 和
docker_registry_auth 變量的值。
圖示(harbor認證): gitlab、harbor全局憑證ID:
gitlab ID: 26abeef4-acf8-4ba8-8e4e-454bc8a77513
harbor ID: a87872af-6fd5-45ed-a6b3-fb59ce0bcbf4
4 將 kubeconfig 存儲在 Jenkins,用於 slave 鏡像里 kubectl 連接 k8s 集群
系統管理 -> 系統配置 -> Managed files -> Add a new Config -> Custom file -> Next -> Content字段(填寫內容是
kubeconfig,kubeadm 部署 k8s 默認路徑在 master 節點 "/root/.kube/config",如果是二進制部署,需要自己生成),然后
復制 ID 替換腳本中 k8s_auth 變量的值。
說明: 將 kubectl、helm 工具封裝到 Slave 鏡像中,並通過 Config File Provider 插件存儲連接 K8s 集群的 kubeconfig 認證
文件,然后掛載到 slave 容器中,這樣就能使用 "kubectl apply deploy.yaml --kubeconfig=config" 命令管理 K8s 應用了,為
提高安全性,kubeconfig 文件可分配權限。
圖示(k8s認證):
k8s_auth ID: 1f58f4c8-720f-4126-91c7-b4d919655737
注: 剩余內容請查看文章"基於Jenkins構建微服務發布平台-2"