文章目录
- [K8s Ingress 详解](#K8s Ingress 详解)
K8s Ingress 详解
Ingress 资源清单
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: <string>
namespace: <string>
spec:
ingressClassName: "nginx" # 适配的Ingress控制器
rules: <[]Object> # Ingress 规则列表
- host: <string>
http: <Object>
paths: <[]Object> # 虚拟主机PATH 定义列表,列表由path 和 backend 组成
- path: <string> # 匹配以什么开头,类似nginx 中的location的作用
pathType: <string> # Prefix 前缀匹配,不区分大小写 Exact 精确匹配URL, 区分大小写
backend: <Object>
service: <Object> # 关联的后端Service
name: <string> # 后端Service 的名称
port: <Object> # 后端Service 端口的对象
name: <string> # 端口的名称
number: <integr> # 端口号
Ingress 基于URL 实现路由
注: 同一域名,不同的URL调度到不同的 Service
部署demoapp
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-prod
spec:
replicas: 2
selector:
matchLabels:
app: demoapp
template:
metadata:
labels:
app: demoapp
spec:
containers:
- name: demo
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: app-svc
spec:
type: ClusterIP
selector:
app: demoapp
ports:
- port: 80
targetPort: 80
部署demo tomcat
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-prod
spec:
replicas: 2
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: java
image: tomcat:9.0.6
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
type: ClusterIP
selector:
app: tomcat
ports:
- port: 8080
targetPort: 8080
部署ingress
- 默认URL:用户请求foo.ingress.net/app,代理到后端请求也会带上/app,后端无法处理该UrL,就会报错
- 修改URL:用户请求foo.ingress.net/app,代理到后端后,将请求的/app删除,foo.ingress,net/
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2 # 配置Rewrite规则
spec:
ingressClassName: "nginx"
rules:
- host: foo.ingress.net
http:
paths:
- path: /app(/|$)(.*) # 匹配的URL的第二部分(由第二个括号捕获的部分)作为新的目标路径。
pathType: Prefix
backend:
service:
name: app-svc
port:
number: 80
- path: /java(/|$)(.*)
pathType: Prefix
backend:
service:
name: tomcat-svc
port:
number: 8080
Ingress 基于名称虚拟主机
配置Ingress
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foo-ingress
spec:
ingressClassName: "nginx"
rules:
- host: app.ingress.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-svc
port:
number: 80
- host: java.ingress.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tomcat-svc
port:
number: 8080
Ingress 实现HTTPS
在 Ingress 中引入 Secret 资源,然后告诉 Ingress 控制器使用 TLS 加密从客户端到负载均衡器的通道
创建TLS 证书
sh
# 使用openssl命令充当CA权威机构创建证书(生产不使用此方式生成证书,不被互联网认可的黑户证书)
openssl需要下载
[root@web01 ssl_key]# openssl genrsa -idea -out server.key 2048
Enter pass phrase for server.key: 123456
Verifying - Enter pass phrase for server.key: 123456
[root@web01 ssl_key]# ll
total 4
-rw-r--r--. 1 root root 1739 Dec 9 11:27 server.key
#生成自签证书(公钥),同时去掉私钥的密码
[root@web01 ssl_key]# openssl req -days 36500 -x509 -sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:meiguo
Locality Name (eg, city) [Default City]:riben
Organization Name (eg, company) [Default Company Ltd]:heishoudang
Organizational Unit Name (eg, section) []:oldboy
Common Name (eg, your name or your server's hostname) []:oldboy
Email Address []:123@qq.com
创建Secrets
sh
[root@k8s-master ssl]# kubectl create secret tls java-ingress-tls --key=server.key --cert=server.crt
secret/java-ingress-tls created
配置ingress
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: java-ingress
spec:
ingressClassName: "nginx"
# https
tls:
- hosts:
- java.ingress.net
secretName: "java-ingress-tls"
rules:
- host: java.oldxu.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tomcat-svc
port:
number: 8080
Ingress Rewrite
- Ingress Rewrite:Rancher(一个流行的Kubernetes管理平台)中提供的一项功能,通过改写HTTP请求和响应的URL路径,实现请求重定向、负载均衡以及URL路径的重写。
- 请求重定向:可以将请求导向到不同的后端服务,实现简单的负载均衡。
- URL路径重写:修改请求的URL路径,使其匹配实际需要的后端服务。
上面基于URL实现路由方案中,就应用到了 ingress rewrite 方案,下面示例插入自定义的 Nginx 配置。
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2 # 如果需要基于路径重写,可以使用这个注解,但这里仅作为示例
nginx.ingress.kubernetes.io/configuration-snippet: |
location /old-path/ {
rewrite ^/old-path/(.*)$ /new-path/$1 break;
proxy_pass http://my-app-service;
}
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
Ingress 灰度发布
Ingress 灰度发布就是通过两套ingress 配置同一个域名,来实现
Ingress 灰度发布可以通过三个方式实现,
-
基于Request Header的流量切分
- 使用
nginx.ingress.kubernetes.io/canary-by-header
和nginx.ingress.kubernetes.io/canary-by-header-value
annotations。 - 客户端请求时,根据Request Header的值决定是否将请求路由到灰度版本。
- 使用
-
基于Cookie的流量切分
- 使用
nginx.ingress.kubernetes.io/canary-by-cookie
annotation。 - 根据客户端Cookie的值来决定是否将请求路由到灰度版本。
- 使用
-
基于服务权重的流量切分
- 使用
nginx.ingress.kubernetes.io/canary-weight
annotation。 - 设定灰度版本的权重(0-100%),按权重比例将请求路由到灰度版本。
- 使用
-
流量切分的优先级 header 和 cookie > 权重
生产版本
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demoapp-ingress-prod
spec:
ingressClassName: "nginx"
rules:
- host: "demoapp.ingress.net"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demoapp-prod-svc
port:
number: 80
灰度版本
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demoapp-ingress-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true" # 启动灰度发布
#nginx.ingress.kubernetes.io/canary-by-header: "deploy" # 基于header
#nginx.ingress.kubernetes.io/canary-by-header-value: "new"
#nginx.ingress.kubernetes.io/canary-weight: "30" # 权重 30%流量调度到这个灰度的版本上
nginx.ingress.kubernetes.io/canary-by-cookie: "request_from_wh" # cookie
spec:
ingressClassName: "nginx"
rules:
- host: "demoapp.ingress.net"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demoapp-canary-svc
port:
number: 80
Ingress 配置认证
先生成一个 basic-auth secret ,再引入nginx 就能给 nginx 设置账户密码
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: java-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic # 认证类型
nginx.ingress.kubernetes.io/auth-secret: basic-auth # 包含用户和密码的 secret 资源名称
nginx.ingress.kubernetes.io/auth-realm: 'Please User password' # 要显示的信息
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/configuration-snippet: | # 自定义跳转规则
rewrite ^/docs/(.*)$ /java/docs/$1 redirect;
rewrite ^/manager/(.*)$ /java/manager/$1 redirect;
rewrite ^/examples/(.*)$ /java/examples/$1 redirect;
nginx.ingress.kubernetes.io/server-snippet: |
set $agentflag 0;
if ($http_user_agent ~* "(iPhone|android)" ){
set $agentflag 1;
}
if ( $agentflag = 1 ) {
return 301 http://app.ingress.net;
}
spec:
ingressClassName: "nginx"
rules:
- host: java.ingress.net
http:
paths:
- path: /java(/|$)(.*)
pathType: Prefix
backend:
service:
name: tomcat-svc
port:
number: 8080