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的优势

三、部署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

  1. 具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现转发。
  2. 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-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller改如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。

1.3 ingress介绍

可能从大致印象上就是能利用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组成

  1. ingress-nginx-controller:根据用户编写的ingress规则(创建的ingress的yaml文件),动态的去更改nginx服务的配置文件,并且reload重载使其失效(是自动化的,通过脚本来是实现的);
  2. 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域名解析。

三、部署nginx-ingress-controller

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

1.mkdir /opt/ingress
2.cd /opt/ingress
==========================================================
官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml

上面可能无法下载,可用国内的gitee
3.wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml

wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml

#mandatory.yaml文件中包含了很多资源的创建,包括namespace、configMap、role,ServiceAccount等等所有部署ingress-controller需要的资源

img

3.2 修改clusterRole资源配置 

vim mandatory.yaml
....
- apiGroups:
    - ""
  resources:
    -services
  verbs:
    - get
    - list
    - watch
- apiGroups:
    - "extensions"
    - "networking.k8s.io"#增加(0.25版本)
  resources:
    - ingresses
  verbs:
    - get
    - list
    - watch
- apiGroups:
    - ""
  resources:
    - events
  verbs:
    - create
    - patch
- apiGroups:
    - "extensions"
    - "networking.k8s.io"#增加(o.25版本)
  resources:
    - ingresses/ status
  verbs:
    - update

img

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节点

kubectl label node node02 ingress=true

kubectl get nodes --show-labels

img

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

vim mandatory.yaml
...
apiversion: apps/vl
kind: Daemonset   #修改kind
...
hostNetwork: true  #使用主机网络
nodeSelector:
  ingress: "true"   #选择节点运行
...

img 

img 

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

mkdir /opt/ingress
cd /opt/ingress
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar

img

3.4.4 启动nginx-ingress-controller 

#主节点
kubectl apply -f mandatory.yaml

kubectl get pod -n ingress-nginx -o wide

img

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

img

3.4.5 创建ingress规则 

创建一个deployment和svc

在主节点创建
vim service-nginx.yaml
==========================================================
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: nginx-app
  name: nginx-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx-app
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata :
  name: nginx-service
spec:
  type: ClusterIP
  ports :
  - port: 7777
    targetPort: 80
  selector :
   app: nginx
==========================================================
kubectl apply -f service-nginx.yaml

kubectl get pod,svc

img

3.4.6  创建ingress 

vim ingress-1.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:
  - host: www.gxd.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service  #指定你创建的svc的名称
          servicePort: 80
==========================================================
kubectl apply -f ingress-1.yaml

kubectl get pod,svc,ingress

img

3.4.7 做端口映射并访问测试 

echo '192.168.10.30 www.gxd.com' >> /etc/hosts

curl www.gxd.com

img

3.4.8 查看nginx-ingress-controller 

kubectl get pod -n ingress-nginx -o wide

kubectl exec -it nginx-ingress-controller-k5vvf  -n ingress-nginx bash

img

img

img

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

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

在主节点
mkdir /opt/ingress-nodeport
cd /opt/ingress-nodeport

官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

国内 gitee 资源地址:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

img 

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

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

img

3.5.3  启动nginx-ingress-controller 

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

img

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

vim ingress-nginx.yaml 
==========================================================
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-app
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-test
spec:
  rules:
    - host: www.gxd111.com
      http:
        paths:
        - path: /
          backend:
            serviceName: nginx-svc
            servicePort: 80
==========================================================kubectl apply -f ingress-nginx.yaml                       
kubectl get pod,svc,ingress -owide

img

3.5.5 做端口映射并访问测试 

echo '192.168.10.30 www.gxd111.com' >> /etc/hosts

curl www.gxd111.com

img

3.5.6 ingress http代理访问虚拟主机 

mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost
==========================================================
#创建虚拟主机1资源
vim demo1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment1
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx1
    spec:
      containers:
        - name: nginx1
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    name: nginx1
  type: ClusterIP
==========================================================
#创建虚拟主机2资源
vim demo2.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: deployment2
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx2
    spec:
      containers:
        - name: nginx2
          image: nginx
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-2
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    name: nginx2
  type: ClusterIP
==========================================================
创建ingress资源
vim ingress-nginx.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress1
spec:
  rules:
    - host: www1.gxd.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-1
            servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress2
spec:
  rules:
    - host: www2.gxd.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-2
            servicePort: 80
==========================================================
kubectl apply -f demo1.yaml
kubectl apply -f demo2.yaml
kubectl apply -f ingress-nginx.yaml
kubectl get pod,svc,ingress

img

echo '192.168.10.30 www1.gxd.com ' >> /etc/hosts
echo '192.168.10.30 www2.gxd.com ' >> /etc/hosts
curl www1.gxd.com:31396
curl www2.gxd.com:31396

img

3.5.7 ingress https代理访问 

创建工作目录

mkdir /opt/ingress-nodeport/https
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"

img

创建secret资源进行存储 

kubectl create secret tls tls-secret --key tls.key --cert tls.crt

kubectl get secret

kubectl describe secret tls-secret

img

创建deployment、service和ingress的yaml资源 

vim demo3.yaml 
==========================================================
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-app
spec:
  replicas: 2
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc-3
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress3
spec:
  tls:
    - hosts: 
      - www.gxd222.com
      secretName: tls-secret
  rules: 
    - host: www.gxd222.com
      http:
        paths:
        - path: /
          backend:
            serviceName: svc-3
            servicePort: 80
==========================================================kubectl apply -f demo3.yaml                       
kubectl get pod,svc,ingress 

img

做端口映射并访问测试 

echo '192.168.10.30 www.gxd222.com' >> /etc/hosts

在浏览器访问 https://www.gxd222.com:31067
点击高级选项,确认安全例外即可

img 

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

创建工作目录

mkdir /opt/ingress-nodeport/basic-auth
cd /opt/ingress-nodeport/basic-auth

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

yum install -y httpd
htpasswd -c auth gxd
kubectl create secret generic basic-auth --from-file=auth
kubectl get secret
kubectl describe secret basic-auth

img

创建ingress资源 

//具体详细设置方法可参考官网https://kubernetes.github.io/ingress-nginx/examples/auth/basic/

vim ingress-auth.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-auth
  annotations:
    #设置认证类型basic
    nginx.ingress.kubernetes.io/auth-type: basic
    #设置secret资源名称basic-auth
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    #设置认证窗口提示信息
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - gxd'
spec:
  rules:
  - host: auth.gxd.com
    http:
      paths:
      - path: /
        backend:
          serviceName: svc-2  #之前指定创建过的svc
          servicePort: 80
==========================================================
kubectl apply -f ingress-auth.yaml 
kubectl get ingress

img做端口映射并访问测试 

echo '192.168.10.30 auth.gxd.com' >> /etc/hosts

在浏览器访问 http://auth.gxd.com:31396

imgimg

3.5.9 nginx进行重写 

配置说明

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

编写yaml文件 

vim ingress-rewrite.yaml
==========================================================
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-rewrite
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: http://auth.gxd.com:31396
spec:
  rules:
  - host: rewrite.gxd.com
    http:
      paths:
      - path: /
        backend:
          serviceName: ggggg  #由于rewrite.gxd.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义
          servicePort: 1111 
==========================================================
kubectl apply -f ingress-rewrite.yaml
kubectl get ingress

img

做端口映射并访问测试 

echo '192.168.10.30 rewrite.gxd.com' >> /etc/hosts

在浏览器访问 http://rewrite.gxd.com

imgimg

猜你喜欢

转载自blog.csdn.net/weixin_67470255/article/details/126227743