GitLab教程(10): GitLab与Kubernetes集成
GitLab可以与Kubernetes深度集成,实现自动化部署和环境管理。本文将介绍GitLab与Kubernetes的集成方法和部署策略。
连接Kubernetes集群
使用GitLab Agent
# 1. 在项目中创建Agent配置
# 文件: .gitlab/agents/my-agent/config.yaml
ci_access:
projects:
- id: mygroup/myproject
# 2. 注册Agent
# Project > Infrastructure > Kubernetes clusters > Connect a cluster
# 选择Agent,点击 "Register"
# 获取Agent Token
# 3. 在Kubernetes中安装Agent
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm install gitlab-agent gitlab/gitlab-agent \
--namespace gitlab-agent-my-agent \
--create-namespace \
--set config.token= \
--set config.kasAddress=wss://kas.gitlab.com
# 输出
NAME: gitlab-agent
NAMESPACE: gitlab-agent-my-agent
STATUS: deployed
REVISION: 1
# 验证安装
kubectl get pods -n gitlab-agent-my-agent
# 输出
NAME READY STATUS RESTARTS AGE
gitlab-agent-abc123-xyz 1/1 Running 0 2m
在CI/CD中访问Kubernetes
# 使用Agent访问集群
deploy:
stage: deploy
image:
name: bitnami/kubectl:latest
entrypoint: [""]
script:
- kubectl config get-contexts
- kubectl get nodes
- kubectl apply -f k8s/
rules:
- if: $CI_COMMIT_BRANCH == "main"
# CI_JOB_TOKEN自动用于Agent认证
# 无需手动配置kubeconfig
# 执行输出
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO
* gitlab-agent:my-agent ... ...
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
node-1 Ready 30d v1.28.0
node-2 Ready 30d v1.28.0
$ kubectl apply -f k8s/
deployment.apps/myapp created
service/myapp created
Kubernetes Manifest部署
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: registry.gitlab.com/mygroup/myproject:CI_COMMIT_SHA
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: production
resources:
limits:
memory: "256Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
type: ClusterIP
# .gitlab-ci.yml
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
# 替换镜像标签
- sed -i "s/CI_COMMIT_SHA/$CI_COMMIT_SHA/g" k8s/deployment.yaml
# 应用配置
- kubectl apply -f k8s/
# 等待部署完成
- kubectl rollout status deployment/myapp --timeout=300s
environment:
name: production
url: https://myapp.example.com
使用Helm部署
# Helm Chart结构
myapp-chart/
├── Chart.yaml
├── values.yaml
├── values-staging.yaml
├── values-production.yaml
└── templates/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
└── _helpers.tpl
# Chart.yaml
apiVersion: v2
name: myapp
version: 1.0.0
appVersion: "1.0"
# values.yaml
replicaCount: 2
image:
repository: registry.gitlab.com/mygroup/myproject
tag: latest
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
host: myapp.example.com
# .gitlab-ci.yml
deploy-staging:
stage: deploy
image:
name: alpine/helm:latest
entrypoint: [""]
script:
- helm upgrade --install myapp ./myapp-chart \
--namespace staging \
--create-namespace \
--set image.tag=$CI_COMMIT_SHA \
-f ./myapp-chart/values-staging.yaml
environment:
name: staging
url: https://staging.myapp.example.com
rules:
- if: $CI_COMMIT_BRANCH == "develop"
deploy-production:
stage: deploy
image:
name: alpine/helm:latest
entrypoint: [""]
script:
- helm upgrade --install myapp ./myapp-chart \
--namespace production \
--create-namespace \
--set image.tag=$CI_COMMIT_SHA \
-f ./myapp-chart/values-production.yaml \
--wait \
--timeout 10m
environment:
name: production
url: https://myapp.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
# 执行输出
$ helm upgrade --install myapp ./myapp-chart ...
Release "myapp" has been upgraded. Happy Helming!
NAME: myapp
LAST DEPLOYED: Sat Feb 8 12:00:00 2026
NAMESPACE: production
STATUS: deployed
REVISION: 5
Auto DevOps
# GitLab Auto DevOps自动提供完整的CI/CD流程
# 无需手动编写.gitlab-ci.yml
# 启用Auto DevOps
# Project > Settings > CI/CD > Auto DevOps
# 勾选 "Default to Auto DevOps pipeline"
# Auto DevOps包含:
# - 自动构建 (使用Cloud Native Buildpacks)
# - 自动测试
# - 自动代码质量检查
# - 自动安全扫描
# - 自动部署到Kubernetes
# - Review Apps
# - 自动扩缩容
# 环境变量配置
# Settings > CI/CD > Variables
# 必需变量
KUBECONFIG: (base64编码的kubeconfig)
KUBE_INGRESS_BASE_DOMAIN: example.com
# 可选变量
POSTGRES_ENABLED: "true"
AUTO_DEVOPS_CHART: stable/auto-deploy-app
REPLICAS: 3
环境管理
# 多环境部署配置
stages:
- build
- deploy
build:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
.deploy-template:
stage: deploy
image: bitnami/kubectl:latest
script:
- envsubst < k8s/deployment.yaml | kubectl apply -f -
- kubectl rollout status deployment/myapp -n $KUBE_NAMESPACE
deploy-dev:
extends: .deploy-template
variables:
KUBE_NAMESPACE: dev
environment:
name: development
url: https://dev.myapp.example.com
rules:
- if: $CI_COMMIT_BRANCH == "develop"
deploy-staging:
extends: .deploy-template
variables:
KUBE_NAMESPACE: staging
environment:
name: staging
url: https://staging.myapp.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy-production:
extends: .deploy-template
variables:
KUBE_NAMESPACE: production
environment:
name: production
url: https://myapp.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
# 查看环境
# Project > Deployments > Environments
# 环境列表
┌─────────────┬───────────────┬──────────────────┬──────────┐
│ Environment │ URL │ Last Deployment │ Status │
├─────────────┼───────────────┼──────────────────┼──────────┤
│ production │ myapp.example │ 2 hours ago │ Running │
│ staging │ staging.myapp │ 1 hour ago │ Running │
│ development │ dev.myapp │ 30 minutes ago │ Running │
└─────────────┴───────────────┴──────────────────┴──────────┘
Review Apps
# 为每个MR创建临时环境
deploy-review:
stage: deploy
image: bitnami/kubectl:latest
variables:
KUBE_NAMESPACE: review-$CI_COMMIT_REF_SLUG
script:
- kubectl create namespace $KUBE_NAMESPACE --dry-run=client -o yaml | kubectl apply -f -
- helm upgrade --install review-$CI_COMMIT_REF_SLUG ./chart \
--namespace $KUBE_NAMESPACE \
--set image.tag=$CI_COMMIT_SHA \
--set ingress.host=$CI_COMMIT_REF_SLUG.review.example.com
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.review.example.com
on_stop: stop-review
auto_stop_in: 1 week
rules:
- if: $CI_MERGE_REQUEST_IID
stop-review:
stage: deploy
image: bitnami/kubectl:latest
variables:
KUBE_NAMESPACE: review-$CI_COMMIT_REF_SLUG
GIT_STRATEGY: none
script:
- helm uninstall review-$CI_COMMIT_REF_SLUG --namespace $KUBE_NAMESPACE || true
- kubectl delete namespace $KUBE_NAMESPACE || true
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
rules:
- if: $CI_MERGE_REQUEST_IID
when: manual
# MR页面会显示Review App链接
# View app: https://feature-login.review.example.com
部署回滚
# 方式1: 通过GitLab界面回滚
# Project > Deployments > Environments > production
# 选择之前的部署 > Re-deploy
# 方式2: 通过Kubernetes回滚
rollback:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl rollout undo deployment/myapp -n production
- kubectl rollout status deployment/myapp -n production
environment:
name: production
when: manual
# 方式3: Helm回滚
rollback-helm:
stage: deploy
image: alpine/helm:latest
script:
- helm history myapp -n production
- helm rollback myapp -n production
when: manual
# Helm历史
$ helm history myapp -n production
REVISION STATUS DESCRIPTION
1 superseded Install complete
2 superseded Upgrade complete
3 superseded Upgrade complete
4 deployed Upgrade complete
Secrets管理
# 使用GitLab CI/CD变量作为Secrets
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
# 创建或更新Secret
- |
kubectl create secret generic myapp-secrets \
--from-literal=database-url="$DATABASE_URL" \
--from-literal=api-key="$API_KEY" \
--namespace production \
--dry-run=client -o yaml | kubectl apply -f -
# 部署应用
- kubectl apply -f k8s/
# 在Deployment中使用Secret
# k8s/deployment.yaml
spec:
containers:
- name: myapp
envFrom:
- secretRef:
name: myapp-secrets
# 使用External Secrets Operator
# externalsecret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: myapp-secrets
spec:
secretStoreRef:
name: gitlab-secrets
kind: ClusterSecretStore
target:
name: myapp-secrets
data:
- secretKey: database-url
remoteRef:
key: DATABASE_URL
完整示例
# 完整的Kubernetes部署Pipeline
stages:
- build
- test
- deploy
variables:
DOCKER_TLS_CERTDIR: "/certs"
build:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
test:
stage: test
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
script:
- npm run test
.kubectl-deploy:
image: bitnami/kubectl:latest
before_script:
- kubectl config get-contexts
deploy-staging:
extends: .kubectl-deploy
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n staging
- kubectl rollout status deployment/myapp -n staging --timeout=300s
environment:
name: staging
url: https://staging.myapp.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
deploy-production:
extends: .kubectl-deploy
stage: deploy
script:
- kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -n production
- kubectl rollout status deployment/myapp -n production --timeout=300s
environment:
name: production
url: https://myapp.example.com
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: manual
总结
本文介绍了GitLab与Kubernetes的集成方法,包括Agent配置、部署策略、环境管理和Review Apps。GitLab提供了完整的Kubernetes部署解决方案。
下一篇我们将学习GitLab的安全扫描功能。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。







