前情提要

k8s/k3s 访问集群外独立的服务最好的方式是采用Endpoint方式,Endpoint 是什么呢?

Endpoint是可被访问的服务端点,即一个状态为running的pod,它是service访问的落点,只有service关联的pod才可能成为endpoint。

Endpoint、service和pod的

业务逻辑架构如下图:

kubernetes 污点 解除 kubernetes endpoints_Endpoint

关系架构关系如下图:

kubernetes 污点 解除 kubernetes endpoints_选择器_02

endpoints 概念详解

1 Endpoints

Endpoints表示一个Service对应的所有Pod副本的访问地址。

Node上的Kube-proxy进程获取每个Service的Endpoints,实现Service的负载均衡功能。

kubernetes 污点 解除 kubernetes endpoints_Pod_03

2 Endpoints Controller

Endpoints Controller就是负责生成和维护所有Endpoints对象的控制器,它负责监听Service和对应的Pod副本的变化。

如果检测到Service被删除,则删除和该Service同名的Endpoints对象。

如果检测到新的Service被创建或者修改则根据该Service信息获得相关的Pod列表,然后创建或者更新Service对应的Endpoints对象。

3 检查系统的 Endpoints

kubectl get endpoints

kubernetes 污点 解除 kubernetes endpoints_Endpoint_04

4 访问集群外部的服务

对于一个集群内部的 pod 来说,如果他想访问一个集群外部的服务该怎么办呢?例如一个网站的公共 api,或者是一个云数据库。我们就没办法使用svc+标签选择器的方式来获取这些服务了,因为标签选择器只能监测集群内部的 pod 。而无法放眼外部。那么我们应该怎么做呢?
当然可以通过自定义一个endpoint资源,用它指定外部服务的 ip 及端口,然后绑定到一个svc上,这样内部的 pod 不就通过完全一样的方式访问外部服务了么?

kubernetes 污点 解除 kubernetes endpoints_选择器_05

你可以把这张图拿去和"service 对 pod 的动态绑定"小节中的图做对比,你会发现最根本的service > endpoint > 服务提供者的传递流程是没有变的。ok,现在我们来动手操作一下,首先新建一个webhook 的 svc,仅有一个端口9443可以提供访问:

svc.yaml 如下:

apiVersion: v1
kind: Service
metadata:
  name: webhook-service
  namespace: system
spec:
  ports:
    - port: 443
      targetPort: 9443
  selector:
    control-plane: controller-manager

endpoint.yaml 如下:

---
apiVersion: v1
kind: Endpoints
metadata:
  name: webhook-service
  namespace: system
subsets:
  - addresses:
      - ip: <k8s-master-ip>
    ports:
      - port: 9443

查看部署情况:

# 查询获取所有的 endpoint
kubectl get ep -A

kubernetes 污点 解除 kubernetes endpoints_kubernetes 污点 解除_06