7.DaemonSet分析

前面提到过,DaemonSet是一种Controller,适用于每个Node只能运行一个副本的应用。

DaemonSet 的典型应用场景有:

  1. 在集群的每个节点上运行存储 Daemon,比如 glusterd 或 ceph。

  2. 在每个节点上运行日志收集 Daemon,比如 flunentd 或 logstash。

  3. 在每个节点上运行监控 Daemon,比如 Prometheus Node Exporter 或 collectd。

注意,每个节点上就有DaemonSet系统组件,如kube-flannel和kube-proxy。在NameSpace为kube-system上运行。执行命令:

kubectl get daemonset --namespace=kube-system

DaemonSet kube-flannel-ds 和 kube-proxy 分别负责在每个节点上运行 flannel 和 kube-proxy 组件。因为 flannel 和 kube-proxy 属于系统组件,需要在命令行中通过 --namespace=kube-system 指定 namespace kube-system。如果不指定则只返回默认 namespace default 中的资源。

k8s默认会有default、kube-system两个NameSpace。

之前部署flannel网络命令:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

详细解析 kube-flannel.yaml

配置文件只保留了部分重要内容!

① DaemonSet 配置文件的语法和结构与 Deployment 几乎完全一样,只是将 kind 设为 DaemonSet

② hostNetwork 指定 Pod 直接使用的是 Node 的网络,相当于 docker run --network=host。考虑到 flannel 需要为集群提供网络连接,这个要求是合理的。

③ containers 定义了运行 flannel 服务的两个容器。

详细解析 kube-proxy

执行命令

kubectl edit daemonset kube-proxy --namespace=kube-system

可以查看配置

同样为了便于理解,这里只保留了最重要的信息。

① kind: DaemonSet 指定这是一个 DaemonSet 类型的资源。

② containers 定义了 kube-proxy 的容器。

③ status 是当前 DaemonSet 的运行时状态,这个部分是 kubectl edit特有的。其实 Kubernetes 集群中每个当前运行的资源都可以通过 kubectl edit 查看其配置和运行状态,比如 kubectl edit deployment nginx-deployment

 8.一次性任务Job

容器按照持续运行的时间可分为两类:服务类容器和工作类容器。工作类容器则是一次性任务,比如批处理程序,完成后容器就退出。工作类容器则是一次性任务,比如批处理程序,完成后容器就退出。

简单的 Job 配置文件 myjob.yml:

① batch/v1 是当前 Job 的 apiVersion

② 指明当前资源的类型为 Job

③ restartPolicy 指定什么情况下需要重启容器。对于 Job,只能设置为 Never 或者 OnFailure。对于其他 controller(比如 Deployment)可以设置为 Always 。

通过 kubectl apply -f myjob.yml 启动 Job。

kubectl get job 查看 Job 的状态:

DESIRED 和 SUCCESSFUL 都为 1,表示按照预期启动了一个 Pod,并且已经成功执行。

使用kubectl get pod查不到pod存在,因为pod运行完成后就已经关闭,我们需要使用kubectl get pod --show--all才能看到所有历史pod(包括已经关闭的pod)。

kubectl logs 可以查看 Pod 的标准输出:

job执行失败会如何? restartPolicy 设置为 Never 或者 OnFailure的区别:

假设myjob.yaml写错了,那么pod会怎么运行呢?这里故意引入错误。

 kubectl delete -f myjob.yml删除之前的yaml文件。此时restartPolicy 设置为Never,即为不重启。

运行新的 Job 并查看状态:

当前 SUCCESSFUL 的 Pod 数量为 0,查看 Pod 的状态:

这里都可以观察到desired为1,但是successful为0。为什么会这样呢?

原因是:当第一个 Pod 启动时,容器失败退出,根据 restartPolicy: Never,此失败容器不会被重启,但 Job DESIRED 的 Pod 是 1,目前 SUCCESSFUL 为 0,不满足,所以 Job controller 会启动新的 Pod,直到 SUCCESSFUL 为 1。对于我们这个例子,SUCCESSFUL 永远也到不了 1,所以 Job controller 会一直创建新的 Pod。为了终止这个行为,只能删除 Job。

但如果我们将restartPolicy 设置为OnFailure呢?

删除上面的myjob.yaml,下面我们实践一下,修改 myjob.yml 后重新启动。

Job 的 SUCCESSFUL Pod 数量还是为 0,看看 Pod 的情况:

这里只有一个 Pod,不过 RESTARTS 为 3,而且不断增加,说明 OnFailure 生效,容器失败后会自动重启。

9.并行启动job

parallelism表示同时并行运行Job的个数, completions 设置 Job 成功完成 Pod 的总数:该yaml文件表示运行6个名为myjob的Pod并且每次同时运行两个。

上面的例子只是为了演示 Job 的并行特性,实际用途不大。

10.定时启动Job

 类似于linux系统下的cron命令,任务调度,定时执行某个配置文件或者命令。k8s的CronJob提供了类似的功能

① batch/v2alpha1 是当前 CronJob 的 apiVersion

② 指明当前资源的类型为 CronJob

③ schedule 指定什么时候运行 Job,其格式与 Linux cron 一致。这里 */1 * * * * 的含义是每一分钟启动一次。

④ jobTemplate 定义 Job 的模板,格式与前面 Job 一致。

通过 kubectl apply 创建 CronJob。

 失败了。这是因为 Kubernetes 默认没有 enable CronJob 功能,需要在 kube-apiserver 中加入这个功能。方法很简单,修改 kube-apiserver 的配置文件 /etc/kubernetes/manifests/kube-apiserver.yaml:

 将此处改为true即可。

kube-apiserver 本身也是个 Pod。kubelet 会重启 kube-apiserver Pod。通过 kubectl api-versions 确认 kube-apiserver 现在已经支持 batch/v2alpha1。

再次使用 apply -f 创建CronJob即可。 

通过 kubectl get cronjob 查看 CronJob 的状态:

等待几分钟,然后通过 kubectl get jobs 查看 Job 的执行情况:

可以看到每隔一分钟就会启动一个 Job。执行 kubectl logs 可查看某个 Job 的运行日志:

自此,容器运行应用已经全部介绍完成,这一部分是k8s最重要的核心功能,需要经常复习浏览! 

Logo

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

更多推荐