java后臺
創建harbor鏡像拉取Secret:kubectl create secret docker-registry harbor-regcred \ --docker-server= \ --docker-username= \ --docker-password= \ -n productionDockerfile
FROM *harbor地址*/library/custom-jdk:1.8.0-alpineLABEL maintainer = "Winter Lee"
RUN apk add --no-cache tzdata fontconfig ttf-dejavu && \ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ echo "Asia/Shanghai" > /etc/timezone
RUN mkdir -p \ /home/backend/jar_28888 \ /home/backend/etc \ /home/logs \ /home/app/logs && \ chmod -R 777 /home/appWORKDIR /home
ARG JAR_PATH
COPY ${JAR_PATH} /home/backend/jar_28888/admin.jarVOLUME /app/logs
EXPOSE 28888
ENTRYPOINT [ "java" , \ "-Djava.awt.headless=true" , \ "-Xms512m" , \ "-Xmx2048m" , \ "-DLOG_PATH=/app/logs" , \ "-jar" , \ "/jono/backend/jar_28888/admin.jar" ] JEKINS構建鏡像推送到harbor私服pipeline { agent anyparameters { gitParameter( name: 'TAG_NAME' ,type: 'PT_TAG' ,description: '選擇要構建的 Git 標簽' ,branch: 'test' ,tagFilter: '*' ,sortMode: 'DESCENDING' ,defaultValue: '' ) } environment { HARBOR_REG = "harbor地址" PROJECT_NAME = "項目名稱" IMAGE_NAME = "鏡像名稱" // 使用Harbor憑證(需先在Jenkins創建)HARBOR_CRED = credentials( 'de3f0156-4c04-445d-9621-2f966ba40f28' ) } stages { stage( 'Checkout Code' ) { steps { checkout( [ $class : 'GitSCM' ,branches: [ [ name: "refs/tags/${params.TAG_NAME} " ] ] ,extensions: [ [ $class : 'CloneOption' , depth: 0 , shallow: false] ] ,userRemoteConfigs: [ [ url: '代碼倉庫地址' ,credentialsId: '代碼倉庫憑證' ,refspec: '+refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/*' ] ] ] ) } } stage( 'Maven Build' ) { steps { dir( '.' ) { timeout( time: 15 , unit: 'MINUTES' ) { sh 'mvn clean package -P sit' } sh 'ls -l target/admin.jar' } } } // 新增:準備鏡像標簽stage( 'Prepare Image Tag' ) { steps { script { // 清理標簽名(替換非法字符為橫杠,轉小寫)env.IMAGE_TAG = params.TAG_NAME.replaceAll( /[ ^a-zA-Z0-9\ \ .-] /, '-' ) .toLowerCase( ) echo "使用鏡像標簽: ${env.IMAGE_TAG} " } } } stage( 'Docker Build' ) { steps { script { // 安全登錄Harborsh "echo ${HARBOR_CRED_PSW} | docker login -u ${HARBOR_CRED_USR} --password-stdin ${HARBOR_REG} " // 使用Git標簽名作為鏡像標簽sh "" "docker build \ \ --build-arg JAR_PATH = target/admin.jar \ \ -t ${HARBOR_REG} /${PROJECT_NAME} /${IMAGE_NAME} : ${env.IMAGE_TAG} \ \ -f env/sit/Dockerfile \ \ . "" "} } } stage( 'Push to Harbor' ) { steps { script { // 推送指定標簽的鏡像sh "docker push ${HARBOR_REG} /${PROJECT_NAME} /${IMAGE_NAME} :${env.IMAGE_TAG} " } } } } post { always { script { // 清理本地鏡像sh "docker rmi ${HARBOR_REG} /${PROJECT_NAME} /${IMAGE_NAME} :${env.IMAGE_TAG} || true" sh "docker logout ${HARBOR_REG} " } cleanWs( ) } }
} K8s部署 yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:name: admin-productionnamespace: production labels:app: adminenv: production
spec:replicas: 2 revisionHistoryLimit: 5 strategy:type: RollingUpdaterollingUpdate:maxSurge: 25 % maxUnavailable: 25 % selector:matchLabels:app: adminenv: productiontemplate:metadata:labels:app: adminenv: productionspec:securityContext: runAsUser: 1000 runAsGroup: 3000 fsGroup: 2000 containers:- name: adminimage: *代碼倉庫地址/項目名稱*/admin:44-sit-202505231400ports:- containerPort: 28888 volumeMounts:- name: etc-volumemountPath: /home/backend/etcreadOnly: true resources: limits:cpu: "1" memory: 1Girequests:cpu: "0.5" memory: 512MilivenessProbe: httpGet:path: /admin/captchaImageport: 28888 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet:path: /admin/captchaImageport: 28888 initialDelaySeconds: 20 periodSeconds: 5 volumes:- name: etc-volumehostPath:path: /tmp/etctype: DirectoryOrCreateimagePullSecrets: - name: harbor-regcredaffinity: podAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100 podAffinityTerm:labelSelector:matchExpressions:- key: appoperator: Invalues: [ "admin" ] topologyKey: kubernetes.io/hostname
apiVersion: v1
kind: Service
metadata:name: admin-servicenamespace: production
spec:type: NodePort selector:app: adminenv: productionports:- protocol: TCPport: 28888 targetPort: 28888 nodePort: 31000 滾動更新:
只有修改了 deployment 配置文件中的 template 中的屬性后,才會觸發更新操作修改 nginx 版本號
kubectl set image deployment/nginx-deployment nginx = nginx:1.9.1kubectl set image deployment/admin-production *harbor地址*/*項目名稱*/admin= 44 -sit-202505231400或者通過 kubectl edit deployment/nginx-deployment 進行修改查看滾動更新的過程
kubectl rollout status deploy < deployment_name> 查看部署描述,最后展示發生的事件列表也可以看到滾動更新過程
kubectl describe deploy < deployment_name> 通過 kubectl get deployments 獲取部署信息,UP-TO-DATE 表示已經有多少副本達到了配置中要求的數目通過 kubectl get rs 可以看到增加了一個新的 rs通過 kubectl get pods 可以看到所有 pod 關聯的 rs 變成了新的回滾:
有時候你可能想回退一個Deployment,例如,當Deployment不穩定時,比如一直crash looping。默認情況下,kubernetes會在系統中保存前兩次的Deployment的rollout歷史記錄,以便你可以隨時會退(你可以修改revision history limit來更改保存的revision數)。案例:
更新 deployment 時參數不小心寫錯,如 nginx:1.9.1 寫成了 nginx:1.91
kubectl set image deployment/nginx-deploy nginx = nginx:1.91監控滾動升級狀態,由于鏡像名稱錯誤,下載鏡像失敗,因此更新過程會卡住
kubectl rollout status deployments nginx-deploy結束監聽后,獲取 rs 信息,我們可以看到新增的 rs 副本數是 2 個
kubectl get rs通過 kubectl get pods 獲取 pods 信息,我們可以看到關聯到新的 rs 的 pod,狀態處于 ImagePullBackOff 狀態為了修復這個問題,我們需要找到需要回退的 revision 進行回退
通過 kubectl rollout history deployment/nginx-deploy 可以獲取 revison 的列表通過 kubectl rollout history deployment/nginx-deploy --revision= 2 可以查看詳細信息確認要回退的版本后,可以通過 kubectl rollout undo deployment/nginx-deploy 可以回退到上一個版本也可以回退到指定的 revision
kubectl rollout undo deployment/nginx-deploy --to-revision= 2 再次通過 kubectl get deployment 和 kubectl describe deployment 可以看到,我們的版本已經回退到對應的 revison 上了可以通過設置 .spec.revisonHistoryLimit 來指定 deployment 保留多少 revison,如果設置為 0 ,則不允許 deployment 回退了。發布新版本操作流程
1 . 修改 YAML 文件
yaml
spec:template:spec:containers:- name: your-appimage: local.harbor.com/sw/sw-web:NEW_TAG ports:- containerPort: 8088
2 . 應用新配置
bash
kubectl apply -f deployment.yaml -n your-namespace
kubectl rollout status deployment/your-deployment -n your-namespace
3 . 驗證新版本
bash
kubectl get pods -n your-namespace -l app = your-app-label
kubectl logs -f < new-pod-name> -n your-namespace
kubectl exec < new-pod-name> -n your-namespace -- curl -I http://localhost:8088/web/
二、回滾操作流程
方法一:使用 Kubernetes 內置回滾(推薦)
bash
kubectl rollout history deployment/your-deployment -n your-namespace
REVISION CHANGE-CAUSE
1 Initial deployment
2 Update image to v1.2.3
3 Update image to v1.2.4 < --- 當前問題版本
kubectl rollout undo deployment/your-deployment --to-revision= 2 -n your-namespace
kubectl rollout status deployment/your-deployment -n your-namespace
方法二:通過舊版 YAML 文件回滾
bash
git checkout v1.2.3 -- deployment.yaml
kubectl apply -f deployment.yaml -n your-namespace --force
kubectl get pods -n your-namespace -l app = your-app-label
三、最佳實踐建議
1 . 版本追蹤策略
bash
git add deployment.yaml
git commit -m "Update to v1.2.4"
git tag v1.2.4
git push origin master --tags
2 . 增強部署可靠性
yaml
livenessProbe:httpGet:path: /healthzport: 8088 initialDelaySeconds: 15 periodSeconds: 20 readinessProbe:httpGet:path: /readyport: 8088 initialDelaySeconds: 5 periodSeconds: 10
3 . 自動記錄變更原因
bash
kubectl annotate deployment/your-deployment \ kubernetes.io/change-cause= "Update to v1.2.4 for feature X" \ -n your-namespace --overwrite
4 . 多環境驗證流程
bash
kubectl apply -f deployment.yaml -n test-env
curl -X POST http://your-ci-server/run-tests
kubectl apply -f deployment.yaml -n prod-env
四、常見問題排查
1 . 如果回滾失敗
bash
kubectl describe deployment/your-deployment -n your-namespace
kubectl get events -n your-namespace --sort-by= .metadata.creationTimestamp
2 . 保留歷史版本數量控制
yaml
spec:revisionHistoryLimit: 5 更新版本的時候可以添加 --record記錄操作內容
[ root@k8s-master ~]
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/web-production image updated
[ root@k8s-master ~]
deployment.apps/web-production
REVISION CHANGE-CAUSE
1 < none>
2 kubectl set image deployment/web-production web = web:v20250523_1.0.0 --namespace= production --record= true查看對應revision的更新內容
kubectl rollout history deployment/web-production -n production --revision= 2
deployment.apps/web-production with revision
Pod Template:Labels: app = webenv = productionpod-template-hash= 764cdbc6c4Annotations: kubernetes.io/change-cause: kubectl set image deployment/web-production web = web:v20250523_1.0.0 --namespace= production --record= trueContainers:web:Image: web:v20250523_1.0.0Port: 8088 /TCPHost Port: 0 /TCPLimits:cpu: 200mmemory: 1GiRequests:cpu: 100mmemory: 512MiEnvironment: < none> Mounts: < none> Volumes: < none> 版本回退操作
回退到revision 為1的版本
[ root@k8s-master ~]
deployment.apps/web-production rolled back
[ root@k8s-master ~]
deployment.apps/web-production
REVISION CHANGE-CAUSE
2 kubectl set image deployment/web-production web = web:v20250523_1.0.0 --namespace= production --record= true
3 < none>
查看回滾進度
kubectl rollout status deployment/web-production -n production擴容縮容
kubectl scale --replicas= 5 deployment web-production -n production 通過修改replicas的值完成擴容和縮容 暫停和恢復
kubectl rollout pause deploy web-production -n production
kubectl rollout resume deploy web-production -n production