深入理解ingress-nginx
8.1 Ingress为弥补NodePort不足而生
NodePort存在的不足:
-
-
只支持4层负载均衡
8.2 Pod与Ingress的关系
-
通过Service相关联
-
通过Ingress Controller实现Pod的负载均衡
-
支持TCP/UDP 4层和HTTP 7层
-
8.3 Ingress Controller
为了使Ingress资源正常工作,集群必须运行一个Ingress Controller(负载均衡实现)。
所以要想通过ingress暴露你的应用,大致分为两步:
-
部署Ingress Controller
-
创建Ingress规则
整体流程如下:
Ingress Controller有很多实现,我们这里采用官方维护的Nginx控制器。
注意事项:
-
镜像地址修改成国内的:lizhenliang/nginx-ingress-controller:0.20.0
-
1 2 3 4 5 | # kubectl apply -f ingress-controller.yaml # kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE nginx-ingress-controller-5r4wg 1 /1 Running 0 13s nginx-ingress-controller-x7xdf 1 /1 Running 0 13s |
此时在任意Node上就可以看到该控制监听的80和443端口:
1 2 3 | # netstat -natp |egrep ":80|:443" tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 104750 /nginx : maste tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 104750 /nginx : maste |
80和443端口就是接收来自外部访问集群中应用流量,转发对应的Pod上。
其他主流控制器:
Traefik: HTTP反向代理、负载均衡工具
8.4 Ingress 规则
接下来,就可以创建ingress规则了。
在ingress里有三个必要字段:
-
host:访问该应用的域名,也就是域名解析
-
serverName:应用的service名称
-
serverPort:service端口
1、HTTP访问
1 2 3 4 5 6 7 8 9 10 11 12 13 | apiVersion: networking.k8s.io /v1beta1 kind: Ingress metadata: name: example-ingress spec: rules: - host: example.ctnrs.com http: paths: - path: / backend: serviceName: web servicePort: 80 |
生产环境:example.ctnrs.com 域名是在你购买域名的运营商上进行解析,A记录值为K8S Node的公网IP(该Node必须运行了Ingress controller)。
测试环境:可以绑定hosts模拟域名解析("C:\Windows\System32\drivers\etc\hosts"),对应IP是K8S Node的内网IP。例如:
192.168.31.62 example.ctnrs.com
2、HTTPS访问
四。创建https方式访问网站
1.创建cfssl.sh,并执行此脚本,默认加载到bin目录变成可执行文件
1 2 3 4 5 6 7 | wget https: //pkg .cfssl.org /R1 .2 /cfssl_linux-amd64 wget https: //pkg .cfssl.org /R1 .2 /cfssljson_linux-amd64 wget https: //pkg .cfssl.org /R1 .2 /cfssl-certinfo_linux-amd64 chmod +x cfssl* mv cfssl_linux-amd64 /usr/bin/cfssl mv cfssljson_linux-amd64 /usr/bin/cfssljson mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo |
2.创建certs.sh

cat > ca-config.json <<EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } cat > ca-csr.json <<EOF { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing" } ] } EOF cfssl gencert -initca ca-csr.json | cfssljson -bare ca - cat > blog.ctnrs.com-csr.json <<EOF { "CN": "blog.ctnrs.com", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing" } ] } EOF cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes blog.ctnrs.com-csr.json | cfssljson -bare blog.ctnrs.com kubectl create secret tls blog-ctnrs-com --cert=blog.ctnrs.com.pem --key=blog.ctnrs.com-key.pem
3.创建ingress.yaml 证书里的域名和ingress里的域名要一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | apiVersion: networking.k8s.io /v1beta1 kind: Ingress metadata: name: tls-example-ingress spec: tls: - hosts: - blog.ctnrs.com secretName: example-ctnrs-com rules: - host: blog.ctnrs.com http: paths: - path: / backend: serviceName: web servicePort: 80 |
4.直接网页访问即可
3、根据URL路由到多个服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | apiVersion: networking.k8s.io /v1beta1 kind: Ingress metadata: name: url-ingress annotations: nginx.ingress.kubernetes.io /rewrite-target : / spec: rules: - host: foobar.ctnrs.com http: paths: - path: /foo backend: serviceName: service1 servicePort: 80 - host: foobar.ctnrs.com http: paths: - path: /bar backend: serviceName: service2 servicePort: 80 |
工作流程:
1 2 | foobar.ctnrs.com -> 178.91.123.132 -> / foo service1:80 / bar service2:80 |
4、基于名称的虚拟主机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | apiVersion: networking.k8s.io /v1beta1 kind: Ingress metadata: name: name-virtual-host-ingress spec: rules: - host: foo.ctnrs.com http: paths: - backend: serviceName: service1 servicePort: 80 - host: bar.ctnrs.com http: paths: - backend: serviceName: service2 servicePort: 80 |
工作流程:
1 2 3 | foo.bar.com --| |-> service1:80 | 178.91.123.132 | bar.foo.com --| |-> service2:80 |
HTTP:配置Nginx常用参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | apiVersion: networking.k8s.io /v1beta1 kind: Ingress metadata: name: example-ingress annotations: kubernetes.io /ingress .class: "nginx“ nginx.ingress.kubernetes.io /proxy-connect-timeout : "600" nginx.ingress.kubernetes.io /proxy-send-timeout : "600" nginx.ingress.kubernetes.io /proxy-read-timeout : "600" nginx.ingress.kubernetes.io /proxy-body-size : "10m" spec: rules: - host: example.ctnrs.com http: paths: - path: / backend: serviceName: web servicePort: 80 |
HTTPS:禁止访问HTTP强制跳转到HTTPS(默认开启)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | apiVersion: networking.k8s.io /v1beta1 kind: Ingress metadata: name: tls-example-ingress annotations: kubernetes.io /ingress .class: "nginx“ nginx.ingress.kubernetes.io /ssl-redirect : 'false' spec: tls: - hosts: - sslexample.ctnrs.com secretName: secret-tls rules: - host: sslexample.ctnrs.com http: paths: - path: / backend: serviceName: web servicePort: 80 |
如果域名只解析到一台Ingress controller,是存在单点的,挂了就不能提供服务了。这就需要具备高可用,有两种常见方案:
左边:双机热备,选择两台Node专门跑Ingress controller,然后通过keepalived对其做主备。用户通过VIP访问。
右边:高可用集群(推荐),前面加一个负载均衡器,转发请求到后端多台Ingress controller。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?