如何显式定义 Kubernetes 服务的端点

How to explicitely define an Endpoint of an Kubernetes Service

我已经通过 kubespray 在我自己的几个虚拟机上配置了一个 kubernetes 集群。 Kubespray 使用 project-calico 作为默认的 network-plugin,这非常符合我对集群网络中代理服务到外部世界的要求。

Kubespray 将 apiserver 本身部署为 ClusterIP 服务。为了使其可以从外部访问,它使用主节点主机 IP 地址定义了该服务的端点,据我自己所知,该地址由 Calico 路由到内部 ClusterIP。

我的问题是:如何定义我自己的端点(用于另一个服务),因为这些端点已经通过配置 service.yaml 隐式定义并且不能被覆盖。我想采用类似的方法让我的 Rook/Ceph 仪表板从集群外部可见。

编辑:请注意 kubectl get ingresses.networking.k8s.io --all-namespaces returns No resources found.kubectl describe service kubernete returns

Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.233.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         192.168.103.254:6443
Session Affinity:  None
Events:            <none>

我不太确定你的意思是什么,但我认为你正在寻找的是向外部公开服务的能力。

您可以使用 "Publishing Services"(向外部公开内部服务的服务类型)公开您的服务,例如 Rook/Ceph 仪表板。

引自 kubernetes 文档:

For some parts of your application (for example, frontends) you may want to expose a Service onto an external IP address, that’s outside of your cluster.

Kubernetes ServiceTypes allow you to specify what kind of Service you want. The default is ClusterIP.

Type values and their behaviors are:

  • ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.
  • NodePort: Exposes the Service on each Node’s IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You’ll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
  • LoadBalancer: Exposes the Service externally using a cloud provider’s load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.
  • ExternalName: Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record with its value. No proxying of any kind is set up.

这是文档中的 example


您还可以像这样使用 yaml 清单定义 Services

apiVersion: v1
kind: Service
metadata:
  name: examplelb
spec:
  type: LoadBalancer
  selector:
    app: asd
  ports:
    -
      name: koala
      port: 22223
      targetPort: 22225
      nodePort: 31913
    -
      name: grisly
      port: 22224
      targetPort: 22226
      nodePort: 31914
    -
      name: polar
      port: 22225
      targetPort: 22227
      nodePort: 31915

这使得 pods 带有标签:app: asd 有以下端口以模式公开 在 31913.

上暴露的内部端口 22223
$ kubectl get svc examplelb
NAME        TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                           AGE
examplelb   LoadBalancer   10.111.8.204   <pending>     22223:31913/TCP,22224:31914/TCP,22225:31915/TCP   7d2h

如果类型为 LoadBalancer 的服务有待定的外部 IP,您仍然可以访问每个节点上的所有这些端口作为 NodePort

希望对您有所帮助。

我会参考你的问题:

How is it possible to define my own endpoint?

你必须:

1 ) 创建一个没有 Pod 选择器的服务:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 9376

(此时,K8S 不会创建 auto-generated 端点,因为它无法决定这些端点应该指向哪个 pods。

2 ) 创建一个 Endpoints 对象并将其映射到外部资源所在的所需网络地址和端口 运行:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.45
    ports:
      - port: 9376

(*) 请注意,服务名称和 Endpoints 对象的名称应该匹配。