快捷搜索:  汽车  科技

什么是kubernetes资讯(Kubernetes服务解释)

什么是kubernetes资讯(Kubernetes服务解释)在 K8s 集群中,我们的应用程序代码使用 K8s部署资源在容器内运行。这个部署资源在内部创建了一个 K8s Pod资源,它反过来实际运行容器。让我们从回答原因开始。在整个博客文章中,我们将假设以下内容。Kubernetes 集群

每日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。Kubernetes 中的 NodePorts、LoadBalancers、Ingresses 等的概要!

Kubernetes 网络原理确实令人困惑,尤其是如果您是初学者。

不管我如何遵循官方文档,老实说,我一个该死的东西都不懂!

在 YouTube 上观看了一些教程后,我能够编写和复制教程,但仍然缺少对 Kubernetes 网络概念的核心理解。

这篇博文是我对深入解释 Kubernetes 网络概念并回答以下问题的看法,这些问题总是让我感到困惑:

  • Kubernetes 网络资源如何解决 Kubernetes 中的服务发现问题?
  • LoadBalancer 服务真的会自动配置负载均衡器吗?如果我在本地创建此服务会发生什么?
  • 生产就绪的 Kubernetes 集群如何公开其应用程序?
  • Ingress 和 Ingress 控制器有什么区别?
  • 和更多…
让我们开始吧

在整个博客文章中,我们将假设以下内容。

  • 您熟悉 Kubernetes YAML 资源定义的结构。
  • 您已经在云上跨三个 VM 部署了一个虚构的 Kubernetes 集群。虚拟机/节点具有以下公共 IP 地址
    • 节点 A (192.168.0.1)
    • 节点 B (192.168.0.2)
    • 节点 C (192.168.0.3)
  • 具有四个服务的微服务应用程序部署在该 K8s 集群上。应用程序的部署方式使得每个 VM 至少有一个运行该服务的副本
    • Products
    • Reviews
    • Details
    • Ratings
  • 符号
    • $Reviews_A$ 表示Reviews服务在节点 A 上运行
    • K8s表示 Kubernetes
    • LBs表示负载均衡器

什么是kubernetes资讯(Kubernetes服务解释)(1)

Kubernetes 集群


让我们从回答原因开始。

为什么我们首先需要服务?

在 K8s 集群中,我们的应用程序代码使用 K8s部署资源在容器内运行。这个部署资源在内部创建了一个 K8s Pod资源,它反过来实际运行容器。

每当创建 Pod 时,K8s 都会分配一个 IP 地址。下面的命令显示了 Pod 的示例 IP 地址

kubectl get pods <pod-name> -o wide

什么是kubernetes资讯(Kubernetes服务解释)(2)

示例 Pod IP

K8s pod 是短暂的/短暂的。

因此,如果某个 pod 因任何原因死亡,K8s 会自动重启该 pod,但分配给该 pod 的 IP 地址也会发生变化。这反过来会导致 $Products_A$ 和 $Reviews_A$ 微服务之间的通信失败,因为 $Reviews_A$ 服务的 IP 地址是硬编码在 $Products_A$ 服务的配置文件中的。这是有问题的!

如果以某种方式将静态 IP 地址或 DNS 名称分配给 Pod,那不是很好吗?这将解决我们的问题。

这就是K8s的Service资源的用武之地。我知道服务这个名字听起来很骗人。服务 资源不运行我们的容器。它只是为我们的 Pod 资源提供和维护一个网络身份。

此服务网络身份提供静态 IP 地址和 DNS 名称。我们只需要指定接收请求的端口和发送请求的 pod 的端口。

服务侦听不会更改的静态地址,并将请求转发到不可靠的容器地址。它在内部保留一个始终包含 Pod 最新 IP 地址的映射。因此,每当 Pod 重新启动时,它都会自动更新该映射,以便您获得无缝连接。

使用服务的另一个好处是同一应用程序的副本之间的负载平衡。对于我们想象的应用程序,由于每个微服务的三个实例运行在不同的虚拟机上,服务将在 $Products_A$ $Proudcts_B$ $Products_C$ 的副本之间对请求进行负载平衡。

什么是kubernetes资讯(Kubernetes服务解释)(3)

使用服务资源在 K8s 中的 Pod 之间进行负载平衡

到目前为止,我们已经了解什么是服务以及为什么需要它们。让我们看看 K8s 提供的不同服务及其用例。

如何让 $Products_A$ 服务与 $Reviews_A$ 服务对话?ClusterIP 服务救援

以下 YAML 定义了 ClusterIP 类型的服务

apiVersion: v1
kind: Service
metadata:
labels:
app: reviews
name: reviews
spec:
ports:
- name: http
port: 5000
protocol: TCP
targetPort: 80
selector:
app: reviews
type: ClusterP

此 YAML 中的重要字段是

  • targetPort: 表示需要转发请求的容器端口
  • port: 表示服务接受传入请求的端口
  • selector:用于将 K8s Service资源关联/附加到 K8s Pod资源。这是通过将 pod 的标签(键值对)与选择器部分中指定的选择器标签匹配来完成的。

选择器标签必须匹配才能将服务附加到 pod。

下面的命令显示了可以被其他 Pod 使用的服务的静态 IP 地址:

kubectl get service <service-name>

什么是kubernetes资讯(Kubernetes服务解释)(4)

您可以使用上述 IP 地址在 $Products_A$ 和 $Reviews_A$ 微服务之间进行通信。

有两种使用 DNS 进行通信的方式。

  • 位于同一个 K8s Namespace 中的 Pod可以使用服务的名称进行 DNS 解析
    • 示例 →http://reviews:5000
  • 位于其他命名空间中的 Pod 可以使用以下 DNS 表示法 →<service-name>.<namespace>.svc.cluster.local
    • 假设 $Products$ Pod 位于products 命名空间中,而 $Reviews$ pod 位于reviews 命名空间中。对于 $Products$ pod 与 $Reviews$ pod 通信,您将使用以下 DNS →http://reviews.reviews.svc.cluster.local:5000

现在您可以将这些地址传递给您的微服务进行通信。

什么是kubernetes资讯(Kubernetes服务解释)(5)

使用集群 IP 服务的内部通信


到目前为止,我们已经了解了 K8s 集群内的应用程序如何相互通信,但是您让您的应用程序被互联网上的用户使用。让我们看看它是如何完成的。

如何通过 Internet 公开 $Products_A$ 服务?

默认情况下部署在 K8s 中的每个应用程序都无法通过网络/互联网访问。它们需要通过Service公开。K8s 提供了两个服务来做到这一点:

节点端口服务

以下 YAML 可用于创建 NodePort 服务:

apiVersion: v1
kind: Service
metadata:
labels:
app: reviews
name: reviews
spec:
ports:
- name: http
port: 5000
protocol: TCP
targetPort: 80
selector:
app: reviews
type: NodePort


上述 YAML 定义与ClusterIP Service定义非常相似。唯一改变的type字段是从ClusterIP 到 NodePort的字段。当您创建 NodePort 服务时,K8s 会随机选择节点/VM 上介于30000 - 32767之间的任何可用端口,并在其上侦听传入请求。

您可以在服务定义中自己指定 NodePort 字段,但您必须处理检查端口是否在每个节点上都可用的麻烦。

创建服务后,要获取此 NodePort 服务正在侦听请求的端口,请使用以下命令:

kubectl get service <service-name>

什么是kubernetes资讯(Kubernetes服务解释)(6)

在我们想象的 K8s 集群中,这将发生在所有节点上:

  • 节点 A (192.168.0.1:30519)
  • 节点 B (192.168.0.2:30519)
  • 节点 C (192.168.0.3:30519)

您可以使用地址nodeIP:30519访问您的应用程序。对于节点 A,它将是 192.168.0.1:30519。

什么是kubernetes资讯(Kubernetes服务解释)(7)

使用 Nodeport 服务公开应用程序

但这并不实用。您的应用程序的用户不会记住您的 IP 地址和端口来访问您的应用程序。他们需要一个域名myapp.com来访问您的应用程序。我们通过在我们的虚拟机前面放置一个外部负载均衡器来解决这个问题。负载均衡器的公共 IP 映射到 myapp.com,因此当您在浏览器中键入 myapp.com 时,它会解析为负载均衡器的 IP。然后,负载均衡器根据负载均衡器中配置的算法将这些请求转发到我们三个节点中的任何一个。

K8s 提供了另一个服务来公开您的应用程序,称为 LoadBalancer 服务。

负载均衡器

以下 YAML 可用于创建 LoadBalancer 服务:

apiVersion: v1
kind: Service
metadata:
labels:
app: reviews
name: reviews
spec:
ports:
- name: http
port: 5000
protocol: TCP
targetPort: 80
selector:
app: reviews
type: LoadBalancer

上述 YAML 定义与ClusterIP Service定义非常相似。唯一更改的type字段是从ClusterIP 到 LoadBalancer的字段。

LoadBalancer 服务是对 NodePort 服务的抽象。该服务的特别之处在于,如果您使用的是 EKS(AWS)、GKS(GCP)、AKS(Azure) 或任何其他云提供商等托管 Kubernetes 服务,它会自行配置负载均衡器,这样您就不需要不必麻烦自己设置负载均衡器。

创建服务后,要获取此服务提供的负载均衡器的公共 IP 地址,请使用以下命令:

kubectl get service <service-name>

什么是kubernetes资讯(Kubernetes服务解释)(8)

负载均衡器服务示例

但是,如果您在本地 K8s 集群上创建 LoadBalancer 服务或在云中从头开始配置自己的 K8s,会发生什么?

答案是:它不会做任何事情。您将看到 IP 地址部分的 <Pending> 状态。原因是特定于云的 K8s 集群添加了其他特殊程序/控制器来检测 LoadBalancer 服务的创建并相应地采取适当的操作。

这里要注意一件事:LoadBalancer 服务本身并不像 NodePort 服务那样公开任何端口。

LoadBalancer是 NodePort 的超集,NodePortclusterIP服务的超集,这意味着,当您创建 NodePort 类型的服务时,也会隐式创建 ClusterIP 服务。因此,如果您为 $Products$ 微服务创建 NodePort 服务,那么该服务既可以用于其他 pod 的内部通信,也可以用于访问 Internet 上的 $Products$ 服务。

什么是kubernetes资讯(Kubernetes服务解释)(9)

服务超集


我们应该使用 NodePort 还是 LoadBalancer 服务?

如果您仔细阅读,您会发现 NodePort 和 LoadBalancer 服务之间并没有太大的区别,只是在后者中进行了一些自动化操作。

使用 LoadBalancer 服务消除了配置和供应 LB 的琐碎任务。同时,使用 NodePort 可以让您自由设置自己的负载均衡解决方案,例如配置 Kubernetes 不完全支持的环境,甚至直接暴露一个或多个节点的 IP。

所以这取决于你所处的情况,但一般的经验法则是先尝试使用 LoadBalancer 服务,但如果它不适用于你的环境,请使用 NodePort 服务

也就是说,这两个服务用于将您的应用程序暴露在集群之外。但是有一个小问题。

如果要公开多个应用程序,最终会创建多个 NodePort / LoadBalancer 服务。这可以完成工作,但您必须面对一些后果,因为对于每个 NodePort 服务,您需要处理手动管理 IP 和端口的麻烦。使用每个 LoadBalancer 服务,您会继续增加您的云账单。

不用担心,K8s 已经通过使用Ingress 和 Ingress 控制器解决了这个问题。

如何在不创建多个服务的情况下公开多个应用程序入口和入口控制器

Ingress 和 Ingress 控制器是两个不同的东西。

Ingress 控制器只是另一个 K8s 部署资源(在容器中运行的应用程序),但这种部署的特别之处在于它为进入 Kubernetes 集群的所有传入流量提供了单点控制。

Ingress 控制器视为运行在 K8s 中的智能代理,将Ingress视为配置Ingress 控制器 路由逻辑的 K8s 资源。对于使用过 Nginx 的人来说,Nginx 网络服务器将是您的 Ingress 控制器,而 nginx.conf 文件将是您的 Ingress 资源。

通过这些,您可以根据任何请求参数(如主机、URL 路径、子域等)指定需要将哪些请求路由到 K8s 集群中的哪个服务。

以下 YAML 可用于创建 Ingress 资源:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
ingressClassName: nginx
rules:
- host: "products.myapp.com"
http:
paths:
- pathType: Prefix
path: "/products"
backend:
service:
name: products-app
port:
number: 80
- host: "ratings.foo.com"
http:
paths:
- pathType: Prefix
path: "/ratings"
backend:
service:
name: ratings-app
port:
number: 80

通过上面的 YAML,我们暴露了两个服务。如果一个请求来自products.myapp.com并且请求路径以 开头/proudcts,我们将它发送到我们的 products-app K8s 服务,它反过来将请求转发到我们的容器。

同样,如果一个请求来自ratings.bar.com它,它会被转发到 ratings-app

入口 YAML 说明

这些 YAML 中的重要字段是:

  • ingressClassName:通常,集群中只有一个入口控制器,但没有人阻止您创建多个。该字段用于选择入口控制器,类似于服务的选择器字段
  • service: 表示必须转发请求的服务的名称

入口资源应该在对应的K8s Service所在的同一个命名空间中创建,但是入口控制器可以放置在任何命名空间中。它会在ingressClassName.

要记住的重要一点是,Ingress 本身不会暴露任何端口。说到底,它只是一个 K8s 部署资源。您需要在它前面提供一个服务(NodePort/LoadBalancer)来公开它。

什么是kubernetes资讯(Kubernetes服务解释)(10)

使用负载均衡器服务公开应用程序


结论

恭喜你坚持到最后。让我们总结一下到目前为止我们学到的东西。Kubernetes 为我们提供了三种服务资源对象

  • 集群 IP 服务
    • 用于工作负载之间的内部通信并处理服务发现。
  • 节点端口服务
    • 用于通过 Internet 公开应用程序,主要用于开发环境
  • 负载均衡器服务
    • 用于通过 Internet 公开应用程序
    • 在支持的云平台上在云上配置实际负载均衡器
  • 入口资源
    • 用于控制 Kubernetes 集群中的传入流量
    • 各种实现方式各有优缺点

这就是这篇博文的内容。如果你喜欢这篇博文,可以在 Twitter 上关注我@SharadRegoti,我在这里讨论微服务、云、Kubernetes 和 Golang。

猜您喜欢: