pod 控制器介绍

一    pod 控制器相关理论介绍

1,Pod控制器 是什么

Pod控制器,又称之为工作负载(workload),是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。
 

2,pod控制器 类型

2.1 ReplicaSet

代用户创建指定数量的pod副本,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。

ReplicaSet主要三个组件组成:
(1)用户期望的pod副本数量
(2)标签选择器,判断哪个pod归自己管理
(3)当现存的pod数量不足,会根据pod资源模板进行新建
帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。

2.2  Deployment

工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。
ReplicaSet 与Deployment 这两个资源对象逐步替换之前RC的作用。
 

2.3 DaemonSet

用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务
特性:服务是无状态的
服务必须是守护进程
 

2.4 StatefulSet

管理有状态应用

应用范围:

数据库       分布式存储     kafka  等

2.5 Job

只要完成就立即退出,不需要重启或重建
 

2.6 Cronjob

周期性任务控制,不需要持续后台运行
 

3,什么是有状态应用 和无状态应用

3.1无状态应用(Stateless Application)

定义:无状态应用是指不依赖于任何先前交互上下文或会话数据的应用程序。每个请求都被视为独立的,可以被任何实例处理,而不需要关心之前发生过什么。这类应用不保存客户端会话数据,也不依赖于应用上次运行时的状态。

特点

  • 可伸缩性:易于横向扩展,可以简单地增加或减少实例数量而不会影响应用状态或导致数据一致性问题。
  • 负载均衡:请求可以被任意实例处理,非常适合使用负载均衡器分发请求。
  • 容错性:实例可以随时启动或停止,因为没有状态需要保留,因此容错性较高。
  • 示例:简单的Web服务器、API网关、缓存服务器(如Redis,当配置为不持久化数据时)等。
3.2 有状态应用(Stateful Application)

定义:有状态应用则相反,它需要维护一些跨请求或会话的数据状态。这些应用依赖于特定实例上的数据或需要存储和跟踪客户端交互的历史信息,如用户会话、数据库连接或文件系统中的特定文件。

特点

  • 持久化存储:需要持久化存储来维持状态,如数据库、文件系统或专用存储卷。
  • 有序扩展:扩展时需要考虑状态的连续性,不能随意添加或移除实例,因为数据一致性至关重要。
  • 标识与持久性:每个实例通常需要唯一的标识,并且与存储资源绑定,如Kubernetes中的StatefulSet资源就为此设计。
  • 示例:数据库(如MySQL)、消息队列(如RabbitMQ)、用户会话服务等。

总结:有状态应用和无状态应用的主要区别在于是否需要维护持久化的状态信息。无状态应用更易于部署和扩展,而有状态应用则需要更复杂的管理机制来确保数据的一致性和持久化。在设计和部署现代云原生应用时,理解这两者的差异对于选择合适的服务管理和部署策略至关重要。

4,  Pod与控制器之间的关系

controllers:在集群上管理和运行容器的 pod 对象, pod 通过 label-selector 相关联。
Pod 通过控制器实现应用的运维,如伸缩,升级等。

  1. Pods与控制器(Controllers)的基本概念:

    • Pod: 是Kubernetes中的最小可部署单元,包含一个或多个紧密相关的容器(例如微服务的一个实例),这些容器共享存储和网络空间。Pod用来封装应用的运行环境。

    • 控制器(Controllers): 是更高层次的抽象,用于管理Pod的生命周期,确保Pod按照预期的数量、状态运行。常见的控制器包括Deployment、StatefulSet、DaemonSet、Job和CronJob等。

  2. 通过label-selector相关联:

    • 控制器管理Pod的方式之一是使用label-selector。每个Pod都会被打上一组键值对标签(labels),控制器则根据这些标签来选择并管理目标Pod。例如,一个Deployment可能会配置为管理所有带有特定标签(如app=my-web-server)的Pods,这样控制器就能准确地知道哪些Pod属于它的管理范围,即使Pod因故障重建或扩缩容而发生变化。
  3. Pod通过控制器实现应用的运维:

    • 伸缩(Scaling): 控制器允许自动或手动调整托管Pod的数量,以应对负载变化。比如,Deployment可以设置副本数(replicas),自动增加或减少Pod的数量以响应流量需求。

    • 升级(Rolling Updates/Rollbacks): 控制器支持平滑升级,能够在不中断服务的情况下逐步替换旧版本Pod为新版本Pod。如果新版本有问题,还可以轻松回滚到之前的稳定版本。

    • 健康检查与自愈: 控制器负责监控Pod的健康状况,如果发现某个Pod不健康或失败,它会自动创建新的Pod替换它,确保应用总是按预期运行。

综上所述,Pod与控制器之间的关系是:控制器利用label-selector机制识别并管理Pod集合,通过实施策略(如自动伸缩、滚动更新)来实现应用的自动化运维,保证服务的高可用性和灵活性。这种方式极大地简化了分布式系统的服务管理和运维工作。

二   pod 控制器 实例演示

1, Deployment

部署无状态应用
管理Pod和ReplicaSet
具有上线部署、副本设定、滚动升级、回滚等功能
提供声明式更新,例如只更新一个新的image
应用场景:web服务

deployment 启动nginx pod

vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx	
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

原神! 启动!

kubectl create -f nginx-deployment.yaml

查看控制器配置

kubectl edit deployment/nginx-deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2021-04-19T08:13:50Z"
  generation: 1
  labels:
    app: nginx					#Deployment资源的标签
  name: nginx-deployment
  namespace: default
  resourceVersion: "167208"
  selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/nginx-deployment
  uid: d9d3fef9-20d2-4196-95fb-0e21e65af24a
spec:
  progressDeadlineSeconds: 600
  replicas: 3					#期望的pod数量,默认是1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%				#升级过程中会先启动的新Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
      maxUnavailable: 25%		#升级过程中在新的Pod启动好后销毁的旧Pod的数量不超过期望的Pod数量的25%,也可以是一个绝对值
    type: RollingUpdate			#滚动升级
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx				#Pod副本关联的标签
    spec:
      containers:
      - image: nginx:1.15.4				#镜像名称
        imagePullPolicy: IfNotPresent	#镜像拉取策略
        name: nginx
        ports:
        - containerPort: 80				#容器暴露的监听端口
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always				#容器重启策略
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
......

查看历史版本

kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION  CHANGE-CAUSE
1         <none>

2, DaemonSet

2.1 DaemonSet 是什么

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

2.2 DaemonSet 典型用法

●运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
●在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
●在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。
应用场景:Agent
 

2.3 官方案例

//官方案例(监控)
https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
 

2.4 示例
vim ds.yaml 
apiVersion: apps/v1
kind: DaemonSet 
metadata:
  name: nginx-daemonSet
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

DaemonSet会在每个node节点都创建一个Pod

kubectl apply -f ds.yaml


kubectl get pods
nginx-deployment-4kr6h   1/1     Running     0          35s
nginx-deployment-8jrg5   1/1     Running     0          35s

3,  Job

常用于运行那些仅需要执行一次的任务
 

 3.1  应用场景

数据库迁移、批处理脚本、kube-bench扫描、离线数据处理,视频解码等业务
 

3.2 官网

https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/    
 

3.3 实例

写yaml

vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

//参数解释
.spec.template.spec.restartPolicy该属性拥有三个候选值:OnFailure,Never和Always。默认值为Always。它主要用于描述Pod内容器的重启策略。在Job中只能将此属性设置为OnFailure或Never,否则Job将不间断运行。

.spec.backoffLimit用于设置job失败后进行重试的次数,默认值为6。默认情况下,除非Pod失败或容器异常退出,Job任务将不间断的重试,此时Job遵循 .spec.backoffLimit上述说明。一旦.spec.backoffLimit达到,作业将被标记为失败。

 在所有node节点下载perl镜像,因为镜像比较大,所以建议提前下载好

docker pull perl

执行

kubectl apply -f job.yaml 

kubectl get pods
pi-bqtf7                 0/1     Completed   0          41s

结果输出到控制台

kubectl logs pi-bqtf7
3.14159265......

4, CronJob 

4.1 是什么

周期性任务,像Linux的Crontab一样。
周期性任务
 

4.2 应用场景

通知,备份
https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/

4.3 实例

每分钟打印hello

vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

//cronjob其它可用参数的配置
spec:
  concurrencyPolicy: Allow                           #要保留的失败的完成作业数(默认为1)
  schedule: '*/1 * * * *'                                   #作业时间表。在此示例中,作业将每分钟运行一次
  startingDeadlineSeconds: 15                       #pod必须在规定时间后的15秒内开始执行,若超过该时间未执行,则任务将不运行,且标记失败
  successfulJobsHistoryLimit: 3                     #要保留的成功完成的作业数(默认为3)
  terminationGracePeriodSeconds: 30           #job存活时间 默认不设置为永久
  jobTemplate:                                                 #作业模板。这类似于工作示例
 

执行    查看计划任务

kubectl create -f cronjob.yaml 

kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          25s

查看日志

kubectl get pods
NAME                     READY   STATUS      RESTARTS   AGE
hello-1621587180-mffj6   0/1     Completed   0          3m
hello-1621587240-g68w4   0/1     Completed   0          2m
hello-1621587300-vmkqg   0/1     Completed   0          60s
kubectl logs hello-1621587180-mffj6
Fri May 21 09:03:14 UTC 2021
Hello from the Kubernetes cluster

4.4 报错
//如果报错:Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log hello-1621587780-c7v54)
//解决办法:绑定一个cluster-admin的权限
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous

三    SatefulSet  单独介绍

1,理论

1.1 SatefulSet 是什么

部署有状态应用
稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
有序收缩,有序删除(即从N-1到0)
 

1.2 常见的应用场景

用在数据库

和 分布式存储

和 kafka

1.3 官网

https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/

1.4 yaml 文件实例
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

 

2, 三个组件

从上面的应用场景可以发现,StatefulSet由以下几个部分组成:

●Headless Service(无头服务):用于为Pod资源标识符生成可解析的DNS记录。
●volumeClaimTemplates(存储卷申请模板):基于静态或动态PV供给方式为Pod资源提供专有的固定存储。
●StatefulSet:用于管控Pod资源。

2.1 为什么要有headless?

在deployment中,每一个pod是没有名称,是随机字符串,是无序的。而statefulset中是要求有序的,每一个pod的名称必须是固定的。当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一。
为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称。
 

2.2 为什么要有volumeClainTemplate?

大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点。而在 deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的,这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷
 

3, 服务发现

3.1 定义

就是应用服务之间相互定位的过程。

3.2 应用场景

●动态性强:Pod会飘到别的node节点
●更新发布频繁:互联网思维小步快跑,先实现再优化,老板永远是先上线再慢慢优化,先把idea变成产品挣到钱然后再慢慢一点一点优化
●支持自动伸缩:一来大促,肯定是要扩容多个副本
 

3.3 K8S里服务发现的方式

DNS,使K8S集群能够自动关联Service资源的“名称”和“CLUSTER-IP”,从而达到服务被集群自动发现的目的。
 

3.4 实现K8S里DNS功能的插件:

●skyDNS:Kubernetes 1.3之前的版本
●kubeDNS:Kubernetes 1.3至Kubernetes 1.11
●CoreDNS:Kubernetes 1.11开始至今
 

4, 安装CoreDNS

仅二进制部署环境需要安装CoreDNS

CoreDNS用于提供解析服务与自动发现,使K8S集群能够自动关联Service资源的“名称”和“CLUSTER-IP”,从而达到服务被集群自动发现的目的

使用kubeadm安装或其它一键安装k8s集群的,会默认安装CoreDNS,只有当使用二进制安装的时候,需要手动去安装CoreDNS

4.1 方法一

下载链接:https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base

vim transforms2sed.sed
s/__DNS__SERVER__/10.0.0.2/g
s/__DNS__DOMAIN__/cluster.local/g
s/__DNS__MEMORY__LIMIT__/170Mi/g
s/__MACHINE_GENERATED_WARNING__/Warning: This is a file generated from the base underscore template file: coredns.yaml.base/g

sed -f transforms2sed.sed coredns.yaml.base > coredns.yaml

4.2  方法二

上传 coredns.yaml 文件

kubectl create -f coredns.yaml

kubectl get pods -n kube-system

4.3  验证DNS是否可以使用
[root@master01 pod]#kubectl run busybox --image=busybox:1.28  -- sleep 36000 
pod/busybox created
#创建一个busybox的pod,该容器提供一些基本的命令,主要用于测试环境
[root@master01 pod]#kubectl get pod busybox
NAME                                      READY   STATUS    RESTARTS   AGE
busybox                                   1/1     Running   0          4s
[root@master01 pod]#kubectl exec -it busybox sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup kubernetes    #测试svc能否正常解析,可以使用kubectl get svc查看有哪些svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 
Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
#解析正常,解析kubernetes的地址为10.96.0.1
[root@master01 pod]#kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   13d
mydb         ClusterIP   10.96.50.193   <none>        80/TCP    5d17h
myservice    ClusterIP   10.96.33.11    <none>        80/TCP    5d17h
nginx        ClusterIP   10.96.222.66   <none>        80/TCP    3d20h

5,   创建service(无头模式)

StatefulSet 资源依赖于无头模式的service

[root@master01 pod]#vim service.yaml
[root@master01 pod]#cat service.yaml
apiVersion: v1           #指定API版本
kind: Service            #创建资源类型为Service
metadata:
  name: headless-svc     #指定service名称
  labels:
    app: headless-svc    #设置service标签
spec:
  ports:
  - port: 80             #service端口
    name: web            #端口名称
    targetport: 80       #指定流量转发的目标端口,与pod暴露的端口一致
  clusterIP: None        #将clusterIP地址的值设置为None,表示无IP地址,即无头模式
  selector:              #选择管理的标签
    app: state           #此标签需要与StatefulSet控制器管理的pod模板中定义的标签一致
  type: ClusterIP        #设置类型为ClusterIP,此为默认设置,可以省略

创建service

[root@master01 pod]#kubectl apply -f service.yaml
service/headless-svc created
[root@master01 pod]#kubectl get svc headless-svc 
NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
headless-svc   ClusterIP   None         <none>        80/TCP    10s

6, 创建StatefulSet

[root@master01 pod]#vim statefulset.yaml
[root@master01 pod]#cat statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet               #创建资源类型为StatefulSet
metadata:
  name: state                   #指定资源名称
spec:
  serviceName: headless-svc     #指定需要绑定的service名称
  replicas: 3                   #创建pod数量为三个
  selector:                     #标签选择器,指定StatefulSet要管理哪些pod
    matchLabels:                #指定标签名称
      app: state   #必须与service中selector定义的标签一致。pod含有此标签的,都会去管理
  template:                     #指定pod创建模板
    metadata:
      labels:
        app: state              #设置pod标签,与上面标签选择器相同,StatefulSet才会管理
    spec:
      containers:               #定义pod中运行的容器
      - name: nginx-pod         #应当设置有状态的服务,在此以nginx为例,官方文档有MySQL示例
        image: nginx:1.18.0     #定义镜像
        ports:
        - containerPort: 80     #定义容器监听端口
          name: web             #端口名称
        volumeMounts:           #定义将存储卷卷挂载到指定目录
        - name: html            #指定存储卷名称
          mountPath: /usr/share/nginx/html  #挂载到此目录,此目录为nginx服务的站点目录
  volumeClaimTemplates:         #PVC的请求模板
  - metadata:
      name: html                #定义PVC的名称
      annotations:
        volume.beta.kubernetes.io/storage-class: nfs-client-storageclass
#用于指定存储类的注解。该存储类定义了用于动态卷供应的后端存储类型
    spec:
      accessModes: ["ReadWriteOnce"]   #指定访问模式为RWO
      resources:
        requests:
          storage: 2Gi                 #指定存储卷的使用大小

创建pod查看

[root@master01 pod]#kubectl apply -f statefulset.yaml 
statefulset.apps/state created
[root@master01 pod]#kubectl get statefulsets.apps state 
NAME    READY   AGE
state   2/3     14s
[root@master01 pod]#kubectl get statefulsets.apps state 
NAME    READY   AGE
state   3/3     17s
[root@master01 pod]#kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
busybox                                   1/1     Running   0          40m
nfs-client-provisioner-794bf7886f-85bwb   1/1     Running   0          5h51m
state-0                                   1/1     Running   0          25s
state-1                                   1/1     Running   0          19s
state-2                                   1/1     Running   0          13s
#它会按照0到N-1的顺序去指定pod名称,一定建立,指定pod生命周期结束,否则IP地址改变,它的名称也不会改变

创建完之后,查看一下PV与PVC

在NFS服务器上自定义web界面

[root@nfs k8s]#ls
default-html-state-0-pvc-0bffc66c-b29e-40cd-bef5-18c1abe250af   #state-0的PV卷
default-html-state-1-pvc-1aaee76c-7c94-4a8d-abc3-0b4f804239bc   #state-1的PV卷
default-html-state-2-pvc-f82bb183-c3d8-49b1-be39-c4ee96f7e076   #state-2的PV卷
[root@nfs k8s]#echo "this is state-0" > default-html-state-0-pvc-0bffc66c-b29e-40cd-bef5-18c1abe250af/index.html
[root@nfs k8s]#echo "this is state-1" > default-html-state-1-pvc-1aaee76c-7c94-4a8d-abc3-0b4f804239bc/index.html
[root@nfs k8s]#echo "this is state-2" > default-html-state-2-pvc-f82bb183-c3d8-49b1-be39-c4ee96f7e076/index.html

由于没有ClusterIP地址,想要通过IP地址访问,只能在k8s集群中直接访问podIP

7,   使用service访问

此时,创建的service是可以进行解析的 

[root@master01 pod]#kubectl exec -it busybox sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup headless-svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
 
Name:      headless-svc
Address 1: 10.244.2.208 state-0.headless-svc.default.svc.cluster.local
Address 2: 10.244.1.189 state-1.headless-svc.default.svc.cluster.local
Address 3: 10.244.2.209 state-2.headless-svc.default.svc.cluster.local
#该service会通过endpoint关联到后端的pod

由于pod的IP地址是k8s集群内部的IP地址,且并没有clusterIP去绑定podIP,只有域名管理,宿主机的DNS解析,无法解析k8s集群内部的域名与地址,所以使用宿主机无法访问pod。只能通过创建pod,在pod中进行访问

可以看到,访问的pod是随机的,因为k8s内部的负载均衡方式,是通过资源的使用率进行分配的,它会将请求优先分配到资源使用率较少的pod上,可以使用压测工具去测试,而后再进行访问 

8, 删除与创建

当pod删除时,会按照N-1到0的顺序,倒序删除 

[root@master01 pod]#kubectl delete -f statefulset.yaml
statefulset.apps "state" deleted
[root@master01 pod]#kubectl get pod -w
NAME                                      READY   STATUS    RESTARTS   AGE
busybox                                   1/1     Running   0          65m
centos                                    1/1     Running   0          9m12s
nfs-client-provisioner-794bf7886f-85bwb   1/1     Running   0          6h16m
state-0                                   1/1     Running   0          25m
state-1                                   1/1     Running   0          25m
state-2                                   1/1     Running   0          25m
state-2                                   1/1     Terminating   0          25m
state-1                                   1/1     Terminating   0          25m
state-0                                   1/1     Terminating   0          25m
state-2                                   0/1     Terminating   0          25m
state-1                                   0/1     Terminating   0          25m
state-0                                   0/1     Terminating   0          25m
state-2                                   0/1     Terminating   0          25m
state-1                                   0/1     Terminating   0          25m
state-0                                   0/1     Terminating   0          25m

重新创建的时候,数据会持久化 ,而且创建的顺序还是按照0到N-1的顺序创建 

重新创建之后再次访问,数据不会丢失 

再次解析service的话,它的解析地址会发生改变

 

这就是无头模式的作用,不论后端的IP地址如何变化,只通过DNS来解析service,从而绑定后端的IP地址,得到数据

9,  小结


StatefulSet控制器的实现,是一个相对复杂的过程,需要大家在平时多练多学,在生成环境中才能避免出现问题,因为StatefulSet管理的都是一些有状态的服务,一旦容器失败,导致数据丢失,可能会造成不好的影响

deployment与statefulset的区别

4.1 应用场景

Deployment:主要用于部署无状态服务,即服务实例之间可以相互替换且不需要保留特定的网络标识或存储数据。它适用于那些不需要关心Pod具体身份且可任意替换的弹性服务。

StatefulSet:适用于部署有状态的服务,比如数据库集群、消息队列等。这些服务需要稳定的持久化存储和唯一、有序的网络标识。StatefulSet为Pod分配的网络标识符和存储都是稳定的,使得应用能够维持跨重启或再调度的持久状态。

4.2 Pod管理

Deployment:通过ReplicaSet确保指定数量的Pod副本始终运行,提供水平扩展和滚动更新能力。Pod由Deployment创建时,虽然可以自定义名称,但通常由系统生成,并在重建或扩展时可能会发生变化。

StatefulSet:Pods在创建、更新和删除时按照顺序进行,以满足那些依赖于严格顺序启动或停止的应用场景需求。每个Pod都有一个固定的、唯一的网络标识符,并且其持久卷声明(PVC)会绑定到持久化的存储,即使Pod被删除后重新创建,存储的数据也会保留。

4.3 存储与网络

Deployment:通常不直接管理Pod的存储和网络,而是依赖于其他Kubernetes资源(如PersistentVolume和Service)来实现这些功能。

StatefulSet:为Pod提供稳定的存储和网络标识,确保有状态应用能够正常运行。StatefulSet通常与Headless Service和volumeClaimTemplate一起使用,以提供可解析的DNS资源记录和专有且固定的存储。

4.4 升级与回滚

Deployment:支持多种升级策略,如滚动更新和回滚,确保服务在整个升级过程中具有高可用性。通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态,并逐步替换旧的Pod。

StatefulSet:也支持有序而自动的滚动更新,但由于涉及到有状态应用,更新过程可能更加复杂和严格。同时,StatefulSet也支持回滚到之前的版本。

4.5 扩展性

Deployment:可以根据系统负载进行水平扩展和缩容,通过调整ReplicaSet的副本数来实现。

StatefulSet:虽然也支持扩展和缩容操作,但由于涉及到有状态应用和数据一致性等问题,扩展性可能相对较弱。

10,  Headless Service

和 Cluster IP Service 是 Kubernetes (K8s) 中两种不同类型的Service资源,它们的主要区别在于服务发现机制和流量管理方式。

Cluster IP Service:

  • 概述: 这是Kubernetes中最常见的Service类型,它为一组Pod提供一个固定的、虚拟的Cluster IP地址和一个或多个端口。这个Cluster IP地址充当服务的前端入口,客户端通过这个地址访问服务,而实际流量会被kube-proxy组件根据负载均衡策略转发到后端的一个或多个Pod上。

  • 特点:

    • 分配一个虚拟的Cluster IP。

    • 通过kube-proxy实现负载均衡。

    • 隐藏了后端Pod的细节,客户端只与Cluster IP交互。

    • 适用于需要负载均衡和高可用性的场景。

Headless Service:

  • 概述: Headless Service不分配Cluster IP,意味着没有一个中心的IP地址来负载均衡流量。当创建Headless Service时,Kubernetes不会为它分配Cluster IP,也不会通过kube-proxy来进行请求的代理或负载均衡。

  • 特点:

    • 不分配Cluster IP。

    • kube-proxy不会处理这类Service,不提供负载均衡。

    • 每个关联的Pod都有独立的DNS记录,可以直接通过Pod的IP或其DNS名称访问。

    • 适用于需要直接访问Pod、状态ful应用(如MongoDB副本集)、或者客户端需要自己决定连接哪个Pod的场景。

  • 实现方式:

    • 在DNS层面,Headless Service会返回一个包含所有关联Pod IP地址的DNS记录(通常是A或AAAA记录的列表),允许客户端直接选择并连接到特定的Pod。

    • 由于没有Cluster IP,客户端或服务间的通信可以更直接,适用于需要维护会话黏性或有特定Pod选择逻辑的应用场景。

综上,Headless Service通过放弃Cluster IP和负载均衡功能,提供了更直接的Pod访问途径,增加了服务发现的灵活性,特别适合那些需要直接交互或有状态应用的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/673826.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用modbus-serial 库搭配 modbus slave 通过 modbus tcp client 协议来 写入 modbus 寄存器值

使用modbus-serial 库对modbus slave 写入寄存器值 modbus tcp client 代码 目标电脑&#xff08;启动modbus slave 的电脑&#xff09;ip为 192.168.3.46&#xff0c;端口502 // 读取另一台电脑&#xff0c;192.168.3.46:502 Modbus TCP // create an empty modbus client c…

2005NOIP普及组真题 4. 循环

线上OJ&#xff1a; 【05NOIP普及组】循环 核心思想&#xff1a;高精度 1、本题用到了标准的高精度乘法模板 void init(int a[]) //传入一个数组 {string s; cin >> s; //读入字符串s a[0] s.length(); //用a[0]计算字符串s的位数 for(i 1; i < a[0]; i) a[i] …

颠覆与重塑|AI助力汽车开发,汽车智能势不可挡

汽车行业深受人工智能的影响&#xff0c;人工智能正在为我们创造全新的出行方式。随着智能化的加速普及&#xff0c;越来越多的消费者开始关注汽车的智能化。智能化的水平已经成为众多消费者购车的参考因素&#xff0c;也成了车企竞争的主赛道&#xff0c;汽车行业也已经成为人…

高校科研信息管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;公告管理&#xff0c;反馈管理&#xff0c;操作日志管理&#xff0c;科研项目管理&#xff0c;通知管理 科研人员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;反馈管理&#xff…

[SQL-SERVER:数据库安全及维护]:MSSM工具对用户进行用户授权和角色授权操作

文章目录 直接为用户授权&#xff08;20分&#xff09;1. 创建登录TLogin&#xff0c;自行指定登录密码服务器层面选择 安全性 > 点击 登录名 > 点击右键 > 点击 新建登录名 > 选择sqlserver验证 > 关闭强制登录更改密码异常解决&#xff1a;sqlserver 配置管理…

【最新鸿蒙应用开发】——什么是应用开发模型?Stage模型

在应用程序开发时通常需要使用应用模型来提供必备的组件和运行机制&#xff0c;有了应用模型&#xff0c;开发者可以基于一套统一的模型进行应用开发&#xff0c;使应用开发更简单、高效。接下来谈谈鸿蒙应用开发当中的两种模型&#xff1a; Stage模型&#xff1a; HarmonyOS …

过滤器、监听器、拦截器的区别

过滤器、监听器、拦截器的区别 过滤器&#xff08;filter&#xff09;、监听器&#xff08;Listener&#xff09;是JavaWeb的三大组件。而拦截器&#xff08;Interceptor&#xff09;是Spring框架中的。 我们主要是要分清除过滤器和拦截器的区别&#xff1a; 实现原理&#…

晶体(二):差分晶振

一、定义 差分晶振是一种有源晶体振荡器&#xff0c;输出差分信号&#xff08;由两个相位相反、幅度相等的信号组成&#xff09;&#xff0c;从而消除了共模噪声&#xff0c;具有抗干扰能力强、对参考电平完整性要求较弱、抑制串扰、EMI 能力强、功耗小、速率高、不受温度和电压…

【Ubuntu常用命令】终端个人常用命令总结

【Ubuntu常用命令】终端常用命令总结 查看硬盘挂载情况查看内存占用情况移动或重命名文件和目录复制文件或目录conda安装本地文件 查看硬盘挂载情况 mount 命令会列出当前系统上所有已挂载的文件系统。它会显示挂载点、文件系统类型、挂载选项等信息 mount df 命令用于显示文…

MySQL学习——影响选项文件处理的命令行选项和程序选项修改器

大多数支持选项文件的MySQL程序都处理以下选项。因为这些选项会影响选项文件的处理&#xff0c;所以必须在命令行上给出&#xff0c;而不是在选项文件中给出。为了正常工作&#xff0c;这些选项中的每一个都必须先于其他选项给出&#xff0c;但以下情况除外&#xff1a; -prin…

AK F.*ing leetcode 流浪计划之费马小定理与组合数取模

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 费马小定理与证明 参考 https://zhuanlan.zhihu.com/p/594859227 费马小定理&#xff1a;如果p是一个质数&#xff0c;而正整数a不是p的倍数&#xff0c;那么a(p-1)≡…

继承的基本语法

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在编写类时&#xff0c;并不是每次都要从空白开始。当要编写的类和另一个已经存在的类之间存在一定的继承关系时&#xff0c;就可以通过继承来达到代…

AI早班车6.3

1.蚂蚁技术日&#xff1a;支付宝三大「AI 管家」亮相。 2.百度赵世奇&#xff1a;百度搜索&#xff0b;文心智能体平台&#xff0c;助力智能体人人可用。 3.腾讯&#xff1a;发布大模型App腾讯元宝。 4.AFAC2024金融智能创新大赛启动&#xff0c;让高质量金融服务人人可用 …

Docker笔记-解决非交互式运行python时print不输出的问题

换句话来说就是在docker中如何不会python的print 只需要在启动时&#xff0c;不让python缓冲其输出。 关键命令如下&#xff1a;PYTHONUNBUFFERED1 如下&#xff1a; docker run -e PYTHONUNBUFFERED1 <your_image> 下面解释下-e "-e"选项的全称是"…

lux和ffmpeg进行下载各大主流自媒体平台视频

1、lux下载&#xff0c;链接&#xff1a;https://pan.baidu.com/s/1WjGbouL3KFTU6LeqZmACpA?pwdagpp 提取码&#xff1a;agpp 2、ffmpeg下载&#xff0c;跟lux放在同一个目录&#xff1b; 3、为lux、ffmpeg设置环境变量&#xff1b; 4、WINR&#xff0c;打开运行&#xff0…

Love-Yi情侣网站3.0存在SQL注入漏洞

目录 1. 前言 2. 网站简介 3. 寻找特征点 3.1 第一次尝试 3.2 第二次尝试 4.资产搜索 5.漏洞复现 5.1 寻找漏洞点 5.2 进行进一步测试 5.2.1 手动测试 1.寻找字段 2.寻找回显位 3.查询当前用户 5.2.2 sqlmap去跑 6.总结 1. 前言 朋友说自己建了一个情侣网站,看到…

chat4-Server端保存聊天消息到mysql

本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端 同时将聊天消息保存到mysql 服务端为当前客户端创建一个线程&#xff0c;此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端同时将聊天消息保存到mysql 本文档主要总结了将聊天…

基于django | 创建app,并启动django

1、删除系统默认的目录路径&#xff1a;BASE_DIR / templetes 2、在终端输入命令&#xff1a; python manage.py startapp app01 # 这里的app01是我创建app的名称 3、如果没有创建成功&#xff0c;手动点击 Creat App , 4、在 setting.py 中找到 INSTALLED_APPS ,添加 ap…

✅count(1)、count(*) 与 count(列名) 的区别

简单来说&#xff1a; COUNT(1) 和 COUNT(*) 表示的是直接查询符合条件的数据库表的行数。而 COUNT(列名) 表示的是查询符合条件的列的值不为 NULL 的行数。 除了查询得到结果集有区别之外&#xff0c;在性能方面 COUNT() 约等于 COUNT(1)&#xff0c;但是 **COUNT() 是 SQL9…

Qt——升级系列(Level Two):Hello Qt 程序实现、项目文件解析、

Hello Qt 程序实现 使用“按钮”实现 纯代码方式实现&#xff1a; // Widget构造函数的实现 Widget::Widget(QWidget *parent): QWidget(parent) // 使用父类构造函数初始化QWidget&#xff0c;传入父窗口指针, ui(new Ui::Widget) // 创建Ui::Widget类的实例&#xff0c;并…