K8S里有一个 namespace 命名空间概念,如图
在 1 处是 namespaces 筛选的地方,2 处是我要搜索这个服务的名字,3 处是搜索的结果。
问:2 个不同的 namespaces 之间的服务如何进行通信呢?
答:K8S 内部自带有一套机制,就是通过自带的一个 DNS,作为连接不同 namespaces 的桥梁。
这里假设:命名空间 SpaceA、SpaceB,SpaceA 里有一个服务 ServiceA、SpaceB 里有一个服务 ServiceB;ServiceA 端口号为 PortA,ServiceB 端口号为 PortB。
那么,ServiceA.SpaceA:PortA 就可以和 ServiceB.SpaceB:PortB 之间进行互相访问。
注意:这里的 Port 指的是内部端口号(port)而不是(nodePort),这里的 ServiceX.SpaceX 通过 K8S 自带的 DNS 会解析成 clusterIP(K8S内部IP),如图
应用场景
1、外部访问 K8S 服务
- 映射 K8S 管理界面的 IP 作为 ServiceX.SpaceX(当然也可以叫其他域名,反正是本地的 hosts 映射),这里的 IP 注意不是 clusterIP
- 暴露端口为 nodePort: PortX
- 访问:ServiceX.SpaceX:PortX
2、内部访问 K8S 服务
- 将程序部署到同一个 K8S 里
- 不需要暴露任何端口
- 直接访问:ServiceX.SpaceX:PortX,(ServiceX.SpaceX 填写格式按照“服务名称.命名空间名称”)(PortX 采用的是 port)
3、内/外部使用一个地址同时都可以访问到 K8S 服务
- 看第 1 种场景,外部域名是可以变化的,然后端口也是可以自定义的(只要不冲突就行)
- 那么要想达到内外部利用一套“地址:端口”就可以访问,只需要将“ServiceX.SpaceX”本地映射成这种格式,nodePort == port 即可
常见问题
- 为什么我设置了 hosts 映射成 K8S 页面地址,端口也暴露了,本地好使,线上却不好使?
- 这个原因很可能是这样:本地用的域名首先也符合 "serviceName.namespaces:nodePort",但是这里的 nodePort 可能不等于 port。这会导致一个问题是 K8S 最终解析成“clusterIP:nodePort”,这样自然是行不通的,因为要么“K8SIP:nodePort”,要么“clusterIP:port”,这 2 种规范才可以的噢!