Kubernetes进阶 -- 五种控制器的使用方法

控制器

  • Pod 的分类:
    • 自主式 Pod:Pod 退出后不会被创建
    • 控制器管理的 Pod:在控制器的生命周期里,始终要维持 Pod 的副本数目
  • 控制器类型:
    • Replication Controller和ReplicaSet
    • Deployment
    • DaemonSet
    • StatefulSet
    • Job //定时任务
    • CronJob //重复任务
    • HPA全称Horizontal Pod Autoscaler

Replication Controller和ReplicaSet

  • ReplicaSet 是下一代的 Replication Controller,官方推荐使用ReplicaSet。
  • ReplicaSet 和 Replication Controller 的唯一区别是选择器的支持,ReplicaSet支持新的基于集合的选择器需求。
  • ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。
  • 虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创
    建、删除和更新的机制。

Deployment

  • Deployment 为 Pod 和 ReplicaSet 提供了一个申明式的定义方法。

典型的应用场景:

  • 用来创建Pod和ReplicaSet
  • 滚动更新和回滚
  • 扩容和缩容
  • 暂停与恢复

DaemonSet

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

DaemonSet 的典型用法:

  • 在每个节点上运行集群存储 DaemonSet,例如 glusterd、ceph。
  • 在每个节点上运行日志收集 DaemonSet,例如 fluentd、logstash。
  • 在每个节点上运行监控 DaemonSet,例如 Prometheus Nodexporter、zabbix agent等
  • 一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种
    类型的 daemon 使用。
  • 一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,
    但具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。

StatefulSet

  • StatefulSet 是用来管理有状态应用的工作负载 API 对象。实例之间有不对
    等关系,以及实例对外部数据有依赖关系的应用,称为“有状态应用”
  • StatefulSet 用来管理 Deployment 和扩展一组 Pod,并且能为这些 Pod
    提供序号和唯一性保证
  • StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:
    • 稳定的、唯一的网络标识符。
    • 稳定的、持久的存储。
    • 有序的、优雅的部署和缩放。
    • 有序的、自动的滚动更新。

Job

  • 执行批处理任务,仅执行一次任务,保证任务的一个或多个Pod成功结束。

CronJob

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

HPA

  • 根据资源利用率自动调整service中Pod数量,实现Pod水平自动缩放。

Replicaset控制器示例

[root@server2 manifest]# vim rs.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1

[root@server2 manifest]# kubectl apply -f rs.yml 
replicaset.apps/replicaset-example created
[root@server2 manifest]# kubectl get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
replicaset-example-dcrwh   1/1     Running   0          16s   10.244.2.38   server4   <none>           <none>
replicaset-example-l8gw8   1/1     Running   0          16s   10.244.1.63   server3   <none>           <none>
replicaset-example-mlx8p   1/1     Running   0          16s   10.244.2.39   server4   <none>           <none>
[root@server2 manifest]# vim rs.yml
spec:
  replicas: 2		
[root@server2 manifest]# kubectl apply -f rs.yml 	直接应用,不用删除之前的副本
replicaset.apps/replicaset-example configured
[root@server2 manifest]# kubectl get pod -o wide
NAME                       READY   STATUS        RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
replicaset-example-dcrwh   1/1     Running       0          2m19s   10.244.2.38   server4   <none>           <none>
replicaset-example-l8gw8   1/1     Running       0          2m19s   10.244.1.63   server3   <none>           <none>
replicaset-example-mlx8p   0/1     Terminating   0          2m19s   10.244.2.39   server4   <none>           <none>
	//这个正在回收,默认会回收最新的pod
[root@server2 manifest]# kubectl  get all
NAME                           READY   STATUS    RESTARTS   AGE
pod/replicaset-example-dcrwh   1/1     Running   0          9m11s
pod/replicaset-example-l8gw8   1/1     Running   0          9m11s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/replicaset-example   2         2         2       9m11s
// 多了一个控制器在前面

那我们让副本数不变,更换镜像哪?

spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2		// 改成v2

[root@server2 manifest]# kubectl  apply -f rs.yml 
replicaset.apps/replicaset-example configured
[root@server2 manifest]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
replicaset-example-dcrwh   1/1     Running   0          11m
replicaset-example-l8gw8   1/1     Running   0          11m
// 还是这两个pod,没有变。

[root@server2 manifest]# vim  rs.yml
  replicas: 4		//再将副本改称4个
...
        image: myapp:v2	
[root@server2 manifest]# kubectl  apply -f rs.yml 
replicaset.apps/replicaset-example configured
[root@server2 manifest]# kubectl get pod -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
replicaset-example-bsckv   1/1     Running   0          2m    10.244.1.64   server3   <none>           <none>
replicaset-example-dcrwh   1/1     Running   0          15m   10.244.2.38   server4   <none>           <none>
replicaset-example-jkvfb   1/1     Running   0          2m    10.244.2.40   server4   <none>           <none>
replicaset-example-l8gw8   1/1     Running   0          15m   10.244.1.63   server3   <none>           <none>
// 新开起了两个容器,我们进行访问:

[root@server2 manifest]# curl 10.244.2.40
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server2 manifest]# curl 10.244.1.64
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@server2 manifest]# curl 10.244.1.63
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 manifest]# curl 10.244.2.38
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

//通过访问我们发现,副本数不变更改镜像,不会发生改变,增加副本数改变镜像,新增的副本使用改变后的镜像。

若要想直接全部更新,就需要使用deployment控制器了。

Deployment控制器

[root@server2 manifest]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment	//和rs控制器写法一致,只有这里改变,因为deployment调用的底层就是rs控制器
metadata:
  name: deployment-example
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1

[root@server2 manifest]# kubectl apply -f deployment.yml 
deployment.apps/deployment-example created
[root@server2 manifest]# kubectl get all
NAME                                      READY   STATUS    RESTARTS   AGE
pod/deployment-example-7449b5b68f-cnxsw   1/1     Running   0          18s
pod/deployment-example-7449b5b68f-kv7zb   1/1     Running   0          18s
pod/deployment-example-7449b5b68f-rfbtf   1/1     Running   0          18s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deployment-example   3/3     3            3           18s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/deployment-example-7449b5b68f   3         3         3       18s                      

我们可以看到不止有deployment控制器,还有rs控制器

pod/deployment-example-7449b5b68f-cnxsw
这个pod的名称是由 pod 名 + rs名 + pod唯一标示 组成的.

[root@server2 manifest]# vim deployment.yml 
...
    spec:
      containers:
      - name: myapp
        image: myapp:v2		//将镜像换为v2
[root@server2 manifest]# kubectl apply -f deployment.yml 
kubec	deployment.apps/deployment-example configured

[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS              RESTARTS   AGE
deployment-example-67764dd8bd-bqxt4   1/1     Running             0          7s
deployment-example-67764dd8bd-z8mf4   1/1     Running             0          5s
deployment-example-67764dd8bd-zwdgr   0/1     ContainerCreating   0          2s
deployment-example-7449b5b68f-cnxsw   0/1     Terminating         0          7m32s
deployment-example-7449b5b68f-kv7zb   1/1     Running             0          7m32s
deployment-example-7449b5b68f-rfbtf   1/1     Terminating         0          7m32s
[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS        RESTARTS   AGE
deployment-example-67764dd8bd-bqxt4   1/1     Running       0          16s
deployment-example-67764dd8bd-z8mf4   1/1     Running       0          14s
deployment-example-67764dd8bd-zwdgr   1/1     Running       0          11s

现在我们在更换镜像的时候会直接删除原来的三个容器,重新打开三个pod。
而且:

[root@server2 manifest]# kubectl get all
...
NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deployment-example   3/3     3            3           10m

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/deployment-example-67764dd8bd   3         3         3       3m4s
replicaset.apps/deployment-example-7449b5b68f   0         0         0       10m

生成了一个新的rs控制器,但是原来的rs还保留着,这是用于回滚的。
新生成的三个pod都使用的是新的rs控制器生成的。

  • 回滚
[root@server2 manifest]# vim deployment.yml 
...
    spec:
      containers:
      - name: myapp
        image: myapp:v1		//改回v1
[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-7449b5b68f-c94st   1/1     Running   0          23s
deployment-example-7449b5b68f-f59mw   1/1     Running   0          20s
deployment-example-7449b5b68f-lwq2k   1/1     Running   0          17s
它就会使用原来的那个rs。
  • pod更新
    当我们发现一个pod的状态不正常时,我们可以直接删除这个pod,控制器回自动的拉取一个新的pod:
[root@server2 manifest]# kubectl delete pod deployment-example-7449b5b68f-c94st 
pod "deployment-example-7449b5b68f-c94st" deleted
[root@server2 manifest]# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
deployment-example-7449b5b68f-f59mw   1/1     Running   0          4m14s	//新pod
deployment-example-7449b5b68f-lwq2k   1/1     Running   0          4m11s
deployment-example-7449b5b68f-wwpgp   1/1     Running   0          17s
  • pod删除
[root@server2 manifest]# kubectl delete  -f  deployment.yml 
deployment.apps "deployment-example" deleted
[root@server2 manifest]# kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d
// 连同控制器,rs,pod一块删除了

多个控制器

多个控制器和多个资源的放时一样,用—分割开就行了

[root@server2 manifest]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v1

---		//分割线

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-v2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:v2
[root@server2 manifest]# kubectl apply -f deployment.yml 
deployment.apps/deployment-v1 created
deployment.apps/deployment-v2 created
[root@server2 manifest]# kubectl get deployments.apps 
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
deployment-v1   3/3     3            3           10s
deployment-v2   3/3     3            3           10s
[root@server2 manifest]# kubectl get rs
NAME                       DESIRED   CURRENT   READY   AGE
deployment-v1-7449b5b68f   3         3         3       105s
deployment-v2-67764dd8bd   3         3         3       105s
[root@server2 manifest]# kubectl get pod -o wide
NAME                             READY   STATUS    RESTARTS   AGE    IP            NODE      NOMINATED NODE   READINESS GATES
deployment-v1-7449b5b68f-csldb   1/1     Running   0          119s   10.244.1.73   server3   <none>           <none>
deployment-v1-7449b5b68f-srkxx   1/1     Running   0          119s   10.244.2.49   server4   <none>           <none>
deployment-v1-7449b5b68f-x5c59   1/1     Running   0          119s   10.244.2.50   server4   <none>           <none>
deployment-v2-67764dd8bd-bmmrc   1/1     Running   0          119s   10.244.2.51   server4   <none>           <none>
deployment-v2-67764dd8bd-m5c2g   1/1     Running   0          119s   10.244.1.75   server3   <none>           <none>
deployment-v2-67764dd8bd-zf8wx   1/1     Running   0          119s   10.244.1.74   server3   <none>           <none>
  • 删除
[root@server2 manifest]# kubectl delete deployments.apps deployment-v1
deployment.apps "deployment-v1" deleted
[root@server2 manifest]# kubectl get all
NAME                                 READY   STATUS        RESTARTS   AGE
pod/deployment-v1-7449b5b68f-g2s28   1/1     Terminating   0          87s
pod/deployment-v1-7449b5b68f-l4z8q   0/1     Terminating   0          87s
pod/deployment-v1-7449b5b68f-mqkqc   1/1     Terminating   0          87s
pod/deployment-v2-67764dd8bd-89t2z   1/1     Running       0          87s
pod/deployment-v2-67764dd8bd-rqsjn   1/1     Running       0          87s
pod/deployment-v2-67764dd8bd-sqrzg   1/1     Running       0          87s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d

NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deployment-v2   3/3     3            3           87s

NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/deployment-v2-67764dd8bd   3         3         3       87s

删除v1,v2还在。

Daemonset控制器

Daemonset控制器适用于每个节点运行一个的pod。
我们之前使用的控制器不是在每个结点运行一个的,而是有可能都再一个结点运行:

[root@server2 manifest]# kubectl get pod -o wide
NAME                             READY   STATUS              RESTARTS   AGE   IP       NODE      NOMINATED NODE   READINESS GATES
deployment-v1-7449b5b68f-jz5h9   0/1     ContainerCreating   0          3s    <none>   server4   <none>           <none>
deployment-v1-7449b5b68f-lmksm   0/1     ContainerCreating   0          3s    <none>   server4   <none>           <none>
deployment-v1-7449b5b68f-v9d64   0/1     ContainerCreating   0          3s    <none>   server4   <none>           <none>
[root@server2 manifest]# vim daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-example
  labels:
    k8s-app: zabbix-agent
spec:
  selector:
    matchLabels:
      name: zabbix-agent
  template:
    metadata:
      labels:
        name: zabbix-agent
    spec:
      containers:
      - name: zabbix-agent
        image:  zabbix-agent

[root@server2 manifest]# kubectl apply -f daemonset.yml 
daemonset.apps/daemonset-example created
[root@server2 manifest]# kubectl get pod -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
daemonset-example-67tmd   1/1     Running   0          6s    10.244.1.78   server3   <none>           <none>
daemonset-example-qjtks   1/1     Running   0          6s    10.244.2.56   server4   <none>           <none>
//一个结点一个,新加入的结点页回自动拉起一个这个pod

job控制器

[root@server2 manifest]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  template:
    metadata:
      name: example-job
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl"]
        args: ["-Mbignum=bpi", "-wle", "print bpi(2000)"]	//计算pi的值.2000位
      restartPolicy: Never

[root@server2 manifest]# kubectl apply -f job.yml 
job.batch/example-job created
[root@server2 manifest]# kubectl get pod -w
NAME                READY   STATUS              RESTARTS   AGE
example-job-9vzb9   0/1     ContainerCreating   0          42s	//正在拉取镜像,比较大
example-job-9vzb9   1/1     Running             0          50s	//正在计算
example-job-9vzb9   0/1     Completed           0          54s	//计算完毕
[root@server2 manifest]# kubectl logs example-job-9vzb9 
3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384
[root@server2 manifest]# kubectl get job
NAME          COMPLETIONS   DURATION   AGE
example-job   1/1           54s        3m16s
[root@server2 manifest]# kubectl delete -f job.yml 
job.batch "example-job" deleted
[root@server2 manifest]# kubectl get job
No resources found in default namespace.

cronjob控制器

执行周期性任务。

[root@server2 manifest]# vim cronjob.yml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cronjob-example
spec:
  schedule: "* * * * *"		//每分钟
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cronjob
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from k8s cluster
          restartPolicy: OnFailure
[root@server2 manifest]# kubectl apply -f cronjob.yml 
cronjob.batch/cronjob-example created
No resources found in default namespace.
[root@server2 manifest]# kubectl get pod 	//每分钟执行一次,所以等待一分钟
No resources found in default namespace.
[root@server2 manifest]# kubectl get pod 
NAME                               READY   STATUS      RESTARTS   AGE
cronjob-example-1593239100-hd4mk   0/1     Completed   0          3s
[root@server2 manifest]# kubectl logs cronjob-example-1593239100-hd4mk 
Sat Jun 27 06:25:03 UTC 2020
Hello from k8s cluster
//再等待一分钟
[root@server2 manifest]# kubectl get pod 
NAME                               READY   STATUS      RESTARTS   AGE
cronjob-example-1593239100-hd4mk   0/1     Completed   0          60s
[root@server2 manifest]# kubectl get pod 
NAME                               READY   STATUS      RESTARTS   AGE
cronjob-example-1593239100-hd4mk   0/1     Completed   0          66s
cronjob-example-1593239160-mzwrz   0/1     Completed   0          5s	//又拉起一个
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章