K8s学习笔记 (8)
@ wgjak47 | 星期二,七月 30 日,2019 年 | 3 分钟阅读 | 更新于 星期二,七月 30 日,2019 年

k8s学习笔记

Ingress

Ingress是一种管理访问集群内服务的外部流量的对象。 Ingress可以提供URL,负载均衡,SSL以及基于名称的虚拟主机等等功能给集群内的services。 架构图

先觉条件

Ingress Resource

例子:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- http:
# 默认是*
hosts: xxx.com
paths:
- path: /testpath
# 转发请求到对应的service
backend:
serviceName: test
servicePort: 80

Ingress类型

单Ingress

虽然可以通过Service.Type=LoadBalancer或者Service.Type=NodePort来完成,但是仍然可以通过Ingress来实现,通过指定一个没有rule的默认backend的方式。例如:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
backend:
serviceName: testsvc
servicePort: 80

而且通过Ingress可以更加有效的使用loadbalancer,减少资源浪费:

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

上面这个ingress只使用了一个loadbalancer,通过把服务映射到不同path的方式,就完成了原本需要两个loadbalancer才能搞定的工作。

注:同apache/nginx类似,你通过设置一个没有rules的backends作为默认页(一般是404页面)

基于名称的虚拟主机

Ingress也可以像apache/nginx等传统http server一样,提供Name-Based虚拟主机功能,在一个IP下拥有多个主机名,例子:

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私钥和证书的secret来加密Ingress。 目前,Ingress仅支持单个TLS端口443,并假定TLS termination。 如果Ingress中的TLS配置部分指定了不同的主机,则它们将根据通过SNI TLS扩展指定的主机名(假如Ingress controller支持SNI)在多个相同端口上进行复用。 TLS secret中必须包含名为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
----
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: no-rules-map
spec:
tls:
- secretName: testsecret
backend:
serviceName: s1
servicePort: 80

Ingress更新

Ingress更新和其他k8s的object更新类似,例子:

$ 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

代替方案

  • 使用Service.Type=LoadBalancer
  • 使用Service.Type=NodePort
  • 使用Port Proxy
  • 部署一个Service loadbalancer 这允许你在多个service之间共享单个IP,并通过Service Annotations实现更高级的负载平衡。