创建命名空间
1 2
| kubectl create ns jenkins kubectl create ns dev
|
创建 Jenkins 的 ServiceAccount
1 2 3 4 5
| apiVersion: v1 kind: ServiceAccount metadata: name: jenkins-sa namespace: jenkins
|
1
| kubectl apply -f jenkins-sa.yaml
|
给 Jenkins 授权操作 dev 环境
jenkins-role.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: jenkins-deploy-role namespace: dev rules: - apiGroups: ["apps"] resources: ["deployments", "replicasets"] verbs: ["get", "list", "watch", "patch", "update"]
- apiGroups: [""] resources: ["pods", "services", "configmaps"] verbs: ["get", "list", "watch"]
- apiGroups: [""] resources: ["events"] verbs: ["get", "list", "watch"]
|
jenkins-rolebinding.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: jenkins-deploy-binding namespace: dev subjects: - kind: ServiceAccount name: jenkins-sa namespace: jenkins roleRef: kind: Role name: jenkins-deploy-role apiGroup: rbac.authorization.k8s.io
|
1 2 3
| # jenkins 命名空间里的 jenkins-sa 可以操作 dev 命名空间里的 Deployment kubectl apply -f jenkins-role.yaml kubectl apply -f jenkins-rolebinding.yaml
|
部署 Jenkins 到 K8s
jenkins-deployment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| apiVersion: apps/v1 kind: Deployment metadata: name: jenkins namespace: jenkins spec: replicas: 1 selector: matchLabels: app: jenkins template: metadata: labels: app: jenkins spec: serviceAccountName: jenkins-sa containers: - name: jenkins image: jenkins/jenkins:lts ports: - containerPort: 8080 volumeMounts: - name: jenkins-home mountPath: /var/jenkins_home volumes: - name: jenkins-home emptyDir: {}
|
jenkins-service.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: v1 kind: Service metadata: name: jenkins namespace: jenkins spec: type: NodePort selector: app: jenkins ports: - port: 8080 targetPort: 8080 nodePort: 30080
|
应用
1 2
| kubectl apply -f jenkins-deployment.yaml kubectl apply -f jenkins-service.yaml
|
访问 http://节点IP:30080
注:生产环境不要用 emptyDir,要换成 PVC,否则 Jenkins 重启数据会丢。
业务项目 Deployment
假设你的服务叫 backend。
backend-deployment.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| apiVersion: apps/v1 kind: Deployment metadata: name: backend namespace: dev spec: replicas: 2 selector: matchLabels: app: backend strategy: type: RollingUpdate template: metadata: labels: app: backend spec: containers: - name: backend image: registry.cn-hangzhou.aliyuncs.com/demo/backend:init ports: - containerPort: 9999 readinessProbe: httpGet: path: /actuator/health port: 9999 initialDelaySeconds: 20 periodSeconds: 5
|
backend-service.yaml
1 2 3 4 5 6 7 8 9 10 11
| apiVersion: v1 kind: Service metadata: name: backend namespace: dev spec: selector: app: backend ports: - port: 9999 targetPort: 9999
|
应用
1 2
| kubectl apply -f backend-deployment.yaml kubectl apply -f backend-service.yaml
|
Jenkinsfile 示例
这里先用最容易理解的版本:Jenkins 负责打包,然后更新 K8s。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| pipeline { agent any
environment { APP_NAME = 'backend' NAMESPACE = 'dev' IMAGE_REPO = 'registry.cn-hangzhou.aliyuncs.com/demo/backend' IMAGE_TAG = "${BUILD_NUMBER}" IMAGE = "${IMAGE_REPO}:${IMAGE_TAG}" }
stages { stage('拉取代码') { steps { checkout scm } }
stage('Maven 打包') { steps { sh 'mvn clean package -DskipTests' } }
stage('构建并推送镜像') { steps { sh ''' echo "这里推荐用 Kaniko / BuildKit 构建镜像" echo "镜像版本: ${IMAGE}" ''' } }
stage('部署到 K8s') { steps { sh ''' kubectl set image deployment/${APP_NAME} \ ${APP_NAME}=${IMAGE} \ -n ${NAMESPACE}
kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE} ''' } } }
post { failure { sh ''' echo "发布失败,可以执行回滚:" echo "kubectl rollout undo deployment/${APP_NAME} -n ${NAMESPACE}" ''' } }
}
|
权限验证
进入 Jenkins Pod:
1
| kubectl exec -it -n jenkins deploy/jenkins -- bash
|
测试权限
1 2
| kubectl get pods -n dev kubectl get deployment -n dev
|
测试不能操作其他 namespace
1
| kubectl get pods -n kube-system
|
如果权限控制正常,这个应该会报Forbidden
整体理解
1 2 3 4 5 6 7 8 9 10 11
| Jenkins Pod ↓ serviceAccountName: jenkins-sa ↓ jenkins-sa ↓ RoleBinding ↓ jenkins-deploy-role ↓ 允许更新 dev namespace 的 Deployment
|