美文网首页
Kubernetes:控制器

Kubernetes:控制器

作者: minute_5 | 来源:发表于2020-01-11 14:48 被阅读0次

    Kubernetes控制器

    Deployment -- 两层控制器

    通过ReplicaSet个数描述应用版本(滚动升级),再通过ReplicaSet属性控制Pod数量(水平扩展)

    image
    1. Deployment 的控制器,实际上控制的是 ReplicaSet 的数目,以及每个 ReplicaSet 的属性。
    2. 一个应用的版本,对应的是一个 ReplicaSet。这个版本应用的 Pod 数量,则由 ReplicaSet 通过它自己的控制器(ReplicaSet Controller)来保证。
    3. 通过这样的多个 ReplicaSet 对象,Kubernetes 项目就实现了对多个“应用版本”的描述。

    有状态应用编排 -- Stateful

    1. 拓扑状态:应用多实例有多种关系。主从、主备顺序等。
    2. 存储状态:应用多实例分别绑定不同存储数据。比如容器当前读取到的数据和半小时后读取的数据是同一份数据。
    3. Stateful的实现方式就是记录下这些状态,然后当Pod被重建时,恢复这些状态。

    Stateful 如何实现拓扑状态?

    外界如何访问Pod -- Service

    Service就是外界连接Pod的网络机制。比如一个Deployment控制了多个Pod,这是定义一个Service就能访问到这三个Pod。

    那Service又是如何怎么被访问的呢

    1. 通过虚拟IP(virtual IP),当访问一个预先定义好的VIP时,K8s就会把这次的访问请求路由到Service上。
    2. 通过Service DNS,比如:test-service.test-namespace.svc.cluster.test。在DNS解析时有两种处理方式
      1. 一种是通过test-service.test-namespace.svc.cluster.test解析到VIP从而找到Pod
      2. 另一种是访问时,解析出来的就是直接暴露出来的Pod IP而不是VIP, 这种解析方式叫做Headless Service。(Headless Service的定义其实就是将cluster IP字段置为None,从而让这个Service没有一个VIP 作为头信息,从而暴露出Pod IP)

    Stateful如何保持Pod拓扑状态

    1. 当定义Stateful时指定serviceName,比如如下,让Stateful在控制循环的时候使用test-sf来保证Pod的可解析身份
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: test-sf
    spec:
      serviceName: "test"
      replicas: 2
      selector:
        matchLabels:
          app: test-pod
      template:
        metadata:
          labels:
            app: test-pod
        spec:
          containers:
          - name: test-pod
            image: xxx
            ports:
            - containerPort: 80
              name: testPod
    
    1. 当启动test这个svc和stateful后,Stateful就会创建两个testPod,并为它们命名为 testPod-0 与 testPod-1 。然后Stateful就会把两个Pod及其名称存储下来,以后不管是testPod-0或1被删除了,只要在Stateful生命周期内,这些顺序关系就不会失效。

    Stateful 如何实现存储状态?

    Persistent Volume Claim
    1. 定义一个 PVC,声明想要的 Volume 的属性:在这个 PVC 对象里,不需要任何关于 Volume 细节的字段,只有描述性的属性和定义。比如,storage: 1Gi,表示我想要的 Volume 大小至少是 1 GiB;accessModes: ReadWriteOnce,表示这个 Volume 的挂载方式是可读写,并且只能被挂载在一个节点上而非被多个节点共享
    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: pv-claim-test
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    
    1. 在应用的 Pod 中,声明使用这个 PVC,只要我们创建这个 PVC 对象,Kubernetes 就会自动为它绑定一个符合条件的 Volume 即 pv
    apiVersion: v1
    kind: Pod
    metadata:
      name: pv-pod
    spec:
      containers:
        - name: pv-container
          image: nginx
          ports:
            - containerPort: 80
              name: "http-server"
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: pv-storage
      volumes:
        - name: pv-storage
          persistentVolumeClaim:
            claimName: pv-claim-test
    
    1. Kubernetes 中 PVC 和 PV 的设计,实际上类似于接口实现。开发者只要知道并会使用接口,即:PVC;而运维人员则负责给接口绑定具体的实现,即:PV。这种解耦,就避免了因为向开发者暴露过多的存储系统细节而带来的隐患。此外,这种职责的分离,往往也意味着出现事故时可以更容易定位问题和明确责任

    StatefulSet存储状态

    1. 回到StatefulSet对存储状态管理上来
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: test-sf
    spec:
      serviceName: "test"
      replicas: 2
      selector:
        matchLabels:
          app: test-pod
      template:
        metadata:
          labels:
            app: test-pod
        spec:
          containers:
          - name: test-pod
            image: xxx
            ports:
            - containerPort: 80
              name: xxx
            volumeMounts:
            - name: testVM
              mountPath: /usr/share/xxx
      volumeClaimTemplates:
      - metadata:
          name: testVM
        spec:
          accessModes:
          - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi
    
    1. 这个 StatefulSet 额外添加了一个 volumeClaimTemplates 字段。它跟 Deployment 里 Pod 模板(PodTemplate)的作用类似 => 凡是被这个 StatefulSet 管理的 Pod,都会声明一个对应的 PVC;而这个 PVC 的定义,就来自于 volumeClaimTemplates 这个模板字段。更重要的是,这个 PVC 的名字,会被分配一个与这个 Pod 完全一致的编号。这个自动创建的 PVC,与 PV 绑定成功后,就会进入 Bound 状态,这就意味着这个 Pod 可以挂载并使用这个 PV 了。
    2. 通过kubectl get pvc -l app=nginx,可以看到,这些 PVC,都以<PVC 名字 >-<StatefulSet 名字 >-< 编号 >的方式命名,并且处于 Bound 状态。
    3. 这个 StatefulSet 创建出来的所有 Pod,都会声明使用编号的 PVC。比如,在名叫 test-pod-0 的 Pod 的 volumes 字段,它会声明使用名叫 testVM 的 PVC,从而挂载到这个 PVC 所绑定的 PV。

    守护进程 -- DaemonSet

    1. 举个例子: 我们很多组件,比如网络插件、存储插件、监控和日志组件都需要agent来帮助处理容器的网络,存储目录挂载、收集节点监控数据。而这个agent就是我们节点的守护进程。
    2. 在K8s中,它也是一种编排对象 -- DaemonSet,它比其他所有对象的启动时机都要早。
    3. DaemonSetController通过给node打污点的方式来保证 同样能容忍这个污点的Pod 也就是 DaemonSet 的Pod 是第一个关联到node上的。
    参考:

    《深入剖析Kubernetes》 - 张磊

    相关文章

      网友评论

          本文标题:Kubernetes:控制器

          本文链接:https://www.haomeiwen.com/subject/srzvactx.html