• Kubernetes(22):Ingress详解


    第一节 Ingress 介绍

    前面已经提到,Service对集群之外暴露服务的主要方式有两种:NodePort和LoadBalancer,但是这两种方式,都有一定的缺点:

    • NodePort方式的缺点是占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就会愈发明显
    • LB方式的缺点是每个service需要一个LB,浪费、麻烦,并且需要kubernetes之外设备的支持。

    基于这种现状,kubernetes提供了Ingress资源对象,Ingress只需要一个NodePort或者一个LB就可以满足暴露多个service的需求。工作机制如下:
    在这里插入图片描述
    实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress 里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx

    • ingress: kubernetes中的一个对象,作用是定义请求如何转发到service的规则
    • ingress controller: 具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式很多,比如Nginx,Contour,Haproxy等

    Ingress(以Nginx为例)的工作原理如下

    1. 用户编写Ingress规则,说明哪些域名对应kubernetes集群中的哪些service
    2. Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx配置
    3. Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
    4. 到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则

    在这里插入图片描述

    第二节 Ingress 使用

    1. 环境准备

    # 创建文件夹
    [root@master ~]# mkdir ingress-controller
    [root@master ~]# cd ingress-controller/
    
    # 获取ingress-nginx
    [root@master ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
    [root@master ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
    [root@master ingress-controller]# ls
    mandatory.yaml  service-nodeport.yaml
    [root@master ingress-controller]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    # 创建ingress-nginx
    [root@master ingress-controller]# kubectl apply -f ./
    namespace/ingress-nginx created
    configmap/nginx-configuration created
    configmap/tcp-services created
    configmap/udp-services created
    serviceaccount/nginx-ingress-serviceaccount created
    clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
    role.rbac.authorization.k8s.io/nginx-ingress-role created
    rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
    clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
    deployment.apps/nginx-ingress-controller created
    limitrange/ingress-nginx created
    service/ingress-nginx created
    
    # 查看ingress-nginx
    [root@master ingress-controller]# kubectl get pod -n ingress-nginx
    NAME                                        READY   STATUS    RESTARTS   AGE
    nginx-ingress-controller-7f74f657bd-c2zwl   1/1     Running   0          3m16s
    
    
    # 查看service
    # 这里可以看到80对应的http端口(外部是30692), 443对应的https端口(外部是30254)
    [root@master ingress-controller]# kubectl get svc -n ingress-nginx
    NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx   NodePort   10.97.146.1   <none>        80:31586/TCP,443:32714/TCP   4m6s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2. 准备service和pod

    为例后面的实验方便,创建如下图所示的模型
    在这里插入图片描述

    创建tomcat-nginx.yaml

    ---
    apiVersion: apps/v1   #版本号
    kind: Deployment    #类型
    metadata:   #元数据
      name: nginx-deployment    #rs名称
      namespace: dev   #所属命名空间
    spec:  #详情
      replicas: 3 #副本数量3
      selector: #选择器,通过它指定该控制器管理哪些pod
        matchLabels: #labels匹配规则,用于匹配template
          app: nginx-pod
      template:  #模板,当副本数量不足时,会根据模板创建pod副本
        metadata:
          labels:
            app: nginx-pod
        spec:
          containers:
            - name: nginx
              image: nginx:1.17.1
              ports:
                - containerPort: 80
    
    ---
    apiVersion: apps/v1   #版本号
    kind: Deployment    #类型
    metadata:   #元数据
      name: tomcat-deployment    #rs名称
      namespace: dev   #所属命名空间
    spec:  #详情
      replicas: 3 #副本数量3
      selector: #选择器,通过它指定该控制器管理哪些pod
        matchLabels: #labels匹配规则,用于匹配template
          app: tomcat-pod
      template:  #模板,当副本数量不足时,会根据模板创建pod副本
        metadata:
          labels:
            app: tomcat-pod
        spec:
          containers:
            - name: tomcat
              image: tomcat:8.5-jre10-slim
              ports:
                - containerPort: 8080
    
    ---
    apiVersion: v1   #版本号
    kind: Service    #类型
    metadata:   #元数据
      name: nginx-service    #svc名称
      namespace: dev   #所属命名空间
    spec:  #详情
      selector: #选择器,通过它指定该控制器管理哪些pod
        app: nginx-pod
      clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
      type: ClusterIP
      ports:
        - port: 80    #Service端口
          targetPort: 80 #pod端口
    
    ---
    apiVersion: v1   #版本号
    kind: Service    #类型
    metadata:   #元数据
      name: tomcat-service    #svc名称
      namespace: dev   #所属命名空间
    spec:  #详情
      selector: #选择器,通过它指定该控制器管理哪些pod
        app: tomcat-pod
      clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
      type: ClusterIP
      ports:
        - port: 8080    #Service端口
          targetPort: 8080
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    # 创建 pod和service
    [root@master ~]# kubectl create -f tomcat-nginx.yaml 
    deployment.apps/nginx-deployment created
    deployment.apps/tomcat-deployment created
    service/nginx-service created
    service/tomcat-service created
    
    # 查看service
    [root@master ~]# kubectl get svc -n dev
    NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
    nginx-service    ClusterIP   None         <none>        80/TCP     13s
    tomcat-service   ClusterIP   None         <none>        8080/TCP   13s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. http代理

    创建ingress-http.yaml

    apiVersion: extensions/v1beta1   #版本号
    kind: Ingress    #类型
    metadata:   #元数据
      name: ingress-http    #svc名称
      namespace: dev   #所属命名空间
    spec:  #详情
      rules:
        - host: nginx.abc.com
          http:
            paths:
              - path: /
                backend:
                  serviceName: nginx-service
                  servicePort: 80
        - host: tomcat.abc.com
          http:
            paths:
              - path: /
                backend:
                  serviceName: tomcat-service
                  servicePort: 8080
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    # 创建ingress
    [root@master ~]# kubectl create -f ingress-http.yaml 
    ingress.extensions/ingress-http created
    
    # 查看ingress
    [root@master ~]# kubectl get ing ingress-http -n dev
    NAME           HOSTS                          ADDRESS   PORTS   AGE
    ingress-http   nginx.abc.com,tomcat.abc.com             80      17s
    
    # 查看ingress详情
    [root@master ~]# kubectl  describe ing ingress-http -n dev
    Name:             ingress-http
    Namespace:        dev
    Address:          
    Default backend:  default-http-backend:80 (<none>)
    Rules:
      Host            Path  Backends
      ----            ----  --------
      nginx.abc.com   
                      /   nginx-service:80 (10.244.1.108:80,10.244.2.178:80,10.244.2.179:80)
      tomcat.abc.com  
                      /   tomcat-service:8080 (10.244.1.107:8080,10.244.1.109:8080,10.244.2.180:8080)
    Annotations:
    Events:  <none>
    [root@master ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    配置host域名

    192.168.88.100  nginx.abc.com
    192.168.88.100  tomcat.abc.com
    
    • 1
    • 2

    在这里插入图片描述

    打开浏览器访问http://nginx.abc.com:31586/和http://tomcat.abc.com:31586/,(端口请查看ingress-nginx的80对应的端口)

    [root@master ~]# kubectl get svc ingress-nginx -n ingress-nginx
    NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx   NodePort   10.97.146.1   <none>        80:31586/TCP,443:32714/TCP   12m
    [root@master ~]#
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    4. https代理

    # 生成证书
    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=abc.com"
    
    # 创建密钥
    kubectl create secret tls tls-secret --key tls.key --cert tls.crt
    
    • 1
    • 2
    • 3
    • 4
    • 5

    创建ingress-https.yaml

    apiVersion: extensions/v1beta1   #版本号
    kind: Ingress    #类型
    metadata:   #元数据
      name: ingress-https    #svc名称
      namespace: dev   #所属命名空间
    spec:  #详情
      tls:
        - hosts:
            - nginx.abc.com
            - tomcat.abc.com
          secretName: tls-secret #指定密钥
      rules:
        - host: nginx.abc.com
          http:
            paths:
              - path: /
                backend:
                  serviceName: nginx-service
                  servicePort: 80
        - host: tomcat.abc.com
          http:
            paths:
              - path: /
                backend:
                  serviceName: tomcat-service
                  servicePort: 8080
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    # 生成证书
    [root@master ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=abc.com"
    Generating a 2048 bit RSA private key
    .....................................................................................+++
    .............+++
    writing new private key to 'tls.key'
    -----
    
    # 创建密钥
    [root@master ~]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
    secret/tls-secret created
    
    [root@master ~]# vim ingress-https.yaml
    
    # 创建sevice
    [root@master ~]# kubectl create -f ingress-https.yaml 
    ingress.extensions/ingress-https created
    
    # 查看ingress
    [root@master ~]# kubectl get ing ingress-https -n dev
    NAME            HOSTS                          ADDRESS   PORTS     AGE
    ingress-https   nginx.abc.com,tomcat.abc.com             80, 443   15s
    
    # 查看ingress详情,可以看到describe有一个TLS,表示https配置成功
    [root@master ~]# kubectl describe ing ingress-https -n dev
    Name:             ingress-https
    Namespace:        dev
    Address:          
    Default backend:  default-http-backend:80 (<none>)
    TLS:
      tls-secret terminates nginx.abc.com,tomcat.abc.com
    Rules:
      Host            Path  Backends
      ----            ----  --------
      nginx.abc.com   
                      /   nginx-service:80 (10.244.1.118:80,10.244.2.195:80,10.244.2.197:80)
      tomcat.abc.com  
                      /   tomcat-service:8080 (10.244.1.116:8080,10.244.1.117:8080,10.244.2.196:8080)
    Annotations:
    Events:
      Type    Reason  Age   From                      Message
      ----    ------  ----  ----                      -------
      Normal  CREATE  30s   nginx-ingress-controller  Ingress dev/ingress-https
    [root@master ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    打开浏览器访问https://nginx.abc.com:32714/和https://tomcat.abc.com:32714/,(端口请查看ingress-nginx的443对应的端口)

    [root@master ~]# kubectl get svc -n ingress-nginx
    NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx   NodePort   10.97.146.1   <none>        80:31586/TCP,443:32714/TCP   38m
    [root@master ~]# 
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    问题 遇到的问题

    1. 最后打开浏览器无法访问

    浏览器一直空转
    排查发现ingress-http的镜像下载失败,使用官方镜像即可。
    在这里插入图片描述
    在这里插入图片描述
    如果七牛的镜像无法下载,请使用官方镜像。

    # 七牛镜像(可能不可靠)
    quay-mirror.qiniu.com/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
    
    • 1
    • 2

    修改使用官方镜像:

    # 官方镜像(默认)
    quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
    
    • 1
    • 2

    在这里插入图片描述

  • 相关阅读:
    六、e2studio VS STM32CubeIDE之代码自动补全
    flink技术总结待续
    nodejs+java+python小区住户防疫健康出入返乡登记管理系统vue+elementui
    SRM系统能为企业带来什么好处,企业该怎么选择SRM系统供应商
    谷歌浏览器的视频下载插件推荐
    每日一道面试题之什么是上下文切换?
    请你说说Spring
    视频监控系统/视频汇聚平台EasyCVR如何反向代理进行后端保活?
    嵌入式系统测试思路
    把握出租车行驶的数据脉搏 :出租车轨迹数据给你答案!
  • 原文地址:https://blog.csdn.net/u011628753/article/details/127384324