Kubernetes v1.19版本开始提供一种更为高级的流量管理方式,尤其是对HTTP/HTTPS的协议的流量管理。Kubernetes使用Ingress控制器作为统一流量入口,管理内部各种服务,并通过Ingress这一API资源来描述如何区分流量以及内部的路由逻辑。
有了Ingress和Ingress控制器,我们就可通过定义路由流量规则来完成服务队外发布,而无需创建一堆NodePort或LoadBalancer类型的Service,且流量由Ingress控制器直接到达Pod对象
Ingress 控制器
为了让Ingress资源定义的规则工作,集群必须有一个正在运行的 Ingress 控制器,本质上,Ingress控制器本身就是一类以HTTP/HTTPS代理程序,需要单独部署,常用有Nginx Ingress 、AWS、和GCE
- 部署Nginx Ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/baremetal/deploy.yaml
k8s.gcr.io 项目的镜像需要特殊处理,比如代理或者镜像,注意版本匹配情况
-
Ingress 类
上面的yaml里面自带Ingress类定义apiVersion: networking.k8s.io/v1 kind: IngressClass metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: ingress-nginx app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.1.3 name: nginx spec: controller: k8s.io/ingress-nginx
Ingress
有了Ingress 控制器,就可以通过Ingress资源API定义规则, Ingress有两个版本extensions/v1beta1
和networking.k8s.io/v1
, 以下例子以新版本networking.k8s.io/v1
为例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
spec:
ingressClassName: nginx #指定Ingress 类
defaultBackend: #默认后端路由
service:
name: test
port:
number: 80
rules:
- host: "foo.bar.com" #主机精确匹配
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
- host: "*.foo.com" #通配符匹配,bar.foo.com匹配,test.bar.foo.com不匹配
http:
paths:
- pathType: Prefix #以 / 分隔的 URL 路径前缀匹配,匹配区分大小写(必填)
path: "/foo"
backend:
service:
name: service2
port:
number: 80
路径类型
- Exact:精确匹配 URL 路径,且区分大小写。
- Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写
- ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。
例子:
类型 | 路径 | 请求路径 | 匹配与否 |
---|---|---|---|
Prefix | / | (所有路径) | 是 |
Prefix | /foo | /foo, /foo/ | 是 |
Prefix | /foo/ | /foo,/foo/ | 是 |
Prefix | /foo | /foo/abc | 是,匹配子路径 |
Prefix | /foo | /fooo | 否 |
Exact | /foo | /foo/ | 否 |
Exact | /foo/ | /foo | 否 |
多重匹配优先级
如果Ingress 中的多条路径会匹配同一个请求,最长的匹配路径优先。 如果仍然有两条同等的匹配路径,则精确路径类型优先于前缀路径类型
TLS
可以通过TLS保护Ingress, 本质上就是ingres 控制器上配置https,如果是nginx ingress, 就相当于nginx 配置https。
- 1.通过secret定义证书
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 编码的证书
tls.key: base64 编码的私钥
type: kubernetes.io/tls
- Ingress 上指定secret
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
spec:
tls:
- hosts:
- https-example.foo.com
secretName: testsecret-tls
rules:
- host: https-example.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
跨名字空间访问
Ingress 资源定义backend 服务默认都是跟Ingress资源同一命名空间,如果要实现访问其他命名空间的Service,可以使用ExternalName
类型的服务
- 假设my-service 是在test 空间,Ingress 在ingress空间
1.在Ingress空间下创建service
apiVersion: v1
kind: Service
metadata:
name: my-service-external
namespace: ingress
spec:
type: ExternalName
externalName: my-service.test
2.Ingress 指定my-service-external
···
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: my-service-external #关联同命名空间服务
port:
number: 80
···
当查找主机
my-service-external
时,集群 DNS 服务返回 CNAME 记录, 其值为my-service.test
。 访问 my-service 的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发
Ingress 类
- 默认Ingress类
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
name: nginx-example
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
当有定义默认Ingress类,定义Ingress资源可以无需指定
ingressClassName
, 默认选用默认Ingress类
官网地址:https://kubernetes.github.io/ingress-nginx/deploy/
Github:https://github.com/kubernetes/ingress-nginx
Yaml文件:https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/baremetal/deploy.yaml