对于刚接触 Kubernetes (K8s) 的同学来说,理解不同的工作负载类型(Workloads)常常是一个挑战。本文将以英雄联盟 (LOL) 中的英雄角色为类比,帮助大家更形象地理解 K8s 中 Deployment、StatefulSet、DaemonSet、Job 和 CronJob 的作用和使用场景,并深入探讨它们在实际生产环境中的应用,比如 Nginx 的部署,以及如何通过宝塔面板进行简化管理。
Deployment:灵活的 ADC - 如探险家伊泽瑞尔
Deployment 是 K8s 中最常用的工作负载类型,用于部署无状态应用。它可以控制 Pod 的副本数量,并提供滚动更新、回滚等功能。我们可以将 Deployment 比作 LOL 中的 ADC(Attack Damage Carry),比如探险家伊泽瑞尔。ADC 的特点是灵活,输出稳定,Deployment 也是如此。
底层原理:ReplicaSet 的管理者
Deployment 本身并不直接管理 Pod,而是通过 ReplicaSet 来管理。ReplicaSet 负责维护 Pod 的副本数量,并确保 Pod 在出现故障时能够自动重启。Deployment 相当于 ReplicaSet 的管理者,可以创建、更新和删除 ReplicaSet。
配置示例:部署 Nginx 服务
以下是一个简单的 Deployment 示例,用于部署 Nginx 服务:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # 定义 3 个副本
selector:
matchLabels:
app: nginx # 通过 label 选择 Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest # 使用 Nginx 最新镜像
ports:
- containerPort: 80 # 暴露 80 端口
实战避坑:滚动更新策略
在生产环境中,滚动更新策略非常重要。K8s 提供了两种滚动更新策略:RollingUpdate 和 Recreate。RollingUpdate 策略会逐步替换旧的 Pod,而 Recreate 策略会先删除所有旧的 Pod,然后再创建新的 Pod。在选择滚动更新策略时,需要根据应用的特点进行选择。如果应用对停机时间敏感,应选择 RollingUpdate 策略。
StatefulSet:可靠的辅助 - 如众星之子索拉卡
StatefulSet 用于部署有状态应用,例如数据库、消息队列等。StatefulSet 会为每个 Pod 分配一个唯一的标识符,并保证 Pod 的顺序部署和删除。我们可以将 StatefulSet 比作 LOL 中的辅助,比如众星之子索拉卡。辅助的特点是为团队提供保护和支持,StatefulSet 也是如此。
底层原理:稳定持久的身份
StatefulSet 通过 Headless Service 和 VolumeClaimTemplate 来实现有状态应用的部署。Headless Service 不会分配 Cluster IP,而是通过 DNS 为每个 Pod 创建一个域名。VolumeClaimTemplate 用于为每个 Pod 创建持久化存储,保证数据不会丢失。
配置示例:部署 MySQL 集群
以下是一个简单的 StatefulSet 示例,用于部署 MySQL 集群:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql" # 指定 Headless Service
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7 # 使用 MySQL 5.7 镜像
env:
- name: MYSQL_ROOT_PASSWORD
value: "password" # 设置 root 密码
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql # 挂载数据卷
volumeClaimTemplates:
- metadata:
name: mysql-data # 定义数据卷模板
spec:
accessModes: [ "ReadWriteOnce" ] # 定义访问模式
resources:
requests:
storage: 10Gi # 定义存储大小
实战避坑:存储卷的正确使用
在使用 StatefulSet 部署有状态应用时,必须正确配置存储卷。需要根据应用的特点选择合适的存储卷类型,并保证存储卷的容量足够大。此外,还需要注意备份和恢复数据。
DaemonSet:全图支援的战士 - 如武器大师贾克斯
DaemonSet 用于在每个节点上运行一个 Pod。DaemonSet 通常用于部署监控 Agent、日志收集 Agent 等。我们可以将 DaemonSet 比作 LOL 中的战士,比如武器大师贾克斯。战士的特点是能打能抗,全图支援,DaemonSet 也是如此。
底层原理:节点级别的守护者
DaemonSet 会在每个节点上创建一个 Pod,并保证 Pod 在节点重启后能够自动启动。DaemonSet 可以通过 NodeSelector 来选择在哪些节点上运行 Pod。
配置示例:部署 Fluentd 日志收集 Agent
以下是一个简单的 DaemonSet 示例,用于部署 Fluentd 日志收集 Agent:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
containers:
- name: fluentd
image: fluent/fluentd:latest # 使用 Fluentd 最新镜像
volumeMounts:
- name: varlog
mountPath: /var/log # 挂载 /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
实战避坑:资源限制的合理设置
在使用 DaemonSet 部署 Agent 时,需要合理设置资源限制。如果资源限制设置不合理,可能会导致节点资源耗尽。
Job 和 CronJob:精准打击的刺客 - 如影流之主劫
Job 用于运行一次性任务,例如数据迁移、备份等。CronJob 用于定期运行任务,例如定时备份、清理日志等。我们可以将 Job 和 CronJob 比作 LOL 中的刺客,比如影流之主劫。刺客的特点是精准打击,完成目标任务,Job 和 CronJob 也是如此。
底层原理:任务的执行者
Job 会创建一个或多个 Pod 来执行任务,并等待所有 Pod 完成后自动删除。CronJob 会根据 Cron 表达式定期创建 Job。
配置示例:定时备份数据库
以下是一个简单的 CronJob 示例,用于每天凌晨 3 点备份数据库:
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-db
spec:
schedule: "0 3 * * *" # Cron 表达式,每天凌晨 3 点
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: busybox # 使用 busybox 镜像
command: ["sh", "-c", "mysqldump -u root -pPASSWORD db > /backup/db.sql"]
volumeMounts:
- name: backup-volume
mountPath: /backup
restartPolicy: OnFailure # 任务失败时重启 Pod
volumes:
- name: backup-volume
emptyDir: {}
实战避坑:任务失败的处理
在使用 Job 和 CronJob 时,需要考虑任务失败的处理。可以通过设置 restartPolicy 来控制 Pod 在任务失败时是否重启。此外,还需要记录任务执行日志,方便排查问题。
总结:选择适合你的英雄
本文通过 LOL 英雄类比的方式,介绍了 K8s 中常用的工作负载类型。希望能够帮助大家更形象地理解这些概念,并在实际生产环境中选择合适的 Workloads。理解 K8s 不同工作负载对应LOL里哪位英雄,能帮助开发者更好的理解其应用场景,从而选择最适合自己项目需求的方案。例如,如果需要部署一个高可用、无状态的 Web 应用,可以选择 Deployment;如果需要部署一个有状态的数据库集群,可以选择 StatefulSet;如果需要在每个节点上运行一个日志收集 Agent,可以选择 DaemonSet;如果需要运行一次性任务,可以选择 Job;如果需要定期运行任务,可以选择 CronJob。
冠军资讯
脱发程序员