41.Ingress
Ingress
术语
在本篇文章中你将会看到一些在其他地方被交叉使用的术语,为了防止产生歧义,我们首先来澄清下。
- 节点:
Kubernetes 集群中的一台物理机或者虚拟机。 - 集群:位于
Internet 防火墙后的节点,这是Kubernetes 管理的主要计算资源。 - 边界路由器:为集群强制执行防火墙策略的路由器。这可能是由云提供商或物理硬件管理的网关。
- 集群网络:一组逻辑或物理链接,可根据
Kubernetes 网络模型 实现集群内的通信。集群网络的实现包括Overlay 模型的 flannel 和基于SDN 的OVS 。 - 服务:使用标签选择器标识一组
pod 成为的Kubernetes 服务。除非另有说明,否则服务假定在集群网络内仅可通过虚拟IP 访问。
什么是Ingress ?
通常情况下,
internet
|
------------
[Services]
internet
|
[Ingress]
--|-----|--
[Services]
你可以给
先决条件
在使用
- 你需要一个
Ingress Controller
来实现Ingress
,单纯的创建一个Ingress
没有任何意义。 GCE/GKE 会在master 节点上部署一个ingress controller 。你可以在一个pod 中部署任意个自定义的ingress controller 。你必须正确地注解每个ingress ,比如运行多个ingress controller 和关闭glbc 。- 在非
GCE/GKE 的环境中,你需要在pod 中部署一个controller ,例如 Nginx Ingress Controller。
Ingress 资源
最简化的
1: apiVersion: extensions/v1beta1
2: kind: Ingress
3: metadata:
4: name: test-ingress
5: spec:
6: rules:
7: - http:
8: paths:
9: - path: /testpath
10: backend:
11: serviceName: test
12: servicePort: 80
如果你没有配置
配置说明
apiVersion
,kind
和 metadata
字段。配置文件的详细说明请查看 部署应用,配置容器 和使用资源。
host
配置项(比如path
列表(比如:/testpathbackend
service:port
的组合。
全局参数:为了简单起见,
IngressClass
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb
spec:
controller: example.com/ingress-controller
parameters:
apiGroup: k8s.example.com
kind: IngressParameters
name: external-lb
.spec.parameters
字段可用于引用其他资源以提供额外的相关配置。
参数(parameters
)的具体类型取决于你在 .spec.controller
字段中指定的
IngressClass 的作用域
默认IngressClass
你可以将一个特定的ingressclass.kubernetes.io/is-default-class
注解设置为 true
将确保新的未指定 ingressClassName
字段的
kubernetes.io/ingress.class
注解
在ingressClassName
字段之前,kubernetes.io/ingress.class
注解来指定的。这个注解从未被正式定义过,但是得到了
ingressClassName
配置项是该注解的替代品,但并不完全等价。该注解通常用于引用实现该
Ingress 类型
以下文档描述了
注意
单Service Ingress
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
就是RULE
列表示所有发送给该BACKEND
所列的
简单展开
如前面描述的那样,
foo.bar.com -> 178.91.123.132 -> /foo s1:80
/bar s2:80
你需要一个这样的
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)存在,
基于名称的虚拟主机
foo.bar.com --| |-> foo.bar.com s1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com s2:80
下面这个
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
默认
TLS
你可以通过指定包含tls.crt
和 tls.key
的密钥,这里面包含了用于
apiVersion: v1
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
kind: Secret
metadata:
name: testsecret
namespace: default
type: Opaque
在
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: no-rules-map
spec:
tls:
- secretName: testsecret
backend:
serviceName: s1
servicePort: 80
请注意,各种
还值得注意的是,尽管健康检查不直接通过
更新Ingress
假如你想要向已有的
$ kubectl get ing
NAME RULE BACKEND ADDRESS
test - 178.91.123.132
foo.bar.com
/foo s1:80
$ kubectl edit ing test
这会弹出一个包含已有的
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
..
保存它会更新
$ 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
命令一样可以达到同样的效果。
跨可用域故障
在不同云供应商之间,跨故障域的流量传播技术有所不同。有关详细信息,请查看相关
未来计划
- 多样化的
HTTPS/TLS 模型支持(如SNI ,re-encryption) - 通过声明来请求
IP 或者主机名 - 结合
L4 和L7 Ingress - 更多的
Ingress controller
请跟踪
替代方案
你可以通过很多种方式暴露
- 使用 Service.Type=LoadBalancer
- 使用 Service.Type=NodePort
- 使用 Port Proxy
- 部署一个 Service loadbalancer 这允许你在多个
service 之间共享单个IP ,并通过Service Annotations 实现更高级的负载平衡。