Kubernetes集群Pod控制器

前言

在 K8s 集群中,Pod 控制器是一种关键的组件,负责管理和控制Pod的生命周期。Pod 是 K8s 中最小的可部署单元,通常包含一个或多个容器,Pod 控制器则确保所需数量的 Pod 实例处于运行状态,并根据定义的规则进行自动扩展或缩减。本文将介绍 K8s 集群中 Pod 控制器的定义、类型以及 Pod 与控制器之间的关系。

目录

[一、Pod 控制器介绍](#一、Pod 控制器介绍)

[1. 概述及作用](#1. 概述及作用)

[2. pod 控制器的类型](#2. pod 控制器的类型)

[2.1 ReplicaSet](#2.1 ReplicaSet)

[2.2 Deployment](#2.2 Deployment)

[2.3 DaemonSet](#2.3 DaemonSet)

[2.4 StatefulSet](#2.4 StatefulSet)

[2.5 Jop](#2.5 Jop)

[2.6 CronJob](#2.6 CronJob)

[3. Pod 与控制器之间的关系](#3. Pod 与控制器之间的关系)

[二、控制器管理 Pod 示例](#二、控制器管理 Pod 示例)

[1. Deployment 部署无状态应用](#1. Deployment 部署无状态应用)

[2. SatefulSet 部署有状态应用](#2. SatefulSet 部署有状态应用)

[2.1 SatefulSet 三个组件](#2.1 SatefulSet 三个组件)

[2.2 实现 K8S 里 DNS 功能的插件](#2.2 实现 K8S 里 DNS 功能的插件)

[2.3 解析 kubernetes 和 nginx-service 名称](#2.3 解析 kubernetes 和 nginx-service 名称)

[2.4 查看 statefulset 的定义](#2.4 查看 statefulset 的定义)

[2.5 清单定义 StatefulSet](#2.5 清单定义 StatefulSet)

[2.5.1 定义资源清单](#2.5.1 定义资源清单)

[2.5.2 创建 statefulset](#2.5.2 创建 statefulset)

[2.5.3 删除 statefulset](#2.5.3 删除 statefulset)

[2.6 滚动更新](#2.6 滚动更新)

[3. DaemonSet 一次创建多节点](#3. DaemonSet 一次创建多节点)

三、总结


一、Pod 控制器介绍

1. 概述及作用

概述:

Pod 控制器是一种 K8s 对象,设计用于管理和维护 Pod 实例。它们不是直接操作 Pod,而是通过与 K8s API 交互来间接控制 Pod,从而保证即使面对节点故障、Pod 终止或其他意外情况,也能维持应用的高可用性和期望的部署配置。

作用:

自动扩缩容

  • 根据预设策略自动增加或减少Pod副本的数量,以应对负载变化或确保服务的高可用性。

自我修复

  • 当检测到Pod由于各种原因(如节点故障、容器崩溃)不再运行时,控制器会自动创建新的Pod副本以替换故障实例,保持预期的Pod数量和配置。

滚动更新

  • 在不中断服务的情况下,逐步将Pod升级到新版本的应用镜像,通过逐步替换旧Pod来平滑过渡。

版本控制

  • 管理应用的多个版本,允许快速回滚到之前的版本。

有序部署和管理

  • 对于有状态应用,如数据库,使用StatefulSet控制器来确保Pod按顺序创建和销毁,维护稳定的网络标识符和存储卷。

定时任务

  • CronJob控制器能够根据预定的计划时间自动创建Job来执行一次性任务,适用于定期执行的任务,如数据备份、报表生成等。

资源组织和命名空间管理

  • 帮助组织和隔离不同的应用或服务资源,便于团队协作和资源分配。

2. pod 控制器的类型

常见的 Pod 控制器类型包括 ReplicaSet、Deployment、DaemonSet、StatefulSet、Job 和 CronJob 等。

2.1 ReplicaSet

确保在任何给定时间都有指定数量的 Pod 副本在运行,确保 Pod 副本数量符合期望值,并且支持滚动式自动扩容和缩容功能。主要三个组件组成:

  • 用户期望的 pod 副本数量
  • 标签选择器,判断哪个 pod 归自己管理
  • 当现存的 pod 数量不足,会根据 pod 资源模板进行新建

2.2 Deployment

它建立在 ReplicaSet 之上,提供了额外的功能,如滚动更新、暂停/恢复更新、版本回滚等。

2.3 DaemonSet

确保每个节点上都运行着一个指定的 Pod 实例,比如日志收集、监控代理等。当有新的节点加入集群时,DaemonSet 会自动在新节点上创建 Pod;节点从集群移除时,对应的 Pod 也会被清理。

2.4 StatefulSet

管理有状态应用设计,如数据库、需要持久化存储和稳定的网络标识(如: CEPH)。StatefulSet 中的每个 Pod 都有唯一的、持久的标识符和稳定的存储卷。它确保 Pod 按顺序启动和关闭(理论上是倒序),且在重启后仍能访问相同的存储资源,这对于维护数据一致性至关重要。

2.5 Jop

用于运行完成特定次数后终止的 Pod,即执行一次性或批处理任务。只要完成就立即退出,不需要重启或重建。

2.6 CronJob

周期性任务控制,基于时间调度来定期执行 Job,类似于Linux的cron定时任务,不需要持续后台运行。

3. Pod 与控制器之间的关系

Controllers (控制器)是管理和运行容器的 Pod 对象的实体,在集群中,Pod 通过 Label Selector (标签与选择器)进行相关联。它们通过控制器来实现应用的运维任务,例如伸缩和升级。

可以理解为:Pod 与控制器之间是一种管理和被管理的关系,控制器利用 K8s 的标签系统来识别和控制其管理的 Pod 集合,从而实现了应用的自动化运维和高可用性。

二、控制器管理 Pod 示例

1. Deployment 部署无状态应用

部署并维护一个由3个副本组成的 Nginx 服务,管理 Pod 和 ReplicaSet;应用场景:web服务。

① 定义 yaml 配置

bash 复制代码
[root@master01 controller]# vim nginx-deployment.yaml
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.14
        ports:
        - containerPort: 80

② 创建控制器

bash 复制代码
[root@master01 controller]# kubectl apply -f nginx-deployment.yaml

③ 获取集群中Pods、Deployments、以及 ReplicaSets 的信息

bash 复制代码
[root@master01 controller]# kubectl get pod,deploy,rs
NAME                                          READY   STATUS    RESTARTS   AGE
pod/nfs-client-provisioner-5f7484cd44-ls45v   1/1     Running   0          14h
pod/nginx-deployment-d9d8cf5c7-j2c8p          1/1     Running   0          50s
pod/nginx-deployment-d9d8cf5c7-mf578          1/1     Running   0          50s
pod/nginx-deployment-d9d8cf5c7-xqh57          1/1     Running   0          50s
NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment         3/3     3            3           50s
# READY: 表示期望的Pod副本中有多少是Ready状态。3/3意味着所有3个副本都已准备就绪,可以接收请求。
# UP-TO-DATE: 表示已经更新到最新配置的Pod副本数量,这里也是3,说明没有正在进行的更新操作或所有Pod都已经是最新配置。
# AVAILABLE: 表示当前可用的Pod副本数量,同样为3,说明服务完全可用。
# AGE: 显示了Deployment被创建的时间,这里是50秒。

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-d9d8cf5c7          3         3         3       50s
# DESIRED: 表示ReplicaSet期望维持的Pod副本数量,这里是3。
# CURRENT: 实际存在的Pod副本数量,也是3,符合期望。
# READY: 准备好提供服务的Pod副本数量,3个副本都已就绪。

④ 查看控制器配置

bash 复制代码
kubectl edit deployment/nginx-deployment
  labels:
    app: nginx			    # Deployment资源的标签

  replicas: 3				#期望的pod数量,默认是1

    rollingUpdate:
      maxSurge: 25%		    # 升级过程中会先启动的新Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
      maxUnavailable: 25%	# 升级过程中在新的Pod启动好后销毁的旧Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
    type: RollingUpdate		# 滚动升级

spec:
  template:
      labels:
        app: nginx			# Pod副本关联的标签
    spec:
      containers:
      - image: nginx:1.14				#镜像名称
        imagePullPolicy: IfNotPresent	#镜像拉取策略
        ports:
        - containerPort: 80				#容器暴露的监听端口

      restartPolicy: Always				#容器重启策略

⑤ 查看历史版本

bash 复制代码
[root@master01 controller]# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment 
REVISION  CHANGE-CAUSE
1         <none>

小结:

deployment 部署无状态应用的管理 ReplicaSet 和 Pod 并创建 Pod,主要维护 Pod 副本数量与期望值相同;创建和删除 Pod 时,并行执行,升级时也会创建一部分再删除一部分。

2. SatefulSet 部署有状态应用

  • 稳定的持久化存储,即 Pod 重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现;
  • 稳定的网络标志,即 Pod 重新调度后其 PodName 和 HostName 不变,基于 Headless Service(即无头模式,利用 DNS 来解析 Service,没有Cluster IP的Service)来实现;
  • 有序部署,有序扩展,即 Pod 是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个 Pod 运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态),基于 init containers 来实现;
  • 有序收缩,有序删除(即从N-1到0)。

常见的应用场景:数据库StatefulSets | Kubernetes

2.1 SatefulSet 三个组件

  • Headless Service(无头服务):用于为Pod资源标识符生成可解析的DNS记录。
  • volumeClaimTemplates(存储卷申请模板):基于静态或动态PV供给方式为Pod资源提供专有的固定存储。
  • StatefulSet:用于管控Pod资源。

(1)为什么要有headless?

  • 在deployment中,每一个pod是没有名称,是随机字符串,是无序的;
  • 而statefulset中是要求有序的,每一个pod的名称必须是固定的;

当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一。

为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称。

(2)为什么要有volumeClainTemplate?

大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点;

  • 在 deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷;
  • 而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的,这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷。

2.2 实现 K8S 里 DNS 功能的插件

skyDNS:Kubernetes 1.3之前的版本

kubeDNS:Kubernetes 1.3至Kubernetes 1.11

CoreDNS:Kubernetes 1.11开始至今

2.3 解析 kubernetes 和 nginx-service 名称

创建一个service,然后用dns去测试解析。

① 定义 nginx-svc yaml

bash 复制代码
[root@master01 controller]# vim nginx-service.yaml
apiVersion: v1  
kind: Service  
metadata:
  name: nginx-service
  labels:
    app: nginx  
spec:
  type: NodePort  
  ports:
  - port: 80
    targetPort: 80  
  selector:
    app: nginx

② 创建 nginx-svc

bash 复制代码
[root@master01 controller]# kubectl apply -f nginx-service.yaml 
service/nginx-service created

[root@master01 controller]# kubectl get svc
nginx-service      NodePort    10.96.193.207   <none>        80:32037/TCP      7s

③ 定义一个dns-pod yaml

bash 复制代码
[root@master01 controller]# vim dns-test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4  #一个小型的Unix工具集合,常用于测试和基础任务
    args:
    - /bin/sh
    - -c
    - sleep 36000          #让容器运行后休眠36000秒
  restartPolicy: Never     #指定了Pod的重启策略

④ 创建 pod

bash 复制代码
[root@master01 controller]# kubectl apply -f dns-test.yaml
[root@master01 controller]# kubectl get pod
NAME                                      READY   STATUS      RESTARTS   AGE
dns-test                                  1/1     Running     0          48s

⑤ 进入容器测试解析

bash 复制代码
[root@master01 controller]# kubectl exec -it dns-test sh
/ # nslookup kubernetes
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
/ # nslookup nginx-service
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx-service
Address 1: 10.96.193.207 nginx-service.default.svc.cluster.local

2.4 查看 statefulset 的定义

bash 复制代码
kubectl explain statefulset

kubectl explain statefulset.spec
FIELDS:
   podManagementPolicy	<string>     #Pod管理策略
   replicas	<integer>                #副本数量
   revisionHistoryLimit	<integer>    #历史版本限制
   selector	<Object> -required-      #选择器,必选项
   serviceName	<string> -required-  #服务名称,必选项
   template	<Object> -required-      #模板,必选项
   updateStrategy	<Object>         #更新策略
   volumeClaimTemplates	<[]Object>   #存储卷申请模板,必选项

2.5 清单定义 StatefulSet

如上所述,一个完整的 StatefulSet 控制器由一个 Headless Service、一个 StatefulSet 和一个 volumeClaimTemplate 组成。定义了一个Kubernetes StatefulSet资源和一个Headless Service(无头服务),用于部署一个有状态应用:

2.5.1 定义资源清单
bash 复制代码
[root@master01 controller]# vim stateful-demo.yaml 
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
  labels:
    app: myapp-svc
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None   #None表明这是一个无头服务,没有Cluster IP分配,直接返回关联Pod的IP列表
  selector:
    app: myapp-pod  #用于选择带有此标签的Pods,与后续的StatefulSet关联
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: myapp
spec:
  serviceName: myapp-svc
  replicas: 3
  selector:
    matchLabels:       #为Pod定义标签,与selector匹配
      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 #挂载卷myappdata到/usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: myappdata
	  annotations:         
#动态PV创建时,使用annotations在PVC里声明一个StorageClass对象的标识进行关联
        volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
    spec:
      accessModes: ["ReadWriteOnce"]  #定义访问模式
      resources:
        requests:
          storage: 2Gi

由于 StatefulSet 资源依赖于一个实现存在的 Headless 类型的 Service 资源,所以需要先定义一个名为 myapp-svc 的 Headless Service 资源,用于为关联到每个 Pod 资源创建 DNS 资源记录。接着定义了一个名为 myapp 的 StatefulSet 资源,它通过 Pod 模板创建了 3 个 Pod 资源副本,并基于 volumeClaimTemplates 向前面创建的PV进行了请求大小为 2Gi 的专用存储卷。

2.5.2 创建 statefulset
bash 复制代码
[root@master01 controller]# kubectl apply -f stateful-demo.yaml

查看创建的无头服务myapp-svc:
[root@master01 controller]# kubectl get svc
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP           14d
myapp-svc          ClusterIP   None            <none>        80/TCP            32m

查看statefulset:
[root@master01 controller]# kubectl get sts
NAME    READY   AGE
myapp   3/3     24m

查看pvc绑定:
[root@master01 controller]# kubectl get pvc
NAME                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS              AGE
myappdata-myapp-0   Bound    pvc-d9b33a5b-076e-4a17-b457-03d7b50d08b7   2Gi        RWO            nfs-client-storageclass   25m
myappdata-myapp-1   Bound    pvc-4748da6b-1c81-45c0-9b50-a20898cc5f11   2Gi        RWO            nfs-client-storageclass   5m51s
myappdata-myapp-2   Bound    pvc-a4999f31-ab02-4640-913e-c6cf19ccf7a0   2Gi        RWO            nfs-client-storageclass   5m46s

查看pv绑定:
[root@master01 controller]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                       STORAGECLASS              REASON   AGE
pvc-4748da6b-1c81-45c0-9b50-a20898cc5f11   2Gi        RWO            Delete           Bound    default/myappdata-myapp-1   nfs-client-storageclass            8m14s
pvc-a4999f31-ab02-4640-913e-c6cf19ccf7a0   2Gi        RWO            Delete           Bound    default/myappdata-myapp-2   nfs-client-storageclass            8m9s
pvc-d9b33a5b-076e-4a17-b457-03d7b50d08b7   2Gi        RWO            Delete           Bound    default/myappdata-myapp-0   nfs-client-storageclass            8m26s

查看Pod信息:
[root@master01 controller]# kubectl get pods
NAME                                      READY   STATUS    RESTARTS   AGE
myapp-0                                   1/1     Running   0          27m
myapp-1                                   1/1     Running   0          8m39s
myapp-2                                   1/1     Running   0          8m34s
2.5.3 删除 statefulset

当删除的时候是从myapp-2开始进行删除的,关闭是逆向关闭(不过一般是同时删除);然后再次创建,观察 pod 创建详情:

bash 复制代码
[root@master01 volumes]# kubectl get pod -w
NAME                                      READY   STATUS    RESTARTS   AGE
myapp-0                                   1/1     Running   0          32m
myapp-1                                   1/1     Running   0          12m
myapp-2                                   1/1     Running   0          12m
nfs-client-provisioner-5f7484cd44-ft5lv   1/1     Running   0          13m
myapp-1                                   1/1     Terminating   0          14m
myapp-2                                   1/1     Terminating   0          14m
myapp-0                                   1/1     Terminating   0          34m
myapp-1                                   0/1     Terminating   0          14m
myapp-2                                   0/1     Terminating   0          14m
myapp-0                                   0/1     Terminating   0          34m
myapp-1                                   0/1     Terminating   0          14m
myapp-1                                   0/1     Terminating   0          14m
myapp-2                                   0/1     Terminating   0          14m
myapp-2                                   0/1     Terminating   0          14m
myapp-0                                   0/1     Terminating   0          34m
myapp-0                                   0/1     Terminating   0          34m
myapp-0                                   0/1     Pending       0          0s
myapp-0                                   0/1     Pending       0          0s
myapp-0                                   0/1     ContainerCreating   0          0s
myapp-0                                   1/1     Running             0          2s
myapp-1                                   0/1     Pending             0          0s
myapp-1                                   0/1     Pending             0          0s
myapp-1                                   0/1     ContainerCreating   0          0s
myapp-1                                   1/1     Running             0          2s
myapp-2                                   0/1     Pending             0          0s
myapp-2                                   0/1     Pending             0          0s
myapp-2                                   0/1     ContainerCreating   0          0s
myapp-2                                   1/1     Running             0          2s

此时PVC依旧存在的,再重新创建pod时,依旧会重新去绑定原来的pvc:

bash 复制代码
[root@master01 controller]# kubectl get pvc
NAME                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS              AGE
myappdata-myapp-0   Bound    pvc-d9b33a5b-076e-4a17-b457-03d7b50d08b7   2Gi        RWO            nfs-client-storageclass   36m
myappdata-myapp-1   Bound    pvc-4748da6b-1c81-45c0-9b50-a20898cc5f11   2Gi        RWO            nfs-client-storageclass   17m
myappdata-myapp-2   Bound    pvc-a4999f31-ab02-4640-913e-c6cf19ccf7a0   2Gi        RWO            nfs-client-storageclass   17m

2.6 滚动更新

StatefulSet 控制器将在 StatefulSet 中删除并重新创建每个 Pod。它将以与 Pod 终止相同的顺序进行(从最大的序数到最小的序数),每次更新一个 Pod。在更新其前身之前,它将等待正在更新的 Pod 状态变成正在运行并就绪。如下操作的滚动更新是按照2-0的顺序更新。

① 修改 yaml 定义

bash 复制代码
[root@master01 controller]# vim stateful-demo.yaml
......
        image: nginx:1.18.0     # 原来是1.14
......

② 更新 svc yaml

bash 复制代码
[root@master01 controller]# kubectl apply -f stateful-demo.yaml

③ 查看滚动更新的过程

bash 复制代码
[root@master01 volumes]# kubectl get pod -w
NAME                                      READY   STATUS    RESTARTS   AGE
myapp-0                                   1/1     Running   0          12s
myapp-1                                   1/1     Running   0          9s
myapp-2                                   1/1     Running   0          7s
nfs-client-provisioner-5f7484cd44-ft5lv   1/1     Running   0          29m
myapp-2                                   1/1     Terminating   0          51s
myapp-2                                   0/1     Terminating   0          52s
myapp-2                                   0/1     Terminating   0          53s
myapp-2                                   0/1     Terminating   0          53s
myapp-2                                   0/1     Pending       0          0s
myapp-2                                   0/1     Pending       0          0s
myapp-2                                   0/1     ContainerCreating   0          0s
myapp-2                                   1/1     Running             0          2s
myapp-1                                   1/1     Terminating         0          57s
myapp-1                                   0/1     Terminating         0          58s
myapp-1                                   0/1     Terminating         0          59s
myapp-1                                   0/1     Terminating         0          59s
myapp-1                                   0/1     Pending             0          0s
myapp-1                                   0/1     Pending             0          0s
myapp-1                                   0/1     ContainerCreating   0          0s
myapp-1                                   1/1     Running             0          2s
myapp-0                                   1/1     Terminating         0          64s
myapp-0                                   0/1     Terminating         0          65s
myapp-0                                   0/1     Terminating         0          66s
myapp-0                                   0/1     Terminating         0          66s
myapp-0                                   0/1     Pending             0          0s
myapp-0                                   0/1     Pending             0          0s
myapp-0                                   0/1     ContainerCreating   0          0s
myapp-0                                   1/1     Running             0          2s

④ 进入 dns-test Pod中,每一个 pod 自己的名称都是可以被解析的

bash 复制代码
[root@master01 controller]# kubectl exec -it  dns-test sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup myapp-svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      myapp-svc
Address 1: 10.244.2.40 myapp-0.myapp-svc.default.svc.cluster.local
Address 2: 10.244.2.39 myapp-1.myapp-svc.default.svc.cluster.local
Address 3: 10.244.1.201 myapp-2.myapp-svc.default.svc.cluster.local
/ # nslookup  myapp-0.myapp-svc.default.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      myapp-0.myapp-svc.default.svc.cluster.local
Address 1: 10.244.2.40 myapp-0.myapp-svc.default.svc.cluster.local
/ # nslookup  myapp-1.myapp-svc.default.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      myapp-1.myapp-svc.default.svc.cluster.local
Address 1: 10.244.2.39 myapp-1.myapp-svc.default.svc.cluster.local
/ # nslookup  myapp-2.myapp-svc.default.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

3. DaemonSet 一次创建多节点

DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

使用 DaemonSet 的一些典型用法:

  • 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
  • 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
  • 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。

应用场景:Agent

官方案例(监控):https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/

示例:

bash 复制代码
[root@master01 data]# vim ds.yaml
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.14
        ports:
        - containerPort: 80

[root@master01 data]# kubectl apply -f ds.yaml

DaemonSet会在每个node节点都创建一个Pod:
[root@master01 data]# kubectl get pod -o wide
nginx-daemonset-bqmtg                     1/1     Running   0          15s     10.244.1.202   node01   <none>           <none>
nginx-daemonset-n89xc                     1/1     Running   0          15s     10.244.2.42    node02   <none>           <none>

三、总结

1. Pod 控制器

① deployment 部署无状态应用的管理 RS 和 pod 创建 Pod ,主要是维护 pod 副本数量与期望状态相同;创建和删除 pod 时并行执行升级时是想创建一部分,再删除一部分;

② statefulset 部署有状态的应用,每个 pod 名称唯一且不变,每个 pod 拥有自己专属的持久化的存储(PVC 和 PV)在 k8s 集群内部可以通过{pod_name}.{service_name}.{namespace).svc.cluster.local 解析出 pod 的 IP(基于 headless service 和 coreDNS)创建和删除 pod 是有顺序的(串行执行的),升级时串行执行的,会删除旧的 pod,再创建新 pod;删除和升级是逆序执行的(先从标识符最大的 n-1开始,一直到最小的0);

③ Daemonset 理论上在 k8s 集群的所有 node 节点上创建相同的 pod(无论 node 节点什么时候加入到 k8s 集群),但是会收到 node 节点上污点影响;

④ 部署一次性任务的 pod,正常完成后容器立即退出并且不重启容器(restartpolicy 不设置Always),也不会重建,异常完成后重试任务,重建次数根据 backofflimit 配置指定(默认为6次);

⑤ cronjob 周期性的部署任务的 pod,正常完成后容器会立即退出并不会重启容器(restartPolicy 不设置 Always),也不会重键 pod schedule 配置周期的性的事件表(*****分时日月周)。

bash 复制代码
无状态:
1)deployment 认为所有的pod都是一样的
2)不用考虑顺序的要求
3)不用考虑在哪个node节点上运行
4)可以随意扩容和缩容 

有状态
1)实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
2)实例之间不对等的关系,以及依靠外部存储的应用。

常规service和无头服务区别
service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现。
Headless service:无头服务,不需要cluster-IP,而是直接以DNS记录的方式解析出被代理Pod的IP地址。
相关推荐
later_rql1 小时前
k8s-集群部署1
云原生·容器·kubernetes
weixin_453965003 小时前
[单master节点k8s部署]31.ceph分布式存储(二)
分布式·ceph·kubernetes
大G哥6 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes
妍妍的宝贝6 小时前
k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
nginx·微服务·kubernetes
大道归简7 小时前
Docker 命令从入门到入门:从 Windows 到容器的完美类比
windows·docker·容器
爱跑步的程序员~8 小时前
Docker
docker·容器
福大大架构师每日一题8 小时前
23.1 k8s监控中标签relabel的应用和原理
java·容器·kubernetes
程序那点事儿8 小时前
k8s 之动态创建pv失败(踩坑)
云原生·容器·kubernetes
疯狂的大狗8 小时前
docker进入正在运行的容器,exit后的比较
运维·docker·容器
长天一色9 小时前
【Docker从入门到进阶】01.介绍 & 02.基础使用
运维·docker·容器