说说 Kubernetes 是怎么实现服务发现的
我们来说说 Kubernetes 的服务发现 。那么首先这个大前提是同主机通信以及跨主机通信都是 ok 的 , 即同一 Kubernetes 集群中各个 Pod 都是互通的 。这点是由更底层的方案实现 , 包括 docker0/CNI 网桥、Flannel vxlan/host-gw 模式等 , 在此篇就不展开讲了 。
文章图片
文章图片
在各 Pod 都互通的前提下 , 我们可以通过访问 podIP 来调用 Pod 上的资源 , 那么离服务发现还有多少距离呢?首先 Pod 的 IP 不是固定的 , 另一方面我们访问一组 Pod 实例的时候往往会有负载均衡的需求 , 那么 Service 对象就是用来解决此类问题的 。
集群内通信 Endpoints
Service 首先解决的是集群内通信的需求 , 首先我们编写一个普通的 deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: hostnames spec: selector: matchLabels:app: hostnames replicas: 3 template: metadata:labels:app: hostnames spec:containers:- name: hostnamesimage: mirrorgooglecontainers/serve_hostnameports:- containerPort: 9376protocol: TCP
这个应用干的事儿就是访问它是返回自己的 hostname , 并且每个 Pod 都带上了 APP 为 hostnames 的标签 。
那么我们为这些 pod 编写一个普通的 Service:
apiVersion: v1 kind: Service metadata: name: hostnames spec: selector: app: hostnames ports: - name: defaultprotocol: TCPport: 80targetPort: 9376
可以看到 Service 通过 selector 选择 了带相应的标签 Pod , 而这些被选中的 Pod , 成为 Endpoints , 我们可以试一下:
~/cloud/k8s kubectl get ep hostnames NAMEENDPOINTS hostnames172.28.21.66:9376,172.28.29.52:9376,172.28.70.13:9376
当某一个 Pod 出现问题 , 不处于 running 状态或者 readinessProbe 未通过时 , Endpoints 列表会将其摘除 。
ClusterIP
以上我们有了 Service 和 Endpoints , 而默认创建 Service 的类型是 ClusterIP 类型 , 我们查看一下之前创建的 Service:
~ kubectl get svc hostnames NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE hostnamesClusterIP10.212.8.12780/TCP8m2s
我们看到 ClusterIP 是 10.212.8.127 , 那么我们此时可以在 Kubernetes 集群内通过这个地址访问到 Endpoints 列表里的任意 Pod:
sh-4.2# curl 10.212.8.127 hostnames-8548b869d7-9qk6b sh-4.2# curl 10.212.8.127 hostnames-8548b869d7-wzksp sh-4.2# curl 10.212.8.127 hostnames-8548b869d7-bvlw8
访问了三次 ClusterIP 地址 , 返回了三个不同的 hostname , 我们意识到 ClusterIP 模式的 Service 自动对请求做了 round robin 形式的负载均衡 。
对于此时 ClusterIP 模式 Serivice 来说 , 它有一个 A 记录是 service-name.namespace-name.svc.cluster.local , 指向 ClusterIP 地址:
sh-4.2# nslookup hostnames.coops-dev.svc.cluster.local Server:10.212.0.2 Address:10.212.0.2#53Name:hostnames.coops-dev.svc.cluster.local Address: 10.212.8.127
理所当然我们通过此 A 记录去访问得到的效果一样:
sh-4.2# curl hostnames.coops-dev.svc.cluster.local hostnames-8548b869d7-wzksp
那对 Pod 来说它的 A 记录是啥呢 , 我们可以看一下:
sh-4.2# nslookup 172.28.21.6666.21.28.172.in-addr.arpa name = 172-28-21-66.hostnames.coops-dev.svc.cluster.local.Headless service
Service 的 CluserIP 默认是 Kubernetes 自动分配的 , 当然也可以自己设置 , 当我们将 CluserIP 设置成 None 的时候 , 它就变成了 Headless service 。
Headless service 一般配合 StatefulSet 使用 。StatefulSet 是一种有状态应用的容器编排方式 , 其核心思想是给予 Pod 指定的编号名称 , 从而让 Pod 有一个不变的唯一网络标识码 。那这么说来 , 使用 CluserIP 负载均衡访问 Pod 的方式显然是行不通了 , 因为我们渴望通过某个标识直接访问到 Pod 本身 , 而不是一个虚拟 vip 。
- 原神心海是几星(原神心海角色属性介绍)
- 今年的iphonese,还是你熟悉的模样
- 原神雷神是什么定位(原神手游雷神定位分析)
- 原神无尽骤战高分打法是什么(原神无尽骤战玩法技巧分享)
- 崩坏3V5.0版本累计消费活动是什么(崩坏3V5.0版本夏日活动介绍)
- 249克!开箱道通EVO Nano+袖珍无人机:夜景是亮点
- 浓缩洗涤剂,还是老牌国货一轻日化好~
- 饿了么是不是只能用支付宝(饿了么平台运营详细解说)
- 微信朋友验证消息是怎么回事(?微信查看好友添加来源步骤)
- 妄想山海神树蕴养玩法是什么(妄想山海神树蕴养玩法思路介绍)
