【云原生】kubernetes学习之资源对象控制器概述---概念和实战五

一,kubernetes内的资源(或者称之为对象)

首先,应该是思考一个问题,为什么kubernetes里要引入资源(对象)这个概念?

Kubernetes 中的所有内容都被抽象为“资源”,如 Pod、Service、Node 等都是资源。“对象”就是“资源”的实例,是持久化的实体。如某
个具体的 Pod、某个具体的 Node。Kubernetes 使用这些实体去表现整个集群的状态。
对象的创建、删除、修改都是通过 “Kubernetes API”,也就是 “Api Server” 组件提供的 API 接口,这些是 RESTful 风格的 Api,与 k8s
的“万物皆对象”理念相符。命令行工具 “kubectl”,实际上也是调用的 kubernetes api。
K8s 中的资源类别有很多种,kubectl 可以通过配置文件来创建这些 “对象”,配置文件更像是描述对象“属性”的文件,配置文件格式可以
是 “JSON” 或 “YAML”,常用 “YAML”

那么,以下这些资源或者称之为对象的东西在kubernetes内是由哪个服务提供的呢?kube-apiserver这个服务提供的。

常见资源类型及API

  • 资源对象:Pods(po)、ReplicaSets(rs)、ReplicationControllers(rc)、Deployment、StatefulSet、DaemonSet(ds)、Job、CronJob(cj),HorizontalPodAutoscaling、Node、Namespace(ns)、Services(svc)、Ingress(ing)、Label、CustomResourceDefinition,nodes(no)
  • 存储对象:Volume、PersistentVolume(pv)、PersistentVolumeClaim(pvc)、Secret、ConfigMap(cm),componentstatuses(cs)
  • 策略对象:SecurityContext.ResourceQuota、LimitRange
  • 身份对象:ServiceAccounts(sa)、Role、ClusterRole,clusterrolebindings
  • 以上是资源以及它们的缩写,例如,kubectl get no 等于kubectl get nodes
  • 对象是用来完成某些任务的,是持久的,是有目的性的,因此 kubernetes 创建每个对象后,将持续地工作以确保对象存在(例如pod)。当
    然,kubernetes 并不只是维持对象的存在这么简单,kubernetes 还管理着对象的属性。

查询kubernetes内有哪些资源呢?通过命令 kubectl  api-resources 即可看到。

[root@master ~]# k api-resources
NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND
bindings                                                                      true         Binding
componentstatuses                 cs                                          false        ComponentStatus
configmaps                        cm                                          true         ConfigMap
endpoints                         ep                                          true         Endpoints
events                            ev                                          true         Event
limitranges                       limits                                      true         LimitRange
namespaces                        ns                                          false        Namespace
。。。。。略略略

例如,一个最为简单的资源清单文件,使用了namespace这个资源(kind后面就是资源名称),执行这个文件将会创建一个名字叫ns-elk的namespace:

[root@master ~]# cat 00-ns.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: ns-elk

 

kubernetes的学习基本也是围绕着上面查询出来的各种各样的资源来展开的,那如何使用这些资源又是一个难点,因此,kubernetes又提出了一个概念---控制器。

二,

控制器

kubernetes的基础服务kube-controller-manager内建了很多controller(控制器),这些相当于一个状态机,用来控制pod的具体状态和行为。kube-controller-manager 由一系列的控制器组成(并不完整,常用的控制器):

Replication Controller
Node Controller
CronJob Controller
Daemon Controller
Deployment Controller
Endpoint Controller
Garbage Collector
Namespace Controller
Job Controller
Pod AutoScaler
RelicaSet
Service Controller
ServiceAccount Controller
StatefulSet Controller
Volume Controller
Resource quota Controller

 

非常常用的控制器有这些:

  • 确保预期的Pod副本数量---ReplicationController 和 ReplicaSet
  • 无状态应用部署----Deployment Controller
  • 有状态应用部署----StatefulSet Controller
  • 确保所有的node运行同一个pod----Daemonset Controller
  • 一次性任务和定时任务-----CronJob Controller和Job Controller

1,ReplicationController 和 ReplicaSet

ReplicationController用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收,Replication Controller简称RC。

在新版本的Kubernetes中建议使用ReplicaSet来取代ReplicationController。ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,并且ReplicaSet支持集合式的selector。Replication Set简称RS。

虽然ReplicaSet可以独立使用,但一般还是建议使用 Deployment 来自动管理ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)。

下面是一个安装nginx的示例,使用的是ReplicationController这个控制器:

[root@master ~]# cat demo-replica.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

查询pods如下:

[root@master ~]# k get po -A -o wide
NAMESPACE     NAME                                      READY   STATUS      RESTARTS   AGE   IP               NODE      NOMINATED NODE   READINESS GATES
default       nginx-7mfzc                               1/1     Running     0          40m   10.244.1.9       slave1    <none>           <none>
default       nginx-8djp7                               1/1     Running     0          40m   10.244.1.10      slave1    <none>           <none>
default       nginx-s5xgq                               1/1     Running     0          40m   10.244.2.10      slave2    <none>           <none>

删除任意一个nginx 的pod,由于是多副本部署,将会自动重新拉起一个新的pod以保持规定的pod数目。

如果想要彻底删除相关pod,需要先查询出rc的名称,然后删除rc就可以了。

[root@master ~]# k get rc -A
NAMESPACE   NAME    DESIRED   CURRENT   READY   AGE
default     nginx   3         3         3       47s

k delete rc nginx

下面仍然是一个安装nginx的示例,使用的是Replicationset这个控制器,nginx的版本是指定为1.20.2:

[root@master ~]# cat demo-replica.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-test
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      name: nginx
      labels:
        app: myapp
    spec:
      containers:
      - name: nginx
        image: nginx:1.20.2
        ports:
        - containerPort: 80

这里需要注意一点,和ReplicationController不同的,Replicationset是在app组下,因此,apiVersion: apps/v1,选择器使用的是matchLabels,别的基本都是一样的。当然,删除也是一样的。只是查询的时候是rs不是rc了,也就是这个了:kuberctl get rs -A

Replication Controller和ReplicaSet的创建删除和Pod并无太大区别,Replication Controller目前几乎已经不在生产环境中使用,ReplicaSet也很少单独被使用,都是使用更高级的资源Deployment、DaemonSet、StatefulSet进行管理Pod。

2,Deployment Controller

Deployment 主要是用于部署无状态的服务,这也是最常用的控制器。一般用于管理维护企业内部无状态的微服务,比如configserver、zuul、springboot。他可以管理多个副本的Pod实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。

Deployment Controller的主要作用:

  • 发布应用
  • 升级应用
  • 回退应用
  • 扩缩容

它和上面的rc和rs相比较,多了升级,回退,扩缩容的功能。

首先一个示例,还是部署nginx,这次版本更改为1.18,部署在test这个namespace内,副本数量是1(这个叫test的namespace要先建立哦):

[root@master ~]# cat web01.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  namespace: test
  labels:
    app: web01
  name: web01
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web01
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web01
    spec:
      containers:
      - image: nginx:1.18
        imagePullPolicy: IfNotPresent
        name: nginx
        resources: {}
status: {}

deployment controller控制器并不直接管理pod,而是通过管理replicaset来间接管理pod,即:deployment管理replicaset,replicaset管理pod。

[root@master ~]# k get rs -A
NAMESPACE     NAME                                DESIRED   CURRENT   READY   AGE
kube-system   coredns-6c76c8bb89                  2         2         2       71d
kube-system   nfs-client-provisioner-6fc484bd4f   1         1         1       26h
test          web01-5464b576c5                    1         1         1       12m
[root@master ~]# k get deploy -A
NAMESPACE     NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   coredns                  2/2     2            2           71d
kube-system   nfs-client-provisioner   1/1     1            1           26h
test          web01                    1/1     1            1           25m

因此,我们可以看到的是,get rs和get deploy 是一样结果,但deploy有一个 UP-TO-DATE,并且名称也不一样。但是看到的pod是一致的哦。

水平扩展---将web01这个部署扩展到三个副本:

[root@master ~]# k scale deploy web01 --replicas=3 -n test
deployment.apps/web01 scaled

水平扩展后,可以看到,slave1节点多了两个nginx的pod。

[root@master ~]# k get po -n test -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
web01-859c876457-d5978   1/1     Running   0          2m56s   10.244.1.23   slave1   <none>           <none>
web01-859c876457-j7hd5   1/1     Running   0          3m35s   10.244.2.20   slave2   <none>           <none>
web01-859c876457-mbt7p   1/1     Running   0          2m56s   10.244.1.24   slave1   <none>           <none>

当然,扩缩容以及发布等等还有很多的地方可写,比如,蓝灰发布,hpa自动扩缩容等等,内容太多,以后单独一文写吧。 

 

3,StatefulSet Controller

StatefulSet Controller主要是用于部署有状态的服务有状态的pod与无状态的pod不一样的是,有状态的pod有时候需要通过其主机名来定位,而无状态的不需要,因为无状态的pod每个都是一样的,随机选一个就行,但对于有状态的来说,每一个pod都不一样,通常希望操作的是特定的某一个。

statefulset适用于需要以下特点的应用:
(1)稳定的网络标志(主机名):Pod重新调度后其PodName和HostName不变;
(2)稳定的持久化存储:基于PVC,Pod重新调度后仍能访问到相同的持久化数据;
(3)稳定的创建与扩容次序:有序创建或扩容,从序号小到大的顺序对pod进行创建(即从0到N-1),且在下一个Pod创建运行之前,所有之前的Pod必须都是Running和Ready状态;
(4)稳定的删除与缩容次序:有序删除或缩容,从序号大到小的顺序对pod进行删除(即从N-1到0),且在下一个Pod终止与删除之前,所有之前的Pod必须都已经被删除;
(5)稳定的滚动更新次序:从序号大到小的顺序对pod进行更新(即从N-1到0),先删除后创建,且需等待当前序号的pod再次创建完成且状态为Ready时才能进行下一个pod的更新处理。

示例,nginx使用volume挂载保存首页状态,具体代码如下:

sc是这个:

[root@master ~]# k get sc -A
NAME                  PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   fuseim.pri/ifs   Delete          Immediate           true                   28h

service和StatefulSet一起编写。 

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
     app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: sts-nginx
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.18
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]  # ["ReadWriteOnce","ReadWriteMany"]
      storageClassName: managed-nfs-storage
      resources:
        requests:
          storage: 1Gi

查看pv,pvc和pod的名称以及状态。 

[root@master ~]# k get pvc -A
NAMESPACE   NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
default     test-claim   Bound    pvc-39177650-a78e-46d4-899c-7c1f52108280   1Mi        RWX            managed-nfs-storage   28h
default     www-web-0    Bound    pvc-ffd14bef-e852-4955-840d-6d3c84d3c3d8   1Gi        RWO            managed-nfs-storage   19m
default     www-web-1    Bound    pvc-5fd485a8-9e7b-470f-816f-d674cb5d7648   1Gi        RWO            managed-nfs-storage   19m
[root@master ~]# k get pv -A
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS          REASON   AGE
pvc-39177650-a78e-46d4-899c-7c1f52108280   1Mi        RWX            Delete           Bound    default/test-claim   managed-nfs-storage            28h
pvc-5fd485a8-9e7b-470f-816f-d674cb5d7648   1Gi        RWO            Delete           Bound    default/www-web-1    managed-nfs-storage            19m
pvc-ffd14bef-e852-4955-840d-6d3c84d3c3d8   1Gi        RWO            Delete           Bound    default/www-web-0    managed-nfs-storage            19m

[root@master ~]# k get po -A |grep web
default       web-0                                     1/1     Running     0          21m
default       web-1                                     1/1     Running     0          21m

由以上输出可以看到statefulset的命名规则和删除规则:

statefulset pod的命名规则、pod创建与删除
如果创建一个名称为web、replicas为3的statefulset对象,则其pod名称分别为web-0、web-1、web-2。

statefulset pod的创建按0 - n的顺序创建,且在创建下一个pod之前,需要等待前一个pod创建完成并处于ready状态。

同样拿上面的例子来说明,在web statefulset创建后,2 个 Pod 将按顺序创建 web-0,web-1。在 web-0 处于 ready 状态之前,web-1 将不会被创建。直到 web-0 再次回到ready状态。

statefulset滚动更新或缩容过程中pod的删除按n - 0的顺序删除,且在删除下一个pod之前,需要等待前一个pod删除完成。

另外,当statefulset.Spec.VolumeClaimTemplates中定义了pod所需的pvc时,statefulset controller在创建pod时,会同时创建对应的pvc出来,但删除pod时,不会做对应pvc的删除操作,这些pvc需要人工额外做删除操作。
 

4,Daemonset Controller

  • DaemonSet:服务守护进程,它的主要作用是在Kubernetes集群的所有节点中运行我们部署的守护进程,相当于在集群节点上分别部署Pod副本,如果有新节点加入集群,Daemonset会自动的在该节点上运行我们需要部署的Pod副本,相反如果有节点退出集群,Daemonset也会移除掉部署在旧节点的Pod副本。
  • DaemonSet的主要特征:

这个 Pod 运行在 Kubernetes 集群里的每一个节点(Node)上;

每个节点上只会运行一个这样的 Pod 实例;

如果新的节点加入 Kubernetes 集群后,该 Pod 会自动地在新节点上被创建出来;

而当旧节点被删除后,它上面的 Pod 也相应地会被回收掉。

  • DaemonSet常用场景:

网络插件的 Agent 组件,如(Flannel,Calico)需要运行在每一个节点上,用来处理这个节点上的容器网络;
存储插件的 Agent 组件,如(Ceph,Glusterfs)需要运行在每一个节点上,用来在这个节点上挂载F远程存储目录;
监控系统的数据收集组件,如(Prometheus Node Exporter,Cadvisor)需要运行在每一个节点上,负责这个节点上的监控信息搜集。
日志系统的数据收集组件,如(Fluent,Logstash)需要运行在每一个节点上,负责这个节点上的日志信息搜集。

下面是一个示例,该示例将会在每个node内创建一个nginx-1.9.9版本的pod,除了master节点:

[root@master ~]# cat ds-test.yaml 
apiVersion: apps/v1
kind: DaemonSet # 类型为DaeminSet
metadata:
  name: deamonset-example
  labels:
    app: daemonset
spec:
  selector:
    matchLabels:
      name: deamonset-example  # 当前这个 daemenset 只管理标签 name=deamonset-example的pod
  template:
    metadata:
      labels:
        name: deamonset-example  # 设置标签 匹配上文
    spec:
      containers:
      - name: daemonset-example
        image: nginx:1.9.9

5,CronJob Controller和Job Controller

Job Controller
简单示例一个,比如,打印π值到2000位,代码如下:

[root@master ~]# cat job-test
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  completions: 3
  template:
      spec:
        containers:
        - name: pi
          image: registry.cn-beijing.aliyuncs.com/google_registry/perl:5.26
          command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
        restartPolicy: Never
  backoffLimit: 4

执行这个文件:

k apply -f job-test.yaml

查看pod状态:

[root@master ~]# k get po -A |grep pi
default       pi-5zzr7                                  0/1     Completed   0          32m
default       pi-nhgqg                                  0/1     Completed   0          35m
default       pi-slf4k                                  0/1     Completed   0          32m

查看日志,证明这个job完成了:

[root@master ~]# k logs  pi-slf4k
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275898

其中有一个参数可以自动清理:

activeDeadlineSeconds: 10

这个表示该job运行成功10秒后,自动删除pod,那么,如果是需要看一下log的job,以确认job完成无误的话,这个参数是不可以带的哦。

CronJob Controller

示例:启动一个pod,打印容器内时间并打印hello world,代码如下:

[root@master ~]# cat 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 world"
          restartPolicy: OnFailure

可以看到,每一分钟启动一个pod 

[root@master ~]# k get po -A |grep hello
default       hello-1661256840-zbz77                    0/1     Completed   0          2m19s
default       hello-1661256900-cjvsk                    0/1     Completed   0          78s
default       hello-1661256960-pbmmr                    0/1     Completed   0          18s

查看日志:

[root@master ~]# k logs hello-1661256840-zbz77
Tue Aug 23 12:14:06 UTC 2022
Hello world

删除该任务:

[root@master ~]# k get cronjob -A
NAMESPACE   NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
default     hello   */1 * * * *   False     1        12s             6m42s
[root@master ~]# k delete cronjob hello
cronjob.batch "hello" deleted

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340