云原生技术
概述
云原生是一种构建和运行应用程序的方法,充分利用云计算模型的优势。云原生应用设计为在云环境中运行,具有高可用性、可扩展性和弹性。
核心概念
什么是云原生
云原生是一种软件架构方法,专门为云环境设计,充分利用云平台的可扩展性、弹性和分布式特性。
云原生特征:
- 容器化部署
- 微服务架构
- 不可变基础设施
- 声明式API
- 自动化运维
- 可观测性
云原生 vs 传统架构
特性 | 传统架构 | 云原生架构 |
---|---|---|
部署方式 | 物理机/虚拟机 | 容器化 |
扩展性 | 手动扩展 | 自动扩展 |
故障恢复 | 手动恢复 | 自动恢复 |
资源利用 | 固定分配 | 动态分配 |
开发流程 | 瀑布式 | DevOps |
容器化技术
Docker基础
容器概念
容器是一种轻量级、可移植的软件单元,包含运行应用程序所需的所有依赖。
dockerfile
# 基础Dockerfile示例
FROM node:16-alpine
# 设置工作目录
WORKDIR /app
# 复制package文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 启动命令
CMD ["npm", "start"]
多阶段构建
dockerfile
# 多阶段构建示例
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:16-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["npm", "start"]
Docker Compose
yaml
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=postgres
depends_on:
- postgres
- redis
postgres:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:6-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
容器编排
Kubernetes基础概念
Pod: Kubernetes的最小部署单元
yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
Deployment: 管理Pod的副本
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 3000
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
Service: 暴露应用服务
yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
Ingress: 外部访问入口
yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
高级Kubernetes特性
ConfigMap和Secret
yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: "postgresql://user:pass@db:5432/myapp"
redis_url: "redis://redis:6379"
log_level: "info"
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
database_password: cGFzc3dvcmQ= # base64编码
api_key: YXBpLWtleQ==
使用ConfigMap和Secret
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-app
image: my-app:latest
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database_url
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: database_password
Horizontal Pod Autoscaler (HPA)
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
服务网格 (Service Mesh)
Istio基础
服务网格是一种基础设施层,处理服务间通信,提供负载均衡、服务发现、认证、监控等功能。
安装Istio
bash
# 下载Istio
curl -L https://istio.io/downloadIstio | sh -
# 安装到Kubernetes集群
istioctl install --set profile=demo -y
# 启用自动注入
kubectl label namespace default istio-injection=enabled
Virtual Service和Destination Rule
yaml
# virtual-service.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-app-vs
spec:
hosts:
- myapp.example.com
gateways:
- my-app-gateway
http:
- route:
- destination:
host: my-app-service
port:
number: 80
weight: 80
- destination:
host: my-app-v2-service
port:
number: 80
weight: 20
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-app-dr
spec:
host: my-app-service
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
流量管理
yaml
# 金丝雀发布
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: my-app-vs
spec:
hosts:
- myapp.example.com
http:
- route:
- destination:
host: my-app-service
subset: v1
weight: 90
- destination:
host: my-app-service
subset: v2
weight: 10
安全策略
yaml
# 认证策略
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: my-app-auth
namespace: default
spec:
selector:
matchLabels:
app: my-app
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/my-app-sa"]
to:
- operation:
methods: ["GET"]
paths: ["/api/public/*"]
- from:
- source:
namespaces: ["default"]
to:
- operation:
methods: ["POST", "PUT", "DELETE"]
paths: ["/api/admin/*"]
DevOps和CI/CD
GitOps实践
GitOps是一种持续部署方法,使用Git作为单一事实来源来管理基础设施和应用程序。
ArgoCD配置
yaml
# argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/myapp
targetRevision: HEAD
path: k8s
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
GitHub Actions CI/CD
yaml
# .github/workflows/deploy.yml
name: Deploy to Kubernetes
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: myorg/myapp:${{ github.sha }}
- name: Update kustomize
run: |
cd k8s
kustomize edit set image myorg/myapp=myorg/myapp:${{ github.sha }}
- name: Deploy to Kubernetes
run: |
kubectl apply -k k8s/
监控和可观测性
Prometheus监控
yaml
# prometheus-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: prometheus-config
data:
prometheus.yml: |
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
Grafana仪表板
json
{
"dashboard": {
"title": "Application Metrics",
"panels": [
{
"title": "Request Rate",
"type": "graph",
"targets": [
{
"expr": "rate(http_requests_total[5m])",
"legendFormat": "{{method}} {{path}}"
}
]
},
{
"title": "Response Time",
"type": "graph",
"targets": [
{
"expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))",
"legendFormat": "95th percentile"
}
]
}
]
}
}
分布式追踪 (Jaeger)
yaml
# jaeger-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: jaeger
spec:
replicas: 1
selector:
matchLabels:
app: jaeger
template:
metadata:
labels:
app: jaeger
spec:
containers:
- name: jaeger
image: jaegertracing/all-in-one:latest
ports:
- containerPort: 16686
- containerPort: 14268
env:
- name: COLLECTOR_OTLP_ENABLED
value: "true"
云原生存储
持久化存储
yaml
# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-storage
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: fast-ssd
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-app
image: my-app:latest
volumeMounts:
- name: app-storage
mountPath: /app/data
volumes:
- name: app-storage
persistentVolumeClaim:
claimName: app-storage
对象存储
javascript
// 使用MinIO对象存储
const Minio = require('minio');
const minioClient = new Minio.Client({
endPoint: 'minio.example.com',
port: 9000,
useSSL: true,
accessKey: 'your-access-key',
secretKey: 'your-secret-key'
});
// 上传文件
async function uploadFile(bucketName, objectName, filePath) {
await minioClient.fPutObject(bucketName, objectName, filePath);
console.log('File uploaded successfully');
}
// 下载文件
async function downloadFile(bucketName, objectName, filePath) {
await minioClient.fGetObject(bucketName, objectName, filePath);
console.log('File downloaded successfully');
}
云原生安全
网络安全策略
yaml
# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-network-policy
spec:
podSelector:
matchLabels:
app: my-app
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
ports:
- protocol: TCP
port: 3000
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
RBAC权限控制
yaml
# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: app-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-role-binding
namespace: default
subjects:
- kind: ServiceAccount
name: my-app-sa
namespace: default
roleRef:
kind: Role
name: app-role
apiGroup: rbac.authorization.k8s.io
最佳实践
1. 12-Factor应用原则
- 代码库: 一个代码库对应一个应用
- 依赖: 显式声明依赖关系
- 配置: 通过环境变量管理配置
- 后端服务: 将后端服务视为附加资源
- 构建、发布、运行: 严格分离构建和运行阶段
- 进程: 应用以无状态进程运行
- 端口绑定: 通过端口绑定提供服务
- 并发: 通过进程模型进行扩展
- 易处理: 快速启动和优雅关闭
- 开发/生产环境等价: 保持开发和生产环境相似
- 日志: 将日志视为事件流
- 管理进程: 将管理任务作为一次性进程运行
2. 容器最佳实践
dockerfile
# 安全最佳实践
FROM node:16-alpine
# 创建非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
WORKDIR /app
# 复制package文件
COPY package*.json ./
# 安装依赖
RUN npm ci --only=production && npm cache clean --force
# 复制应用代码
COPY --chown=nodejs:nodejs . .
# 切换到非root用户
USER nodejs
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["npm", "start"]
3. Kubernetes最佳实践
yaml
# 资源限制
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-app
image: my-app:latest
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
4. 监控最佳实践
javascript
// 应用指标收集
const prometheus = require('prom-client');
// 注册指标
const register = new prometheus.Registry();
prometheus.collectDefaultMetrics({ register });
// 自定义指标
const httpRequestDuration = new prometheus.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.1, 0.5, 1, 2, 5]
});
const httpRequestsTotal = new prometheus.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code']
});
register.registerMetric(httpRequestDuration);
register.registerMetric(httpRequestsTotal);
// 中间件
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = (Date.now() - start) / 1000;
httpRequestDuration
.labels(req.method, req.route?.path || req.path, res.statusCode)
.observe(duration);
httpRequestsTotal
.labels(req.method, req.route?.path || req.path, res.statusCode)
.inc();
});
next();
});
// 指标端点
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
总结
云原生技术是现代软件开发和部署的核心,它提供了:
- 容器化: 一致的运行环境
- 编排: 自动化的部署和管理
- 服务网格: 智能的服务间通信
- DevOps: 自动化的开发和运维流程
- 监控: 全面的可观测性
- 安全: 多层次的安全防护
通过采用云原生技术,企业可以:
- 提高应用的可靠性和可扩展性
- 降低运维成本
- 加快开发和部署速度
- 提升资源利用率
- 增强安全性
云原生不是一蹴而就的,需要逐步迁移和优化,但长期来看,它将为企业带来巨大的竞争优势。