当前位置:   article > 正文

【云原生】Kubernetes----Ingress对外服务

【云原生】Kubernetes----Ingress对外服务

目录

引言

一、K8S对外方式

(一)NodePort

1.作用

2.弊端

3.示例

(二)externalIPs

1.作用

2.弊端

3.示例

(三)LoadBalancer

1.作用

2.弊端

(四)Ingress

二、Ingress的基本概念

(一)基本概念

(二)Ingress组成

1.ingress

2.ingress-controller

3.关系归纳

(三)Ingress的工作原理

(四)访问流程

三、配置Ingress规则

(一)ingress暴露服务方式

(二)方式二搭建

1.获取资源

1.1 获取配置文件

1.2 获取镜像资源

2.修改ClusterRole资源配置

3.修改nginx-ingress-controller配置

4.创建资源

4.1 创建ingress-controller

4.2 创建pod与service

5.创建ingress规则

6.客户端访问

(三)方式三搭建

1.清空环境

2.获取文件

3.创建代理资源

3.1 创建nginx-ingress-controller资源

3.2 创建service资源

4.创建访问资源

4.1 创建Deployment

4.2 创建service

4.3 创建Ingress规则

5.使用客户端进行访问

四、虚拟主机

(一)创建pod资源

(二)创建service资源

(三)创建ingress规则

(四)客户端访问

五、HTPPS代理

(一)获取SSL证书

(二)创建Kubernetes Secret

(三)创建pod资源

(四)创建service

(五)创建ingress规则

(六)客户端访问

六、实现BasicAuth

(一)创建认证文件

1.下载htpasswd工具

2.创建认证文件

(二)创建Secret

(三)创建pod资源

(四)创建service

(五)创建ingress资源

七、Nginx重写


引言

随着Kubernetes在云原生应用领域的广泛应用,如何高效地管理集群的外部流量成为了许多开发者和管理员面临的挑战。在Kubernetes中,Ingress提供了一个标准化的方式来管理外部流量到集群内部服务的路由,从而简化了流量管理的复杂性。本文将介绍Ingress的基本概念、工作原理以及如何使用Ingress来优化你的Kubernetes集群的流量路由

一、K8S对外方式

在Kubernetes(k8s)中,使外部应用能够访问集群内的服务主要有四种方式

(一)NodePort

1.作用

NodePort服务类型将服务暴露在每个Kubernetes节点的相同端口上。外部用户可以通过访问任何节点的IP地址和该端口来访问服务。

2.弊端

NodePort背后就是Kube-Proxy,Kube-Proxy是沟通service网络、Pod网络和节点网络的桥梁。
测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理就是个灾难。因为每个端口只能是一种服务,端口范围只能是 30000-32767

3.示例

  1. [root@master01 pod]#vim deployment.yaml
  2. [root@master01 pod]#cat deployment.yaml
  3. apiVersion: apps/v1
  4. kind: Pod
  5. metadata:
  6. name: nginx-pod
  7. labels:
  8. app: nginx
  9. spec:
  10. containers:
  11. - name: nginx
  12. image: nginx:1.18.0
  13. ports:
  14. - containerPort: 80
  15. ---
  16. apiVersion: v1
  17. kind: Service #创建service
  18. metadata:
  19. name: nginx-svc
  20. labels:
  21. app: nginx
  22. spec:
  23. type: NodePort #type类型为NodePort,用于对外提供服务
  24. ports:
  25. - port: 80
  26. targetPort: 80
  27. selector:
  28. app: nginx

执行完yaml文件之后,查看地址与映射端口

  1. [root@master01 pod]#kubectl apply -f pod.yaml
  2. pod/nginx-pod created
  3. service/nginx-svc created
  4. [root@master01 pod]#
  5. [root@master01 pod]#kubectl get pod -owide
  6. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  7. nginx-pod 1/1 Running 0 14s 10.244.2.3 node02 <none> <none>
  8. [root@master01 pod]#kubectl get svc
  9. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  10. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17d
  11. nginx-svc NodePort 10.96.131.227 <none> 80:30425/TCP 31s
  12. #使用客户端访问任意节点的30425端口

使用客户端进行访问

  1. [root@nfs ~]#curl 192.168.83.30:30425 -I
  2. HTTP/1.1 200 OK
  3. Server: nginx/1.18.0
  4. Date: Mon, 03 Jun 2024 06:55:53 GMT
  5. Content-Type: text/html
  6. Content-Length: 612
  7. Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
  8. Connection: keep-alive
  9. ETag: "5e9efe7d-264"
  10. Accept-Ranges: bytes

(二)externalIPs

1.作用

Kubernetes中的externalIPs允许将一个或多个外部IP地址直接绑定到一个Kubernetes服务上,从而可以通过这些外部IP地址直接访问该服务

2.弊端

当使用externalIPs时,外部流量将直接通过指定的IP地址进入集群,这可能增加了集群的安全风险。攻击者可能会利用这些外部IP地址对集群进行攻击,如拒绝服务攻击(DoS)、中间人攻击(MITM)等。不支持负载均衡和故障转移

3.示例

  1. [root@master01 pod]#cat pod02.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx-pod02
  6. labels:
  7. app: nginx
  8. spec:
  9. nodeName: node02
  10. #pod需要使用节点亲和,指定pod建立在externalIPs指定nodeIP地址之外
  11. #同样IP可能导致网络数据包的路由变得混乱,使得Kubernetes集群内外的网络无法正确区分和处理流量
  12. #如果使用deployment建立的pod,则externalIPs只会非本节点的pod实例
  13. containers:
  14. - name: nginx
  15. image: nginx:1.18.0
  16. ports:
  17. - containerPort: 80
  18. ---
  19. apiVersion: v1
  20. kind: Service
  21. metadata:
  22. name: nginx-svc02
  23. labels:
  24. app: nginx
  25. spec:
  26. externalIPs: #指定pod绑定地址
  27. - 192.168.83.40 #绑定到node01节点的IP上
  28. ports:
  29. - port: 80
  30. targetPort: 80
  31. selector:
  32. app: nginx

创建后,查看服务

  1. [root@master01 pod]#kubectl apply -f pod02.yaml
  2. pod/nginx-pod02 created
  3. service/nginx-svc02 created
  4. [root@master01 pod]#kubectl get pod nginx-pod02
  5. [root@master01 pod]#kubectl get pod nginx-pod02 -owide
  6. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  7. nginx-pod02 1/1 Running 0 5s 10.244.2.4 node02 <none> <none>
  8. [root@master01 pod]#kubectl get svc nginx-svc02
  9. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  10. nginx-svc02 ClusterIP 10.96.42.161 192.168.83.40 80/TCP 14s

客户端直接访问节点即可

  1. [root@nfs ~]#curl 192.168.83.40 -I
  2. HTTP/1.1 200 OK
  3. Server: nginx/1.18.0
  4. Date: Mon, 03 Jun 2024 07:08:42 GMT
  5. Content-Type: text/html
  6. Content-Length: 612
  7. Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
  8. Connection: keep-alive
  9. ETag: "5e9efe7d-264"
  10. Accept-Ranges: bytes

(三)LoadBalancer

1.作用

LoadBalancer服务类型允许外部负载均衡器将流量路由到Kubernetes集群中的服务。

这种方式通常用于云服务提供商(如AWS、Azure、GCP等),它们可以自动创建一个负载均衡器并为其分配一个外部IP地址。

2.弊端

这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。受限于云平台,且通常在云平台部署LoadBalancer还需要额外的费用

(四)Ingress

  • Ingress是Kubernetes中的一个API对象,它管理外部访问到集群内服务的HTTP和HTTPS路由规则。
  • 通常与Ingress Controller一起使用,Ingress Controller是一个反向代理服务器,负责实现Ingress定义的路由规则。
  • Ingress可以基于域名、路径或其他HTTP请求属性进行流量路由。
  • 配置Ingress需要创建Ingress对象并定义路由规则,同时还需要部署Ingress Controller。
  • Ingress提供了比LoadBalancer更高级的路由和流量管理功能。

二、Ingress的基本概念

(一)基本概念

在Kubernetes中,Ingress是一个API对象,它用于定义集群外部访问内部服务的规则。通过Ingress,可以配置基于主机名、路径等条件的路由规则,将外部流量转发到集群内的一个或者多个service。Ingress提供了一种统一的、声明式的方式来管理外部流量,使得流量路由更加灵活和可配置。

Ingress资源本身不会进行任何网络流量的路由,它依赖于Ingress控制器(如Nginx Ingress Controller、HAProxy Ingress Controller、Traefik等)来根据Ingress资源中定义的规则进行实际的路由

(二)Ingress组成

1.ingress

  • 定义:Ingress是一个Kubernetes API对象,通常使用YAML文件进行配置。它主要的作用是定义请求如何转发到集群内部服务的规则。
  • 功能:Ingress提供了负载均衡、SSL和基于名称的虚拟托管。通过Ingress,可以定义服务外部可访问的URL、负载均衡流量、SSL/TLS配置,以及基于名称的虚拟主机。
  • 特点:Ingress可以被视为一种配置模板,用于描述外部访问集群内部服务的方式。它定义了集群外部流量如何进入集群内各个服务的路由规则,但它本身无法直接实现这些路由。

2.ingress-controller

  • 定义:Ingress Controller是具体实现Ingress规则的程序。它与Kubernetes API交互,动态地感知集群中Ingress规则的变化,并按照这些规则生成相应的配置文件(例如Nginx的配置文件)。
  • 功能:Ingress Controller负责处理实际的流量转发工作,确保外部请求能够正确地路由到集群内部的Service。它实现了反向代理及负载均衡的功能,确保外部请求能够高效地路由到集群内部的服务。
  • 特点:Ingress Controller监听Ingress资源对象的变更,并根据Ingress规则进行配置。通常,Ingress Controller通过负载均衡器(如Nginx、Traefik等)来实现其功能。

ingress-controller并不是k8s自带的组件,实际上ingress-controller只是一个统称,用户可以选择不同的ingress-controller实现

目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,其他还有很多第三方维护的ingress-controller,具体可以参考官方文档。

但是不管哪一种ingress-controller,实现的机制都大同小异,只是在具体配置上有差异。

一般来说,ingress-controller的形式都是一个pod,里面跑着daemon程序和反向代理程序。daemon负责不断监控集群的变化,根据 ingress对象生成配置并应用新配置到反向代理

比如ingress-nginx就是动态生成nginx配置,动态更新upstream,并在需要的时候reload程序应用新配置。为了方便,后面的例子都以k8s官方维护的ingress-nginx为例。

3.关系归纳

  • Ingress定义了请求转发的规则,这些规则描述了外部流量如何进入集群内的各个服务。
  • Ingress Controller负责实现这些规则,并与Kubernetes API交互,动态地感知并应用Ingress规则的变化。
  • 要使Ingress资源生效,集群中必须有一个正在运行的Ingress Controller来读取这些规则并相应地进行流量转发。

总结:ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到 ingress-controller, 而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名、哪些URL要转发到哪些service等等

(三)Ingress的工作原理

Ingress的工作原理可以简单概括为以下几个步骤

监听Ingress对象:Ingress Controller通过Kubernetes API服务器监听Ingress对象的变化。当新的Ingress对象被创建、更新或删除时,Ingress Controller能够感知到这些变化。

解析Ingress规则:Ingress Controller解析Ingress对象中定义的规则。这些规则包括主机名、路径、后端服务等信息,用于确定如何将流量路由到集群内的不同服务。

生成配置:Ingress Controller将解析后的规则转化为特定负载均衡器(如Nginx、HAProxy等)可以理解的配置。这些配置通常包括反向代理设置、负载均衡策略、SSL/TLS配置等。再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中

动态更新:Ingress Controller能够实时响应Ingress对象的变化,并动态更新其配置。这意味着当Ingress规则发生变化时,无需重启Ingress Controller或整个集群,流量路由将自动更新以适应新的规则。

(四)访问流程

1.客户端访问域名,通过DNS解析到Ingress-confoller所在的节点

2.同时客户端向Ingress-confoller所在的节点发送HTTP/HTTPS请求

3.Ingress-confoller通过Ingress的配置信息(URL、域名等),确定将请求转发到哪一个service,而后根据service关联的pod地址,决定Ingress-confoller将请求转发到pod当中。

三、配置Ingress规则

(一)ingress暴露服务方式

ingress 暴露服务的方式有以下三种

方式一:Deployment+LoadBalancer 模式的 Service

这是公有云环境中非常常见的方式。在Kubernetes集群中,可以使用Deployment来部署Ingress Controller的Pod,并创建一个类型为LoadBalancer的Service来将Pod暴露到外部。在公有云环境中,当创建LoadBalancer类型的Service时,云提供商通常会为你自动创建一个负载均衡器(例如AWS的ELB,Azure的LB等),并且通常还会为你分配一个公网IP地址。你只需要将你的域名解析到这个公网IP地址,就可以通过Ingress来访问你的服务了

优点

  1. 自动化与便捷性:在公有云环境中,创建LoadBalancer类型的Service会自动为你创建负载均衡器,并分配公网IP,简化了配置过程。
  2. 高可用性:负载均衡器通常具有容错和故障转移的能力,保证服务的稳定性。
  3. 易于扩展:可以根据需求动态调整LoadBalancer的配置,如增加后端节点等。

缺点

  1. 成本:在公有云环境中,使用LoadBalancer通常需要支付额外的费用。
  2. 环境限制:这种方式主要适用于公有云环境,对于自建Kubernetes集群或者私有云环境可能不适用

方式二:DaemonSet+HostNetwork+nodeSelector

这种方式下,Ingress Controller以DaemonSet的方式部署,通过nodeSelector选择特定的节点运行。同时,使用HostNetwork将Ingress Controller的Pod与宿主机的网络打通,直接使用宿主机的80/443端口来提供服务。这样,Ingress Controller所在的节点就起到了边缘节点的作用,可以直接接受外部请求,并将请求转发到集群内的服务。这种方式的优点是请求链路简单,性能较好。但是,由于Ingress Controller直接占用了宿主机的端口,所以一个节点上通常只能运行一个Ingress Controller的Pod。

优点

  1. 性能优越:由于直接使用宿主机的网络和端口,请求链路简单,性能较好。
  2. 配置简单:通过DaemonSet和nodeSelector可以很方便地将Ingress Controller部署到指定的节点上。
  3. 适合大并发环境:对于需要处理大量并发请求的生产环境,这种方式具有更好的性能表现。

缺点

  1. 资源限制:由于Ingress Controller直接占用了宿主机的端口,因此一个节点上通常只能运行一个Ingress Controller的Pod。
  2. 安全性:由于Ingress Controller直接暴露在公网上,需要特别注意安全性问题,如防止DDoS攻击等。
  3. 可移植性差:使用HostNetwork和特定节点的方式使得Ingress Controller的部署与特定环境紧密相关,不利于跨环境部署和迁移。

方式三:Deployment+NodePort模式的Service

在这种方式下,Ingress Controller仍然以Deployment的方式部署,但是关联的Service的类型是NodePort。NodePort类型的Service会将Pod的端口映射到集群中每个节点的特定端口上。然后,你可以通过任意节点的IP地址和该节点上的映射端口来访问Ingress Controller。由于NodePort映射的端口是随机选择的,因此通常还需要在集群外部再部署一个负载均衡器来将流量分发到各个节点上。这种方式适用于节点IP地址相对固定的环境,但需要注意的是,由于NodePort类型的Service在节点之间进行了NAT转发,因此在请求量很大时可能会对性能产生一定的影响。

优点

  1. 灵活性:NodePort类型的Service可以灵活地将Pod的端口映射到集群中每个节点的特定端口上,便于外部访问。
  2. 适用于固定IP环境:在节点IP地址相对固定的环境中,这种方式可以很方便地暴露服务。

缺点

  1. 性能损耗:由于NodePort类型的Service在节点之间进行了NAT转发,因此在请求量很大时可能会对性能产生一定的影响。
  2. 需要额外配置:通常需要在集群外部再部署一个负载均衡器来将流量分发到各个节点上,增加了配置的复杂性。
  3. 端口管理:由于NodePort映射的端口是随机选择的,可能会与现有应用或服务产生冲突,需要进行端口管理。

(二)方式二搭建

DaemonSet+HostNetwork+nodeSelector

1.获取资源

1.1 获取配置文件

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

官方无法下载的话,可用国内的 gitee

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

  1. [root@master01 ingress]#wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
  2. --2024-06-03 16:40:40-- https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
  3. 正在解析主机 gitee.com (gitee.com)... 180.76.198.77
  4. 正在连接 gitee.com (gitee.com)|180.76.198.77|:443... 已连接。
  5. 已发出 HTTP 请求,正在等待回应... 200 OK
  6. 长度:6635 (6.5K) [text/plain]
  7. 正在保存至: “mandatory.yaml”
  8. 100%[============================================================================>] 6,635 --.-K/s 用时 0s
  9. 2024-06-03 16:40:41 (735 MB/s) - 已保存 “mandatory.yaml” [6635/6635])
  10. [root@master01 ingress]#ls
  11. mandatory.yaml
  12. [root@master01 ingress]#wc -l mandatory.yaml
  13. 293 mandatory.yaml
1.2 获取镜像资源

事先准备好镜像,防止执行yaml文件过程中下载镜像失败,导致无法进入工作状态

  1. //在node01节点上下载
  2. [root@node01 ~]#docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
  3. 0.30.0: Pulling from kubernetes-ingress-controller/nginx-ingress-controller
  4. ......
  5. //在node02节点上下载
  6. [root@node02 ~]#docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
  7. 0.30.0: Pulling from kubernetes-ingress-controller/nginx-ingress-controller
  8. ......

2.修改ClusterRole资源配置

  1. [root@master01 ingress]#vim mandatory.yaml
  2. ......
  3. 91 - apiGroups:
  4. 92 - "extensions"
  5. 93 - "networking.k8s.io" #0.25版本以前,需要添加此段
  6. 94 resources:
  7. 95 - ingresses
  8. 96 verbs:
  9. 97 - get
  10. 98 - list
  11. 99 - watch
  12. 100 - apiGroups:
  13. 101 - "extensions"
  14. 102 - "networking.k8s.io" #0.25版本以前,需要添加此段
  15. 103 resources:
  16. 104 - ingresses/status
  17. 105 verbs:
  18. 106 - update
  19. ......
  20. ---------------------------------------------------------------
  21. ClusterRole的规则部分,用于定义哪些API资源可以被特定的用户或用户组访问,以及可以进行哪些操作
  22. 91-99行:定义第一个规则组:
  23. apiGroups: 定义了资源所属的API组。这里指定了两个API组:"extensions""networking.k8s.io"
  24. resources: 定义具体的资源类型,允许对Ingress资源(用于HTTP/HTTPS路由)进行操作
  25. verbs:定义了可以对资源进行的操作。get(获取资源信息)、list(列出所有资源)和watch(监视资源变化)
  26. 100-106行:定义第二个规则组
  27. ingresses/status:允许对Ingress资源的状态进行操作
  28. verbs: update,允许更新
  29. 在Kubernetes1.18及以后的版本中,extensions/v1beta1 Ingress已经被废弃,并在Kubernetes 1.22版本中完全移除。
  30. Kubernetes集群版本是1.18或更高,使用networking.k8s.io/v1 API组,并且通常不需要在Role或ClusterRole中包含extensions API组

3.修改nginx-ingress-controller配置

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

①添加node02节点标签

  1. [root@master01 ingress]#kubectl label nodes node02 china=zg
  2. node/node02 labeled
  3. #添加标签
  4. [root@master01 ingress]#kubectl get nodes node02 --show-labels #查看标签
  5. NAME STATUS ROLES AGE VERSION LABELS
  6. node02 Ready <none> 18d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,china=zg,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux

②修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络

  1. [root@master01 ingress]#vim mandatory.yaml
  2. ......
  3. 190 apiVersion: apps/v1
  4. 191 kind: DaemonSet
  5. #修改资源类型为DaemonSet,需要在每个指定的节点上运行ingress-controller,标签选择时可以选择多个节点
  6. 192 metadata:
  7. 193 name: nginx-ingress-controller
  8. 194 namespace: ingress-nginx
  9. 195 labels:
  10. 196 app.kubernetes.io/name: ingress-nginx
  11. 197 app.kubernetes.io/part-of: ingress-nginx
  12. 198 spec:
  13. 199 # replicas: 1 #注释或删除replicas
  14. 200 selector:
  15. 201 matchLabels:
  16. .......
  17. 204 template:
  18. ......
  19. 212 spec:
  20. 213 # wait up to five minutes for the drain of connections
  21. 214 #terminationGracePeriodSeconds: 300
  22. #定义pod被强制杀死之前应该等待多长时间来优雅地关闭。此处不需要,注释掉
  23. 215 hostNetwork: true #开启HostNetwork,使Pod与宿主机之前的网络建立隧道
  24. 216 serviceAccountName: nginx-ingress-serviceaccount
  25. 217 nodeSelector:
  26. 218 china: zg #更换指定节点标签
  27. 219 containers:
  28. 220 - name: nginx-ingress-controller
  29. 221 image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
  30. ......

4.创建资源

4.1 创建ingress-controller
  1. [root@master01 ingress]#kubectl apply -f mandatory.yaml
  2. namespace/ingress-nginx created
  3. configmap/nginx-configuration created
  4. configmap/tcp-services created
  5. configmap/udp-services created
  6. ........
  7. [root@master01 ingress]#kubectl get pod -n ingress-nginx -owide
  8. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  9. nginx-ingress-controller-2n7f6 1/1 Running 0 144m 192.168.83.50 node02 <none> <none>

在node02节点过滤80端口

  1. [root@node02 ~]#netstat -antulp |grep :80
  2. tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 62842/nginx: master
  3. tcp6 0 0 :::80 :::* LISTEN 62842/nginx: master
  4. -------------------------------------------------------------------------------
  5. 虽然80端口已经开启,但是使用客户端进行访问会出现404报错,因为它只是ingress-nginx在监听宿主机的80端口,本身不提供web服务
  6. [root@node02 ~]#netstat -lntp | grep nginx
  7. tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 62842/nginx: master
  8. tcp 0 0 0.0.0.0:8181 0.0.0.0:* LISTEN 62842/nginx: master
  9. tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 62842/nginx: master
  10. tcp 0 0 127.0.0.1:10245 0.0.0.0:* LISTEN 62787/nginx-ingress
  11. tcp 0 0 127.0.0.1:10246 0.0.0.0:* LISTEN 62842/nginx: master
  12. tcp 0 0 127.0.0.1:10247 0.0.0.0:* LISTEN 62842/nginx: master
  13. tcp6 0 0 :::10254 :::* LISTEN 62787/nginx-ingress
  14. tcp6 0 0 :::80 :::* LISTEN 62842/nginx: master
  15. tcp6 0 0 :::8181 :::* LISTEN 62842/nginx: master
  16. tcp6 0 0 :::443 :::* LISTEN 62842/nginx: master
  17. -----------------------------------------------------------------------------------
  18. 由于配置了hostnetwork,nginx已经在node主机本地监听80/443/8181端口。
  19. 其中8181是nginx-controller 默认配置的一个default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。
  20. 这样,只要访问node主机有公网IP,就可以直接映射域名来对外网暴露服务了。
  21. 如果要nginx高可用的话,可以在多个node上部署,并在前面再搭建一套LVS+keepalived做负载均衡
4.2 创建pod与service

此时需要在node02节点上创建一个pod

  1. [root@master01 ingress]#vim pod.yaml
  2. [root@master01 ingress]#cat pod.yaml
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: nginx01-ingress
  7. labels:
  8. run: nginx-run
  9. spec:
  10. nodeName: node02
  11. containers:
  12. - name: nginx
  13. image: nginx:1.20.2
  14. ports:
  15. - containerPort: 80
  16. ---
  17. apiVersion: v1
  18. kind: Service
  19. metadata:
  20. name: in-ng-svc
  21. spec:
  22. type: NodePort
  23. ports:
  24. - port: 80
  25. targetPort: 80
  26. selector:
  27. run: nginx-run

创建完毕后,此时四层的服务已经设置完毕

  1. [root@master01 ingress]#kubectl apply -f pod.yaml
  2. pod/nginx01-ingress created
  3. service/in-ng-svc created
  4. [root@master01 ingress]#kubectl get pod,svc -owide
  5. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  6. pod/nginx01-ingress 1/1 Running 0 12s 10.244.2.6 node02 <none> <none>
  7. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
  8. service/in-ng-svc NodePort 10.96.9.79 <none> 80:32169/TCP 12s run=nginx-run
  9. service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18d <none>
  10. [root@master01 ingress]#curl 10.96.9.79 -I
  11. HTTP/1.1 200 OK
  12. Server: nginx/1.20.2
  13. Date: Mon, 03 Jun 2024 12:54:15 GMT
  14. Content-Type: text/html
  15. Content-Length: 612
  16. Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
  17. Connection: keep-alive
  18. ETag: "6193c3b2-264"
  19. Accept-Ranges: bytes
  20. [root@master01 ingress]#kubectl exec -it nginx01-ingress bash
  21. root@nginx01-ingress:/# echo "this is ingress-nginx" >/usr/share/nginx/html/index.html
  22. #自定义访问界面
  23. root@nginx01-ingress:/# exit
  24. exit
  25. [root@master01 ingress]#curl 10.96.9.79
  26. this is ingress-nginx
  27. #自定义一个访问界面

5.创建ingress规则

  1. [root@master01 ingress]#vim ingress.yaml
  2. [root@master01 ingress]#cat ingress.yaml
  3. apiVersion: networking.k8s.io/v1 #Kubernetes网络扩展API的版本1,它定义了Ingress资源。
  4. kind: Ingress #定义了资源的类型
  5. metadata:
  6. name: nginx-ingress
  7. spec:
  8. rules: #定义Ingress规则,将HTTP/HTTPS请求路由到集群内的服务
  9. - host: www.ingress.com #指定规则适用的主机名
  10. http: #定义了 HTTP 相关的配置。
  11. paths: #定义了 HTTP 请求的路径和它们应该被路由到的后端服务
  12. - path: / #指定了匹配的路径,这里使用了/,表示匹配所有路径
  13. pathType: Prefix #定义了路径匹配的类型。Prefix表示路径是基于前缀的匹配
  14. backend: #定义了当请求匹配上述路径时应该被路由到的后端服务
  15. service: #定义了后端服务的配置,即指定转发带哪一个service
  16. name: in-ng-svc #后端服务的名称,即service的名称
  17. port: #定义了后端服务的端口配置
  18. number: 80 #指定后端服务的端口号
  19. ---------------------------------------------------------------------------------
  20. 'host: www.ingress.com'
  21. #当请求的Host头部为www.ingress.com时,这个规则会被应用。
  22. 'pathType类型'
  23. #Exact
  24. 精确匹配。只有当请求的路径与定义的路径完全相同时才进行路由。
  25. 如果path定义为/exact-path,并且pathType设置为 Exact
  26. 那么只有当请求的URL路径也是/exact-path 时,该请求才会被路由到对应的后端服务。
  27. 类似于nginx配置文件中的location = /path
  28. #Prefix
  29. 前缀匹配。如果请求的路径以定义的路径为前缀,则进行路由。
  30. 类似于nginx配置文件中的location ^~ /path
  31. #ImplementationSpecific
  32. 实现特定匹配。此选项告诉Ingress控制器使用其实现特定的方式进行路径选择,这通常是默认值。
  33. 由于这是依赖于Ingress 控制器的实现方式,所以并没有统一的匹配规则。
  34. 不同的Ingress控制器可能会有不同的行为。
  35. 如果没有在Ingress资源中明确指定pathType,那么可能会默认使用ImplementationSpecific
  36. 使用ImplementationSpecific路径类型时,需要确保了解所使用Ingress控制器的具体实现和配置要求
  37. 由于ImplementationSpecific的行为可能因控制器而异,因此在切换控制器或更新控制器版本时,
  38. 需要仔细测试和验证路径匹配的行为是否仍然符合预期

创建规则

  1. [root@master01 ingress]#kubectl apply -f ingress.yaml
  2. ingress.networking.k8s.io/nginx-ingress created
  3. [root@master01 ingress]#kubectl get ingress
  4. NAME CLASS HOSTS ADDRESS PORTS AGE
  5. nginx-ingress <none> www.ingress.com 80 27s

进入ingress规则进行查看

  1. [root@master01 ingress]#kubectl exec -it nginx-ingress-controller-2n7f6 -n ingress-nginx bash
  2. bash-5.0$ egrep -e 'server_name' -e 'start server' -e 'end server' /etc/nginx/nginx.conf
  3. server_names_hash_max_size 1024;
  4. server_names_hash_bucket_size 64;
  5. # Reverse proxies can detect if a client provides a X-Request-ID header, and pass it on to the backend server.
  6. server_name_in_redirect off;
  7. ## start server _
  8. server_name _ ;
  9. ## end server _
  10. ## start server www.ingress.com
  11. server_name www.ingress.com;
  12. ## end server www.ingress.com;
  13. #自动添加域名信息
  14. #从start server www.ingress.com到end server www.ingress.com之间包含此域名用于反向代理的配置

6.客户端访问

  1. [root@nfs ~]#vim /etc/hosts
  2. [root@nfs ~]#grep '192.168.83.50' /etc/hosts
  3. 192.168.83.50 node02 www.ingress.com
  4. #添加客户端域名解析信息,使用域名进行访问,触发ingress规则
  5. [root@nfs ~]#curl www.ingress.com
  6. this is ingress-nginx
  7. #自定义的web访问界面

(三)方式三搭建

Deployment+NodePort模式的Service

1.清空环境

清空之前的操作信息防止pod运行冲突

  1. [root@master01 ingress]#kubectl delete -f pod.yaml
  2. pod "nginx01-ingress" deleted
  3. service "in-ng-svc" deleted
  4. [root@master01 ingress]#kubectl delete -f ingress.yaml
  5. ingress.networking.k8s.io "nginx-ingress" deleted
  6. [root@master01 ingress]#kubectl delete -f mandatory.yaml

2.获取文件

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

官方下载地址

https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

国内 gitee 资源地址 

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

https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

  1. [root@master01 data]#mkdir in-nodeport
  2. [root@master01 data]#cd in-nodeport/
  3. [root@master01 in-nodeport]#wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
  4. [root@master01 in-nodeport]#wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
  5. [root@master01 in-nodeport]#ls
  6. mandatory.yaml service-nodeport.yaml

3.创建代理资源

3.1 创建nginx-ingress-controller资源
[root@master01 in-nodeport]#vim mandatory.yaml

  1. [root@master01 in-nodeport]#kubectl apply -f mandatory.yaml
  2. #创建nginx-ingress-controller资源
  3. #以pod的形式在ingress-nginx命名空间运行
  4. [root@master01 in-nodeport]#kubectl get pod -owide -n ingress-nginx
  5. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  6. nginx-ingress-controller-54b86f8f7b-vj8rl 1/1 Running 0 153m 10.244.1.214 node01 <none> <none>
3.2 创建service资源

查看service-nodeport.yaml 文件,都是默认内容,直接创建即可

  1. [root@master01 in-nodeport]#cat service-nodeport.yaml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: ingress-nginx
  6. namespace: ingress-nginx #所在命名空间,需要先执行mandatory.yaml文件创建
  7. labels:
  8. app.kubernetes.io/name: ingress-nginx
  9. app.kubernetes.io/part-of: ingress-nginx
  10. spec:
  11. type: NodePort
  12. ports:
  13. - name: http
  14. port: 80
  15. targetPort: 80
  16. protocol: TCP
  17. - name: https
  18. port: 443
  19. targetPort: 443
  20. protocol: TCP
  21. selector:
  22. app.kubernetes.io/name: ingress-nginx
  23. app.kubernetes.io/part-of: ingress-nginx
  24. #此标签是nginx-ingress-controller的标签,该service绑定该标签,
  25. #将nginx-ingress-controllerNodePort的形式暴露出去
  26. ---

创建service资源

  1. [root@master01 in-nodeport]#kubectl apply -f service-nodeport.yaml
  2. [root@master01 in-nodeport]#kubectl get svc -n ingress-nginx
  3. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  4. service/ingress-nginx NodePort 10.96.43.71 <none> 80:31705/TCP,443:32391/TCP 31s
  5. [root@master01 in-nodeport]#kubectl describe svc -n ingress-nginx
  6. Name: ingress-nginx
  7. Namespace: ingress-nginx
  8. Labels: app.kubernetes.io/name=ingress-nginx
  9. app.kubernetes.io/part-of=ingress-nginx
  10. Annotations: <none>
  11. Selector: app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
  12. Type: NodePort
  13. IP Families: <none>
  14. IP: 10.96.43.71
  15. IPs: 10.96.43.71
  16. Port: http 80/TCP
  17. TargetPort: 80/TCP
  18. NodePort: http 31705/TCP
  19. Endpoints: 10.244.1.214:80
  20. Port: https 443/TCP
  21. TargetPort: 443/TCP
  22. NodePort: https 32391/TCP
  23. Endpoints: 10.244.1.214:443 #后端关联地址为nginx-ingress-controller地址
  24. Session Affinity: None
  25. External Traffic Policy: Cluster
  26. Events: <none>

4.创建访问资源

4.1 创建Deployment
  1. [root@master01 in-nodeport]#vim deployment.yaml
  2. [root@master01 in-nodeport]#cat deployment.yaml
  3. apiVersion: apps/v1
  4. kind: Deployment
  5. metadata:
  6. name: nginx01-ingress
  7. labels:
  8. nginx-label: nginx01
  9. spec:
  10. replicas: 2
  11. selector:
  12. matchLabels:
  13. nginx-label: nginx01
  14. template:
  15. metadata:
  16. labels:
  17. nginx-label: nginx01
  18. spec:
  19. containers:
  20. - name: nginx
  21. image: nginx:1.18.0
  22. ports:
  23. - containerPort: 80
  24. [root@master01 in-nodeport]#kubectl apply -f deployment.yaml
  25. deployment.apps/nginx01-ingress created
  26. [root@master01 in-nodeport]#kubectl get pod -owide
  27. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  28. nginx01-ingress-5d89744488-g7v6w 1/1 Running 0 8s 10.244.2.7 node02 <none> <none>
  29. nginx01-ingress-5d89744488-x66jh 1/1 Running 0 8s 10.244.1.215 node01 <none> <none>
  30. ------------------------------------------------------------------------------------
  31. #自定义web访问界面
  32. [root@master01 in-nodeport]#kubectl exec -it nginx01-ingress-5d89744488-g7v6w bash
  33. root@nginx01-ingress-5d89744488-g7v6w/~# echo "this is web01" >/usr/share/nginx/html/index.html
  34. root@nginx01-ingress-5d89744488-g7v6w/~# exit
  35. exit
  36. [root@master01 in-nodeport]#kubectl exec -it nginx01-ingress-5d89744488-x66jh bash
  37. root@nginx01-ingress-5d89744488-x66jh:/# echo "this is web02" >/usr/share/nginx/html/index.html
  38. root@nginx01-ingress-5d89744488-x66jh:/# exit
  39. exit
4.2 创建service
  1. [root@master01 in-nodeport]#vim service.yaml
  2. [root@master01 in-nodeport]#cat service.yaml
  3. apiVersion: v1
  4. kind: Service
  5. metadata:
  6. name: in-ng-svc
  7. spec:
  8. type: NodePort #设置类型为NodePort,用于暴露端口
  9. ports:
  10. - port: 80
  11. targetPort: 80
  12. selector:
  13. nginx-label: nginx01
  14. [root@master01 in-nodeport]#kubectl apply -f service.yaml
  15. service/in-ng-svc created
  16. [root@master01 in-nodeport]#kubectl get svc in-ng-svc
  17. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  18. in-ng-svc NodePort 10.96.174.168 <none> 80:32502/TCP 10s
4.3 创建Ingress规则
  1. [root@master01 in-nodeport]#vim ingress.yaml
  2. [root@master01 in-nodeport]#cat ingress.yaml
  3. apiVersion: networking.k8s.io/v1 #网络API组的v1版本。
  4. kind: Ingress #创建一个Ingress 资源
  5. metadata:
  6. name: nginx-ingress-test
  7. spec:
  8. rules: #定义ingress规则
  9. - host: www.china.com #指定当HTTP请求的Host头部为www.benet.com时触发规则
  10. http: #定义HTTP路由规则
  11. paths: #定义路径列表及其对应的后端服务
  12. - path: / #定义要匹配的路径。这里使用了根路径,也就是web服务的站点目录
  13. pathType: Prefix #表示使用前缀匹配方式
  14. backend: #定义与上述路径匹配时应该路由到的后端服务
  15. service: #指定后端服务的名称
  16. name: in-ng-svc #
  17. port: #定义后端服务的端口
  18. number: 80 #端口号为80
  19. -------------------------------------------------------------------------------------
  20. #上述文件表示,客户端通过www.china.com访问时,会触发定义的ingress规则,
  21. #而后通过ingress-controller转发到指定的后端服务(service)当中,后端服务再将请求转发给绑定的pod
  22. [root@master01 in-nodeport]#kubectl apply -f ingress.yaml
  23. ingress.networking.k8s.io/nginx-ingress-test created
  24. [root@master01 in-nodeport]#kubectl get ingress
  25. NAME CLASS HOSTS ADDRESS PORTS AGE
  26. nginx-ingress-test <none> www.china.com 80 9s

5.使用客户端进行访问

  1. //master01查看ingress的service对外暴露的端口
  2. [root@master01 in-nodeport]#kubectl get svc -n ingress-nginx
  3. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  4. ingress-nginx NodePort 10.96.43.71 <none> 80:31705/TCP,443:32391/TCP 137m
  5. //客户端使用nginx-ingress-controller的service对外暴露的端口进行访问
  6. [root@nfs ~]#cat /etc/hosts |grep www.china.com
  7. 192.168.83.40 node01 www.china.com
  8. #添加客户端的域名解析,IP地址为nginx-ingress-controller的pod所以节点的IP地址
  9. [root@nfs ~]#curl www.china.com:31705
  10. this is web01
  11. [root@nfs ~]#curl www.china.com:31705
  12. this is web02
  13. [root@nfs ~]#curl www.china.com:31705
  14. this is web01
  15. [root@nfs ~]#curl www.china.com:31705
  16. this is web02
  17. ----------------------------------------------------------------------------------
  18. 可以看到,访问的方式,是以轮询的方式,发送到deployment管理的pod上。因为,它的数据流向是
  19. 1.用户将请求发送到ingress-controller,而后ingress-controller根据请求的Hosst头部信息,
  20. 也就是www.china.com触发ingress规则
  21. 2.ingress-controller通过ingress规则,获取到关联的service,以及endpoints关联地址
  22. 3.service会将流量平均分配,而后将地址返回给ingress-controller
  23. 4.ingress-controller最后将请求发送给合适的pod

四、虚拟主机

Ingress HTTP 代理访问虚拟主机,使用同一个nginx-ingress-controller,根据不同的域名,代理到不同的后端服务

例如访问www.china.com触发规则后,代理到service-01;访问www.zg.com触发规则二

(一)创建pod资源

创建两个不同的pod资源,或者两个不同的deployment资源

  1. [root@master01 vhost]#cat pod.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx-01
  6. labels:
  7. nginx: nginx01
  8. spec:
  9. containers:
  10. - name: nginx
  11. image: nginx:1.18.0
  12. ports:
  13. - containerPort: 80
  14. ---
  15. apiVersion: v1
  16. kind: Pod
  17. metadata:
  18. name: nginx-02
  19. labels:
  20. nginx: nginx02
  21. spec:
  22. containers:
  23. - name: nginx
  24. image: nginx:1.18.0
  25. ports:
  26. - containerPort: 80
  27. [root@master01 vhost]#kubectl apply -f pod.yaml
  28. pod/nginx-01 created
  29. pod/nginx-02 created
  30. [root@master01 vhost]#kubectl get pod -owide
  31. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  32. nginx-01 1/1 Running 0 14s 10.244.2.8 node02 <none> <none>
  33. nginx-02 1/1 Running 0 13s 10.244.1.216 node01 <none> <none>

自定义web访问页面

  1. [root@master01 vhost]#kubectl exec -it nginx-01 bash
  2. root@nginx-01:/# echo "this is nginx-01" >/usr/share/nginx/html/index.html
  3. root@nginx-01:/# exit
  4. exit
  5. [root@master01 in-nodeport]#kubectl exec -it nginx-02 bash
  6. root@nginx-02:/# echo "this is nginx-02" >/usr/share/nginx/html/index.html
  7. root@nginx-02:/# exit
  8. exit
  9. [root@master01 vhost]#curl 10.244.2.8
  10. this is nginx-01
  11. [root@master01 vhost]#curl 10.244.1.216
  12. this is nginx-02

(二)创建service资源

  1. [root@master01 vhost]#vim service.yaml
  2. [root@master01 vhost]#cat service.yaml
  3. apiVersion: v1
  4. kind: Service
  5. metadata:
  6. name: service-01
  7. spec:
  8. ports:
  9. - port: 80
  10. targetPort: 80
  11. selector:
  12. nginx: nginx01 #使用标签选择,关联的pod为nginx-01
  13. ---
  14. apiVersion: v1
  15. kind: Service
  16. metadata:
  17. name: service-02
  18. spec:
  19. ports:
  20. - port: 80
  21. targetPort: 80
  22. selector:
  23. nginx: nginx02 #使用标签选择,关联的pod为nginx-02
  24. [root@master01 vhost]#kubectl apply -f service.yaml
  25. service/service-01 created
  26. service/service-02 created
  27. [root@master01 vhost]#kubectl get svc
  28. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  29. service-01 ClusterIP 10.96.198.216 <none> 80/TCP 11s
  30. service-02 ClusterIP 10.96.89.179 <none> 80/TCP 11s

(三)创建ingress规则

  1. [root@master01 vhost]#cat ingress.yaml
  2. apiVersion: networking.k8s.io/v1
  3. kind: Ingress
  4. metadata:
  5. name: nginx-vhost-ingress
  6. spec:
  7. rules:
  8. - host: www.chinese.com
  9. http:
  10. paths:
  11. - path: /
  12. pathType: Prefix
  13. backend:
  14. service:
  15. name: service-01
  16. port:
  17. number: 80
  18. - host: www.zg.com
  19. http:
  20. paths:
  21. - path: /
  22. pathType: Prefix
  23. backend:
  24. service:
  25. name: service-02
  26. port:
  27. number: 80
  28. [root@master01 vhost]#kubectl apply -f ingress.yaml
  29. ingress.networking.k8s.io/nginx-vhost-ingress created
  30. [root@master01 vhost]#kubectl get ingress nginx-vhost-ingress
  31. NAME CLASS HOSTS ADDRESS PORTS AGE
  32. nginx-vhost-ingress <none> www.chinese.com,www.zg.com 80 12s

(四)客户端访问

  1. [root@nfs ~]#cat /etc/hosts |grep www.chinese.com
  2. 192.168.83.40 node01 www.china.com www.chinese.com www.zg.com
  3. #同样在客户端添加解析信息,而后使用nginx-ingress-controller的31705端口访问
  4. [root@nfs ~]#curl www.chinese.com:31705
  5. this is nginx-01
  6. [root@nfs ~]#curl www.chinese.com:31705
  7. this is nginx-01
  8. [root@nfs ~]#curl www.zg.com:31705
  9. this is nginx-02
  10. [root@nfs ~]#curl www.zg.com:31705

五、HTPPS代理

要实现 HTTPS 代理,你需要在Ingress 对象中配置 SSL 证书,并确保 Ingress 控制器支持 HTTPS

(一)获取SSL证书

可以从证书颁发机构(CA)购买 SSL 证书,或者使用 Let's Encrypt 等服务获取免费证书

  1. [root@master01 data]#mkdir /data/https
  2. [root@master01 data]#cd /data/https
  3. [root@master01 data]#openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
  4. Generating a 2048 bit RSA private key
  5. ....................................+++
  6. ........+++
  7. writing new private key to 'tls.key'
  8. -----
  9. [root@master01 https]#ls
  10. tls.crt tls.key
  11. [root@master01 https]#
  12. --------------------------------------------------------------------------------
  13. openssl req #OpenSSL命令行工具的一个子命令,用于创建和处理PKCS#10 证书签名请求以及自签名证书
  14. -x509 #指定要生成一个自签名的证书,而不是一个证书签名请求(CSR)。
  15. -sha256 #使用SHA-256哈希算法来签名证书。
  16. -nodes #在生成私钥时不加密它。这意味着私钥将以明文形式存储在tls.key文件中
  17. -days 365 #设置证书的有效期为 365 天(一年)。
  18. -newkey rsa:2048 #在生成证书的同时,也生成一个新的RSA私钥,其长度为2048位。
  19. -keyout tls.key #指定私钥的输出文件名为 tls.key。
  20. -out tls.crt #指定证书的输出文件名为 tls.crt。
  21. -subj "/CN=nginxsvc/O=nginxsvc" #设置证书的主题(Subject)字段。
  22. CN(通用名称)被设置为 nginxsvc,O(组织)也被设置为 nginxsvc。通常,CN 应该是域名或服务器名称

(二)创建Kubernetes Secret

将 SSL 证书和私钥存储在 Kubernetes Secret 中,以便 Ingress 控制器可以访问它们

  1. [root@master01 https]#kubectl create secret tls my-tls-secret --key tls.key --cert tls.crt
  2. secret/my-tls-secret created
  3. [root@master01 https]#kubectl get secret my-tls-secret
  4. NAME TYPE DATA AGE
  5. my-tls-secret kubernetes.io/tls 2 16s
  6. [root@master01 https]#kubectl describe secret my-tls-secret
  7. Name: my-tls-secret
  8. Namespace: default
  9. Labels: <none>
  10. Annotations: <none>
  11. Type: kubernetes.io/tls
  12. Data
  13. ====
  14. tls.crt: 1143 bytes
  15. tls.key: 1708 bytes
  16. ----------------------------------------------------------------------------------------
  17. kubectl #Kubernetes 的命令行工具,用于与集群进行交互。
  18. create secret tls #指示 kubectl 创建一个 TLS 类型的 Secret。
  19. my-tls-secret #要创建的 Secret 的名称。
  20. --key tls.key #指定私钥文件的路径。文件处在当前路径
  21. --cert tls.crt #指定证书文件的路径。同样,文件处在当前路径

(三)创建pod资源

使用deployment控制器创建,或者直接创建pod

  1. [root@master01 https]#vim pod-https.yaml
  2. [root@master01 https]#cat pod-https.yaml
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: nginx-https
  7. labels:
  8. nginx: nginx-https
  9. spec:
  10. containers:
  11. - name: nginx
  12. image: nginx:1.18.0
  13. ports:
  14. - containerPort: 80
  15. [root@master01 https]#kubectl apply -f pod-https.yaml
  16. pod/nginx-https created
  17. [root@master01 https]#kubectl get pod nginx-https -owide
  18. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  19. nginx-https 1/1 Running 0 12s 10.244.2.9 node02 <none> <none>

自定义web界面

  1. [root@master01 https]#kubectl exec -it nginx-https bash
  2. root@nginx-https:/# echo "this is nginx-https" >/usr/share/nginx/html/index.html
  3. root@nginx-https:/# exit
  4. exit
  5. [root@master01 https]#curl 10.244.2.9
  6. this is nginx-https

(四)创建service

  1. [root@master01 https]#vim service-https.yaml
  2. [root@master01 https]#cat service-https.yaml
  3. apiVersion: v1
  4. kind: Service
  5. metadata:
  6. name: service-https
  7. spec:
  8. ports:
  9. - port: 80
  10. targetPort: 80
  11. selector:
  12. nginx: nginx-https
  13. [root@master01 https]#kubectl apply -f service-https.yaml
  14. service/service-https created
  15. [root@master01 https]#kubectl get svc service-https
  16. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  17. service-https ClusterIP 10.96.128.206 <none> 80/TCP 13s

(五)创建ingress规则

  1. [root@master01 https]#vim ingress-https.yaml
  2. [root@master01 https]#cat ingress-https.yaml
  3. apiVersion: networking.k8s.io/v1
  4. kind: Ingress
  5. metadata:
  6. name: nginx-https-ingress
  7. spec:
  8. tls:
  9. - hosts: #这是一个列表,指定了哪些主机名应该使用此TLS配置
  10. - www.https.com #指定使用该TSL的主机名称为www.https.com,可以定义多个
  11. secretName: my-tls-secret #引用Secret,该Secret包含TLS私钥和证书
  12. rules:
  13. - host: www.https.com #与tls中hosts字段定义的主机名一致
  14. http:
  15. paths:
  16. - path: /
  17. pathType: Prefix
  18. backend:
  19. service:
  20. name: service-https #指定后端service名称
  21. port:
  22. number: 80
  23. [root@master01 https]#kubectl apply -f ingress-https.yaml
  24. ingress.networking.k8s.io/nginx-https-ingress created
  25. [root@master01 https]#kubectl get ingress nginx-https-ingress
  26. NAME CLASS HOSTS ADDRESS PORTS AGE
  27. nginx-https-ingress <none> www.https.com 10.96.43.71 80, 443 20s

(六)客户端访问

在客户端添加域名信息,使用https访问443端口映射的主机端口

使用虚拟机客户端的web浏览器

或者在物理机的 C:\Windows\System32\drivers\etc\hosts 文件添加www.https.com的解析信息

而后使用物理机浏览器访​问https://www.https.com:映射端口

  1. [root@nfs ~]#cat /etc/hosts |grep www.https.com
  2. 192.168.83.40 node01 www.china.com www.chinese.com www.zg.com www.https.com
  3. #添加客户端的解析信息,而后使用虚拟机的web浏览器访问
  4. //在master节点,查看443端口映射的宿主机端口
  5. [root@master01 https]#kubectl get svc -n ingress-nginx
  6. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  7. ingress-nginx NodePort 10.96.43.71 <none> 80:31705/TCP,443:32391/TCP 3h10m
  8. #使用浏览器访问https://www.https.com:32391端口

六、实现BasicAuth

BasicAuth是一种用于在客户端和服务器之间进行身份验证的协议,特别是用于HTTP请求的身份验证

BasicAuth通过在HTTP请求头中添加一个“Authorization”字段来进行身份验证。这个字段包含了一个Base64编码的用户名和密码信息

(一)创建认证文件

1.下载htpasswd工具

  1. [root@master01 https]#mkdir /data/basicauth
  2. [root@master01 https]#cd /data/basicauth/
  3. [root@master01 basicauth]#yum install httpd-tools.x86_64 -y
  4. #下载httpd-tools工具包,使用htpasswd命令生成证书文件

2.创建认证文件

  1. [root@master01 basicauth]#htpasswd -c auth xiaoming
  2. New password: #输入密码
  3. Re-type new password: #确认密码
  4. Adding password for user xiaoming
  5. [root@master01 basicauth]#ls
  6. auth #生成的证书文件名称为auth
  7. ------------------------------------------------------------------------------
  8. htpasswd #用于创建和更新存储用户名和密码的文件的实用工具
  9. -c #创建一个新的密码文件
  10. auth #存储用户信息的文件,文件名称固定为auth
  11. xiaoming #添加到密码文件中的用户名,回车之后下面输入密码

(二)创建Secret

创建 secret 资源存储用户密码的认证文件

  1. [root@master01 basicauth]#kubectl create secret generic basic-auth --from-file=auth
  2. secret/basic-auth created
  3. [root@master01 basicauth]#kubectl get secrets basic-auth
  4. NAME TYPE DATA AGE
  5. basic-auth Opaque 1 15s
  6. [root@master01 basicauth]#kubectl describe secrets basic-auth
  7. Name: basic-auth
  8. Namespace: default
  9. Labels: <none>
  10. Annotations: <none>
  11. Type: Opaque
  12. Data
  13. ====
  14. auth: 47 bytes

(三)创建pod资源

  1. [root@master01 basicauth]#vim pod-auth.yaml
  2. [root@master01 basicauth]#cat pod-auth.yaml
  3. apiVersion: v1
  4. kind: Pod
  5. metadata:
  6. name: nginx-auth
  7. labels:
  8. nginx: nginx-auth
  9. spec:
  10. containers:
  11. - name: nginx
  12. image: nginx:1.18.0
  13. ports:
  14. - containerPort: 80
  15. [root@master01 basicauth]#kubectl apply -f pod-auth.yaml
  16. pod/nginx-auth created
  17. [root@master01 basicauth]#kubectl get pod nginx-auth -owide
  18. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  19. nginx-auth 1/1 Running 0 19s 10.244.1.217 node01 <none> <none>
  20. [root@master01 basicauth]#kubectl exec -it nginx-auth bash
  21. root@nginx-auth:/# echo "this is auth" >/usr/share/nginx/html/index.html
  22. root@nginx-auth:/# exit
  23. exit
  24. #自定义web界面

(四)创建service

  1. [root@master01 basicauth]#cat service-auth.yaml
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: service-auth
  6. spec:
  7. ports:
  8. - port: 80
  9. targetPort: 80
  10. selector:
  11. nginx: nginx-auth
  12. [root@master01 basicauth]#kubectl apply -f pod-auth.yaml
  13. pod/nginx-auth created
  14. [root@master01 basicauth]#kubectl apply -f service-auth.yaml
  15. service/service-auth created
  16. [root@master01 basicauth]#kubectl get svc service-auth
  17. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  18. service-auth ClusterIP 10.96.127.61 <none> 80/TCP 15s

(五)创建ingress资源

  1. [root@master01 basicauth]#vim ingress-auth.yaml
  2. [root@master01 basicauth]#cat ingress-auth.yaml
  3. apiVersion: networking.k8s.io/v1
  4. kind: Ingress
  5. metadata:
  6. name: nginx-auth-ingress
  7. annotations:
  8. nginx.ingress.kubernetes.io/auth-type: basic
  9. #指定认证类型为基本认证(basic)
  10. nginx.ingress.kubernetes.io/auth-secret: basic-auth
  11. #指定包含基本认证凭据的Secret资源名称basic-auth
  12. nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - xiaoming'
  13. #定义了当用户需要认证时显示的领域(realm)名称,即认证窗口提示信息
  14. spec:
  15. rules:
  16. - host: www.auth.com #指定主机名触发条件
  17. http:
  18. paths:
  19. - path: /
  20. pathType: Prefix
  21. backend:
  22. service:
  23. name: service-auth #关联的后端服务service
  24. port:
  25. number: 80

添加解析信息后,使用web浏览器进行访问

  1. [root@nfs ~]#cat /etc/hosts |grep www.auth.com
  2. 192.168.83.40 node01 www.auth.com

添加完解析信息后,使用浏览器访问80映射的主机端口,即www.auth.com:31705

七、Nginx重写

当域名更新之后,可以使用重写功能,使旧域名,跳转到新的域名当中

例如当访问www.old.com时,使用重写功能跳转到www.new.com

#metadata.annotations 配置说明

nginx.ingress.kubernetes.io/rewrite-target: <字符串>

此注解允许你修改目标服务的请求 URI。这对于重写来自 Ingress 的流量路径特别有用,尤其是当你想将流量映射到后端服务的不同路径时。

<字符串> 通常是一个包含捕获组的正则表达式,这些捕获组会被替换为实际请求路径中的相应部分。

nginx.ingress.kubernetes.io/ssl-redirect: <布尔值>

默认情况下,如果 Ingress 资源配置了 TLS 证书(通过 tls 部分),并且此注解设置为 true,则所有非 SSL 请求都将被重定向到 SSL(HTTPS)。

<布尔值> 可以是 true 或 false。如果设置为 false,即使配置了 TLS 证书,非 SSL 请求也不会被重定向。

nginx.ingress.kubernetes.io/force-ssl-redirect: <布尔值>

即使 Ingress 资源没有配置 TLS 证书,将此注解设置为 true 也会强制将所有请求重定向到 HTTPS。

<布尔值> 可以是 true 或 false。请注意,将此注解设置为 true 时,你需要确保 Nginx Ingress Controller 能够处理 HTTPS 请求(例如,通过前端代理或负载均衡器终止 SSL)。

nginx.ingress.kubernetes.io/app-root: <字符串>

如果你的应用程序部署在根路径(/)之外,但你想将所有根路径的流量重定向到该应用程序的实际路径,可以使用此注解。

<字符串> 是你的应用程序的实际根路径(例如,/myapp/)。

nginx.ingress.kubernetes.io/use-regex: <布尔值>

此注解指示 Ingress 资源中定义的路径是否使用正则表达式进行匹配。

<布尔值> 可以是 true 或 false。如果设置为 true,paths 下的 path 字段将被视为正则表达式进行匹配

以auth为例,使旧的域名访问时,跳转到该域名

  1. [root@master01 data]#mkdir /data/rewrite
  2. [root@master01 data]#cd /data/rewrite/
  3. [root@master01 rewrite]#vim ingress-rewrite.yaml
  4. [root@master01 rewrite]#cat ingress-rewrite.yaml
  5. apiVersion: networking.k8s.io/v1
  6. kind: Ingress
  7. metadata:
  8. name: nginx-rewrite
  9. annotations:
  10. nginx.ingress.kubernetes.io/rewrite-target: http://www.auth.com:31705
  11. #重写目标URL,重写为http://www.auth.com:31705
  12. spec:
  13. rules:
  14. - host: www.rewrite.com #流量应该匹配的主机名,访问该主机名,将会被重写
  15. http:
  16. paths:
  17. - path: /
  18. pathType: Prefix
  19. backend:
  20. service:
  21. name: nginx-rewrite
  22. port:
  23. number: 80
  24. [root@master01 rewrite]#kubectl apply -f ingress-rewrite.yaml
  25. ingress.networking.k8s.io/nginx-rewrite created
  26. [root@master01 rewrite]#kubectl get ingress nginx-rewrite
  27. NAME CLASS HOSTS ADDRESS PORTS AGE
  28. nginx-rewrite <none> www.rewrite.com 10.96.43.71 80 25s

添加解析信息之后使用浏览器访问

  1. [root@nfs ~]#cat /etc/hosts |grep www.rewrite.com
  2. 192.168.83.40 node01 www.auth.com www.rewrite.com

更多的重写机制,可以查阅官方文档,或者nginx重写规则进行查看

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/676113
推荐阅读
相关标签
  

闽ICP备14008679号