如何对外暴露服务 是一个非常重要又非常让人困惑的问题
这里有一个基本通用准则是
如果需要在TCP层(L4)上通讯,那么使用Nodeport (典型应用是 Mysql)
如果只需要HTTP或者HTTPS(L7)上通讯,那么使用 Ingress (典型应用是 Nginx)
大多数Helloworld程序都会简单粗暴的使用的 Nodeport , 它简单易用而且几乎可以在任何情况下使用,但是却并不优雅,Ingress 借助于反向代理服务优雅的解决了一些问题,但是却无法支持 L4 层网络通讯
但是大多数的文档资料和图书都很少提及 External IP ,甚至官方文档说得也非常含糊。
If there are external IPs that route to one or more cluster nodes, Kubernetes Services can be exposed on those
externalIPs
. Traffic that ingresses into the cluster with the external IP (as destination IP), on the Service port, will be routed to one of the Service endpoints.externalIPs
are not managed by Kubernetes and are the responsibility of the cluster administrator.
部署一个 Mysql 应用
创建一个 Nodeport 服务
可以看到 30686 已经打开,可以正常连接数据库
要创建 ExternalIP 的服务,需要创建类型是 ClusterIP ,然后添加ExternalIP
它的yaml看起来是这样的
spec:
clusterIP: 10.43.245.251
clusterIPs:
- 10.43.245.251
externalIPs:
- 192.168.194.149
ports:
- name: default
port: 3306
protocol: TCP
targetPort: 3306
selector:
workloadID_mysqle: "true"
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
看起来是不是很奇怪,明明是 ExternalIP ,类型却是 ClusterIP
ExternalIP可以让你直接使用 IP 加 3306连接 Mysql,而不需要使用看起来非常怪异的 High port (30686)
ExternalIP的优点在于
可以直接使用 IP + 原端口 访问服务
缺点其实也很明显
没有 高可用,也没有负载均衡
ExternalIP 不是集群管理的,IP也需要手动控制,你得做不少手动工作
这里负载均衡和高可用可以通过一个 Portal 或者 robin DNS 自己处理,当然可能也需要复杂的健康检查和熔断机制才能达到商用级别