Kubernetes Pod调度基础

目录

一、Replication Controller 和 ReplicaSet

1. Replication Controller

Replication Controller 的使用示例

2. 标签与标签选择器

标签

标签选择器

标签与标签选择器举例

3. ReplicaSet

定义 ReplicaSet 实例

二、无状态应用管理 Deployment

1. 什么是无状态

2. 无状态服务特点

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

4. 创建 Deployment

5. 更新 Deployment

6. 回滚 deployment

7. 扩容 deployment

8. 删除 Deployment

三、有状态应用管理 StatefulSet

1. 有状态服务的定义

2. 有状态服务的特征

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

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

5. 编写 statefulSet 资源文件

6. statefulset 扩容

7. 缩容

8. 非级联删除 statefulset

9. 级联删除 statefulset

四、守护进程集 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)用于确保 Pod 副本数达到期望值,保障一个或多个同类 Pod 始终可用。若 Pod 数量大于设定值,它会终止额外 Pod;若数量不足,则启动更多 Pod。与手动创建 Pod 不同,由 Replication Controller 维护的 Pod 在失败、删除或终止时会自动替换,因此即便应用只需一个 Pod,也建议用其或其他方式管理。它类似进程管理程序,但监视的是多个节点上的多个 Pod,而非单个节点上的各个进程。

Replication Controller 的使用示例
  • 编辑 ReplicationController 文件
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

  • 创建 ReplicationController
kubectl apply -f replicationcontroller-nginx.yaml
kubectl get pod

结果显示创建了 3 个运行状态的 nginx Pod。

  • 删除一个 pod 并查看状态
kubectl delete pod nginx-9g78r -n default
kubectl get pod

可见新的 Pod 被创建来替换删除的 Pod。

  • 删除 ReplicationController
kubectl delete -f replicationcontroller-nginx.yaml

2. 标签与标签选择器

标签

标签是附加在 K8S 对象上的一组键值对,用于方便地筛选或排除一组对象。在同一个对象下,标签的 Key 值必须唯一。标签名不得多于 63 个字符,须由字母或数字开头或结尾,可包含字母、数字、-、_、. 等字符;标签前缀可选,需以 DNS 子域名方式指定。标签值若不为空,长度不得多于 63 个字符,也须由字母或数字开头或结尾,可包含相应字符。

标签选择器

APIServer 支持基于等式和基于集合的两种标签选择器:

  • 基于等式的标签选择器:使用 =、==、!= 三种操作符,前两者表示相等,第三种表示不等,选择条件可叠加。
  • 基于集合的标签选择器:可同时选择一组对象,支持 in、notin、exists 操作符,选择条件也可叠加,且与基于等式的选择器在相同意义条件下等价。
标签与标签选择器举例

基于等式的标签选择器如selector: component: redis;基于集合的标签选择器如通过matchLabelsmatchExpressions组合选择。

3. ReplicaSet

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

定义 ReplicaSet 实例
  • 编辑 ReplicaSet 文件
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  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
          ports:
            - containerPort: 80

  • 创建 RS
kubectl create -f replicaset-example.yaml

二、无状态应用管理 Deployment

1. 什么是无状态

无状态服务对单次请求的处理不依赖其他请求,处理一次请求所需信息要么在请求里,要么可从外部获取,服务器本身不存储任何信息。即服务无特殊状态,各请求统一无差别处理,请求携带服务端所需所有参数,服务端不存储与请求相关数据(不包括数据库存储信息)。启动服务时,若不依赖其之前运行状态或其他服务,即为无状态服务,反之则为有状态服务。

2. 无状态服务特点

  • 数据方面:不在本地存储持久化数据,多个实例可共享相同持久化数据。
  • 结果方面:多个服务实例对同一用户请求响应结果完全一致。
  • 关系方面:多服务实例之间无依赖关系。
  • 影响方面:在 k8s 控制器中动态启停无状态服务的 pod 不会对其他 pod 产生影响。
  • 示例方面:nginx 实例、tomcat 实例、web 应用。
  • 资源方面:相关 k8s 资源有 ReplicaSet、ReplicationController、Deployment。
  • 创建方式:Deployment 被设计用来管理无状态服务的 pod,每个 pod 完全一致,原因包括无状态服务内多个 Pod 创建顺序无要求、名称随机、重新启动调度后名称与 IP 变化、背后共享存储。
  • 扩缩容方式:随机缩容,因所有实例返回值一样,缩容任何一个 pod 均可。

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

Deployment 用来管理 RS,并为 Pod 和 RS 提供声明性更新及许多新功能,生产环境中用 Deployment 替代 RS。它一般用于部署公司的无状态服务,因为企业内部以微服务为主,微服务实现无状态化是最佳实践,可利用其高级功能做到无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等。

4. 创建 Deployment

  • 编写 Deployment 文件
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

  • 创建 Deployment
kubectl create -f nginx-deployment.yaml

  • 查看 Deployment 的状态
kubectl get deploy

  • 查看创建过程状态
kubectl rollout status deployment/nginx-deployment

  • 查看对应的 RS
kubectl get rs -l app=nginx

  • 查看创建的 pod
kubectl get pods --show-labels

5. 更新 Deployment

通过 Deployment 部署应用后,若需更新配置文件或镜像版本,更改后会创建新的 RepliccaSet 并对 Pod 进行滚动升级。

  • 更新 pod 的 image
kubectl set image deployment nginx-deployment nginx=nginx:1.9.1 --record

  • 查看更新过程
kubectl rollout status deployment.v1.apps/nginx-deployment

  • 查看 RS
kubectl get rs

6. 回滚 deployment

当更新版本不稳定或配置不合理时可回滚。

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

  • 查看更新历史
kubectl rollout history deployment/nginx-deployment

  • 查看某次更新详情
kubectl rollout history deployment/nginx-deployment --revision=2

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

  • 回滚到上次版本
kubectl rollout undo deployment/nginx-deployment

7. 扩容 deployment

kubectl scale deployment.v1.apps/nginx-deployment --replicas=3

8. 删除 Deployment

kubectl delete -f nginx-deployment.yaml

三、有状态应用管理 StatefulSet

1. 有状态服务的定义

StatefulSet(有状态集,缩写为 sts)常用于部署有状态且需要有序启动的应用程序,如生产环境中的 Elasticsearch 集群、MongoDB 集群、RabbitMQ 集群、Redis 集群、Kafka 集群和 ZooKeeper 集群等。它管理着基于相同容器规范的 Pod,与 Deployment 不同的是,为每个 Pod 维护一个标识,这些 Pod 不可互换,每个都有持久标识符,重新调度时会保留。

2. 有状态服务的特征

  • 数据方面:需要在本地存储持久化数据,典型应用是分布式数据库。
  • 结果方面:实例之间请求结果可能不一致。
  • 关系方面:分布式节点实例之间有依赖的拓扑关系,如主从关系。
  • 影响方面:若 K8 停止分布式集群中任一实例 pod,可能导致数据丢失或集群崩溃。
  • 示例方面:mysql 数据库、kafka、zookeeper、Redis 主从架构。
  • 资源方面:statefulSet。
  • 创建方式:statefulSet 管理,Pod 具有唯一性(每个 Pod 分配唯一序号)、顺序性(启动、更新、销毁按顺序进行)、稳定的网络标识(主机名、DNS 地址不随重新调度变化)、稳定的持久化存储(重新调度后仍能挂载原有 PV,保证数据完整性和一致性)。

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

有状态的 pod 用于运行有状态应用,其在数据卷上存储的数据非常重要,Statefulset 缩容时删除声明可能是灾难性的,缩容简单如减少 replicas 数值,因此释放特定持久卷时需手动删除对应持久卷声明。有状态服务需要在本地存储持久化数据,典型是分布式数据库应用,节点实例间有依赖拓扑关系,如主从关系,停止任一实例 pod 可能导致数据丢失或集群崩溃,也可以说是需要数据存储功能的服务或多线程类型的服务、队列等,还常用于实现事务,如商城购买商品的例子。

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

  • 无状态服务:不依赖自身状态,实例状态数据可维护在内存中;任何请求可被任意实例处理;不存储状态数据,可水平拓展,通过负载均衡分发请求;在封闭系统中只存在一个数据闭环;通常存在于单体架构的集群中。
  • 有状态服务:依赖或存在局部状态数据,需自身持久化或可通过其他节点恢复;一个请求只能被某个节点(或同等状态下的节点)处理;存储状态数据,实例拓展需整个系统参与状态迁移;在封闭系统中存在多个数据闭环,需考虑数据一致性问题;通常存在于分布式架构中。

5. 编写 statefulSet 资源文件

  • 定义 statefulSet 资源文件
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

  • 创建 statefulSet
kubectl create -f redis-statefulset.yaml

  • 查看 statefulset 状态
kubectl get sts

  • 查看群集状态
kubectl get service
kubectl get po -l app=redis-sts

6. statefulset 扩容

kubectl scale sts redis-sts --replicas=3

7. 缩容

  • 动态显示缩容流程
kubectl get pods -w -l app=redis-sts

  • 修改副本数
kubectl patch sts redis-sts -p '{"spec":{"replicas":2}}'

8. 非级联删除 statefulset

  • 采用非级联删除
kubectl delete statefulset redis-sts --cascade=false

  • 查看管理的 pod,发现 pod 未被删除,需手动删除。

9. 级联删除 statefulset

  • 创建 statefulset
kubectl create -f redis-statefulset.yaml

  • 级联删除
kubectl delete statefulset redis-sts

  • 查看 pod,发现已被删除,再删除 redis 服务。

四、守护进程集 DaemonSet

1. 什么是 DaemonSet

当需要在每个 Kubernetes 节点或符合条件的节点上都部署某个应用时,可使用 DaemonSet 调度 Pod。它确保全部(或符合条件)的节点上运行一个 Pod 副本,新节点加入集群时为其新增 Pod,节点移除时回收 Pod,删除 DaemonSet 会删除其创建的所有 Pod。

2. 定义一个 DaemonSet

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 -owide

5. 查看 pod 所在的节点

kubectl get pod -n dev -owide

6. 删除 DaemonSet

kubectl delete ds pod-controller -n dev

五、CronJob

1. 创建 CronJob

  • 编辑 Cronjob 文件
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: hello
              image: busybox:v1
              args:
                - /bin/sh
                - -c
                - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

  • 创建 Cronjob
kubectl create -f cronjob-example.yaml

  • 查看创建结果
kubectl get cj

  • 查看生成的 pod 及日志
kubectl get jobs
kubectl get pod
kubectl logs -f hello-27743522-crnf8

  • 删除 Cronjob
kubectl delete cronjob hello

你可能感兴趣的:(个人笔记,容器)