【k8s学习】Kubernetes Ingress介绍

【本文内容】

  • 什么是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的示例:

image.png

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
  • apiVersionkind,前两行是声明,其中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 addons enable ingress

我minikube启动的时候vm-driver用的是hyperkit,然后遇到如下问题:
image.png

于是我换成docker作为vm-driver,先用命令minikube delete --all删除下minikube,然后再run:minikube start --vm-driver=docker
再安装ingress,就没有问题了:

image.png

通过查看namespace=kube-system下的pod,可以看到名为nginx-ingress-controller的相关的已经running了:

kubectl get all -n ingress-nginx

image.png
3.4 示例:给kubernetes-dashboard配置Ingress

在minikube上安装好基于Kubernetes Nginx的Ingress Controller后,我们试着给kubenetes-dashboard配置Ingress,以便以hostName的方式暴露给集群外部使用。
首先运行minikube dashboard:

minikube dashboard

image.png

首先查看kubernetes dashboard的所有配置(在namespace为kubernetes-dashboard下):

kubectl get all -n kubernetes-dashboard

image.png

编写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

kubectl apply -f dashboard-ingress.yaml

创建好之后,查看Ingress列表,需要加上-n(即namespace的意思),否则只会在namespace=default下查询:
image.png

进入host文件(我的是MacOS系统,如果是Windows,自行查阅):

sudo vim /etc/hosts

在host文件的最后加上跳转的mapping:


image.png

这要在浏览器中访问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

你可能感兴趣的:(【k8s学习】Kubernetes Ingress介绍)