CI&CD:
如果springboot-demo需要修改某些代碼,按照上述流程,是不是又要重新打包?然后寫Dockerfile,push鏡像,然后寫k8s配置文件等等之類的操作,在生產環境我們也會遇到發包更新頻繁的問題,那么有什么辦法提高我們的發布效率與協作效率呢?這里我們通常會引入CI&CD的概念
-
持續集成(Continuous integration,簡稱CI:頻繁地(一天多次或者N次)將代碼集成到主干。將軟件個人研發的部分向軟件整體部分交付,頻繁進行集成以便更快地發現其中的錯誤。
-
持續交付(Continuous delivery):指的是,頻繁地將軟件的新版本,交付給質量團隊或者用戶,以供評審。如果評審通過,代碼就進入生產階段。持續交付在持續集成的基礎上,將集成后的代碼部署到更貼近真實運行環境的「類生產環境」(production-like environments)中。持續交付優先於整個產品生命周期的軟件部署,建立在高水平自動化持續集成之上。
-
持續部署(continuous deployment,簡稱CD):是持續交付的下一步,指的是代碼通過評審以后,自動部署到生產環境。持續部署的目標是,代碼在任何時刻都是可部署的,可以進入生產階段。持續部署的前提是能自動化完成測試、構建、部署等步驟。
持續集成、持續交付、持續部署提供了一個優秀的 DevOps 環境。對於整個開發團隊來說,能很大地提升開發效率,好處與挑戰並行。無論如何,頻繁部署、快速交付以及開發測試流程自動化都將成為未來軟件工程的重要組成部分。
我們就來感受一下CICD帶來的效率,首先我們基於先前的SpringBoot-demo工程進行發布,當有Push操作的時候會通過Web Hook鈎子讓Jenkins進行構建,推送,讓后簡歷docker鏡像,k8s構建pod。發布服務:
基礎環境准備:
- JDK 1.8.0_161 :https://www.cnblogs.com/wuzhenzhao/p/9481083.html
- apache-maven-3.6.3.
- git 2.24.1.
- Docker 環境。
- 必須要在 k8s 集群中,我這邊選用的是兩台阿里雲的服務器。注意需要有外網IP。接受 Web Hook
- 准備一個springboot-demo,上傳至Github,用IDEA進行關聯。等等需要Push代碼觸發 Web Hook
- 需要安裝Jenkins:https://www.cnblogs.com/wuzhenzhao/p/11425237.html ,並且把 Git ,Maven ,JDK 三個全局工具配置好。nohup java -jar jenkins.war --httpPort=8080 & 啟動。
測試pipeline任務:
(1)創建jenkins的task
(2)拉取github代碼,在最下面編寫pipeline,然后“保存和立即構建“,同時可以查看“Console Output”
腳本如下
node { def mvnHome stage('Preparation') { // for display purposes git 'https://github.com/itcrazy2016/springboot-demo.git' } }
創建完返回首頁點擊構建:
(3)來到Jenkins安裝節點: /root/.jenkins/workspace/springboot-demo
(4)配置springboot-demo的task,修改pipeline內容 ,增加maven構建,然后“保存和立即構建“,同時可以查看“Console Output”
node { def mvnHome stage('Preparation') { // for display purposes git 'https://github.com/wuzhenzhao/springboot-demo.git' } dir('/root/.jenkins/workspace/springboot-demo/springboot-demo') { // 切換到/home/jenkins目錄中做一些事情 // some block stage('Maven Build') { sh "mvn clean package" } } }
(5)來到節點:ll /root/.jenkins/workspace/springboot-demo/springboot-demo
先看Jenkins控制台的輸出
看看服務器的目錄,果然生成了 target目錄。
至此,我們已經可以通過在jenkins上手動構建的方式,拿到github上的代碼,並且用maven進行構建。
git push觸發jenkins自動構建:
(1)在github上配置jenkins的webhook地址,配置GitHub Server [系統管理]->[系統配置]->[找到github服務器]->找到Github,這里有 Web Hook的地址:
選擇構建觸發器,並且選擇Github Hook觸發
然后配置Github:
(2)生成Personal access tokens
Jenkins訪問github需要授權,所以在github上生成token交給jenkins使用,即 Personal access tokens.
github的Settings[個人信息右上角]-->Developer settings-->Personal access tokens
Generate new token 最后保存好該token,比如: 0b9d624404e95d6fe36f86d84374f2dcce402b43
(3) 配置GitHub Server [系統管理]->[系統配置]->[找到github服務器]->[添加github服務器] 然后按照下面圖片步驟進行操作:
jenkins安裝插件:
01 安裝github plugin插件:[系統管理]->[插件管理]->[可選插件] 02 安裝gitlab插件和gitlab hook插件:[系統管理]->[插件管理]->[可選插件]
系統設置找到Github,這里有 Web Hook的地址:
配置完是這樣的:
然后用 IDEA 提交以下代碼測試一下,確保無誤進行下面的操作。
核心實戰走起:
build&push鏡像:經過前面的折騰,肯定可以獲取到代碼,並且用maven進行構建了,最終拿到一個target/xxx.jar
來到 jenkins安裝主機節點上的workspace目錄:cd /root/.jenkins/workspace
(1) 創建文件夾准備一個文件,名稱為springboot-demo-build-image.sh
mkdir /root/.jenkins/workspace/scripts/
vi /root/.jenkins/workspace/scripts/springboot-demo-build-image.sh
(2)編寫springboot-demo-build-image.sh文件
# 進入到springboot-demo目錄 cd ../springboot-demo # 編寫Dockerfile文件 cat <<EOF > Dockerfile FROM openjdk:8-jre-alpine COPY target/springboot-demo-1.0-SNAPSHOT.jar /springboot-demo.jar ENTRYPOINT ["java","-jar","/springboot-demo.jar"] EOF echo "Dockerfile created successfully!" # 基於指定目錄下的Dockerfile構建鏡像 docker build -t registry.cn-hangzhou.aliyuncs.com/wuzz-docker/springboot-demo:v1.0 . # push鏡像,這邊需要阿里雲鏡像倉庫登錄,在當前安裝了jenkins主機上登錄 docker push registry.cn-hangzhou.aliyuncs.com/wuzz-docker/springboot-demo:v1.0
sudo docker login --username=隨風去wuzz registry.cn-hangzhou.aliyuncs.com 先登錄。
chmod +x /root/.jenkins/workspace/scripts/springboot-demo-build-image.sh 給文件授權
(3)增加pipeline
node { def mvnHome stage('Preparation') { // for display purposes git 'https://github.com/wuzhenzhao/springboot-demo.git' } dir('/root/.jenkins/workspace/springboot-demo/springboot-demo') { // 切換到/home/jenkins目錄中做一些事情 // some block stage('Maven Build') { sh "mvn clean package" } stage('Build Image') { sh "/root/.jenkins/workspace/scripts/springboot-demo-build-image.sh" } } }
(4):重新構建,成功如下
查看鏡像:docker images
看看阿里雲倉庫是否有鏡像了:
Kubernetes拉取鏡像運行:
經過前面的折騰,現在已經能夠把鏡像push到鏡像倉庫了,接下來就是k8s拉取鏡像並且運行在集群中咯。根據前面的經驗,肯定再創建一個stage,然后運行sh腳本,腳本中執行內容,包括yaml文件
(1) 編寫springboot-demo.yaml文件 。在/root/.jenkins/workspace/scripts/目錄下創建springboot-demo.yaml
# 以Deployment部署Pod apiVersion: apps/v1 kind: Deployment metadata: name: springboot-demo spec: selector: matchLabels: app: springboot-demo replicas: 1 template: metadata: labels: app: springboot-demo spec: containers: - name: springboot-demo image: registry.cn-hangzhou.aliyuncs.com/wuzz-docker/springboot-demo:v1.0 ports: - containerPort: 8888 --- # 創建Pod的Service apiVersion: v1 kind: Service metadata: name: springboot-demo spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: springboot-demo --- # 創建Ingress,定義訪問規則 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: springboot-demo spec: rules: - host: springboot.wuzz.com http: paths: - path: / backend: serviceName: springboot-demo servicePort: 80
(2)編寫k8s-deploy-springboot-demo.sh文件
vi /root/.jenkins/workspace/scripts/k8s-deploy-springboot-demo.sh
kubectl delete -f /root/.jenkins/workspace/scripts/springboot-demo.yaml kubectl apply -f /root/.jenkins/workspace/scripts/springboot-demo.yaml echo "k8s deploy success!"
(3)編寫pipeline:
node { def mvnHome stage('Preparation') { // for display purposes
git 'https://github.com/wuzhenzhao/springboot-demo.git' } dir('/root/.jenkins/workspace/springboot-demo/springboot-demo') { // 切換到/home/jenkins目錄中做一些事情 // some block
stage('Maven Build') { sh "mvn clean package" } stage('Build Image') { sh "/root/.jenkins/workspace/scripts/springboot-demo-build-image.sh" } stage('K8S Deploy') { sh "/root/.jenkins/workspace/scripts/k8s-deploy-springboot-demo.sh" } } }
chmod +x /root/.jenkins/workspace/scripts/k8s-deploy-springboot-demo.sh 授權。
先查看一下 Nodes 是都是 ready :kubectl get nodes:
確保網絡沒問題:查看系統 pods:kubectl get pods --all-namespaces -w
這個時候IDEA 修改后提交代碼,會觸發構建:
查看 pod,service,ingress信息
再查看一下 pod 的啟動日志 :kubectl logs -f pod-name:
到這里就部署完成了,由於我這里是阿里雲沒有域名,無法再本地操作,到了這一步,只要 k8s集群沒問題,部署就沒問題了。如果 Jenkins 是部署在 worker 節點, worker執行不了kubectl
- 切換到master上,cd ~ ---> cat .kube/config --->復制內容
- 切換到worker上 cd ~ ---> vi .kube/config --->粘貼內容