Kubernetes Ingress 之 Nginx Ingress

发布时间 2023-06-21 21:34:18作者: darcy_yuan

一. 引言

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具体的工作原理如下:

  1. ingress contronler通过与k8s的api进行交互,动态的去感知k8s集群中ingress服务规则的变化,然后读取它,并按照定义的ingress规则,转发到k8s集群中对应的service。
  2. 而这个ingress规则写明了哪个域名对应k8s集群中的哪个service,然后再根据ingress-controller中的nginx配置模板,生成一段对应的nginx配置。
  3. 然后再把该配置动态的写到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