资源清单

资源清单,又称工作负载,是在 Kubernetes 上运行的应用程序。

Kubernetes Pods 有确定的生命周期。 例如,当某 Pod 在你的集群中运行时,Pod 运行所在的 节点出现致命错误时, 所有该节点上的 Pods 都会失败。Kubernetes 将这类失败视为最终状态: 即使该节点后来恢复正常运行,你也需要创建新的 Pod 来恢复应用。

直接管理每个 Pod显然是一件繁杂的事,我们可以使用 负载资源 来管理一组 Pods。 这些资源配置控制器可以确保合适类型的、处于运行状态的 Pod 个数是正确的,与所指定的状态相一致。

资源:Kubernetes中所有的内容都抽象为资源,也可以称作工作负载。 资源实例化之后,叫做对象。

资源清单:一般使用yaml文件启动pod,yaml文件即资源清单。

资源分类:

  • 工作负载型资源 :PodReplicaSetDeploymentStatefulSetDaemonSetJobCronJob
  • 服务发现及负载均衡型资源:ServiceIngress
  • 配置与存储型资源:VolumeCSI
  • 特殊类型存储资源:ConfigMapSecretDownwardAPI
  • 集群级资源:NamespaceNodeRoleClusterRoleRoleBinding
  • 元数据型资源:HPAPodTemplate

Kubernetes 提供若干种内置的工作负载资源

  • DeploymentReplicaSet (替换原来的资源 ReplicationController)。 Deployment 很适合用来管理你的集群上的无状态应用,Deployment 中的所有 Pod 都是相互等价的,并且在需要的时候被换掉。

  • StatefulSet 让你能够运行一个或者多个以某种方式跟踪应用状态的 Pods。 例如,如果你的负载会将数据作持久存储,你可以运行一个 StatefulSet,将每个 Pod 与某个 PersistentVolume 对应起来。你在 StatefulSet 中各个 Pod 内运行的代码可以将数据复制到同一 StatefulSet 中的其它 Pod 中以提高整体的服务可靠性。

  • DaemonSet 定义提供节点本地支撑设施的 Pods。这些 Pods 可能对于你的集群的运维是 非常重要的,例如作为网络链接的辅助工具或者作为网络 插件 的一部分等等。每次你向集群中添加一个新节点时,如果该节点与某 DaemonSet 的规约匹配,则控制面会为该 DaemonSet 调度一个 Pod 到该新节点上运行。

  • JobCronJob。 定义一些一直运行到结束并停止的任务。Job 用来表达的是一次性的任务,而 CronJob 会根据其时间规划反复运行。

一、Deployments

一个 DeploymentPodsReplicaSets 提供声明式的更新能力。

用户负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。

使用场景

以下是 Deployments 的典型用例:

  • 创建 Deployment 以将 ReplicaSet 上线。 ReplicaSet 在后台创建 Pods。 检查 ReplicaSet 的上线状态,查看其是否成功。
  • 通过更新 Deployment 的 PodTemplateSpec,声明 Pod 的新状态。 新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新 Deployment 的修订版本。
  • 如果 Deployment 的当前状态不稳定,回滚到较早的 Deployment 版本。 每次回滚都会更新 Deployment 的修订版本。
  • 扩大 Deployment 规模以承担更多负载
  • 暂停 Deployment以应用对 PodTemplateSpec 所作的多项修改, 然后恢复其执行以启动新的上线版本。
  • 使用 Deployment 状态来判定上线过程是否出现停滞。
  • 清理较旧的不再需要的 ReplicaSet

1.创建Deployment

nginx-deployment.yaml文件解读。

apiVersion: apps/v1
kind: Deployment   # 资源类型Deployment
metadata:
  name: nginx-deployment   # 定义Deployment的名称:nginx-deployment
  labels: 
    app: nginx    # 对Deployment打上标签:app=nginx
spec:    # 这里定义Deployment的规格(期望)
  replicas: 3    # 三个Pod副本
  selector:
    matchLabels:
      app: nginx  # 定义 Deployment 根据标签 app=nginx 查找要管理的 Pods
  template:
    metadata:
      labels:
        # 对Deployment的pod模板打上标签 app=nginx  这里和spec.selector.matchLabels的要一致
        app: nginx 
    spec:  # 这里指定容器规格(或者说期望)
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

通过运行以下命令创建 Deployment :

kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml

通过运行以下命令查看 Deployment :

kubectl get deployments
kubectl get deployments -o wide

通过运行以下命令查看 Deployment的上线状况 :

kubectl rollout status deployment/nginx-deployment

通过运行以下命令查看该Deployment 创建的 ReplicaSet :

kubectl get rs

通过运行以下命令查看 Deployment的生成标签 :

kubectl get pods --show-labels

2.更新Deployment

4种方式可以更新Deployment

通过运行以下命令 以更新 nginx:1.14.2nginx:1.16.1 镜像 :

kubectl --record deployment.apps/nginx-deployment set image \
   deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1

或者使用下面的命令:

kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record

或者,可以 edit Deployment 并将 .spec.template.spec.containers.imagenginx:1.14.2 更改至 nginx:1.16.1

kubectl edit deployment.v1.apps/nginx-deployment

或者直接修改nginx-deployment.yaml文件,修改为 spec.containers.image: nginx:1.16.1

kubectl apply -f nginx-deployment.yaml

运行 kubectl get rs 可以查看到Deployment 通过 创建新的 ReplicaSet 将其扩容到 3 个副本,并将旧 ReplicaSet 缩容到 0 个副本完成了 Pod 的更新操作。

kubectl get rs

输出类似于:

NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-559d658b74   3         3         3       1m23s
nginx-deployment-66b6c48dd5   0         0         0       3m

旧的 ReplicaSet 会一直保持,直到我们把它删除。那它为什么为一直保存呢?

→ 用于Deployment的回滚

3.回滚 Deployment

当新版本的Deployment出现不稳定状况或者有bug存在时,我们希望回滚到前一稳定版本。默认情况下,Deployment 的所有上线记录都保留在系统中,以便可以随时回滚。

首先,检查 Deployment 修订历史:

kubectl rollout history deployment.v1.apps/nginx-deployment

输出类似于:

deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1           kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
2           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true
3           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true

CHANGE-CAUSE 的内容是从 Deployment 的 kubernetes.io/change-cause 注解复制过来的。 复制动作发生在修订版本创建时。

要查看修订历史的详细信息,运行:

kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2

假定现在已决定撤消当前上线并回滚到以前的修订版本:

kubectl rollout undo deployment.v1.apps/nginx-deployment

输出类似于:

deployment.apps/nginx-deployment

或者,你也可以通过使用 --to-revision 来回滚到特定修订版本:

kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2

输出类似于:

deployment.apps/nginx-deployment

检查回滚是否成功以及 Deployment 是否正在运行,运行:

kubectl get deployment nginx-deployment

输出类似于:

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3         3         3            3           15m

4.Deployment 的扩缩容

可以使用如下指令缩放 Deployment( Deployment 扩容到10 个副本 ):

kubectl scale deployment.v1.apps/nginx-deployment --replicas=10

或者可以为 Deployment 设置自动缩放器,基于现有 Pods 的 CPU 利用率选择 要运行的 Pods 个数下限和上限。

kubectl autoscale deployment.v1.apps/nginx-deployment --min=5 --max=15 --cpu-percent=80

以上两种命令都会输出类似如下,表示扩缩容成功:

deployment.apps/nginx-deployment scaled

5.暂停、恢复 Deployment

使用如下指令暂停运行:

kubectl rollout pause deployment.v1.apps/nginx-deployment

输出类似于:

deployment.apps/nginx-deployment paused

接下来更新 Deployment 镜像:

kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1

可以根据需要执行很多更新操作,例如,可以要使用的资源:

kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi

输出类似于:

deployment.apps/nginx-deployment resource requirements updated

暂停Deployment之前的初始状态将继续发挥作用,但新的更新在Deployment被暂停期间不会产生任何效果。

最终,恢复 Deployment 执行并观察新的 ReplicaSet 的创建过程,其中包含了所应用的所有更新:

kubectl rollout resume deployment.v1.apps/nginx-deployment

输出:

deployment.apps/nginx-deployment resumed

观察上线的状态,直到完成。-w表示监控

kubectl get rs -w

说明: 不可以回滚处于暂停状态的 Deployment,除非先恢复其执行状态。

Deployment 状态

Deployment 的生命周期中会有许多状态。上线新的 ReplicaSet 期间可能处于 Progressing(进行中),可能是 Complete(已完成),也可能是 Failed(失败)以至于无法继续进行。

进行中的 Deployment

执行下面的任务期间,Kubernetes 标记 Deployment 为 进行中(Progressing)

  • Deployment 创建新的 ReplicaSet
  • Deployment 正在为其最新的 ReplicaSet 扩容
  • Deployment 正在为其旧有的 ReplicaSet(s) 缩容
  • 新的 Pods 已经就绪或者可用(就绪至少持续了 MinReadySeconds 秒)。

你可以使用 kubectl rollout status 监视 Deployment 的进度。

完成的 Deployment

当 Deployment 具有以下特征时,Kubernetes 将其标记为 完成(Complete)

  • 与 Deployment 关联的所有副本都已更新到指定的最新版本,这意味着之前请求的所有更新都已完成。
  • 与 Deployment 关联的所有副本都可用。
  • 未运行 Deployment 的旧副本。

你可以使用 kubectl rollout status 检查 Deployment 是否已完成。 如果上线成功完成,kubectl rollout status 返回退出代码 0。

kubectl rollout status deployment/nginx-deployment

对失败 Deployment 的操作

可应用于已完成的 Deployment 的所有操作也适用于失败的 Deployment。 你可以对其执行扩缩容、回滚到以前的修订版本等操作,或者在需要对 Deployment 的 Pod 模板应用多项调整时,将 Deployment 暂停。

清理策略

你可以在 Deployment 中设置 .spec.revisionHistoryLimit 字段以指定保留此 Deployment 的多少个旧有 ReplicaSet。其余的 ReplicaSet 将在后台被垃圾回收。 默认情况下,此值为 10

二、ReplicaSet

ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。

ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非你需要自定义更新业务流程或根本不需要更新。

可以这么理解:ReplicaSet 通常用于协助 Deployment 保持Pod副本的数量,几乎很少单独使用。

三、StatefulSets

StatefulSet 是用来管理有状态应用的工作负载 API 对象。它强调的是稳定和有序

StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。

和 Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的,但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。

使用场景

StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:

  • 稳定的、唯一的网络标识符。
  • 稳定的、持久的存储。
  • 有序的、优雅的部署和缩放。
  • 有序的、自动的滚动更新。

如果应用程序不需要有序的部署、删除或伸缩或者任何稳定的标识符,则应该使用 Deployment 来满足无状态应用部署需要。

使用Statefulset的一些规则

  • 给定 Pod 的存储必须由 PersistentVolume 驱动基于所请求的 storage class 来提供,或者由管理员预先提供。
  • 删除或者收缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
  • StatefulSet 当前需要 Headless 服务来负责 Pod 的网络标识。你需要负责创建此服务。
  • 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序地且优雅地终止,可以在删除之前将 StatefulSet 缩放为 0。
  • 在默认 Pod 管理策略(OrderedReady) 时使用 滚动更新,可能进入需要 人工干预 才能修复的损坏状态。

创建StatefulSet

nginx-statefulset-pvc.yaml文件解读。

apiVersion: v1
kind: Service    # StatefulSet 需要一个 Headless服务来负责 Pod 的网络标识
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:     
  # PVC请求匹配(PVC会根据以下定义accessModes和storageClassName来匹配可用的pv,如果匹配不到,则会一直处于pending状态,直到有匹配的pv被创建出来)
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "nfs"            # 这里以nfs卷存储为例(先安装nfs服务)
      resources:
        requests:
          storage: 1Gi

安装nfs服务:

# k8s 主节点安装 nfs 服务
yum install -y nfs-common nfs-utils rpcbind
# 指定共享文件夹(用于挂载,可以指定多个)
mkdir /nfs
chmod 777 /nfs
# 在文件 /etc/exports中添加: /nfs *(rw,no_root_squash,no_all_squash,sync)
# 查看内容是否添加正确:
cat /etc/exports
# 输出
# /nfs *(rw,no_root_squash,no_all_squash,sync)
# 重启nfs服务
systemctl start rpcbind
systemctl start nfs

# k8s 其它节点安装nfs客户端(pod有可能运行在任何节点,所以都要安装nfs)
yum install -y nfs-utils rpcbind

创建部署 PV nginx-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
   name: nfspv1
spec:
   capacity:
     storage: 10Gi
   accessModes:
     - ReadWriteOnce   
   persistentVolumeReclaimPolicy: Retain
   storageClassName: nfs
   nfs:  # nfs配置
     path: /nfs   # 安装nfs时指定的共享文件夹
     server: 192.168.168.50   # 安装有nfs的服务器

运行如下命令创建 pv 和 statefulset-pvc。

kubectl apply -f nginx-pv.yaml
kubectl apply -f nginx-statefulset-pvc.yaml

观察statefulset的有序性。可以修改PV的名称,并创建新的PV。

查看PV:kubectl get pv

NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
nfspv1   10Gi       RWO            Retain           Bound    default/www-web-0   nfs                     4h

查看pod:kubectl get pod

web-0                               1/1     Running   0          6s
web-1                               0/1     Pending   0          4s

再次创建新的PV,名称为nfspv2

查看PV:kubectl get pv

NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM               STORAGECLASS   REASON   AGE
nfspv1   10Gi       RWO            Retain           Bound       default/www-web-0   nfs                     4h2m
nfspv2   10Gi       RWO            Retain           Available                       nfs                     4s

查看pod:kubectl get pod

web-0                               1/1     Running   0          5m15s
web-1                               1/1     Running   0          5m13s
web-2                               0/1     Pending   0          12s

可以看出,statefulset的创建是有序的。前一个创建完成,才开始创建下一个。

四、DaemonSet

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

使用场景

  • 在每个节点上运行集群守护进程
  • 在每个节点上运行日志收集守护进程
  • 在每个节点上运行监控守护进程

一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。

五、Jobs

Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。

Job 完成时不会再创建新的 Pod,不过已有的 Pod 也不会被删除。 保留这些 Pod 使得你可以查看已完成的 Pod 的日志输出,以便检查错误、警告 或者其它诊断性输出。 Job 完成时 Job 对象也一样被保留下来,这样你就可以查看它的状态。 在查看了 Job 状态之后删除老的 Job 的操作留给了用户自己。 你可以使用 kubectl 来删除 Job(例如,kubectl delete jobs/pi 或者 kubectl delete -f ./job.yaml)。 当使用 kubectl 来删除 Job 时,该 Job 所创建的 Pods 也会被删除。

六、TTL控制器

TTL 控制器提供了一种 TTL 机制来限制已完成执行的资源对象的生命周期。 TTL 控制器目前只处理 Job, 可能以后会扩展以处理将完成执行的其他资源,例如 Pod 和自定义资源。

七、CronJob

Cron Job 创建基于时间调度的 Jobs。

一个 CronJob 对象就像 crontab (cron table) 文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。

八、ReplicationController

ReplicationController 确保在任何时候都有特定数量的 Pod 副本处于运行状态。 换句话说,ReplicationController 确保一个 Pod 或一组同类的 Pod 总是可用的。

九、Horizontal Pod Autoscaler

Horizontal Pod Autoscaler 可以根据 CPU 利用率自动扩缩 ReplicationController、 Deployment、ReplicaSet 或 StatefulSet 中的 Pod 数量 。

例如,在前面的 Deployment 中,我们已经使用过自动扩缩容命令:

kubectl autoscale deployment.v1.apps/nginx-deployment --min=5 --max=15 --cpu-percent=80
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐