目录
引言
一、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.示例
[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文件之后,查看地址与映射端口
[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端口
使用客户端进行访问
[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.示例
[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
创建后,查看服务
[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
客户端直接访问节点即可
[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来访问你的服务了
优点:
- 自动化与便捷性:在公有云环境中,创建LoadBalancer类型的Service会自动为你创建负载均衡器,并分配公网IP,简化了配置过程。
- 高可用性:负载均衡器通常具有容错和故障转移的能力,保证服务的稳定性。
- 易于扩展:可以根据需求动态调整LoadBalancer的配置,如增加后端节点等。
缺点:
- 成本:在公有云环境中,使用LoadBalancer通常需要支付额外的费用。
- 环境限制:这种方式主要适用于公有云环境,对于自建Kubernetes集群或者私有云环境可能不适用
方式二:DaemonSet+HostNetwork+nodeSelector
这种方式下,Ingress Controller以DaemonSet的方式部署,通过nodeSelector选择特定的节点运行。同时,使用HostNetwork将Ingress Controller的Pod与宿主机的网络打通,直接使用宿主机的80/443端口来提供服务。这样,Ingress Controller所在的节点就起到了边缘节点的作用,可以直接接受外部请求,并将请求转发到集群内的服务。这种方式的优点是请求链路简单,性能较好。但是,由于Ingress Controller直接占用了宿主机的端口,所以一个节点上通常只能运行一个Ingress Controller的Pod。
优点:
- 性能优越:由于直接使用宿主机的网络和端口,请求链路简单,性能较好。
- 配置简单:通过DaemonSet和nodeSelector可以很方便地将Ingress Controller部署到指定的节点上。
- 适合大并发环境:对于需要处理大量并发请求的生产环境,这种方式具有更好的性能表现。
缺点:
- 资源限制:由于Ingress Controller直接占用了宿主机的端口,因此一个节点上通常只能运行一个Ingress Controller的Pod。
- 安全性:由于Ingress Controller直接暴露在公网上,需要特别注意安全性问题,如防止DDoS攻击等。
- 可移植性差:使用HostNetwork和特定节点的方式使得Ingress Controller的部署与特定环境紧密相关,不利于跨环境部署和迁移。
方式三:Deployment+NodePort模式的Service
在这种方式下,Ingress Controller仍然以Deployment的方式部署,但是关联的Service的类型是NodePort。NodePort类型的Service会将Pod的端口映射到集群中每个节点的特定端口上。然后,你可以通过任意节点的IP地址和该节点上的映射端口来访问Ingress Controller。由于NodePort映射的端口是随机选择的,因此通常还需要在集群外部再部署一个负载均衡器来将流量分发到各个节点上。这种方式适用于节点IP地址相对固定的环境,但需要注意的是,由于NodePort类型的Service在节点之间进行了NAT转发,因此在请求量很大时可能会对性能产生一定的影响。
优点:
- 灵活性:NodePort类型的Service可以灵活地将Pod的端口映射到集群中每个节点的特定端口上,便于外部访问。
- 适用于固定IP环境:在节点IP地址相对固定的环境中,这种方式可以很方便地暴露服务。
缺点:
- 性能损耗:由于NodePort类型的Service在节点之间进行了NAT转发,因此在请求量很大时可能会对性能产生一定的影响。
- 需要额外配置:通常需要在集群外部再部署一个负载均衡器来将流量分发到各个节点上,增加了配置的复杂性。
- 端口管理:由于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
[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文件过程中下载镜像失败,导致无法进入工作状态
//在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资源配置
[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节点标签
[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 网络
[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
[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端口
[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
[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
创建完毕后,此时四层的服务已经设置完毕
[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规则
[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的行为可能因控制器而异,因此在切换控制器或更新控制器版本时,
需要仔细测试和验证路径匹配的行为是否仍然符合预期
创建规则
[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规则进行查看
[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.客户端访问
[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运行冲突
[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
[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资源
[root@master01 in-nodeport]#vim mandatory.yaml
[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 文件,都是默认内容,直接创建即可
[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资源
[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
[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
[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规则
[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.使用客户端进行访问
//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资源
[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访问页面
[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资源
[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规则
[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
(四)客户端访问
[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 等服务获取免费证书
[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 控制器可以访问它们
[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
[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界面
[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
[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规则
[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:映射端口
[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工具
[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.创建认证文件
[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 资源存储用户密码的认证文件
[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资源
[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
[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资源
[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浏览器进行访问
[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为例,使旧的域名访问时,跳转到该域名
[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
添加解析信息之后使用浏览器访问
[root@nfs ~]#cat /etc/hosts |grep www.rewrite.com
192.168.83.40 node01 www.auth.com www.rewrite.com
更多的重写机制,可以查阅官方文档,或者nginx重写规则进行查看