准备环境:两个Service(demoapp10和demoapp11)
部署demoapp v1.0
kubectl create deployment demoapp10 --image=ikubernetes/demoapp:v1.0 --replicas=5
kubectl create service clusterip demoapp10 --tcp=80:80
部署demoapp v1.1
kubectl create deployment demoapp11 --image=ikubernetes/demoapp:v1.1 --replicas=2
kubectl create service clusterip demoapp11 --tcp=80:80
需求 将demoapp v1.1 demoapp v1.0两个应用发布出去 使用同一个主机名
Ingress资源配置示例—创建Ingress
示例 Simple fanout 简单扇出
基于URI方式代理不同应用的请求时,后端应用的URI若与代理时使用的URI不同,则需要启用URL Rewrite完成URI的重写
Ingress-Nginx支持使用“annotation nginx.ingress.kubernetes.io/rewrite-target”注解进行
示例1
对于发往demoapp.magedu.com的请求
- 将“/v10”代理至service/demoapp10
- 将“/v11”代理至service/demoapp11
kubectl create ingress demo --rule="demoapp.magedu.com/v10=demoapp10:80" --rule="demoapp.magedu.com/v11=demoapp11:80" --class=nginx --annotation nginx.ingress.kubernetes.io/rewrite-target="/"
参数解释:
--class=nginx kubernets允许同时部署多个ingress-controller 需要明确指明用哪个作为负载均衡
--annotation nginx.ingress.kubernetes.io/rewrite-target="/" 注解信息
配置 demoapp.magedu.com 的域名解析
测试访问
curl demoapp.magedu.com:30635/v10
匹配方式改成 前缀
功能同上,但使用URI的前缀匹配,而非精确匹配,且基于正则表达式模式进行url rewrite
kubectl create ingress demo --rule='demoapp.magedu.com/v10(/|$)(.*)=demoapp10:80' --rule='demoapp.magedu.com/v11(/|$)(.*)=demoapp11:80' --class=nginx --annotation nginx.ingress.kubernetes.io/rewrite-target='/$2'
示例 Name based virtual hosting 基于主机名
基于FQDN名称代理不同应用的请求时,需要事先准备好多个域名,且确保对这些域名的解析能够到达Ingress Controller
需求:
- 对demoapp10.magedu.com的请求代理至service/demoapp10
- 对demoapp11.magedu.com请求代理至service/demoapp11
kubectl create ingress demoapp --rule="demoapp10.magedu.com/*=demoapp10:80" --rule="demoapp11.magedu.com/*=demoapp11:80" --class=nginx
测试
TLS
基于TLS的Ingress要求事先准备好专用的“kubernetes.io/tls”类型的Secret对象
step1 创建私钥
umask 077;
openssl genrsa -out magedu.key 2048
step2 创建证书 绑定主机名demoapp10.magedu.com
openssl req -new -x509 -key magedu.key -out magedu.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=demoapp10.magedu.com
step3 创建tls类型的secret
kubectl create secret tls tls-magedu --cert=./magedu.crt --key=./magedu.key
step4 创建常规的虚拟主机代理规则,同时将该主机定义为TLS类型
kubectl create ingress tls-demo --rule='demoapp10.magedu.com/*=demoapp10:80,tls=tls-magedu' --class=nginx
注意:启用tls后,该域名下的所有URI默认为强制将http请求跳转至https,若不希望使用该功能,可以使用如下注解选项
--annotation nginx.ingress.kubernetes.io/ssl-redirect=false
Ingress资源规范
Ingress资源规范的v1版本隶属于“networking.k8s.io”群组
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: null
name: demoapp
spec:
ingressClassName: nginx
rules:
- host: demoapp10.magedu.com
http:
paths:
- backend:
service:
name: demoapp10
port:
number: 80
path: /
pathType: Prefix
- host: demoapp11.magedu.com
http:
paths:
- backend:
service:
name: demoapp11
port:
number: 80
path: /
pathType: Prefix
status:
loadBalancer: {}
基于Ingress Nginx的灰度发布
Ingress-Nginx支持配置Ingress Annotations来实现不同场景下的灰度发布和测试,它能够满足金丝雀发布、蓝绿部署与A/B测试等不 同的业务场景
基于Ingress Nginx的Canary规则
Ingress Nginx Annotations支持的Canary规则
-
nginx.ingress.kubernetes.io/canary-by-header:基于该Annotation中指定Request Header进行流量切分,适用于灰度发布以及A/B测试
- 在请求报文中,若存在该Header且其值为always时,请求将会被发送到Canary版本
- 若存在该Header且其值为never时,请求将不会被发送至Canary版本
- 对于任何其它值,将忽略该Annotation指定的Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较
-
nginx.ingress.kubernetes.io/canary-by-header-value:基于该Annotation中指定的Request Header的值进行流量切分,标头名称则由前一个Annotation (nginx.ingress.kubernetes.io/canary-by-header)进行指定
- 请求报文中存在指定的标头,且其值与该Annotation的值匹配时,它将被路由到Canary版本
- 对于任何其它值,将忽略该Annotation
-
nginx.ingress.kubernetes.io/canary-by-header-pattern
-
同canary-by-header-value的功能类似,但该Annotation基于正则表达式匹配Request Header的值
-
若该Annotation与canary-by-header-value同时存在,则该Annotation会被忽略
-
-
nginx.ingress.kubernetes.io/canary-weight:基于服务权重进行流量切分,适用于蓝绿部署,权重范围0 - 100按百分比将请求路由到Canary Ingress中 指定的服务
- 权重为 0 意味着该金丝雀规则不会向Canary入口的服务发送任何请求
- 权重为100意味着所有请求都将被发送到 Canary 入
-
nginx.ingress.kubernetes.io/canary-by-cookie:基于 cookie 的流量切分,适用于灰度发布与 A/B 测试
- cookie的值设置为always时,它将被路由到Canary入口
- cookie的值设置为 never时,请求不会被发送到Canary入口
- 对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较
规则的应用次序
- Canary规则会按特定的次序进行评估
- 次序:canary-by-header -> canary-by-cookie -> canary-weight
示例 基于标头的金丝雀发布
示例 基于权重的金丝雀发布
问题思考
只有一个工网IP 如何将内网的多个service对外暴露 方法1 绑定loadbalance 绑定fqdn主机名 使用7层负载均衡