Kubernetes 网络介绍(九)
Ingress
Ingress 是Kubernetes特有的L7(HTTP)负载均衡器,可以从外部访问,与内部集群的L4 Cluster IP服务形成对比。这是将HTTP(S)工作负载展示给外部用户的标准选择。Ingress 可以是API或基于微服务架构的单个Ingress点。可以根据请求中的HTTP信息将流量路由到服务。Ingress 是配置规范(有多个实现)以将HTTP流量路由到Kubernetes服务。图5-7概括了 Ingress组件。
图5-7. Ingress 架构
在带有Ingress的集群中管理流量,需要两个组件:控制器和规则。控制器管理Ingress容器,部署在控制器配置中的规则规定了流量如何路由。
Ingress 控制器和规则
我们称Ingress实现为“Ingress控制器”。在Kubernetes中,控制器是负责管理典型资源类型并使现实与所需状态相匹配的软件。有两种类型的控制器:外部负载均衡器控制器和内部负载均衡器控制器。外部负载均衡器控制器创建一个存在于“集群外”的负载均衡器,如云提供商的产品。内部负载均衡器控制器部署运行在集群内的负载均衡器,并不直接解决消费者路由到负载均衡器的问题。集群管理员运行内部负载均衡器的方式多种多样,例如在特定节点集上运行负载均衡器,并以某种方式将流量路由到这些节点。选择内部负载均衡器的主要动机是成本减少。入囗的内部负载均衡器能够路由多个入囗对象的流量,而外部负载均衡器控制器通常需要为每个入囗配置一个负载均衡器。由于大多数云提供商以负载均衡器为单位收费,因此支持单一云负载均衡器在集群内部进行分发比多个云负载均衡器要便宜。请注意,这会引入操作成本和增加延迟和计算成本,因此要确保节省的钱物有所值。许多公司有一个坏习惯,即对不重要的云支出项目进行优化。
让我们看看Ingress控制器的规范。大体上,规范是通用的,但是各种Ingress控制器有不同的特性和接受不同的配置。我们从基础开始:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: basic-ingress
spec:
rules:
- http:
paths:
# 向demo服务发送所有/demo请求。
- path: /demo
pathType: Prefix
backend:
service:
name: demo-service
port:
number: 80
# 将所有其他请求发送到main服务。
defaultBackend:
service:
name: main-service
port:
number: 80
上述示例代表了典型的Ingress。它将流量发送到/demo到一个服务,所有其他流量发送到另一个。Ingress具有“默认后端”,如果没有任何规则匹配,则请求将被调度。这可以在许多Ingress控制器的控制器配置中进行配置(例如,一个通用的404页面),并且许多支持.spec.defaultBackend字段。Ingress支持多种指定路径的方式。目前有三种:
精确匹配特定路径并只有指定路径(包括尾随/或缺乏)。
前缀
匹配所有以给定路径开头的路径。
实现特定允许从当前Ingress控制器获取自定义语义。
当请求与多个路径匹配时,最具体的匹配被选择。例如,如果有规则为/first和/first/second,任何开始以/first/second的请求将被调度到/first/second的后端。如果路径与精确规则匹配并匹配前缀路径,则请求将被调度到精确规则的后端。Ingress还可以使用规则中的域名:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-host-ingress
spec:
rules:
- host: a.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service-a
port:
number: 80
- host: b.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service-b
port:
number: 80
在此示例中,我们从一个服务发送到a.example.com的流量,并从另一个服务发送到b.example.com的流量。这与web服务器的虚拟主机类似。您可能希望使用单个负载均衡器和IP为多个唯一域名提供服务。入囗具有基本的TLS支持:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress-secure
spec:
tls:
- hosts:
- https-example.com
secretName: demo-tls
rules:
- host: https-example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-service
port:
number: 80
TLS配置通过名称引用Kubernetes秘密,.spec.tls.[*].secret Name。控制器期望TLS证书和密钥通过在.sh.data."tls.crt"和.sh.data."tls.key"中提供来提供,如下所示:
apiVersion: v1
kind: Secret
metadata:
name: demo-tls
type: kubernetes.io/tls
data:
tls.crt: cert, 编码为base64
tls.key: key, 编码为base64
我们之前提到,入囗仅支持HTTP(S)请求,这对使用不同协议的服务来说是不充分的(例如,大多数数据库使用它们自己的协议)。一些入囗控制器,如NGINX入囗控制器,确实支持TCP和UDP,但这不是常态。
现在,让我们部署入囗控制器以便我们可以向Go语言Web服务器示例添加入囗规则。当我们部署KIND集群时,我们需要添加几种选项以允许我们部署入囗控制器:
-
extraPortMappings允许本地主机使用端口80/443请求入囗控制器。
-
Node-labels仅允许入囗控制器在与标签选择器匹配的特定节点(s)上运行。
可选择的入囗控制器种类繁多。Kubernetes系统没有开始或具有默认控制器的特性。Kubernetes社区支持AWS,GCE和NGINX入囗控制器。表5-1概述了几个入囗选项。
表5-1. 入囗控制器选项简要列表
名称 | 商业引擎 | 协议支持 | SSL终端 | |
---|---|---|---|---|
支持 | ||||
入囗控制器大使 | 是 | Envoy | gRPC、HTTP/2、WebSocket | 是 |
社区版入囗控制器NGINX | 不是 | NGINX | gRPC、HTTP/2、WebSocket | 是 |
NGINX Inc. Ingress控制器 | 是 | NGINX | HTTP、Websocket、gRPC | 是 |
HAProxy Ingress控制器 | 是 | HAProxy | gRPC、HTTP/2、WebSocket | 是 |
Istio Ingress控制器 | 不是 | Envoy | HTTP、HTTPS、gRPC、HTTP/2 | 是 |
Kong Ingress控制器Kubernetes | 是 | Lua在上面的 | gRPC、HTTP/2 | 是 |
Traefik Kubernetes Ingress控制器 | 是 | Traefik | HTTP/2、gRPC、WebSocket | 是 |
选择集群的入囗时,可以考虑以下内容:
-
协议支持:您是否需要超过TCP/UDP,例如gRPC集成或WebSocket?
-
商业支持:您是否需要商业支持? - 高级功能:您的应用程序是否需要JWT/oAuth2认证或断路器?
-
API网关功能:您是否有某些API网关功能的需求,如速率限制?
-
流量分配:您的应用程序是否需要支持如金枪鱼测试或镜像的专用流量分配?
对于我们的示例,我们选择使用NGINX入囗控制器的社区版本。
让我们将NGINX入囗控制器部署到我们的KIND集群:
kubectl apply -f ingress.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
与所有部署一样,我们必须要等待控制器就绪后才能使用它,我们可以通过此命令验证我们的 ingress 控制器是否就绪并可以使用:
kubectl wait --namespace ingress-nginx
> --for=condition=ready pod
> --selector=app.kubernetes.io/component=controller
> --timeout=90s
pod/ingress-nginx-controller-76b5f89575-zps4k condition met
控制器部署到了集群中,现在我们可以为应用程序编写 ingress 规则。
部署 ingress 规则
我们的 YAML 表示文件定义了许多与我们 Golang 网页服务器示例一起使用的 ingress 规则:
kubectl apply -f ingress-rule.yaml
ingress.extensions/ingress-resource created
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-resource <none> * 80 4s
借助 describe 命令我们可以查看映射到集群 IP 服务的所有后端以及相关 pod:
kubectl describe ingress
Name: ingress-resource
Namespace: default
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
*
/host clusterip-service:8080 ( 10.244.1.6:8080,10.244.1.7:8080,10.244.1.8:8080)
Annotations: kubernetes.io/ingress.class: nginx
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 17s nginx-ingress-controller Scheduled for sync
我们的 ingress 规则仅对 /host 路径有作用并将请求路由到 clusterip-service:8080 服务。
我们可以使用 cURL 对于 http://localhost/host 进行测试:
curl localhost/host
NODE: kind-worker2, POD IP:10.244.1.6
curl localhost/healthz
现在我们可以看到 ingress 的强大;让我们部署第二个部署和 ClusterIP 服务。
我们的新部署和服务将用于回答 /data 的请求:
kubectl apply -f ingress-example-2.yaml
deployment.apps/app2 created
service/clusterip-service-2 configured
ingress.extensions/ingress-resource-2 configured
现在,/host 和 /data 工作但路由到不同的服务:
curl localhost/host
NODE: kind-worker2, POD IP:10.244.1.6
curl localhost/data
Database Connected
既然 ingress 在第 7 层(应用层)工作,那么有许多选项用于路由流量,例如主机头和路径 URI。对于更为复杂的流量路由和发布模式,集群网络中需要部署服务网格。下一篇我们继续了解这方面的内容。
原文始发于微信公众号(Docker中文社区):Kubernetes 网络介绍(九)
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论