Kubernetes的Service类型详解

news2025/1/22 9:02:11

1. Service详解

1.1 Service介绍

在Kubernetes中,Service资源解决了Pod IP地址不固定的问题,提供了一种更稳定和可靠的服务访问方式。以下是Service的一些关键特性和工作原理:

  • Service的稳定性:由于Pod可能会因为故障、重启或扩容而获得新的IP地址,直接使用Pod的IP来访问服务是不可靠的。Service通过提供一个固定的虚拟IP(ClusterIP)作为访问入口,使得服务访问变得更加稳定。

  • Service的类型:Kubernetes支持不同类型的Service,包括ClusterIP、NodePort、LoadBalancer和ExternalName,每种类型适用于不同的访问场景:

    • ClusterIP:为Service在集群内部提供一个固定的虚拟IP,只有集群内部的客户端可以访问此服务。

    • NodePort:在所有节点的特定端口上公开Service,使得外部可以通过<NodeIP>:<NodePort>访问服务。

    • LoadBalancer:在NodePort的基础上,通过云服务商的负载均衡器对外提供服务,适用于公有云环境。

    • ExternalName:将服务映射到外部服务的DNS名称,不通过kube-proxy进行代理。

  • Service的负载均衡:Service可以对关联的Pod进行轮询或随机的负载均衡,使得请求可以均匀地分发到各个Pod上。

  • Service的发现机制:Kubernetes中的Pod可以通过DNS或环境变量来发现Service。通过DNS,Pod可以通过Service的名称和命名空间来解析Service的ClusterIP。

  • Service和Pod的关系:Service通过标签选择器(label selector)与一组Pod关联。当Service创建后,kube-proxy或相关的网络插件会监控Pod的变化,并更新Service的后端列表(Endpoints。

  • Headless Service:一种特殊的Service,不分配ClusterIP,而是通过DNS返回Pod的IP列表,适用于需要直接访问每个Pod的场景,如StatefulSets。

  • Service的端口:Service可以定义一个或多个端口,将外部请求映射到Pod的特定端口上。端口分为Service端口(port)、Pod端口(targetPort)和NodePort(仅NodePort类型Service)

image-20240514095437913

  • Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个Node节点上都运行着一个kube-proxy服务进程。当创建Service的时候会通过api-server向etcd写入创建的service的信息,而kube-proxy会基于监听的机制发现这种Service的变动,然后它会将最新的Service信息转换成对应的访问规则。

image-20240514095556728

1.2 kube-proxy三种工作模式

8.2.1 userspace模式

  • userspace模式下,kube-proxy会为每一个Service创建一个监听端口,发向Cluster IP的请求被iptables规则重定向到kube-proxy监听的端口上,kube-proxy根据LB算法选择一个提供服务的Pod并和其建立链接,以将请求转发到Pod上。

  • 该模式下,kube-proxy充当了一个四层负责均衡器的角色。由于kube-proxy运行在userspace中,在进行转发处理时会增加内核和用户空间之间的数据拷贝,虽然比较稳定,但是效率比较低。

  • kube-proxyuserspace模式下的工作原理如下:

    • Service的监听kube-proxy为每个Service创建一个监听端口,这个端口对应Service的ClusterIP和端口号。当客户端向Service的ClusterIP:Port发送请求时,请求会被iptables规则捕获并重定向到kube-proxy的监听端口上。

    • 负载均衡kube-proxy根据定义的负载均衡算法(如轮询、随机等)从提供该服务的所有Pod中选择一个Pod,然后与该Pod建立连接,并将请求转发到选定的Pod上。kube-proxy在此过程中充当了四层(TCP/UDP)负载均衡器的角色。

    • 用户空间的开销:由于kube-proxyuserspace模式下运行,数据包需要在内核空间和用户空间之间来回拷贝,这会导致额外的性能开销。虽然这种方法比较稳定,但是在高负载情况下,由于数据拷贝的开销,效率相对较低。

    • 其他模式:除了userspace模式,kube-proxy还支持iptables模式和ipvs模式,这两种模式效率更高,因为它们直接在内核空间工作,减少了数据拷贝的开销。iptables模式通过修改网络规则来实现负载均衡,而ipvs模式则是内核级别的负载均衡,通常提供更好的性能和更复杂的负载均衡特性。

image-20240514100818525

8.2.2 iptables模式

  • iptables模式下,kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向ClusterIP的请求重定向到一个Pod IP。

  • 该模式下kube-proxy不承担四层负责均衡器的角色,只负责创建iptables规则。该模式的优点是较userspace模式效率更高,但不能提供灵活的LB策略,当后端Pod不可用时也无法进行重试。

  • iptables模式下的kube-proxy工作原理如下:

    • 创建规则:在iptables模式下,kube-proxy为每个Service后端的Pod创建相应的iptables规则。当请求到达Service的ClusterIP时,这些规则将请求直接重定向到后端Pod的IP地址上。

    • 直接重定向:与userspace模式不同,在iptables模式下,kube-proxy不进行实际的流量转发,而是通过修改网络规则来实现负载均衡。这意味着流量直接从客户端通过网络路由到目的Pod,而不需要经过kube-proxy进程。

    • 效率提升:由于避免了用户空间和内核空间之间的上下文切换以及数据拷贝,iptables模式通常比userspace模式有更高的网络性能。

    • 简化的LB策略:在iptables模式下,kube-proxy不实现复杂的负载均衡策略,如会话保持或智能负载均衡。它仅根据轮询策略简单地分发请求到各个Pod。

    • 重试限制:由于iptables规则直接将流量路由到Pod,如果选定的Pod不可用,请求将失败,而kube-proxy不会进行重试。这与userspace模式不同,在userspace模式下,kube-proxy可以检测到连接失败并重新选择另一个Pod进行重试。

    • 安全性iptables模式下,流量直接从客户端路由到Pod,这意味着Pod的网络安全策略需要正确配置,以确保不会直接暴露给不受信任的网络。

  • iptables模式提供了一种高效的方式来实现Service的负载均衡,但牺牲了一定程度的灵活性和容错能力。选择合适的模式需要根据具体的应用需求和性能要求来决定。对于需要高性能和简单负载均衡策略的场景,iptables模式是一个不错的选择。而对于需要复杂负载均衡策略和容错能力的场景,userspace模式或ipvs模式可能更合适。

image-20240514101428737

8.2.3 ipvs模式

  • ipvs模式和iptables类似,kube-proxy监控Pod的变化并创建相应的ipvs规则。ipvs相对iptables转发效率更高。除此以外,ipvs支持更多的LB算法。

  • ipvs(IP Virtual Server)模式是kube-proxy的另一种工作模式,它在很多方面都优于iptables模式:

    • 内核级负载均衡:与iptables不同,ipvs是在内核空间实现的,这意味着它可以直接进行网络包的转发,而不需要在用户空间和内核空间之间来回拷贝数据。因此,ipvs可以提供更低的延迟和更高的数据包转发速率。

    • 高效的性能:由于ipvs在内核中实现,它通常能够提供比iptables更高的性能,尤其是在高负载和大规模集群中。

    • 丰富的负载均衡算法ipvs支持多种负载均衡算法,包括轮询(round-robin)、最小连接(least-connection)、源IP哈希(source IP hashing)等,这为实现复杂的负载均衡策略提供了可能。

    • Session persistenceipvs支持会话保持(Session persistence),这意味着来自同一客户端的请求可以始终被路由到同一个后端Pod,这对于需要维持会话状态的应用非常重要。

    • 健康检查ipvs可以根据Pod的健康状态来路由流量,只将请求转发到健康的Pod上,从而提高服务的可用性。

    • SNAT优化ipvs可以更有效地处理源地址转换(SNAT),这对于使用NodePortLoadBalancer服务类型时,从外部网络访问集群内部服务非常重要。

    • 直接路由ipvs使用直接路由(Direct Routing)模式,这意味着流量不需要经过额外的网络地址转换,从而减少了资源消耗。

    • 状态同步kube-proxyipvs模式下,会监控Pod和Service的变化,并将这些变化实时同步到ipvs规则中。

image-20240514101729240

  • 此模式必须安装ipvs内核模块,否则会降级为iptables

[root@K8s-master ~]# kubectl edit configmap kube-proxy -n kube-system    
    mode: "ipvs"  #修改此处,默认为空
    
[root@K8s-master ~]# kubectl get pod -n kube-system
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-74586cf9b6-96v5x             1/1     Running   0          3d2h
coredns-74586cf9b6-f5q7h             1/1     Running   0          3d2h
etcd-k8s-master                      1/1     Running   0          3d2h
kube-apiserver-k8s-master            1/1     Running   0          3d2h
kube-controller-manager-k8s-master   1/1     Running   0          3d2h
kube-flannel-ds-6gqmv                1/1     Running   0          3d
kube-flannel-ds-g7zcj                1/1     Running   0          3d
kube-flannel-ds-hh52b                1/1     Running   0          3d
kube-proxy-glhml                     1/1     Running   0          3d1h
kube-proxy-klcs2                     1/1     Running   0          3d1h
kube-proxy-x9v8k                     1/1     Running   0          3d2h
kube-scheduler-k8s-master            1/1     Running   0          3d2h
[root@K8s-master ~]# kubectl delete pod kube-proxy-glhml kube-proxy-klcs2 kube-proxy-x9v8k -n kube-system
pod "kube-proxy-glhml" deleted
pod "kube-proxy-klcs2" deleted
pod "kube-proxy-x9v8k" deleted

1.3 Service类型

  • Service的资源清单文件:

---
kind: Service # 资源类型
apiVersion: v1 # 资源版本
metadata: # 元数据
  name: service # 资源名称
  namespace: dev # 命名空间
spec: # 描述
  selector: # 标签选择器,用于确定当前service代理哪些pod
    app: nginx
  type: ClusterIP # Service类型,指定service的访问方式
  clusterIP: None # 虚拟服务的ip地址,设置为None表示创建Headless Service
  sessionAffinity: ClientIP # session亲和性,支持ClientIP、None两个选项
  ports: # 端口信息
    - protocol: TCP
      port: 3017 # service端口
      targetPort: 5003 # pod端口
  • ClusterIP

    • 默认类型。Kubernetes 为 Service 分配一个虚拟的 IP 地址(ClusterIP),这个 IP 只能在集群内部访问。

    • 适用于在集群内部提供服务发现和负载均衡,而不对外公开服务。

  • NodePort

    • 在集群的所有节点上打开一个静态端口(NodePort),外部可以通过任何节点的 IP 地址加这个端口来访问 Service。

    • 适用于需要从集群外部访问服务的场景,但不像 LoadBalancer 那样需要云服务提供商的支持。

  • LoadBalancer

    • 与 NodePort 类似,但会利用云服务提供商的负载均衡器来分发流量。

    • 适用于需要高可用性和可扩展性的场景,并且外部访问流量较大时推荐使用。

    • 注意:需要云服务商支持,并且可能涉及额外的费用。

  • ExternalName

    • 不分配 ClusterIP,而是将服务映射到一个外部的 DNS 名称。

    • 适用于将集群外部的服务(如数据库服务)映射到 Kubernetes 集群内部,使得集群内的服务可以像调用集群内的服务一样调用这些外部服务。

1.4 Service使用

1.4.1 环境准备

  • 创建三个Pod

[root@K8s-master ~]# vim deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: pc-deployment
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - containerPort: 80
​
[root@K8s-master ~]# kubectl apply -f deployment.yaml 
deployment.apps/pc-deployment created
​
[root@K8s-master ~]# kubectl get pod -n test -o wide
NAME                             READY   STATUS    RESTARTS   AGE    IP           NODE          NOMINATED NODE   READINESS GATES
pc-deployment-6769786c4c-62d94   1/1     Running   0          3m1s   10.244.2.2   k8s-node-02   <none>           <none>
pc-deployment-6769786c4c-fv6jj   1/1     Running   0          3m1s   10.244.2.3   k8s-node-02   <none>           <none>
pc-deployment-6769786c4c-qn9ls   1/1     Running   0          3m1s   10.244.1.4   k8s-node-01   <none>           <none>
​
[root@K8s-master ~]# kubectl get pod -n test --show-labels
NAME                             READY   STATUS    RESTARTS   AGE     LABELS
pc-deployment-6769786c4c-62d94   1/1     Running   0          3m20s   app=nginx-pod,pod-template-hash=6769786c4c
pc-deployment-6769786c4c-fv6jj   1/1     Running   0          3m20s   app=nginx-pod,pod-template-hash=6769786c4c
pc-deployment-6769786c4c-qn9ls   1/1     Running   0          3m20s   app=nginx-pod,pod-template-hash=6769786c4c
​
​
# 为了方便后面的测试,修改下三台nginx的index.html页面(三台修改的IP地址不一致)
[root@K8s-master ~]# kubectl exec -it pc-deployment-6769786c4c-62d94 -n test /bin/sh
# echo "`hostname -I` web-01" > /usr/share/nginx/html/index.html
# exit
​
[root@K8s-master ~]# kubectl exec -it pc-deployment-6769786c4c-fv6jj -n test /bin/sh
# echo "`hostname -I` web-02" > /usr/share/nginx/html/index.html           
# exit
​
[root@K8s-master ~]# kubectl exec -it pc-deployment-6769786c4c-qn9ls -n test /bin/sh
# echo "`hostname -I` web-03" > /usr/share/nginx/html/index.html
# exit
​
[root@K8s-master ~]# curl 10.244.2.2
10.244.2.2  web-01
[root@K8s-master ~]# curl 10.244.2.3
10.244.2.3  web-02
[root@K8s-master ~]# curl 10.244.1.4
10.244.1.4  web-03

1.4.2 ClusterIP类型的Service

  • ClusterIP 类型的 Service 是 Kubernetes 中最基本的服务之一,它提供了一种稳定的、只限于集群内部访问的方式。以下是 ClusterIP 类型 Service 的一些关键特点:

    • 虚拟 IP 地址:ClusterIP 类型的 Service 会被分配一个虚拟的 IP 地址(Cluster IP),这个 IP 地址在 Service 的整个生命周期中保持不变。

    • 集群内部通信:Pods 可以通过这个固定的 Cluster IP 来访问 Service,从而实现集群内部的服务发现和负载均衡,而无需关心后端 Pods 的具体 IP 地址。

    • 不对外公开:ClusterIP 类型的 Service 不会被分配外部可访问的 IP 地址,因此它只能从集群内部访问,不能从集群外部直接访问。

    • 负载均衡:Kubernetes 会自动为 ClusterIP 类型的 Service 提供简单的负载均衡,将请求分发到后端的多个 Pods 上。

    • 会话亲和性:可以通过设置 sessionAffinity 属性来控制会话亲和性,确保来自同一客户端的请求始终被路由到同一个后端 Pod。

    • DNS 解析:在集群内部,可以通过 Service 名称进行 DNS 解析,解析结果为分配给该 Service 的 Cluster IP。

    • 适用于内部服务:ClusterIP 类型的 Service 非常适合用于需要在集群内部通信的内部服务,如数据库、缓存服务等。

[root@K8s-master ~]# vim service-clusterip.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
  namespace: test
spec:
  selector:
    app: nginx-pod
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
​
[root@K8s-master ~]# kubectl apply -f service-clusterip.yaml 
service/svc-clusterip created
​
[root@K8s-master ~]# kubectl get svc,pod -n test
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/svc-clusterip   ClusterIP   10.110.170.62   <none>        80/TCP    78s
​
NAME                                 READY   STATUS    RESTARTS   AGE
pod/pc-deployment-6769786c4c-62d94   1/1     Running   0          5m48s
pod/pc-deployment-6769786c4c-fv6jj   1/1     Running   0          5m48s
pod/pc-deployment-6769786c4c-qn9ls   1/1     Running   0          5m48s
​
[root@K8s-master ~]# kubectl describe svc svc-clusterip -n test
Name:              svc-clusterip
Namespace:         test
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.110.170.62
IPs:               10.110.170.62
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.4:80,10.244.2.2:80,10.244.2.3:80
Session Affinity:  None
Events:            <none>
​
#访问ClusterIP
[root@K8s-master ~]# for ((i=1;i<=6;i++)) do  curl 10.110.170.62; done  #集群内部访问(只能再集群内部fan
10.244.2.3  web-02
10.244.2.2  web-01
10.244.1.4  web-03
10.244.2.3  web-02
10.244.2.2  web-01
10.244.1.4  web-03
​
[root@K8s-master ~]# ipvsadm -Ln | grep -A3  10.110.170.99:80  #默认负载均衡算法为轮询
TCP  10.110.170.62:80 rr
  -> 10.244.2.3:80                Masq    1      0          0         
  -> 10.244.2.2:80                Masq    1      0          0         
  -> 10.244.1.4:80                Masq    1      0          0   

1.4.3 Endpoint类型的Service

  • Endpoint是kubernetes中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址,它是根据service配置文件中selector描述产生的。

  • 一个Service由一组Pod组成,这些Pod通过Endpoints暴露出来,Endpoints是实现实际服务的端点集合。换句话说,service和pod之间的联系是通过endpoints实现的。

  • Endpoint 类型 Service 的一些特点:

    • 直接使用 Endpoints:Endpoint 类型的服务不提供标准的负载均衡器或代理,它允许客户端直接与 Endpoints 对象中的 Pod 进行通信。

    • 无需代理:与标准的 Service 类型不同,Endpoint 类型的服务不会创建 kube-proxy 监听的端点。这意味着,使用这种服务类型的客户端需要能够直接解析和连接到 Endpoints 对象中定义的 Pod IP 地址。

    • 适用于特定场景:这种服务类型适用于那些需要绕过 Kubernetes 服务发现机制的特定场景,例如,当您需要直接与 Pod 通信以进行调试或使用自定义的负载均衡器时。

    • 手动管理:使用 Endpoint 类型的服务时,您需要手动管理 Endpoints 对象,包括添加和删除端点。

    • 不提供服务发现:由于它不通过标准的 Kubernetes 服务发现机制,所以它不提供自动的服务发现功能。

    • 安全性:直接与 Pod 通信可能会带来安全风险,因为 Pod 的 IP 地址可能会变化,而且没有内置的负载均衡或健康检查机制。

    • 使用场景限制:Endpoint 类型的服务通常只在特定的用例中使用,比如当您需要直接控制网络流量或使用自定义的网络策略时。

image-20240514213245379

[root@K8s-master ~]# kubectl get endpoints -n test -o wide
NAME            ENDPOINTS                                   AGE
svc-clusterip   10.244.1.4:80,10.244.2.2:80,10.244.2.3:80   93s

在 Kubernetes 中,负载分发策略用于确定如何将传入的网络请求分配到后端的 Pod 上。以下是您提到的两种策略的详细说明:

  • 默认的 kube-proxy 策略

    • 随机(Random):kube-proxy 随机选择一个后端 Pod 来处理传入的请求。这种策略适用于大多数情况,因为它可以提供良好的负载均衡,并且实现起来相对简单。

    • 轮询(Round Robin):kube-proxy 按顺序将请求分发给后端的每个 Pod。当所有 Pod 都具有相同的处理能力时,这种策略可以确保每个 Pod 接收到相同数量的请求。

    除了随机和轮询,Kubernetes 还提供了其他几种负载分发策略,包括:

    • 最小连接数(Least Connections):选择当前活跃连接数最少的 Pod。

    • 源 IP(Source IP):确保来自同一个客户端 IP 的所有请求都发送到同一个 Pod,以保持会话的一致性。

  • 会话保持

    • Kubernetes 的服务可以配置会话保持,也称为会话亲和性或粘性会话。当启用会话保持时,来自同一个客户端的所有请求都将被路由到同一个后端 Pod,直到该会话结束。

    • 这种策略对于需要保持用户会话状态的应用非常有用,例如购物车应用或需要用户登录信息的应用。

    • 会话保持可以通过两种方式实现:

      • 客户端 IP:基于客户端的 IP 地址进行会话保持,确保来自同一 IP 的请求总是路由到同一个 Pod。

      • Cookie 基于会话:kube-proxy 可以生成一个特殊的哈希值,存储在客户端的 Cookie 中,以确保来自同一个 Cookie 的请求被路由到同一个 Pod。

      • 此模式可以使在spec中添加 sessionAffinity: ClientIP选项,表示Service将使用客户端IP地址来进行会话亲和性(session affinity)。当一个客户端请求连接到Service时,Service将根据客户端的IP地址将请求转发到一个稳定的Pod上。这意味着来自同一个客户端的所有请求在默认情况下都会被转发到同一个Pod上,直到该Pod不再可用。

[root@K8s-master ~]# kubectl delete -f service-clusterip.yaml 
service "svc-clusterip" deleted
[root@K8s-master ~]# vim service-clusterip.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
  namespace: test
spec:
  selector:
    app: nginx-pod
  clusterIP: 10.110.170.99    #可以指定IP
  type: ClusterIP
  sessionAffinity: ClientIP   #表示Service将使用客户端IP地址来进行会话亲和性
  ports:
    - port: 80
      targetPort: 80
​
[root@K8s-master ~]# kubectl apply -f service-clusterip.yaml 
service/svc-clusterip created
​
[root@K8s-master ~]# kubectl describe service/svc-clusterip -n test
Name:              svc-clusterip
Namespace:         test
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.110.170.99
IPs:               10.110.170.99
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.4:80,10.244.2.2:80,10.244.2.3:80
Session Affinity:  ClientIP
Events:            <none>
​
[root@K8s-master ~]# ipvsadm -Ln | grep -A3  10.110.170.99:80
TCP  10.110.170.99:80 rr persistent 10800   #会话保持,在10800秒内始终由最稳定的一台提供访问
  -> 10.244.1.4:80                Masq    1      0          0         
  -> 10.244.2.2:80                Masq    1      0          0         
  -> 10.244.2.3:80                Masq    1      0          0     
  
[root@K8s-master ~]# for ((i=1;i<=6;i++)) do  curl 10.110.170.99; done
10.244.2.3  web-02
10.244.2.3  web-02
10.244.2.3  web-02
10.244.2.3  web-02
10.244.2.3  web-02
10.244.2.3  web-02

1.4.4 HeadLiness类型的Service

  • 在某些场景中,开发人员可能不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这种情况,kubernetes提供了HeadLiness Service,这类Service不会分配Cluster IP,如果想要访问service,只能通过service的域名进行查询。

  • 在 Kubernetes 中,存在一种不分配 Cluster IP 的 Service 类型,称为 "Headless Service"。

  • Headless Service 的特点如下:

    • 不分配 Cluster IP:与标准的 ClusterIP 类型 Service 不同,Headless Service 不会为服务分配一个虚拟 IP 地址。

    • 通过域名访问:Pods 可以通过 Service 的 DNS 名称直接访问到后端的 Pods。由于没有 Cluster IP,客户端不能直接通过一个固定的 IP 地址来访问服务,而是通过 DNS 解析来获取后端 Pods 的实际 IP 地址。

    • 自定义负载均衡:开发者可以自由地实现自己的负载均衡策略,而不是依赖 Kubernetes 提供的内置负载均衡。

    • DNS 解析:Kubernetes 会为每个后端 Pod 创建一个 DNS 记录。这意味着通过 DNS 查询,客户端可以获取到后端所有 Pod 的 IP 地址。

    • 适用于无头服务:Headless Service 特别适合于那些需要直接与 Pod 通信的场景,例如,当使用 StatefulSets 部署具有唯一身份的 Pods 时。

[root@K8s-master ~]# vim service-headliness.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: svc-clusterip
  namespace: test
spec:
  selector:
    app: nginx-pod
  clusterIP: None   #这里IP设为None
  type: ClusterIP
  sessionAffinity: ClientIP
  ports:
    - port: 80
      targetPort: 80
​
[root@K8s-master ~]# kubectl apply -f service-headliness.yaml 
service/svc-clusterip created
[root@K8s-master ~]# kubectl describe service/svc-clusterip -n test  #这里集群IP为None
Name:              svc-clusterip
Namespace:         test
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                None
IPs:               None
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.4:80,10.244.2.2:80,10.244.2.3:80
Session Affinity:  ClientIP
Events:            <none>
​
# 查看域名解析
[root@K8s-master ~]# kubectl exec -it pc-deployment-6769786c4c-62d94 -n test /bin/bash
root@pc-deployment-6769786c4c-62d94:/# cat /etc/resolv.conf 
search test.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5
​
[root@K8s-master ~]# nslookup svc-clusterip.test.svc.cluster.local 10.96.0.10
Server:         10.96.0.10
Address:        10.96.0.10#53
​
Name:   svc-clusterip.test.svc.cluster.local
Address: 10.244.2.2
Name:   svc-clusterip.test.svc.cluster.local
Address: 10.244.2.3
Name:   svc-clusterip.test.svc.cluster.local
Address: 10.244.1.4
​
[root@K8s-master ~]# sed -i 's/^nameserver/#nameserver/' /etc/resolv.conf
[root@K8s-master ~]# echo 'nameserver 10.96.0.10' >> /etc/resolv.conf   #指定DNS
​
[root@K8s-master ~]# for ((i=1;i<=6;i++)) do  curl svc-clusterip.test.svc.cluster.local; done
10.244.1.4  web-03
10.244.2.3  web-02
10.244.2.3  web-02
10.244.2.3  web-02
10.244.2.3  web-02
10.244.2.2  web-01

1.4.5 NodePort类型的Service

  • 之前的样例中,创建的Service的ip地址只有集群内部才可以访问,如果希望将Service暴露给集群外部使用,那么就要使用到另外一种类型的Service,称为NodePort类型。NodePort的工作原理其实就是将service的端口映射到Node的一个端口上,然后就可以通过 NodeIp: NodePort 来访问Service了。

  • NodePort 类型的 Service 是 Kubernetes 中用于将服务暴露给集群外部的一种方式。下面是 NodePort 类型 Service 的一些关键点:

    • 端口映射:NodePort 类型的 Service 会在集群的所有节点上打开一个静态端口(NodePort),这个端口范围通常是 30000-32767。这个端口将被映射到 Service 所代理的后端 Pods 的端口上。

    • 通过节点 IP 访问:外部用户可以通过 <NodeIP>:<NodePort> 的形式访问到这个 Service。这里的 NodeIP 是集群中任何节点的 IP 地址,而 NodePort 是 Service 映射的端口号。

    • 无需额外配置:与 LoadBalancer 类型相比,NodePort 不需要云服务商提供的额外配置或支持,因此它在不支持 LoadBalancer 的环境中非常有用。

    • 安全性考虑:由于 NodePort 会在所有节点上开放端口,因此需要考虑到安全性问题。通常建议使用防火墙规则来限制访问,只允许特定的 IP 地址访问这些端口。

    • 适用于简单的外部访问:NodePort 适合于简单的外部访问需求,但对于生产环境,通常推荐使用 LoadBalancer 或 Ingress,因为它们提供了更好的性能、安全性和高级路由功能。

image-20240516112136442

[root@K8s-master ~]# vim service-nodeport.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nodeport
  namespace: test
spec:
  selector:
    app: nginx-pod
  type: NodePort
  ports:
    - port: 80     # Service 在所有节点上监听的端口号
      nodePort: 32522  # 默认的取值范围是:30000-32767, 如果不指定,会默认分配
      targetPort: 80  # 后端 Pod 监听的端口号
​
[root@K8s-master ~]# kubectl apply -f service-nodeport.yaml 
service/svc-nodeport created
​
[root@K8s-master ~]# kubectl get svc,pod -n test -o wide
NAME                   TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/svc-nodeport   NodePort   10.102.4.48   <none>        80:32522/TCP   5s    app=nginx-pod
​
NAME                                 READY   STATUS    RESTARTS   AGE   IP           NODE          NOMINATED NODE   READINESS GATES
pod/pc-deployment-6769786c4c-62d94   1/1     Running   0          74m   10.244.2.2   k8s-node-02   <none>           <none>
pod/pc-deployment-6769786c4c-fv6jj   1/1     Running   0          74m   10.244.2.3   k8s-node-02   <none>           <none>
pod/pc-deployment-6769786c4c-qn9ls   1/1     Running   0          74m   10.244.1.4   k8s-node-01   <none>           <none>
  • 外部访问测试

image-20240516113258620

[root@K8s-master ~]# ipvsadm -Ln | grep -A3 32522
TCP  192.168.110.21:32522 rr
  -> 10.244.1.4:80                Masq    1      0          0         
  -> 10.244.2.2:80                Masq    1      0          1         
  -> 10.244.2.3:80                Masq    1      0          1         
--
TCP  10.244.0.0:32522 rr
  -> 10.244.1.4:80                Masq    1      0          0         
  -> 10.244.2.2:80                Masq    1      0          0         
  -> 10.244.2.3:80                Masq    1      0          0       

1.4.6 LoadBalancer类型的Service

  • LoadBalancer和NodePort很相似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备,而这个设备需要外部环境支持的,外部服务发送到这个设备上的请求,会被设备负载之后转发到集群中。

  • LoadBalancer 类型的 Service 是 Kubernetes 中用于将服务暴露给外部世界的一种方式,它通常需要云服务商的支持。以下是 LoadBalancer 类型 Service 的一些关键特点:

    • 外部负载均衡器:LoadBalancer 类型的 Service 会利用云服务商提供的外部负载均衡器(如 AWS ELB、Azure Load Balancer 或 GCP Load Balancer)来暴露服务。

    • 自动配置:Kubernetes 会自动配置负载均衡器,将外部请求路由到后端的 Pods。

    • 外部 IP 地址:LoadBalancer 会提供一个或多个外部可访问的 IP 地址,这些 IP 地址可以是公网 IP 或云服务商的内部 IP。

    • 自动扩展:许多云服务商的负载均衡器支持自动扩展,这意味着它们可以根据流量自动调整后端 Pods 的数量。

    • 安全性和性能:LoadBalancer 提供了额外的安全和性能优势,因为它们通常包括内置的防火墙规则、SSL 终止和 DDoS 防护。

    • 适用于生产环境:由于其高级特性和性能,LoadBalancer 类型的 Service 非常适合生产环境。

    • 可能涉及费用:使用云服务商的负载均衡器可能会产生额外的费用。

image-20240516114217789

1.4.6.1 开源 Kubernetes 负载均衡器
1. MetalLB
  • 介绍:MetalLB 是一个为 Kubernetes 集群设计的负载均衡器,特别适用于裸金属环境。它通过在集群中运行的组件来监控服务对象的变化,为 LoadBalancer 类型的服务提供实现。10^

  • 工作原理:MetalLB 通过标准的路由协议(如 ARP、NDP 或 BGP)来实现负载均衡。它有两种工作模式:Layer2 模式和 BGP 模式。在 Layer2 模式下,MetalLB 会在集群中的一个节点上处理所有服务 IP 的流量,而在 BGP 模式下,它通过与网络路由器建立 BGP 会话来实现真正的负载均衡。2^11^

  • 特点:MetalLB 易于部署,支持自动和静态 IP 地址分配,并且可以与 kube-proxy 紧密集成。

2. PureLB
  • 介绍:PureLB 是另一种负载均衡器,它使用自定义资源(CRD)进行配置,由两部分组成:分配器负责分配 IP 地址,而 lbnodeagent 负责在所有节点上配置节点网络。

  • 工作原理:PureLB 的 Layer2 工作模式特点在于它会在 Kubernetes 集群的受管节点上创建一个虚拟网卡(如 kube-lb0),并通过任意路由协议实现 ECMP(等价多路径),以进行负载均衡和流量分发。

  • 特点:PureLB 可以根据单个 VIP 选择节点,并将多个 VIP 分散到不同节点,以此来避免节点负载失衡。

3. OpenELB
  • 介绍:OpenELB 是由 KubeSphere 社区发起的云原生负载均衡器,现已成为 CNCF 沙箱项目。它适用于物理机和虚拟化环境,利用 BGP 和 ECMP 实现高性能和高可用性。

  • 工作原理:OpenELB 支持两种工作模式:Layer2 模式和 BGP 模式。在 BGP 模式下,它通过与集群的边界路由器建立 BGP 连接来实现高效的流量调度和管理。OpenELB 还支持 ECMP,允许在多条路径之间进行负载均衡和流量分发。6^

  • 特点:OpenELB 易于与 Kubernetes 集成,提供了丰富的监控和日志功能,支持动态服务发现、流量调度和安全防护等高级特性。

特性/项目MetalLBPureLBOpenELB
介绍适用于裸金属环境的负载均衡器使用 CRD 配置的负载均衡器云原生负载均衡器,CNCF 沙箱项目
支持环境裸金属、云环境裸金属、云环境物理机、虚拟化环境
工作原理ARP/NDP/BGP任意路由协议BGP/ECMP
Layer2 模式支持支持支持
BGP 模式支持不适用支持
IP 地址分配自动和静态不明确动态服务发现
节点负载均衡不适用支持支持
与 kube-proxy 集成紧密集成不明确支持
监控和日志基本不明确丰富
安全性基本不明确支持
高级特性基本不明确高级特性支持
社区活跃度
1.4.6.2 LoadBalancer 类型的 Service 的定义示例可能如下:
apiVersion: v1
kind: Service
metadata:
  name: my-loadbalancer-service
spec:
  type: LoadBalancer
  ports:
    - port: 80  # Service 的端口
      targetPort: 8080  # 后端 Pod 的端口
  selector:
    app: my-app  # 选择具有该标签的 Pods

1.4.7 ExternalName类型的Service

  • ExternalName类型的Service用于引入集群外部的服务,它通过 externalName 属性指定外部一个服务的地址,然后在集群内部访问此service就可以访问到外部的服务了。

  • ExternalName 类型的 Service 在 Kubernetes 中用于将一个 DNS 名称映射到一个外部的服务,而不需要在集群内创建任何代理或负载均衡器。这种方式非常适合于将集群内部的应用程序指向外部的数据库、API 服务或其他不在 Kubernetes 管理下的资源。

  • ExternalName 类型 Service 的一些关键特点:

    • 无 Cluster IP:ExternalName 类型的 Service 不分配 Cluster IP。

    • DNS 解析:在 Kubernetes 集群内部,当对这种类型的 Service 进行 DNS 解析时,将直接返回 externalName 字段指定的值。

    • 简单配置:只需要指定一个 externalName 和一个可选的 port

    • 直接访问:Pods 可以直接通过 Service 名称访问外部服务,就像访问集群内的其他服务一样。

    • 适用于外部资源:适合于引用那些不在 Kubernetes 控制范围内的外部服务。

    • 无需特殊网络配置:不需要任何特殊的网络配置或云服务提供商支持。

image-20240516114724022

  • 配置实例

apiVersion: v1
kind: Service
metadata:
  name: my-external-service
spec:
  type: ExternalName
  externalName: api.example.com  # 外部服务的地址
  ports:
    - port: 443  # 外部服务监听的端口

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

gpt4o在哪用?

GPT-4o功能&#xff1f; 1.感知用户情绪&#xff1a;前沿研究部门主管陈信翰&#xff08;Mark Chen&#xff09;让ChatGPT-4o聆听他的呼吸&#xff0c;聊天机器人侦测到他急促的呼吸&#xff0c;并幽默地建议他不要像吸尘器那样呼吸&#xff0c;要放慢速度。随后Mark深呼吸一次…

vue嵌套路由

一、嵌套 children配置 1.父类路由 mymusic 2.子类路由 musicson 1.创建MusicSon组件 <template><div><p>从前和后来</p><p>唯一</p><p>运气来的似有若无</p></div> </template><script>export defaul…

element-ui dialog form 弹框表单组件封装

在使用 element-ui 进行后端管理系统开发时&#xff0c;在封装弹框表单时&#xff0c;遇到两个问题&#xff0c;这里进行简单记录&#xff1a; 1、问题一&#xff1a;点击关闭按钮及遮罩层关闭弹框时&#xff0c;页面报错&#xff0c;如下&#xff1a; 子组件封装&#xff1a;…

数据分析案例-印度美食数据可视化分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

C# 结合 JavaScript 对 Web 控件进行数据输入验证

目录 关于数据验证 范例运行环境 验证设计 JavaScript 方法 设计 实现 调用示例 C# 方法 设计 实现 调用示例 小结 关于数据验证 在 Web 应用的录入界面&#xff0c;数据验证是一项重要的实现功能&#xff0c;数据验证是指确认 Web 控件输入或选择的数据&#xff…

数据库设计大题详解

大题一&#xff1a;画E-R图&#xff08;概念结构设计&#xff09; 实体就是具体的物品&#xff0c;关系就是实体之间的关系&#xff0c;属性就是特征&#xff0c;内涵的意思 简单的小栗子&#xff1a; 1对1&#xff0c;1对n&#xff0c;n对m&#xff0c;自己考虑两者存在这个关…

还拿B端设计经验,设计政务类系统,驴唇不对马嘴啦。

一、什么是政务类系统&#xff0c;涉及哪些领域 政务类系统是指用于政府机构或政府部门进行管理和运营的信息化系统。政务类系统的目的是提高政府工作效率、优化公共服务、加强政府与公民之间的互动和沟通。 政务类系统通常涵盖了各个方面的政府工作&#xff0c;包括但不限于以…

Find My资讯|苹果 iOS 17.5 率先执行跨平台反跟踪器标准

苹果和谷歌公司于 2023 年 5 月宣布推出“检测预期外位置追踪器”&#xff08;Detecting Unwanted Location Trackers&#xff09;行业标准&#xff0c;经过 1 年多的打磨之后&#xff0c;该标准目前已通过 iOS 17.5 部署到 iPhone 上。谷歌也将为运行 Android 6.0 或更高版本的…

苹果cms:生成网站地图报错站点Connection refused

我们搭建苹果cms站点之后&#xff0c;会使用SEO工具包生成网站地图&#xff0c;在这个过程中我们会遇到一个问题 Connection refused 注意&#xff1a;这个问题并不是数据库无法连接&#xff0c;而是redis关闭了&#xff0c;原因是由于站点开启了redis缓存机制&#xff0c;SEO请…

规范数据处理 保障数据安全 || 「CCRC-DSA数据安全评估师」

数据安全&#xff0c;不容小觑&#xff01;DSA学习助你成为数据安全评估师&#xff01; 想要深入了解数据安全领域吗&#xff1f; DSA学习将带你走进数据安全的世界&#xff0c;以《数据安全法》、《数据出境安全评估办法》等法律法规为准绳&#xff0c;让你了解不同行业数据…

【ros】rosdep update报错

参考文章https://blog.csdn.net/m0_70557820/article/details/129343561 报错信息如下 ERROR: unable to process source [https://raw.githubusercontent.com/ros/rosdistro/master/rosdep/osx-homebrew.yaml]: <urlopen error timed out> (https://raw.githubuse…

“安”网守护,“乐享”服务——革新教育行业运维与安全体验,锐捷发布两大创新方案

5月11日,锐捷网络举办以“’安‘网联动, ’乐享‘运维”为主题的线上发布会,正式发布了锐捷乐享教育订阅服务方案,以及以新一代智能安全网关为核心的安全防护解决方案。 锐捷网络教育系统部总经理马雪峰为发布会致开场辞,他指出,在数字化浪潮席卷全球的今天,教育行业正进来前所…

小白也会SQL:大模型改变交互方式(上)

在人工智能与自然语言处理交汇点&#xff0c;有一种技术正悄然改变与数据交互的方式——将日常语言转化为精准SQL查询。这一“text-to-sql”转换任务&#xff0c;使非专业人士也能轻松驾驭复杂的数据库操作&#xff0c;极大地拓宽了数据应用的边界。 然而&#xff0c;现有前沿…

Hello, GPT-4o!

2024年5月13日&#xff0c;OpenAI 在官网正式发布了最新的旗舰模型 GPT-4o 它是一个 多模态模型&#xff0c;可以实时推理音频、视频和文本。 * 发布会完整版视频回顾&#xff1a;https://www.youtube.com/watch?vDQacCB9tDaw GPT-4o&#xff08;“o”代表“omni”&#xff0c…

【JavaSE】反射机制-基础概述

Catalog JavaSE-反射机制-基础概述1. 应用场景2. 优点3. 缺点4. Class类解析5. 获取Class类实例的方式6. 反射机制是什么7. 反射机制原理图&#xff08;老韩&#xff09;8. 具体应用 JavaSE-反射机制-基础概述 1. 应用场景 常见的如下&#xff1a; 当获取到一个未知类型但是知…

错误、调试和测试

在程序运行过程中&#xff0c;总会遇到各种各样的错误。 有的错误是程序编写有问题造成的&#xff0c;比如本来应该输出整数结果输出了字符串&#xff0c;这种错误我们通常称之为bug&#xff0c;bug是必须修复的。 有的错误是用户输入造成的&#xff0c;比如让用户输入email地…

万亿国债即将发行,普通人能分一杯羹吗?信任为何提前亮起红灯?

财政部最新公告揭示&#xff1a;《2024年国债发行计划》正式出炉&#xff0c;涵盖一系列长期至超长期限的国债&#xff0c;涵盖20年、30年及50年期限。这一消息瞬间点燃了市场的讨论热情&#xff0c;激发了民众对于国家债务投资的兴趣与疑虑。 一、超长国债&#xff0c;你准备好…

春秋云镜 CVE-2023-52064

靶标介绍&#xff1a; Wuzhicms v4.1.0 被发现存在一个 SQL 注入漏洞&#xff0c;该漏洞通过位于/core/admin/copyfrom.php 的 $keywords 参数触发。 开启靶场&#xff1a; 打开靶场链接&#xff0c;如上图所示 开始实验&#xff1a; 1、通过安装Wuzhicms的知后台登录链接&a…

【OceanBase诊断调优】—— 备份恢复如何定位 NFS 服务异常

当备份、归档出现异常时&#xff0c;我们应该首先排除备份介质、网络是否正常&#xff0c;本文讲述如何通过系统表和日志来定位 NFS 服务异常。 适用版本 OceanBase 数据库所有版本。 如何查看备份归档异常&#xff1f; 查看备份归档状态表&#xff0c;MAX_NEXT_TIME 应与当…

树莓派5安装使用

文章目录 树莓派&#xff08;Raspberry Pi&#xff09;一、树莓派1、介绍2、构造3、信息 二、系统搭建1、硬件准备2、烧录系统2.1、下载[烧录软件](https://www.raspberrypi.com/software/) Raspberry Pi Imager2.2、下载[镜像](https://www.raspberrypi.com/software/operatin…