术语
- Node:
Kuberentes集群中的虚拟机节点或者物理机器节点 - Cluster
一系列的被防火墙隔离的节点,它们是Kubernetes管理的主要资源 - Edge router
加强了防火墙策略的路由, 他可以是硬件或者是云提供商提供的网关 - Cluster network
一系列逻辑或者物理的链接, 根据Kubernetes网络模型组成了集群内的通信, 集群网络的例子包括flannel类似的overlay网络或者OVS类似的SDN网络 - Service
Kubernetes中的服务表示通过label-selector组织起来的一系列的pods. 除非另有说明,否则服务假定在集群网络内仅可路由虚拟IP
Ingress是什么?
通常情况下,Services和Pods拥有的IPs只支持集群网络的路由. 所有的流量将会在边缘路由被丢弃或者是转发. 理论上, 它们看上去如下所示
internet
|
————
[ Services ]
Ingress是一系列的规则,那个允许到达的连接能够抵达集群中的服务.
internet
|
[ Ingress ]
–|—–|–
[ Services ]
它可以配置为提供外部可访问的URL,负载均衡流量,终止SSL,基于名称的虚拟主机等。用户通过将Ingress资源发布到API服务器来请求进入。 Ingress控制器负责实现Ingress,通常使用负载平衡器,尽管它还可以配置边缘路由器或其他前端,以帮助以HA方式处理流量。
先决条件
在开始使用Ingress资源之前,这里有许多东西需要理解, Ingress是一个beta版本的资源,在1.1版本之前的Kubernetes的版本是不可用的. 你需要一个Ingress控制器来满足ingress, 仅仅创建资源是无效的.
GCE/GKE在master节点上部署一个ingress控制器, 你可以部署一系列的ingress控制器在pod中. 你必须要注解每个ingress通过合适的类别, 像这样描述一样 exp.
确定你查看了这个控制器的beta limitation.在其他的平台中, 你可以通过pod的形式来部署一个控制器.
Ingress资源
最小的Ingress资源例子
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: rules: - http: paths: - path: /testpath backend: serviceName: test servicePort: 80
apiVersion/kind/metadata是必须的
Ingress spec用来配置loadbalancer或者proxy server.更重要的是它包含了一系列的规则来匹配请求. 当前http仅仅支持http规则
Lines 8-9:每个http规则包含了如下的信息, 一个host(比如foo.bar.com, 默认为*), 路径的列表(比如/testpath)每个关联一个后端(test:80), 如果host和path都匹配上了请求,将会通过loadbalancer转发到后端.
Lines 10-12 后端是service:port, 流程将会直接发送到匹配的后端的endpoints.
Global Parameters: 在最简单的例子中没有指定全局参数,可以通过参看api-reference里面的详细描述. 在没有与规范中的路径不匹配的请求发送到Ingress控制器的默认后端的情况下,可以指定全局缺省后端。
Ingress控制器
为了Ingress能够正常的工作,在集群中ingress控制器必须是运行的,跟其他类型的控制器不一样, 它们是作为kube-controller-manager的一部分来运行的.他们将会在集群创建的时候自己运行.您需要选择最适合您的集群的入口控制器实现,或实现一个。 示例和说明可以在这里找到。
在开始之前
以下文档描述了通过Ingress资源公开的一组跨平台功能。 理想情况下,所有Ingress控制器都应该符合这个规范,但是我们还没有。 GCE和nginx控制器的文档分别在这里和这里。 确保您查看控制器特定的文档,以便您了解每个文档的注意事项
Ingress类型
kubernetes中已经存在机制来暴露单个服务,然而你也可以通过ingress来实现,通过指定defualt backend,而不指定rules
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: backend: serviceName: testsvc servicePort: 80
通过kubectl create -f
$ kubectl get ing NAME RULE BACKEND ADDRESS test-ingress - testsvc:80 107.178.254.228
这里107.178.254.228是ingress分配的ip来满足这个ingress. 这个Rule表示所有发送到这个ip的请求都会转发到BackEND的service.
简单fanout
正如上面描述的,Kubernetes中的Pods的ip只在集群网络中可见, 所有我们需要在边缘有些东西来接受ingress的流量以及代理转发到正确的endpoints. 这个组建是一个通常高可用的负载均衡器. 一个ingress允许你将负载均衡器的数量降低到最少.
foo.bar.com -> 178.91.123.132 -> / foo s1:80 / bar s2:80
使用如下的yaml文件
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - path: /foo backend: serviceName: s1 servicePort: 80 - path: /bar backend: serviceName: s2 servicePort: 80
执行kubectl create -f ./
$ kubectl get ing NAME RULE BACKEND ADDRESS test - foo.bar.com /foo s1:80 /bar s2:80
只要存在服务(s1,s2),Ingress控制器将提供满足Ingress的实现特定负载平衡器。 当这样做时,您将在Ingress的最后一列看到负载均衡器的地址。
基于名称的虚拟主机
基于名称的虚拟主机使用相同IP地址的多个主机名。
foo.bar.com --| |-> foo.bar.com s1:80 | 178.91.123.132 | bar.foo.com --| |-> bar.foo.com s2:80
下面的ingress告诉loadbalancer根据host header来转发
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 - host: bar.foo.com http: paths: - backend: serviceName: s2 servicePort: 80
默认后端:没有规则的入口(如上一节所示)将所有流量发送到单个默认后端。 您可以使用相同的技术通过指定一组规则和默认后端来告诉负载均衡器找到您的网站的404页面。 如果您的Ingress中的主机与请求标头中的主机匹配,并且/或没有一个路径与请求的URL匹配,则流量将路由到您的默认后端.
TLS
您可以通过指定包含TLS私钥和证书的密钥来保护Ingress。 目前,Ingress仅支持单个TLS端口443,并假定TLS终止。 如果Ingress中的TLS配置部分指定不同的主机,则它们将根据通过SNI TLS扩展指定的主机名(提供Ingress控制器支持SNI)在多个相同端口上进行复用。 TLS秘密必须包含名为tls.crt和tls.key的密钥,其中包含用于TLS的证书和私钥,例如:
apiVersion: v1 data: tls.crt: base64 encoded cert tls.key: base64 encoded key kind: Secret metadata: name: testsecret namespace: default type: Opaque
在ingress里面引用该secert来加密从client到负载均衡器的通道
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: no-rules-map spec: tls: - secretName: testsecret backend: serviceName: s1 servicePort: 80
关于TLS功能不同的ingress控制器支持存在这差异,可以查看nginx的文档或者其他平台指定的ingress控制器来理解TLS在你的环境中怎么工作的.
负载均衡器
Ingress控制器引导一些适用于所有Ingress的负载平衡策略设置,例如负载均衡算法,后端权重方案等。更高级的负载平衡概念(例如持久会话,动态权重)尚未通过Ingress公开。 您仍然可以通过服务负载均衡器获取这些功能。 随着时间的推移,我们计划将适用跨平台的负载平衡模式提取到Ingress资源中。
还值得注意的是,尽管健康检查不直接通过Ingress公开,但Kubernetes中存在并行概念,例如准备探查,可以使您达成同样的最终结果。 请查看控制器特定的文档,以了解他们如何处理健康检查(nginx,GCE)。
更新ingress
$ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 $ kubectl edit ing test
修改对应的yaml文件的内容
spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 path: /foo - host: bar.baz.com http: paths: - backend: serviceName: s2 servicePort: 80 path: /foo
保存它将会更新api-server中的yaml资源
$ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 bar.baz.com /foo s2:80
你同样可以实现通过kubectl replace -f
在可用区域之间失败
在云端提供商之间跨越故障域传播流量的技术不同。 有关详细信息,请查看相关Ingress控制器的文档。 有关在联合群集中部署Ingress的详细信息,请参阅联盟文档
进一步的工作
HTTPS/TLS支持的不同的模式
通过claims来请求ip或者hostname
结合L4和L7的ingress
更多的ingress控制器