我正在使用 Kubernetes Continuous Deploy Plugin 在 Kubernetes 集群上部署和升级 Deployment。 我正在使用管道,这是 Jenkinsfile:
pipeline {
environment {
JOB_NAME = "${JOB_NAME}".replace("-deploy", "")
REGISTRY = "my-docker-registry"
}
agent any
stages {
stage('Fetching kubernetes config files') {
steps {
git 'git_url_of_k8s_configurations'
}
}
stage('Deploy on kubernetes') {
steps {
kubernetesDeploy(
kubeconfigId: 'k8s-default-namespace-config-id',
configs: 'deployment.yml',
enableConfigSubstitution: true
)
}
}
}
}
Deployment.yml 改为:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ${JOB_NAME}
spec:
replicas: 1
template:
metadata:
labels:
build_number: ${BUILD_NUMBER}
app: ${JOB_NAME}
role: rolling-update
spec:
containers:
- name: ${JOB_NAME}-container
image: ${REGISTRY}/${JOB_NAME}:latest
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: postgres
imagePullSecrets:
- name: regcred
strategy:
type: RollingUpdate
为了让 Kubernetes 了解 Deployment 已更改(以便升级它和 Pod),我使用 Jenkins 内部版本号作为注释:
...
metadata:
labels:
build_number: ${BUILD_NUMBER}
...
问题还是我的误解:
如果 Kubernetes 上不存在 Deployment,则一切正常,创建一个 Deployment 和一个 ReplicaSet。
如果 Deployment 仍然存在并且应用了升级,Kubernetes 将创建一个新的 ReplicaSet:
首次部署之前
首次部署
第二次部署
第三次部署
如您所见,每个新的 Jenkins 部署都会正确更新部署,但会创建一个新的 ReplicaSet,而不删除旧的 ReplicaSet。
可能是什么问题?
这是预期的行为。每次更新 Deployment 时,都会创建一个新的 ReplicaSet。但是,旧的 ReplicaSet 将被保留,以便您可以在更新的 Deployment 出现任何问题时回滚到之前的状态。
参考:更新部署
但是,您可以通过
spec.revisionHistoryLimit
字段限制保留多少个 ReplicaSet。默认值为 10。参考:RevisionHistoryLimit
管道示例
pipeline {
agent any
tools {nodejs "node"}
environment {
CI = 'true'
PROJECT_ID = 'marshmallow'
CLUSTER_NAME = 'cluster-1'
LOCATION = 'us-central1-c'
CREDENTIALS_ID = 'kubernetes'
DOCKER_FILE_PATH="${FOLDER_NAME}/Dockerfile"
SERVICE_NAME='auth'
FOLDER_NAME='prod-config'
K8_FILE_PATH="${FOLDER_NAME}/k8.yaml"
IMAGE_TAG = "us.gcr.io/${PROJECT_ID}/${SERVICE_NAME}:${env.BUILD_NUMBER}"
}
stages {
stage('Scm Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
dir("${SERVICE_NAME}/"){
sh 'npm install'
}
}
}
stage('Build Docker Image') {
steps {
sh 'whoami'
script {
dockerImage = docker.build("${IMAGE_TAG}","-f ${SERVICE_NAME}/${DOCKER_FILE_PATH} ${SERVICE_NAME}")
}
}
}
stage("Push Docker Image") {
steps {
script {
echo "Push Docker Image"
docker.withRegistry('https://us.gcr.io', "gcr:google-container-registry") {
dockerImage.push()
}
}
}
}
stage('Change image version') {
steps {
dir("${SERVICE_NAME}/prod-config"){
sh """
cat k8.yaml | grep image
sed -i 's|image: .*|image: "${IMAGE_TAG}"|' k8.yaml
cat k8.yaml | grep image
"""
}
}
}
stage('Deploy to K8s') {
steps{
echo "Deployment started ..."
sh 'ls -ltr'
sh 'pwd'
echo "Start deployment of ${SERVICE_NAME} service."
step([
$class: 'KubernetesEngineBuilder',
projectId: env.PROJECT_ID,
clusterName: env.CLUSTER_NAME,
location: env.LOCATION,
manifestPattern: "${SERVICE_NAME}/${K8_FILE_PATH}",
credentialsId: env.CREDENTIALS_ID,
// verifyDeployments: true
])
echo "Deployment Finished ..."
}
}
}
post {
always {
echo "Deleting docker iamge ..."
sh "docker rmi -f ${IMAGE_TAG}"
}
}
}