0
点赞
收藏
分享

微信扫一扫

Python 使用全局变量:深入探索与实战指南

静守幸福 2024-06-06 阅读 7

目录

引言

一、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

2.ingress-controller

3.关系归纳

(三)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或整个集群,流量路由将自动更新以适应新的规则。

(四)访问流程

三、配置Ingress规则

(一)ingress暴露服务方式

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

方式一:Deployment+LoadBalancer 模式的 Service

方式二:DaemonSet+HostNetwork+nodeSelector

方式三:Deployment+NodePort模式的Service

(二)方式二搭建

DaemonSet+HostNetwork+nodeSelector

1.获取资源

1.1 获取配置文件
[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 暴露端口配置文件,

[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端口映射的主机端口

[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重写

#metadata.annotations 配置说明

以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重写规则进行查看

举报

相关推荐

0 条评论