Kubernetes Pod控制器与配置资源管理
Kubernetes Pod控制器与配置资源管理详解
- 一、Pod控制器
- 1. Pod控制器概述
- 2. Pod控制器的类型
- 3. Deployment控制器
- 4. StatefulSet控制器(有状态)
- 5. DaemonSet控制器
- 6. Job控制器
- 7. CronJob控制器
- 8. 无状态 vs 有状态应用对比
- 9. 常规Service与Headless Service对比
- 10. 服务发现机制
- 11. 总结
- 二、配置资源管理
- 1. Secret(密钥管理)
- 2. ConfigMap(配置管理)
- 3. 总结对比表
- 结语
在现代云原生应用开发中,Kubernetes(简称K8s)已成为容器编排的事实标准。它不仅提供了强大的容器管理能力,还通过一系列控制器和配置资源,简化了应用的部署、扩展和管理。本文将深入探讨Kubernetes中的Pod控制器与配置资源管理,帮助读者全面理解并掌握这些关键技术。
一、Pod控制器
Pod控制器,也称为工作负载(Workload),是Kubernetes中用于管理Pod的中间层。其主要职责是确保集群中的Pod资源始终符合用户定义的“期望状态”。通过Pod控制器,用户可以轻松实现Pod的自动化管理,包括副本数量的维护、异常恢复、伸缩、滚动更新和回滚等功能。
1. Pod控制器概述
Pod控制器是Kubernetes的核心组件之一,它负责管理和维护Pod的生命周期。通过Pod控制器,用户可以定义Pod的期望状态,如副本数量、更新策略等,而Kubernetes则会自动调整实际状态以匹配期望状态。
2. Pod控制器的类型
Kubernetes提供了多种类型的Pod控制器,以满足不同应用场景的需求。以下是几种常见的Pod控制器及其功能和应用场景:
- ReplicaSet:保证指定数量的Pod副本存在,支持滚动扩缩容。通常不直接使用,而是由Deployment管理。适用于无状态应用。
- Deployment:管理ReplicaSet,实现声明式部署、滚动升级、回滚等。适用于Web服务等无状态应用。
- StatefulSet:管理有状态应用,提供稳定的网络标识与存储。适用于数据库、Zookeeper等有状态应用。
- DaemonSet:确保每个Node上运行一个Pod。常用于运行系统级后台任务,如日志收集、监控代理等。
- Job:执行一次性任务。适用于数据迁移、批处理等任务。
- CronJob:周期性任务(类似Crontab)。适用于定期备份、定时通知等任务。
3. Deployment控制器
Deployment控制器是Kubernetes中最常用的控制器之一,用于管理无状态应用。它支持滚动更新与回滚,提供声明式配置更新,并与ReplicaSet协作使用。
特点:
- 管理无状态应用。
- 支持滚动更新与回滚。
- 声明式配置更新。
- 与ReplicaSet协作使用。
案例:通过YAML文件定义一个Deployment,创建三个Nginx Pod副本,并使用kubectl
命令进行部署和管理。
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentlabels:app: nginx
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.15.4ports:- containerPort: 80
-----------------------------------------------------------------------
kubectl create -f nginx-deployment.yaml
kubectl get pods,deploy,rs
kubectl edit deployment/nginx-deployment
kubectl rollout history deployment nginx-deployment
4. StatefulSet控制器(有状态)
StatefulSet控制器用于管理有状态应用,提供稳定的网络标识与存储。与Deployment不同,StatefulSet中的每个Pod都有固定的名称和DNS记录,适用于需要稳定标识和独立存储的应用,如数据库和Zookeeper。
特点:
- 稳定存储:基于PVC实现,每个Pod独立存储。
- 稳定网络标识:Pod名称和DNS名称固定。
- 有序部署/删除:从0到N-1创建,从N-1到0删除。
- 依赖Headless Service。
案例:通过定义Headless Service和StatefulSet,创建三个带有独立存储的Pod副本,并进行滚动更新。
---
# -------------------------------
# 1. Namespace(推荐,隔离资源)
# -------------------------------
apiVersion: v1
kind: Namespace
metadata:name: nfs-client
---
# -------------------------------
# 2. ServiceAccount
# -------------------------------
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisionernamespace: nfs-client
---
# -------------------------------
# 3. ClusterRole
# -------------------------------
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: nfs-client-provisioner-runner
rules:- 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: ["list", "watch", "create", "update", "patch"]- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
# -------------------------------
# 4. ClusterRoleBinding
# -------------------------------
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: run-nfs-client-provisioner
subjects:- kind: ServiceAccountname: nfs-client-provisionernamespace: nfs-client
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io
---
# -------------------------------
# 5. StorageClass(关键!名称为 nfs-client-storageclass)
# -------------------------------
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclassnamespace: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # ? 官方 provisioner 标识
parameters:archiveOnDelete: "false"
---
# -------------------------------
# 6. Deployment(使用官方镜像)
# -------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisionernamespace: nfs-client
spec:replicas: 1strategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: k8s-sigs.io/nfs-subdir-external-provisioner- name: NFS_SERVERvalue: 192.168.10.10 # ? 改成你的 NFS 服务器 IP,如 192.168.1.100- name: NFS_PATHvalue: /opt/k8s # ? 改成你的 NFS 共享目录,如 /data/nfsvolumes:- name: nfs-client-rootnfs:server: 192.168.10.10 # ? 与 NFS_SERVER 一致path: /opt/k8s
---------------------------------------------------------------------------------
apiVersion: v1
kind: Service
metadata:name: myapp-svc
spec:ports:- port: 80name: webclusterIP: Noneselector:app: myapp-pod
-----------------------------------------------------------------
apiVersion: apps/v1
kind: StatefulSet
metadata:name: myapp
spec:serviceName: myapp-svcreplicas: 3selector:matchLabels:app: myapp-podtemplate:metadata:labels:app: myapp-podspec:containers:- name: myappimage: ikubernetes/myapp:v1ports:- containerPort: 80name: webvolumeMounts:- name: myappdatamountPath: /usr/share/nginx/htmlvolumeClaimTemplates:- metadata:name: myappdataannotations:volume.beta.kubernetes.io/storage-class: nfs-client-storageclassspec:accessModes: ["ReadWriteOnce"]resources:requests:storage: 2Gi
kubectl edit sts myapp #修改版本保存
kubectl get pods -w
5. DaemonSet控制器
DaemonSet控制器确保每个Node上都运行一个Pod副本,常用于运行系统级后台任务,如日志收集和监控代理。
功能:
-
确保每个Node上运行一个Pod副本。
-
典型场景包括Fluentd、Logstash日志收集,Prometheus监控代理等。
案例:通过YAML文件定义一个DaemonSet,在每个Node上创建一个Nginx Pod。
apiVersion: apps/v1
kind: DaemonSet
metadata:name: nginx-daemonsetlabels:app: nginx
spec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.15.4ports:- containerPort: 80
6. Job控制器
Job控制器用于执行一次性任务,任务完成后即退出。适用于数据迁移、批处理、安全扫描等任务。
特点:
- 执行一次性任务。
- 任务完成后Pod自动终止。
案例:通过YAML文件定义一个Job,计算圆周率并输出结果。
apiVersion: batch/v1
kind: Job
metadata:name: pi
spec:template:spec:containers:- name: piimage: perlcommand: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]restartPolicy: NeverbackoffLimit: 4
kubectl get pod
kubectl logs pi-[name]
apiVersion: batch/v1
kind: Job
metadata:name: busybox
spec:template:spec:containers:- name: busyboximage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh", "-c", "sleep 10;date;exit 1"]restartPolicy: NeverbackoffLimit: 2
7. CronJob控制器
CronJob控制器用于执行周期性任务,类似于Linux的Crontab。适用于定期备份、定时通知、日志清理等任务。
特点:
- 周期性任务。
- 类似于Linux的Crontab。
案例:通过YAML文件定义一个CronJob,每分钟打印一次“Hello from the Kubernetes cluster”。
apiVersion: batch/v1beta1
kind: CronJob
metadata:name: hello
spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: helloimage: busyboxargs:- /bin/sh- c - date; echo Hello from the Kubernetes clusterrestartPolicy: OnFailure
8. 无状态 vs 有状态应用对比
无状态应用(如Deployment)和有状态应用(如StatefulSet)在Pod名称、存储、网络标识、扩缩容顺序和应用示例等方面存在显著差异。无状态应用适用于Web服务和API,而有状态应用适用于数据库和Zookeeper等需要稳定存储和网络标识的应用。
9. 常规Service与Headless Service对比
常规Service和Headless Service在是否有ClusterIP、访问方式和作用方面有所不同。常规Service提供负载均衡和服务发现,适用于集群统一访问入口;而Headless Service直接解析到Pod IP,适用于StatefulSet中的DNS定位。
10. 服务发现机制
Kubernetes内置的DNS机制通过Pod名称、Service名称和Namespace等信息,实现Pod间的通信。服务发现机制的演变从SkyDNS到KubeDNS,再到现在的CoreDNS,提供了稳定可靠的DNS解析服务。
11. 总结
Kubernetes提供了多种Pod控制器,以满足不同应用场景的需求。通过合理选择和使用这些控制器,用户可以实现应用的高效部署、管理和扩展。以下是各控制器的简要总结:
- Deployment:无状态应用部署、滚动升级。
- ReplicaSet:保证副本数量,通常由Deployment管理。
- StatefulSet:有状态应用,稳定网络与存储。
- DaemonSet:每个节点运行一个Pod。
- Job:一次性任务。
- CronJob:周期性任务。
二、配置资源管理
在Kubernetes中,配置资源管理是确保应用安全和高效运行的重要组成部分。通过Secret和ConfigMap,用户可以分别管理敏感信息和普通配置数据,实现应用配置的灵活管理和安全存储。
1. Secret(密钥管理)
Secret用于保存敏感数据,如密码、Token和密钥。通过将敏感信息与Pod分离,Secret降低了数据泄露的风险,并提供了安全的访问控制。
Secret类型:
- kubernetes.io/service-account-token:用于访问APIServer,Pod默认挂载在特定路径。
- Opaque:默认类型,用于用户自定义密码、密钥等(Base64编码)。
- kubernetes.io/dockerconfigjson:存储私有Docker Registry的认证信息。
- kubernetes.io/tls:存储SSL/TLS证书与私钥。
创建和使用Secret: - 命令行创建:通过
kubectl create secret
命令创建Secret。
echo -n "nh" > username.txt
echo -n "123455" >password.txt
kubectl create secret generic myst --from-file=username.txt --from-file=password.txt
kubectl get secrets
kubectl describe secret myst
- YAML文件创建:通过Base64编码的YAML文件创建Secret。
apiVersion: v1
kind: Secret
metadata:name: mysecret1
type: Opaque
data:username: bmg=password: YWJjMTIzNA==
- 使用方式:作为Volume文件挂载、导入环境变量或kubelet拉取镜像时使用认证信息。
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: nginximage: nginxvolumeMounts:- name: secretsmountPath: "/etc/secrets"readOnly: truevolumes:- name: secretssecret:secretName: myst
apiVersion: v1
kind: Pod
metadata:name: mypod1
spec:containers:- name: nginximage: nginxenv:- name: TEST_USERvalueFrom:secretKeyRef:name: mysecret1key: username - name: TEST_PASSWORDvalueFrom:secretKeyRef:name: mysecret1key: password
2. ConfigMap(配置管理)
ConfigMap用于存储非敏感配置数据,如配置文件、命令行参数或环境变量。通过ConfigMap,用户可以实现应用配置的灵活管理和动态更新。
创建ConfigMap:
- 从目录创建:通过指定目录创建ConfigMap。
mkdir /opt/configmap/
vim /opt/configmap/game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
vim /opt/configmap/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
- 从文件创建:通过指定文件创建ConfigMap。
kubectl create configmap game-config-2 \--from-file=/opt/configmap/game.properties \--from-file=/opt/configmap/ui.properties
- 使用字面值:通过字面值直接创建ConfigMap。
kubectl create configmap special-config \--from-literal=special.how=very \--from-literal=special.type=good
在Pod中使用ConfigMap:
- 作为环境变量注入:将ConfigMap中的键值对作为环境变量注入Pod。
vim env.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: special-confignamespace: default
data:special.how: veryspecial.type: good
---
apiVersion: v1
kind: ConfigMap
metadata:name: env-confignamespace: default
data:log_level: INFO
======================================================================================
kubectl apply -f env.yaml kubectl get cm
NAME DATA AGE
env-config 1 6s
special-config 2 6s
==============================================================
#Pod的创建
vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:containers:- name: busyboximage: busybox:1.28.4command: ["/bin/sh", "-c", "env"]env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Never
-------------------------------------------------------------------------------------
kubectl logs test-pod
- 命令行参数使用:将ConfigMap中的键值对作为命令行参数使用。
apiVersion: v1
kind: Pod
metadata:name: test-pod2
spec:containers:- name: busyboximage: busybox:1.28.4command: - /bin/sh- -c- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY)"env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Never
- 以Volume形式挂载:将ConfigMap中的数据挂载为Volume,供Pod访问。
apiVersion: v1
kind: Pod
metadata:name: test-pod3
spec:containers:- name: busyboximage: busybox:1.28.4command: [ "/bin/sh", "-c", "sleep 36000" ]volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: special-configrestartPolicy: Never
ConfigMap热更新机制:通过修改ConfigMap,可以实现配置的热更新,但环境变量不会自动更新。通过手动触发滚动更新,可以实现Pod的配置更新。
apiVersion: v1
kind: ConfigMap
metadata:name: log-confignamespace: default
data:log_level: INFO
---
apiVersion: apps/v1
kind: Deployment
metadata:name: my-nginx
spec:replicas: 1selector:matchLabels:app: my-nginxtemplate:metadata:labels:app: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: log-config
3. 总结对比表
项目 | Secret | ConfigMap |
---|---|---|
存储内容 | 敏感信息(密码、密钥) | 普通配置信息 |
数据编码 | Base64 | 纯文本 |
使用方式 | Volume、Env、镜像拉取凭证 | Volume、Env、命令参数 |
是否自动更新 | Volume 延迟更新,Env 不会 | Volume 延迟更新,Env 不会 |
安全性 | 高(需 RBAC 控制) | 普通 |
结语
Kubernetes的Pod控制器与配置资源管理是其强大功能的核心组成部分。通过合理使用Pod控制器,用户可以实现应用的高效部署、管理和扩展;通过配置资源管理,用户可以确保应用的安全性和配置的灵活性。希望本文能够帮助读者深入理解Kubernetes的这些关键技术,为构建稳定、高效的云原生应用提供有力支持。随着Kubernetes生态的不断发展,掌握这些基础知识将为我们在云原生领域的探索和实践奠定坚实的基础。