【云原生】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.1 获取配置文件)

[1.2 获取镜像资源](#1.2 获取镜像资源)

2.修改ClusterRole资源配置

3.修改nginx-ingress-controller配置

4.创建资源

[4.1 创建ingress-controller](#4.1 创建ingress-controller)

[4.2 创建pod与service](#4.2 创建pod与service)

5.创建ingress规则

6.客户端访问

(三)方式三搭建

1.清空环境

2.获取文件

3.创建代理资源

[3.1 创建nginx-ingress-controller资源](#3.1 创建nginx-ingress-controller资源)

[3.2 创建service资源](#3.2 创建service资源)

4.创建访问资源

[4.1 创建Deployment](#4.1 创建Deployment)

[4.2 创建service](#4.2 创建service)

[4.3 创建Ingress规则](#4.3 创建Ingress规则)

5.使用客户端进行访问

四、虚拟主机

(一)创建pod资源

(二)创建service资源

(三)创建ingress规则

(四)客户端访问

五、HTPPS代理

(一)获取SSL证书

[(二)创建Kubernetes Secret](#(二)创建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.示例

cs 复制代码
[root@master01 pod]#vim deployment.yaml 
[root@master01 pod]#cat deployment.yaml 
apiVersion: apps/v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx  
spec:
  containers:
  - name: nginx
    image: nginx:1.18.0
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service             #创建service
metadata:
  name: nginx-svc
  labels:
    app: nginx
spec:
  type: NodePort          #type类型为NodePort,用于对外提供服务
  ports:
  - port: 80
    targetPort: 80 
  selector:
    app: nginx

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

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

使用客户端进行访问

cs 复制代码
[root@nfs ~]#curl 192.168.83.30:30425  -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Mon, 03 Jun 2024 06:55:53 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
Connection: keep-alive
ETag: "5e9efe7d-264"
Accept-Ranges: bytes

(二)externalIPs

1.作用

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

2.弊端

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

3.示例

cs 复制代码
[root@master01 pod]#cat pod02.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod02
  labels:
    app: nginx  
spec:
  nodeName: node02        
#pod需要使用节点亲和,指定pod建立在externalIPs指定nodeIP地址之外
#同样IP可能导致网络数据包的路由变得混乱,使得Kubernetes集群内外的网络无法正确区分和处理流量
#如果使用deployment建立的pod,则externalIPs只会非本节点的pod实例
  containers:
  - name: nginx
    image: nginx:1.18.0
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc02
  labels:
    app: nginx
spec: 
  externalIPs:          #指定pod绑定地址
  - 192.168.83.40       #绑定到node01节点的IP上
  ports:
  - port: 80
    targetPort: 80 
  selector:
    app: nginx

创建后,查看服务

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

客户端直接访问节点即可

cs 复制代码
[root@nfs ~]#curl 192.168.83.40  -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Mon, 03 Jun 2024 07:08:42 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
Connection: keep-alive
ETag: "5e9efe7d-264"
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

cs 复制代码
[root@master01 ingress]#wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
--2024-06-03 16:40:40--  https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
正在解析主机 gitee.com (gitee.com)... 180.76.198.77
正在连接 gitee.com (gitee.com)|180.76.198.77|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:6635 (6.5K) [text/plain]
正在保存至: "mandatory.yaml"

100%[============================================================================>] 6,635       --.-K/s 用时 0s      

2024-06-03 16:40:41 (735 MB/s) - 已保存 "mandatory.yaml" [6635/6635])
[root@master01 ingress]#ls
mandatory.yaml
[root@master01 ingress]#wc -l mandatory.yaml 
293 mandatory.yaml
1.2 获取镜像资源

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

cs 复制代码
//在node01节点上下载
[root@node01 ~]#docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
0.30.0: Pulling from kubernetes-ingress-controller/nginx-ingress-controller
......


//在node02节点上下载
[root@node02 ~]#docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
0.30.0: Pulling from kubernetes-ingress-controller/nginx-ingress-controller
......

2.修改ClusterRole资源配置

cs 复制代码
[root@master01 ingress]#vim mandatory.yaml
......
 91   - apiGroups:
 92       - "extensions"
 93       - "networking.k8s.io"    #0.25版本以前,需要添加此段
 94     resources:
 95       - ingresses
 96     verbs:
 97       - get
 98       - list
 99       - watch
100   - apiGroups:
101       - "extensions"
102       - "networking.k8s.io"     #0.25版本以前,需要添加此段
103     resources:
104       - ingresses/status
105     verbs:
106       - update
......
---------------------------------------------------------------   
ClusterRole的规则部分,用于定义哪些API资源可以被特定的用户或用户组访问,以及可以进行哪些操作
91-99行:定义第一个规则组:
apiGroups: 定义了资源所属的API组。这里指定了两个API组:"extensions" 和 "networking.k8s.io"
resources: 定义具体的资源类型,允许对Ingress资源(用于HTTP/HTTPS路由)进行操作
verbs:定义了可以对资源进行的操作。get(获取资源信息)、list(列出所有资源)和watch(监视资源变化)

100-106行:定义第二个规则组
ingresses/status:允许对Ingress资源的状态进行操作
verbs: update,允许更新

在Kubernetes1.18及以后的版本中,extensions/v1beta1 Ingress已经被废弃,并在Kubernetes 1.22版本中完全移除。
Kubernetes集群版本是1.18或更高,使用networking.k8s.io/v1 API组,并且通常不需要在Role或ClusterRole中包含extensions API组

3.修改nginx-ingress-controller配置

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

①添加node02节点标签

cs 复制代码
[root@master01 ingress]#kubectl label nodes node02 china=zg
node/node02 labeled
#添加标签
[root@master01 ingress]#kubectl get nodes node02 --show-labels   #查看标签
NAME     STATUS   ROLES    AGE   VERSION    LABELS
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 网络

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

4.创建资源

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

在node02节点过滤80端口

cs 复制代码
[root@node02 ~]#netstat -antulp |grep :80
tcp      0    0 0.0.0.0:80      0.0.0.0:*      LISTEN     62842/nginx: master 
tcp6     0    0 :::80           :::*           LISTEN     62842/nginx: master
-------------------------------------------------------------------------------
虽然80端口已经开启,但是使用客户端进行访问会出现404报错,因为它只是ingress-nginx在监听宿主机的80端口,本身不提供web服务


[root@node02 ~]#netstat -lntp | grep nginx
tcp    0    0 0.0.0.0:80            0.0.0.0:*       LISTEN    62842/nginx: master 
tcp    0    0 0.0.0.0:8181          0.0.0.0:*       LISTEN    62842/nginx: master 
tcp    0    0 0.0.0.0:443           0.0.0.0:*       LISTEN    62842/nginx: master 
tcp    0    0 127.0.0.1:10245       0.0.0.0:*       LISTEN    62787/nginx-ingress 
tcp    0    0 127.0.0.1:10246       0.0.0.0:*       LISTEN    62842/nginx: master 
tcp    0    0 127.0.0.1:10247       0.0.0.0:*       LISTEN    62842/nginx: master 
tcp6   0    0 :::10254              :::*            LISTEN    62787/nginx-ingress 
tcp6   0    0 :::80                 :::*            LISTEN    62842/nginx: master 
tcp6   0    0 :::8181               :::*            LISTEN    62842/nginx: master 
tcp6   0    0 :::443                :::*            LISTEN    62842/nginx: master
-----------------------------------------------------------------------------------
由于配置了hostnetwork,nginx已经在node主机本地监听80/443/8181端口。
其中8181是nginx-controller 默认配置的一个default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。
这样,只要访问node主机有公网IP,就可以直接映射域名来对外网暴露服务了。
如果要nginx高可用的话,可以在多个node上部署,并在前面再搭建一套LVS+keepalived做负载均衡
4.2 创建pod与service

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

cs 复制代码
[root@master01 ingress]#vim pod.yaml 
[root@master01 ingress]#cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx01-ingress
  labels:
    run: nginx-run
spec:
  nodeName: node02
  containers:
  - name: nginx
    image: nginx:1.20.2
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: in-ng-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
  selector:
    run: nginx-run

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

cs 复制代码
[root@master01 ingress]#kubectl apply -f pod.yaml 
pod/nginx01-ingress created
service/in-ng-svc created
[root@master01 ingress]#kubectl get pod,svc -owide
NAME                  READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
pod/nginx01-ingress   1/1     Running   0          12s   10.244.2.6   node02   <none>           <none>

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/in-ng-svc    NodePort    10.96.9.79   <none>        80:32169/TCP   12s   run=nginx-run
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP        18d   <none>
[root@master01 ingress]#curl 10.96.9.79 -I
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Mon, 03 Jun 2024 12:54:15 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
Connection: keep-alive
ETag: "6193c3b2-264"
Accept-Ranges: bytes
[root@master01 ingress]#kubectl exec -it nginx01-ingress bash
root@nginx01-ingress:/# echo "this is ingress-nginx" >/usr/share/nginx/html/index.html 
#自定义访问界面
root@nginx01-ingress:/# exit
exit
[root@master01 ingress]#curl 10.96.9.79
this is ingress-nginx
#自定义一个访问界面 

5.创建ingress规则

cs 复制代码
[root@master01 ingress]#vim ingress.yaml
[root@master01 ingress]#cat ingress.yaml
apiVersion: networking.k8s.io/v1     #Kubernetes网络扩展API的版本1,它定义了Ingress资源。
kind: Ingress                        #定义了资源的类型
metadata:
  name: nginx-ingress
spec:
  rules:                             #定义Ingress规则,将HTTP/HTTPS请求路由到集群内的服务
  - host: www.ingress.com            #指定规则适用的主机名
    http:                            #定义了 HTTP 相关的配置。
      paths:                         #定义了 HTTP 请求的路径和它们应该被路由到的后端服务
      - path: /                      #指定了匹配的路径,这里使用了/,表示匹配所有路径
        pathType: Prefix             #定义了路径匹配的类型。Prefix表示路径是基于前缀的匹配
        backend:                     #定义了当请求匹配上述路径时应该被路由到的后端服务
          service:                   #定义了后端服务的配置,即指定转发带哪一个service
            name: in-ng-svc          #后端服务的名称,即service的名称
            port:                    #定义了后端服务的端口配置
              number: 80             #指定后端服务的端口号
---------------------------------------------------------------------------------
'host: www.ingress.com'
#当请求的Host头部为www.ingress.com时,这个规则会被应用。

'pathType类型'
#Exact
精确匹配。只有当请求的路径与定义的路径完全相同时才进行路由。
如果path定义为/exact-path,并且pathType设置为 Exact
那么只有当请求的URL路径也是/exact-path 时,该请求才会被路由到对应的后端服务。
类似于nginx配置文件中的location = /path

#Prefix
前缀匹配。如果请求的路径以定义的路径为前缀,则进行路由。
类似于nginx配置文件中的location ^~ /path

#ImplementationSpecific
实现特定匹配。此选项告诉Ingress控制器使用其实现特定的方式进行路径选择,这通常是默认值。
由于这是依赖于Ingress 控制器的实现方式,所以并没有统一的匹配规则。
不同的Ingress控制器可能会有不同的行为。
如果没有在Ingress资源中明确指定pathType,那么可能会默认使用ImplementationSpecific
使用ImplementationSpecific路径类型时,需要确保了解所使用Ingress控制器的具体实现和配置要求
由于ImplementationSpecific的行为可能因控制器而异,因此在切换控制器或更新控制器版本时,
需要仔细测试和验证路径匹配的行为是否仍然符合预期

创建规则

cs 复制代码
[root@master01 ingress]#kubectl apply -f ingress.yaml 
ingress.networking.k8s.io/nginx-ingress created
[root@master01 ingress]#kubectl get ingress
NAME            CLASS    HOSTS             ADDRESS   PORTS   AGE
nginx-ingress   <none>   www.ingress.com             80      27s

进入ingress规则进行查看

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

6.客户端访问

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

(三)方式三搭建

Deployment+NodePort模式的Service

1.清空环境

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

cs 复制代码
[root@master01 ingress]#kubectl delete -f pod.yaml 
pod "nginx01-ingress" deleted
service "in-ng-svc" deleted
[root@master01 ingress]#kubectl delete -f ingress.yaml 
ingress.networking.k8s.io "nginx-ingress" deleted
[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

cs 复制代码
[root@master01 data]#mkdir in-nodeport
[root@master01 data]#cd in-nodeport/
[root@master01 in-nodeport]#wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@master01 in-nodeport]#wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
[root@master01 in-nodeport]#ls
mandatory.yaml  service-nodeport.yaml

3.创建代理资源

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

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

cs 复制代码
[root@master01 in-nodeport]#cat service-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx      #所在命名空间,需要先执行mandatory.yaml文件创建
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      targetPort: 80
      protocol: TCP
    - name: https
      port: 443
      targetPort: 443
      protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx         
    app.kubernetes.io/part-of: ingress-nginx
#此标签是nginx-ingress-controller的标签,该service绑定该标签,
#将nginx-ingress-controller以NodePort的形式暴露出去
---

创建service资源

cs 复制代码
[root@master01 in-nodeport]#kubectl apply -f service-nodeport.yaml
[root@master01 in-nodeport]#kubectl get svc -n ingress-nginx 
NAME                    TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx   NodePort   10.96.43.71   <none>        80:31705/TCP,443:32391/TCP   31s
[root@master01 in-nodeport]#kubectl describe svc -n ingress-nginx 
Name:                     ingress-nginx
Namespace:                ingress-nginx
Labels:                   app.kubernetes.io/name=ingress-nginx
                          app.kubernetes.io/part-of=ingress-nginx
Annotations:              <none>
Selector:                 app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
Type:                     NodePort
IP Families:              <none>
IP:                       10.96.43.71
IPs:                      10.96.43.71
Port:                     http  80/TCP
TargetPort:               80/TCP
NodePort:                 http  31705/TCP
Endpoints:                10.244.1.214:80
Port:                     https  443/TCP
TargetPort:               443/TCP
NodePort:                 https  32391/TCP
Endpoints:                10.244.1.214:443   #后端关联地址为nginx-ingress-controller地址
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

4.创建访问资源

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

5.使用客户端进行访问

cs 复制代码
//master01查看ingress的service对外暴露的端口
[root@master01 in-nodeport]#kubectl get svc -n ingress-nginx 
NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.96.43.71   <none>        80:31705/TCP,443:32391/TCP   137m

//客户端使用nginx-ingress-controller的service对外暴露的端口进行访问
[root@nfs ~]#cat /etc/hosts |grep www.china.com
192.168.83.40 node01 www.china.com     
#添加客户端的域名解析,IP地址为nginx-ingress-controller的pod所以节点的IP地址
[root@nfs ~]#curl www.china.com:31705 
this is web01
[root@nfs ~]#curl www.china.com:31705
this is web02
[root@nfs ~]#curl www.china.com:31705
this is web01
[root@nfs ~]#curl www.china.com:31705
this is web02
----------------------------------------------------------------------------------
可以看到,访问的方式,是以轮询的方式,发送到deployment管理的pod上。因为,它的数据流向是
1.用户将请求发送到ingress-controller,而后ingress-controller根据请求的Hosst头部信息,
也就是www.china.com触发ingress规则
2.ingress-controller通过ingress规则,获取到关联的service,以及endpoints关联地址
3.service会将流量平均分配,而后将地址返回给ingress-controller
4.ingress-controller最后将请求发送给合适的pod

四、虚拟主机

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

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

(一)创建pod资源

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

cs 复制代码
[root@master01 vhost]#cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-01
  labels:
    nginx: nginx01
spec:
  containers: 
  - name: nginx
    image: nginx:1.18.0
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-02
  labels:
    nginx: nginx02
spec:   
  containers: 
  - name: nginx
    image: nginx:1.18.0
    ports:
    - containerPort: 80
[root@master01 vhost]#kubectl apply -f pod.yaml 
pod/nginx-01 created
pod/nginx-02 created
[root@master01 vhost]#kubectl get pod -owide
NAME        READY  STATUS  RESTARTS  AGE  IP            NODE     NOMINATED NODE   READINESS GATES
nginx-01    1/1    Running  0        14s  10.244.2.8    node02   <none>           <none>
nginx-02    1/1    Running  0        13s  10.244.1.216  node01   <none>           <none>

自定义web访问页面

cs 复制代码
[root@master01 vhost]#kubectl exec -it nginx-01 bash
root@nginx-01:/# echo "this is nginx-01" >/usr/share/nginx/html/index.html 
root@nginx-01:/# exit
exit
[root@master01 in-nodeport]#kubectl exec -it nginx-02 bash
root@nginx-02:/# echo "this is nginx-02" >/usr/share/nginx/html/index.html
root@nginx-02:/# exit
exit
[root@master01 vhost]#curl 10.244.2.8
this is nginx-01
[root@master01 vhost]#curl 10.244.1.216
this is nginx-02

(二)创建service资源

cs 复制代码
[root@master01 vhost]#vim service.yaml 
[root@master01 vhost]#cat service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: service-01
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    nginx: nginx01         #使用标签选择,关联的pod为nginx-01
---
apiVersion: v1
kind: Service
metadata:
  name: service-02
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    nginx: nginx02         #使用标签选择,关联的pod为nginx-02
[root@master01 vhost]#kubectl apply -f service.yaml 
service/service-01 created
service/service-02 created
[root@master01 vhost]#kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service-01   ClusterIP   10.96.198.216   <none>        80/TCP    11s
service-02   ClusterIP   10.96.89.179    <none>        80/TCP    11s

(三)创建ingress规则

cs 复制代码
[root@master01 vhost]#cat ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-vhost-ingress
spec:
  rules:
  - host: www.chinese.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: service-01
            port:
              number: 80
  - host: www.zg.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: service-02
            port:
              number: 80
[root@master01 vhost]#kubectl apply -f ingress.yaml 
ingress.networking.k8s.io/nginx-vhost-ingress created
[root@master01 vhost]#kubectl get ingress nginx-vhost-ingress 
NAME                  CLASS    HOSTS                        ADDRESS   PORTS   AGE
nginx-vhost-ingress   <none>   www.chinese.com,www.zg.com             80      12s

(四)客户端访问

cs 复制代码
[root@nfs ~]#cat /etc/hosts |grep www.chinese.com
192.168.83.40 node01 www.china.com www.chinese.com www.zg.com
#同样在客户端添加解析信息,而后使用nginx-ingress-controller的31705端口访问
[root@nfs ~]#curl www.chinese.com:31705
this is nginx-01
[root@nfs ~]#curl www.chinese.com:31705
this is nginx-01
[root@nfs ~]#curl www.zg.com:31705
this is nginx-02
[root@nfs ~]#curl www.zg.com:31705

五、HTPPS代理

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

(一)获取SSL证书

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

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

(二)创建Kubernetes Secret

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

cs 复制代码
[root@master01 https]#kubectl create secret tls my-tls-secret --key tls.key --cert tls.crt
secret/my-tls-secret created
[root@master01 https]#kubectl get secret my-tls-secret 
NAME            TYPE                DATA   AGE
my-tls-secret   kubernetes.io/tls   2      16s
[root@master01 https]#kubectl describe secret my-tls-secret 
Name:         my-tls-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.crt:  1143 bytes
tls.key:  1708 bytes
----------------------------------------------------------------------------------------
kubectl               #Kubernetes 的命令行工具,用于与集群进行交互。
create secret tls     #指示 kubectl 创建一个 TLS 类型的 Secret。
my-tls-secret         #要创建的 Secret 的名称。
--key tls.key         #指定私钥文件的路径。文件处在当前路径
--cert tls.crt        #指定证书文件的路径。同样,文件处在当前路径

(三)创建pod资源

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

cs 复制代码
[root@master01 https]#vim pod-https.yaml 
[root@master01 https]#cat pod-https.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-https
  labels:
    nginx: nginx-https
spec:
  containers: 
  - name: nginx
    image: nginx:1.18.0
    ports:
    - containerPort: 80
[root@master01 https]#kubectl apply -f pod-https.yaml 
pod/nginx-https created
[root@master01 https]#kubectl get pod nginx-https -owide
NAME          READY  STATUS   RESTARTS AGE  IP          NODE    NOMINATED NODE  READINESS GATES
nginx-https   1/1    Running  0        12s  10.244.2.9  node02  <none>          <none>

自定义web界面

cs 复制代码
[root@master01 https]#kubectl exec -it nginx-https bash
root@nginx-https:/# echo "this is nginx-https" >/usr/share/nginx/html/index.html 
root@nginx-https:/# exit
exit
[root@master01 https]#curl 10.244.2.9
this is nginx-https

(四)创建service

cs 复制代码
[root@master01 https]#vim service-https.yaml 
[root@master01 https]#cat service-https.yaml 
apiVersion: v1
kind: Service
metadata:
  name: service-https
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    nginx: nginx-https
[root@master01 https]#kubectl apply -f service-https.yaml 
service/service-https created
[root@master01 https]#kubectl get svc service-https 
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service-https   ClusterIP   10.96.128.206   <none>        80/TCP    13s

(五)创建ingress规则

cs 复制代码
[root@master01 https]#vim ingress-https.yaml 
[root@master01 https]#cat ingress-https.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-https-ingress
spec:
  tls:
  - hosts:                       #这是一个列表,指定了哪些主机名应该使用此TLS配置
    - www.https.com              #指定使用该TSL的主机名称为www.https.com,可以定义多个
    secretName: my-tls-secret    #引用Secret,该Secret包含TLS私钥和证书
  rules:
  - host: www.https.com          #与tls中hosts字段定义的主机名一致
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: service-https  #指定后端service名称
            port:
              number: 80
[root@master01 https]#kubectl apply -f ingress-https.yaml 
ingress.networking.k8s.io/nginx-https-ingress created
[root@master01 https]#kubectl get ingress nginx-https-ingress
NAME                  CLASS    HOSTS           ADDRESS       PORTS     AGE
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:映射端口

cs 复制代码
[root@nfs ~]#cat /etc/hosts |grep www.https.com
192.168.83.40 node01 www.china.com www.chinese.com www.zg.com www.https.com
#添加客户端的解析信息,而后使用虚拟机的web浏览器访问

//在master节点,查看443端口映射的宿主机端口
[root@master01 https]#kubectl get svc -n ingress-nginx 
NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.96.43.71   <none>        80:31705/TCP,443:32391/TCP   3h10m
#使用浏览器访问https://www.https.com:32391端口

六、实现BasicAuth

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

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

(一)创建认证文件

1.下载htpasswd工具

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

2.创建认证文件

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

(二)创建Secret

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

cs 复制代码
[root@master01 basicauth]#kubectl create secret generic basic-auth --from-file=auth
secret/basic-auth created
[root@master01 basicauth]#kubectl get secrets basic-auth 
NAME         TYPE     DATA   AGE
basic-auth   Opaque   1      15s
[root@master01 basicauth]#kubectl describe secrets basic-auth 
Name:         basic-auth
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
auth:  47 bytes

(三)创建pod资源

cs 复制代码
[root@master01 basicauth]#vim pod-auth.yaml 
[root@master01 basicauth]#cat pod-auth.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-auth
  labels:
    nginx: nginx-auth
spec:
  containers: 
  - name: nginx
    image: nginx:1.18.0
    ports:
    - containerPort: 80
[root@master01 basicauth]#kubectl apply -f pod-auth.yaml 
pod/nginx-auth created
[root@master01 basicauth]#kubectl get pod nginx-auth -owide
NAME         READY   STATUS    RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
nginx-auth   1/1     Running   0          19s   10.244.1.217   node01   <none>           <none>
[root@master01 basicauth]#kubectl exec -it nginx-auth bash
root@nginx-auth:/# echo "this is auth" >/usr/share/nginx/html/index.html
root@nginx-auth:/# exit
exit
#自定义web界面

(四)创建service

cs 复制代码
[root@master01 basicauth]#cat service-auth.yaml 
apiVersion: v1
kind: Service
metadata:
  name: service-auth
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    nginx: nginx-auth
[root@master01 basicauth]#kubectl apply -f pod-auth.yaml 
pod/nginx-auth created
[root@master01 basicauth]#kubectl apply -f service-auth.yaml 
service/service-auth created
[root@master01 basicauth]#kubectl get svc service-auth 
NAME           TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service-auth   ClusterIP   10.96.127.61   <none>        80/TCP    15s

(五)创建ingress资源

cs 复制代码
[root@master01 basicauth]#vim ingress-auth.yaml 
[root@master01 basicauth]#cat ingress-auth.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-auth-ingress
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    #指定认证类型为基本认证(basic)
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    #指定包含基本认证凭据的Secret资源名称basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - xiaoming'
    #定义了当用户需要认证时显示的领域(realm)名称,即认证窗口提示信息
spec:
  rules:
  - host: www.auth.com             #指定主机名触发条件
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: service-auth     #关联的后端服务service
            port:
              number: 80

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

cs 复制代码
[root@nfs ~]#cat /etc/hosts |grep www.auth.com
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为例,使旧的域名访问时,跳转到该域名

cs 复制代码
[root@master01 data]#mkdir /data/rewrite
[root@master01 data]#cd  /data/rewrite/
[root@master01 rewrite]#vim ingress-rewrite.yaml
[root@master01 rewrite]#cat ingress-rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-rewrite
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: http://www.auth.com:31705
#重写目标URL,重写为http://www.auth.com:31705
spec:
  rules:
  - host: www.rewrite.com  #流量应该匹配的主机名,访问该主机名,将会被重写
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-rewrite
            port:
              number: 80
[root@master01 rewrite]#kubectl apply -f ingress-rewrite.yaml 
ingress.networking.k8s.io/nginx-rewrite created
[root@master01 rewrite]#kubectl get ingress nginx-rewrite 
NAME            CLASS    HOSTS             ADDRESS       PORTS   AGE
nginx-rewrite   <none>   www.rewrite.com   10.96.43.71   80      25s

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

cs 复制代码
[root@nfs ~]#cat /etc/hosts |grep www.rewrite.com
192.168.83.40 node01 www.auth.com www.rewrite.com

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

相关推荐
weixin_453965001 小时前
[单master节点k8s部署]30.ceph分布式存储(一)
分布式·ceph·kubernetes
weixin_453965001 小时前
[单master节点k8s部署]32.ceph分布式存储(三)
分布式·ceph·kubernetes
tangdou3690986551 小时前
1分钟搞懂K8S中的NodeSelector
云原生·容器·kubernetes
Lansonli2 小时前
云原生(四十一) | 阿里云ECS服务器介绍
服务器·阿里云·云原生
Dylanioucn3 小时前
【分布式微服务云原生】掌握分布式缓存:Redis与Memcached的深入解析与实战指南
分布式·缓存·云原生
later_rql4 小时前
k8s-集群部署1
云原生·容器·kubernetes
weixin_453965006 小时前
[单master节点k8s部署]31.ceph分布式存储(二)
分布式·ceph·kubernetes
大G哥9 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes
feng_xiaoshi9 小时前
【云原生】云原生架构的反模式
云原生·架构
妍妍的宝贝9 小时前
k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
nginx·微服务·kubernetes