【Kubernetes 008】多种类型控制器区别及实际操作详解(RS,Deployment,DaemonSet,Job,ConJob)

2023-11-14

Pod是k8s中的基本结构,前面我们已经创建过一个。但是生产环境中往往不需要我们自己去创建pod,而是通过创建管理pod的控制器而达到自动批量管理pod的目的。这一节我们就一起来看看k8s中有哪些控制器,以及这些控制器的一些基本操作。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

控制器类型

k8s的控制器一共有如下几种:

  • ReplicationController(已弃用)和ReplicaSet
  • Deployment
  • DaemonSet
  • StatefulSet
  • Job/CronJob
  • Horizontal Pod Autoscaling

下面对每种进行详细介绍

ReplicationController和ReplicaSet

RC和RS的作用一致,都是确保pod的副本数量维持在期望水平,但是RS可以根据容器的label进行集合式的选择,这个RC是做不到的,所以RC被RS淘汰了。

Deployment

Deployment为pod和RS提供一个声明式(declarative)方法,替代以前的RC来管理应用。

命令式编程:一步步告诉程序应该执行的命令
声明式编程:只声明一个结果,并不给出具体步骤,然后让计算机去实现

典型的应用场景如下:

  • 定义Deployment来创建pod和RS
  • 滚动升级和回滚应用
    通过创建新的RS在下面创建pod,并停止旧RS来进行升级。重新启动旧RS而停止新RS来达到回滚的目的。
  • 扩容和缩容
  • 暂停和继续Deployment

在可选RS和Deployment的情况下,优先选择Deployment。

DaemonSet

DaemonSet确保全部或一些Node上运行一个pod的副本。当有Node加入集群时,也会为该Node创建一个pod副本。

典型的应用场景如下:

  • 运行集群存储的Daemon,例如glusterd,ceph
  • 运行日志收集Daemon,例如fluentd,logstash
  • 运行监控的Daemon,例如Prometheus Node Exporter,collectd等

Job

在pod里面部署一些脚本单次运行,并确保这些pod成功结束。

CronJob

类似linux的Cron,用来在给定时间点或者是周期循环执行任务。

StatefulSet

StatefulSet为pod提供了唯一的标识,可以保证部署和scale的顺序。区别于RS的无状态服务,StatefulSet是为了解决有状态服务而创建的。典型应用场景如下:

  • 稳定的持久化存储,即pod重新调度后还是能访问到完全相同的存储
  • 稳定的网络标识,即pod重新调度后其podname和hostname不变
  • 有序部署,有序扩展,从0到N-1,通过前面说的Init容器来实现
  • 有序收缩,有序删除,从N-1到0,后启动的pod先停止,避免报错

HPA

HPA有点像上面这些控制器的附属品,通过一些指标,例如cpu,去控制之前提到的控制器达到自动扩缩容的目的。HPA不直接控制pod。

实际操作

以下所有yaml文件都托管在Github:
https://github.com/Victor2Code/centos-k8s-init/tree/master/test%20yaml

RS实际操作

和前面生成pod一样,rs也是通过yaml文件来定义。所有字段的详细解释可以通过kubectl explain rs或者kubectl explain ReplicaSet来查看。

几个重要的字段总结一下

字段 类型 说明
apiVersion string extensions/v1beta1
kind string ReplicaSet
spec object
spec.replicas integer 副本的期望数目,默认为1
spec.selector object 对pod的选择条件
spec.selector.matchLabels object
spec.template object 描述rs管理的pod的信息
spec.template.metadata object 和pod的定义一样,不过注意labels内容要和上面的一致
spec.template.spec object 和pod的定义一样

补充apiversion查询手册https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/

或者通过kubectl explain xx 来查询apiversion怎么填

通过yaml文件test-rs.yaml创建一个rs

apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  name: test-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: rs-app
  template:
    metadata:
      labels:
        app: rs-app
    spec:
      containers:
        - name: mynginx
          image: mynginx:v1
          ports:
            - containerPort: 80

这里pod里面只有一个容器,使用的是我重新tag的nginx镜像。

在所有可能被分配pod的node上通过命令docker tag nginx mynginx:v1去重新打标签,目的是为了不让k8s每次去下载latest镜像

创建之后可以看到起了3个pod

[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES
curl-6bf6db5c4f-kljp4   1/1     Running   1          3d18h   10.244.1.2    k8s-node1    <none>           <none>
hellok8s                2/2     Running   0          2d23h   10.244.1.6    k8s-node1    <none>           <none>
test-init-main          1/1     Running   31         2d1h    10.244.1.8    k8s-node1    <none>           <none>
test-rs-74mw2           1/1     Running   0          64m     10.244.1.17   k8s-node1    <none>           <none>
test-rs-89l2s           1/1     Running   0          64m     10.244.1.16   k8s-node1    <none>           <none>
test-rs-w8zw8           1/1     Running   0          64m     10.244.0.4    k8s-master   <none>           <none>
test-start-stop         1/1     Running   0          37h     10.244.1.15   k8s-node1    <none>           <none>

上面一共有7个pod,其中以test-rs开头的3个pod是通过rs自动创建的,可以看到其中2个在node1上,另一个在master上。另外4个pod是之前的实验创建的,它们并不归任何控制器管

下面我们尝试删除所有的pod,当然这个命令只会删除default命名空间下的pod,不会删除kube-system下的

[root@k8s-master k8s-test]# kubectl delete pod --all
pod "curl-6bf6db5c4f-kljp4" deleted
pod "hellok8s" deleted
pod "test-init-main" deleted
pod "test-rs-74mw2" deleted
pod "test-rs-89l2s" deleted
pod "test-rs-w8zw8" deleted
pod "test-start-stop" deleted

接着再查看pod

[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME            READY   STATUS    RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES
test-rs-gtxln   1/1     Running   0          2m27s   10.244.0.5    k8s-master   <none>           <none>
test-rs-hn4g5   1/1     Running   0          2m27s   10.244.1.20   k8s-node1    <none>           <none>
test-rs-wrrh2   1/1     Running   0          2m27s   10.244.1.19   k8s-node1    <none>           <none>

发现不是由RS创建的pod都不会重启,而由RS创建的3个pod又改了个名字重新出现了。这就是自主式pod和由控制器控制的pod的一个最大不同

此时如果看一下这三个pod的label

[root@k8s-master k8s-test]# kubectl get pod -o wide --show-labels
NAME            READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES   LABELS
test-rs-gtxln   1/1     Running   0          11h   10.244.0.5    k8s-master   <none>           <none>            app=rs-app
test-rs-hn4g5   1/1     Running   0          11h   10.244.1.20   k8s-node1    <none>           <none>            app=rs-app
test-rs-wrrh2   1/1     Running   0          11h   10.244.1.19   k8s-node1    <none>           <none>            app=rs-app

这三个pod的label是一致的,都是app=rs-app。这时我们修改其中一个pod的label

[root@k8s-master k8s-test]# kubectl label pod test-rs-wrrh2 --overwrite app=rs-app1
pod/test-rs-wrrh2 labeled
[root@k8s-master k8s-test]# kubectl get pod --show-labels
NAME            READY   STATUS    RESTARTS   AGE    LABELS
test-rs-hn4g5   1/1     Running   0          11h    app=rs-app
test-rs-n5zxb   1/1     Running   0          5s     app=rs-app
test-rs-pph4b   1/1     Running   0          101s   app=rs-app
test-rs-wrrh2   1/1     Running   0          11h    app=rs-app1

通过kubectl label --help可以查看标签的一些命令,要修改一个pod已经存在的一个标签要加上--overwrite

我们发现rs又给我们新建了一个标签为app=rs-app的pod。

这就是rs的一个机制,就是通过label去判断到底哪些pod是归这个rs管的。当有一个pod的label变了,rs发现自己下面的pod少了一个,就又会新建一个来达到期望值3。而app=rs-app1的pod就变为了自主pod,删除了也不会再重启了。

现在删除刚才创建的rs

[root@k8s-master k8s-test]# kubectl delete rs test-rs
replicaset.extensions "test-rs" deleted
[root@k8s-master k8s-test]# kubectl get pod --show-labels
NAME            READY   STATUS    RESTARTS   AGE   LABELS
test-rs-wrrh2   1/1     Running   0          11h   app=rs-app1

属于rs下面的3个pod都随着rs被删除,而自主式pod并没有影响。

Deployment实际操作

下面这个图很好地表现了deployment通过新建rs来达到滚动更新以及回退的过程
1-deployment.png

下面我们用实际操作来验证一下这个过程。

通过yaml文件test-deployment.yaml来创建一个deployment

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: test-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: deployment-app
    spec:
      containers:
        - name: mynginx
          image: mynginx:v1
          ports:
            - containerPort: 80

这里的字段和rs中的差不多,不过少了selector,一会我们就能看到为什么不需要这个selector了。

创建好deployment后会发现它创建了一个rs,名字为deployment的名字加一个hash值,并且下面有3个pod,名字为rs的名字后面再接一个hash值

[root@k8s-master k8s-test]# kubectl apply -f test-deployment.yaml
deployment.extensions/test-deployment created
[root@k8s-master k8s-test]# kubectl get deployment
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
test-deployment   3/3     3            3           5s
[root@k8s-master k8s-test]# kubectl get rs
NAME                        DESIRED   CURRENT   READY   AGE
test-deployment-d796d98d4   3         3         3       16s
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
test-deployment-d796d98d4-kkm25   1/1     Running   0          21s   10.244.1.29   k8s-node1   <none>           <none>
test-deployment-d796d98d4-qknvs   1/1     Running   0          21s   10.244.1.30   k8s-node1   <none>           <none>
test-deployment-d796d98d4-v5v85   1/1     Running   0          21s   10.244.1.28   k8s-node1   <none>           <none>

如果查看每个pod的标签,会发现deployment自动为每个pod加上了一个叫做pod-template-xxx的标签

[root@k8s-master k8s-test]# kubectl get pod --show-labels
NAME                              READY   STATUS    RESTARTS   AGE   LABELS
test-deployment-d796d98d4-kkm25   1/1     Running   0          12m   app=deployment-app,pod-template-hash=d796d98d4
test-deployment-d796d98d4-qknvs   1/1     Running   0          12m   app=deployment-app,pod-template-hash=d796d98d4
test-deployment-d796d98d4-v5v85   1/1     Running   0          12m   app=deployment-app,pod-template-hash=d796d98d4

所以即使我们不加上自己的selector,deployment也会根据这个新的label来进行pod选择。

扩缩容

下面来试一下将3个pod副本自动进行扩缩容。

直接一条命令指定扩缩容后新的副本数量即可,格式为

kubectl scale deployment <deployment_name> --replicas=n

例如将刚才的pod副本扩容为5个

[root@k8s-master k8s-test]# kubectl scale deployment test-deployment --replicas=5
deployment.extensions/test-deployment scaled
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
test-deployment-d796d98d4-kkm25   1/1     Running   0          18m   10.244.1.29   k8s-node1    <none>           <none>
test-deployment-d796d98d4-pwz46   1/1     Running   0          13s   10.244.0.8    k8s-master   <none>           <none>
test-deployment-d796d98d4-qknvs   1/1     Running   0          18m   10.244.1.30   k8s-node1    <none>           <none>
test-deployment-d796d98d4-v5v85   1/1     Running   0          18m   10.244.1.28   k8s-node1    <none>           <none>
test-deployment-d796d98d4-w2k2w   1/1     Running   0          13s   10.244.1.31   k8s-node1    <none>           <none>

再试试缩容到1个

[root@k8s-master k8s-test]# kubectl scale deployment test-deployment --replicas=1
deployment.extensions/test-deployment scaled
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP           NODE         NOMINATED NODE   READINESS GATES
test-deployment-d796d98d4-pwz46   1/1     Running   0          65s   10.244.0.8   k8s-master   <none>           <none>
滚动更新和回滚

下面来试一下前面提到的滚动更新。

首先把pod的副本数量恢复到5个,便于一会儿查看中间过程

[root@k8s-master k8s-test]# kubectl scale deployment test-deployment --replicas=5
deployment.extensions/test-deployment scaled
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES
test-deployment-d796d98d4-9x5c2   1/1     Running   0          2s      10.244.1.34   k8s-node1    <none>           <none>
test-deployment-d796d98d4-pwz46   1/1     Running   0          2m41s   10.244.0.8    k8s-master   <none>           <none>
test-deployment-d796d98d4-r2dt7   1/1     Running   0          2s      10.244.1.35   k8s-node1    <none>           <none>
test-deployment-d796d98d4-rrlkc   1/1     Running   0          2s      10.244.1.33   k8s-node1    <none>           <none>
test-deployment-d796d98d4-rs4zx   1/1     Running   0          2s      10.244.1.32   k8s-node1    <none>           <none>

既然要更新那必须得给容器准备一个新的镜像,创建下面这个Dockerfile

FROM mynginx:v1
RUN echo 'this is mynginx v2' > /usr/share/nginx/html/index.html

这里在v1基础上修改了index.html的内容,这样一会curl比较容易验证。然后生成v2版本的mynginx

[root@k8s-master k8s-test]# docker build -t mynginx:v2 .
Sending build context to Docker daemon   12.8kB
Step 1/2 : FROM mynginx:v1
 ---> 602e111c06b6
Step 2/2 : RUN echo 'this is mynginx v2' > /usr/share/nginx/html/index.html
 ---> Running in bdba2f09126d
Removing intermediate container bdba2f09126d
 ---> 418ab2e19eb5
Successfully built 418ab2e19eb5
Successfully tagged mynginx:v2
[root@k8s-master k8s-test]# docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
mynginx                              v2                  418ab2e19eb5        5 seconds ago       127MB
mynginx                              v1                  602e111c06b6        10 days ago         127MB
nginx                                latest              602e111c06b6        10 days ago         127MB

注意这个新的image必须要所有的node都可以访问到,不然会出现拉取image失败的报错

对deployment的更新命令格式如下

kubectl set image deployment/<deployment_name> <container_name>=<new_image_name>

下面将mynginx的版本更新为v2

[root@k8s-master k8s-test]# kubectl set image deployment/test-deployment mynginx=mynginx:v2
deployment.extensions/test-deployment image updated

之后马上查看pod的状态,此时通过pod的名字可以发现,似乎旧的pod在被停止,而一个新的rs在创建新的pod

[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                               READY   STATUS        RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
test-deployment-64484c94f7-4xwk4   1/1     Running       0          6s    10.244.0.9    k8s-master   <none>           <none>
test-deployment-64484c94f7-646lx   1/1     Running       0          6s    10.244.1.39   k8s-node1    <none>           <none>
test-deployment-64484c94f7-7rg5q   1/1     Running       0          97s   10.244.1.37   k8s-node1    <none>           <none>
test-deployment-64484c94f7-dbthf   1/1     Running       0          8s    10.244.1.38   k8s-node1    <none>           <none>
test-deployment-64484c94f7-lctwk   1/1     Running       0          97s   10.244.1.36   k8s-node1    <none>           <none>
test-deployment-d796d98d4-pwz46    0/1     Terminating   0          19m   10.244.0.8    k8s-master   <none>           <none>
test-deployment-d796d98d4-rrlkc    0/1     Terminating   0          16m   10.244.1.33   k8s-node1    <none>           <none>
test-deployment-d796d98d4-rs4zx    0/1     Terminating   0          16m   10.244.1.32   k8s-node1    <none>           <none>

稍等一会旧的pod就全部被新的取代

[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                               READY   STATUS    RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES
test-deployment-64484c94f7-4xwk4   1/1     Running   0          16s    10.244.0.9    k8s-master   <none>           <none>
test-deployment-64484c94f7-646lx   1/1     Running   0          16s    10.244.1.39   k8s-node1    <none>           <none>
test-deployment-64484c94f7-7rg5q   1/1     Running   0          107s   10.244.1.37   k8s-node1    <none>           <none>
test-deployment-64484c94f7-dbthf   1/1     Running   0          18s    10.244.1.38   k8s-node1    <none>           <none>
test-deployment-64484c94f7-lctwk   1/1     Running   0          107s   10.244.1.36   k8s-node1    <none>           <none>

看看是不是新的镜像

[root@k8s-master k8s-test]# curl 10.244.0.9
this is mynginx v2

升级成功,而正如之前的图片上描述的那样,deployment也确实创建了一个新的rs

[root@k8s-master k8s-test]# kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
test-deployment-64484c94f7   5         5         5       9m14s
test-deployment-d796d98d4    0         0         0       45m

旧的rs并没有消失,这是为了方便做回滚。

回滚的命令格式如下,回滚到上一个版本

kubectl rollout undo deployment/<deployment_name>

回滚到v1版本的mynginx

[root@k8s-master k8s-test]# kubectl rollout undo deployment/test-deployment
deployment.extensions/test-deployment rolled back
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                               READY   STATUS        RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
test-deployment-64484c94f7-646lx   0/1     Terminating   0          11m   10.244.1.39   k8s-node1    <none>           <none>
test-deployment-64484c94f7-lctwk   0/1     Terminating   0          12m   10.244.1.36   k8s-node1    <none>           <none>
test-deployment-d796d98d4-4qjpj    1/1     Running       0          7s    10.244.1.43   k8s-node1    <none>           <none>
test-deployment-d796d98d4-5kvz7    1/1     Running       0          10s   10.244.1.41   k8s-node1    <none>           <none>
test-deployment-d796d98d4-g4stw    1/1     Running       0          8s    10.244.0.10   k8s-master   <none>           <none>
test-deployment-d796d98d4-rpv8w    1/1     Running       0          10s   10.244.1.40   k8s-node1    <none>           <none>
test-deployment-d796d98d4-twrbk    1/1     Running       0          8s    10.244.1.42   k8s-node1    <none>           <none>
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
test-deployment-d796d98d4-4qjpj   1/1     Running   0          10s   10.244.1.43   k8s-node1    <none>           <none>
test-deployment-d796d98d4-5kvz7   1/1     Running   0          13s   10.244.1.41   k8s-node1    <none>           <none>
test-deployment-d796d98d4-g4stw   1/1     Running   0          11s   10.244.0.10   k8s-master   <none>           <none>
test-deployment-d796d98d4-rpv8w   1/1     Running   0          13s   10.244.1.40   k8s-node1    <none>           <none>
test-deployment-d796d98d4-twrbk   1/1     Running   0          11s   10.244.1.42   k8s-node1    <none>           <none>

值得一提的就是滚动更新的过程中,k8s会始终保证有期望数量的pod在运行,最多不少于期望减一个pod。

历史版本

上面提到回滚只能回到上一个版本,而如果再次执行回滚操作又会回到当前版本。那么有没有可能回滚到更早的版本呢,当然是可以的。

查看一下滚动更新的历史纪录

[root@k8s-master k8s-test]# kubectl rollout history deployment/test-deployment
deployment.extensions/test-deployment
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

我们现在在第3个revision,其中第1个revision是v1版本mynginx,第2个revision是v2版本的mynginx,第3个revision是回滚到的v1版本的mynginx。可以通过字段deployment.spec.revisionHistoryLimit去设置要保留多少历史记录,默认是保留所有的记录。

想要回滚到某个revision,可以用命令

kubectl rollout undo deployment/<deployment_name> --to-revision=n

这里我就不演示了。但是值得说明的是,即使k8s提供了这种revision的功能,但是看起来很不清晰,生产环境还是要做好操作记录和配置备份,通过配置文件去回滚。

同时,还可以查询rollout的状态

[root@k8s-master k8s-test]# kubectl set image deployment/test-deployment mynginx=mynginx:v2
deployment.extensions/test-deployment image updated
[root@k8s-master k8s-test]# kubectl rollout status deployment/test-deployment
Waiting for deployment "test-deployment" rollout to finish: 4 out of 5 new replicas have been updated...
Waiting for deployment "test-deployment" rollout to finish: 2 old replicas are pending termination...
Waiting for deployment "test-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "test-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "test-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "test-deployment" rollout to finish: 4 of 5 updated replicas are available...
deployment "test-deployment" successfully rolled out

DaemonSet实际操作

DaemonSet和RS唯一的区别就是不用指定副本数量,因为默认是每个node有且仅有一个副本。

通过yaml文件test-daemonset.yaml去创建一个daemonset

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: test-daemonset
spec:
  selector:
    matchLabels:
      app: daemonset-app
  template:
    metadata:
      labels:
        app: daemonset-app
    spec:
      containers:
        - name: mynginx
          image: mynginx:v2

成功创建,发现每个node有一个pod副本

[root@k8s-master k8s-test]# vim test-daemonset.yaml
[root@k8s-master k8s-test]# kubectl apply -f test-daemonset.yaml
daemonset.extensions/test-daemonset created
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                   READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
test-daemonset-7qp6p   1/1     Running   0          10s   10.244.0.12   k8s-master   <none>           <none>
test-daemonset-ml9c7   1/1     Running   0          10s   10.244.1.48   k8s-node1    <none>           <none>

后面再详细讲如何通过给node添加污点,不让daemonset在上面创建pod。

Job实际操作

通过yaml文件test-job.yaml去创建一个跑一次的任务

apiVersion: batch/v1
kind: Job
metadata:
  name: test-job
spec:
  template:
    spec:
      nodeName: k8s-master
      containers:
        - name: pi
          image: perl
          command: ['perl','-Mbignum=bpi','-wle','print bpi(1000)']
      restartPolicy: Never

这里通过nodeName关键字去选择运行该Job的目标node,也可以用nodeSelector批量去选择。如果不指定则k8s任意选择一个node去执行。

成功创建并执行完job

[root@k8s-master k8s-test]# kubectl get job
NAME       COMPLETIONS   DURATION   AGE
test-job   1/1           29s        29s
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME             READY   STATUS      RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
test-job-8qvlr   0/1     Completed   0          34s   10.244.0.13   k8s-master   <none>           <none>

查看pod的日志可以看到结果

[root@k8s-master k8s-test]# kubectl logs test-job-8qvlr
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199

ConJob实际操作

ConJob是用来创建和管理job的,在cronjob.spec.jobTemplate.spec下有一些字段需要额外说明一下的

  • completions - 指定期望的成功运行job的pod数量,默认为1
  • parallelism - 指定并行pod并发数,默认为1
  • activeDeadlineSeconds - 指定任务运行超时时间,单位为秒

同时在conjob.spec下也有一些字段要注意

  • schedule - 同linux中的contab的写法
  • jobTemplate - 嵌套上面Job的格式
  • startingDeadlineSeconds - 任务启动超时时间
  • concurrencyPolicy - 指定当前一个job还没执行完时,又有一个job需要被执行的的做法
  • successfulJobsHistoryLimit - 指定保留多少个成功的历史记录,默认为3个

下面通过yaml文件test-cronjob.yaml去创建一个定时任务

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: test-conjob
spec:
  schedule: '* * * * *'
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: hello
              image: busybox
              command: ['sh','-c','date;echo hello from the k8s cluster']
          restartPolicy: OnFailure

创建出来以后等待约5分钟,会发现出现了3个job以及3个对应的pod

[root@k8s-master k8s-test]# kubectl get job
NAME                     COMPLETIONS   DURATION   AGE
test-conjob-1588577280   1/1           5s         2m34s
test-conjob-1588577340   1/1           6s         94s
test-conjob-1588577400   1/1           5s         34s
[root@k8s-master k8s-test]# kubectl get pod -o wide
NAME                           READY   STATUS      RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
test-conjob-1588577280-9jp6t   0/1     Completed   0          2m37s   10.244.1.60   k8s-node1   <none>           <none>
test-conjob-1588577340-jzhw6   0/1     Completed   0          97s     10.244.1.62   k8s-node1   <none>           <none>
test-conjob-1588577400-95xc7   0/1     Completed   0          37s     10.244.1.64   k8s-node1   <none>           <none>

即使继续等待也只会出现3个历史记录,由上面说的successfulJobsHistoryLimit参数控制

总结

这一节我们学习了k8s中各种不同的控制器,并且通过实例操作了解了每一种的具体用法。在实际中yaml文件肯定不会像这里这么简单,我们还需要多多用kubectl explain命令去了解每种控制器各个字段的含义,达到熟能生巧的地步。

StatefulSet和HPA的实际操作因为比较复杂这里没有写,我们后来用到的时候再补充。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Kubernetes 008】多种类型控制器区别及实际操作详解(RS,Deployment,DaemonSet,Job,ConJob) 的相关文章

  • Vue + Element UI 实现权限管理系统 前端篇(十四):菜单功能实现菜

    Vue Element UI 实现权限管理系统 前端篇 十四 菜单功能实现 菜单功能实现 菜单接口封装 菜单管理是一个对菜单树结构的增删改查操作 提供一个菜单查询接口 查询整颗菜单树形结构 http modules menu js 添加 f
  • Java爬虫技术(一)普通网站爬取图片

    爬虫简单介绍 用户和网站服务器的操作如下 而爬虫需要做的是模拟仿照用户机 去向服务器发送请求数据 并接受响应数据 接着去解析数据 获得我们想要的数据 步骤大致分为 准备好要爬取的网址 定义爬虫的参数 开始爬 获取爬取的数据 使用xpath技
  • 未来两年以调试osgearth源码为主线,且整合GIS引擎

    按照 https blog csdn net hankern category 9281734 html 本来以为每天调试一节就可以了 没想到 试了3周 结果只调试了3节 平均每周一节 那么就要用2年左右了 花费这么长时间 值不值得呢 跳出
  • com.alibaba.easyexcel导出EXCEL文件

    com alibaba easyexcel导出EXCEL文件 1 POM XML
  • Redis安装配置

    1 下载 http redis io download 2 安装 安装C语言环境 已经安装可跳过 yum install gcc c 下载压缩包 wget http download redis io releases redis 4 0
  • Windows 运行窗口(win+r)常用命令

    打开运行窗口方法 windows系统电脑中 直接按键盘快捷键 win r 通过点击左下角搜索图标 输入 运行 进行搜索 就能找到 运行 点击之后即可打开运行窗口 点击左下角开始程序图标 然后点击 windows系统 之后 点击 运行 即可打
  • 曼彻斯特编码/差分曼彻斯特编码

    1 曼彻斯特编码 Manchester Encoding 位中间电平从低到高跳变表示 0 位中间电平从高到低跳变表示 1 2 差分曼彻斯特编码 differential Manchester encoding 在最初信号的时候 即第一个信号
  • stm32最小系统板烧录的简单说明

    首先 最小系统板烧录往往需要usb转串口模块 可以自行购买 一般买了会附送资料 上面都会有相应的驱动 根据以往的经验来看 这个模块的驱动经常出问题 比如一直显示占用 装了之后需要手动切换 具体可百度 就是打开设备管理器 点击相应com端口
  • Kubernetes 常见问题总结

    如何删除不一致状态下的 rc deployment service 在某些情况下 经常发现 kubectl 进程挂起现象 然后在 get 时候发现删了一半 而另外的删除不了 root k8s master kubectl get f flu
  • css实现勾号 √

    check position relative display inline block width 25px height 25px background red border radius 25px check after conten
  • 经典CNN卷积神经网络发展史+论文+网络实现(PyTorch)

    网络搭建目录 Lenet 学习笔记 pytorch官方demo代码复现 放风筝的猪的博客 CSDN博客 AlexNet网络结构详解与代码复现 放风筝的猪的博客 CSDN博客 VGG网络结构详解与代码复现 感受野计算 放风筝的猪的博客 CSD
  • qt制作播放器-进度条属性设置

    QSlider groove horizontal border 1px solid 4A708B background C0C0C0 height 30px border radius 1px padding left 1px paddi
  • Centos8安装WPS

    下载安装包 到wps官网下载linux版本的安装包 根据自己的linux是 32 位还是64位的 下载对应的安装包 我下载的是64位的rpm包 下载地址 http www wps cn product wpslinux 安装目录 如果想安装
  • Unix哲学

    Unix哲学 起源于Ken Thompson在早期关于如何设计一个设计接口简洁 小巧精干的操作系统的思考 随着Unix文化在学习如何尽可能发掘Thompson设计思想的过程中不断成长 同时它还一路上博采众长 Unix哲学并不是一个正规的设计
  • Vue-ElementUI实现前端多选框切换分页选择保留之前选的数据,分页选择、回显功能

    前端页面开发经常会遇到切换分页时 之前页面选的数据不会保存以及选择的数据如何回显的问题 然后之前写的方法还有个bug 新增数据时 选择多个分页的数据保存后 进入编辑页 如果直接保存的话只会提交首页选择的数据 如果是分页一页一页点击过去 最后
  • ==和equals区别

    对于基本数据类型 byte short char int float double long boolean 比较的是值 他们是作为常量在方法区中的常量池里面以HashSet策略存储起来的 对于这样的字符串 123 也是相同的道理 在常量池
  • java取出每年的七夕情人节日期

    83 java取出每年的七夕情人节日期
  • deactivate不能关闭venv

    python virtualenv deactivate 命令无法正常关闭venv虚拟环境 用的是python3 用vritualenv封装项目后发现 venv目录下没有bin目录 activate文件和deactivate文件在Scrip
  • 中小企业实施MES管理系统,这几点需要注意

    制造业是中国经济命脉所系 是立国之本 强国之基 作为世界制造大国 制造业一直是热门话题 当下 中小制造企业的产业地位不断提升 想要规范生产制造 提升产品竞争力 进行实施MES管理系统解决方案的企业越来越多 那么企业应该如何选型才能保证生产管

随机推荐

  • swift UITextField 设置leftView不生效

    swift 给UITextField 设置了 leftView 但是不显示 设置UITextField的光标输入位置 设置UITextField的leftView 但是没显示 视图层上也没有 let iamgeView UIImageVie
  • macOS Monterey 12.0.1 App闪退问题

    Apple还是一贯的尿性 m1升级了最新的macOS Monterey 12 0 1 发现了一些App闪退 CleanMyMac X 偏好设置 gt 通用 gt 取消 声音 这个选项 重新启动就不会闪退了 MWeb 去AppStore下载了
  • 数电常混淆的知识点(结合FPGA)

    组合逻辑最大的缺点就是会存在竞争冒险 这种竞争冒险问题是非常危险的 常常会引起电路的不稳定性和工作时的不确定性 时序逻辑就可以极大地避免上面的问题 从而使系统更加稳定 时序逻辑最基本的单元就是寄存器 寄存器具有存储功能 一般是由 D 触发器
  • 组合逻辑与时序逻辑的综合

    目录 1 综合简介 1 1 逻辑综合 1 2 RTL综合 1 3 高级综合 2 组合逻辑的综合 2 1 优先级结构的综合 2 2 利用逻辑无关紧要条件 2 3 ASIC单元与资源共享 3 带锁存器的时序逻辑综合 3 1 锁存器的无意综合 3
  • ‘StringArray‘ object has no attribute ‘tolist‘的处理方法

    先看原代码 sams pd array 2weq 2 2432 2 2ewq 2 2ew 1 sam pd unique sams sam tolist 想要利用pd的unique函数将列表里的数据进行去重处理 但是其返回的是一个np ar
  • 无影云桌面

    概念 无影云桌面 是阿里云推出的一台放在云上的超级电脑 这是基于云计算和虚拟化技术的云上桌面服务 通过客户端登录云桌面之后 就像操作本地电脑一样 在云端电脑完成开发 办公 并且数据都在云端 在任何地方都可以登录访问 最近体验了一段时间 操作
  • bazel build //:go

    作者简介 何 源 古典互联网从业者 2014年底加入英语流利说 目前主要负责 Platform Team 来流利说工作之前 在 the Plant 杭州工作 内 容 大 纲 1 程序包管理 Package Management 2 代码管理
  • ENVI_IDL:读取OMI数据(HDF5)并输出为Geotiff文件+详细解析

    目录 1 课堂内容 2 知识储备 3 编程 1 课堂内容 读取OMI数据 HDF5 并输出为Geotiff文件 最重要的是数据的处理以及输出 这里我个人觉得难度不大 第一 获取OMI文件的NO2数据集的数据以及对数据中的异常值做处理 譬如全
  • 进程的五种通信方式

    一 管道 1 什么是管道 我们把一个进程连接到另一个进程的数据流称为一个管道 它是最古老的进程通信形式 2 原型 匿名管道 include
  • 【云原生之Docker实战】使用Docker部署File Manager文件管理系统

    云原生之Docker实战 使用Docker部署File Manager文件管理系统 一 File Manager简介 1 File Manager简介 2 File Manager特点 二 检查宿主机系统版本 三 检查本地docker环境
  • 微软禁俄下载、开源投毒攻击、Rust不会重写Linux、开放原子峰会7月举办

    WeOpen Insight 是腾源会推出的 开源趋势与开源洞见 内容专栏 不定期为读者呈现开源圈内的第一手快讯 优质工具盘点等 洞察开源技术发展的风向标 预见未来趋势 1 开源社区新闻 1 Linus Torvalds 称并未用 Rust
  • java计算月份所在的季度

    java计算月份所在的季度 月份 2 3 下班的时候无意中看到同事写的根据月份计算季度的代码 获取两个时间内的季度集合 返回结果说明 quarterList1 2019 1 quarterList2 2019年1季度 param start
  • IDEA Writing classes... 比较慢

    IDEA配置修改如下 1 File gt Settings 2 Build Execution Deployment gt Compiler Build process heap size 配置为 2048 3 Build Executio
  • hex转换成C语言源程序吗,第6节:把.c源代码编译成.hex机器码的操作流程

    从业十年 教你单片机入门 第6讲 第一步 打开一个现成的工程 双击桌面 keil uVision4 的图标启动keil软件 如果发现此软件默认打开了一个之前已经存在的工程 请点击上面 Project 选项 在弹出的下拉菜单中选择 Close
  • html js实现分页代码,js前端分页实现

    最近做的一个项目 整个页面的数据更新要纯ajax实现 没办法 连分页都得由我来写了 基本思路还是像后台那样实现分页 后台实现分页其实也就是用后台的程序来处理那段分页的模版 于是我想 下面是分页的模版 1 代码 JavaScript 代码 h
  • 常见的颜色空间概念

    文章目录 1 RGB颜色空间 2 HSV颜色空间 3 YCbCr颜色空间 4 Lab颜色空间 5 YUV颜色空间 1 RGB颜色空间 是最常见的面向硬件设备的彩色模型 它是人的视觉系统密切相连的模型 根据人眼结构 所有的颜色都可以看做是3种
  • 2017年阳光私募基金一季度报告

    2017年阳光私募基金一季度报告 时间 2017 05 09 10 14 00 来源 网友评论 0 条 一 证券类私募行业大数据 一 证券类私募行业大数据 一 规模篇 1 私募基金管理规模达11 90万亿 证券类规模为2 63万亿 2 百亿
  • C语言eigen存为txt文件,如何使用线性代数的C模板库Eigen?

    我有一个矩阵的图像处理算法 我有自己的矩阵运算代码 乘法 逆 但我使用的处理器是ARM Cortex A8处理器 它有NEON协处理器进行矢量化 因为矩阵运算是SIMD操作的理想情况 我要求编译器 mfpu neon mfloat abi
  • webrtc音频引擎之audio_processing介绍

    audio processing模块为语音处理的精华 包含音频的回音处理 降噪处理 自动增益处理等音频的核心处理业务算法 静音检测在另外一个模块 不知道新版与这基本算法放到了同一个模块木有 模块结构为 1 aec和aecm 也就是回音消除
  • 【Kubernetes 008】多种类型控制器区别及实际操作详解(RS,Deployment,DaemonSet,Job,ConJob)

    Pod是k8s中的基本结构 前面我们已经创建过一个 但是生产环境中往往不需要我们自己去创建pod 而是通过创建管理pod的控制器而达到自动批量管理pod的目的 这一节我们就一起来看看k8s中有哪些控制器 以及这些控制器的一些基本操作 我是T