ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

k8s资源对象:StatefulSet和DaemonSet

2022-08-13 17:30:08  阅读:174  来源: 互联网

标签:node StatefulSet statefulset DaemonSet test Pod k8s 节点


k8s资源对象:StatefulSet和DaemonSet

StatefulSet

简介:

StatefulSet 是用来管理有状态应用的工作负载 API 对象。

  • 无状态服务(Stateless Service):该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一个请求响应的结果是完全一致的。

  • 有状态服务(Stateful Service):就和上面的概念是对立的了,该服务运行的实例需要在本地存储持久化数据,比如MySQL数据库,你现在运行在节点A,那么他的数据就存储在节点A上面的,如果这个时候你把该服务迁移到节点B去的话,那么就没有之前的数据了,因为他需要去对应的数据目录里面恢复数据,而此时没有任何数据。

StatefulSet 用来管理某 Pod 集合的部署和扩缩, 并为这些 Pod 提供持久存储和持久标识符。

Deployment 类似, StatefulSet 管理基于相同容器规约的一组 Pod。但和 Deployment 不同的是, StatefulSet 为它们的每个 Pod 维护了一个有粘性的 ID。这些 Pod 是基于相同的规约来创建的, 但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。

如果希望使用存储卷为工作负载提供持久存储,可以使用 StatefulSet 作为解决方案的一部分。 尽管 StatefulSet 中的单个 Pod 仍可能出现故障, 但持久的 Pod 标识符使得将现有卷与替换已失败 Pod 的新 Pod 相匹配变得更加容易。

StatefulSet作用:

  • Statefulset为了解决有状态服务的集群部署、集群之间的数据同步问题(MySQL主从等)
  • Statefulset所管理的Pod拥有唯一且固定的Pod名称
  • Statefulset按照顺序对pod进行启停、伸缩和回收
  • Headless Services(无头服务,请求的解析直接解析到pod IP)

StatefulSet 对于需要满足以下一个或多个需求的应用程序很有价值:

  • 稳定的、唯一的网络标识符。
  • 稳定的、持久的存储。
  • 有序的、优雅的部署和扩缩。
  • 有序的、自动的滚动更新。

使用限制:

  • 给定 Pod 的存储必须由 PersistentVolume 驱动 基于所请求的 storage class 来提供
  • 删除或者扩缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
  • StatefulSet 当前需要无头服务 来负责 Pod 的网络标识。
  • 当删除一个 StatefulSet 时,该 StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序且体面地终止,可以在删除之前将 StatefulSet 缩容到 0。
  • 在默认 Pod 管理策略(OrderedReady) 时使用 滚动更新,可能进入需要人工干预才能修复的损坏状态。

官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/statefulset/

示例:

root@k8s-master-01:/opt/yaml/StatefulSet# vim StatefulSet-test.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-test
  namespace: myserver
spec:
  selector:
    matchLabels:
      app: statefulset-nginx
  serviceName: statefulset-nginx-service
  replicas: 2
  template:
    metadata:
      labels:
        app: statefulset-nginx
    spec:
      containers:
      - name: statefulset-nginx
        image: xmtx.harbor.com/baseimages/nginx:1.9.1
        ports:
          - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  namespace: myserver
  name: statefulset-nginx-service
spec:
  clusterIP: None  #无头服务,请求的解析直接解析到pod IP
  ports:
  - name: http
    port: 80
  selector:
    app: statefulset-nginx
#运行
root@k8s-master-01:/opt/yaml/StatefulSet# kubectl apply -f StatefulSet-test.yaml 
statefulset.apps/statefulset-test unchanged
service/statefulset-nginx-service created
#查看,每个名字后都带有序号,代表先后顺序
root@k8s-master-01:/opt/yaml/StatefulSet# kubectl get pod -n myserver 
NAME                 READY   STATUS    RESTARTS   AGE
statefulset-test-0   1/1     Running   0          29s
statefulset-test-1   1/1     Running   0          29s
root@k8s-master-01:/opt/yaml/StatefulSet# kubectl get service -n myserver 
NAME                        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
statefulset-nginx-service   ClusterIP   None         <none>        80/TCP    3m46s
#每个 Pod 都拥有一个基于其顺序索引的稳定的主机名。使用 kubectl exec 在每个 Pod 中执行 hostname:
root@k8s-master-01:/opt/yaml/StatefulSet# for i in 0 1; do kubectl exec "statefulset-test-$i" -n myserver -- sh -c 'hostname'; done
statefulset-test-0
statefulset-test-1
#访问测试
root@k8s-master-01:/opt/yaml/StatefulSet# kubectl exec -it statefulset-test-1 bash  -n myserver 
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@statefulset-test-1:/# cat /etc/hosts 
# Kubernetes-managed hosts file.
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
fe00::0	ip6-mcastprefix
fe00::1	ip6-allnodes
fe00::2	ip6-allrouters
100.200.89.155	statefulset-test-1.statefulset-nginx-service.myserver.svc.xmtx.local	statefulset-test-1

root@statefulset-test-1:/# ping statefulset-test-0.statefulset-nginx-service.myserver.svc.xmtx.local
PING statefulset-test-0.statefulset-nginx-service.myserver.svc.xmtx.local (100.200.44.222): 56 data bytes
64 bytes from 100.200.44.222: icmp_seq=0 ttl=62 time=0.948 ms
64 bytes from 100.200.44.222: icmp_seq=1 ttl=62 time=0.609 ms
64 bytes from 100.200.44.222: icmp_seq=2 ttl=62 time=0.492 ms

扩缩容

扩容:
#副本数改为5
...
spec:
  selector:
    matchLabels:
      app: statefulset-nginx
  serviceName: statefulset-nginx-service
  replicas: 5
...
#root@k8s-master-01:/opt/yaml/StatefulSet# kubectl get pod -n myserver

StatefulSet 控制器扩展了副本的数量。 如同创建 StatefulSet 所述,StatefulSet 按序号索引顺序创建各个 Pod,并且会等待前一个 Pod 变为 Running 和 Ready 才会启动下一个 Pod。

缩容:
#重新将副本数改为2
replicas: 2

控制器会按照与 Pod 序号索引相反的顺序每次删除一个 Pod。在删除下一个 Pod 前会等待上一个被完全关闭。

升级

StatefulSet 里的 Pod 采用和序号相反的顺序更新。在更新下一个 Pod 前,StatefulSet 控制器终止每个 Pod 并等待它们变成 Running 和 Ready。 请注意,虽然在顺序后继者变成 Running 和 Ready 之前 StatefulSet 控制器不会更新下一个 Pod,但它仍然会重建任何在更新过程中发生故障的 Pod,使用的是它们当前的版本。

已经接收到更新请求的 Pod 将会被恢复为更新的版本,没有收到请求的 Pod 则会被恢复为之前的版本。 像这样,控制器尝试继续使应用保持健康并在出现间歇性故障时保持更新的一致性。

DaemonSet

简介:

DaemonSet用于在每个Kubernetes节点中将守护进程的副本作为后台进程运行,说白了就是在每个节点部署一个Pod副本,当节点加入到Kubernetes集群中,Pod会被调度到该节点上运行,当节点从集群只能够被移除后,该节点上的这个Pod也会被移除,当然,如果我们删除DaemonSet,所有和这个对象相关的Pods都会被删除。

DaemonSet 的一些典型用法:

  • 集群存储守护程序,如glusterdceph要部署在每个节点上以提供持久性存储;
  • 节点监视守护进程,如Prometheus监控集群,可以在每个节点上运行一个node-exporter进程来收集监控节点的信息;
  • 日志收集守护程序,如fluentdlogstash,在每个节点上运行以收集容器的日志

DaemonSet是如何确保每个节点只运行一个Pod:

  1. DaemonSet的控制器模型DaemonSet Controller先从从 Etcd 里获取所有的 Node 列表;
  2. 然后遍历所有的 Node检查,当前这个 Node节点上是不是有一个携带了我们定义标签的 Pod 在运行;
  3. 如果没有定义的 Pod,那么就意味着要在这个 Node 上创建这样一个 Pod;
  4. 如果有定义的 Pod,但是数量大于 1,那就说明要调用 Kubernetes API 把多余的 Pod 从这个 Node 上删除掉;
  5. 如果正好只有一个定义的 Pod,那说明这个节点是正常的。

官方文档:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/daemonset/

示例:

root@k8s-master-01:/opt/yaml/DaemonSet# cat DaemonSet-test.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-test
  namespace: myserver
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      tolerations:
        # 这些容忍度设置是为了让该守护进程集在控制平面节点上运行
        # 如果你不希望自己的控制平面节点运行 Pod,可以删除它们
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: nginx
        image: xmtx.harbor.com/baseimages/nginx:1.9.1
        ports:
          - containerPort: 80
#运行
root@k8s-master-01:/opt/yaml/DaemonSet# kubectl apply -f DaemonSet-test.yaml 
daemonset.apps/daemonset-test created
#查看,可以看到每个节点都运行了一个daemonset-test的pod
root@k8s-master-01:/opt/yaml/DaemonSet# kubectl get  pod -n myserver -o wide 
NAME                   READY   STATUS    RESTARTS   AGE   IP                NODE           NOMINATED NODE   READINESS GATES
daemonset-test-7ggd5   1/1     Running   0          37s   100.200.154.229   172.31.3.120   <none>           <none>
daemonset-test-8lcjc   1/1     Running   0          37s   100.200.183.129   172.31.3.112   <none>           <none>
daemonset-test-9lwsn   1/1     Running   0          37s   100.200.151.129   172.31.3.110   <none>           <none>
daemonset-test-dwldh   1/1     Running   0          37s   100.200.44.228    172.31.3.121   <none>           <none>
daemonset-test-rm6jp   1/1     Running   0          37s   100.200.95.1      172.31.3.111   <none>           <none>
daemonset-test-xckf8   1/1     Running   0          37s   100.200.89.161    172.31.3.122   <none>           <none>
root@k8s-master-01:/opt/yaml/DaemonSet# kubectl get nodes 
NAME           STATUS                     ROLES    AGE   VERSION
172.31.3.110   Ready,SchedulingDisabled   master   13d   v1.24.3
172.31.3.111   Ready,SchedulingDisabled   master   13d   v1.24.3
172.31.3.112   Ready,SchedulingDisabled   master   13d   v1.24.3
172.31.3.120   Ready                      node     13d   v1.24.3
172.31.3.121   Ready                      node     13d   v1.24.3
172.31.3.122   Ready                      node     13d   v1.24.3

部署prometheus node客户端

root@k8s-master-01:/opt/yaml/prometheus# cat DaemonSet-prometheus.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring 
  labels:
    k8s-app: node-exporter
spec:
  selector:
    matchLabels:
        k8s-app: node-exporter
  template:
    metadata:
      labels:
        k8s-app: node-exporter
    spec:
      tolerations:  #容忍,允许pod运行在节点上
        - effect: NoSchedule
          key: node-role.kubernetes.io/master
      containers:
      - image: xmtx.harbor.com/prom/node-exporter:v1.3.1
        imagePullPolicy: IfNotPresent
        name: prometheus-node-exporter
        ports:
        - containerPort: 9100
          hostPort: 9100  #直接在节点上暴露端口
          protocol: TCP
          name: metrics
        volumeMounts:
        - mountPath: /host/proc
          name: proc
        - mountPath: /host/sys
          name: sys
        - mountPath: /host
          name: rootfs
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        - --path.rootfs=/host
      volumes:  #将节点上的指定目录挂载,用来收集节点信息
        - name: proc
          hostPath:
            path: /proc
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /
      hostNetwork: true
      hostPID: true
#查看pod
root@k8s-master-01:/opt/yaml/prometheus# kubectl get pod -n monitoring 
NAME                  READY   STATUS    RESTARTS   AGE
node-exporter-4hd5r   1/1     Running   0          10m
node-exporter-5xlvs   1/1     Running   0          10m
node-exporter-74rnw   1/1     Running   0          10m
node-exporter-r4h64   1/1     Running   0          10m
node-exporter-r85bf   1/1     Running   0          10m
node-exporter-vmklq   1/1     Running   0          10m

标签:node,StatefulSet,statefulset,DaemonSet,test,Pod,k8s,节点
来源: https://www.cnblogs.com/xmtx97/p/16583576.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有