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