在k8s中各服务之间通过内部域名【服务名.namespace】的形式进行调用非常方便, 但是容器集群内的服务如何调用部署在集群外的中间件(如:Mysql、Redis、MongoDB)呢?
一、配置方法:
其实, k8s的Service 可以通过独立配置Endpoints的方法,直接代理外部服务并支持代理多个端口, 代码如下:
# describe: Service 代理外部服务
# author: qianmuYZ
# since: 2020-11-30
apiVersion: v1
kind: Service
metadata:
name: mysql-proxy # 资源名称,必须与Endpoints中metadata.name相同
namespace: myspace # 资源命名空间,必须与Endpoints中metadata.namespace相同
spec:
type: NodePort # 如果为ClusterIP模式,配置为:type: ClusterIP
ports:
- port: 6446 # 集群内部使用的端口
nodePort: 30306 # 如果NodePort模式才需要配置
name: rw1 # 必须与Endpoints中定义的端口名相同
- port: 6447 # 集群内部使用的端口
nodePort: 30307 # 如果NodePort模式才需要配置
name: ro1 # 必须与Endpoints中定义的端口名相同
- port: 6448 # 集群内部使用的端口
nodePort: 30308 # 如果NodePort模式才需要配置
name: rw2 # 必须与Endpoints中定义的端口名相同
- port: 6449 # 集群内部使用的端口
nodePort: 30309 # 如果NodePort模式才需要配置
name: ro2 # 必须与Endpoints中定义的端口名相同
---
# 重要提示:Endpoints 相当于配置 Service 的 targetPort,端口的名称必须相同
kind: Endpoints
apiVersion: v1
metadata:
name: mysql-proxy
namespace: myspace
subsets:
- addresses:
- ip: 192.168.2.2 # 外部服务的IP列表
- ip: 192.168.2.4
ports:
- name: rw1 # 外部服务的端口列表,与Service中映射的端口名相对应
port: 3306
- name: ro1
port: 3306
- addresses:
- ip: 192.168.2.5 # 外部服务的IP列表
- ip: 192.168.2.6
ports:
- name: rw2 # 外部服务的端口列表,与Service中映射的端口名相对应
port: 3306
- name: ro2
port: 3306
二、深度解读:
摘自Kubernetes权威指南(3.2.5 Service Controller 与 Endpoint Controller)
Service 、Endpoints 与 Pod的关系图:
1. Endpoints表示一个Service对应的所有Pod副本的访问地址,而Endpoints Controller就是负责生成和维护所有Endpoints对象的控制器.它负责监听Service和对应的Pod副本的变化,如果检测到Service被删除,则删除和该Service同名的Endpoints对象。如果检测到新的Service被创建或者修改则根据该Service信息获得相关的Pod列表,然后创建或者更新Service对应的Endpoints对象。
2. 每个计算节点(Node)上的Kube-proxy进程获取每个Service的Endpoints,实现Service的负载均衡功能。
3. Service Controller属于Kubernetes集群与外部云平台之间的一个接口控制器。