Kubernetes Ingress 之 Nginx Ingress
一. 引言
k8s 提供了一下四种方式来暴露端口,分别是:
- ClusterIP, 仅供集群内部访问
- NodePort,端口映射,给node随机分配端口,然后由service进行代理
- LoadBalancer, 负载均衡模式,一般由云服务商提供负载均衡策略
- Ingress,网关模式,使用自定义的http(s)路由规则对Service进行代理。这也是实际生产中普遍使用的模式。
Ingress 模型如下:
二. 基于minikube的实践
由于笔者条件有限,这里基于minikube进行实践
1.启用ingress插件,检查验证 NGINX Ingress 控制器处于运行状态
# 启动插件
➜ ~ minikube addons enable ingress
💡 ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
💡 After the addon is enabled, please run "minikube tunnel" and your ingress resources would be available at "127.0.0.1"
▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794
▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794
▪ Using image registry.k8s.io/ingress-nginx/controller:v1.7.0
🔎 Verifying ingress addon...
🌟 启动 'ingress' 插件
# 检查
➜ ~ kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-b7gn2 0/1 Completed 0 40s
ingress-nginx-admission-patch-d44xm 0/1 Completed 1 40s
ingress-nginx-controller-6cc5ccb977-4dvhb 1/1 Running 0 40
2.创建第一个应用
# 部署
➜ ~ kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0
deployment.apps/web created
# 使用NodePort暴露服务
➜ ~ kubectl expose deployment web --type=NodePort --port=8080
service/web exposed
# 查看服务
➜ ~ kubectl get service web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web NodePort 10.100.58.21 <none> 8080:30013/TCP 10s
# 测试
➜ ~ minikube service web --url
http://127.0.0.1:51952
❗ Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
访问 http://127.0.0.1:51952,得到如下信息:
Hello, world!
Version: 1.0.0
Hostname: web-55b8c6998d-8k564
3.创建Ingress
# 创建Ingress
kubectl apply -f https://k8s.io/examples/service/networking/example-ingress.yaml
ingress.networking.k8s.io/example-ingress created
# 查看Ingress
➜ ingress kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> hello-world.info 192.168.49.2 80 68s
注意:minikube是不可以直接使用ip (192.168.49.2)访问的的,我们在另一个窗口打开tunnel服务
➜ ~ minikube tunnel
✅ Tunnel successfully started
📌 NOTE: Please do not close this terminal as this process must stay alive for the tunnel to be accessible ...
❗ The service/ingress example-ingress requires privileged ports to be exposed: [80 443]
🔑 sudo permission will be asked for it.
🏃 Starting tunnel for service example-ingress.
在/etc/hosts 配置域名映射
127.0.0.1 hello-world.info
然后访问 http://hello-world.info/
4.添加更多的Ingress
# 部署
➜ ~ kubectl create deployment web2 --image=gcr.io/google-samples/hello-app:2.0
deployment.apps/web2 created
# 暴露端口
➜ ~ kubectl expose deployment web2 --port=8080 --type=NodePort
service/web2 exposed
修改之前的Ingress配置,添加如下:
- path: /v2
pathType: Prefix
backend:
service:
name: web2
port:
number: 8080
是配置生效:
➜ ingress kubectl apply -f example-ingress.yaml
ingress.networking.k8s.io/example-ingress configured
然后访问 http://hello-world.info/v2
三.原理
Ingress具体的工作原理如下:
- ingress contronler通过与k8s的api进行交互,动态的去感知k8s集群中ingress服务规则的变化,然后读取它,并按照定义的ingress规则,转发到k8s集群中对应的service。
- 而这个ingress规则写明了哪个域名对应k8s集群中的哪个service,然后再根据ingress-controller中的nginx配置模板,生成一段对应的nginx配置。
- 然后再把该配置动态的写到ingress-controller的pod里,该ingress-controller的pod里面运行着一个nginx服务,控制器会把生成的nginx配置写入到nginx的配置文件中,然后reload一下,使其配置生效,以此来达到域名分配置及动态更新的效果
四.总结
本文简单介绍了Nginx Ingress的基本概念和使用,在实际的生产环境中的配置或许稍有不同,配置也更为复杂。
Ingress的工作原理看起来挺简单,但是nginx reload的过程是非常复杂的,后续有机会可以仔细解读其中的细节。
五.参考
https://kubernetes.io/docs/concepts/services-networking/service/
https://kubernetes.io/zh-cn/docs/tasks/access-application-cluster/ingress-minikube/
https://stackoverflow.com/questions/58561682/minikube-with-ingress-example-not-working
https://blog.csdn.net/weixin_44729138/article/details/105978555