Kubernetes精选学习

【K8s 精选】Kubernetes Service 介绍

2021-09-15  本文已影响0人  熊本极客

1.Service 背景

问题1:为什么需要服务发现
① 容器 Pod 生命周期短暂,容器 IP 地址随时变化
② Deployment 中的 Pod 组需要统一的访问入口和负载均衡
③ 应用在不同部署环境需要统一部拓扑和访问方式

问题2:如何提供外部访问和负载均衡的能力
Kubernetes Service 具备服务发现和负载均衡的功能,即一方面提供了统一的访问入口,另一方面负载均衡到后端 Pod。下图是 Service 的简约架构图,左侧表示 Service 提供了外部访问和 Pod 网络访问 ,右侧表示对接了一组 Pod,同时把请求负载均衡到这组 Pod。

Service 的简约架构图.JPG

2.Service 架构

Master 节点:Kubernetes 管理节点,负责管理和控制整个集群,包含的组件是 APIServer、Controller Manager 和Scheduler。
Worker 节点:Kubernetes 工作负载节点,包含的组件主要有 Kubelet、Kube-proxy。

Kubernetes 服务发现架构.JPG

2.1 Service 的关键组件

APIServer:Kubernetes 所有对象都会注册到 APIServer上,监听这些对象的变化,例如 Pod、StatefulSet、Service 等。
Controller Manager:负责配置 LoadBalance 的一个负责均衡器给外部访问。
Coredns:负责把 Service 名字(类似域名)解析为 Service 虚拟 IP 即 ClusterIP,同时观测 Service 的变化。
Kube-proxy:负责把 Service 虚拟 IP 即 ClusterIP 转换为后端 Pod IP,同时观测后端 Pod 的变化。

2.2 访问链路分析

2.2.1 集群内部访问

如上架构图示例,Client Pod3 访问 Service 的步骤:
Coredns 解析出 CluserIP:Client Pod3 拿着 Service name (域名)请求 Coredns,Coredns 解析域名后返回 ClusterIP。
Kube-proxy 拦截后负载均衡到后端 Pod:Client Pod3 拿着 ClusterIP 请求宿主机网络后,被 Kube-proxy 所配置的 iptables 拦截了,随后负债均衡转发到后端 Pod。

2.2.2 集群外部访问

LoaderBalancer 转发请求到某节点的 NodePort:外部请求通过 LoaderBalancer 转发到某节点的 NodePort,同时 LoaderBalander 通过 Controller Manager 监听 Service 的变化。
Kube-proxy 把 NodePort 转换为 ClusterIP 并转发到后端 Pod:NodePort 的请求被 Kube-proxy 所配置的 iptables 拦截并转发到 CluserIP,最终转发到后端 Pod。

3.Service 示例

3.1 创建和查看 Service

# 创建 service
$kubectl apply -f service.yaml

# 查看 service
$kubectl describe service my-service
Name:              my-service
Namespace:         default
Labels:            app=my-service
Selector:          app=MyApp
Type:              ClusterIP
IP:                172.29.3.27   # Service 虚拟 IP
Port:              80/TCP
TargetPort:        9376/TCP
Endpoints:         192.168.115.236:9376,192.168.115.237:9376,192.168.115.238:9376   # Selector 匹配到的后端 Pod 地址
Session Affinity:  None

3.2 集群内访问 Service

3.2.1 ClusterIP 访问

集群内访问Service.JPG

直接使用 ClusterIP

# 查询 ClusterIP
$kubectl get svc |grep my-service

直接使用 Service Name,Codedns 解析
{servicename}.{namespace}.svc.cluster.local

使用环境变量访问

MY_SERVICE_PORT_80_TCP_PROTO=tcp
MY_SERVICE_PORT=tcp://172.29.3.27:80
MY_SERVICE_SERVICE_PORT=80
MY_SERVICE_PORT_80_TCP_PORT=80
MY_SERVICE_PORT_80_TCP=tcp://172.29.3.27:80
MY_SERVICE_SERVICE_PORT=80
MY_SERVICE_SERVICE_HOST=172.29.3.27
MY_SERVICE_PORT_80_TCP_ADDR=172.29.3.27

3.2.1 Headless Service

Headless访问.JPG
apiVersion: v1
kind: Service
metadata:
  name: my-service
  label:
    app: my-service
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
  selector:
    app: myApp
  clusterIP: None    # 作用是让 Service 不再通过虚拟 IP 来负载均衡

通过 Service Name 可以直接解析到所有后端 Pod IP
客户端可以自主选择需要访问的 Pod IP

3.3 集群外访问 Service

集群外访问Service.JPG
apiVersion: v1
kind: Service
metadata:
  name: my-service
  label:
    app: my-service
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 30080
  selector:
    app: myApp
  type: NodePort
上一篇 下一篇

猜你喜欢

热点阅读