当前位置: 首页 > ds >正文

云原生技术与应用-Kubernetes Pod调度基础

文章目录

一.Replication Controller和ReplicaSet

   1.Replication Controller

   2.标签与标签选择器

   3.ReplicaSet

二.无状态应用管理Deployment

  1.什么是无状态

  2.无状态服务特点

  3.无状态服务的应用场景

  4.创建Deployment

三.有状态应用管理StatefulSet

  1.有状态服务的定义

  2.有状态服务的特征

  3.有状态服务的应用场景

  4.无状态服务和有状态服务的比较

  5.编写ststefulSet资源文件

四.守护进程集DaemonSet

  1.什么是DaemonSet

  2.定义一个DaemonSet

  3.创建DaemonSet

  4.查看DaemonSet

  5.查看pod所在的节点

  6.删除DaemonSet

五.CronJob

  1.创建Cronjob文件


一.Replication Controller和ReplicaSet

  1.Replication Controller

   Replication Controller(复制控制器,RC)
   RC 用来确保 Pod 副本数达到期望值,这样可以确保一个或多个同类 Pod 总是可用的。
   如果存在的 Pod 数量大于设定的值,Replication Controller 将终止额外的 Pod,如果太少,Replication Controller 将会启动更多的 Pod 用于保证达到期望值,与手动创建 Pod 不同的是,用 Replication Controller 维护的 Pod 在失败、删除或终止时会自动替换。因此,即使应用程序只需要一个 Pod,也应该使用 Replication Controller 或其他方式管理。Replication Controller 类似于进程管理程序,但是 Replication Controller 不是监视单个节点上的各个进程,而是监视多个节点上的多个 Pod。

(1)编辑ReplicationController文件

[root@k8s-master ~]# vim replicationcontroller-nginx.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:1.7.9
        ports:
        - containerPort: 80

(2)创建ReplicationController 

[root@k8s-master ~]# ku apply -f replicationcontroller-nginx.yaml 
replicationcontroller/nginx created

[root@k8s-master ~]# ku get pod
NAME          READY   STATUS    RESTARTS   AGE
nginx-888mw   1/1     Running   0          8s
nginx-cth7g   1/1     Running   0          8s
nginx-g2gp7   1/1     Running   0          8s

[root@k8s-master ~]# ku get rc
NAME    DESIRED   CURRENT   READY   AGE
nginx   3         3         3       19s

(3)删除一个pod并立即查看pod状态

[root@k8s-master ~]# ku delete pod nginx-cth7g -n default
pod "nginx-cth7g" deleted
[root@k8s-master ~]# ku get pod
NAME          READY   STATUS    RESTARTS   AGE
nginx-888mw   1/1     Running   0          118s
nginx-g2gp7   1/1     Running   0          118s
nginx-gxz6f   1/1     Running   0          6s 

(4)删除ReplicationController

[root@k8s-master ~]# ku delete -f replicationcontroller-nginx.yaml 
replicationcontroller "nginx" deleted

2.标签与标签选择器

 (1) 标签
   标签是用来标识 K8S 对象的一组附加在其上的键值对,通过标签我们可以方便地筛选或排除一组对象。
借鉴资料中的话来讲,集群中的应用部署或是批处理的程序部署通常都是多维度的,为了实现对这些对象的管理,往往需要对某一特定维度的对象进行操作,而标签可以通过用户的意愿组织集群中的对象之间的结构,而不需要对集群进行修改。

   在同一个对象之下标签的 Key 值必须唯一的。名称方面,标签名不得多于 63 个字符且必须由字母或数字开头或结尾,可以包含字母、数字、-、、. 等字符;标签前缀是可选的,必须以 DNS 子域名的方式指定。

(2) 标签选择器
   标签选择器可以用来选择一组对象(标签并不能唯一标识一个对象),APIServer 支持两种标签选择器:基于等式的标签选择器与基于集合的标签选器;

   基于等式的标签选择方式:在这种选择方式下可以使用 =、==、!= 三种操作符来进行选择,前两个的含义是一样的,都代表相等,第三种代表不等。选择条件可以通过,叠加,例如 date=day1,name!=build 代表选择 date 值为 day1 且 name 值不为 build 的对象。 

  基于集合的标签选择方式:这种选择器可以同时选择一组对象。支持的操作符有:in、notin、exists。

3.ReplicaSet

   ReplicaSet(复制集,RS)是支持基于集合的标签选择器的下一代 Replication Controller,它主要用于 Deployment 协调创建、删除和更新 Pod,和 Replication Controller 唯一的区别是,ReplicaSet 支持标签选择器。在实际应用中,虽然 ReplicaSet 可以单独使用,但是一般建议使用 Deployment 来自动管理 ReplicaSet,除非自定义的 Pod 不需要更新或有其他编排等。

(1)编辑ReplicaSet文件

[root@k8s-master ~]# vim replicaset-example.yaml 

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
    matchExpressions:
      - {key: tier, operator: In, values: [frontend]}
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: nginx:1.7.9
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below.
          # value: env
        ports:
        - containerPort: 80

matchExpressions 是一个列表,其中可以包含多个匹配表达式。这里的例子只包含了一个表达式。

表示列表中的一个条目。
{key: tier, operator: In, values: [frontend]} 这是一个具体的匹配表达式,它包含以下几个部分:
key:标签键(label key),这里是 tier。
operator:匹配操作符,在这里为 In,表示 “在... 之中”。
values:匹配值列表,这里只有一个值 [frontend]。
requests:代表容器启动请求的资源限制,分配的资源必须要达到此要求

limits:代表最多可以请求多少资源

(2)创建RS

[root@k8s-master ~]# ku create -f replicaset-example.yaml 
replicaset.apps/frontend created
[root@k8s-master ~]# ku get pod
NAME             READY   STATUS    RESTARTS   AGE
frontend-5pd2k   1/1     Running   0          9s
frontend-k2c4m   1/1     Running   0          9s
frontend-kdg8k   1/1     Running   0          9s
[root@k8s-master ~]# ku delete -f replicaset-example.yaml 
replicaset.apps "frontend" deleted

二.无状态应用管理Deployment

  1.什么是无状态

     无状态服务(stateless service)对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说数据库),服务器本身不存储任何信息。这种服务叫做无状态服务。

  无状态服务:就是没有特殊状态的服务,各个请求对于服务器来说统一无差别处理,请求自身携带了所有服务端所需要的所有参数(服务端自身不存储跟请求相关的任何数据,不包括数据库存储信息)

  如果在启动一个服务时,不依赖于该服务之前的运行状态,或者不依赖于其他服务,这个服务就是无状态服务;反之,就是有状态服务。

 2.无状态服务特点

  (1)数据方面:无状态服务不会在本地存储持久化数据,多个实例可以共享相同的持久化数据
(2)结果方面:多个服务实例对于同一个用户请求的响应结果是完全一致的
(3)关系方面:这种多服务实例之间是没有依赖关系
(4)影响方面:在 k8s 控制器中动态启停无状态服务的 pod 并不会对其它的 pod 产生影响
(5)示例方面:nginx 实例,tomcat 实例,web 应用
(6)资源方面:相关的 k8s 资源有:ReplicaSet、ReplicationController、Deployment
(7)创建方式:Deployment 被设计用来管理无状态服务的 pod
每个 pod 完全一致,原因如下:

  无状态服务内的多个 Pod 创建的顺序是没有顺序的

  无状态服务内的多个 Pod 的名称是随机的
  pod 被重新启动调度后,它的名称与 IP 都会发生变化
  无状态服务内的多个 Pod 背后是共享存储的
(8)扩缩容方式:随机缩容
由于是无状态服务,所以这些控制器创建的 pod 序号都是随机值。并且在缩容也是随机,并不会明确缩容某一个 pod。因为所有实例得到的返回值都是一样,所以缩容任何一个 pod 都可以。

3.无状态服务的应用场景

   无状态服务不会在本地存储持久化数据。多个服务实例对于同一个用户请求的响应结果是完全一致的。这种多服务实例之间是没有依赖关系,比如 web 应用,在 k8s 控制器中动态启停无状态服务的 pod 并不会对其它的 pod 产生影响。

   Deployment 被设计用来管理无状态服务的 pod,每个 pod 完全一致
无状态服务内的多个 Pod 创建的顺序是没有顺序的。
   无状态服务内的多个 Pod 的名称是随机的,pod 被重新启动调度后,它的名称与 IP 都会发生变化。
  无状态服务内的多个 Pod 背后是共享存储的。

4.创建Deployment

(1)编写Deployment文件

[root@k8s-master ~]# vim nginx-deployment.yaml 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - name: nginx
              containerPort: 80

replicas: pod 的副本数
selector: 定义 Deployment 如何找到要管理的 Pod,与 template 的 label 标签对应。
template:

  • app: nginx 使用 label 标记 pod

  • spec: 定义 pod 的详细信息
    11

  • name: nginx 表示 pod 运行一个名字为 nginx 的容器

  • image: 运行此 pod 使用的镜像

  • port: 容器用于发送和接收流量的端口

(2)使用kubectl create 创建此Deployment

[root@k8s-master ~]# ku create -f nginx-deployment.yaml 
deployment.apps/nginx-deployment created

(3)查看Deployment的状态

[root@k8s-master ~]# ku get deploy
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           59s

 (4)使用rollout查看整个Deployment的创建过程状态

[root@k8s-master ~]# ku rollout status deployment/nginx-deployment

(5)查看此Deployment创建的pod

[root@k8s-master ~]# ku get rs -l app=nginx
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-6cf9b75cdd   2         2         2       3m37s 

2.更新Deployment

     通过 Deployment 部署应用后,如果需要对 Deployment 文件的配置文件或者镜像版本进行更新,更改后该 Deployment 会创建新的 RepliccaSet,之后会对管理的 Pod 进行滚动升级。

(1)更新pod的images

[root@k8s-master ~]# ku set image deployment nginx-deployment nginx=1.9.1 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx-deployment image updated
[root@k8s-master ~]# ku set image deployment nginx-deployment nginx=1.12.0 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx-deployment image updated

(2)查看更新过程

[root@k8s-master ~]# ku rollout status deloyment.v1.apps/nginx-deployment 

3. 回滚deployment

(1) 多更新几次 deployment
kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record
kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v2 --record

(2) 查看更新历史
kubectl rollout history deployment/nginx-deployment
最后的一个版本是当前版本

(3) 查看某次更新的详情
kubectl rollout history deployment/nginx-deployment --revision=2

(4) 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

查看回滚结果:
kubectl rollout history deployment/nginx-deployment

(5) 回滚到上次版本
kubectl rollout undo deployment/nginx-deployment

查看回滚结果:
kubectl rollout history deployment/nginx-deployment

4:扩容 deployment
(1) 调整 pod 的副本数
kubectl scale deployment.v1.apps/nginx-deployment --replicas=3

查看扩容结果:
kubectl get pods

5:删除 Deployment
kubectl delete -f nginx-deployment.yaml

三.有状态应用管理StatefulSet

1.有状态服务的定义
    有状态服务(StatefulSet)是一种 Kubernetes 资源对象,用于管理有状态的应用且保证其应用的顺序性。比如在生产环境中,可以用 Elasticsearch 集群、Redis 集群或者需要持久化存储的 RabbitMQ 集群、RocketMQ 集群、Kafka 集群、Zookeeper 集群等。
一个 StatefulSet 对象管理了一组有特定标识的 Pod,与 Deployment 不同的是,StatefulSet 为每个 Pod 提供了一个唯一的标识。这些 Pod 是根据相同的模板创建的,但是不互斥,每个 Pod 都有一个持久的标识,在重新调度时也会保留。

  1. 状态服务的特征
    (1)数据方面:有状态服务需要在本地存储持久化数据,典型的应用是分布式数据库。
    (2)结果方面:不同实例,处理相同请求的结果不一致。
    (3)关系方面:分布式节点之间有强依赖关系,比如主从关系。
    (4)影响方面:如果 K8S 停止分布式集群中任意一个 Pod,就可能会导致服务丢失或者集群的 crash(崩溃),例如 Zookeeper、Elasticsearch。
    (5)示例方面:mysql 数据库、kafka、zookeeper、Redis 主从架构。
    (6)资源方面:StatefulSet 资源。
    (7)创建方式:StatefulSet 资源。
    StatefulSet 管理的 Pod 具有如下特征:

    • 唯一的:每个 Pod 会被分配一个唯一的序号。

    • 顺序的:Pod 的启动、终止都是按照顺序进行。

    • 稳定的网络标识:Pod 的主机名、DNS 地址不会随着 Pod 被重新调度而发生变化。

    • 稳定的持久化存储:Pod 被重新调度后,仍然挂载原有的 Pod 的 PVC,保证了数据的完整性和一致性。

  2. 有状态服务的应用场景
    有状态的 Pod 是用来运行有状态应用的,所以在其配置上存储的数据非常重要。在 StatefulSet 被删除时这些声明是被保留的,特别是对于 StatefulSet 来说,删除或减少其 replicas 数量时,要手动处理相关资源,否则会导致数据丢失。
    有状态服务需要在本地存储持久化数据,典型的应用是分布式数据库、消息队列(如 kafka、RabbitMQ、RocketMQ、Zookeeper 等)。
    有状态服务常用于实现网关(不是唯一的方式,下文会介绍另外的方案)、单一登录的例子。在互联网中有一些信息,需要记录用户的购物车、确认订单、付款等多个步骤,由于 HTTP 协议本身是无状态的,所以为了实现有状态服务,就需要通过一些额外的手段,比如通常会用 session,将用户挑选的商品(购物车)、收货信息等 session 中的信息,当付款的时候,再从购物车中取出商品信息。  

  3. 无状态服务和有状态服务的比较

    • 服务不保存请求的状态,实例的状态都是可以被替代的(无状态)。

    • 任何一个组成都可以被同一个集群的其他实例所替代。

    • 不存储关键数据,实例可以水平扩展,遇到负载均衡将请求分发给各个节点。

    • 在一个时间的维度中,只存在一个数据副本。

    • 通常存在于单集群的部署中。
      (2)有状态服务

    • 需要存储和依赖有状态的相关数据,这些数据需要自身持久化或者可以通过其他节点恢复。

    • 一个组成能被其他节点(或者部分节点参与的方式)处理。

    • 存储核心数据,某个节点的故障可能导致整个服务的不可用。

    • 在一个时间的维度中,存在多个数据副本,需要考虑这些副本的一致性、一致性问题。

    • 通常存在于分布式集群中。

5: 编写 statefulSet 资源文件
(1) 定义一个 statefulSet 资源文件
via redis-statefulset.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-svc
spec:
selector:
app: redis-sts
ports:

  • port: 6379
    protocol: TCP
    targetPort: 6379
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
    name: redis-sts
    spec:
    serviceName: redis-svc
    replicas: 2
    selector:
    matchLabels:
    app: redis-sts
    template:
    metadata:
    labels:
    app: redis-sts
    spec:
    containers:

    • image: redis:5-alpine
      name: redis
      ports:

      • containerPort: 6379

  • kind: Service 定义了一个名字为 redis-svc 的服务。

  • kind:StatefulSet 定义了一个名字为 redis-sts 的 StatefulSet,replicas 表示部署 Pod 的副本数。
    (2) 创建 statefulSet
    kubectl create -f redis-statefulset.yaml
    (3) 查看 statefulSet 状态
    kubectl get sts
    (4) 查看群集状态
    kubectl get service

kubectl get po -l app=redis-sts

NAME READY STATUS RESTARTS AGE
redis-sts-0 1/1 Running 0 5m38s
redis-sts-1 1/1 Running 0 4m55s

-1: 指定标签(label)
注意 NAME 列,名称是 sts 的 name - 序号,这里序号越小则说明创建的越早从 AGE 列也可以看出来。
这就解决了有状态应用中的启动顺序问题,比如可以让 redis-sts-0 作为 redis 的主节点,redis-sts-1 作为从节点

6: statefulset 扩容
(1) 扩容,将副本数修改为 3
kubectl scale sts redis-sts --replicas=3
ku get pod
NAME READY STATUS RESTARTS AGE
redis-sts-0 1/1 Running 0 7m50s
redis-sts-1 1/1 Running 0 7m7s
redis-sts-2 1/1 Running 0 6s

7: 缩容
(1) 打开第二个终端,动态显示缩容流程
kubectl get pods -w -l app=redis-sts
备注:
-w:动态监听所有的 pod
(2) 在原来第一个终端修改副本数为 2
kubectl patch sts redis-sts -p '{"spec":{"replicas":2}}'
注意:
此时可以查看第二个终端上的变化
(3) 在第一个终端上查看最终结果
kubectl get pods -l app=redis-sts

8: 非级联删除 statefulset
删除 StatefulSet 有两种方式:级联删除和非级联删除。
使用非级联方式删除 StatefulSet 时,StatefulSet 的 Pod 不会被删除,使用级联方式删除 StatefulSet 时,StatefulSet 和它的 Pod 都会被删除。
(1) 采用非级联删除
kubectl delete statefulset redis-sts --cascade=false
查看删除结果:
kubectl get sts
(2) 查看管理的 pod
kubectl get po
发现 pod 并没有被删除
(3) 删除 pod
kubectl delete po redis-sts-0

kubectl delete po redis-sts-1
9: 级联删除 statefulset
(1) 先创建出 statefulset
kubectl create -f redis-statefulset.yaml
(2) 级联删除
kubectl delete statefulset redis-sts
查看
kubectl get po
两个 pod 全都没了
(3) 删除 redis 服务
kubectl delete -f redis-statefulset.yaml

四.守护进程集DaemonSet

  1. 什么是 DaemonSet
    有时候我们希望在每个 Kubernetes 节点(或符合条件的节点)上都部署某个应用,那么就可以使用 Kubernetes 的 DaemonSet(守护进程集)。DaemonSet 确保在(符合条件的)节点上运行一个 Pod 副本。当有新的节点加入集群时,也会为它们新增一个 Pod;当节点从集群中移除时,这些 Pod 会被删除。删除 DaemonSet 时,也会删除它创建的所有 Pod。

  2. 定义一个 DaemonSet
    vim daemonset-nginx.yaml
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
    name: pod-controller
    namespace: dev
    labels:
    controller: daemonset
    spec:
    selector:
    matchLabels:
    app: nginx-pod
    template:
    metadata:
    labels:
    app: nginx-pod
    spec:
    containers:

    • name: nginx
      image: nginx:1.7.9
      ports:

      • name: nginx-port
        containerPort: 80
        protocol: TCP

  3. 创建 DaemonSet
    kubectl create namespace dev
    kubectl create -f daemonset-nginx.yaml

  4. 查看 DaemonSet
    kubectl get ds -n dev -o wide

  5. 查看 Pod 所在的节点
    kubectl get pod -n dev -o wide

  6. 删除 DaemonSet
    kubectl delete ds pod-controller -n dev

五.CronJob

    CronJob(计划任务,缩写为 Cron)用于以时间为基准的周期性任务运行,让你在 Kubernetes 集群上的运行任务和在 Linux 系统上使用 cron 一样。

  1. 创建 CronJob
    (1)编辑 cronjob 文件
    vim cronjob-example.yaml
    apiVersion: batch/v1 # v1 版本以上,改为 batch/v1
    kind: CronJob
    metadata:
    name: hello
    spec:
    schedule: "*/1 * * * *"
    jobTemplate:
    spec:
    template:
    spec:
    containers:

    name: hello
    image: busybox:v1
    args:    date; echo Hello from the Kubernetes cluster
    restartPolicy: OnFailure

    • 备注:
      这个案例将会每分钟执行一次计划任务,
      并输出当前时间和 “Hello from the Kubernetes cluster”

(2)创建 cronjob
kubectl create -f cronjob-example.yaml

(3)查看创建结果
kubectl get cj
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
hello */1 * * * * false 0 48s 94s
等待一会后可以查看到生成的 pod
kubectl get jobs
NAME COMPLETIONS DURATION AGE
hello-27720354 1/1 20s 74s
hello-27743535 0/1 14s 14s

(4)查看生成的 pod,并查看 pod 的执行日志
kubectl get pod
kubectl logs -f hello-27720354-<容器 ID>
Sat Oct 1 09:52:16 UTC 2022
Hello from the Kubernetes cluster

(5)删除 CronJob
kubectl delete cronjob hello

http://www.xdnf.cn/news/16110.html

相关文章:

  • jdk25浅谈
  • 深度学习-常用环境配置
  • 使用 Tailwind CSS 控制元素在移动端不显示
  • MySQL 核心知识点梳理(2)
  • C++ 分配内存释放内存
  • 深度学习 ---神经网络以及数据准备
  • 清理磁盘空间
  • LiteCoT:难度感知的推理链压缩与高效蒸馏框架
  • NISP-PTE基础实操——代码审计
  • 从实践出发--探究C/C++空类的大小,真的是1吗?
  • 微店关键词搜索接口深度开发指南
  • 有关Maven的个人笔记总结
  • ssh2-sftp-client 简化 sftp 文件传输的 node库
  • python实现接收九数云的异常分析指标推送通知
  • C++基础数据结构
  • Java IO 流详解:从基础到实战,彻底掌握输入输出编程
  • A316-HF-DAC-V1:专业USB HiFi音频解码器评估板技术解析
  • 牛客网题解 | 单词识别
  • 关于Ajax的学习笔记
  • 二叉树实现堆,咕咕咕
  • 结构型模式-架构解耦与扩展实践
  • Linux的目录
  • stream event
  • 软文发布平台推荐指南,软文发稿平台该怎么选?
  • 网络协议(三)网络层 IPv4、CIDR(使用子网掩码进行网络划分)、NAT在私网划分中的应用
  • Axios
  • Qt中的网络通信
  • javaSE(从0开始)day13
  • 通过TPLink路由器进行用户行为审计实战
  • 【图像处理基石】什么是相机的内外参数?