kubernetes-有状态和无状态服务

本文详细介绍了Kubernetes中的有状态服务(如StatefulSet和数据库应用)、无状态服务(如Web服务器)以及无头服务(HeadlessService)的特点、应用场景和配置示例。着重讲解了服务的DNS解析和直接访问Pod的方式。
摘要由CSDN通过智能技术生成

kubernetes-有状态和无状态服务

1.有状态的应用

1.1、理解

有状态服务 可以说是 需要数据存储功能的服务、或者指多线程类型的服务,队列等。(mysql数据库、kafka、zookeeper等)

有状态的应用—>数据需要保存的应用—》数据库应用:MySQL,redis等

statefulSet 有状态控制器

1.2、特点

  • 状态依赖:应用需要保持状态信息,如用户会话、文件系统状态等。
  • 持久化存储:通常需要持久化存储来保存状态信息,如使用Persistent Volumes。
  • 顺序和唯一性:某些操作可能需要按照特定的顺序执行,或者需要保证操作的唯一性。
  • 扩容,缩减的时候是有顺序进行的,不是随机的

2、无状态应用

2.1、理解

数据都是一样的,无论怎么访问,没有什么不同

无状态的应用不需要保存数据–》web服务器

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

2.2、特点

  • 独立性:每个请求都是独立的,不需要保存任何会话信息。
  • 可替换性:任何Pod实例都可以被另一个完全相同的实例替换,而不影响应用的整体功能。
  • 水平扩展:可以轻松地通过增加Pods的数量来扩展应用。
  • **顺序:**随机
  • 不需要保存数据

3、玩一下

3.1、启动一个nginx无状态的业务

[root@master stateful]# vim pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-state
  labels:
    app: nginx
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
[root@master stateful]# 

启动pod

[root@master stateful]# kubectl apply -f pod.yaml 
deployment.apps/nginx-deployment-state created
[root@master stateful]# kubectl get -f pod.yaml 
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment-state   6/6     6            6           15s
[root@master stateful]# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
nginx-deployment-state-75b69bd684-cqh5b   1/1     Running   0          22s
nginx-deployment-state-75b69bd684-hw78n   1/1     Running   0          22s
nginx-deployment-state-75b69bd684-l2r5f   1/1     Running   0          22s
nginx-deployment-state-75b69bd684-ljbrs   1/1     Running   0          22s
nginx-deployment-state-75b69bd684-tk5zt   1/1     Running   0          22s
nginx-deployment-state-75b69bd684-v47cf   1/1     Running   0          22s
[root@master stateful]# 

cqh5b,hw78n这些编号都是随机产生的,没有按照顺序产生

nginx-deployment-state-75b69bd684-cqh5b

  • 部署控制器名字+副本控制器名字+pod编号

3.2、启动一个nginx有状态的业务

[root@master stateful]# vim pod-stateful.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-stateful
  labels:
    app: nginx-stateful
spec:
  type: NodePort
  ports:
  - port: 80
    name: web
    targetPort: 80
    nodePort: 30011
  selector:
    app: nginx-stateful
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web  #pod的名字从web-0开始
spec:
  selector:
    matchLabels:
      app: nginx-stateful # 必须匹配 .spec.template.metadata.labels
  serviceName: "nginx-stateful"
  replicas: 6 # 默认值是 1
  template:
    metadata:
      labels:
        app: nginx-stateful # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx-stateful
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: web

这个pod-stateful.yaml文件包含了两个Kubernetes资源的定义:一个Service和一个StatefulSet。下面是对这两个资源的解释:

Service: nginx-stateful

  • apiVersion: v1: 指定了Kubernetes的API版本为v1。
  • kind: Service: 指定了资源类型为Service。
  • metadata: 包含了Service的元数据。
    • name: nginx-stateful: Service的名称。
    • labels: 定义了标签,这里用于标识这个Service属于nginx-stateful应用。
  • spec: 定义了Service的具体规格。
    • type: NodePort: Service类型为NodePort,这意味着Service将在集群的所有节点上公开端口,并且可以通过nodePort指定的端口从外部访问。
    • ports: 定义了端口映射。
      • port: 80: Service在所有节点上的端口号。
      • targetPort: 80: Pod内部的目标端口号,Service将流量转发到这个端口。
      • name: web: 端口的名称,用于内部引用。
    • selector: 定义了如何选择Pods,这里选择标签为app: nginx-stateful的Pods。

StatefulSet: web

  • apiVersion: apps/v1: 指定了Kubernetes的API版本为apps/v1。
  • kind: StatefulSet: 指定了资源类型为StatefulSet。
  • metadata: 包含了StatefulSet的元数据。
    • name: web: StatefulSet的名称。
  • spec: 定义了StatefulSet的具体规格。
    • selector: 定义了如何通过标签选择Pods,这里选择标签为app: nginx-stateful的Pods。
    • serviceName: 指定了Service的名称,Pods将通过这个Service名进行DNS解析。
    • replicas: 指定了StatefulSet中Pod副本的数量,这里设置为6。
    • template: 定义了Pod模板。
      • metadata: 定义了Pod的元数据。
        • labels: 定义了Pod的标签,这里用于与StatefulSet的selector匹配。
      • spec: 定义了Pod的规格。
        • terminationGracePeriodSeconds: 指定了Pod在停止前等待的时间,用于处理关闭钩子或者优雅地关闭应用。
        • containers: 定义了容器的列表。
          • name: nginx-stateful: 容器的名称。
          • image: nginx: 指定了容器使用的镜像。
          • imagePullPolicy: IfNotPresent: 指定了拉取镜像的策略,如果本地没有镜像则拉取。
          • ports: 定义了容器的端口。
            • containerPort: 80: 容器内部监听的端口号。
              • name: web: 端口的名称,用于内部引用。

总结来说,这个YAML文件定义了一个NodePort类型的Service,它将外部的HTTP请求转发到后端的Nginx Pod上。同时,它还定义了一个StatefulSet,用于管理6个Nginx Pod的生命周期和部署。每个Pod都将被分配一个唯一的名称,并且它们都将监听端口80。

启动

[root@master stateful]# kubectl apply -f pod-stateful.yaml 
service/nginx-stateful created
statefulset.apps/web created
[root@master stateful]# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
nginx-deployment-state-75b69bd684-cqh5b   1/1     Running   0          13m
nginx-deployment-state-75b69bd684-hw78n   1/1     Running   0          13m
nginx-deployment-state-75b69bd684-l2r5f   1/1     Running   0          13m
nginx-deployment-state-75b69bd684-ljbrs   1/1     Running   0          13m
nginx-deployment-state-75b69bd684-tk5zt   1/1     Running   0          13m
nginx-deployment-state-75b69bd684-v47cf   1/1     Running   0          13m
web-0                                     1/1     Running   0          6s
web-1                                     1/1     Running   0          4s
web-2                                     1/1     Running   0          3s
web-3                                     1/1     Running   0          2s
web-4                                     0/1     Pending   0          1s
[root@master stateful]# 

能看到pod的名字是有顺序的

image-20240317165010687

4、无头服务

Headless Service(无头服务) 发布pod的时候,不给pod分配ip地址

  • 无头服务的特点是服务发布的时候,负载均衡器没有ip地址
  • 只能通过域名去访问后端的发布的pod
  • 通过k8s内部的coredns进行域名解析–》也可以找到pod
  • 就是相当于中间的负载均衡器没有ip,就相当于跳过负载均衡器 直接访问pod

无头服务(Headless Service)是Kubernetes中的一种特殊服务类型,它不提供负载均衡和单一的访问入口,而是直接将流量路由到后端的Pods。这与普通的Service不同,普通Service会提供一个稳定的虚拟IP(ClusterIP),所有进入该IP的流量都会被均匀地分发到后端的Pods上。

4.1、无头服务的特点:

  1. 没有ClusterIP:无头服务不会分配ClusterIP。这意味着你不能通过Service的IP地址来访问后端的Pods,而是直接通过Pods的IP地址进行通信。

  2. 直接访问Pods:由于没有ClusterIP,客户端可以直接通过Pods的IP地址访问服务。这在某些需要直接与Pod通信的场景中非常有用,例如数据库集群的节点发现。

  3. DNS解析:在无头服务中,服务名可以通过DNS解析为后端Pods的IP地址列表。当执行DNS查询时,你会得到所有匹配标签选择器的Pods的IP地址。

  4. 轮询:虽然无头服务不提供内置的负载均衡,但是客户端可以实现自己的轮询逻辑,或者使用客户端库来实现负载均衡。

4.2、无头服务的用途:

  • 服务发现:在某些分布式系统中,例如数据库集群或消息队列,节点需要知道彼此的位置。无头服务可以通过DNS服务发现来帮助这些节点相互发现。

  • 客户端负载均衡:在需要客户端进行负载均衡的场景中,无头服务提供了一种方式,让客户端直接与后端Pods通信,而不是通过Service的ClusterIP。

  • 有状态应用:对于有状态的应用(如数据库),每个实例可能需要有独立的、稳定的网络标识。无头服务允许直接通过Pod的IP地址访问,这对于保持会话状态和持久化连接非常有用。

4.3、无头服务的YAML示例:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  clusterIP: None  # 设置为None来创建无头服务
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

在这个示例中,clusterIP: None是创建无头服务的关键。这样定义后,Kubernetes不会为这个Service分配ClusterIP,而是允许直接通过Pod的IP地址访问服务。

4.4、只能通过域名去访问

域名的组成: pod name + service name + namespace name +.svc.cluster.local
pod名字 服务的名字 命名空间的名字
web-2.nginx.default.svc.cluster.local

[root@master stateful]# kubectl exec -it web-0 -- bash
root@web-0:/# curl  web-0.nginx-stateful.default.svc.cluster.local

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>


<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>


<p><em>Thank you for using nginx.</em></p>

</body>
</html>
root@web-0:/# 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不冤不乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值