在现代云原生应用开发中,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-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - 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-provisioner
  namespace: 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: ServiceAccount
    name: nfs-client-provisioner
    namespace: nfs-client
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
# -------------------------------
# 5. StorageClass(关键!名称为 nfs-client-storageclass)
# -------------------------------
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client-storageclass
  namespace: 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-provisioner
  namespace: nfs-client
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          imagePullPolicy: IfNotPresent
          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.10.10    # ? 改成你的 NFS 服务器 IP,如 192.168.1.100
            - name: NFS_PATH
              value: /opt/k8s          # ? 改成你的 NFS 共享目录,如 /data/nfs
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.10.10 # ? 与 NFS_SERVER 一致
            path: /opt/k8s
---------------------------------------------------------------------------------
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: myapp-pod
-----------------------------------------------------------------
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp
spec:
  serviceName: myapp-svc
  replicas: 3
  selector:
    matchLabels:
      app: myapp-pod
  template:
    metadata:
      labels:
        app: myapp-pod
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: myappdata
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: myappdata
      annotations:
        volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
    spec:
      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-daemonset
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

在这里插入图片描述

6. Job控制器

Job控制器用于执行一次性任务,任务完成后即退出。适用于数据迁移、批处理、安全扫描等任务。
特点

  • 执行一次性任务。
  • 任务完成后Pod自动终止。

案例:通过YAML文件定义一个Job,计算圆周率并输出结果。

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl","-Mbignum=bpi","-wle","print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4
kubectl get pod
kubectl logs pi-[name]

在这里插入图片描述

apiVersion: batch/v1
kind: Job
metadata:
  name: busybox
spec:
  template:
    spec:
      containers:
        - name: busybox
          image: busybox
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]
      restartPolicy: Never
  backoffLimit: 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: hello
            image: busybox
            args:
            - /bin/sh
            - c 
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: 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: nginx
    image: nginx
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
  volumes:
  - name: secrets
    secret:
      secretName: myst
apiVersion: v1
kind: Pod
metadata:
  name: mypod1
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: TEST_USER
        valueFrom:
          secretKeyRef:
            name: mysecret1
            key: username 
      - name: TEST_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret1
            key: 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-config
  namespace: default
data:
  special.how: very
  special.type: good
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: 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: busybox
    image: busybox:1.28.4
    command: ["/bin/sh", "-c", "env"]
    env:
      - name: SPECIAL_HOW_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.how
      - name: SPECIAL_TYPE_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.type
    envFrom:
      - configMapRef:
          name: env-config
  restartPolicy: Never
-------------------------------------------------------------------------------------
kubectl logs test-pod

在这里插入图片描述

  • 命令行参数使用:将ConfigMap中的键值对作为命令行参数使用。
apiVersion: v1
kind: Pod
metadata:
  name: test-pod2
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: 
	- /bin/sh
	- -c
	- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY)"
    env:
      - name: SPECIAL_HOW_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.how
      - name: SPECIAL_TYPE_KEY
        valueFrom:
          configMapKeyRef:
            name: special-config
            key: special.type
    envFrom:
      - configMapRef:
          name: env-config
  restartPolicy: Never

在这里插入图片描述

  • 以Volume形式挂载:将ConfigMap中的数据挂载为Volume,供Pod访问。
apiVersion: v1
kind: Pod
metadata:
  name: test-pod3
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    command: [ "/bin/sh", "-c", "sleep 36000" ]
    volumeMounts:
    - name: config-volume
      mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
  restartPolicy: Never

在这里插入图片描述
ConfigMap热更新机制:通过修改ConfigMap,可以实现配置的热更新,但环境变量不会自动更新。通过手动触发滚动更新,可以实现Pod的配置更新。

apiVersion: v1
kind: ConfigMap
metadata:
  name: log-config
  namespace: default
data:
  log_level: INFO
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-nginx
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: log-config

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-rewrite
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: http://www1.nh.com:30558
spec:
  rules:
  - host: re.nh.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          # 仅用于跳转,svc 名可随意
          service:
            name: nginx-svc
            port:
              number: 80

3. 总结对比表

项目SecretConfigMap
存储内容敏感信息(密码、密钥)普通配置信息
数据编码Base64纯文本
使用方式Volume、Env、镜像拉取凭证Volume、Env、命令参数
是否自动更新Volume 延迟更新,Env 不会Volume 延迟更新,Env 不会
安全性高(需 RBAC 控制)普通

结语

Kubernetes的Pod控制器与配置资源管理是其强大功能的核心组成部分。通过合理使用Pod控制器,用户可以实现应用的高效部署、管理和扩展;通过配置资源管理,用户可以确保应用的安全性和配置的灵活性。希望本文能够帮助读者深入理解Kubernetes的这些关键技术,为构建稳定、高效的云原生应用提供有力支持。随着Kubernetes生态的不断发展,掌握这些基础知识将为我们在云原生领域的探索和实践奠定坚实的基础。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐