云其它

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > 云其它 > k8s之Pod控制器

k8s之Pod控制器使用及说明

作者:刘艳芬_

本文介绍了Kubernetes中的Pod控制器,包括Deployment、ReplicaSet、StatefulSet、DaemonSet、Job和CronJob等类型,详细解释了它们的工作原理、特点和应用场景

k8s之Pod控制器

一、Pod控制器

1、pod控制器类型

1.1 ReplicaSet

ReplicaSet主要三个组件组成

帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。

1.2 Deployment
1.3 DaemonSet
1.4 StatefulSet
1.5 Job
1.6 Cronjob

2、Pod与控制器之间的关系

二、使用POD控制器

1、Deployment

1.1 创建控制器
kubectl create deployment deploy --image=nginx:1.18 --port=80 --replicas=1 --dry-run=client -oyaml > deploy.yaml
#生成yaml配置文件模板

#修改yaml配置文件
vim deploy.yaml
apiVersion: apps/v1
#指定API版本
kind: Deployment
#指定创建资源类型为Deployment
metadata:
#定义资源的元数据信息
  name: nginx-deploy
  #指定资源的名称
  labels:
  #设置标签
    app: nginx
    #标签以键值表示,标签键为app,标签值为nginx
spec:
#定义资源的规格
  replicas: 1
  #指定创建pod数量为1个
  selector:
  #选择由Deployment管理的Pod的标签选择器
    matchLabels:
    #指定用于匹配的标签
      app: nginx
      #设置标签需要与模板标签一致
  template:
  #创建pod的模板,deployment管理的pod实例,都由此模板定义
    metadata:
    #模板的元数据信息
      labels:
      #定义pod的标签
        app: nginx
        #此处需要与deployment管理pod的标签选择器一致
    spec:
    #pod的规格信息
      containers:
      #定义pod中运行的容器列表
      - name: nginx
      #指定容器名称
        image: nginx:1.18.0
        #指定镜像版本
        ports:
        #定义端口
        - containerPort: 80
        #定义容器内部的监听端口

kubectl apply -f deploy.yaml
#创建资源

kubectl get pods,deploy,rs
#查看pod资源信息

1.2 更新版本
curl 10.244.2.116 -I
#查看版本信息(nginx版本信息是1.80版本)

#修改yaml配置文件
vim deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.20
      #修改版本号
        name: nginx
        ports:
        - containerPort: 80

kubectl apply -f deploy.yaml
#重新创建资源

1.3 查看更新的版本号
kubectl get pod -w
#另开一个终端,追踪查看pod更新过程

curl -I 10.244.1.104
#查看版本信息(nginx版本更新为1.20版本)

2、SatefulSet

StatefulSet 是 Kubernetes 中的一个资源控制器,它用于管理有状态的应用。与 Deployment 和 ReplicaSet 这样的无状态工作负载不同,StatefulSet 为每个 Pod 提供了一个稳定的、唯一的标识符,并且能够保证 Pod 的部署顺序和终止顺序。

https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
#官方文档
2.1 StatefulSet的三个关键组成部分以及其作用

StatefulSet 的设计是为了满足有状态应用的需求,这些应用通常需要持久化存储和稳定的网络标识。

2.1.1 Headless Service(无头服务)
2.1.2 VolumeClaimTemplates
2.1.3 StatefulSet 控制器

总结

这三个组件共同工作,使得 StatefulSet 能够为有状态应用提供所需的稳定性和可靠性。Headless Service 解决了网络标识的稳定性问题,VolumeClaimTemplates 解决了持久化存储的需求,而 StatefulSet 控制器则确保了 Pod 的有序管理和更新。这种设计使得 StatefulSet 成为部署和管理有状态应用的理想选择,如数据库、消息队列等。

为什么要有headless?

为什么要有volumeClainTemplate?

服务发现:就是应用服务之间相互定位的过程。

应用场景

K8S里服务发现的方式—DNS,使K8S集群能够自动关联Service资源的“名称”和“CLUSTER-IP”,从而达到服务被集群自动发现的目的。

实现K8S里DNS功能的插件

2.2 创建控制器

kubectl run busybox --image=busybox:1.28 -- sleep 36000
#创建一个busybox的pod,该容器提供一些基本的命令,主要用于测试环境

kubectl get pod busybox
#查看pod资源

kubectl exec -it busybox sh
#进入容器

/ # nslookup kubernetes
#测试svc能否正常解析,可以使用kubectl get svc查看有哪些svc(解析正常,解析kubernetes的地址为10.96.0.1)

kubectl get svc
#查看svc资源信息

2.2.1 创建svc资源
#编辑yaml配置文件
vim service.yaml
apiVersion: v1
#指定API版本
kind: Service
#创建资源类型为Service
metadata:
  name: headless-svc
  #指定service名称
  labels:
    app: headless-svc
    #设置service标签
spec:
  ports:
  - port: 80
  #service端口
    name: web
    #端口名称
    targetPort: 80
    #指定流量转发的目标端口,与pod暴露的端口一致
  clusterIP: None
  #将clusterIP地址的值设置为None,表示无IP地址,即无头模式
  selector:
  #选择管理的标签
    app: state
    #此标签需要与StatefulSet控制器管理的pod模板中定义的标签一致
  type: ClusterIP
  #设置类型为ClusterIP,此为默认设置,可以省略

kubectl apply -f service.yaml
#创建资源

kubectl get svc headless-svc
#查看资源信息

2.2.2 创建StatefulSet
#编辑yaml配置文件
vim statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
#创建资源类型为StatefulSet
metadata:
  name: state
  #指定资源名称
spec:
  serviceName: headless-svc
  #指定需要绑定的service名称
  replicas: 3
  #创建pod数量为三个
  selector:
  #标签选择器,指定StatefulSet要管理哪些pod
    matchLabels:
    #指定标签名称
      app: state
      #必须与service中selector定义的标签一致。pod含有此标签的,都会去管理
  template:
  #指定pod创建模板
    metadata:
      labels:
        app: state
        #设置pod标签,与上面标签选择器相同,StatefulSet才会管理
    spec:
      containers:
      #定义pod中运行的容器
      - name: nginx-pod
      #应当设置有状态的服务,在此以nginx为例,官方文档有MySQL示例
        image: nginx:1.18.0
        #定义镜像
        ports:
        - containerPort: 80
        #定义容器监听端口
          name: web
          #端口名称
        volumeMounts:
        #定义将存储卷卷挂载到指定目录
        - name: html
        #指定存储卷名称
          mountPath: /usr/share/nginx/html
          #挂载到此目录,此目录为nginx服务的站点目录
  volumeClaimTemplates:
  #PVC的请求模板
  - metadata:
      name: html
      #定义PVC的名称
      annotations:
        volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
        #用于指定存储类的注解。该存储类定义了用于动态卷供应的后端存储类型
    spec:
      accessModes: ["ReadWriteOnce"]
      #指定访问模式为RWO
      resources:
        requests:
          storage: 2Gi
          #指定存储卷的使用大小

kubectl apply -f statefulset.yaml 
#创建资源
长度、
kubectl get statefulsets.apps state
#查看资源信息

kubectl get pod -owide -w
#查看pod资源信息
#它会按照0到N-1的顺序去指定pod名称,一定建立,指定pod生命周期结束,否则IP地址改变,它的名称也不会改变

kubectl get pv,pvc
#查看pv/pvc资源信息

cd /nfs/k8s
#切换目录

echo "this is state-0" > default-html-state-0-pvc-5d4f3a8c-f5da-4aae-a244-1cfef9f328ec/index.html
#编辑state-0访问页面

echo "this is state-1" > default-html-state-1-pvc-23363402-a920-471e-9a1b-da43af18620d/index.html
#编辑state-1访问页面

echo "this is state-2" > default-html-state-2-pvc-754e992e-4573-408d-b78d-687f5dfd285f/index.html
#编辑state-2访问页面

由于没有ClusterIP地址,想要通过IP地址访问,只能在k8s集群中直接访问podIP

curl 10.244.2.120
curl 10.244.2.121
curl 10.244.1.109
#访问验证

2.2.3 使用service访问
kubectl exec -it busybox sh
#进入容器

/ # nslookup headless-svc
#查看dns解析
#service会通过endpoint关联到后端的pod

由于pod的IP地址是k8s集群内部的IP地址,且并没有clusterIP去绑定podIP,只有域名管理,宿主机的DNS解析,无法解析k8s集群内部的域名与地址,所以使用宿主机无法访问pod。只能通过创建pod,在pod中进行访问

kubectl run centos --image=centos:7 -- sleep 36000
#创建一个centos容器,访问service

kubectl exec -it centos sh
#进入容器

curl headless-svc
#访问验证

2.3 删除与创建

kubectl delete -f statefulset.yaml
#删除pod资源

kubectl get pod -w
#另开一个终端,跟踪查看pod资源信息

kubectl apply -f statefulset.yaml 
#重新创建资源

kubectl exec -it centos sh
#进入容器

curl headless-svc
#访问验证(重新创建之后再次访问,数据不会丢失)

kubectl exec -it busybox sh
#进入测试容器

/ # nslookup headless-svc
#测试svc解析,后端ip地址发生变化
#不论后端的IP地址如何变化,只通过DNS来解析service,从而绑定后端的IP地址,得到数据

2.4 deployment与statefulset的区别
2.4.1 应用场景
2.4.2 Pod管理
2.4.3 存储与网络
2.4.4 升级与回滚
2.4.5 扩展性

3、DaemonSet

3.1 关键特性
3.2 应用场景
https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
#官方案例(监控)
3.3 创建控制器
#编辑yaml配置文件
vim daemonset.yaml  
apiVersion: apps/v1
kind: DaemonSet
#创建资源类型为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.18.0
        ports:
        - containerPort: 80

kubectl apply -f daemonset.yaml
#创建资源

kubectl get pod -owide
#查看详细信息(DaemonSet会在每个node节点都创建一个Pod)

4、Job

4.1 主要特点
4.2 应用场景

批处理作业

数据迁移和清理

后台任务

日志打包和压缩

备份和恢复操作

其它应用场景

4.3 创建控制器
#编辑yaml配置文件
vim job.yaml
apiVersion: batch/v1
#Batch API的第一个稳定版
kind: Job
#指定创建的资源类型是Job
metadata:
  name: job
  #资源名称
spec:
  template:
    spec:
    #spec.template.spec 定义了 Pod 的规格,包括容器的名称、镜像和执行的命令
      containers:
      - name: busybox
      #容器名称
        image: busybox:1.28
        #镜像名称
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
        #perl解释器,-Mbignum=bpi模块中的子进程,使用计算功能,计算结果输出圆周率2000位的结果
      restartPolicy: Never
      #表示 Pod 失败后不会重启。
  backoffLimit: 4
  #表示 Job 在失败后最多重试 4 次

kubectl apply -f job.yaml 
#创建资源

kubectl get job
#查看job资源信息

kubectl get pod -w
#追踪查看pod资源信息

4.4 清除job资源
kubectl get job
#查看job资源信息

kubectl delete -f job.yaml 
#删除job资源

kubectl get job
#查看job资源信息

#编辑yaml配置文件
vim job-limit.yaml
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
  
kubectl apply -f job-limit.yaml
#创建资源
 
kubectl get job,pods
#查看资源信息
 
kubectl get pod -w
#追踪查看资源信息

5、CronJob

5.1 创建控制器
#编辑yaml配置文件
vim cronjob.yaml
apiVersion: batch/v1beta1
#指定 Kubernetes API 的版本
kind: CronJob
#指定资源类型为 CronJob
metadata:
#包含 CronJob 的名称
  name: hello
spec:
#包含 CronJob 的规格
  schedule: "*/1 * * * *"
  #使用 Cron 表达式定义任务的执行时间表。在这个例子中,"*/1 * * * *" 表示每分钟执行一次。
  jobTemplate:
  #定义了 Job 模板,它包含了执行任务的 Pod 规格
    spec:
      template:
        spec:
          containers:
          #定义了容器的名称、镜像和其他参数
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            args:
            #执行的命令,这里使用 /bin/sh 打印当前日期和 "Hello" 消息
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
          #设置为 OnFailure,表示只在容器失败时重启
 
 
kubectl apply -f cronjob.yaml 
#创建资源
 
kubectl get cronjob
#查看cronjob资源
 
kubectl get pods
#查看pod资源
 
kubectl logs hello-1717340820-s8n4j
#我们查看了 hello-1717225740-8nlx7 Pod 的日志,可以看到打印的日期和 "Hello" 消息。

--------------------------------------------------------------------------------------------
#解决日志查看权限问题
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous

#如果在查看日志时遇到权限问题,可以通过创建一个 clusterrolebinding 来授予 system:anonymous 用户 cluster-admin 权限。这通常不推荐,因为它会降低集群的安全性。在生产环境中,应该使用更细粒度的权限控制。
-------------------------------------------------------------------------------------------

Pod控制器

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文