
java后台
创建harbor镜像拉取Secret:
kubectl create secret docker-registry harbor-regcred \
--docker-server= \
--docker-username= \
--docker-password= \
-n production
Dockerfile
FROM *harbor地址*/library/custom-jdk:1.8.0-alpine
LABEL 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/app
WORKDIR /home
ARG JAR_PATH
COPY ${JAR_PATH} /home/backend/jar_28888/admin.jar
VOLUME /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 any
parameters {
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 {
// 安全登录Harbor
sh "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-production
namespace: production
labels:
app: admin
env: production
spec:
replicas: 2
revisionHistoryLimit: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
selector:
matchLabels:
app: admin
env: production
template:
metadata:
labels:
app: admin
env: production
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: admin
image: *代码仓库地址/项目名称*/admin:44-sit-202505231400
ports:
- containerPort: 28888
volumeMounts:
- name: etc-volume
mountPath: /home/backend/etc
readOnly: true
resources:
limits:
cpu: "1"
memory: 1Gi
requests:
cpu: "0.5"
memory: 512Mi
livenessProbe:
httpGet:
path: /admin/captchaImage
port: 28888
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /admin/captchaImage
port: 28888
initialDelaySeconds: 20
periodSeconds: 5
volumes:
- name: etc-volume
hostPath:
path: /tmp/etc
type: DirectoryOrCreate
imagePullSecrets:
- name: harbor-regcred
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values: ["admin"]
topologyKey: kubernetes.io/hostname
apiVersion: v1
kind: Service
metadata:
name: admin-service
namespace: production
spec:
type: NodePort
selector:
app: admin
env: production
ports:
- protocol: TCP
port: 28888
targetPort: 28888
nodePort: 31000
滚动更新:
只有修改了 deployment 配置文件中的 template 中的属性后,才会触发更新操作
修改 nginx 版本号
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
kubectl 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-app
image: 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: /healthz
port: 8088
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /ready
port: 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=web
env=production
pod-template-hash=764cdbc6c4
Annotations: kubernetes.io/change-cause: kubectl set image deployment/web-production web=web:v20250523_1.0.0 --namespace=production --record=true
Containers:
web:
Image: web:v20250523_1.0.0
Port: 8088/TCP
Host Port: 0/TCP
Limits:
cpu: 200m
memory: 1Gi
Requests:
cpu: 100m
memory: 512Mi
Environment: <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