Kubernetes之Ingress-Nginx详细讲解&部署
1. Ingress-nginx
1.1 ingress-nginx是什么?
它是 Kubernetes 的官方入口网关,用 NGINX 实现七层(HTTP/HTTPS)流量管理,自动将域名和路径路由到集群内不同服务。
核心功能
- 统一入口
- 通过单个IP+端口(80/443)暴露所有HTTP服务,替代多个
NodePort/LoadBalancer。
- 通过单个IP+端口(80/443)暴露所有HTTP服务,替代多个
- 智能路由
- 根据 域名(
Host)和 路径(Path)转发请求到后端Service。
- 根据 域名(
- 自动化
- 监听K8s API,动态更新NGINX配置,无需手动重启。
解决了什么问题?
- 痛点:直接用Service的
NodePort或LoadBalancer时:- ❌ 无法基于域名路由
- ❌ 需维护多个IP/端口
- ❌ 手动管理TLS证书
- 方案:Ingress-NGINX 通过声明式配置(YAML)一键搞定。
1.2 为什么引入Ingress?
我们说k8s 的服务(service)时,说暴露了service的三种方式ClusterIP、NodePort与LoadBalance,这几种方式都是在service的维度提供的,service的作用体现在两个方面,对集群内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制,对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。但是,单独用service暴露服务的方式,在实际生产环境中不太合适:
-
ClusterIP的方式只能在集群内部访问。
-
NodePort方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理是灾难。
-
LoadBalance方式受限于云平台,且通常在云平台部署ELB还需要额外的费用。
所幸k8s还提供了一种集群维度暴露服务的方式,也就是ingress。ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。
service通过iptables、ipvs实现。有缺陷:每一组业务都要开启nodePort,这样nodePort越来越多越来越难管理
解决方案:多加一层管理庞大的service
- 本来nodePort是映射到Service的,现在在往上抽一层,映射到上层,由上层再分发到service,此方案Ingress实现了
- 而Ingress是K8S中的资源,接口,可以由不同的控制器实现
- Ingress-nginx是其中的一种实现,是对nginx的二次开发,来满足Ingress的规范ingress-nginx官方讲解

1.3 基于Helm部署ingress-nginx
官方地址: https://github.com/kubernetes/ingress-nginx
确保自己的harbor仓库有这两个镜像,可以在国内的渡渡鸟镜像网站里下载
- 控制器镜像(controller):Ingress-Nginx 的核心组件,负责监听 Kubernetes API 并根据 Ingress 规则配置负载均衡器。它处理所有进入集群的 HTTP/HTTPS 流量,并将请求路由到对应的 Service。
- kube-webhook-certgen 镜像(可选):用于自动生成和管理 Ingress-Nginx 的 admission webhook 所需的 TLS 证书。如果启用了 webhook 验证功能(默认启用),则需要此镜像。

[root@master 7.6]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
[root@master 7.6]# helm pull ingress-nginx/ingress-nginx
[root@master 7.6]# ls
ingress-nginx-4.12.3.tgz
[root@master 7.6]# tar -xf ingress-nginx-4.12.3.tgz
[root@master 7.6]# ls
ingress-nginx ingress-nginx-4.12.3.tgz
# 修改values.yaml文件
1- 修改global.image.registry=harbor:443
2- 修改image的拉取地方为harbor仓库里的镜像,tag也是
3- 修改 hostNetwork 的值为 true ,共享宿主机网络
4- dnsPolicy的值改为: clusterFirstWithHostNet
5- kind类型更改为:DaemonSet,启冗余作用
6- 关闭所有镜像的 digest
7- ingressClassResource.default=true
# 创建一个名称空间为ingress
[root@master 7.6]# kubectl create ns ingress
# 部署ingress-nginx
[root@master 7.6]# helm install ingress-nginx -f ingress-nginx/values.yaml -n ingress ingress-nginx/
# 查看pod状态,为running就部署成功!
[root@master 7.6]# kubectl get pods -n ingress -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-controller-8lsvd 1/1 Running 0 3m37s 192.168.10.12 node02 <none> <none>
ingress-nginx-controller-hhzmz 1/1 Running 0 3m37s 192.168.10.13 node03 <none> <none>
ingress-nginx-controller-lqxlj 1/1 Running 0 3m37s 192.168.10.11 node01 <none>
1.4 Ingress HTTP 代理访问
[root@master 7.6]# vim 1.ingress_http.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: ingress-http-www1
spec:
replicas: 2
selector:
matchLabels:
hostname: www1
template:
metadata:
labels:
hostname: www1
spec:
containers:
- name: web
image: myos:httpd
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: ingress-http-www1
spec:
ports:
- port: 80
targetPort: 80
selector:
hostname: www1
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: ingress-http-www1
spec:
ingressClassName: nginx # 关联到ingress-nginx控制器
rules: # ingress规则定义
- host: www1.zkbr.com # 定义域名
http: # 使用的协议
paths: # 定义访问的路径
- path: / # 访问的url路径
pathType: Prefix # 路径的类型(Exact、Prefix)
backend: # 定义后端服务
service: # 声明svc
name: ingress-http-www1 # svc的名称
port: # 声明端口号
number: 80 # 访问服务的端口号
[root@master 7.6]# kubectl apply -f 1.ingress_http.yaml
[root@master 7.6]# kubectl get pods
NAME READY STATUS RESTARTS AGE
ingress-http-www1-c8bd7b98-6pptq 1/1 Running 0 5s
ingress-http-www1-c8bd7b98-r9zg4 1/1 Running 0 6s
[root@master 7.6]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-http-www1 ClusterIP 10.245.44.237 <none> 80/TCP 15s
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 67d
[root@master 7.6]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-http-www1 nginx www1.zkbr.com 80 19s
测试环境要配置host域名解析


访问域名,ingress会根据定义的规则来调用后端的svc响应
# hostNetwork 模式的访问链路
用户 → DNS 解析 → 宿主机 IP:80/443(直接绑定 ingress-nginx-controller Pod) → Nginx 匹配 Ingress 规则 → 转发到后端 Service → 后端 Pod → 响应返回给用户

1.4.1 基于ingress-nginx创建多虚拟主机的访问
[root@master 7.6]# vim 2.ingress_http.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: ingress-http-www2
spec:
replicas: 2
selector:
matchLabels:
hostname: www2
template:
metadata:
labels:
hostname: www2
spec:
containers:
- name: web
image: myos:httpd
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: ingress-http-www2
spec:
ports:
- port: 80
targetPort: 80
selector:
hostname: www2
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: ingress-http-www2
spec:
ingressClassName: nginx
rules:
- host: www2.zkbr.com # 也可以创建多个host来实现多虚拟主机(推荐)
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-http-www2
port:
number: 80
[root@master 7.6]# kubectl apply -f 2.ingress_http.yaml
[root@master 7.6]# kubectl get pods
NAME READY STATUS RESTARTS AGE
ingress-http-www1-c8bd7b98-6pptq 1/1 Running 0 30m
ingress-http-www1-c8bd7b98-r9zg4 1/1 Running 0 30m
ingress-http-www2-786b6bcd67-h2gnx 1/1 Running 0 10s
ingress-http-www2-786b6bcd67-jxmpj 1/1 Running 0 10s
[root@master 7.6]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-http-www1 ClusterIP 10.245.44.237 <none> 80/TCP 34m
ingress-http-www2 ClusterIP 10.245.60.88 <none> 80/TCP 3m50s
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 67d
[root@master 7.6]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-http-www1 nginx www1.zkbr.com 80 34m
ingress-http-www2 nginx www2.zkbr.com 80 3m54s
添加解析记录

访问www2.zkbr.com/info.php

1.5 Ingress HTTPS 代理访问
# 生成测试环境中的私钥和证书,生产环境中肯定是要去购买
[root@master 7.7]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
Generating a RSA private key
..............+++++
...................................+++++
writing new private key to 'tls.key'
-----
[root@master 7.7]# ls
tls.crt tls.key
# 创建tls类型的secret,并指定私钥和证书
[root@master 7.7]# kubectl create secret tls ingress-nginx-tls --key tls.key --cert tls.crt
# 编写资源清单文件
[root@master 7.7]# vim 1.ingress-nginx-https.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-http-ssl
spec:
replicas: 2
selector:
matchLabels:
app: ingress-http-ssl
template:
metadata:
labels:
app: ingress-http-ssl
spec:
containers:
- image: myos:httpd
name: myos
---
apiVersion: v1
kind: Service
metadata:
name: ingress-http-ssl
spec:
ports:
- port: 80
targetPort: 80
selector:
app: ingress-http-ssl
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: ingress-http-ssl
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true" # 强制 HTTPS 重定向,将所有 HTTP 请求(端口 80)重定向到 HTTPS(端口 443)
spec:
ingressClassName: nginx
tls:
- hosts:
- ssl.zkbr.com
secretName: ingress-nginx-tls
rules:
- host: ssl.zkbr.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-http-ssl
port:
number: 80
[root@master 7.7]# kubectl apply -f 1.ingress-nginx-https.yaml
[root@master 7.7]# kubectl get pods
NAME READY STATUS RESTARTS AGE
ingress-http-ssl-678cf7dcf6-29p2b 1/1 Running 0 6m6s
ingress-http-ssl-678cf7dcf6-wc87h 1/1 Running 0 6m6s
ingress-http-www1-c8bd7b98-6pptq 1/1 Running 1 (12h ago) 24h
ingress-http-www1-c8bd7b98-r9zg4 1/1 Running 1 (12h ago) 24h
ingress-http-www2-786b6bcd67-h2gnx 1/1 Running 1 (12h ago) 24h
ingress-http-www2-786b6bcd67-jxmpj 1/1 Running 1 (12h ago) 24h
[root@master 7.7]# kubectl get svc,ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-http-ssl ClusterIP 10.245.100.178 <none> 80/TCP 6m29s
service/ingress-http-www1 ClusterIP 10.245.44.237 <none> 80/TCP 24h
service/ingress-http-www2 ClusterIP 10.245.60.88 <none> 80/TCP 24h
service/kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 68d
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/ingress-http-ssl nginx ssl.zkbr.com 80, 443 6m29s
ingress.networking.k8s.io/ingress-http-www1 nginx www1.zkbr.com 80 24h
ingress.networking.k8s.io/ingress-http-www2 nginx www2.zkbr.com 80 24h
测试环境添加域名解析记录


1.6 Ingress basicAuth 代理
[root@master 7.7]# dnf -y install httpd-tools
[root@master 7.7]# htpasswd -c auth hehe
# 添加用户
[root@master 7.7]# htpasswd auth lili
[root@master 7.7]# cat auth
hehe:$apr1$.qikKmFZ$9sbloDIxooQ20Phrd0.pu/
lili:$apr1$H8rRr66e$6dDOrWsGERrQhcrDXpgt80
[root@master 7.7]# kubectl create secret generic ingress-basic-auth --from-file=auth
[root@master 7.7]# vim 2.ingress-nginx-auth.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ingress-http-auth
spec:
replicas: 2
selector:
matchLabels:
app: ingress-http-auth
template:
metadata:
labels:
app: ingress-http-auth
spec:
containers:
- image: myos:httpd
name: myos
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: ingress-http-auth
spec:
ports:
- port: 80
targetPort: 80
selector:
app: ingress-http-auth
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-http-auth
annotations: # 添加释文
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: ingress-basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Admin Area'
spec:
ingressClassName: nginx
rules:
- host: auth.zkbr.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: ingress-http-auth
port:
number: 80
tls:
- hosts:
- auth.zkbr.com
secretName: ingress-nginx-tls
[root@master 7.7]# kubectl apply -f 2.ingress-nginx-auth.yaml
[root@master 7.7]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-http-auth nginx auth.zkbr.com 80, 443 6m59s
ingress-http-ssl nginx ssl.zkbr.com 80, 443 44h
ingress-http-www1 nginx www1.zkbr.com 80 2d20h
ingress-http-www2 nginx www2.zkbr.com 80 2d20h
测试环境添加解析记录


1.7 Ingress-nginx 域名重定向
Redirect(重定向):
- 作用:重定向是指服务器向客户端发出一个新的URL,让客户端进行新的请求。客户端会收到一个HTTP3xx状态码,然后根据其中的重定向地址进行新的请求。这意味着客户端会知道发生了重定向,客户端的地址栏也会变成重定向的地址,它会发起新的请求
- 示例:比如你有一个网站的旧地址是http://example.com,但是你希望所有的请求都转发到https://example.com,这时你就可以使用重定向将所有的HTTP请求重定向到HTTPS
[root@master 7.9]# vim 1.ingress-redirect.yaml
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: ingress-redirect
annotations:
# 设置301永久重定向
nginx.ingress.kubernetes.io/permanent-redirect: https://www.jd.com
spec:
ingressClassName: nginx
rules:
- host: redirect.zkbr.com
http: # 因为我们要把整个域名重定向到京东,所以下面就不用定义访问路径了
测试效果
[root@master 7.9]# echo "192.168.10.13 redirect.zkbr.com" >> /etc/hosts
[root@master 7.9]# curl -I redirect.zkbr.com
HTTP/1.1 301 Moved Permanently
Date: Wed, 09 Jul 2025 10:35:54 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://www.jd.com # 被301重定向到了jd


1.8 Ingress-nginx 地址重写
Rewrite (重写)
- 作用:重写是指修改请求的路径,但是客户端不会察觉到这个变化,它仅在服务器内部发生。在Kubernetes 中,可以通过Ingress 的注解来配置重写规则
- 示例:比如你有一个服务部署在/v1路径下,但是你希望用户访问时不需要输入/v1,那么你可以使用重写将请求从根路径/重写到/v1
[root@master 7.9]# vim 2.ingress-rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-rewrite
annotations:
# 启用URL重写功能
nginx.ingress.kubernetes.io/rewrite-target: /info.$1
# 启用正则表达式匹配
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: nginx
rules:
- host: rewrite.zkbr.com
http:
paths:
- path: /test.(.*)
pathType: ImplementationSpecific
backend:
service:
name: ingress-http-www1 # 请求被该svc响应
port:
number: 80
测试环境添加域名解析


1.9 Ingress-nginx 自定义错误页
[root@master 7.10]# vim 1.ingress-error.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: ingress-error
spec:
replicas: 2
selector:
matchLabels:
name: error
template:
metadata:
labels:
name: error
spec:
containers:
- name: test
image: library/errorweb:v1.0 # 该镜像是我提前下载到我的harbor仓库中的,使用的是汪洋老师的镜像
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: ingress-error
spec:
selector:
name: error
ports:
- port: 80
targetPort: 80
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: ingress-error
annotations:
# 指定需要自定义的错误码
nginx.ingress.kubernetes.io/custom-http-errors: "404,500"
# 将错误请求转发到后端的svc来响应
nginx.ingress.kubernetes.io/default-backend: "ingress-error"
spec:
rules:
- host: error.zkbr.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-http-www1 # 该svc,是之前定义的svc
port:
number: 80
[root@master 7.10]# kubectl apppl -f 1.ingress-error.yaml
[root@master 7.10]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-error nginx error.zkbr.com 80 15m
ingress-http-auth nginx auth.zkbr.com 80, 443 28h
ingress-http-ssl nginx ssl.zkbr.com 80, 443 3d
ingress-http-www1 nginx www1.zkbr.com 80 4d1h
ingress-http-www2 nginx www2.zkbr.com 80 4d
ingress-redirect nginx redirect.zkbr.com 80 27h
ingress-rewrite nginx rewrite.zkbr.com 80 26h
测试环境添加域名解析记录



1.10 Ingress-nginx snippet 自定义配置片段
在 Ingress-nginx 中,snippet 通常指的是通过注解(Annotations)向 Nginx 配置注入的自定义配置片段。下面从其作用、使用方式、优势与风险等方面详细介绍:
1.10.1 作用
Ingress-nginx 作为 Kubernetes 中常用的 Ingress 控制器,负责将外部流量路由到集群内的服务上。尽管它提供了丰富的默认配置和参数,但在一些复杂场景下,默认配置无法满足需求。这时,snippet 就派上用场了,它允许用户灵活地自定义 Nginx 的配置,从而实现更精细的流量控制、安全策略、性能优化等功能 。例如:
- 自定义重定向:根据请求的来源、客户端类型等条件,设置特定的重定向规则。
- 添加自定义 HTTP 头:在响应中添加自定义的 HTTP 头部信息,用于实现特定的业务逻辑或安全策略。
- 配置缓存策略:对某些资源设置缓存规则,提高响应速度。
1.10.2 优势与风险
- 优势:极大地增强了
Ingress-nginx的灵活性和扩展性,能满足多样化的业务需求,而无需修改Ingress-nginx的代码或重新部署。 - 风险:直接修改 Nginx 配置存在一定的安全风险,如果配置不当,可能会导致服务不可用、安全漏洞等问题。因此,默认情况下,
Ingress-nginx禁止通过注解注入配置片段,需要在Ingress-nginx的 ConfigMap 中设置allow-snippet-annotations: "true"来开启该功能,并且在使用时需要严格测试和审核配置内容 。
1.10.3开启注解注入配置片段的权限
当allow-snippet-annotations参数设为 true 时,用户可以在 Ingress 资源的 annotations 中使用以下特殊注解,直接注入 Nginx 配置片段:
nginx.ingress.kubernetes.io/configuration-snippet:注入到 Nginx 服务器(server)块的配置中(适用于路由级别的自定义,如重定向、缓存策略等)。nginx.ingress.kubernetes.io/server-snippet:注入到 Nginx 全局http块的配置中(适用于全局级别的自定义,如日志格式、全局变量等)。nginx.ingress.kubernetes.io/location-snippet:注入到 Nginx location 块的配置中(适用于特定路径的细节配置)。
# 开启自定义配置片段功能
[root@master 8.10]# kubectl edit -n ingress cm ingress-nginx-controller
data:
allow-snippet-annotations: "true"
[root@master 8.10]# vim snippet.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: snippet
spec:
replicas: 1
selector:
matchLabels:
app: snippet
template:
metadata:
labels:
app: snippet
spec:
containers:
- name: test
image: myos:httpd
---
kind: Service
apiVersion: v1
metadata:
name: snippet
spec:
ports:
- name: 80-80
port: 80
targetPort: 80
protocol: TCP
selector:
app: snippet
type: ClusterIP
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: snippet.zkbr.com
annotations:
# 配置全局变量和地址重定向
nginx.ingress.kubernetes.io/server-snippet: |
set $agentflag 0;
if ($http_user_agent ~* "(Firefox)") {
set $agentflag 1;
}
if ($agentflag = 1){
# 如果用户使用Firefox浏览器访问,那么会临时重定向到百度
return 302 http://www.baidu.com;
break;
}
if ($http_user_agent ~* "(chrome)") {
set $agentflag 2;
}
if ($agentflag = 2){
# 如果用户使用chrome浏览器访问,那么会临时重定向到京东
return 302 http://www.jd.com;
break;
}
spec:
rules:
- host: snippet.zkbr.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: snippet
port:
number: 80
[root@master 8.10]# kubectl apply -f snippet.yaml
验证
# 添加解析记录
[root@master 8.10]# echo "192.168.10.12 snippet.zkbr.com" >> /etc/hosts
[root@master 8.10]# curl snippet.zkbr.com -H 'User-Agent: chrome' -I
HTTP/1.1 302 Moved Temporarily # 使用的是302临时重定向
Date: Sun, 10 Aug 2025 09:35:43 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
Location: http://www.jd.com # 被重定向到了京东
[root@master 8.10]# curl snippet.zkbr.com -H 'User-Agent: Firefox' -I
HTTP/1.1 302 Moved Temporarily # 使用的是302临时重定向
Date: Sun, 10 Aug 2025 09:36:12 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
Location: http://www.baidu.com # 被重定向到了百度
[root@master 8.10]# curl snippet.zkbr.com -I
HTTP/1.1 200 OK # 核心状态码:请求成功处理
Date: Sun, 10 Aug 2025 09:36:18 GMT # 服务器处理时间
Content-Type: text/html; charset=UTF-8 # 响应体是 HTML 文本(UTF-8 编码)
Content-Length: 23 # 响应体大小为 23 字节
Connection: keep-alive # 保持长连接
Last-Modified: Mon, 16 Jan 2023 04:21:54 GMT # 资源最后修改时间
ETag: "17-5f259ec4c7c80" # 资源唯一标识(用于缓存验证)
Accept-Ranges: bytes # 服务器支持断点续传(按字节范围请求
1.11 Ingress-nginx 配置黑白名单
1.11.1 配置方案
- Annotations:只对指定的ingress生效
- ConfigMap:全局生效
- 若是同时配置了Annotations和configmap,一般都是annotations 生效,configmap不生效,因为annotations优先级比configmap高
1.11.2 黑白名单概念
- 白名单:仅允许指定 IP 地址(或 IP 段)访问后端服务,其他 IP 被拒绝。
- 黑名单:拒绝指定 IP 地址(或 IP 段)访问,其他 IP 被允许。
1.11.3 配置方案建议
- 黑名单建议使用ConfigMap去配置
- 白名单建议使用Annotations去配置
1.11.4 Configmap 添加黑名单
[root@master 8.10]# kubectl edit -n ingress cm ingress-nginx-controller
data:
allow-snippet-annotations: "true"
# 添加黑名单
block-cidrs: 192.168.10.12
# 用之前部署的ingress做实验
[root@master 8.10]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-error nginx error.zkbr.com 80 30d
ingress-http-auth nginx auth.zkbr.com 80, 443 32d
ingress-http-ssl nginx ssl.zkbr.com 80, 443 33d
ingress-http-www1 nginx www1.zkbr.com 80 34d
ingress-http-www2 nginx www2.zkbr.com 80 34d
ingress-redirect nginx redirect.zkbr.com 80 32d
ingress-rewrite nginx rewrite.zkbr.com 80 31d
snippet.zkbr.com nginx snippet.zkbr.com 80 107m
[root@master 8.10]# echo "192.168.10.12 www1.zkbr.com" >> /etc/hosts
[root@master 8.10]# curl www1.zkbr.com
Welcome to The Apache.
# 用node01(192.168.10.11)访问,能访问
[root@node01 ~]# echo "192.168.10.13 www1.zkbr.com" >> /etc/hosts
[root@node01 ~]# curl www1.zkbr.com
Welcome to The Apache.
# 用node03(192.168.10.13)访问,不能访问,权限被拒绝
[root@node03 ~]# echo "192.168.10.12 www1.zkbr.com" >> /etc/hosts
[root@node03 ~]# curl www1.zkbr.com
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
1.11.5 Annotations 添加白名单
[root@master 8.10]# vim white.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: white-deploy
spec:
replicas: 1
selector:
matchLabels:
app: white
template:
metadata:
labels:
app: white
spec:
containers:
- image: myos:httpd
name: myapp
---
apiVersion: v1
kind: Service
metadata:
labels:
app: white
name: white-svc
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: white
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# 配置白名单IP,这了就192.168.10.13一个IP
nginx.ingress.kubernetes.io/whitelist-source-range: 192.168.10.13
name: white-zkbr-com
labels:
app: white
spec:
rules:
- host: white.zkbr.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: white-svc
port:
number: 80
[root@master 8.10]# kubectl apply -f white.yaml
[root@master 8.10]# echo "192.168.10.12 white.zkbr.com" >> /etc/hosts
# 访问失败,因为我们配置了白名单,只能192.168.10.13能访问
[root@master 8.10]# curl white.zkbr.com
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
# 访问失败,因为我们配置了白名单,只能192.168.10.13能访问
[root@node01 ~]# echo "192.168.10.12 white.zkbr.com" >> /etc/hosts
[root@node01 ~]# curl white.zkbr.com
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
==========================================================
# 访问成功,因为node03的IP是192.168.10.13
# 同时我们也证明了一点,当configmap和Annotations同时配置的时候,configmap是不生效的,因为Annotations优先级高,即生效。
[root@node03 ~]# echo "192.168.10.12 white.zkbr.com" >> /etc/hosts
[root@node03 ~]# curl white.zkbr.com
Welcome to The Apache.
1.12 Ingress-nginx 金丝雀部署和灰度发布
在 Kubernetes(K8s)中,金丝雀部署(Canary Deployment) 和灰度发布(Gray Release) 是两种常用的渐进式发布策略,用于在生产环境中安全地验证新版本应用的稳定性。Ingress 作为 K8s 中管理外部流量入口的 API 对象,可通过 Ingress 控制器(如 Nginx Ingress、Traefik 等)的扩展能力实现这两种策略,核心是通过精细化的流量规则将部分流量导向新版本,逐步扩大范围直至全量切换。
1.12.1 核心概念
- 金丝雀部署:通常基于流量比例(如 10%、30%、50%)将部分流量路由到新版本,验证无误后逐步提高比例,最终全量切换。
- 灰度发布:更强调精准的用户 / 场景筛选(如按用户 ID、地域、浏览器类型等),仅让特定群体访问新版本,验证通过后分批扩大覆盖范围。
1.12.2 金丝雀部署示例:
这里我们是把业务web服务的apache改为nginx,企业中一般都是从v1版本升级到v2版本,思路是一样的。
[root@master 8.13]# vim 1.old_ingress.yaml
---
# apache版本的Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-http
spec:
replicas: 5
selector:
matchLabels:
app: myapp-http
template:
metadata:
labels:
app: myapp-http
spec:
containers:
- name: http
image: myos:httpd
ports:
- containerPort: 80
---
# apache版本的Service
apiVersion: v1
kind: Service
metadata:
name: myapp-http-svc
spec:
selector:
app: myapp-http
ports:
- port: 80
targetPort: 80
---
# apache版本的ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-http-ingress
spec:
rules:
- host: myapp-web.zkbr.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-http-svc
port:
number: 80
[root@master 8.13]# kubectl apply -f 1.old_ingress.yaml
[root@master 8.13]# echo "192.168.10.12 myapp-web.zkbr.com" >> /etc/hosts
# 访问apache的ingress,不管怎么访问都是apache给的回应,因为我们还没部署nginx
[root@master 8.13]# curl myapp-web.zkbr.com
Welcome to The Apache.
[root@master 8.13]# curl myapp-web.zkbr.com
Welcome to The Apache.
=======================新版本Ingress====================
[root@master 8.13]# vim 2.new_ingress.yaml
---
# nginx版本的Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-nginx
spec:
replicas: 5
selector:
matchLabels:
app: myapp-nginx
template:
metadata:
labels:
app: myapp-nginx
spec:
containers:
- name: nginx
image: myos:nginx
ports:
- containerPort: 80
---
# nginx版本的Service
apiVersion: v1
kind: Service
metadata:
name: myapp-nginx-svc
spec:
selector:
app: myapp-nginx
ports:
- port: 80
targetPort: 80
---
# 金丝雀Ingress(路由部分流量到nginx版本)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-canary-ingress
annotations:
nginx.ingress.kubernetes.io/canary: "true" # 声明为金丝雀Ingress
nginx.ingress.kubernetes.io/canary-weight: "10" # 10%流量到nginx版本(0-100之间)
spec:
rules:
- host: myapp-web.zkbr.com # 与apache的Ingress同域名,共享流量规则
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-nginx-svc # 金丝雀流量到nginx版本
port:
number: 80
[root@master 8.13]# kubectl apply -f 2.new_ingress.yaml
[root@master 8.13]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp-canary-ingress nginx myapp-web.zkbr.com 80 18m
myapp-http-ingress nginx myapp-web.zkbr.com 80 25m
1.12.3 验证金丝雀部署:
# 我们使用脚本来验证
[root@master 8.13]# for i in {1..100};do curl myapp-web.zkbr.com >> sum;done
# 10% 的请求会被路由到nginx,90% 到apache;
[root@master 8.13]# cat sum | sort | uniq -c
9 Nginx is running !
91 Welcome to The Apache.
# 调整:若 nginx版本 稳定,可逐步将canary-weight从 10→30→50→100,最终删除主 Ingress 完成全量切换。
# 把canary-weight的值设置为50
[root@master 8.13]# kubectl edit ingress myapp-canary-ingress

[root@master 8.13]# for i in {1..100};do curl myapp-web.zkbr.com >> sum;done^C
# 50% 的请求会被路由到nginx,50% 到apache
[root@master 8.13]# cat sum | sort | uniq -c
57 Nginx is running !
43 Welcome to The Apache.
更多推荐



所有评论(0)