容器技术已成为现代应用部署的标准,从开发测试到生产环境,容器化带来了前所未有的敏捷性和可扩展性。本文将深入探讨Docker与Kubernetes在生产环境中的实战应用。
![图片[1]-Linux容器技术深度实战:Docker与Kubernetes生产环境部署指南](https://blogimg.vcvcc.cc/2025/11/20251119084502528-1024x768.png?imageView2/0/format/webp/q/75)
一、Docker高级应用与生产优化
(1) 多阶段构建与镜像优化
# 生产级Dockerfile示例
# 阶段1: 构建环境
FROM node:18-alpine AS builder
# 安装构建依赖
RUN apk add --no-cache \
python3 \
make \
g++ \
git
# 设置工作目录
WORKDIR /app
# 复制package文件
COPY package*.json ./
COPY yarn.lock ./
# 安装依赖(利用Docker缓存层)
RUN yarn install --frozen-lockfile --production=false
# 复制源代码
COPY . .
# 运行测试和构建
RUN yarn test
RUN yarn build
# 阶段2: 生产环境
FROM node:18-alpine AS production
# 安装运行时依赖
RUN apk add --no-cache \
curl \
tini
# 使用tini作为初始化进程
ENTRYPOINT ["/sbin/tini", "--"]
# 创建非root用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
# 设置工作目录
WORKDIR /app
# 从构建阶段复制构建结果
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
# 切换到非root用户
USER nextjs
# 暴露端口
EXPOSE 3000
# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1
# 启动应用
CMD ["yarn", "start"]
# 阶段3: 安全扫描(可选)
FROM aquasec/trivy:latest AS security
COPY --from=production /app /app
RUN trivy filesystem --exit-code 1 --no-progress /
(2) 生产环境Docker Compose配置
# docker-compose.prod.yml
version: '3.8'
x-logging: <strong>&default-logging</strong>
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "production"
services:
# 前端应用
webapp:
build:
context: .
target: production
args:
- NODE_ENV=production
image: my-registry/webapp:${TAG:-latest}
container_name: webapp-prod
restart: unless-stopped
logging: <strong>*default-logging</strong>
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
- JWT_SECRET=${JWT_SECRET}
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
reservations:
memory: 256M
cpus: '0.5'
networks:
- frontend
- backend
# Nginx反向代理
nginx:
image: nginx:1.23-alpine
container_name: nginx-prod
restart: unless-stopped
logging: <strong>*default-logging</strong>
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/ssl:/etc/nginx/ssl:ro
- ./logs/nginx:/var/log/nginx
depends_on:
webapp:
condition: service_healthy
healthcheck:
test: ["CMD", "nginx", "-t"]
interval: 30s
timeout: 10s
retries: 3
networks:
- frontend
# Redis缓存
redis:
image: redis:7-alpine
container_name: redis-prod
restart: unless-stopped
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
logging: <strong>*default-logging</strong>
volumes:
- redis_data:/data
- ./redis/redis.conf:/etc/redis/redis.conf:ro
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 10s
timeout: 3s
retries: 3
deploy:
resources:
limits:
memory: 256M
cpus: '0.5'
networks:
- backend
# PostgreSQL数据库
postgres:
image: postgres:15-alpine
container_name: postgres-prod
restart: unless-stopped
logging: <strong>*default-logging</strong>
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgres/backups:/backups
- ./postgres/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
deploy:
resources:
limits:
memory: 1G
cpus: '1.0'
networks:
- backend
# 监控服务
prometheus:
image: prom/prometheus:latest
container_name: prometheus-prod
restart: unless-stopped
logging: <strong>*default-logging</strong>
ports:
- "9090:9090"
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=30d'
- '--web.enable-lifecycle'
networks:
- monitoring
# 日志收集
loki:
image: grafana/loki:main
container_name: loki-prod
restart: unless-stopped
logging: <strong>*default-logging</strong>
ports:
- "3100:3100"
volumes:
- ./loki/loki-config.yml:/etc/loki/local-config.yaml:ro
- loki_data:/loki
command: -config.file=/etc/loki/local-config.yaml
networks:
- monitoring
volumes:
redis_data:
driver: local
postgres_data:
driver: local
prometheus_data:
driver: local
loki_data:
driver: local
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
backend:
driver: bridge
ipam:
config:
- subnet: 172.21.0.0/16
monitoring:
driver: bridge
ipam:
config:
- subnet: 172.22.0.0/16
二、Kubernetes生产集群部署
(1) 高可用Kubernetes集群初始化
<strong>#!/bin/bash</strong>
# k8s-cluster-init.sh
# Kubernetes生产集群初始化脚本
set -euo pipefail
# 配置变量
CLUSTER_NAME="production-cluster"
K8S_VERSION="1.28.2"
POD_NETWORK_CIDR="10.244.0.0/16"
SERVICE_CIDR="10.96.0.0/12"
API_SERVER_VIP="192.168.1.100"
MASTER_NODES=("k8s-master-01" "k8s-master-02" "k8s-master-03")
WORKER_NODES=("k8s-worker-01" "k8s-worker-02" "k8s-worker-03")
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARNING] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}"
exit 1
}
# 系统准备
prepare_system() {
log "准备系统环境..."
# 禁用Swap
swapoff -a
sed -i '/swap/d' /etc/fstab
# 加载内核模块
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 配置sysctl参数
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# 安装容器运行时
install_container_runtime
}
install_container_runtime() {
log "安装容器运行时..."
# 安装Docker
apt-get update
apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
# 配置containerd
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml
# 使用systemd cgroup驱动
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl enable docker
systemctl start docker
}
# 安装Kubernetes组件
install_kubernetes() {
log "安装Kubernetes组件..."
# 添加Kubernetes仓库
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get install -y kubelet=$K8S_VERSION-1.1 kubeadm=$K8S_VERSION-1.1 kubectl=$K8S_VERSION-1.1
apt-mark hold kubelet kubeadm kubectl
systemctl enable kubelet
}
# 初始化控制平面
init_control_plane() {
local node_name=$1
local is_first_master=$2
log "在 $node_name 上初始化控制平面..."
if [ "$is_first_master" = "true" ]; then
# 第一个控制平面节点
kubeadm init \
--control-plane-endpoint "$API_SERVER_VIP:6443" \
--upload-certs \
--pod-network-cidr="$POD_NETWORK_CIDR" \
--service-cidr="$SERVICE_CIDR" \
--kubernetes-version "$K8S_VERSION" \
--ignore-preflight-errors=all
# 配置kubectl
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 安装网络插件
install_network_plugin
# 生成加入命令
generate_join_commands
else
# 其他控制平面节点
kubeadm join $API_SERVER_VIP:6443 \
--token $(cat /tmp/kubeadm-token) \
--discovery-token-ca-cert-hash $(cat /tmp/kubeadm-ca-cert-hash) \
--control-plane \
--certificate-key $(cat /tmp/kubeadm-certificate-key)
fi
}
# 安装网络插件
install_network_plugin() {
log "安装Calico网络插件..."
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
# 等待Calico就绪
kubectl wait --for=condition=ready pod -l k8s-app=calico-node -n kube-system --timeout=300s
}
# 生成加入命令
generate_join_commands() {
log "生成节点加入命令..."
# 获取token
kubeadm token create --print-join-command > /tmp/worker-join-command.sh
# 获取证书key
kubeadm init phase upload-certs --upload-certs | tail -1 > /tmp/certificate-key
# 生成控制平面加入命令
local join_command=$(cat /tmp/worker-join-command.sh)
local cert_key=$(cat /tmp/certificate-key)
echo "kubeadm join $API_SERVER_VIP:6443 \
--token $(echo $join_command | awk '{print $5}') \
--discovery-token-ca-cert-hash $(echo $join_command | awk '{print $7}') \
--control-plane \
--certificate-key $cert_key" > /tmp/controlplane-join-command.sh
chmod +x /tmp/*-join-command.sh
}
# 安装存储类
install_storage_class() {
log "安装存储类..."
# 安装NFS客户端 provisioner
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: nfs-storage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: nfs-storage
labels:
app: nfs-client-provisioner
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.1.50
- name: NFS_PATH
value: /data/nfs
volumes:
- name: nfs-client-root
nfs:
server: 192.168.1.50
path: /data/nfs
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: nfs-storage
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: nfs-storage
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "false"
EOF
}
# 安装监控栈
install_monitoring_stack() {
log "安装监控栈..."
# 创建监控命名空间
kubectl create namespace monitoring
# 安装Prometheus
kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/main/manifests/setup/*
kubectl apply -f https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/main/manifests/*
# 安装Grafana
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: grafana-pvc
namespace: monitoring
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: nfs-client
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grafana
namespace: monitoring
spec:
replicas: 1
selector:
matchLabels:
app: grafana
template:
metadata:
labels:
app: grafana
spec:
containers:
- name: grafana
image: grafana/grafana:latest
ports:
- name: http
containerPort: 3000
protocol: TCP
volumeMounts:
- name: grafana-storage
mountPath: /var/lib/grafana
- name: grafana-datasources
mountPath: /etc/grafana/provisioning/datasources
volumes:
- name: grafana-storage
persistentVolumeClaim:
claimName: grafana-pvc
- name: grafana-datasources
configMap:
name: grafana-datasources
---
apiVersion: v1
kind: Service
metadata:
name: grafana
namespace: monitoring
spec:
type: NodePort
ports:
- port: 3000
targetPort: 3000
nodePort: 30000
selector:
app: grafana
---
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-datasources
namespace: monitoring
data:
prometheus.yaml: |
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus-k8s.monitoring.svc:9090
access: proxy
isDefault: true
EOF
}
# 主初始化流程
main() {
local node_type=$1
local node_name=$2
case $node_type in
"master")
prepare_system
install_kubernetes
if [ "$node_name" = "${MASTER_NODES[0]}" ]; then
init_control_plane "$node_name" "true"
install_storage_class
install_monitoring_stack
else
init_control_plane "$node_name" "false"
fi
;;
"worker")
prepare_system
install_kubernetes
# 执行worker加入命令
bash /tmp/worker-join-command.sh
;;
*)
error "未知节点类型: $node_type"
;;
esac
log "节点 $node_name 初始化完成"
}
# 脚本入口
if [ $# -eq 2 ]; then
main "$1" "$2"
else
echo "用法: $0 {master|worker} 节点名称"
exit 1
fi
三、Kubernetes应用部署实战
(1) 完整的微服务部署配置
# k8s/applications/webapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: production
labels:
app: webapp
version: v1.0.0
spec:
replicas: 3
revisionHistoryLimit: 3
selector:
matchLabels:
app: webapp
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: webapp
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "3000"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: webapp-sa
securityContext:
runAsNonRoot: <strong>true</strong>
runAsUser: 1001
fsGroup: 1001
containers:
- name: webapp
image: my-registry/webapp:${IMAGE_TAG}
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
protocol: TCP
env:
- name: NODE_ENV
value: "production"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: database-url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: redis-url
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: app-secrets
key: jwt-secret
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 1
startupProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 10
volumeMounts:
- name: config-volume
mountPath: /app/config
- name: tmp-volume
mountPath: /tmp
volumes:
- name: config-volume
configMap:
name: webapp-config
- name: tmp-volume
emptyDir: {}
tolerations:
- key: "node.kubernetes.io/arch"
operator: "Equal"
value: "amd64"
effect: "NoSchedule"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- webapp
topologyKey: "kubernetes.io/hostname"
---
# Service配置
apiVersion: v1
kind: Service
metadata:
name: webapp-service
namespace: production
labels:
app: webapp
spec:
selector:
app: webapp
ports:
- name: http
port: 80
targetPort: 3000
protocol: TCP
type: ClusterIP
---
# Ingress配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: webapp-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp-service
port:
number: 80
---
# HPA配置
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapp-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
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
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 60
(2) 数据库有状态应用部署
# k8s/databases/postgresql-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql
namespace: production
spec:
serviceName: "postgresql"
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
spec:
serviceAccountName: postgresql-sa
securityContext:
runAsUser: 999
runAsGroup: 999
fsGroup: 999
containers:
- name: postgresql
image: postgres:15-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5432
protocol: TCP
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: postgresql-secrets
key: database-name
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgresql-secrets
key: username
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgresql-secrets
key: password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1"
livenessProbe:
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U $POSTGRES_USER
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
exec:
command:
- /bin/sh
- -c
- -e
- |
exec pg_isready -U $POSTGRES_USER
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
volumeMounts:
- name: postgresql-data
mountPath: /var/lib/postgresql/data
- name: postgresql-config
mountPath: /etc/postgresql
volumes:
- name: postgresql-config
configMap:
name: postgresql-config
volumeClaimTemplates:
- metadata:
name: postgresql-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "nfs-client"
resources:
requests:
storage: 50Gi
---
# PostgreSQL服务
apiVersion: v1
kind: Service
metadata:
name: postgresql
namespace: production
spec:
selector:
app: postgresql
ports:
- name: postgresql
port: 5432
targetPort: 5432
protocol: TCP
type: ClusterIP
---
# 数据库备份CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: postgresql-backup
namespace: production
spec:
schedule: "0 2 * * *" # 每天凌晨2点
concurrencyPolicy: Forbid
startingDeadlineSeconds: 600
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:15-alpine
command:
- /bin/bash
- -c
- |
set -e
PGPASSWORD=$POSTGRES_PASSWORD pg_dump -h postgresql -U $POSTGRES_USER $POSTGRES_DB > /backup/backup-$(date +%Y%m%d-%H%M%S).sql
find /backup -name "backup-*.sql" -mtime +7 -delete
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgresql-secrets
key: password
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: postgresql-secrets
key: username
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: postgresql-secrets
key: database-name
volumeMounts:
- name: backup-storage
mountPath: /backup
restartPolicy: OnFailure
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: postgresql-backup-pvc
四、服务网格与高级流量管理
(1) Istio服务网格配置
# k8s/istio/webapp-virtualservice.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: webapp
namespace: production
spec:
hosts:
- "app.example.com"
gateways:
- production-gateway
http:
- name: "primary-route"
match:
- headers:
x-canary-release:
exact: "false"
route:
- destination:
host: webapp-service
subset: v1
weight: 100
- name: "canary-route"
match:
- headers:
x-canary-release:
exact: "true"
route:
- destination:
host: webapp-service
subset: v2
weight: 100
- route:
- destination:
host: webapp-service
subset: v1
weight: 90
- destination:
host: webapp-service
subset: v2
weight: 10
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: webapp
namespace: production
spec:
host: webapp-service
subsets:
- name: v1
labels:
version: v1.0.0
- name: v2
labels:
version: v1.1.0
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
maxRequestsPerConnection: 10
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 30s
maxEjectionPercent: 50
---
# 熔断器配置
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: redis-circuit-breaker
namespace: production
spec:
host: redis-service
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
connectTimeout: 30ms
http:
http1MaxPendingRequests: 1024
maxRequestsPerConnection: 1024
outlierDetection:
consecutive5xxErrors: 7
interval: 5m
baseEjectionTime: 15m
总结
容器化技术为现代应用部署带来了革命性的变化。通过合理的Docker镜像优化、Kubernetes集群部署和服务网格配置,可以构建出高可用、可扩展且易于维护的云原生应用架构。
核心最佳实践:
- 镜像优化:多阶段构建、非root用户、最小化基础镜像
- 集群部署:高可用控制平面、合理的资源分配、网络策略
- 应用部署:适当的健康检查、资源限制、滚动更新策略
- 流量管理:金丝雀发布、熔断器、负载均衡
- 监控运维:完善的监控体系、日志收集、自动备份
【进阶方向】
探索GitOps工作流(如ArgoCD)、服务网格高级特性(如Istio的安全策略)、以及Serverless架构在Kubernetes上的实现。
© 版权声明
THE END













暂无评论内容