Docker 和 Kubernetes 部署最佳实践 2027:构建可靠的容器化应用
·
Docker 和 Kubernetes 部署最佳实践 2027:构建可靠的容器化应用
1. 容器化的核心概念
容器化是一种轻量级的虚拟化技术,它允许应用程序及其依赖项被打包到一个标准化的单元中,称为容器。Docker 是最流行的容器化平台,而 Kubernetes 则是最流行的容器编排平台。
1.1 容器化的优势
- 一致性:容器在任何环境中都以相同的方式运行
- 隔离性:容器之间相互隔离,提高安全性
- 可移植性:容器可以在不同的环境中轻松移动
- 资源效率:容器比虚拟机更轻量,占用更少的资源
- 快速部署:容器可以在几秒钟内启动和停止
2. Docker 最佳实践
2.1 Dockerfile 优化
# 使用官方基础镜像
FROM openjdk:25-jdk-slim
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY pom.xml .
COPY mvnw .
COPY .mvn .mvn
# 下载依赖
RUN ./mvnw dependency:go-offline
# 复制源代码
COPY src src
# 构建应用
RUN ./mvnw package -DskipTests
# 暴露端口
EXPOSE 8080
# 运行应用
CMD ["java", "-jar", "target/app.jar"]
2.2 多阶段构建
# 构建阶段
FROM maven:3.9-eclipse-temurin-25 as builder
WORKDIR /app
COPY . .
RUN mvn package -DskipTests
# 运行阶段
FROM eclipse-temurin:25-jre-slim
WORKDIR /app
COPY --from=builder /app/target/app.jar .
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
2.3 镜像管理
- 使用官方镜像:优先使用官方基础镜像
- 固定版本:指定具体的镜像版本,避免使用 latest 标签
- 定期更新:定期更新基础镜像,获取安全补丁
- 镜像大小:使用 Alpine 等轻量级基础镜像
- 镜像扫描:使用工具扫描镜像中的安全漏洞
3. Kubernetes 部署最佳实践
3.1 部署配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
labels:
app: user-service
spec:
replicas: 3
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
spec:
containers:
- name: user-service
image: user-service:1.0.0
ports:
- containerPort: 8080
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "200m"
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
env:
- name: SPRING_PROFILES_ACTIVE
value: "production"
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database.url
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: database.password
3.2 服务配置
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 80
targetPort: 8080
type: ClusterIP
3.3 配置管理
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.url: "jdbc:mysql://mysql:3306/app"
redis.url: "redis://redis:6379"
spring.profiles.active: "production"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
database.password: c2VjcmV0
redis.password: c2VjcmV0
4. 水平扩展
4.1 自动缩放
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: user-service-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: user-service
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
4.2 手动缩放
# 手动缩放副本数
kubectl scale deployment user-service --replicas=5
# 查看部署状态
kubectl get deployments
5. 服务发现与负载均衡
5.1 服务发现
- DNS 服务发现:Kubernetes 内置 DNS 服务,通过服务名称解析 IP 地址
- 环境变量:Kubernetes 为每个服务创建环境变量
- 服务网格:使用 Istio 等服务网格增强服务发现能力
5.2 负载均衡
- ClusterIP:默认类型,仅在集群内部访问
- NodePort:在每个节点上开放一个端口,外部可访问
- LoadBalancer:使用云提供商的负载均衡器
- Ingress:管理外部访问
6. 存储管理
6.1 存储类型
- EmptyDir:临时存储,Pod 重启后数据丢失
- HostPath:使用节点上的文件系统
- PersistentVolumeClaim:持久化存储
- ConfigMap:存储配置信息
- Secret:存储敏感信息
6.2 持久化存储
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: root.password
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc
7. CI/CD 集成
7.1 GitHub Actions 配置
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 25
uses: actions/setup-java@v3
with:
java-version: '25'
distribution: 'temurin'
- name: Build with Maven
run: mvn clean package -DskipTests
- name: Build Docker image
run: docker build -t user-service:${{ github.sha }} .
- name: Login to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Push Docker image
run: |
docker tag user-service:${{ github.sha }} user-service:latest
docker push user-service:${{ github.sha }}
docker push user-service:latest
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Kubectl
uses: azure/setup-kubectl@v3
- name: Configure Kubernetes context
run: |
echo "${{ secrets.KUBE_CONFIG }}" > kubeconfig.yml
kubectl config use-context my-cluster
- name: Update deployment
run: |
kubectl set image deployment/user-service user-service=user-service:${{ github.sha }}
kubectl rollout status deployment/user-service
7.2 GitLab CI/CD 配置
# .gitlab-ci.yml
stages:
- build
- test
- deploy
build:
stage: build
image: maven:3.9-eclipse-temurin-25
script:
- mvn clean package -DskipTests
- docker build -t user-service:${CI_COMMIT_SHA} .
- docker tag user-service:${CI_COMMIT_SHA} user-service:latest
- docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}
- docker push user-service:${CI_COMMIT_SHA}
- docker push user-service:latest
test:
stage: test
image: maven:3.9-eclipse-temurin-25
script:
- mvn test
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- echo "${KUBE_CONFIG}" > kubeconfig.yml
- kubectl config use-context my-cluster
- kubectl set image deployment/user-service user-service=user-service:${CI_COMMIT_SHA}
- kubectl rollout status deployment/user-service
environment:
name: production
only:
- main
8. 监控与日志
8.1 监控配置
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: user-service-monitor
namespace: monitoring
spec:
selector:
matchLabels:
app: user-service
endpoints:
- port: http
path: /actuator/prometheus
interval: 15s
---
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: user-service-pod-monitor
namespace: monitoring
spec:
selector:
matchLabels:
app: user-service
podMetricsEndpoints:
- port: http
path: /actuator/prometheus
interval: 15s
8.2 日志管理
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.14-debian-elasticsearch7
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.monitoring.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
9. 安全最佳实践
9.1 容器安全
- 使用官方镜像:避免使用不可信的镜像
- 最小化镜像:只包含必要的组件
- 非 root 用户:使用非 root 用户运行容器
- 限制权限:使用最小权限原则
- 镜像扫描:定期扫描镜像中的安全漏洞
9.2 网络安全
- 网络策略:限制容器间通信
- TLS 加密:使用 HTTPS
- 防火墙:配置适当的防火墙规则
- 入侵检测:使用入侵检测系统
9.3 集群安全
- RBAC:使用基于角色的访问控制
- ** secrets 管理**:使用 secrets 存储敏感信息
- Pod 安全策略:限制 Pod 的权限
- 定期审计:定期审计集群配置
10. 实际应用案例
10.1 微服务部署
# 部署多个微服务
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: order-service:1.0.0
ports:
- containerPort: 8080
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "200m"
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service
ports:
- port: 80
targetPort: 8080
type: ClusterIP
10.2 数据库部署
# 部署 MySQL 数据库
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secrets
key: root.password
- name: MYSQL_DATABASE
value: "app"
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
clusterIP: None
11. 总结与最佳实践
11.1 最佳实践
- 容器化:使用 Docker 容器化应用,提高部署一致性
- 镜像管理:使用官方镜像,定期更新,扫描漏洞
- Kubernetes 部署:使用 Deployment、Service、ConfigMap 等资源
- 水平扩展:使用 HPA 实现自动缩放
- 服务发现:使用 Kubernetes 内置的服务发现机制
- 存储管理:使用 PersistentVolumeClaim 管理持久化存储
- CI/CD 集成:实现自动化的构建和部署
- 监控与日志:使用 Prometheus、Grafana、ELK 等工具
- 安全:从容器、网络、集群层面加强安全措施
- 备份与恢复:定期备份数据,制定恢复策略
11.2 注意事项
- 资源配置:合理配置容器的资源请求和限制
- 健康检查:配置适当的 readiness 和 liveness 探针
- 滚动更新:使用滚动更新策略,减少服务中断
- 命名规范:使用统一的命名规范,提高可维护性
- 文档:编写详细的部署文档,便于团队协作
别叫我大神,叫我 Alex 就好。这其实可以更优雅一点,通过合理使用 Docker 和 Kubernetes,我们可以构建出更可靠、更高效的容器化应用。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)