CI/CD 持续集成与持续部署
约 1240 字大约 4 分钟
CI/CD 持续集成与持续部署
CI/CD基础概念 🟢
1. 什么是CI/CD
CI/CD(持续集成/持续部署)是一种通过自动化流程来频繁地向客户交付应用的方法。它主要包含以下几个方面:
- 持续集成(CI):
- 频繁地将代码集成到主干
- 自动化构建和测试
- 及早发现集成问题
- 保证代码质量
- 持续交付(CD):
- 自动化构建部署流程
- 随时可以部署到生产环境
- 手动触发部署
- 确保部署过程的可靠性
- 持续部署(CD):
- 完全自动化的部署流程
- 代码变更自动部署到生产
- 无需人工干预
- 快速交付新功能
2. CI/CD工具链
- 代码管理:
- Git
- SVN
- GitLab
- GitHub
- 构建工具:
- Jenkins
- GitLab CI
- GitHub Actions
- CircleCI
- 制品管理:
- NPM
- Docker Registry
- Nexus
- Artifactory
- 部署工具:
- Docker
- Kubernetes
- Ansible
- Terraform
CI/CD实践详解 🟡
1. GitHub Actions配置
GitHub Actions是GitHub提供的自动化工作流工具,以下是详细配置示例:
# .github/workflows/main.yml
name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
env:
NODE_VERSION: '16.x'
DOCKER_REGISTRY: ghcr.io
APP_NAME: my-app
jobs:
# 代码质量检查
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Run TypeScript check
run: npm run type-check
# 单元测试
test:
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test:ci
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
# 构建和推送Docker镜像
build:
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
${{ env.DOCKER_REGISTRY }}/${{ github.repository_owner }}/${{ env.APP_NAME }}:${{ github.sha }}
${{ env.DOCKER_REGISTRY }}/${{ github.repository_owner }}/${{ env.APP_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
# 部署到开发环境
deploy-dev:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
environment: development
steps:
- uses: actions/checkout@v3
- name: Install kubectl
uses: azure/setup-kubectl@v3
- name: Set Kubernetes context
uses: azure/k8s-set-context@v3
with:
kubeconfig: ${{ secrets.KUBE_CONFIG_DEV }}
- name: Deploy to Kubernetes
run: |
# 替换镜像标签
sed -i "s|IMAGE_TAG|${{ github.sha }}|g" k8s/dev/*.yaml
# 应用Kubernetes配置
kubectl apply -f k8s/dev/
# 等待部署完成
kubectl rollout status deployment/${{ env.APP_NAME }} -n development
# 部署到生产环境
deploy-prod:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v3
- name: Install kubectl
uses: azure/setup-kubectl@v3
- name: Set Kubernetes context
uses: azure/k8s-set-context@v3
with:
kubeconfig: ${{ secrets.KUBE_CONFIG_PROD }}
- name: Deploy to Kubernetes
run: |
# 替换镜像标签
sed -i "s|IMAGE_TAG|${{ github.sha }}|g" k8s/prod/*.yaml
# 应用Kubernetes配置
kubectl apply -f k8s/prod/
# 等待部署完成
kubectl rollout status deployment/${{ env.APP_NAME }} -n production
2. Docker配置
Docker用于容器化应用,以下是配置示例:
# 构建阶段
FROM node:16-alpine as builder
WORKDIR /app
# 安装依赖
COPY package*.json ./
RUN npm ci
# 构建应用
COPY . .
RUN npm run build
# 运行阶段
FROM nginx:alpine
# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html
# 复制Nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget -q --spider http://localhost/ || exit 1
# 暴露端口
EXPOSE 80
# 启动Nginx
CMD ["nginx", "-g", "daemon off;"]
3. Kubernetes配置
Kubernetes用于容器编排和应用部署,以下是配置示例:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: my-app
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: ghcr.io/owner/my-app:IMAGE_TAG
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
env:
- name: NODE_ENV
value: production
- name: API_URL
valueFrom:
configMapKeyRef:
name: my-app-config
key: api_url
volumeMounts:
- name: config
mountPath: /app/config
volumes:
- name: config
configMap:
name: my-app-config
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app
namespace: production
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: production
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- example.com
secretName: my-app-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80
监控和告警 🔴
1. Prometheus监控配置
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'frontend'
static_configs:
- targets: ['frontend:80']
metrics_path: '/metrics'
scheme: 'http'
relabel_configs:
- source_labels: [__address__]
target_label: instance
regex: '(.*):.*'
replacement: '${1}'
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
alerting:
alertmanagers:
- static_configs:
- targets: ['alertmanager:9093']
rule_files:
- 'alert.rules.yml'
2. Grafana仪表盘配置
{
"annotations": {
"list": []
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus"
},
"expr": "rate(http_requests_total[5m])",
"refId": "A"
}
],
"title": "HTTP Request Rate",
"type": "timeseries"
}
],
"refresh": "5s",
"schemaVersion": 38,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Frontend Dashboard",
"version": 0,
"weekStart": ""
}
通过以上内容,我们详细介绍了CI/CD的各个方面,包括:
- CI/CD的基本概念和工具链
- GitHub Actions的完整配置
- Docker和Kubernetes的部署配置
- 监控和告警系统的搭建
这些内容可以帮助团队建立完整的CI/CD流程,实现自动化部署和监控。