k8s 对外服务之 Ingress
对集群内部,它不断跟踪pod的变化,更新 endpoint 中对应 pod 的对象,提供了 ip 不断变化的 pod 的服务发现机制;对集群外部,他类似负载均衡器,可以在集群内外部对 pod 进行访问。Ingress 是 Kubernetes 中用于管理对集群内服务的外部访问的 API 对象。它允许您将 HTTP 和 HTTPS 路由流量到集群中的服务,通过定义规则,Ingress 可以将传入的请
目录
1.5.1 方式一:Deployment+LoadBalancer 模式的 Service
1.5.2 方式二:DaemonSet+HostNetwork+nodeSelector
1.5.3 方式三:Deployment+NodePort模式的Service
2.1. 方式二:DaemonSet+HostNetwork+nodeSelector
2.1.1 部署 ingress-controller pod 及相关资源
2.1.3 指定 nginx-ingress-controller 运行在 node02 节点
2.1.4 修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络
2.1.6 启动 nginx-ingress-controller
2.1.9 查看 nginx-ingress-controller
2.2. 方式三:Deployment+NodePort模式的Service
2.2.1 下载 nginx-ingress-controller 和 ingress-nginx 暴露端口配置文件
2.2.3 启动 nginx-ingress-controller
3.1. 创建 deployment、Service、Ingress Yaml 资源
5.3. 创建 deployment、Service、Ingress Yaml 资源
6.1. 生成用户密码认证文件,创建 secret 资源进行存储
6.4. 添加宿主机域名解析www.abc.com,访问测试
7.1. metadata.annotations 配置说明
前言
在 Kubernetes 集群中,管理外部服务的访问和流量路由至关重要。通过使用 Ingress 控制器,我们能够实现对外部服务的有效管理,配置灵活的路由规则,并实现负载均衡和流量控制。
一、Ingress 介绍
1.1. Ingress 概述
service 的作用体现在两个方面:
- 对集群内部,它不断跟踪pod的变化,更新 endpoint 中对应 pod 的对象,提供了 ip 不断变化的 pod 的服务发现机制;
- 对集群外部,他类似负载均衡器,可以在集群内外部对 pod 进行访问。
Ingress 是 Kubernetes 中用于管理对集群内服务的外部访问的 API 对象。它允许您将 HTTP 和 HTTPS 路由流量到集群中的服务,通过定义规则,Ingress 可以将传入的请求路由到适当的服务。
1.2. 对外暴露几种方案(发布方式)
外部访问内部图示:
在 Kubernetes 中,Pod 的 IP 地址和 service 的 ClusterIP 仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes 目前提供了以下几种方案:
1.2.1 NodePort
将service暴露在节点网络上,NodePort背后就是Kube-Proxy,Kube-Proxy是沟通service网络、Pod网络和节点网络的桥梁。
测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理就是个灾难。因为每个端口只能是一种服务,端口范围只能是 30000-32767。
1.2.2 LoadBalancer
通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。受限于云平台,且通常在云平台部署LoadBalancer还需要额外的费用。
在service提交后,Kubernetes就会调用CloudProvider在公有云上为你创建一个负载均衡服务,并且把被代理的Pod的IP地址配置给负载均衡服务做后端。
1.2.3 externalIPs
service允许为其分配外部IP,如果外部IP路由到集群中一个或多个Node上,Service会被暴露给这些externalIPs。通过外部IP进入到集群的流量,将会被路由到Service的Endpoint上。
示例:
① 创建控制器定义容器,并对外暴露端口
[root@master01 ingress]# kubectl create deployment app01 --image=nginx:1.14 --replicas=1 --port=80
deployment.apps/app01 created
[root@master01 ingress]# kubectl get pod
NAME READY STATUS RESTARTS AGE
app01-68d9b5486f-d6s4x 1/1 Running 0 3s
[root@master01 ingress]# kubectl expose deployment app01 --port=80 --target-port=80
service/app01 exposed
② 编辑 "app01" 的 Service 的配置文件
[root@master01 ingress]# kubectl edit svc app01
externalIPs:
- 192.168.190.88
③ 查看 Service 列表
[root@master01 ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app01 ClusterIP 10.96.82.195 192.168.190.88 80/TCP 8m43s
④ 访问页面
1.2.4 Ingress
只需一个或者少量的公网IP和LB,即可同时将多个HTTP服务暴露到外网,七层反向代理。
可以简单理解为service的service,它其实就是一组基于域名和URL路径,把用户的请求转发到一个或多个service的规则。
原始架构与 Ingress 对比:
原来ens33是service端去暴露端口的,安全性低、不易管理,会面临k8s端口不够用的问题。
NodePort 和 Ingress 是 Kubernetes 中用于公开服务的两种不同方式:
NodePort:
- NodePort 允许从集群外部访问您的服务。它会在每个节点上打开一个端口,并将该端口映射到 Service 的端口上。这意味着可以通过节点的 IP 地址和 NodePort 来访问 Service。
- 通常用于需要直接暴露到外部的服务,但不适合大规模使用,因为需要管理大量的端口映射。
Ingress:
- Ingress 是一种对外暴露服务的高级方式,它允许您将 HTTP 和 HTTPS 路由流量到集群中的服务。通过定义规则,Ingress 可以将传入的请求路由到适当的服务,实现灵活的流量控制。
- Ingress 需要配合 Ingress Controller 使用,通常基于反向代理实现。它提供了更复杂的路由、负载均衡和 SSL 终止等功能。
1.3.Ingress 组成
1.3.1 Ingress-nginx 资源规则
可以理解为 nginx 的配置文件。ingress是一个API对象,通过yaml文件来配置,ingress对象的作用是定义请求如何转发到service的规则,可以理解为配置模板。
ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS以及基于域名的反向代理。ingress要依靠 ingress-controller 来具体实现以上功能。
1.3.2 ingress-controller
可以当做反向代理或者说是转发器。ingress-controller是具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
实际上负责实现 Ingress 规则并处理外部流量的组件。Ingress Controller 监视 Kubernetes API 中的 Ingress 资源变化,并根据这些资源的配置来配置后端负载均衡器、反向代理或其它网络设备,以实现外部访问服务的目的。
Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/
总结:
ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到 ingress-controller;
而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名、哪些URL要转发到哪些service等等。
1.4. Ingress 工作原理
(1)ingress-controller通过和 kubernetes APIServer 交互,动态的去感知集群中ingress规则变化;
(2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置;
(3)再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中;
(4)然后reload一下使配置生效。以此达到域名区分配置和动态更新的作用。
1.5. ingress 暴露服务的方式
1.5.1 方式一:Deployment+LoadBalancer 模式的 Service
如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个 type为 LoadBalancer 的 service 关联这组 pod。大部分公有云,都会为 LoadBalancer 的 service 自动创建一个负载均衡器,通常还绑定了公网地址。 只要把域名解析指向该地址,就实现了集群服务的对外暴露。
1.5.2 方式二:DaemonSet+HostNetwork+nodeSelector
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。 比较适合大并发的生产环境使用。
1.5.3 方式三:Deployment+NodePort模式的Service
同样用deployment模式部署ingress-controller,并创建对应的service,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。
二、部署 nginx-ingress-controller
2.1. 方式二:DaemonSet+HostNetwork+nodeSelector
2.1.1 部署 ingress-controller pod 及相关资源
[root@master01 ~]# mkdir /opt/ingress;cd /opt/ingress
[root@master01 ingress]# ls
mandatory.yaml
官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml
上面可能无法下载,可用国内的 gitee
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。
2.1.2 修改 ClusterRole 资源配置
[root@master01 ingress]# vim mandatory.yaml
84 - apiGroups:
85 - "extensions"
86 - "networking.k8s.io" #(0.25版本)增加networking.k8s.io Ingress资源的api
100 - apiGroups:
101 - "extensions"
102 - "networking.k8s.io" #(0.25版本)增加networking.k8s.io/v1 Ingress资源的api
2.1.3 指定 nginx-ingress-controller 运行在 node02 节点
采用方式二:DaemonSet+HostNetwork+nodeSelector
[root@master01 ingress]# kubectl label node node02 nj=zs
[root@master01 ingress]# kubectl get nodes --show-labels
NAME STATUS ROLES AGE VERSION LABELS
master01 Ready control-plane,master 18d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master01,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=
node01 NotReady <none> 18d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,fql=a,kubernetes.io/arch=amd64,kubernetes.io/hostname=node01,kubernetes.io/os=linux
node02 NotReady <none> 18d v1.20.11 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,fql=b,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux,nj=zs
2.1.4 修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络
[root@master01 ingress]# vim mandatory.yaml
191 kind: DaemonSet # 修改 kind
199 # replicas: 1 # 删除Replicas
212 spec:
213 hostNetwork: true # 使用主机网络
214 nodeSelector: # 选择节点运行
215 nj: zs
2.1.5 加载镜像
在所有 node02 节点上传 nginx-ingress-controller 镜像压缩包 ingree.contro.tar.gz 到 /opt/ingress 目录,并解压和加载镜像。
[root@node02 data]# ls
ingree.contro.tar.gz
[root@node02 data]# tar xf ingree.contro.tar.gz
[root@node02 data]# ls
ingree.contro.tar ingree.contro.tar.gz
[root@node02 data]# docker load -i ingree.contro.tar
Loaded image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0
2.1.6 启动 nginx-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
serviceaccount/nginx-ingress-serviceaccount created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
Warning: rbac.authorization.k8s.io/v1beta1 Role is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 Role
role.rbac.authorization.k8s.io/nginx-ingress-role created
Warning: rbac.authorization.k8s.io/v1beta1 RoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 RoleBinding
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
daemonset.apps/nginx-ingress-controller created
① nginx-ingress-controller 已经运行 node02 节点
[root@master01 ingress]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-c5xfb 1/1 Running 0 11s 192.168.190.102 node02 <none> <none>
# 如果是0/1去node节点查看一下80端口是否有pod占用
[root@node02 data]# netstat -antulp | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 129841/nginx: mast
[root@master01 ingress]# kubectl get cm,daemonset -n ingress-nginx -o wide
NAME DATA AGE
configmap/ingress-controller-leader-nginx 0 69s
configmap/nginx-configuration 0 73s
configmap/tcp-services 0 73s
configmap/udp-services 0 73s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/nginx-ingress-controller 1 1 1 1 1 nj=zs 72s nginx-ingress-controller quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0 app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx
② 到 node02 节点查看
[root@node02 data]# netstat -lntp | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 129841/nginx: maste
tcp 0 0 0.0.0.0:8181 0.0.0.0:* LISTEN 129841/nginx: maste
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 129841/nginx: maste
tcp6 0 0 :::10254 :::* LISTEN 129805/nginx-ingre
由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。
这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了。如果要 nginx 高可用的话,可以在多个 node上部署,并在前面再搭建一套 LVS+keepalived 做负载均衡。
2.1.7 创建 ingress 规则
2.1.7.1 创建一个 deploy 和 svc
[root@master01 ingress]# kubectl create deployment myapp-demo01 --image=nginx:1.14 --replicas=3 --port=80
deployment.apps/myapp-demo01 created
[root@master01 ingress]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-demo01-98f9b7bf7-kftxn 1/1 Running 0 2s
myapp-demo01-98f9b7bf7-sgzfn 1/1 Running 0 2s
myapp-demo01-98f9b7bf7-tsjvv 1/1 Running 0 2s
[root@master01 ingress]# kubectl delete svc --all
[root@master01 ingress]# kubectl expose deployment myapp-demo01 --port=80 --target-port=80
service/myapp-demo01 exposed
[root@master01 ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-demo01 ClusterIP 10.96.227.130 <none> 80/TCP 3s
[root@master01 ingress]# curl 10.96.227.130 -I
HTTP/1.1 200 OK
到这里,四层转发已经没有问题了;接下来就是要把 ingress-controller 关联 service。即七层关联四层。
2.1.7.2 创建 ingress
方法一:(extensions/v1beta1 Ingress 在1.22版本即将弃用)
[root@master01 ingress]# vim ingress-app.yaml
apiVersion: extensions/v1beta1
kind: Ingress # 这是一个 Ingress 资源,用于定义对集群中服务的外部访问规则
metadata: # 元数据
name: nginx-app-ingress # 资源的名称
spec: # 规定了 Ingress 资源的规格,包括访问规则
rules: # 定义了访问规则,指定了如何路由到后端服务
- host: www.aaa.com # 指定了这条规则适用于主机 www.aaa.com
http: # 定义了 HTTP 访问规则
paths: # 指定了路径匹配规则
- path: / # 表示所有以 / 开头的路径都会匹配到这个规则,这里是网站的根路径
backend: # 指定了后端服务的配置
serviceName: myapp-demo01 # 后端服务的名称为 myapp-demo01,这是要将流量转发到的服务的名称
servicePort: 80
方法二:
[root@master01 ingress]# vim ingress-app01.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-app-ingress
spec:
rules: # 定义了访问规则,指定了如何路由到后端服务
- host: www.aaa.com # 指定了这条规则适用于主机 www.aaa.com
http: # 定义了 HTTP 访问规则
paths: # 指定了路径匹配规则
- path: / # 网站路径,所有以 / 开头的路径都会匹配到这个规则
pathType: Prefix # 路径匹配,基于前缀;exect 完全匹配
backend: # 指定了后端服务的配置
service: # 定义了后端服务的名称和端口号
name: myapp-demo01 # 后端服务的名称为 myapp-demo01,这是要将流量转发到的服务
port:
number: 80
启动 Ingress
[root@master01 ingress]# kubectl apply -f ingress-app.yaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/nginx-app-ingress created
[root@master01 ingress]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-demo01-98f9b7bf7-kftxn 1/1 Running 0 12m
myapp-demo01-98f9b7bf7-sgzfn 1/1 Running 0 12m
myapp-demo01-98f9b7bf7-tsjvv 1/1 Running 0 12m
[root@master01 ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-app-ingress <none> www.aaa.com 80 28s
2.1.8 测试访问
本地 host 添加域名解析:
[root@master01 ingress]# echo 192.168.190.102 www.aaa.com >> /etc/hosts
访问页面:
[root@master01 ingress]# curl www.aaa.com -I
HTTP/1.1 200 OK
2.1.9 查看 nginx-ingress-controller
[root@master01 ingress]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-controller-c5xfb 1/1 Running 0 32m 192.168.190.102 node02 <none> <none>
[root@master01 ingress]# kubectl exec -it nginx-ingress-controller-c5xfb -n ingress-nginx /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
www-data@node02:/etc/nginx$ cat /etc/nginx/nginx.conf
2.2. 方式三:Deployment+NodePort模式的Service
2.2.1 下载 nginx-ingress-controller 和 ingress-nginx 暴露端口配置文件
[root@master01 ingress]# kubectl delete -f ingress-app.yaml
[root@master01 ingress]# kubectl delete -f mandatory.yaml
[root@master01 ingress]# mkdir nodeport;cd nodeport
官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
国内 gitee 资源地址:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
[root@master01 nodeport]# rz -E
rz waiting to receive.
[root@master01 nodeport]# ls
ingress-nginx.yaml mandatory.yaml service-nodeport.yaml
2.2.2 加载镜像
在所有 node 节点上传镜像包 ingress-controller-0.30.0.tar 到 /opt/ingress-nodeport 目录,并加载镜像。
[root@node01 data]# rz -E
rz waiting to receive.
[root@node01 data]# ls
ingree.contro-0.30.0.tar.gz
[root@node01 data]# tar xf ingree.contro-0.30.0.tar.gz
[root@node01 data]# ls
ingree.contro-0.30.0.tar ingree.contro-0.30.0.tar.gz
[root@node01 data]# docker load -i ingree.contro-0.30.0.tar
[root@node02 data]# docker load -i ingree.contro-0.30.0.tar
2.2.3 启动 nginx-ingress-controller
[root@master01 nodeport]# kubectl apply -f mandatory.yaml
[root@master01 nodeport]# kubectl apply -f service-nodeport.yaml
[root@master01 nodeport]# kubectl get svc,pod -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx NodePort 10.96.69.94 <none> 80:32269/TCP,443:32017/TCP 69s
NAME READY STATUS RESTARTS AGE
pod/nginx-ingress-controller-54b86f8f7b-2gm9j 1/1 Running 0 100s
如果K8S Pod 调度失败,在 kubectl describe pod资源时显示:
Warning FailedScheduling 18s (x2 over 18s) default-scheduler 0/2 nodes are available: 2 node(s) didn't match node selector
解决方案:
① 给需要调度的node加上对应标签
# 相对上面这个Yaml文件的例子
kubectl label nodes node_name kubernetes.io/os=linux
② 删除Yaml文件中的nodeSelector,如果对节点没有要求的话,直接删除节点选择器即可
三、Ingress HTTP 代理访问
Ingress HTTP代理访问通常用于在Kubernetes集群中管理入站和出站流量。通过设置Ingress代理,可以实现对集群中部署的服务进行访问控制、负载均衡、SSL终止等功能。
3.1. 创建 deployment、Service、Ingress Yaml 资源
[root@master01 nodeport]# vim ingress-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
spec:
replicas: 2
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
spec: # 规定了Ingress资源的规格,包括访问规则
rules: # 定义了访问规则,指定了如何路由到后端服务
- host: www.aaa.com # 指定了这条规则适用于主机 www.aaa.com
http: # 定义了 HTTP 访问规则
paths: # 指定了路径匹配规则
- path: / # 表示所有以 / 开头的路径都会匹配到这个规则
pathType: Prefix # 指定了路径匹配类型为前缀匹配
backend: # 指定了后端服务的配置
service: # 定义了后端服务的名称和端口号
name: nginx-svc # 指定了后端服务的名称为 nginx-svc
port:
number: 80
[root@master01 nodeport]# kubectl apply -f ingress-nginx.yaml
[root@master01 nodeport]# kubectl get pod,svc -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-app-57dd86f5cc-2qgww 1/1 Running 0 2m29s 10.244.1.225 node01 <none> <none>
pod/nginx-app-57dd86f5cc-2rhh5 1/1 Running 0 2m29s 10.244.2.61 node02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/nginx-svc ClusterIP 10.96.206.53 <none> 80/TCP 4m26s name=nginx
[root@master01 nodeport]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-test <none> www.aaa.com 10.96.69.94 80 12m
3.2. 进入容器编辑页面内容
[root@master01 nodeport]# kubectl exec -it nginx-app-57dd86f5cc-2qgww sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# echo "this is web1" > /usr/share/nginx/html/index.html
# exit
[root@master01 nodeport]# kubectl exec -it nginx-app-57dd86f5cc-2rhh5 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# echo "this is web2" > /usr/share/nginx/html/index.html
3.3. 访问页面
[root@master01 nodeport]# kubectl get endpoints nginx-svc
NAME ENDPOINTS AGE
nginx-svc 10.244.1.225:80,10.244.2.61:80 24m
任意node地址添加域名解析:
[root@master01 nodeport]# curl www.aaa.com:32269
this is web1
[root@master01 nodeport]# curl www.aaa.com:32269
this is web2
四、Ingress HTTP 代理访问多域名服务路由
测试和实践在Kubernetes集群中使用Ingress资源实现同一端口但不同域名的服务路由和负载均衡。具体来说,通过创建两个不同的Service资源,并使用Ingress资源来将不同域名的流量路由到这两个Service上。
① 创建虚拟主机1资源
[root@master01 nodeport]# mkdir vhost
[root@master01 nodeport]# cd vhost/
[root@master01 vhost]# vim deployment1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment1
spec:
replicas: 1
selector:
matchLabels:
name: nginx1
template:
metadata:
labels:
name: nginx1
spec:
containers:
- name: nginx1
image: soscscs/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-1
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx1
② 启动主机1资源
[root@master01 vhost]# kubectl apply -f deployment1.yaml
③ 创建虚拟主机2资源
[root@master01 vhost]# vim deployment2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment2
spec:
replicas: 1
selector:
matchLabels:
name: nginx2
template:
metadata:
labels:
name: nginx2
spec:
containers:
- name: nginx2
image: soscscs/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: svc-2
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx2
④ 启动主机2资源
[root@master01 vhost]# kubectl apply -f deployment2.yaml
[root@master01 vhost]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment1-c8d988f6c-hrk88 1/1 Running 0 69s
deployment2-5588d5cdcd-k6cx6 1/1 Running 0 38s
⑤ 创建ingress资源
[root@master01 vhost]# vim ingress-nginx.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress1
spec: # 规定了 Ingress 资源的规格,包括访问规则
rules: # 定义了访问规则,指定了如何路由到后端服务
- host: www.fff.com # 指定了这条规则适用于主机 www.fff.com
http: # 定义了 HTTP 访问规则
paths: # 指定了路径匹配规则
- path: / # 表示所有以 / 开头的路径都会匹配到这个规则
pathType: Prefix # 指定了路径匹配类型为前缀匹配
backend: # 指定了后端服务的配置
service: # 定义了后端服务的名称和端口号
name: svc-1 # 指定了后端服务的名称为 svc-1
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress2
spec:
rules:
- host: www.qqq.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-2
port:
number: 80
⑥ 查看svc、ingress信息
[root@master01 vhost]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc ClusterIP 10.96.206.53 <none> 80/TCP 47m
svc-1 ClusterIP 10.96.43.42 <none> 80/TCP 5m35s
svc-2 ClusterIP 10.96.30.23 <none> 80/TCP 5m4s
[root@master01 vhost]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.96.69.94 <none> 80:32269/TCP,443:32017/TCP 64m
[root@master01 vhost]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress1 <none> www.fff.com 10.96.69.94 80 117s
ingress2 <none> www.qqq.com 10.96.69.94 80 117s
nginx-test <none> www.aaa.com 10.96.69.94 80 49m
⑦ 进入容器编辑页面内容
[root@master01 vhost]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment1-c8d988f6c-hrk88 1/1 Running 0 11m
deployment2-5588d5cdcd-k6cx6 1/1 Running 0 11m
[root@master01 vhost]# kubectl exec -it deployment1-c8d988f6c-hrk88 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo "this is web01" > /usr/share/nginx/html/index.html
/ # exit
[root@master01 vhost]# kubectl exec -it deployment2-5588d5cdcd-k6cx6 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo "this is web02" > /usr/share/nginx/html/index.html
/ # exit
⑧ 测试访问
[root@master01 vhost]# vim /etc/hosts
192.168.190.102 www.aaa.com www.fff.com www.qqq.com
[root@master01 vhost]# curl www.fff.com:32269
this is web01
[root@master01 vhost]# curl www.qqq.com:32269
this is web02
五、Ingress HTTPS 代理访问
在Kubernetes集群中使用Ingress资源实现通过HTTPS代理访问服务。
5.1.创建ssl证书
生成一个自签名的TLS证书,用于在实验中配置HTTPS代理访问时使用
[root@master01 vhost]# cd ../
[root@master01 nodeport]# mkdir https
[root@master01 nodeport]# cd https/
[root@master01 https]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
[root@master01 https]# ls
tls.crt tls.key
# -x509:表示生成自签名的证书。
# -sha256:表示使用SHA-256算法进行证书签名。
# -nodes:表示生成的私钥不加密。
# -days 365:表示证书的有效期为365天。
# -newkey rsa:2048:表示生成一个2048位的RSA私钥。
# -keyout tls.key:表示将生成的私钥保存到名为tls.key的文件中。
# -out tls.crt:表示将生成的证书保存到名为tls.crt的文件中。
# -subj "/CN=nginxsvc/O=nginxsvc":表示指定证书的主题信息,其中/CN表示Common Name(通用名称),/O表示Organization(组织)。
5.2. 创建 secret 资源进行存储
[root@master01 https]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created
[root@master01 https]# kubectl get secret
NAME TYPE DATA AGE
tls-secret kubernetes.io/tls 2 7s
[root@master01 https]# kubectl describe secret tls-secret
Name: tls-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 1143 bytes
tls.key: 1704 bytes
5.3. 创建 deployment、Service、Ingress Yaml 资源
[root@master01 https]# vim ingress-https.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-fql
spec:
replicas: 1
selector:
matchLabels:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: n-svc-https
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-https
spec:
tls: # 定义了TLS配置,用于配置HTTPS访问
- hosts:
- www.lll.com # 指定了使用TLS的主机名为www.lll.com
secretName: tls-secret # 存储TLS证书和私钥的 Secret 对象的名称为tls-secret
rules: # 定义了访问规则,指定了如何路由到后端服务
- host: www.lll.com # 这条规则适用于主机 www.lll.com
http: # 定义了HTTP访问规则
paths: # 指定了路径匹配规则
- path: / # 表示所有以 / 开头的路径都会匹配到这个规则
pathType: Prefix # 路径匹配类型为前缀匹配
backend: # 指定了后端服务的配置
service: # 定义了后端服务的名称和端口号
name: n-svc-https #后端服务的名称为 n-svc-https
port:
number: 80
5.4. 启动资源
[root@master01 https]# kubectl apply -f ingress-https.yaml
[root@master01 https]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
n-svc-https ClusterIP 10.96.7.182 <none> 80/TCP 22s
[root@master01 https]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.96.69.94 <none> 80:32269/TCP,443:32017/TCP 101m
[root@master01 https]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-https <none> www.lll.com 80, 443 5s
5.5. 访问资源
在宿主机的 C:\Windows\System32\drivers\etc\hosts 文件中添加 192.168.190.102 www.lll.com 记录。
六、Nginx 进行 BasicAuth
Basic认证是一种简单的HTTP身份验证方法,通过用户名和密码验证用户身份
6.1. 生成用户密码认证文件,创建 secret 资源进行存储
[root@master01 https]# cd ..
[root@master01 nodeport]# mkdir basic-auth
[root@master01 nodeport]# cd basic-auth/
[root@master01 basic-auth]# yum -y install httpd-tools.x86_64
[root@master01 basic-auth]# htpasswd -c auth fql # 认证文件名必须为 auth
[root@master01 basic-auth]# htpasswd -c auth fql
New password: # 密码123
Re-type new password:
Adding password for user fql
[root@master01 basic-auth]# ls
auth
6.2. 创建一个 Secret 对象
[root@master01 basic-auth]# kubectl create secret generic basic-auth --from-file=auth
6.3. 创建 ingress 资源
[root@master01 basic-auth]# vim ingress-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-auth
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - fql'
spec:
rules:
- host: www.abc.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
[root@master01 basic-auth]# kubectl apply -f ingress-auth.yaml
[root@master01 basic-auth]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-auth <none> www.abc.com 10.96.69.94 80 3m4s
6.4. 添加宿主机域名解析www.abc.com,访问测试
七、Nginx 重写
在进行 Nginx Ingress 的 URL 重写实验中,可以配置 Nginx Ingress Controller,然后通过编辑 Ingress 资源规则,使用 Nginx 的 rewrite 指令来修改传入请求的 URL 路径,实现定制的路由和重定向功能。
7.1. metadata.annotations 配置说明
- nginx.ingress.kubernetes.io/rewrite-target: <字符串> #必须重定向流量的目标URI
- nginx.ingress.kubernetes.io/ssl-redirect: <布尔值> #指示位置部分是否仅可访问SSL(当Ingress包含证书时,默认为true)
-
nginx.ingress.kubernetes.io/force-ssl-redirect: <布尔值> #即使Ingress未启用TLS,也强制重定向到HTTPS
-
nginx.ingress.kubernetes.io/app-root: <字符串> #定义Controller必须重定向的应用程序根,如果它在'/'上下文中
-
nginx.ingress.kubernetes.io/use-regex: <布尔值> #指示Ingress上定义的路径是否使用正则表达式
7.2. 示例
针对主机 "www.efg.com" 的请求,在经过 Nginx Ingress Controller 处理后,会被重写为指定的目标 URL www.abc.com:32269,并最终路由到名为 "nginx-svc" 的后端服务的端口 80。
① 定义 Ingress
[root@master01 basic-auth]# vim ingress-rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-rewrite
annotations:
nginx.ingress.kubernetes.io/rewrite-target: http://www.fff.com:32269
spec:
rules:
- host: www.efg.com #由于www.efg.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
② 启动 ingress
[root@master01 basic-auth]# kubectl apply -f ingress-rewrite.yaml
[root@master01 basic-auth]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-rewrite <none> www.efg.com 80 9s
③ 添加宿主机域名解析,访问测试
192.168.190.102 www.lll.com www.abc.com www.efg.com www.fff.com
更多推荐
所有评论(0)