ingress 对象应用案例 ¶
ingress-http 案例 ¶
基于名称的负载均衡
1. 创建 deployment 控制器类型应用 ¶
1. 编辑 nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: ingress-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
2. 应用 nginx.yml 文件
[root@k8smaster001 ingress]# kubectl apply -f nginx.yaml
deployment.apps/nginx created
3. 验证 pod
[root@k8smaster001 ingress]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-rj2rv 0/1 Completed 0 14d
ingress-nginx-admission-patch-84zl9 0/1 Completed 0 14d
ingress-nginx-controller-5458dd5f6-r4k9m 1/1 Running 1 (7d2h ago) 14d
nginx-6555d45fcd-27t8k 1/1 Running 0 15s
nginx-6555d45fcd-5j8jf 1/1 Running 0 15s
2. 创建 service ¶
1. 创建 nginx-service.yml 文件
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: ingress-nginx
labels:
app: nginx
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx
2. 应用 nginx-service.yml 文件
[root@k8smaster001 ingress]# kubectl apply -f nginx-service.yml
service/nginx-service created
3. 验证 service
[root@k8smaster001 ingress]# kubectl get svc nginx-service -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.99.117.76 <none> 80/TCP 69s
3. 创建 ingress 对象 ¶
1. 编写 ingress 规则 资源清单 ingress-nginx.yaml
# 编写 ingress-nginx 规则
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
namespace: ingress-nginx
# saas 前缀区分自己服务与客户服务的区别,jenkins 服务名
spec:
ingressClassName: nginx
rules:
- host: "uri.example.com"
# jenkins 服务名
http:
paths:
- backend:
service:
name: nginx-service
# 需要暴漏的 web服务的 server 名称
port:
number: 80
path: /
pathType: Prefix
2. 创建并查看 ingress 规则
[root@k8smaster001 ingress]# kubectl apply -f ingress-nginx.yaml
ingress.networking.k8s.io/ingress-nginx created
[root@k8smaster001 ingress]# kubectl get ingress -n ingress-nginx
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress nginx uri.example.com 192.168.3.204 80 117s
4. 模拟客户端访问 ¶
1. 准备 pod 内容器运行的 web 主页
[root@k8smaster001 ingress]# kubectl get pods -n ingress-nginx |grep nginx-65
nginx-6555d45fcd-27t8k 1/1 Running 0 128m
nginx-6555d45fcd-5j8jf 1/1 Running 0 128m
[root@k8smaster001 ingress]# kubectl exec -it nginx-6555d45fcd-27t8k -n ingress-nginx -- /bin/sh
/ # echo "ingress web1" > /usr/share/nginx/html/index.html
[root@k8smaster001 ingress]# kubectl exec -it nginx-6555d45fcd-5j8jf -n ingress-nginx -- /bin/sh
/ # echo "ingress web2" > /usr/share/nginx/html/index.html
2. 确认 nginx-ingress-controller 的 pod IP, 下面命令查询的结果为 10.109.138.153
[root@k8smaster002 ~]# kubectl get svc -n ingress-nginx |grep ingress
ingress-nginx-controller NodePort 10.109.138.153 <none> 80:30212/TCP,443:32105/TCP 15d
3. 在集群之外任一主机中添加上述域名与 IP 地址解析(模拟公网DNS)
[root@k8smaster002 ~]# echo "10.109.138.153 uri.example.com" >> /etc/hosts
4. 访问及结果展示
❯ curl uri.example.com
ingress web2
❯ curl uri.example.com
ingress web1
基于 url 的负载均衡 ¶
1. 创建 web1 应用 ¶
1. 编写 web1 的 **Deployment** 资源的资源清单 nginx-uri-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-uri-1
namespace: ingress-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx-uri-1
template:
metadata:
labels:
app: nginx-uri-1
spec:
containers:
- name: c1
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
2. 编写 web1 service 资源的资源清单 nginx-service-uri-1.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service-uri-1
namespace: ingress-nginx
labels:
app: nginx-uri-1
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx-uri-1
3. 创建 deployment 与 service
[root@k8smaster001 ingress]# kubectl apply -f nginx-uri-1.yaml
deployment.apps/nginx-uri-1 created
[root@k8smaster001 ingress]# kubectl apply -f nginx-service-uri-1.yaml
service/nginx-service-uri-1 created
4. 查看 deployment 与 service 是否创建成功
[root@k8smaster001 ingress]# kubectl get pod -n ingress-nginx -owide |grep ur
nginx-uri-1-566bc894c-8pp2h 1/1 Running 0 116s 10.244.87.213 k8sworker001 <none> <none>
nginx-uri-1-566bc894c-bb7pv 1/1 Running 0 116s 10.244.35.54 k8sworker002 <none> <none>
[root@k8smaster001 ingress]# kubectl get svc -n ingress-nginx -owide |grep ur
nginx-service-uri-1 ClusterIP 10.105.135.111 <none> 80/TCP 103s app=nginx-uri-1
2. 创建 web2 应用 ¶
1. 编写 web2 的 **Deployment** 资源的资源清单 nginx-uri-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-uri-2
namespace: ingress-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx-uri-2
template:
metadata:
labels:
app: nginx-uri-2
spec:
containers:
- name: c2
image: nginx:1.15-alpine
imagePullPolicy: IfNotPresent
2. 编写 web2 service 资源的资源清单 nginx-service-uri-2.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service-uri-2
namespace: ingress-nginx
labels:
app: nginx-uri-2
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx-uri-2
3. 创建 deployment 与 service
[root@k8smaster001 ingress]# kubectl apply -f nginx-uri-2.yaml
deployment.apps/nginx-uri-2 created
[root@k8smaster001 ingress]# kubectl apply -f nginx-service-uri-2.yaml
service/nginx-service-uri-2 created
4. 查看 deployment 与 service 是否创建成功
[root@k8smaster001 ingress]# kubectl get pod -n ingress-nginx -owide |grep uri-2
nginx-uri-2-6fcd746f85-7lwb7 1/1 Running 0 28s 10.244.35.29 k8sworker002 <none> <none>
nginx-uri-2-6fcd746f85-fskbs 1/1 Running 0 28s 10.244.87.214 k8sworker001 <none> <none>
[root@k8smaster001 ingress]# kubectl get svc -n ingress-nginx -owide |grep uri-2
nginx-service-uri-2 ClusterIP 10.96.97.105 <none> 80/TCP 35s app=nginx-uri-2
3. 创建 ingress 对象 ¶
1. 编写 ingress 规则 资源清单 ingress-nginx-uri.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-uri
namespace: ingress-nginx
spec:
ingressClassName: nginx
rules:
- host: uri.example.com
http:
paths:
- path: /hello/svc1/
pathType: Prefix
backend:
service:
name: nginx-service-uri-1
port:
number: 80
- path: /hello/svc2/
pathType: Prefix
backend:
service:
name: nginx-service-uri-2
port:
number: 80
2. 应用 YAML 资源清单 ingress-nginx-uri.yaml
[root@k8smaster001 ingress]# kubectl apply -f ingress-nginx-uri.yaml
ingress.networking.k8s.io/ingress-uri created
3. 查看 pod 资源
[root@k8smaster001 ingress]# kubectl get pods -o wide -n ingress-nginx|grep nginx-uri
nginx-uri-1-566bc894c-8pp2h 1/1 Running 0 18m 10.244.87.213 k8sworker001 <none> <none>
nginx-uri-1-566bc894c-bb7pv 1/1 Running 0 18m 10.244.35.54 k8sworker002 <none> <none>
nginx-uri-2-6fcd746f85-7lwb7 1/1 Running 0 14m 10.244.35.29 k8sworker002 <none> <none>
nginx-uri-2-6fcd746f85-fskbs 1/1 Running 0 14m 10.244.87.214 k8sworker001 <none> <none>
4. 验证 ingress
[root@k8smaster001 ingress]# kubectl get ingress -n ingress-nginx
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-uri nginx uri.example.com 192.168.3.204 80 124m
5. 描述查看 ingress 信息
[root@k8smaster001 ingress]# kubectl describe ingress ingress-uri -n ingress-nginx
Name: ingress-uri
Labels: <none>
Namespace: ingress-nginx
Address: 192.168.3.204
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
uri.example.com
/hello/svc1/ nginx-service-uri-1:80 (10.244.35.54:80,10.244.87.213:80)
/hello/svc2/ nginx-service-uri-2:80 (10.244.35.29:80,10.244.87.214:80)
Annotations: <none>
Events: <none>
4. 模拟客户端访问 ¶
1. 确认 nginx-ingress-controller 的 pod IP, 下面命令查询的结果为 10.109.138.153
[root@k8smaster002 ~]# kubectl get svc -n ingress-nginx |grep ingress
ingress-nginx-controller NodePort 10.109.138.153 <none> 80:30212/TCP,443:32105/TCP 15d
2. 在集群之外任一主机中添加上述域名与 IP 地址解析(模拟公网DNS)
[root@k8smaster002 ~]# echo "10.109.138.153 uri.example.com" >> /etc/hosts
3. 查看所有创建的 pod
[root@k8smaster001 ingress]# kubectl get pods -n ingress-nginx |grep nginx-uri
nginx-uri-1-566bc894c-8pp2h 1/1 Running 0 21m
nginx-uri-1-566bc894c-bb7pv 1/1 Running 0 21m
nginx-uri-2-6fcd746f85-7lwb7 1/1 Running 0 16m
nginx-uri-2-6fcd746f85-fskbs 1/1 Running 0 16m
4. 准备 pod 内容器运行的 web 主页
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-8pp2h -n ingress-nginx -- /bin/sh
/ # mkdir /usr/share/nginx/html/hello/svc1 -p
/ # echo "我是 svc1 Pod1" > /usr/share/nginx/html/hello/svc1/index.html
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-bb7pv -n ingress-nginx -- /bin/sh
/ # mkdir /usr/share/nginx/html/hello/svc1 -p
/ # echo "我是 svc1 Pod2" > /usr/share/nginx/html/hello/svc1/index.html
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-7lwb7 -n ingress-nginx -- /bin/sh
/ # mkdir /usr/share/nginx/html/hello/svc2 -p
/ # echo "我是 svc2 Pod1" > /usr/share/nginx/html/hello/svc2/index.html
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-fskbs -n ingress-nginx -- /bin/sh
/ # mkdir /usr/share/nginx/html/hello/svc2 -p
/ # echo "我是 svc2 Pod2" > /usr/share/nginx/html/hello/svc2/index.html
5. 访问及结果展示
[root@k8smaster002 ~]# curl uri.example.com/hello/svc1/index.html
我是 svc1 Pod1
[root@k8smaster002 ~]# curl uri.example.com/hello/svc1/index.html
我是 svc1 Pod2
[root@k8smaster002 ~]# curl uri.example.com/hello/svc2/index.html
我是 svc2 Pod2
[root@k8smaster002 ~]# curl uri.example.com/hello/svc2/index.html
我是 svc2 Pod1
ingress URL Rewrite ¶
rewrite 主要用于地址重写。
名称 | 描述 | 值 |
---|---|---|
nginx.ingress.kubernetes.io/rewrite-target | 必须重定向的目标URL | String |
nginx.ingress.kubernetes.io/ssl-redirect | 指示位置部分是否只能由SSL访问(当Ingress包含证书时,默认为True) | Bool |
nginx.ingress.kubernetes.io/force-ssl-redirect | 即使Ingress没有启用TLS,也强制重定向到HTTPS | Bool |
nginx.ingress.kubernetes.io/app-root | 定义应用程序根目录,Controller在“/”上下文中必须重定向该根目录 | String |
nginx.ingress.kubernetes.io/use-regex | 指示Ingress上定义的路径是否使用正则表达式 | Bool |
1. 编写 ingress 规则 ¶
rewrite.example.com/foo-svc1 -> nginx-service-uri-1:80 -> endpoint(pod1 , pod2 ip) -> web1(pod1 , pod2)。 rewrite.example.com/foo-svc2 -> nginx-service-uri-2:80 -> endpoint(pod1 , pod2 ip) -> web2(pod1 , pod2)。
1. 编写 ingress-nginx-rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-rewrite
namespace: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: "/$1"
spec:
ingressClassName: nginx
rules:
- host: rewrite.example.com
http:
paths:
# ? 表示前面的斜杠字符 / 是可选的。请求路径可以是 /foo-svc1 或者 /foo-svc1/ 后面可以跟任意字符
- path: /foo-svc1/?(.*)
pathType: ImplementationSpecific
backend:
service:
name: nginx-service-uri-1
port:
number: 80
- path: /foo-svc2/?(.*)
pathType: ImplementationSpecific
backend:
service:
name: nginx-service-uri-2
port:
number: 80
2. 应用 YAML 资源清单 ingress-nginx-rewrite.yaml
[root@k8smaster002 rewrite]# kubectl apply -f ingress-nginx-rewrite.yaml
ingress.networking.k8s.io/ingress-nginx-rewrite created
3. 验证 ingress
[root@k8smaster002 rewrite]# kubectl get ingress -n ingress-nginx
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-nginx-rewrite nginx rewrite.example.com 192.168.3.204 80 73s
4. 描述查看 ingress 信息
[root@k8smaster002 rewrite]# kubectl describe ingress ingress-nginx-rewrite -n ingress-nginx
Name: ingress-nginx-rewrite
Labels: <none>
Namespace: ingress-nginx
Address: 192.168.3.204
Ingress Class: nginx
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
rewrite.example.com
/foo-svc1/?(.*) nginx-service-uri-1:80 (10.244.35.54:80,10.244.87.213:80)
/foo-svc2/?(.*) nginx-service-uri-2:80 (10.244.35.29:80,10.244.87.214:80)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Sync 39s (x2 over 97s) nginx-ingress-controller Scheduled for sync
2. 模拟客户端访问 ¶
2. 模拟客户端访问
1. 确认 nginx-ingress-controller 的 pod IP, 下面命令查询的结果为 10.109.138.153
[root@k8smaster002 ~]# kubectl get svc -n ingress-nginx |grep ingress
ingress-nginx-controller NodePort 10.109.138.153 <none> 80:30212/TCP,443:32105/TCP 15d
2. 在集群之外任一主机中添加上述域名与 IP 地址解析(模拟公网DNS)
[root@k8smaster002 ~]# echo "10.109.138.153 rewrite.example.com" >> /etc/hosts
3. 准备 pod 内容器运行的 web 主页
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-8pp2h -n ingress-nginx -- /bin/sh
/ # echo "我是 svc1 Pod1 的主页" > /usr/share/nginx/html/index.html
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-1-566bc894c-bb7pv -n ingress-nginx -- /bin/sh
/ # echo "我是 svc1 Pod2 的主页" > /usr/share/nginx/html/index.html
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-7lwb7 -n ingress-nginx -- /bin/sh
/ # echo "我是 svc2 Pod1 的主页" > /usr/share/nginx/html/index.html
[root@k8smaster001 ingress]# kubectl exec -it nginx-uri-2-6fcd746f85-fskbs -n ingress-nginx -- /bin/sh
/ # echo "我是 svc2 Pod2 的主页" > /usr/share/nginx/html/index.html
4. 访问及结果展示
[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc1
我是 svc1 Pod1 的主页
[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc1
我是 svc1 Pod2 的主页
[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc2
我是 svc2 Pod1 的主页
[root@k8smaster002 rewrite]# curl rewrite.example.com/foo-svc2
我是 svc2 Pod2 的主页
ingress 匹配请求头 ¶
1. 编写 ingress 规则 ¶
开启 server-snippet 功能
1. 发现报错没开放 nginx.ingress.kubernetes.io/contfiguration-snippet 配置
[root@k8smaster002 header]# kubectl apply -f ingress-nginx-header.yaml
\Error from server (BadRequest): error when creating "ingress-nginx-header.yaml": admission webhook "validate.nginx.ingress.kubernetes.io" denied the request: nginx.ingress.kubernetes.io/server-snippet annotation cannot be used. Snippet directives are disabled by the Ingress administrator
2. 修改 ingress-nginx-controller 配置为 true
[root@k8smaster002 header]# kubectl edit cm -n ingress-nginx ingress-nginx-controller
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"allow-snippet-annotations":"false"},"kind":"ConfigMap","metadata":{"annotations":{},"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.10.0"},"name":"ingress-nginx-controller","namespace":"ingress-nginx"}}
creationTimestamp: "2024-03-18T03:04:26Z"
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.10.0
name: ingress-nginx-controller
namespace: ingress-nginx
resourceVersion: "1763166"
uid: 58ef348d-3e35-4e88-ada2-0f9e78f1e7bd
匹配请求头,主要用于根据请求头信息将用户请求转发到不同的应用,比如根据不同的客户端转发请求。
1. 编写 ingress-nginx-header.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-header
namespace: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
set $agentflag 0;
if ($http_user_agent ~* "(iPhone)" ){
set $agentflag 1;
}
if ( $agentflag = 1 ) {
return 301 https://iphone-header.k8s.example.com:60000;
}
spec:
ingressClassName: nginx
rules:
- host: header.k8s.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service-uri-1
port:
number: 80
2. 创建一个 iphone.header.example.com 的 ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-iphoneheader
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
ingressClassName: nginx
rules:
- host: iphone-header.k8s.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service-uri-2
port:
number: 80