首頁技術(shù)文章正文

K8s控制器類型及演示[IT運(yùn)維培訓(xùn)]

更新時(shí)間:2020-04-30 來源:黑馬程序員 瀏覽量:

1577370495235_學(xué)IT就到黑馬程序員.gif

一、Pod控制器

Pod 的分類

1、自主式 Pod

Pod 退出后不會(huì)被創(chuàng)建

2、控制器管理的 Pod

在控制器的生命周期里,始終要維持 Pod 的副本數(shù)目

3、控制器類型

Replication Controller和ReplicaSetDeploymentDaemonSetStatefulSetJobCronJobHPA全稱Horizontal Pod AutoscalerReplication Controller和ReplicaSetReplicaSet (RS)是下一代的 Replication Controller(RC),官方推薦使用ReplicaSet。

ReplicaSet 和 Replication Controller 的唯一區(qū)別是選擇器的支持,ReplicaSet 支持新的基于集合的選擇器需求。

ReplicaSet 確保任何時(shí)間都有指定數(shù)量的 Pod 副本在運(yùn)行。

雖然 ReplicaSets 可以獨(dú)立使用,但今天它主要被Deployments 用作協(xié)調(diào) Pod 創(chuàng)建、刪除和更新的機(jī)制。推薦了解黑馬程序員linux云計(jì)算+運(yùn)維開發(fā)課程。

1)Deployment

Deployment 為 Pod 和 ReplicaSet 提供了一個(gè)申明式的定義方法。

.典型的應(yīng)用場(chǎng)景:

用來創(chuàng)建Pod和ReplicaSet滾動(dòng)更新和回滾擴(kuò)容和縮容暫停與恢復(fù)

2)DaemonSet

DaemonSet 確保全部(或者某些)節(jié)點(diǎn)上運(yùn)行一個(gè) Pod 的副本。當(dāng)有節(jié)點(diǎn)加入集群時(shí), 也會(huì)為他們新增一個(gè) Pod 。當(dāng)有節(jié)點(diǎn)從集群移除時(shí),這些 Pod 也會(huì)被回收。刪除 DaemonSet 將會(huì)刪除它創(chuàng)建的所有 Pod。

DaemonSet 的典型用法:

在每個(gè)節(jié)點(diǎn)上運(yùn)行集群存儲(chǔ) DaemonSet,例如 glusterd、ceph。在每個(gè)節(jié)點(diǎn)上運(yùn)行日志收集 DaemonSet,例如 fluentd、logstash。在每個(gè)節(jié)點(diǎn)上運(yùn)行監(jiān)控 DaemonSet,例如 Prometheus Node Exporter、zabbix agent等一個(gè)簡(jiǎn)單的用法是在所有的節(jié)點(diǎn)上都啟動(dòng)一個(gè) DaemonSet,將被作為每種類型的 daemon 使用。

一個(gè)稍微復(fù)雜的用法是單獨(dú)對(duì)每種 daemon 類型使用多個(gè) DaemonSet,但具有不同的標(biāo)志, 并且對(duì)不同硬件類型具有不同的內(nèi)存、CPU 要求。

3)StatefulSet

StatefulSet 是用來管理有狀態(tài)應(yīng)用的工作負(fù)載 API 對(duì)象。實(shí)例之間有不對(duì)等關(guān)系,以及實(shí)例對(duì)外部數(shù)據(jù)有依賴關(guān)系的應(yīng)用,稱為“有狀態(tài)應(yīng)用”

StatefulSet 用來管理 Deployment 和擴(kuò)展一組 Pod,并且能為這些 Pod 提供序號(hào)和唯一性保證。

StatefulSets 對(duì)于需要滿足以下一個(gè)或多個(gè)需求的應(yīng)用程序很有價(jià)值:

穩(wěn)定的、唯一的網(wǎng)絡(luò)標(biāo)識(shí)符。穩(wěn)定的、持久的存儲(chǔ)。有序的、優(yōu)雅的部署和縮放。有序的、自動(dòng)的滾動(dòng)更新。Job執(zhí)行批處理任務(wù),僅執(zhí)行一次任務(wù),保證任務(wù)的一個(gè)或多個(gè)Pod成功結(jié)束。

4)CronJob

Cron Job 創(chuàng)建基于時(shí)間調(diào)度的 Jobs。

一個(gè) CronJob 對(duì)象就像 crontab (cron table) 文件中的一行,它用 Cron 格式進(jìn)行編寫,并周期性地在給定的調(diào)度時(shí)間執(zhí)行 Job。

HPA根據(jù)資源利用率自動(dòng)調(diào)整service中Pod數(shù)量,實(shí)現(xiàn)Pod水平自動(dòng)縮放。

二、Pod控制器使用示例

ReplicaSet舉例

1、編輯以下yaml文件:

[root@server1 ~]# vim rs.yaml 

[root@server1 ~]# cat rs.yaml 

apiVersion: apps/v1

kind: ReplicaSet

metadata:

    name: replicaset-example

spec:

  replicas: 2 #啟動(dòng)pod的副本數(shù)

  selector: #定義選擇器為標(biāo)簽選擇器。

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx #定義容器的標(biāo)簽

    spec: #定義容器

      containers:

      - name: nginx

        image: nginx

2、運(yùn)行

以上使用的控制器的RS,RS控制器通過pod的標(biāo)簽(matchLabels)來控制pod的數(shù)量,使用apply命令可以實(shí)現(xiàn)創(chuàng)建,更新pod,而create命令創(chuàng)建后若需要更新只能刪除之后再創(chuàng)建,因此建議使用apply:

[root@server1 ~]# kubectl apply -f rs.yaml 

replicaset.apps/replicaset-example created

[root@server1 ~]# kubectl apply -f rs.yaml 

replicaset.apps/replicaset-example unchanged

3、查看狀態(tài):

[root@server1 ~]# kubectl get pod

NAME                       READY   STATUS    RESTARTS   AGE

replicaset-example-p6sv6   1/1     Running   0          34s

replicaset-example-s5jps   1/1     Running   0          34s

[root@server1 ~]# kubectl get rs #獲取rs的信息

NAME                 DESIRED   CURRENT   READY   AGE

replicaset-example   2         2         2       36s

[root@server1 ~]# kubectl get pod -o wide

NAME                       READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES

replicaset-example-p6sv6   1/1     Running   0          38s   10.244.1.14   server2   <none>           <none>

replicaset-example-s5jps   1/1     Running   0          38s   10.244.2.21   server3   <none>           <none>

可以看出一且正常,接下來進(jìn)行pod的拉伸與壓縮:

4、拉伸副本數(shù):

[root@server1 ~]# vim rs.yaml 

[root@server1 ~]# cat rs.yaml 

apiVersion: apps/v1

kind: ReplicaSet

metadata:

    name: replicaset-example

spec:

  replicas: 4 #拉伸為4個(gè)

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: nginx


[root@server1 ~]# kubectl apply -f rs.yaml 

replicaset.apps/replicaset-example configured


5、查看pod數(shù)

[root@server1 ~]# kubectl get pod

NAME                       READY   STATUS    RESTARTS   AGE

replicaset-example-p6sv6   1/1     Running   0          97s

replicaset-example-s5jps   1/1     Running   0          97s

replicaset-example-wzclz   1/1     Running   0          21s

replicaset-example-zk4mb   1/1     Running   0          21s

已經(jīng)被拉伸成了4個(gè)。


6、縮減

[root@server1 ~]# vim rs.yaml 

[root@server1 ~]# cat rs.yaml 

apiVersion: apps/v1

kind: ReplicaSet

metadata:

    name: replicaset-example

spec:

  replicas: 2 #縮減為2個(gè)

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: nginx


[root@server1 ~]# kubectl apply -f rs.yaml 

replicaset.apps/replicaset-example configured

[root@server1 ~]# kubectl get pod

NAME                       READY   STATUS        RESTARTS   AGE

replicaset-example-p6sv6   1/1     Running       0          2m6s

replicaset-example-s5jps   1/1     Running       0          2m6s


可以看出刪除的是剛剛創(chuàng)建的那兩個(gè)pod。

7、更改一個(gè)pod 的標(biāo)簽:

[root@server1 ~]# kubectl label pod replicaset-example-s5jps app=myapp --overwrite   #將標(biāo)簽強(qiáng)制更改為myapp
pod/replicaset-example-s5jps labeled
[root@server1 ~]# kubectl get pod --show-labels
NAME                       READY   STATUS    RESTARTS   AGE     LABELS
replicaset-example-p6sv6   1/1     Running   0          3m56s   app=nginx
replicaset-example-s5jps   1/1     Running   0          3m56s   app=myapp
replicaset-example-w98nk   1/1     Running   0          26s     app=nginx


可以看出現(xiàn)在有3個(gè)pod,兩個(gè)標(biāo)簽為nginx一個(gè)為myapp,RS控制器的工作原理就是維持標(biāo)簽為nginx的pod個(gè)數(shù)有2個(gè),因此當(dāng)我們更改一個(gè)pod的標(biāo)簽后,RS又會(huì)給我們創(chuàng)建一個(gè)標(biāo)簽為nginx的pod,而當(dāng)我們將標(biāo)簽為myapp的pod刪除后RS控制器不會(huì)有操作:

[root@server1 ~]# kubectl delete pod replicaset-example-s5jps

pod "replicaset-example-s5jps" deleted

[root@server1 ~]# kubectl get pod --show-labels

NAME                       READY   STATUS    RESTARTS   AGE    LABELS

replicaset-example-p6sv6   1/1     Running   0          5m8s   app=nginx

replicaset-example-w98nk   1/1     Running   0          98s    app=nginx

8、再更改驗(yàn)證:

[root@server1 ~]# kubectl label pod replicaset-example-p6sv6 app=myapp --overwrite #首先保證3個(gè)pod

pod/replicaset-example-p6sv6 labeled

[root@server1 ~]# kubectl get pod --show-labels

NAME                       READY   STATUS    RESTARTS   AGE     LABELS

replicaset-example-p6sv6   1/1     Running   0          6m4s    app=myapp

replicaset-example-w98nk   1/1     Running   0          2m34s   app=nginx

replicaset-example-x2lq9   1/1     Running   0          26s     app=nginx


[root@server1 ~]# kubectl label pod replicaset-example-p6sv6 app=nginx --overwrite

pod/replicaset-example-p6sv6 labeled

[root@server1 ~]# kubectl get pod --show-labels

NAME                       READY   STATUS        RESTARTS   AGE     LABELS

replicaset-example-p6sv6   1/1     Running       0          6m23s   app=nginx

replicaset-example-w98nk   1/1     Running       0          2m53s   app=nginx

replicaset-example-x2lq9   0/1     Terminating   0          45s     app=nginx

[root@server1 ~]# kubectl get pod --show-labels

NAME                       READY   STATUS    RESTARTS   AGE     LABELS

replicaset-example-p6sv6   1/1     Running   0          6m25s   app=nginx

replicaset-example-w98nk   1/1     Running   0          2m55s   app=nginx

以上實(shí)驗(yàn)可以看出,當(dāng)集群里有3個(gè)標(biāo)簽是nginx的pod的時(shí)候,RS控制器又會(huì)幫我們將最后創(chuàng)建的pod刪除。
實(shí)驗(yàn)后刪除:

[root@server1 ~]# kubectl delete -f rs.yaml 

replicaset.apps "replicaset-example" deleted

Deployment控制器示例

1、編輯yaml文件:

Deployment控制器示例 編輯yaml文件:

[root@server1 ~]# vim deployment.yaml 

[root@server1 ~]# cat deployment.yaml 

apiVersion: apps/v1

kind: Deployment

metadata:

  name: deployment-nginx

  labels:

    app: nginx

spec:

  replicas: 2

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: ikubernetes/myapp:v1

        ports:

        - containerPort: 80

2、創(chuàng)建pod:

[root@server1 ~]# kubectl apply -f deployment.yaml
deployment.apps/deployment-nginx created
[root@server1 ~]# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
deployment-nginx-56d786cd98-kx5pw   1/1     Running   0          23s
deployment-nginx-56d786cd98-qgcjl   1/1     Running   0          23s

[root@server1 ~]# kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
deployment-nginx-56d786cd98   2         2         2       28s
[root@server1 ~]# kubectl get deployments.apps   #查看deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
deployment-nginx   2/2     2            2           32s

以上運(yùn)行結(jié)果可以看出deployments底層也是由RS實(shí)現(xiàn)的,接下來

3、進(jìn)行拉伸:

[root@server1 ~]# vim deployment.yaml 

[root@server1 ~]# cat deployment.yaml 

apiVersion: apps/v1

kind: Deployment

metadata:

  name: deployment-nginx

  labels:

    app: nginx

spec:

  replicas: 4 #拉伸為4個(gè)

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: ikubernetes/myapp:v1

        ports:

        - containerPort: 80


[root@server1 ~]# kubectl apply -f deployment.yaml 

deployment.apps/deployment-nginx configured

[root@server1 ~]# kubectl get pod

NAME                                READY   STATUS    RESTARTS   AGE

deployment-nginx-56d786cd98-942dh   1/1     Running   0          26s

deployment-nginx-56d786cd98-kx5pw   1/1     Running   0          108s

deployment-nginx-56d786cd98-qgcjl   1/1     Running   0          108s

deployment-nginx-56d786cd98-zb8s8   1/1     Running   0          26s

可以看出已經(jīng)拉伸為4個(gè)。接下來進(jìn)行

4、滾動(dòng)更新:

[root@server1 ~]# vim deployment.yaml 

[root@server1 ~]# cat deployment.yaml 

apiVersion: apps/v1

kind: Deployment

metadata:

  name: deployment-nginx

  labels:

    app: nginx

spec:

  replicas: 4

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: ikubernetes/myapp:v2 #更新到v2

        ports:

        - containerPort: 80


[root@server1 ~]# kubectl apply -f deployment.yaml 

deployment.apps/deployment-nginx configured

[root@server1 ~]# kubectl get pod -o wide

NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES

deployment-nginx-868855d887-2zh45   1/1     Running   0          2m39s   10.244.2.26   server3   <none>           <none>

deployment-nginx-868855d887-87m22   1/1     Running   0          2m34s   10.244.1.20   server2   <none>           <none>

deployment-nginx-868855d887-hb6mv   1/1     Running   0          2m39s   10.244.1.19   server2   <none>           <none>

deployment-nginx-868855d887-v8ndt   1/1     Running   0          2m33s   10.244.2.27   server3   <none>           <none>

[root@server1 ~]# curl 10.244.2.26

Hello MyApp | Version: v2 | Pod Name


可以看出更新時(shí)控制器新建一個(gè)rs,然后再新建4個(gè)pod,原來的rs依然存在,為了方便我們

5、進(jìn)行回滾:

[root@server1 ~]# vim deployment.yaml 

[root@server1 ~]# cat deployment.yaml 

apiVersion: apps/v1

kind: Deployment

metadata:

  name: deployment-nginx

  labels:

    app: nginx

spec:

  replicas: 4

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - name: nginx

        image: ikubernetes/myapp:v1

        ports:

        - containerPort: 80

[root@server1 ~]# kubectl apply -f deployment.yaml 

deployment.apps/deployment-nginx configured

[root@server1 ~]# kubectl get pod

NAME                                READY   STATUS              RESTARTS   AGE

deployment-nginx-56d786cd98-78m7z   0/1     ContainerCreating   0          4s

deployment-nginx-56d786cd98-8hnns   1/1     Running             0          9s

deployment-nginx-56d786cd98-lcvzw   1/1     Running             0          9s

deployment-nginx-56d786cd98-xkjhq   0/1     ContainerCreating   0          3s

deployment-nginx-868855d887-2zh45   1/1     Running             0          3m22s

deployment-nginx-868855d887-hb6mv   1/1     Terminating         0          3m22s

deployment-nginx-868855d887-v8ndt   1/1     Terminating         0          3m16s


[root@server1 ~]# kubectl get pod

NAME                                READY   STATUS    RESTARTS   AGE

deployment-nginx-56d786cd98-78m7z   1/1     Running   0          26s

deployment-nginx-56d786cd98-8hnns   1/1     Running   0          31s

deployment-nginx-56d786cd98-lcvzw   1/1     Running   0          31s

deployment-nginx-56d786cd98-xkjhq   1/1     Running   0          25s

可以看出原來v1版本的rs被重新啟用,再原來的rs下面新建4個(gè)pod。當(dāng)然我門也可以使用kubectl delete rs --all命令刪除不用的rs(注意:正在使用的rs不會(huì)刪除):

[root@server1 ~]# kubectl delete rs --all

replicaset.apps "deployment-nginx-56d786cd98" deleted

replicaset.apps "deployment-nginx-868855d887" deleted

[root@server1 ~]# kubectl get pod

NAME                                READY   STATUS    RESTARTS   AGE

deployment-nginx-56d786cd98-6r589   1/1     Running   0          21s

deployment-nginx-56d786cd98-hvz24   1/1     Running   0          21s

deployment-nginx-56d786cd98-k62lj   1/1     Running   0          21s

deployment-nginx-56d786cd98-ss97z   1/1     Running   0          21s

[root@server1 ~]# kubectl get rs

NAME                          DESIRED   CURRENT   READY   AGE

deployment-nginx-56d786cd98   4         4         4       24s #正在使用的RS不會(huì)刪除

實(shí)驗(yàn)后刪除:

[root@server1 ~]# kubectl delete -f deployment.yaml 

deployment.apps "deployment-nginx" deleted

DaemonSet舉例

1、編輯yaml

DaemonSet控制器保證每個(gè)節(jié)點(diǎn)上都運(yùn)行一個(gè)pod:

[root@server1 ~]# vim daemonset.yaml 

[root@server1 ~]# cat daemonset.yaml 

apiVersion: apps/v1

kind: DaemonSet

metadata:

  name: daemonset-example

  labels:

    app: zabbix-agent

spec:

  selector:

    matchLabels:

      name: zabbix-agent

  template:

    metadata:

      labels:

        name: zabbix-agent

    spec:

      containers:

  - name: zabbix-agent

        image: zabbix/zabbix-agent

2、創(chuàng)建pod:

[root@server1 ~]# kubectl apply -f daemonset.yaml 

daemonset.apps/daemonset-example created

[root@server1 ~]# kubectl get pod

NAME                      READY   STATUS    RESTARTS   AGE

daemonset-example-ctbgh   1/1     Running   0          6m5s

daemonset-example-mdqzk   1/1     Running   0          6m5s


[root@server1 ~]# kubectl get pod -o wide

NAME                      READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES

daemonset-example-ctbgh   1/1     Running   0          7m16s   10.244.2.32   server3   <none>           <none>

daemonset-example-mdqzk   1/1     Running   0          7m16s   10.244.1.25   server2   <none>           <none>


可以看出我們的每個(gè)節(jié)點(diǎn)(server3和server2)上都運(yùn)行了一個(gè)pod

3、刪除一個(gè)pod:

[root@server1 ~]# kubectl delete pod daemonset-example-ctbgh

pod "daemonset-example-ctbgh" deleted

[root@server1 ~]# kubectl get pod -o wide

NAME                      READY   STATUS              RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES

daemonset-example-998ck   0/1     ContainerCreating   0          8s      <none>        server3   <none>           <none>

daemonset-example-mdqzk   1/1     Running             0          8m22s   10.244.1.25   server2   <none>           <none>

[root@server1 ~]# kubectl get pod -o wide

NAME                      READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES

daemonset-example-998ck   1/1     Running   0          24s     10.244.2.33   server3   <none>           <none>

daemonset-example-mdqzk   1/1     Running   0          8m38s   10.244.1.25   server2   <none>           <none>


可以看出刪除后DaemonSet控制器又會(huì)幫我們創(chuàng)建pod,以保證每個(gè)節(jié)點(diǎn)運(yùn)行一個(gè)pod。

實(shí)驗(yàn)后刪除:


[root@server1 ~]# kubectl delete -f daemonset.yaml 

daemonset.apps "daemonset-example" deleted

Job控制器舉例

1、編輯yaml

Job控制器只運(yùn)行一次

[root@server1 ~]# vim job.yaml 

[root@server1 ~]# cat job.yaml 

apiVersion: batch/v1

kind: Job

metadata:

  name: pi

spec:

  template:

    spec:

      containers:

  - name: pi

        image: perl #利用perl計(jì)算圓周率

        command: ["perl",  "-Mbignum=bpi", "-wle", "print      bpi(2000)"]

      restartPolicy: Never

  backoffLimit: 4 #容器啟動(dòng)失敗重啟4次之后不再重啟。


2、創(chuàng)建
kubectl apply -f job.yaml

由于Job只運(yùn)行一次,因此運(yùn)行完后狀態(tài)為Completed,我們可以查看日志獲取結(jié)果:

可以看出計(jì)算成功。

實(shí)驗(yàn)后刪除:


[root@server1 ~]# kubectl delete -f job.yaml 

job.batch "pi" deleted


CronJob控制器舉例

CronJob控制器用于定時(shí)執(zhí)行任務(wù):


[root@server1 ~]# vim cronjob.yaml 

[root@server1 ~]# cat cronjob.yaml 

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

Crontab

其中schedule字段與crontab里面的寫法相同," * * * *"表示每分鐘執(zhí)行任務(wù)。

1、創(chuàng)建pod:

[root@server1 ~]# kubectl apply -f cronjob.yaml 

cronjob.batch/cronjob-example created

root@server1 ~]# kubectl get pod

NAME                               READY   STATUS              RESTARTS   AGE

cronjob-example-1587387120-ngt6n   0/1     ContainerCreating   0          16s

[root@server1 ~]# kubectl get pod #等待一分鐘

NAME                               READY   STATUS              RESTARTS   AGE

cronjob-example-1587387120-ngt6n   0/1     Completed           0          60s

cronjob-example-1587387180-hbwzb   0/1     ContainerCreating   0          9s


可以看出每分鐘運(yùn)行一個(gè)pod,查看日志獲取輸出信息:

[root@server1 ~]# kubectl logs cronjob-example-1587387120-ngt6n

Mon Apr 20 12:52:30 UTC 2020

Hello from k8s cluster

[root@server1 ~]# kubectl logs cronjob-example-1587387180-hbwzb

Mon Apr 20 12:53:35 UTC 2020

Hello from k8s cluster

可以看出輸出也是每分鐘輸出一次,也可以使用以下命令查看cronjob的信息:

[root@server1 ~]# kubectl get cronjobs

NAME              SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE

cronjob-example   * * * * *   False     1        16s             3m10s


[root@server1 ~]# kubectl get job -w #查看job信息并且持續(xù)輸出

NAME                         COMPLETIONS   DURATION   AGE

cronjob-example-1587387120   1/1           20s        2m23s

cronjob-example-1587387180   1/1           35s        92s

cronjob-example-1587387240   1/1           20s        32s


實(shí)驗(yàn)后刪除

[root@server1 ~]# kubectl delete -f cronjob.yaml 

cronjob.batch "cronjob-example" deleted

猜你喜歡:

Docker stack 一鍵編排Inmp

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!