• 6.Pod控制器—DaemonSet


    Pod控制器—DaemonSet

    DaemonSet控制器

    DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

    使用 DaemonSet 的一些典型用法:

    • 运行集群存储 daemon,例如在每个 Node 上运行 glusterdceph
    • 在每个 Node 上运行日志收集 daemon,例如fluentdlogstashfilebeat
    • 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exportercollectd、Datadog 代理、New Relic 代理,或 Ganglia gmond

    一个简单的用法是,在所有的 Node 上都存在一个 DaemonSet,将被作为每种类型的 daemon 使用。 一个稍微复杂的用法可能是,对单独的每种类型的 daemon 使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU要求。

    DaemonSet解析

    和其它所有 Kubernetes 配置一样,DaemonSet 需要 apiVersionkindmetadata字段。

    ]# kubectl explain daemonset
    KIND:     DaemonSet
    VERSION:  apps/v1
    
    DESCRIPTION:
         DaemonSet represents the configuration of a daemon set.
    
    FIELDS:
       apiVersion	<string>
         APIVersion defines the versioned schema of this representation of an
         object. Servers should convert recognized schemas to the latest internal
         value, and may reject unrecognized values. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
    
       kind	<string>
         Kind is a string value representing the REST resource this object
         represents. Servers may infer this from the endpoint the client submits
         requests to. Cannot be updated. In CamelCase. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
    
       metadata	<Object>
         Standard object's metadata. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
    
       spec	<Object>
         The desired behavior of this daemon set. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
    
       status	<Object>
         The current status of this daemon set. This data may be out of date by some
         window of time. Populated by the system. Read-only. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
    

    spec字段

    .spec 唯一必需的字段是 .spec.template

    .spec.template 是一个 Pod 模板具有相同的 schema,除了它是嵌套的,而且不具有 apiVersionkind 字段。

    Pod 除了必须字段外,在 DaemonSet 中的 Pod 模板必须指定合理的标签(查看 pod selector)。

    在 DaemonSet 中的 Pod 模板必需具有一个值为 AlwaysRestartPolicy,或者未指定它的值,默认是 Always

    # kubectl explain daemonset.spec.template.spec
    

    Pod Seletor

    .spec.selector 字段表示 Pod Selector,它与 Job 或其它资源的 .sper.selector 的原理是相同的。

    spec.selector 表示一个对象,它由如下两个字段组成:

    • matchLabels - 与 ReplicationController.spec.selector 的原理相同。
    • matchExpressions - 允许构建更加复杂的 Selector,可以通过指定 key、value 列表,以及与 key 和 value 列表的相关的操作符。

    当上述两个字段都指定时,结果表示的是 AND 关系。

    如果指定了 .spec.selector,必须与 .spec.template.metadata.labels 相匹配。如果没有指定,它们默认是等价的。如果与它们配置的不匹配,则会被 API 拒绝。

    如果 Pod 的 label 与 selector 匹配,或者直接基于其它的 DaemonSet、或者 Controller(例如 ReplicationController),也不可以创建任何 Pod。 否则 DaemonSet Controller 将认为那些 Pod 是它创建的。Kubernetes 不会阻止这样做。一个场景是,可能希望在一个具有不同值的、用来测试用的 Node 上手动创建 Pod。

    (4)Daemon Pod通信

    与 DaemonSet 中的 Pod 进行通信,几种可能的模式如下:

    • Push:配置 DaemonSet 中的 Pod 向其它 Service 发送更新,例如统计数据库。它们没有客户端。
    • NodeIP 和已知端口:DaemonSet 中的 Pod 可以使用 hostPort,从而可以通过 Node IP 访问到 Pod。客户端能通过某种方法知道 Node IP 列表,并且基于此也可以知道端口。
    • DNS:创建具有相同 Pod Selector 的 Headless Service,然后通过使用 endpoints 资源或从 DNS 检索到多个 A 记录来发现 DaemonSet。
    • Service:创建具有相同 Pod Selector 的 Service,并使用该 Service 访问到某个随机 Node 上的 daemon。(没有办法访问到特定 Node)

    DaemonSet示例

    编辑daemonset的yaml文件

    可以在同一个yaml文件中定义多个资源,这里将redis和filebeat定义在同一个文件中

    # vim ds-demo.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis
          role: logstor
      template:
        metadata:
          labels:
            app: redis
            role: logstor
        spec:
          containers:
          - name: redis
            image: redis:4.0-alpine
            ports:
            - name: redis
              containerPort: 6379
    ---
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: filebeat-ds
      namespace: default
    spec:
      selector:
        matchLabels:
          app: filebeat
          release: stable
      template:
        metadata:
          labels: 
            app: filebeat
            release: stable
        spec:
          containers:
          - name: filebeat
            image: ikubernetes/filebeat:5.6.5-alpine
            env:
            - name: REDIS_HOST
              value: redis.default.svc.cluster.local
            - name: REDIS_LOG_LEVEL
              value: info
    

    创建pod

    # kubectl apply -f ds-demo.yaml
    deployment.apps/redis created
    daemonset.apps/filebeat-ds created
    

    暴露端口

    # kubectl expose deployment redis --port=6379
    service/redis exposed
    # kubectl get svc
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
    kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP    6d23h
    redis        ClusterIP   10.0.0.56    <none>        6379/TCP   53s
    # kubectl get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    filebeat-ds-8bg8x        1/1     Running   0          2m42s
    filebeat-ds-nws56        1/1     Running   0          2m42s
    filebeat-ds-t442d        1/1     Running   0          2m43s
    redis-646cf89449-zwhzg   1/1     Running   0          2m44s
    web-7c95ff84fc-6n4sg     1/1     Running   0          3d18h
    web-7c95ff84fc-cj84l     1/1     Running   0          3d18h
    

    查看redis、filebeat

    # kubectl exec -it redis-646cf89449-zwhzg -- /bin/sh
    
    /data # netstat -tnl
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       
    tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      
    netstat: /proc/net/tcp6: No such file or directory
    /data # nslookup redis.default.svc.cluster.local
    Server:		10.0.0.2
    Address:	10.0.0.2:53
    
    Name:	redis.default.svc.cluster.local
    Address: 10.0.0.56
    
    
    /data # redis-cli -h redis.default.svc.cluster.local
    redis.default.svc.cluster.local:6379> KEYS *
    (empty list or set)
    
    # kubectl get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    filebeat-ds-8bg8x        1/1     Running   0          4m27s
    filebeat-ds-nws56        1/1     Running   0          4m27s
    filebeat-ds-t442d        1/1     Running   0          4m28s
    redis-646cf89449-zwhzg   1/1     Running   0          4m29s
    web-7c95ff84fc-6n4sg     1/1     Running   0          3d18h
    web-7c95ff84fc-cj84l     1/1     Running   0          3d19h
    
    # kubectl exec -it filebeat-ds-8bg8x -- /bin/sh
    / # cat /etc/filebeat/filebeat.yml 
    filebeat.registry_file: /var/log/containers/filebeat_registry
    filebeat.idle_timeout: 5s
    filebeat.spool_size: 2048
    
    logging.level: info
    
    filebeat.prospectors:
    - input_type: log
      paths:
        - "/var/log/containers/*.log"
        - "/var/log/docker/containers/*.log"
        - "/var/log/startupscript.log"
        - "/var/log/kubelet.log"
        - "/var/log/kube-proxy.log"
        - "/var/log/kube-apiserver.log"
        - "/var/log/kube-controller-manager.log"
        - "/var/log/kube-scheduler.log"
        - "/var/log/rescheduler.log"
        - "/var/log/glbc.log"
        - "/var/log/cluster-autoscaler.log"
      symlinks: true
      json.message_key: log
      json.keys_under_root: true
      json.add_error_key: true
      multiline.pattern: '^s'
      multiline.match: after
      document_type: kube-logs
      tail_files: true
      fields_under_root: true
    
    output.redis:
      hosts: ${REDIS_HOST:?No Redis host configured. Use env var REDIS_HOST to set host.}
      key: "filebeat"
      
    kubectl get pods -l app=filebeat -o wide
    NAME                READY   STATUS    RESTARTS   AGE   IP            NODE          NOMINATED NODE   READINESS GATES
    filebeat-ds-8bg8x   1/1     Running   0          52m   10.244.1.6    k8s-master2   <none>           <none>
    filebeat-ds-nws56   1/1     Running   0          52m   10.244.0.10   k8s-node1     <none>           <none>
    filebeat-ds-t442d   1/1     Running   0          52m   10.244.2.11   k8s-node2     <none>           <none>
    

    DaemonSet滚动更新

    DaemonSet有两种更新策略类型:

    • OnDelete:这是向后兼容性的默认更新策略。使用 OnDelete更新策略,在更新DaemonSet模板后,只有在手动删除旧的DaemonSet pod时才会创建新的DaemonSet pod。这与Kubernetes 1.5或更早版本中DaemonSet的行为相同。
    • RollingUpdate:使用RollingUpdate更新策略,在更新DaemonSet模板后,旧的DaemonSet pod将被终止,并且将以受控方式自动创建新的DaemonSet pod。

    要启用DaemonSet的滚动更新功能,必须将其设置 .spec.updateStrategy.typeRollingUpdate

    查询当前更新策略

    # kubectl get ds/filebeat-ds -o go-template='{{.spec.updateStrategy.type}}{{"
    "}}'
    RollingUpdate
    

    更新DaemonSet模板

    RollingUpdateDaemonSet的任何更新都.spec.template将触发滚动更新。这可以通过几个不同的kubectl命令来完成。

    声明式命令方式:

    如果使用配置文件进行更新DaemonSet,可以使用kubectl aapply:

    kubectl apply -f ds-demo.yaml
    

    补丁式命令方式:

    kubectl edit ds/filebeat-ds
    kubectl patch ds/filebeat-ds -p=<strategic-merge-patch>
    

    仅仅更新容器镜像还可以使用以下命令:

    kubectl set image ds/<daemonset-name> <container-name>=<container-new-image>
    

    下面对filebeat-ds的镜像进行版本更新,如下:

    # kubectl set image daemonsets filebeat-ds filebeat=ikubernetes/filebeat:5.6.6-alpine
    daemonset.apps/filebeat-ds image updated	
    
    #观察更新
    # kubectl get pods -w
    NAME                     READY   STATUS    RESTARTS   AGE
    filebeat-ds-8bg8x        1/1     Running   0          56m
    filebeat-ds-nws56        1/1     Running   0          56m
    filebeat-ds-t442d        1/1     Running   0          56m
    redis-646cf89449-zwhzg   1/1     Running   0          56m
    web-7c95ff84fc-6n4sg     1/1     Running   0          3d19h
    web-7c95ff84fc-cj84l     1/1     Running   0          3d19h
    filebeat-ds-nws56        1/1     Terminating   0          57m
    filebeat-ds-nws56        0/1     Terminating   0          57m
    filebeat-ds-nws56        0/1     Terminating   0          57m
    filebeat-ds-nws56        0/1     Terminating   0          57m
    filebeat-ds-7nmwm        0/1     Pending       0          0s
    filebeat-ds-7nmwm        0/1     Pending       0          1s
    filebeat-ds-7nmwm        0/1     ContainerCreating   0          2s
    filebeat-ds-7nmwm        1/1     Running             0          31s
    filebeat-ds-t442d        1/1     Terminating         0          57m
    filebeat-ds-t442d        0/1     Terminating         0          58m
    filebeat-ds-t442d        0/1     Terminating         0          58m
    filebeat-ds-t442d        0/1     Terminating         0          58m
    filebeat-ds-br5x9        0/1     Pending             0          1s
    filebeat-ds-br5x9        0/1     Pending             0          1s
    filebeat-ds-br5x9        0/1     ContainerCreating   0          4s
    filebeat-ds-br5x9        1/1     Running             0          33s
    filebeat-ds-8bg8x        1/1     Terminating         0          58m
    filebeat-ds-8bg8x        0/1     Terminating         0          58m
    filebeat-ds-8bg8x        0/1     Terminating         0          59m
    filebeat-ds-8bg8x        0/1     Terminating         0          59m
    filebeat-ds-dbrkx        0/1     Pending             0          1s
    filebeat-ds-dbrkx        0/1     Pending             0          2s
    filebeat-ds-dbrkx        0/1     ContainerCreating   0          5s
    filebeat-ds-dbrkx        1/1     Running             0          50s
    
    
    
    # kubectl get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    filebeat-ds-7nmwm        1/1     Running   0          5m15s
    filebeat-ds-br5x9        1/1     Running   0          4m34s
    filebeat-ds-dbrkx        1/1     Running   0          3m
    redis-646cf89449-zwhzg   1/1     Running   0          62m
    web-7c95ff84fc-6n4sg     1/1     Running   0          3d19h
    web-7c95ff84fc-cj84l     1/1     Running   0          3d19h
    

    从上面的滚动更新,可以看到在更新过程中,是先终止旧的pod,再创建一个新的pod,逐步进行替换。

  • 相关阅读:
    为结构体中函数指针赋值的两种方法(转)
    (obj) error: LNK2019: 无法解析的外部符号解决方法
    js cookie存储方法
    js关于对象键值为数字型时输出的对象自动排序问题的解决方法
    HTML5 LocalStorage 本地存储的用法
    onhashchange事件,只需要修改hash值即可响应onhashchange事件中的函数(适用于上一题下一题和跳转页面等功能)
    js实现页面a向页面b传参的方法
    前端比较好的学习资料(包括js和css)以及 最全前端资源汇集
    字符串js编码转换成实体html编码的方法(防范XSS攻击)
    fis3使用环境
  • 原文地址:https://www.cnblogs.com/Gmiaomiao/p/14410045.html
Copyright © 2020-2023  润新知