【本文内容】
- 什么是Ingress
- Ingress的yaml配置
- Ingress的use case(什么情况下需要用到Ingress)
- Ingress Controller的介绍
- Demo - 通过Ingress暴露kubernetes dashboard
- tls相关(https)
【前置文章】
- 【k8s学习】Kubernetes学习——核心组件和架构
- 【k8s学习】minikube、kubectl、yaml配置文件的介绍
- 【k8s学习】在minikube上布署MongoDB和MongoExpress
- 【k8s学习】kubernetes namespace介绍
1. External Service vs. Ingress
External Service
假设我们的Kubernetes集群中有my-app pod
,以及my-app external service
,意味着我们可以从外部以NodeIP + Port
的形式访问my-app项目,如http://124.89.11.11:35010
--> 这就是external service能达到的效果。这时候my-app service的yaml中的配置,则需要配成:spec.type = LoadBalancer,并且需要配置spec.ports.nodePord = 35010,表明需要对集群外暴露这个Service,以下是定义external service的示例:
Ingress
官网:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
但如果我们想要用https://my-app.com
来访问my-app项目,那么就需要用到Ingress
组件了。即会先创建一个my-app ingress
--> 然后转发到my-app internal service
--> 再转发到my-app pod
,可以看到有了Ingress组件后,Service组件不再需要external了(即上述的type可以删掉,不填默认是ClusterIP,即internal service了,不对外暴露,nodePort也可以删除)。
2. Ingress yaml配置文件
简单的Ingress yaml示例:
注,这里的apiVersion有更新,之前的版本是apiVersion: extensions/v1beta1,最新的版本是下述的v1,两者的语法有些许差别,比如v1beta1中是serviceName,servicePort,而在v1(下述)中则是service.name和service.port.number
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: dashboard.info.abc
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: myapp-internal-service
port:
number: 8080
-
apiVersion
和kind
,前两行是声明,其中kind表示当前需要创建的是Ingress资源。 -
spec
中的rules
:表示Routing rules,路由规则。表示这个从host
来的请求,需要被转发到serviceName
中,即request from myapp.com
--> 转发到myapp-internal-service
。 - 其中的
paths
表示可以按url的后缀进行匹配,下文有具体的例子解释。 - 【和internal service的对应】,Ingress中的serviceName对应的是service yaml中的metadata.name,Ingress中的servicePort对应的是service yaml中的spec.ports.port。
3. Ingress Controller
官网:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress-controllers/
3.1 Ingress Controller介绍
除了安装Ingress组件之外,我们还需要一个Ingress的实现(Implementation),这个实现就是Ingress Controller
,Ingress Controller也是运行在Pod中的,即我们可以创建一个Pod,叫Ingress Controller Pod。
Ingress Controller是干什么的?它是用来解析上述Ingress yaml中的rules规则的,即需要怎样的跳转。(如一级域名,二级域名等等,诸如此类的跳转规则的实现)。
目前有很多第三方的实现,如:
- Kubernetes Nginx Ingress Controller,github: https://github.com/kubernetes/ingress-nginx/blob/main/README.md#readme
- Kubernetes AWS Load Balancer Controller, github: https://github.com/kubernetes-sigs/aws-load-balancer-controller#readme
- 等等
3.2 现实中的Ingress Controller架构
如果用的是一些云服务器,例如aws, google提供的Kubernetes,那么请求会先到达这些云服务商的负载均衡器上,即Cloud Load Balancer
--> 再跳转到我们在Kubernetes集群内定义的Ingress Controller Pod
上 --> 然后再是my-app ingress
--> my-app internal service
--> my-app pod
。
相当于云服务商会帮我们做掉负载均衡的部分。
如果我们的Kubernetes集群运行在自己的服务器上(没有依赖aws这些云服务商提供服务),那么在Ingress Controller之前,可能需要一台Proxy Server,用来做转发(负载均衡)。
3.3 在Minikube上安装Ingress Controller
在minikube上可以通过以下命令,minikube会自动帮我们安装Kubernetes Nginx Ingress Controller,安装的时候可能需要一些时间:
我minikube启动的时候vm-driver用的是hyperkit,然后遇到如下问题:�minikube addons enable ingress
于是我换成docker作为vm-driver,先用命令minikube delete --all
删除下minikube,然后再run:minikube start --vm-driver=docker
。
再安装ingress,就没有问题了:
通过查看namespace=kube-system下的pod,可以看到名为nginx-ingress-controller的相关的已经running了:
kubectl get all -n ingress-nginx
3.4 示例:给kubernetes-dashboard配置Ingress
在minikube上安装好基于Kubernetes Nginx的Ingress Controller后,我们试着给kubenetes-dashboard配置Ingress,以便以hostName的方式暴露给集群外部使用。
首先运行minikube dashboard:
minikube dashboard
首先查看kubernetes dashboard的所有配置(在namespace为kubernetes-dashboard下):
kubectl get all -n kubernetes-dashboard
编写Ingress yaml文件:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
spec:
rules:
- host: dashboard.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 80
创建好之后,查看Ingress列表,需要加上-n(即namespace的意思),否则只会在namespace=default下查询:kubectl apply -f dashboard-ingress.yaml
进入host文件(我的是MacOS系统,如果是Windows,自行查阅):
sudo vim /etc/hosts
在host文件的最后加上跳转的mapping:
这要在浏览器中访问dashboard.com的时候会访问到我们的kubernetes dashboard。
3.5 default-http-backend
kubectl describe ingress dashboard-ingress -n kubernetes-dashboard
可能会遇到以下信息:
Default backend: default-http-backend:80 (
这个表示我们没有default http来处理不正确的url,即如果我们在url中输入dashboard.com/abc,会跳404,但如果我们配置了一个Service,名字就叫default-http-backend,那么所有404的跳转,就会跳到这个Service上了。
4. Ingress同一个域名下多个路径
4.1 配置多个path
比如myapp.com网站,除了首页之前,我们可能会有很多Service(即myapp.com项目并不只是一个Web项目,而是拆分成很多的微服务,那么可能会部署不同的Pod以及Mapping在不同的Service上),比如/analytics,/shopping,
我们可以通过在同一个Ingress配置多个path来达到这样的效果:
spec:
rules:
- host: myapp.com
http:
paths:
- path: /analytics
pathType: Prefix
backend:
service:
name: analytics-service
port:
number: 3000
- path: /shopping
pathType: Prefix
backend:
service:
name: shopping-service
port:
number: 3001
4.2 配置多个host
另外一种case是有些大公司不止一个域名,除了myapp.com这个主域名外,还会有二级域名,如analytics.myapp.com,shopping.myapp.com等等,针对这种情况,需要配置多个host:
spec:
rules:
- host: analytics.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: analytics-service
port:
number: 3000
- host: shopping.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: shopping-service
port:
number: 3001
5. 配置TLS认证—http://
官网:https://kubernetes.io/docs/concepts/services-networking/ingress/#tls
需要要Ingress yaml配置文件中的spec加tls配置,指向Secret中的metadata.name(所以还需要再配置一个Secret yaml文件)。
spec:
tls:
- hosts:
- my-app.com
secretName: myapp-secret-tls
Secret yaml配置文件,当需要创建tls的Secret,需要指定的type为kubernetes.io/tls
:
apiVersion: v1
kind: Secret
metadata:
name: myapp-secret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
需要注意的是Secret中的namespace需要和Ingress中的一致,否则Ingress无法mapping这个信息。
参考:
- https://www.youtube.com/watch?v=X48VuDVv0do
- https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
- https://stackoverflow.com/questions/70237546/minikube-dashboard-ingress
- https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0