Skip to content

Latest commit

 

History

History
107 lines (93 loc) · 3.79 KB

File metadata and controls

107 lines (93 loc) · 3.79 KB

K8s服务发现

Pod之间通信

  • IP地址通信(可以用内网ip访问)

    Pod 的 IP 是不稳定的,我们不能把 Pod IP 用作服务之间的调用地址.

Service:原生的服务发现机制

apiVersion: v1
kind: Service
metadata:
  name: backend-service
  labels:
    app: backend
spec:
  type: ClusterIP
  sessionAffinity: None
  selector:
    app: backend # 这是一个 Pod 选择器,这个字段表示通过 Label 匹配 Pod,也就意味着,只要是 Label 包含 app=backend 的 Pod ,都会被当成是 backend-service 的同一组逻辑 Pod。
  ports:
  - port: 5000
    targetPort: 5000
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  ......
spec:
  ......
  template:
    metadata:
      labels:
        app: backend  # Pod Label 字段

Service IP 是稳定的,并且它能为我们抽象一组 Pod 实现负载均衡。这就意味着我们只需要访问 Service IP 就可以找到对应的 Pod。

$ kubectl get service -n example
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
backend-service    ClusterIP   10.96.151.12    <none>        5000/TCP   12h
frontend-service   ClusterIP   10.96.173.32    <none>        3000/TCP   12h
pg-service         ClusterIP   10.96.191.239   <none>        5432/TCP   12h

Service 域名

apiVersion: v1
kind: Service
metadata:
  name: backend-service
  labels:
    app: backend
spec:
  type: ClusterIP
  selector:
    app: backend
  ports:
  - port: 5000
    targetPort: 5000

访问

/frontend #while true; do wget -q -O- http://backend-service.example.svc.cluster.local:5000/host_name && sleep 1; done
{"host_name":"backend-595666f99c-jxpnb"}
{"host_name":"backend-595666f99c-pdxbk"}
{"host_name":"backend-595666f99c-pdxbk"}
{"host_name":"backend-595666f99c-jxpnb"}

请求发起方和目标 Service 在同一个命名空间下时,我们可以省略 namesapce.svc.cluster.local

/frontend #while true; do wget -q -O- http://backend-service:5000/host_name && sleep 1; done
{"host_name":"backend-595666f99c-jxpnb"}
{"host_name":"backend-595666f99c-pdxbk"}
{"host_name":"backend-595666f99c-pdxbk"}
{"host_name":"backend-595666f99c-jxpnb"}

Service 的类型

NodePort

可以使用节点 “IP+ 端口号”的形式来访问服务

Loadbalancer

Loadbalancer 是一种通过负载均衡器来暴露 Service 的方法,通过这种暴露方式,Service 会和云厂商的负载均衡器连接起来,使得 Service 可以通过负载均衡器提供的外网 IP 来进行访问。

在实际的业务中,我们通常会在集群内安装一个入口网关,例如 Ingress-nginx,它会自带一个 Loadbalancer 类型的 Service,然后由 Ingress-nginx 来统一接收外部请求,并将请求转发到集群内部。我们只需要配置域名或路径规则即可实现一个 Loadbalancer IP 暴露集群所有 Service 的效果

ExternalName(跨命名空间访问或者访问外部服务)

ClusterIP、NodePort 和 Loadbalancer 类型都是通过 Pod 选择器将 Service 和 Pod 关联起来,然后将请求转发到对应的 Pod 中的。而 ExternalName 类型非常特殊,它不通过 Pod 选择器关联 Pod ,而是将 Service 和另外一个域名关联起来。

apiVersion: v1
kind: Service
metadata:
  name: backend-service
  namespace: default
spec:
  type: ExternalName
  externalName: backend-service.example.svc.cluster.local

当将上面的 Service 应用到集群之后,在 default 命名空间下访问 http://backend-serivce:5000 时,请求将会被转发到 example 命名空间下的 backend-service。我们会发现虽然目标 Service 和请求发起方不在同一个命名空间下,但可以通过这种方法屏蔽它们在不同命名空间的调用差异,使得两个服务看起来像是在同一个命名空间下。