K8s service 进阶

K8s service 进阶

码农世界 2024-05-31 前端 73 次浏览 0个评论

文章目录

  • K8s service 进阶
    • Service 工作逻辑
    • Service 具体实现
    • Service 资源类型
      • ClusterIP
      • NodePort
      • LoadBalancer
      • ExternalName
      • Service 与 Endpoint
        • Endpoint 与 容器探针
        • 自定义Endpoint
        • Service 相关字段
          • sessionAffinity
          • externalTrafficPolicy
          • internalTrafficPolicy
          • publishNotReadyAddresses

            K8s service 进阶

            Service 工作逻辑

            Service 通过持续监控APIServer,监视Service标签选择器所匹配的后端Pod,并实时跟踪这些Pod对象的变动情况。

            Service 与Pod 之间还有一个中间件 Endpoints, Endpoint 来管理pod 的 address 和 port

            整个默认访问链路为: Service -> Endpoint --iptables–> pod

            Service 具体实现

            在Kubernetes中,service只是抽象的一个概念,真正起作用实现负载均衡规则的其实是Kube-Proxy这个进程。它在每个节点上都需要运行一个kube-Proxy,用来完成负载均衡规则的创建。

            1. 创建Service资源后,会分配一个随机的ServiceIP,返回给用户,然后写入etcd;

            2. endpoints controller负责生成和维护所有endpoints,它会监听Service和pod的状态,当 pod 处于running 且准备就绪

            时,endpoints controller会将 pod ip更新到对应Service的 endpoints 对象中,然后写入Etcd;

            3. kube-proxy通过API-Server监听Service、Endpoints的资源变动,一旦Service或Endpoints资源发生变化,Kube-Proxy会将最新的信息转换为对应的Iptables、IPVS访问规则,而后在本地主机上执行。

            4. 当客户端想要访问Service的时候,其实访问的就是本地节点上的iptables、IPVS规则,由它们路由到对应节点;

            Service 资源类型

            ClusterIP

            • 定义:ClusterIP是Kubernetes中的默认Service类型,它在集群内部提供一个虚拟IP,作为一组Pod的访问入口。
            • 特点:
              • 仅为集群内部提供访问。
              • 通过标签选择器(Label Selector)与一组Pod关联。
              • 提供负载均衡功能,支持轮询或随机策略。
              • 支持会话亲和性(Session Affinity),如ClientIP,以确保来自同一客户端的请求被转发到同一Pod。
              • 用途:适用于集群内部服务间的通信,确保服务的稳定性和可访问性。
                apiVersion: v1
                kind: Service
                metadata: 
                  name: demo-svc-clusterip
                spec:
                  type: ClusterIP  # 默认类型
                  clusterIP:  10.96.1.1  # 设置ip
                  selector:
                    app: web
                  ports:
                  - name: http
                    port: 80
                    targetPort: 80
                  
                 
                

                NodePort

                • 定义:NodePort类型在所有节点上打开一个特定的端口,外部流量可以通过:的方式访问Service。
                • 特点:
                  • 允许外部访问集群内的服务。
                  • Kubernetes在30000-32767范围内自动为每个NodePort类型的Service分配一个端口。
                  • 与ClusterIP类似,也提供负载均衡和会话亲和性支持。
                  • 用途:适用于需要从集群外部访问服务的场景,如临时测试、开发环境等。
                    apiVersion: v1
                    kind: Service
                    metadata:
                      name: demo-svc-nodeport
                    spec:
                      type: NodePort
                      selector:
                        app: web
                      ports:
                      - name: http
                        port: 80   # Service 的port
                        targetPort: 80  # Pod 的 port
                        nodePort: 32001 
                    

                    LoadBalancer

                    • 定义:LoadBalancer类型基于NodePort实现,但进一步通过云服务商提供的负载均衡器将流量分发到各个Node。

                    • 特点:

                      • 适用于公有云环境,如AWS、Azure、GCE等。
                      • 外部流量通过云服务商的负载均衡器转发到集群内的Service。
                      • 提供高可用性、可扩展性和负载均衡等特性。
                      • 用途:适用于生产环境中需要高可用性和可扩展性的服务。

                        ExternalName

                        • 定义:ExternalName类型将Service映射到集群外部的DNS名称,而不是提供一个虚拟IP或端口。
                        • 特点:
                          • 不进行kube-proxy代理或流量转发。
                          • 允许集群内的Pod通过Service名称直接访问外部服务。
                          • 用途:适用于需要将Kubernetes集群内的服务与外部服务(如数据库、消息队列等)集成的场景。通过ExternalName,Pod可以像访问集群内服务一样访问外部服务,简化配置和管理。
                            apiVersion: v1
                            kind: Service
                            metadata:
                              name: demo-svc-externalname
                            spec:
                              type: ExternalName
                              externalName: www.baidu.com
                            

                            Service 与 Endpoint

                            Endpoint 与 容器探针

                            Service对象借助Endpoint资源来跟踪其关联的后端端点,Endpoint对象会根据Service标签选择器筛选出的后端端点的IP地址分别保存在subsets.address字段和subsets.notReady Address字段中,它通过APIServer持续、动态跟踪每个端点的状态变化,并即使反应到端点IP所属的字段中。

                            • subsets.address:保存就绪的容器IP,也就意味着service可以直接将请求调度至该地址段。
                            • subsets.notReadyAddress:保存末就绪容器IP,也就意味着service不会将请求调度至该地址段。

                              自定义Endpoint

                              service通过selector和pod建立关联,K8s会根据service关联到的pOdIP信息组合成一个endpoint。若service定义中没有selector字段,service被创建时,endpoint controller不会自动创建endpoint。

                              我们可以通过配置清单创建Service,而无需使用标签选择器,而后自行创建一个同名的endpoint对象,指定对应的IP。这种一般用于将外部MySQL\Redis等应用引1入KUbernetes集群内部,让内部通过Service的方式访问外部资源。

                              apiVersion: v1
                              kind: Service
                              metadata:
                                name: mysql-external
                              spec:
                                type: ClusterIP
                                ports:
                                - port: 3366                  # 负载均衡的对外端口
                                  targetPort: 3306            # 后端MySQL的端口
                              ---
                              apiVersion: v1
                              kind: Endpoints
                              metadata:
                                name: mysql-external
                              subsets:
                                - addresses:
                                  - ip: 10.0.0.206
                                  #- ip: 10.0.0.205
                                  ports:
                                  - protocol: TCP
                                    port: 3306               # 定义后端的端口是多少
                              

                              Service 相关字段

                              sessionAffinity

                              如果要将来自特定客户端的链接调度到同一Pod,可以通过sessionAffinity 基于客户端 IP 地址进行会话保持。还可以通过设置最大会话停留时间(默认10800秒,3个小时)

                              apiVersion: v1
                              kind: Service
                              metadata: 
                                name: session-svc
                              spec:
                                type: NodePort
                                selector:
                                  role: web
                                ports:
                                - name: http
                                  protocol: TCP
                                  port: 80
                                  targetPort: 80  
                                sessionAffinity:  ClientIp  # 配置 sessionAffinity 策略,默认为 None
                                sessionAffinityConfig:
                                  clientIP:
                                    timeoutSeconds: 60   # 设置最大会话时长
                              

                              externalTrafficPolicy

                              外部流量策略:当外部用户通过NodePort请求Service,是将外部流量路由到本地节点上的Pod,还是路由到集群范围的Pod:

                              • cluster(默认):将用户请求路由到集群范国的所有Pod节点,具有良好的整体负载均衡。
                              • Local:仅会将流量调度至请求的目标节点本地运行的Pod对象之上,以减少网络跳跃,降低网络延迟,但当请求指向的节点本地不存在目标Service相关的Pod对象时直接丢弃该报文。
                                apiVersion: v1
                                kind: Service
                                metadata: 
                                  name: session-svc
                                spec:
                                  type: NodePort
                                  selector:
                                    role: web
                                  ports:
                                  - name: http
                                    protocol: TCP
                                    port: 80
                                    targetPort: 80
                                  externalTrafficPolicy: Local
                                  sessionAffinity:  ClientIp  # 配置 sessionAffinity 策略,默认为 None
                                  sessionAffinityConfig:
                                    clientIP:
                                      timeoutSeconds: 60   # 设置最大会话时长
                                

                                internalTrafficPolicy

                                本地流量策略:当本地Pod对Service发起访问时,是将流量路由到本地节点上的Pod,还是路由到集群范国的Pod:

                                • cluster(默认):将Pod的请求路由到集群范国的所有Pod节点,具有良好的整体负载均衡。
                                • Local:将请求路由到与发起方处于相同节点的端点,这种机制有助手节省开销,提升效率。但当请求指向的节点本地不存在目标service相关的Pod对象时直接丟弃该报文。

                                  注意:在一个Service上,当externalTrafficPolicy已设置为Local时,internalTrafficPolicy则无法使用。换句话说,在一个集群的不同 Service 上可以同时使用这两个特性,但在一个Service 上不行

                                  apiVersion: v1
                                  kind: Service
                                  metadata: 
                                    name: session-svc
                                  spec:
                                    type: NodePort
                                    selector:
                                      role: web
                                    ports:
                                    - name: http
                                      protocol: TCP
                                      port: 80
                                      targetPort: 80
                                    internalTrafficPolicy: Local
                                  

                                  publishNotReadyAddresses

                                  pubishNotReadyAddresses: 表示Pod就绪探针探测失败,也不会将失败的PodIP 加入到NotReadyAddresses列表中

                                  apiVersion: v1
                                  kind: Service
                                  metadata: 
                                    name: session-svc
                                  spec:
                                    type: NodePort
                                    selector:
                                      role: web
                                    ports:
                                    - name: http
                                      protocol: TCP
                                      port: 80
                                      targetPort: 80
                                    pubishNotReadyAddresses: true
                                  

转载请注明来自码农世界,本文标题:《K8s service 进阶》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,73人围观)参与讨论

还没有评论,来说两句吧...

Top