• Kubernetes:(十六)Ingress的概念和原理


    目录

    一:Ingress的概念

    1.1 ingress诞生的背景

    1.2 ingress和ingress-controller的区别

    1.2.1 ingress对象

    1.2.2 ingress-controller

    1.2.3 小结

    1.3 ingress介绍

    1.3.1 pod漂移问题

    1.3.2 端口管理问题 

    1.3.3 域名分配及动态更新问题 

    1.4 Ingress Controller

    1.4.1 第一种介绍

    1.4.2 第二种介绍 

    1.5 ingress-nginx介绍 

    1.5.1 ingress-nginx组成 

    1.5.2 ingress-nginx可以解决的问题

    1.5.3 ingress-nginx工作原理

    二:原理

    2.1 ingress-controller工作原理

    2.2 ingress的部署原理 

    2.2.1 Deployment+LoadBalancer模式的service

    2.2.2 Deployment+NodePort模式的service

    2.2.3 DaemonSet+HostNetwork(+nodeSelector)

    2.2.4 hostnetwork的优势

    2.3 nginx反向代理原理

    2.4 ingress controller工作流程分析

    三:部署nginx-ingress-controller

    3.1 部署ingress-controller pod及相关资源

    3.2 修改clusterRole资源配置  

    3.3 ingress暴露服务的方式  

    3.4 采用方式二:DaemonSet+HostNetwork+nodeselector 

    3.4.1 指定nginx-ingress-controller运行在node02节点

    3.4.2 修改Deployment为Daemonset,指定节点运行,并开启 hostNetwork 

    3.4.3 所有node节点上传nginx-ingress-controller镜像压缩包ingree.contro.tar.gz.到/opt/ingress目录,并解压和加载镜像  

    3.4.4 启动nginx-ingress-controller  

    3.4.5 创建ingress规则  

    3.4.6 创建ingress  

    3.4.7 做端口映射并访问测试  

    3.4.8 查看nginx-ingress-controller  

    3.5 采用方式三:Deployment+NodePort模式的Service  

    3.5.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件 

    3.5.2 在所有node节点上传镜像包ingress-controller-0.30.0.tar到/opt/ingress-nodeport目录,并加载镜像 

    3.5.3 启动nginx-ingress-controller  

    3.5.4 创建deployment、service和ingress的yaml资源  

    3.5.5 做端口映射并访问测试  

    3.5.6 ingress http代理访问虚拟主机  

    3.5.7 ingress https代理访问  

    3.5.8 nginx进行BasicAuth(访问前输入用户和密码)  

    3.5.9 nginx进行重写 

    一:Ingress的概念

    1.1 ingress诞生的背景

    到达service所选中的节点上,然后负载均衡到每一个节点上。nodeport虽然提供了对外的方式但也有很大的弊端:

    由于servcie的实现方式use_space、iptables、ipvs这三种方式只支持4层协议通信,不支持7层协议,因此nodeport不能代理https(客户端的角度);nodeport需要暴露service所属每个node节点上端口,当需求越来越多,端口数量越多,导致维护成本过高,并且集群不好管理(运维的技术难度)。

    1.2 ingress和ingress-controller的区别

    1.2.1 ingress对象

    1. 指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。
    2. ingress是一个api对象,和其他对象一样,通过yaml文件来配置。ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS能力以及基于host的反向代理。ingress要依靠ingress-controller来实现以上功能。大概的配置如下:

    与其他k8s对象一样,ingress配置也包含了apiVersion、kind、metadata、spec等关键字段。有几个关注的在spec字段中,tls用于定义https秘钥、证书;rule用于指定请求路由规则;这里值得关注的还有metadata.annotations字段,在ingress配置中,annotations很重要,ingress-controller有很多不同的实现,而不同的ingress-controller就可以根据“kubernetes.io/ingress.class:”来判断要使用哪些ingress配置,同时,不同的ingress-controller也有对应的annotations配置,用于自定义一些参数,例如上面配置的‘nginx.ingress.kubernetes.io/use-regex:"true"’,最终是在生成nginx配置中,会采用location~来表示正则匹配。

    1.2.2 ingress-controller

    • 具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现转发。
    • ingress-controller并不是k8s自带的组件,实际上ingress-controller只是一个统称,用户可以选择不同的ingress-controller实现,目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,其他还有很多第三方维护的ingress-controller,具体可以参考官方文档。但是不管哪一种ingress-controller,实现的机制都大同小异,只是在具体配置上有差异:
    • 一般来说,ingress-controller的形式都是一个pod,里面跑着daemon程序和反向代理程序(典型的有nginx负载均衡器)。daemon负责不断监控集群的变化,根据ingress对象生成配置并应用新配置到反向代理,比如nginx-ingress就是动态生成nginx配置,动态更新upstream,并在需要的时候reload程序应用新配置。为了方便,后面的例子一般都以k8s官方维护的nginx-ingress为例。

    1.2.3 小结

    ingress和ingress-controller的关系:类似于路由器与路由表的关系

    • ingress对象:
      指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。
    • ingress-controller:
      具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。

    简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller改如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。

    1.3 ingress介绍

    Kubernetes 暴露服务的有三种方式,分别为 LoadBlancer Service、NodePort Service、Ingress。官网对 Ingress 的定义为管理对外服务到集群内服务之间规则的集合,通俗点讲就是它定义规则来允许进入集群的请求被转发到集群中对应服务上,从来实现服务暴漏。 Ingress 能把集群内 Service 配置成外网能够访问的 URL,流量负载均衡,终止SSL,提供基于域名访问的虚拟主机等等。

    可能从大致印象上就是能利用nginx、haproxy啥的负载均衡器暴露集群内服务的工具;那么问题来了,集群内服务想要暴露出去面临着几个问题:

    1.3.1 pod漂移问题

    众所周知k8s具有强大的副本控制能力,能保证在任意副本(pod)挂掉时自动从其他机器启动一个新的,还可以动态扩容等等,总之一句话,这个Pod可能在任何时刻出现在任何节点上,也可能在任何时刻死在任何节点上;那么自然随着pod的创建和销毁,pod ip肯定会动态变化;那么如何把这个动态的pod ip暴露出去?这里借助于k8s的service机制,service可以用标签的形式选定一组带有指定标签的pod,并监控和自动负载他们的pod ip,那么我们向外暴露只暴露service ip就行了;这就是nodeport模式:即在每个节点上开启一个端口,然后转发到内部pod ip上,如图所示:

    1.3.2 端口管理问题 

    采用nodeport方式暴露服务面临一个坑爹的问题是,服务一旦多起来,nodeport在每个节点上开启的端口会极其庞大,而且难以维护;这时候引出的思考问题是“能不能使用nginx啥的只监听一个端口,比如80,然后按照域名向后转发?”这思路很好,简单的实现就是使用daemonset在每个Node上监听80,然后写好规则,因为nginx外面绑定到了宿主机80端口(就像nodeport),本身又在集群内,那么向后直接转发到相应service ip就行了,如图所示:

    1.3.3 域名分配及动态更新问题 

    从上面的思路,采用nginx似乎已经解决了问题,但是其实这里面有一个很大的缺陷:每次有新服务加入怎么改nginx配置?总不能手动改或者来个rolling update前端nginx pod 吧?这时候“伟大而又正直勇敢的”ingress登场,如果不算上面的nginx,ingress只有两大组件:ingress controller和ingress。

    ingress这个玩意,简单的理解就是你原来要改nginx配置,然后配置各种域名对应哪个service,现在把这个动作抽象出来,变成一个ingress对象,你可以用yaml创建,每次不要去改nginx了,直接改yaml然后创建/更新就行;那么问题来了:“nginx咋整?”

    ingress controller这东西就是解决“nginx咋整”的;ingress controller通过与k8s api交互,动态的去感知集群中ingress规则变化,然后读取它,按照他自己模板生成一段nginx配置,再写到nginx pod里,最后reload一下,工作流程如下:

    当然咱实际应用中,最新版本k8s已经将nginx与ingress controller合并为一个组件,所以ngxin无需单独部署,只需要部署ingress controller即可。

    1.4 Ingress Controller

    1.4.1 第一种介绍

    ingress controller是将ingress这种变化生成一段nginx的配置,然后将这个配置通过k8s api写到nginx的pod中,然后reload。

    注意:写入nginx.conf的不是service地址,而是service backend的pod地址,避免在service上增加一层负载均衡转发。service在此处的作用是用于感知pod ip的变化。

    从上图可以很清晰的看出,实际上请求进来还是被负载均衡器拦截,比如nginx,然后ingress controller通过跟ingress交互得知某个域名对应哪个service,再通过k8s api交互得知service地址等信息;综合以后生成配置文件时写入负载均衡器,然后负载均衡器reload改规则便可实现服务发现,即动态映射。

    了解了以上内容以后,这也很好的说明了我为什么喜欢吧负载均衡器部署为daemon set;因为无论如何请求首先是被负载均衡器拦截的,所以在每个node上都部署一下,同时hostport方式监听80端口。那么久解决了其他方式部署不确定负载均衡器在哪的问题,同时访问每个node的80都能正确解析请求。(备:如果前端再放个nginx就又实现了一层负载均衡。)

    ingress controller会根据你定义的ingress对象,提供对应的代理能力。业界常用的各种反向代理项目,比如nginx、HAProxy、Envoy、Traefik等,都已经为k8s专门维护了对应的ingress-controller。

    1.4.2 第二种介绍 

    ingress controller是一个pod服务,封装了一个web前端负载均衡器,同时在其基础上实现了动态感知ingress并根据ingress的定义生成前端web负载均衡器的配置文件,ingress-nginx-controller本质上就是一个nginx,只不过它能根据ingress资源定义的动态生成nginx的配置文件,然后动态reload。个人觉得ingress controller的重大作用是将前端负载均衡器和k8s完美地结合起来,一方面在云、容器平台下方便配置管理,另一方面实现了集群统一的流量入口,而不是像nodeport那样给集群打多个孔。

    备注: 

    总的来说要使用ingress,得先部署ingress controller实体(相当于前端nginx),然后再创ingress(相当于nginx配置的k8s资源体现),ingress controller部署后之后会动态检测到ingress的创建清楚并生成相应的配置。

    1.5 ingress-nginx介绍 

    1.5.1 ingress-nginx组成 

    • ingress-nginx-controller:根据用户编写的ingress规则(创建的ingress的yaml文件),动态的去更改nginx服务的配置文件,并且reload重载使其失效(是自动化的,通过脚本来是实现的);
    • ingress资源对象:将nginx的配置抽象成一个ingress对象,没添加一个新的service资源对象只需写一个新的ingress规则的yaml文件即可(或修改已存在的ingress规则的yaml文件)。

    1.5.2 ingress-nginx可以解决的问题

    ①动态配置服务

    如果按照传统方式,当新添加一个服务时,我们可能需要在流量入口佳一个反向代理指向我们新的k8s服务,而如果用了ingress-nginx,只需要配置好这个服务,当服务启动时,会自动注册到ingress中,不需要额外的操作。

    ②减少不必要的端口映射

    配置过k8的都清楚,第一步是要关闭防火墙,主要原因是k8s的很多服务会以nodeport方式映射出去,这样就相当于给宿主机打了很多孔,既不安全也不优雅,而ingress可以避免这个问题,除了ingress自身服务可能需要映射出去,其他服务都不要用nodeport方式。

    1.5.3 ingress-nginx工作原理

    1. ingress controller通过和k8s api交互,动态的去感知集群中ingress规则变化。
    2. 然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置
    3. 再写到nginx-ingress-controller的pod里,这个ingress controller的pod里运行着一个nginx服务,控制器会吧生成的nginx配置写入/etc/nginx.conf中
    4. 然后reload一下使配置生效。因此达到域名分别配置和动态更新的问题。

    基于ingress-nginx的安装,可以查看k8s的ingress-nginx官网,实现的逻辑如下图:

    1. extrenalLB通过外界的LB调度器,均衡到service代理暴露的ingress-nginx(pod)端口,通过selector选择对应的ingress-nginx。ingress是将backend中的real主机的信息写入到ingress-nginx的配置文件中,因为代理的pods可能会随时丢失,随时重启,对应的pod属性也会改变,所以需要service来代理pods,ingress将监控service,并将信息写入到ingress-nginx中。
    2. 当然,externalLB---ingress-nginx---ingress controller这一步,可以将ingress controller以daemonset的控制方式,挂载在能够容忍某些指定污点的node上,直接对外暴露服务,不需要通过service代理,而是使用hostnetwork的方式,ingress-controller将会使用的是物理机的DNS域名解析(即物理机的/etc/resolv.conf)。而无法使用内部的coredns域名解析。

    二:原理

    2.1 ingress-controller工作原理

    ingress也是k8s api的标准资源类型之一,它其实就是一组基于DNS名称(host)或URL路径把请求转发到指定的service资源的规则。用于将集群外部的请求流量转发到集群内部完成的服务发布。我们需要明白的是,ingress资源自身不能进行“流量穿透”,仅仅是一组规则的集合,这些集合规则还需要其他功能的辅助,比如监听某套接字,然后根据这些规则的匹配进行路由转发,这些能够为ingress资源监听套接字并将流量转发的组件就是ingress controller。

    ingress控制器不同于deployment等pod控制器的是,ingress控制器不直接运行为kube-controller-manager的一部分,它仅仅是k8s集群的一个附件,类似于coreDNS,需要在集群上单独部署。

    ingress controller通过监视api server获取相关ingress、service、endpoint、secret、node、configmap对象,并在程序内部不断循环监视相关service是否有新的endpoint变化,一旦发生变化则自动更新nginx.conf模板配置并产生新的配置文件进行reload。

    2.2 ingress的部署原理 

     ingress的部署,需要考虑两个方面:

    1. ingress-controller是作为pod来运行的,以什么方式部署比较好?
    2. ingress解决了如何请求路由到集群内部,那它自己怎么暴露给外部比较好?

    下面列举一些目前常见的部署和暴露方式,具体使用哪种方式还是得根据实际需求来考勤决定。

    2.2.1 Deployment+LoadBalancer模式的service

    如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署igress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向改地址,就实现了集群服务的对外暴露。

    2.2.2 Deployment+NodePort模式的service

    同样用deployment模式部署ingress-controller,并创建对应的服务,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。改方式一般用于宿主机是相对固定的环境ip地址不变的场景。
    NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定的影响。

     

     备注:

    nodeport的部署思路就是通过在每个节点上开辟nodeport的端口,将流量引入进来,而后通过iptables首先转发到ingress-controller容器汇总(图中的nginx容器),而后由nginx根据ingress的规则进行判断,将其转发到对应的应用web容器中。因此 采用nodeport的部署较为简单。

    2.2.3 DaemonSet+HostNetwork(+nodeSelector)

    用DaemonSet 结合nodeselector来部署ingress-controller到特定的Node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/443端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房的入口nginx服务器。该方式整个请求链路最简单,性能相对nodeport模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。比较适合大并发的生产环境使用。

    2.2.4 hostnetwork的优势

    相比较起来,hostNetwork模式不再需要创建一个nodeport的svc,而是通过直接在每个节点都创建一个ingress-controller的容器,而且将改容器的网络模式设置为hostNetwork。也就是说每个节点物理机的80和443端口将会被ingress-controller中的nginx容器占用。当流量通过80/443端口进入时,将直接进入nginx中。而后nginx根据ingress规则再将流量转发到对应的web应用容器中。

    两种部署方式的比较:

    1. 相比较起来,nodeport部署模式中需要部署的ingress-ocntroller容器较少。一个集群可以部署几个就可以了。而hostNetwork模式需要在每个节点部署一个ingress-controller容器,因此总的消耗资源比较多;
    2. 另外一个比较直观的区别,nodePort模式主要占用的是svc的nodePort端口。而hostNetwork则需要占用物理机的80和443端口。
    3. 从网络流转来说,通过nodePort访问时,改node节点不一定部署了ingress-controller容器。因此还需要iptables将其将其转发到部署有ingress-controller的节点上(用的deployment方式),多了一层流转。
    4. 另外,通过nodePort访问时,nginx接收到的http请求中的source ip将会被转换为接受改请求的node节点的ip,而非真正的client ip。
    5. 使用hostNetwork的方式,ingress-controller将会使用的是物理机的DNS域名解析(即物理机的/etc/resolv.conf)。而无法使用内部的比如coredns域名解析。

    2.3 nginx反向代理原理

    Nginx-ingress 是 Kubernetes 生态中的重要成员,主要负责向外暴露服务,同时提供负载均衡等附加功能;截至目前,nginx-ingress 已经能够完成 7/4 层的代理功能(4 层代理基于 ConfigMap,感觉还有改进的空间);
    Nginx 的 7 层反向代理模式,可以简单用下图表示:

    Nginx 对后端运行的服务(Service1、Service2)提供反向代理,在配置文件中配置了域名与后端服务 Endpoints 的对应关系。客户端通过使用 DNS 服务或者直接配置本地的 hosts 文件,将域名都映射到 Nginx 代理服务器。当客户端访问 service1.com 时,浏览器会把包含域名的请求发送给 nginx 服务器,nginx 服务器根据传来的域名,选择对应的 Service,这里就是选择 Service 1 后端服务,然后根据一定的负载均衡策略,选择 Service1 中的某个容器接收来自客户端的请求并作出响应。过程很简单,nginx 在整个过程中仿佛是一台根据域名进行请求转发的“路由器”,这也就是7层代理的整体工作流程了!
           对于 Nginx 反向代理做了什么,我们已经大概了解了。在 k8s 系统中,后端服务的变化是十分频繁的,单纯依靠人工来更新nginx 的配置文件几乎不可能,nginx-ingress 由此应运而生。Nginx-ingress 通过监视 k8s 的资源状态变化实现对 nginx 配置文件的自动更新,下面本文就来分析下其工作原理。

    2.4 ingress controller工作流程分析

    首先,上一张整体工作模式架构图(只关注配置同步更新):

    不考虑 nginx 状态收集等附件功能,nginx-ingress 模块在运行时主要包括三个主体:NginxController、Store、SyncQueue。其中: 

    1. Store 主要负责从 kubernetes APIServer 收集运行时信息,感知各类资源(如 ingress、service等)的变化,并及时将更新事件消息(event)写入一个环形管道;

    2. SyncQueue 协程定期扫描 syncQueue 队列,发现有任务就执行更新操作,即借助 Store 完成最新运行数据的拉取,然后根据一定的规则产生新的 nginx 配置,(有些更新必须 reload,就本地写入新配置,执行 reload),然后执行动态更新操作,即构造 POST 数据,向本地 Nginx Lua 服务模块发送 post 请求,实现配置更新;

    3. NginxController 作为中间的联系者,监听 updateChannel,一旦收到配置更新事件,就向同步队列 syncQueue 里写入一个更新请求。


    三:部署nginx-ingress-controller

    3.1 部署ingress-controller pod及相关资源

    1. 1.mkdir /opt/ingress
    2. 2.cd /opt/ingress
    3. ==========================================================
    4. 官方下载地址:
    5. wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
    6. 上面可能无法下载,可用国内的gitee
    7. 3.wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
    8. wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
    9. #mandatory.yaml文件中包含了很多资源的创建,包括namespace、configMap、role,ServiceAccount等等所有部署ingress-controller需要的资源

    3.2 修改clusterRole资源配置  

    1. vim mandatory.yaml
    2. ....
    3. - apiGroups:
    4. - ""
    5. resources:
    6. -services
    7. verbs:
    8. - get
    9. - list
    10. - watch
    11. - apiGroups:
    12. - "extensions"
    13. - "networking.k8s.io"#增加(0.25版本)
    14. resources:
    15. - ingresses
    16. verbs:
    17. - get
    18. - list
    19. - watch
    20. - apiGroups:
    21. - ""
    22. resources:
    23. - events
    24. verbs:
    25. - create
    26. - patch
    27. - apiGroups:
    28. - "extensions"
    29. - "networking.k8s.io"#增加(o.25版本)
    30. resources:
    31. - ingresses/ status
    32. verbs:
    33. - update

    3.3 ingress暴露服务的方式  

    Deployment+LoadBalancer模式的Service

    如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个type为 LoadBalancer的 service关联这组pod。大部分公有云,都会为 LoadBalancer的 service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向该地址,就实现了集群服务的对外暴露

    DaemonSet+HostNetwork+nodeselector

    用DaemonSet结合nodeselector来部署ingress-controller到特定的node 上,然后使用Hostiletwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。比较适合大并发的生产环境使用

    Deployment+NodePort模式的Service

    1)同样用deployment模式部署ingres-controller,并创建对应的服务,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上
    2)由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景
    3)NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响

    3.4 采用方式二:DaemonSet+HostNetwork+nodeselector 

    3.4.1 指定nginx-ingress-controller运行在node02节点

    1. kubectl label node node02 ingress=true
    2. kubectl get nodes --show-labels

    3.4.2 修改Deployment为Daemonset,指定节点运行,并开启 hostNetwork 

    1. vim mandatory.yaml
    2. ...
    3. apiversion: apps/vl
    4. kind: Daemonset #修改kind
    5. ...
    6. hostNetwork: true #使用主机网络
    7. nodeSelector:
    8. ingress: "true" #选择节点运行
    9. ...

    3.4.3 所有node节点上传nginx-ingress-controller镜像压缩包ingree.contro.tar.gz.到/opt/ingress目录,并解压和加载镜像  

    1. mkdir /opt/ingress
    2. cd /opt/ingress
    3. tar zxvf ingree.contro.tar.gz
    4. docker load -i ingree.contro.tar

    3.4.4 启动nginx-ingress-controller  

    1. #主节点
    2. kubectl apply -f mandatory.yaml
    3. kubectl get pod -n ingress-nginx -o wide

    1. 到node02节点查看
    2. netstat -natp | grep nginx
    3. ==========================================================
    4. 由于配置了hostnetwork, nginx已经在 node主机本地监听团/443/8181端口。其中 8181 是nginx-controller默认配置的一个defaultbackend (Ingress资源没有匹配的 rule 对象时,流量就会被导向这个default backend)
    5. 这样,只要访问 node主机有公网 TP,就可以直接映射域名来对外网暴露服务了。如果要nginx高可用的话,可以在多个node39上部署,并在前面再搭建一套LVS+keepalive做负载均衡。

    3.4.5 创建ingress规则  

    创建一个deployment和svc

    1. 在主节点创建
    2. vim service-nginx.yaml
    3. ==========================================================
    4. apiVersion: apps/v1
    5. kind: Deployment
    6. metadata:
    7. labels:
    8. run: nginx-app
    9. name: nginx-app
    10. spec:
    11. replicas: 2
    12. selector:
    13. matchLabels:
    14. app: nginx
    15. template:
    16. metadata:
    17. labels:
    18. app: nginx
    19. spec:
    20. containers:
    21. - image: nginx
    22. name: nginx-app
    23. ports:
    24. - containerPort: 80
    25. ---
    26. apiVersion: v1
    27. kind: Service
    28. metadata :
    29. name: nginx-service
    30. spec:
    31. type: ClusterIP
    32. ports :
    33. - port: 7777
    34. targetPort: 80
    35. selector :
    36. app: nginx
    37. ==========================================================
    38. kubectl apply -f service-nginx.yaml
    39. kubectl get pod,svc

    3.4.6 创建ingress  

    1. vim ingress-1.yaml
    2. ==========================================================
    3. apiVersion: extensions/v1beta1
    4. kind: Ingress
    5. metadata:
    6. name: nginx-ingress
    7. spec:
    8. rules:
    9. - host: www.gxd.com
    10. http:
    11. paths:
    12. - path: /
    13. backend:
    14. serviceName: nginx-service #指定你创建的svc的名称
    15. servicePort: 80
    16. ==========================================================
    17. kubectl apply -f ingress-1.yaml
    18. kubectl get pod,svc,ingress

    3.4.7 做端口映射并访问测试  

    1. echo '192.168.10.30 www.gxd.com' >> /etc/hosts
    2. curl www.gxd.com

    3.4.8 查看nginx-ingress-controller  

    1. kubectl get pod -n ingress-nginx -o wide
    2. kubectl exec -it nginx-ingress-controller-k5vvf -n ingress-nginx bash

    3.5 采用方式三:Deployment+NodePort模式的Service  

    3.5.1 下载nginx-ingress-controller和ingress-nginx暴露端口配置文件 

    1. 在主节点
    2. mkdir /opt/ingress-nodeport
    3. cd /opt/ingress-nodeport
    4. 官方下载地址:
    5. wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
    6. wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
    7. 国内 gitee 资源地址:
    8. wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
    9. wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

     

    3.5.2 在所有node节点上传镜像包ingress-controller-0.30.0.tar到/opt/ingress-nodeport目录,并加载镜像 

    1. 在所有node节点
    2. mkdir /opt/ingress-nodeport
    3. cd /opt/ingress-nodeport
    4. tar zxvf ingree.contro-0.30.0.tar.gz
    5. docker load -i ingree.contro-0.30.0.tar

    3.5.3 启动nginx-ingress-controller  

    1. kubectl apply -f mandatory.yaml
    2. kubectl apply -f service-nodeport.yaml

    3.5.4 创建deployment、service和ingress的yaml资源  

    1. vim ingress-nginx.yaml
    2. ==========================================================
    3. apiVersion: extensions/v1beta1
    4. kind: Deployment
    5. metadata:
    6. name: nginx-app
    7. spec:
    8. replicas: 2
    9. template:
    10. metadata:
    11. labels:
    12. name: nginx
    13. spec:
    14. containers:
    15. - name: nginx
    16. image: nginx
    17. imagePullPolicy: IfNotPresent
    18. ports:
    19. - containerPort: 80
    20. ---
    21. apiVersion: v1
    22. kind: Service
    23. metadata:
    24. name: nginx-svc
    25. spec:
    26. ports:
    27. - port: 80
    28. targetPort: 80
    29. protocol: TCP
    30. selector:
    31. name: nginx
    32. ---
    33. apiVersion: extensions/v1beta1
    34. kind: Ingress
    35. metadata:
    36. name: nginx-test
    37. spec:
    38. rules:
    39. - host: www.gxd111.com
    40. http:
    41. paths:
    42. - path: /
    43. backend:
    44. serviceName: nginx-svc
    45. servicePort: 80
    46. ==========================================================kubectl apply -f ingress-nginx.yaml
    47. kubectl get pod,svc,ingress -owide

    3.5.5 做端口映射并访问测试  

    1. echo '192.168.10.30 www.gxd111.com' >> /etc/hosts
    2. curl www.gxd111.com

    3.5.6 ingress http代理访问虚拟主机  

    1. mkdir /opt/ingress-nodeport/vhost
    2. cd /opt/ingress-nodeport/vhost
    3. ==========================================================
    4. #创建虚拟主机1资源
    5. vim demo1.yaml
    6. apiVersion: extensions/v1beta1
    7. kind: Deployment
    8. metadata:
    9. name: deployment1
    10. spec:
    11. replicas: 2
    12. template:
    13. metadata:
    14. labels:
    15. name: nginx1
    16. spec:
    17. containers:
    18. - name: nginx1
    19. image: nginx
    20. ports:
    21. - containerPort: 80
    22. ---
    23. apiVersion: v1
    24. kind: Service
    25. metadata:
    26. name: svc-1
    27. spec:
    28. ports:
    29. - port: 80
    30. protocol: TCP
    31. targetPort: 80
    32. selector:
    33. name: nginx1
    34. type: ClusterIP
    35. ==========================================================
    36. #创建虚拟主机2资源
    37. vim demo2.yaml
    38. apiVersion: extensions/v1beta1
    39. kind: Deployment
    40. metadata:
    41. name: deployment2
    42. spec:
    43. replicas: 2
    44. template:
    45. metadata:
    46. labels:
    47. name: nginx2
    48. spec:
    49. containers:
    50. - name: nginx2
    51. image: nginx
    52. ports:
    53. - containerPort: 80
    54. ---
    55. apiVersion: v1
    56. kind: Service
    57. metadata:
    58. name: svc-2
    59. spec:
    60. ports:
    61. - port: 80
    62. protocol: TCP
    63. targetPort: 80
    64. selector:
    65. name: nginx2
    66. type: ClusterIP
    67. ==========================================================
    68. 创建ingress资源
    69. vim ingress-nginx.yaml
    70. apiVersion: extensions/v1beta1
    71. kind: Ingress
    72. metadata:
    73. name: ingress1
    74. spec:
    75. rules:
    76. - host: www1.gxd.com
    77. http:
    78. paths:
    79. - path: /
    80. backend:
    81. serviceName: svc-1
    82. servicePort: 80
    83. ---
    84. apiVersion: extensions/v1beta1
    85. kind: Ingress
    86. metadata:
    87. name: ingress2
    88. spec:
    89. rules:
    90. - host: www2.gxd.com
    91. http:
    92. paths:
    93. - path: /
    94. backend:
    95. serviceName: svc-2
    96. servicePort: 80
    97. ==========================================================
    98. kubectl apply -f demo1.yaml
    99. kubectl apply -f demo2.yaml
    100. kubectl apply -f ingress-nginx.yaml
    101. kubectl get pod,svc,ingress

    1. echo '192.168.10.30 www1.gxd.com ' >> /etc/hosts
    2. echo '192.168.10.30 www2.gxd.com ' >> /etc/hosts
    3. curl www1.gxd.com:31396
    4. curl www2.gxd.com:31396

    3.5.7 ingress https代理访问  

    创建工作目录

    1. mkdir /opt/ingress-nodeport/https
    2. cd /opt/ingress-nodeport/https

    创建ssl证书 

    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj  "/CN=nginXsvc/O=nginxsvc"
    

    创建secret资源进行存储 

    1. kubectl create secret tls tls-secret --key tls.key --cert tls.crt
    2. kubectl get secret
    3. kubectl describe secret tls-secret

    创建deployment、service和ingress的yaml资源 

    1. vim demo3.yaml
    2. ==========================================================
    3. apiVersion: extensions/v1beta1
    4. kind: Deployment
    5. metadata:
    6. name: nginx-app
    7. spec:
    8. replicas: 2
    9. template:
    10. metadata:
    11. labels:
    12. name: nginx
    13. spec:
    14. containers:
    15. - name: nginx
    16. image: nginx
    17. imagePullPolicy: IfNotPresent
    18. ports:
    19. - containerPort: 80
    20. ---
    21. apiVersion: v1
    22. kind: Service
    23. metadata:
    24. name: svc-3
    25. spec:
    26. ports:
    27. - port: 80
    28. targetPort: 80
    29. protocol: TCP
    30. selector:
    31. name: nginx
    32. ---
    33. apiVersion: extensions/v1beta1
    34. kind: Ingress
    35. metadata:
    36. name: ingress3
    37. spec:
    38. tls:
    39. - hosts:
    40. - www.gxd222.com
    41. secretName: tls-secret
    42. rules:
    43. - host: www.gxd222.com
    44. http:
    45. paths:
    46. - path: /
    47. backend:
    48. serviceName: svc-3
    49. servicePort: 80
    50. ==========================================================kubectl apply -f demo3.yaml
    51. kubectl get pod,svc,ingress

    做端口映射并访问测试

    1. echo '192.168.10.30 www.gxd222.com' >> /etc/hosts
    2. 在浏览器访问 https://www.gxd222.com:31067
    3. 点击高级选项,确认安全例外即可

    3.5.8 nginx进行BasicAuth(访问前输入用户和密码)  

    创建工作目录

    1. mkdir /opt/ingress-nodeport/basic-auth
    2. cd /opt/ingress-nodeport/basic-auth

    生成用户密码文件,创建secret资源进行存储 

    1. yum install -y httpd
    2. htpasswd -c auth gxd
    3. kubectl create secret generic basic-auth --from-file=auth
    4. kubectl get secret
    5. kubectl describe secret basic-auth

    创建ingress资源 

    1. //具体详细设置方法可参考官网https://kubernetes.github.io/ingress-nginx/examples/auth/basic/
    2. vim ingress-auth.yaml
    3. ==========================================================
    4. apiVersion: extensions/v1beta1
    5. kind: Ingress
    6. metadata:
    7. name: ingress-auth
    8. annotations:
    9. #设置认证类型basic
    10. nginx.ingress.kubernetes.io/auth-type: basic
    11. #设置secret资源名称basic-auth
    12. nginx.ingress.kubernetes.io/auth-secret: basic-auth
    13. #设置认证窗口提示信息
    14. nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - gxd'
    15. spec:
    16. rules:
    17. - host: auth.gxd.com
    18. http:
    19. paths:
    20. - path: /
    21. backend:
    22. serviceName: svc-2 #之前指定创建过的svc
    23. servicePort: 80
    24. ==========================================================
    25. kubectl apply -f ingress-auth.yaml
    26. kubectl get ingress

    做端口映射并访问测试 

    1. echo '192.168.10.30 auth.gxd.com' >> /etc/hosts
    2. 在浏览器访问 http://auth.gxd.com:31396

    3.5.9 nginx进行重写 

    配置说明

    1. nginx.ingress.kubernetes.io/rewrite-target:<字符串>#必须重定向流量的目标URI
    2. nginx.ingress . kubernetes.io/ssl-redirect:<布尔值>指示位置部分是否仅可访问sSL(当Ingress包含证书时,默认为true)nginx.ingress . kubernetes.io/force-ssl-redirect:<布尔值>#即使Ingress未启用rLS,也强制重定向到HTTPS
    3. nginx.ingress .kubernetes.io/app-root:<字符串>#定义controller必须重定向的应用程序根,如果它在'/'上下文中·nginx.ingress, kubernetes.io/use-regex:<布尔值>#指示Ingress.上定义的路径是否使用正则表达式

    编写yaml文件

    1. vim ingress-rewrite.yaml
    2. ==========================================================
    3. apiVersion: extensions/v1beta1
    4. kind: Ingress
    5. metadata:
    6. name: nginx-rewrite
    7. annotations:
    8. nginx.ingress.kubernetes.io/rewrite-target: http://auth.gxd.com:31396
    9. spec:
    10. rules:
    11. - host: rewrite.gxd.com
    12. http:
    13. paths:
    14. - path: /
    15. backend:
    16. serviceName: ggggg #由于rewrite.gxd.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义
    17. servicePort: 1111
    18. ==========================================================
    19. kubectl apply -f ingress-rewrite.yaml
    20. kubectl get ingress

    做端口映射并访问测试 

    1. echo '192.168.10.30 rewrite.gxd.com' >> /etc/hosts
    2. 在浏览器访问 http://rewrite.gxd.com

  • 相关阅读:
    突发,Anthropic推出突破性Claude 3系列模型,性能超越GPT-4
    数据流的中位数 [双堆&桶的使用]
    C++哈希表、哈希桶的实现以及模拟实现封装unordered_map 和 unordered_set && 位图 && 布隆过滤器 && 哈希切割相关
    flex布局实现 内容区域高度自适应
    【图片+代码】:GCC 链接过程中的【重定位】过程分析
    ValueError: invalid literal for int() with base 10: 'CLS'
    javascript高级(3)
    <数据集>Udacity交通目标识别数据集<目标检测>
    uniapp列表进入动画
    Java日志系列——规范化日志
  • 原文地址:https://blog.csdn.net/ver_mouth__/article/details/126246108