Pod之间通信
- IP地址通信(可以用内网ip访问)
Pod 的 IP 是不稳定的,我们不能把 Pod IP 用作服务之间的调用地址.
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
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"}
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 和请求发起方不在同一个命名空间下,但可以通过这种方法屏蔽它们在不同命名空间的调用差异,使得两个服务看起来像是在同一个命名空间下。