你知道K8S暴露服务的方式有哪些吗?

开发 前端
Kubernetes 支持多种将外部流量引入集群的方法。 ClusterIP 、 NodePort 和 Ingress 是三种广泛使用的资源,它们都在路由流量中发挥作用。

[[420612]]

Kubernetes 支持多种将外部流量引入集群的方法。 ClusterIP 、 NodePort 和 Ingress 是三种广泛使用的资源,它们都在路由流量中发挥作用。每一个都允许您使用一组独特的功能和折衷方案来公开服务。

背景

默认情况下, Kubernetes 上运行的服务都是在自己的Pod 里过着与世隔绝的生活,外部无法打扰他们。我们可以通过创建  Service 使容器供外部世界可见,这个“外部世界” 即可以整个集群、也可以是整个互联网。

Service 将流量路由到 Pod 内的容器中。 Service 是一种用于在网络上公开 Pod 的抽象机制。每个 Service 有一个类型—— ClusterIP 、 NodePort 或 LoadBalancer 。这些定义了外部流量如何到达服务。

但是光有 Service 也不行 ,有时候我们需要将不同域名和URL路径上的流量路由到集群内部,这就需要 Ingress 帮助才行。

ClusterIP

ClusterIP 是默认的 Service 类型,不指定 Type 时默认就是 ClusterIP 类型的 Service 。 ClusterIP 在集群内提供网络连接。它通常无法从外部访问。我们将这些 ClusterIP Service 用于服务之间的内部网络。

  1. apiVersion: v1 
  2. kind: Service 
  3. spec: 
  4.  metadata: 
  5.    name: my-service 
  6.   selector: 
  7.     app: my-app 
  8.   type: ClusterIP 
  9.   ports: 
  10.     - name: http 
  11.       port: 80 
  12.       targetPort: 8080 
  13.       protocol: TCP 

上面的示例定义了一个 ClusterIP Service 。到 ClusterIP 上端口 80 的流量将转发到你的 Pod 上的端口 8080  (targetPort配置项),携带 app: my-app 标签的 Pod 将被添加到 Service 中作为作为服务的可用端点。

可以通过运行 kubectl get svc my-service 查看分配的 IP 地址。集群中的其他服务可以使用 10.96.0.1:80 与这个的 Service 管控的服务进行交互。

  1. ➜  kubectl get svc app-service 
  2. NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)           AGE 
  3. my-service        ClusterIP   10.96.0.1        <none>        8080:80/TCP       63d 

可以使用 spec.clusterIp 字段手动将 ClusterIP 设置为特定 IP 地址:

  1. spec: 
  2.   type: ClusterIP 
  3.   clusterIp: 123.123.123.123 

NodePort

NodePort 在固定端口号上公开向集群外部暴露服务,它允许从集群外部访问该服务,在集群外部需要使用集群的 IP 地址和 NodePort 指定的端口才能访问。创建 NodePort Service 将在集群中的每个 Node 上开放该端口。 Kubernetes 会自动将端口流量路由到它所连接的服务。下面是一个 NodePort Service 的示例:

  1. apiVersion: v1 
  2. kind: Service 
  3. spec: 
  4.  metadata: 
  5.    name: my-service 
  6.   selector: 
  7.     app: my-app 
  8.   type: NodePort 
  9.   ports: 
  10.     - name: http 
  11.       port: 80 
  12.       targetPort: 8080 
  13.       protocol: TCP 

NodePort 的定义与 ClusterIP Service 具有相同的属性。唯一的区别是把类型设置成了:"NodePort"。 targetPort 字段仍然是必需的,因为 NodePort 由 ClusterIP 提供支持。

创建 NodePort Service 的同时还会自动创建一个 ClusterIP 类型的 Service , NodePort 会将端口上的流量路由给 ClusterIP 类型的 Service。

这也就是为什么下面我们查看 NodePort Service 时发现他也是有 ClusterIP 的原因:

  1. ➜  kubectl get svc my-service 
  2. NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)           AGE 
  3. my-service        NodePort    10.96.44.244     <none>        8080:30176/TCP    56d 

使用上述例子创建 NodePort Service , Kubernetes 将会从30000-32767这个范围随机分配一个端口作为 NodePort 端口,不过我们可以通过设置 ports.nodePort 字段来手动指定端口:

  1. spec: 
  2.   ports: 
  3.     - name: http 
  4.       port: 80 
  5.       targetPort: 8080 
  6.       nodePort: 32000 
  7.       protocol: TCP 

这个会将 32000 端口上的流量通过 Service 最终路由给 Pod 里容器的 8080 端口。

您可以使用 NodePort 快速设置用于开发环境的服务或在其上公开 TCP 或 UDP 服务,但是对于公开 HTTP 服务来说 NodePort 不是一个的理想选择,因为其使用的都是非 HTTP 标准的端口,我们需要使用其他替代方案。

Ingress

Ingress 实际上是与 Service 完全不同的资源,算是 Service 上面的一层代理,通常在 Service 前使用 Ingress 来提供 HTTP 路由配置。它让我们可以设置外部 URL、基于域名的虚拟主机、SSL 和负载均衡。

给 Service 前面加 Ingress ,你的集群中需要有 Ingress-Controller 才行。有多种控制器可供选择。大多数主要的云提供商都有自己的 Ingress-Controller ,与他们的负载平衡基础设施相集成。如果是自建K8S集群,通常使用 nginx-ingress 作为控制器,它使用 NGINX 服务器作为反向代理来把流量路由给后面的 Service 。

关于控制器Nginx-Ingress的安装部署参考:https://kubernetes.github.io/ingress-nginx/deploy/ 后面介绍 Ingress 实践的文章也会再细说。

可以使用 Ingress 资源类型创建 Ingress 。kubernetes.io/ingress.class 注释可让你指明正在创建的 Ingress 分类。如果集群里安装了多个 Ingress-Controller 这将很有用,也可以将不同的 Service 分别挂在不同分类的 Ingress 下面,增加一些高可用性。

  1. apiVersion: networking.k8s.io/v1beta1 
  2. kind: Ingress 
  3. metadata: 
  4.   name: my-ingress 
  5.   annotations: 
  6.     kubernetes.io/ingress.class: nginx 
  7. spec: 
  8.   rules: 
  9.     - host: example.com 
  10.       http: 
  11.         paths: 
  12.           - path: / 
  13.             backend: 
  14.               serviceName: my-service 
  15.               servicePort: 80 
  16.     - host: another-example.com 
  17.       http: 
  18.         paths: 
  19.           - path: / 
  20.             backend: 
  21.               serviceName: second-service 
  22.               servicePort: 80 

上面定义了两个 Ingress 端点。第一个主机规则将 example.com 流量路由到 my-service 服务上的端口 80。第二条规则将 another-example.com 流量路由到 second-service 。

如果想使用 HTTPs 访问服务,可以通过在 Ingress 规范中设置 tls 字段来配置 SSL :

  1. spec: 
  2.   tls: 
  3.     - hosts: 
  4.       - example.com 
  5.       - secretName: my-secret 

不过前提是在集群中需要通过 Secret 对象配置这些域名的证书信息。

当需要处理来自多个域名 和 URL 路径的流量时,应该使用 Ingress 。它让我们可以使用声明性语句配置路由和 Service 。 Ingress 控制器将提供你的路由并将它们映射到服务。

总结

ClusterIP 、 NodePort 、 Ingress 将流量路由到集群中的服务。每一个都是为不同的用例设计的。 ClusterIP 更多是为集群内服务的通信而设计,某些向集群外部暴露的 TCP 和 UDP 服务适合使用 NodePort 。而如果向外暴露的是 HTTP 服务,且需要提供域名和 URL 路径路由能力时则需要在 Service 上面再加一层 Ingress 做反向代理才行。

可能你对 Ingress , Ingress-Controller 还是有一点模糊,后面我在写一篇 Ingress 的实践文章,给大家扫扫盲。

 

责任编辑:张燕妮 来源: 网管叨bi叨
相关推荐

2023-11-07 08:23:05

2023-02-27 07:56:55

IngressKubernetes

2023-08-03 08:36:30

Service服务架构

2016-02-18 16:40:29

SaaS虚拟化自动化

2010-04-16 14:51:05

网络流量

2021-03-11 07:26:52

垃圾回收器单线程

2022-01-07 08:23:38

k8s AnnotationNginx

2019-02-21 16:36:16

云服务器云计算服务器

2019-02-23 15:00:43

2023-10-16 23:12:02

Redis数据结构

2022-12-27 14:18:45

K8S命令

2023-04-26 10:06:08

RocketMQ属性Consumer

2022-08-02 06:55:35

移动设备Android

2022-04-22 13:32:01

K8s容器引擎架构

2023-11-06 07:16:22

WasmK8s模块

2019-09-05 09:10:35

KafkaK8SKubernetes

2023-10-27 08:39:50

KubernetesK8s

2022-04-29 11:13:08

K8s资源Linux

2022-06-30 13:41:44

SQL 语句group by

2020-03-23 08:15:43

JavaScriptError对象函数
点赞
收藏

51CTO技术栈公众号