K8S之控制器

本文深入介绍了Kubernetes中的核心控制器,包括Deployment(用于无状态应用,提供声明式更新和副本管理)、StatefulSet(针对有状态应用,保证Pod顺序和持久存储)、DaemonSet(确保每个Node上运行一个Pod,常用于Agent)、Job(一次性任务执行)和CronJob(周期性任务调度)。通过示例展示了如何创建和管理这些控制器,以及它们在实际应用中的场景和作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、控制器

控制器:又称之为工作负载,分别包含以下类型控制器
1:Deployment
2:StatefulSet
3:DaemonSet
4:Job
5:CronJob

二、Pod与控制器之间的关系

controllers:在集群上管理和运行容器的对象通过label-selector相关联
Pod通过控制器实现应用的运维,如伸缩,升级等
在这里插入图片描述

(一)、Deployment

部署无状态应用
管理Pod和ReplicaSet
具有上线部署、副本设定、滚动升级、回滚等功能
提供声明式更新,例如只更新一个新的Image
应用场景:web服务

示例:

[root@localhost demo]# kubectl create -f nginx-deployment.yaml
//Replicaset 是控制版本,副本数,回滚就是通过此来实现
[root@localhost demo]# kubectl get pods,deploy,rs
NAME                                  READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-d55b94fd-9pwvk   1/1     Running   0          45s
pod/nginx-deployment-d55b94fd-dk4sr   1/1     Running   0          45s
pod/nginx-deployment-d55b94fd-ncrbk   1/1     Running   0          45s
pod/pod-example                       1/1     Running   0          39m

NAME                                     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/nginx-deployment   3         3         3            3           45s

NAME                                              DESIRED   CURRENT   READY   AGE
replicaset.extensions/nginx-deployment-d55b94fd   3         3         3       45s

//查看控制器
[root@localhost demo]# kubectl edit deployment/nginx-deployment
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.15.4
        imagePullPolicy: IfNotPresent
  name: nginx-deployment
  namespace: default
  resourceVersion: "880370"
  selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
  uid: d5f1ec3d-50cd-11ea-895a-000c297a15fb

//查看历史版本
[root@localhost demo]# kubectl rollout history deployment/nginx-deployment
deployment.extensions/nginx-deployment 
REVISION  CHANGE-CAUSE
1         <none>

(二)、SatefulSet

部署有状态应用
解决Pod独立生命周期,保持Pod启动顺序和唯一性
稳定,唯一的网络标识符,持久存储(例如:etcd配置文件,节点地址发生变化,将无法使用)
有序,优雅的部署和扩展、删除和终止(例如:mysql主从关系,先启动主,再启动从)
有序,滚动更新
应用场景:数据库
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/

无状态:
1)deployment 认为所有的pod都是一样的
2)不用考虑顺序的要求
3)不用考虑在哪个node节点上运行
4)可以随意扩容和缩容

有状态
1)实例之间有差别,每个实例都有自己的独特性,元数据不同,例如etcd,zookeeper
2)实例之间不对等的关系,以及依靠外部存储的应用。

常规service和无头服务区别
service:一组Pod访问策略,提供cluster-IP群集之间通讯,还提供负载均衡和服务发现。
Headless service 无头服务,不需要cluster-IP,直接绑定具体的Pod的IP

示例:

[root@localhost demo]# kubectl create -f nginx-service.yaml 
service/nginx-service created
[root@localhost demo]# kubectl get svc
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.0.0.1     <none>        443/TCP        18d
nginx-service   NodePort    10.0.0.202   <none>        80:32655/TCP   3m17s
//在node节点上操作(注意:coredns地址统一,否则无法解析)
[root@localhost ~]# systemctl restart flanneld.service 
[root@localhost ~]# systemctl restart docker
//查看群集间通讯
[root@localhost ~]# curl 10.0.0.202
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

//headless方式(因为Pod动态IP地址,所以常用于绑定DNS访问)
[root@localhost demo]# vim headless.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

[root@localhost demo]# kubectl apply -f headless.yaml 
service/nginx created
[root@localhost demo]# kubectl get svc
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.0.0.1     <none>        443/TCP        19d
nginx           ClusterIP   None         <none>        80/TCP         28s
nginx-service   NodePort    10.0.0.202   <none>        80:32655/TCP   15m

//复制coredns.yaml到master01的root家目录
在这里插入图片描述

https://www.kubernetes.org.cn/4694.html
[root@localhost ~]# ls
coredns.yaml 
[root@localhost ~]# kubectl create -f coredns.yaml
serviceaccount/coredns created
clusterrole.rbac.authorization.k8s.io/system:coredns created
clusterrolebinding.rbac.authorization.k8s.io/system:coredns created
configmap/coredns created
deployment.extensions/coredns created
service/kube-dns created
[root@localhost ~]# kubectl get pods -n kube-system
NAME                                    READY   STATUS    RESTARTS   AGE
coredns-56684f94d6-mvrw5                1/1     Running   0          2m15s
kubernetes-dashboard-7dffbccd68-txcmp   1/1     Running   2          9d
[root@localhost ~]# cd demo/
[root@localhost demo]# vim pod3.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: dns-test
spec:
  containers:
  - name: busybox
    image: busybox:1.28.4
    args:
    - /bin/sh
    - -c
    - sleep 36000
  restartPolicy: Never

//验证dns解析
[root@localhost demo]# kubectl create -f pod6.yaml 
pod/dns-test created
[root@localhost demo]# kubectl get svc
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.0.0.1     <none>        443/TCP        19d
nginx           ClusterIP   None         <none>        80/TCP         24m
nginx-service   NodePort    10.0.0.202   <none>        80:32655/TCP   39m
//解析kubernetes和nginx-service名称
[root@localhost demo]# kubectl exec -it dns-test sh
/ # nslookup kubernetes
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
/ # nslookup nginx-service
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      nginx-service
Address 1: 10.0.0.202 nginx-service.default.svc.cluster.local
[root@localhost demo]# vim sts.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1  
kind: StatefulSet  
metadata:
  name: nginx-statefulset  
  namespace: default
spec:
  serviceName: nginx  
  replicas: 3  
  selector:
    matchLabels:  
       app: nginx
  template:  
    metadata:
      labels:
        app: nginx  
    spec:
      containers:
      - name: nginx
        image: nginx:latest  
        ports:
        - containerPort: 80  

//清理所有pod
[root@localhost demo]# kubectl delete -f .
[root@localhost demo]# kubectl create -f sts.yaml 
statefulset.apps/nginx-statefulset created
[root@localhost demo]# kubectl get pods
NAME                  READY   STATUS    RESTARTS   AGE
nginx-statefulset-0   1/1     Running   0          30s
nginx-statefulset-1   1/1     Running   0          17s
nginx-statefulset-2   1/1     Running   0          9s

[root@localhost demo]# kubectl get pods,svc
NAME                      READY   STATUS    RESTARTS   AGE
pod/nginx-statefulset-0   1/1     Running   0          4m51s
pod/nginx-statefulset-1   1/1     Running   0          4m38s
pod/nginx-statefulset-2   1/1     Running   0          4m30s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP   19d
service/nginx        ClusterIP   None         <none>        80/TCP    64s

[root@localhost demo]# kubectl apply -f pod6.yaml 
pod/dns-test created
//解析pod的唯一域名和自身的ip
[root@localhost demo]# kubectl exec -it dns-test sh
/ # nslookup nginx-statefulset-0.nginx
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      nginx-statefulset-0.nginx
Address 1: 172.17.42.2 nginx-statefulset-0.nginx.default.svc.cluster.local
/ # nslookup nginx-statefulset-1.nginx
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      nginx-statefulset-1.nginx
Address 1: 172.17.25.2 nginx-statefulset-1.nginx.default.svc.cluster.local
/ # nslookup nginx-statefulset-2.nginx
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local

Name:      nginx-statefulset-2.nginx
Address 1: 172.17.42.3 nginx-statefulset-2.nginx.default.svc.cluster.local

//总结
StatefulSet与Deployment区别:有身份的!
身份三要素:
域名 nginx-statefulset-0.nginx
主机名 nginx-statefulset-0
存储(PVC)

(三)、DaemonSet

在每一个Node上运行一个Pod
新加入的Node也同样会自动运行一个Pod

应用场景:Agent
https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
//官方案例(监控)

在这里插入图片描述

示例:

[root@localhost demo]# vim ds.yaml 

apiVersion: apps/v1
kind: DaemonSet 
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

[root@localhost demo]# kubectl apply -f ds.yaml 
daemonset.apps/nginx-deployment created
//DaemonSet会在每个node节点都创建一个Pod
[root@localhost demo]# kubectl get pods
nginx-deployment-4kr6h   1/1     Running     0          35s
nginx-deployment-8jrg5   1/1     Running     0          35s

(四)、Job

Job分为普通任务(Job)和定时任务(CronJob)
一次性执行
应用场景:离线数据处理,视频解码等业务
https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/
在这里插入图片描述

示例:
//示例中,重试次数默认是6次,修改为4次,当遇到异常时Never状态会重启,所以要设定次数。

[root@localhost demo]# vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

//在node节点下载perl镜像,因为镜像比较大所以提前下载好
[root@localhost ~]# docker pull perl

Using default tag: latest
latest: Pulling from library/perl
dc65f448a2e2: Already exists 
346ffb2b67d7: Already exists 
dea4ecac934f: Already exists 
8ac92ddf84b3: Already exists 
a3ca60abc08a: Pull complete 
a4d37f8b7daf: Pull complete 
9aab83cf2239: Pull complete 
Digest: sha256:73eb380276164e629d2daa86dc58aab1a89b462646739cb62a59090dd1aaaa4a
Status: Downloaded newer image for perl:latest
docker.io/library/perl:latest

[root@localhost demo]# kubectl apply -f job.yaml 
job.batch/pi created
//计算完成状态
[root@localhost demo]# kubectl get pods
pi-bqtf7                 0/1     Completed   0          41s
//结果输出到控制台
[root@localhost demo]# kubectl logs pi-bqtf7
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901

[root@localhost demo]# kubectl get job
NAME   COMPLETIONS   DURATION   AGE
pi     1/1           24s        3m37s
//清除job资源
[root@localhost demo]# kubectl delete -f job.yaml 
job.batch "pi" deleted

(五)、CronJob

周期性任务,像Linux的Crontab一样。
周期性任务
应用场景:通知,备份

https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/
在这里插入图片描述

示例:

//每分钟打印hello
[root@localhost ~]# vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

[root@localhost demo]# kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          25s
[root@localhost demo]# kubectl get pods
NAME                     READY   STATUS      RESTARTS   AGE
hello-1581917340-dzxbj   0/1     Completed   0          24s
[root@localhost demo]# kubectl logs hello-1581917340-dzxbj
Mon Feb 17 05:29:09 UTC 2020
Hello from the Kubernetes cluster
//等待一分钟后又会再执行一次
[root@localhost demo]# kubectl get pods
hello-1581917340-dzxbj   0/1     Completed   0          2m45s
hello-1581917400-nkb72   0/1     Completed   0          105s
<think>好的,我现在需要回答用户关于Kubernetes控制器原理和使用教程的问题。首先,我得先理解用户的需求。用户提到了控制器的原理和使用教程,可能需要一个结构化的回答,覆盖基本概念、工作原理、常见控制器类型以及具体的使用步骤。 首先,我应该回顾一下Kubernetes控制器的基本概念。根据引用中的信息,控制器属于控制平面的组件,比如Controller-Manager,用户提到的引用[2]提到可以自定义调度器,这可能与控制器有关。控制器的作用是确保集群的实际状态与期望状态一致,这一点应该是核心。 接下来是控制器的工作原理。这里需要解释控制循环(Control Loop)的过程,包括监测状态、计算差异和执行操作。可能需要结合引用中的例子,比如StatefulSet配合StorageClass(引用[4]),说明控制器如何管理有状态应用。 然后要列出常见的控制器类型,比如Deployment、StatefulSet、DaemonSet、Job/CronJob。每个类型需要简要说明其用途,并可能给出YAML示例,因为引用[3]提到Yaml用于描述资源参数。 使用教程部分需要分步骤,比如安装kubectl、编写YAML、部署、监控状态、扩缩容和更新。每个步骤要有具体命令和示例,这样用户能跟着操作。例如,Deployment的YAML示例,如何应用,查看状态,扩缩容命令等。 注意事项部分需要强调网络、存储和资源限制,这部分可以结合引用[4]提到的StorageClass动态供给,说明存储配置的重要性。同时,引用[2]提到自定义调度器,可能涉及到控制器的扩展。 最后生成相关问题,需要围绕控制器的类型、选择依据、调试、自定义开发以及与准入控制的关系(引用[1]提到准入控制,可能用户会想知道两者的关联)。 需要注意引用标记,在回答中适当的位置添加引用,比如在讲控制器类型时提到StatefulSet和StorageClass时引用[4],在自定义调度器时引用[2]。 检查是否所有数学公式都正确使用$...$或$$...$$,虽然这个问题可能涉及较少数学,但如果有版本号或类似的地方需要注意。例如,可能不需要数学公式,但如果有命令中的变量,可能需要正确格式。 最后确保回答结构清晰,分点明确,语言简洁,符合用户要求的中文回答,并正确引用相关段落。</think>### Kubernetes控制器原理及使用教程 #### 一、控制器核心原理 Kubernetes控制器是控制平面的关键组件,通过**控制循环(Control Loop)**持续监控集群状态,确保实际状态与用户定义的期望状态一致[^2]。其工作原理可分为三步: 1. **状态监测**:通过API Server监听资源对象的变更事件(如Pod创建、删除) 2. **差异计算**:对比`spec`(期望状态)与`status`(实际状态) 3. **调谐操作**:执行扩缩容、重启等操作(例如Deployment控制器通过ReplicaSet维护Pod副本数) $$ \text{控制循环} = \text{监听} \rightarrow \text{比较} \rightarrow \text{修正} $$ #### 二、常见控制器类型 1. **Deployment** - 用途:管理无状态应用,支持滚动更新和回滚 - 示例YAML[^3]: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 ``` 2. **StatefulSet** - 用途:管理有状态应用(如数据库),提供稳定的网络标识和持久化存储[^4] - 特性:有序部署、唯一域名、与StorageClass动态绑定 3. **DaemonSet** - 用途:确保所有(或特定)节点运行指定Pod(如日志收集组件) 4. **Job/CronJob** - 用途:执行一次性任务或定时任务 #### 三、使用教程(以Deployment为例) 1. **安装kubectl** ```bash curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x kubectl && sudo mv kubectl /usr/local/bin/ ``` 2. **编写YAML文件** 创建`deployment.yaml`(参考上述示例) 3. **部署应用** ```bash kubectl apply -f deployment.yaml ``` 4. **监控状态** ```bash kubectl get deployments -w # 实时查看部署进度 kubectl describe deployment/nginx-deployment # 查看详细事件 ``` 5. **扩缩容操作** ```bash kubectl scale deployment nginx-deployment --replicas=5 ``` 6. **更新与回滚** ```bash kubectl set image deployment/nginx-deployment nginx=nginx:1.21 # 更新镜像 kubectl rollout undo deployment/nginx-deployment # 回滚到上一版本 ``` #### 四、关键注意事项 1. **网络配置**:确保Pod间通信正常(如使用Calico网络插件) 2. **存储配置**:StatefulSet需配合PersistentVolume使用[^4] 3. **资源限制**:在YAML中定义`resources.requests/limits`防止资源争抢 §§ 1. Deployment和StatefulSet如何选择? 2. 如何调试控制器调谐失败的问题? 3. 如何开发自定义控制器? 4. 准入控制与控制器如何协作[^1]? --- [^1]: 准入控制器在请求处理链中先于控制器生效,用于验证/修改资源对象的创建请求 [^2]: 控制器管理器通过多个控制循环实现状态协调 [^3]: Yaml文件通过声明式语法定义资源规格 : StatefulSet需配合存储类实现持久化卷动态供给
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值