部署、自动化、监控详解 | 从零基础到精通 | 包含工具、流程和最佳实践
DevOps是开发(Development)和运维(Operations)的结合,目标是加快软件交付速度,提高质量,降低成本。
传统开发:
开发 -> 测试 -> 部署(手动)-> 运维
周期:数月
风险:高
反馈:慢
DevOps:
开发 -> 自动化测试 -> 自动化部署 -> 监控
周期:数天或数小时
风险:低
反馈:快1. 开发者提交代码到版本控制系统
2. 触发自动化构建
3. 运行单元测试
4. 运行集成测试
5. 代码质量检查
6. 生成构建报告
7. 反馈结果给开发者// .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build
run: npm run build
- name: Upload coverage
uses: codecov/codecov-action@v2持续交付(Continuous Delivery):
代码 -> 自动化构建 -> 自动化测试 -> 手动部署到生产
持续部署(Continuous Deployment):
代码 -> 自动化构建 -> 自动化测试 -> 自动化部署到生产// .github/workflows/cd.yml
name: CD
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Push to registry
run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker push myapp:${{ github.sha }}
- name: Deploy to production
run: |
ssh user@server 'docker pull myapp:${{ github.sha }} && docker run -d myapp:${{ github.sha }}'蓝绿部署流程:
1. 蓝环境:当前生产环境
2. 绿环境:新版本环境
3. 在绿环境上部署新版本
4. 运行测试验证
5. 切换流量到绿环境
6. 保留蓝环境作为回滚点
优点:快速切换、快速回滚
缺点:需要双倍资源金丝雀部署流程:
1. 部署新版本到少量服务器(5%)
2. 监控新版本的性能和错误率
3. 如果正常,逐步增加流量(10% -> 25% -> 50% -> 100%)
4. 如果出现问题,立即回滚
优点:降低风险、快速发现问题
缺点:部署时间长滚动部署流程:
1. 逐个停止旧版本的实例
2. 启动新版本的实例
3. 重复直到所有实例都更新
优点:无需额外资源
缺点:部署时间长、可能出现版本混合// main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "web-server"
}
}
resource "aws_security_group" "web" {
name = "web-sg"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}// playbook.yml
---
- hosts: all
become: yes
tasks:
- name: Update packages
apt:
update_cache: yes
- name: Install Node.js
apt:
name: nodejs
state: present
- name: Clone repository
git:
repo: 'https://github.com/user/repo.git'
dest: /app
- name: Install dependencies
npm:
path: /app
- name: Start application
systemd:
name: app
state: started
enabled: yes// prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
- job_name: 'app'
static_configs:
- targets: ['localhost:3000']
// docker-compose.yml
version: '3'
services:
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3000:3000"
depends_on:
- prometheus// ELK Stack
Elasticsearch: 存储日志
Logstash: 处理和转换日志
Kibana: 可视化日志
// 应用中的日志
const logger = require('winston');
logger.info('Application started');
logger.error('Database connection failed', { error: err });
logger.warn('High memory usage', { memory: process.memoryUsage() });// SonarQube - 代码质量和安全
sonar-scanner -Dsonar.projectKey=myapp
// OWASP Dependency-Check - 依赖漏洞扫描
dependency-check --project myapp --scan .
// Snyk - 依赖和容器扫描
snyk test
snyk container test myapp:latest
// Trivy - 容器镜像扫描
trivy image myapp:latest开发者提交代码
↓
GitHub Actions(CI)
├─ 运行测试
├─ 代码质量检查
├─ 构建Docker镜像
└─ 推送到Docker Registry
↓
自动化部署(CD)
├─ 拉取最新镜像
├─ 运行健康检查
└─ 更新生产环境
↓
监控和日志
├─ Prometheus收集指标
├─ Grafana可视化
└─ ELK处理日志
↓
告警和通知
└─ Slack/Email通知name: DevOps Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm install
- run: npm test
- run: npm run lint
build:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v2
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Push to Docker Hub
run: |
echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
docker push myapp:${{ github.sha }}
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to production
run: |
ssh -i ${{ secrets.SSH_KEY }} user@server 'cd /app && docker-compose pull && docker-compose up -d'
- name: Notify Slack
run: |
curl -X POST ${{ secrets.SLACK_WEBHOOK }} -d '{"text":"Deployment successful"}'DevOps是一个持续的过程。从自动化测试开始,逐步建立完整的CI/CD流程。
现在你已经掌握了DevOps的核心知识。
DevOps是一个持续学习的过程。关注行业最新动态,不断优化你的流程。