k8s 对外服务之 Ingress

文章目录

  • [k8s 对外服务之 Ingress](#k8s 对外服务之 Ingress)
    • [一、Ingress 简介](#一、Ingress 简介)
      • 1、外部应用访问集群内部服务的方法
      • [2、Ingress 组成](#2、Ingress 组成)
        • [2.1 ingress:nginx配置文件](#2.1 ingress:nginx配置文件)
        • [2.2 ingress-controller:当做反向代理或者说是转发器](#2.2 ingress-controller:当做反向代理或者说是转发器)
      • [3、Ingress 工作原理](#3、Ingress 工作原理)
    • 二、基于service实现外部应用访问k8s集群内部
    • [三、部署 nginx-ingress-controller](#三、部署 nginx-ingress-controller)
      • [1、部署ingress-controller pod及相关资源](#1、部署ingress-controller pod及相关资源)
      • [2、查看 ClusterRole 资源配置](#2、查看 ClusterRole 资源配置)
      • **采用DaemonSet+HostNetwork+nodeSelector方式部署**
      • 3、指定运行的节点
      • 4、修改资源类型
      • 5、准备相关的镜像
      • [6、启动 nginx-ingress-controller](#6、启动 nginx-ingress-controller)
      • [7、创建 ingress 规则](#7、创建 ingress 规则)
        • [7.1 创建一个 pod 和 svc](#7.1 创建一个 pod 和 svc)
        • [7.2 创建 ingress](#7.2 创建 ingress)
      • [8、查看 nginx-ingress-controller](#8、查看 nginx-ingress-controller)
      • 9、测试访问
      • **采用Deployment+NodePort模式的Service方式部署**
      • 1、下载需要的配置文件
      • 2、上传需要的镜像文件
      • [3、启动 nginx-ingress-controller](#3、启动 nginx-ingress-controller)
      • [4、Ingress HTTP 代理访问](#4、Ingress HTTP 代理访问)
        • [4.1 创建控制器](#4.1 创建控制器)
        • [4.2 测试访问](#4.2 测试访问)
        • [4.3 本地 host 添加域名解析](#4.3 本地 host 添加域名解析)
        • [4.4 外部访问](#4.4 外部访问)
      • [5、Ingress HTTP 代理访问虚拟主机](#5、Ingress HTTP 代理访问虚拟主机)
        • [5.1 创建pod资源](#5.1 创建pod资源)
        • [5.2 创建service资源](#5.2 创建service资源)
        • [5.3 创建ingress资源](#5.3 创建ingress资源)
        • [5.4 测试访问](#5.4 测试访问)
      • [6、Ingress HTTPS 代理访问](#6、Ingress HTTPS 代理访问)
        • [6.1 获取SSL证书](#6.1 获取SSL证书)
        • [6.2 创建Kubernetes Secret](#6.2 创建Kubernetes Secret)
        • [6.3 创建pod资源](#6.3 创建pod资源)
        • [6.4 创建service](#6.4 创建service)
        • [6.5 创建ingress规则](#6.5 创建ingress规则)
        • [6.6 访问测试](#6.6 访问测试)
    • [三、Nginx 进行 BasicAuth](#三、Nginx 进行 BasicAuth)
    • [四、Nginx 进行重写](#四、Nginx 进行重写)

k8s 对外服务之 Ingress

一、Ingress 简介

  • service的作用体现在两个方面:
    • 对集群内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制;
    • 对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。

1、外部应用访问集群内部服务的方法

在Kubernetes中,Pod的IP地址和service的ClusterIP仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes目前提供了以下几种方案:

  • NodePort :将service暴露在节点网络上,NodePort背后就是Kube-Proxy,Kube-Proxy是沟通service网络、Pod网络和节点网络的桥梁。
    测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理就是个灾难。因为每个端口只能是一种服务,端口范围只能是 30000-32767。
  • LoadBalancer :通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。受限于云平台,且通常在云平台部署LoadBalancer还需要额外的费用。
    在service提交后,Kubernetes就会调用CloudProvider在公有云上为你创建一个负载均衡服务,并且把被代理的Pod的IP地址配置给负载均衡服务做后端。
  • externalIPs:service允许为其分配外部IP,如果外部IP路由到集群中一个或多个Node上,Service会被暴露给这些externalIPs。通过外部IP进入到集群的流量,将会被路由到Service的Endpoint上。
  • Ingress :只需一个或者少量的公网IP和LB,即可同时将多个HTTP服务暴露到外网,七层反向代理。
    可以简单理解为service的service,它其实就是一组基于域名和URL路径,把用户的请求转发到一个或多个service的规则。

2、Ingress 组成

2.1 ingress:nginx配置文件
  • ingress是一个API对象,通过yaml文件来配置,ingress对象的作用是定义请求如何转发到service的规则,可以理解为配置模板。
  • ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS以及基于域名的反向代理。ingress要依靠 ingress-controller 来具体实现以上功能。
2.2 ingress-controller:当做反向代理或者说是转发器
  • ingress-controller是具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
  • 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为例。
bash 复制代码
https://github.com/kubernetes/ingress-nginx
#Ingress-Nginx github地址

https://kubernetes.github.io/ingress-nginx/
#Ingress-Nginx 官方网站

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

3、Ingress 工作原理

  • ingress-controller通过和 kubernetes APIServer 交互,动态的去感知集群中ingress规则变化;
  • 然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置;
  • 再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中;
  • 然后reload一下使配置生效。以此达到域名或者url路径区分配置和动态更新的作用。

二、基于service实现外部应用访问k8s集群内部

1、NodePort

bash 复制代码
kubectl create deployment deploy-xx --image=soscscs/myapp:v1 --port=80 --replicas=3
#创建资源(建立3个副本)

kubectl get pod
#查看pod资源信息

kubectl expose deployment deploy-xx --name svc-xx --type=NodePort --port=80 --target-port=80
#暴露端口,对外提供服务

kubectl get pod,svc
#查看pod,svc资源信息

curl 10.96.97.15
#使用集群ip进行访问

http://192.168.10.11:32475
#或者使用浏览器验证访问(任意集群ip:映射的端口)

2、externalIPs

bash 复制代码
kubectl expose deployment deploy-xx --type=NodePort --port=80 --target-port=80 --dry-run=client -oyaml > svc-xx.yaml
#生成yaml配置文件

vim svc-xx.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: deploy-xx
  name: svc-xx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: deploy-xx
  type: NodePort
  externalIPs:
  - 192.168.10.20
  #添加需要外部访问ip
status:
  loadBalancer: {}

kubectl delete -f svc-xx.yaml && kubectl apply -f svc-xx.yaml
#重新创建资源

kubectl get svc
#查看svc资源信息

curl 192.168.10.20
#访问验证

http://192.168.10.20
#使用浏览器访问验证

三、部署 nginx-ingress-controller

1、部署ingress-controller pod及相关资源

bash 复制代码
mkdir /opt/ingress
#新建目录

cd /opt/ingress
#切换目录

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

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
#上面可能无法下载,可用国内的 gitee

#mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。

2、查看 ClusterRole 资源配置

bash 复制代码
vim mandatory.yaml
......
apiVersion: rbac.authorization.k8s.io/v1beta1
#RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
      #(0.25版本)增加 networking.k8s.io Ingress 资源的 api 
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"   # (0.25版本)增加 networking.k8s.io/v1 Ingress 资源的 api 
    resources:
      - ingresses/status
    verbs:
      - update

ingress 暴露服务的方式

  • 方式一:Deployment+LoadBalancer 模式的 Service
    如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个 type为 LoadBalancer 的 service 关联这组 pod。大部分公有云,都会为 LoadBalancer 的 service 自动创建一个负载均衡器,通常还绑定了公网地址。 只要把域名解析指向该地址,就实现了集群服务的对外暴露
  • 方式二:DaemonSet+HostNetwork+nodeSelector
    用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。 比较适合大并发的生产环境使用。
  • 方式三:Deployment+NodePort模式的Service
    同样用deployment模式部署ingress-controller,并创建对应的service,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
    NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。

采用DaemonSet+HostNetwork+nodeSelector方式部署

3、指定运行的节点

  • 指定 nginx-ingress-controller 运行在 node02 节点
bash 复制代码
kubectl label node node02 ingress=true
#node02节点添加标签

kubectl get nodes --show-labels
#查看节点标签信息

4、修改资源类型

  • 修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络
bash 复制代码
#编辑yaml配置文件
vim mandatory.yaml
#在配置文件的190行开始修改
...
apiVersion: apps/v1
kind: DaemonSet
#将kind信息修改为DaemonSet
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
# replicas: 1
#注销或者删除replicas副本信息
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      #terminationGracePeriodSeconds: 300
      #注销此行,定义pod被强制杀死之前应该等待多长时间来优雅地关闭。此处不需要
      hostNetwork: true
      #使用主机网络
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        ingress: "true"
        #使用节点信息
......

5、准备相关的镜像

  • 在所有 node 节点上传 nginx-ingress-controller 镜像压缩包 ingree.contro.tar.gz 到 /opt/ingress 目录,并解压和加载镜像
bash 复制代码
cd /opt/ingress
#切换目录

#上传需要的镜像压缩包ingree.contro.tar.gz

tar zxvf ingree.contro.tar.gz
#解压

docker load -i ingree.contro.tar
#将镜像文件导入到镜像仓库

6、启动 nginx-ingress-controller

  • nginx-ingress-controller 已经运行 node02 节点
bash 复制代码
kubectl apply -f mandatory.yaml
#创建资源

kubectl get pod -n ingress-nginx -owide
#另开一个终端,跟踪查看pod资源信息

到 node02 节点查看
netstat -lntp | grep nginx
#查看nginx进程

#由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了。如果要 nginx 高可用的话,可以在多个 node上部署,并在前面再搭建一套 LVS+keepalived 做负载均衡。

7、创建 ingress 规则

7.1 创建一个 pod 和 svc
  • 配置service四层服务
bash 复制代码
#编辑yaml配置文件,创建pod,svc资源
vim pod-svc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-app
  labels:
    app: nginx
spec:
  nodeName: node02
  containers:
  - name: nginx
    image: nginx:1.20
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-app-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx

kubectl apply -f pod-svc.yaml
#创建资源

kubectl get pod,svc -owide
#查看资源详细信息

curl -I 10.96.95.165
#访问集群ip验证

kubectl exec -it nginx-app bash
#进入容器

echo "this is nginx-app" > /usr/share/nginx/html/index.html
#自定义访问页面

curl 10.96.95.165
#此时访问,显示自定义页面
7.2 创建 ingress
  • 方法一:(extensions/v1beta1 Ingress 在1.22版本即将弃用)
bash 复制代码
vim ingress-app.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-app-ingress
spec:
  rules:
  - host: www.test.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-app-svc
          servicePort: 80
  • 方法二:
bash 复制代码
#修改yaml配置文件
vim ingress-app.yaml	  
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-app
spec:
  rules:
  #定义Ingress规则,将HTTP/HTTPS请求路由到集群内的服务
  - host: www.test.com
  #指定规则适用的主机名
    http:
    #定义了 HTTP 相关的配置。
      paths:
      #定义了 HTTP 请求的路径和它们应该被路由到的后端服务
      - path: /
      #指定了匹配的路径,这里使用了/,表示匹配所有路径
        pathType: Prefix
        #前缀匹配,也就是模糊匹配
        backend:
        #定义了当请求匹配上述路径时应该被路由到的后端服务
          service:
            name: nginx-app-svc
            port:
              number: 80

kubectl apply -f ingress-app.yaml
#创建资源

kubectl get ingress
#查看ingress资源信息

8、查看 nginx-ingress-controller

bash 复制代码
kubectl get pod -n ingress-nginx -owide
#查看资源详细信息

kubectl exec -it nginx-ingress-controller-mscch -n ingress-nginx bash
#进入容器

egrep -e 'server_name' -e 'start server' -e 'end server' /etc/nginx/nginx.conf
#查看nginx配置文件
#可以看到从 start server www.test.com 到 end server www.test.com 之间包含了此域名用于反向代理的配置

9、测试访问

bash 复制代码
#修改hosts文件
vim /etc/hosts
192.168.10.13 www.test.com
#添加node02节点ip和域名

curl www.test.com
#访问验证

#或者使用浏览器访问验证
#真机host文件添加域名解析
C:\Windows\System32\drivers\etc\hosts
192.168.10.13 www.test.com
#添加node02节点ip和域名

http://www.test.com
#使用浏览器访问验证

采用Deployment+NodePort模式的Service方式部署

1、下载需要的配置文件

  • 下载 nginx-ingress-controller 和 ingress-nginx 暴露端口配置文件
bash 复制代码
mkdir /opt/ingress-nodeport
#新建目录

cd /opt/ingress-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
#官方下载地址

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
#国内 gitee 资源地址

2、上传需要的镜像文件

  • 在所有 node 节点上传镜像包 ingress-controller-0.30.0.tar ,并加载镜像
bash 复制代码
#上传需要的镜像压缩包ingree.contro-0.30.0.tar.gz

tar zxvf ingree.contro-0.30.0.tar.gz
#解压

docker load -i ingree-controller-0.30.0.tar
#将镜像文件加载到镜像库

3、启动 nginx-ingress-controller

bash 复制代码
kubectl apply -f mandatory.yaml
#创建资源

kubectl apply -f service-nodeport.yaml
#创建资源
-------------------------------------------------------------------------------------------------------
#如果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

解决方案:
1. 给需要调度的node加上对应标签
# 相对上面这个Yaml文件的例子
kubectl label nodes node_name kubernetes.io/os=linux

2. 删除Yaml文件中的nodeSelector,如果对节点没有要求的话,直接删除节点选择器即可
---------------------------------------------------------------------------------------------------------

kubectl get pod,svc -n ingress-nginx
#查看资源信息

4、Ingress HTTP 代理访问

4.1 创建控制器
  • 创建deployment资源
bash 复制代码
#创建deployment资源
vim deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx01-ingress
  labels:
    name: nginx01
spec:
  replicas: 2
  selector:
    matchLabels:
     name: nginx01
  template:
    metadata:
      labels:
        name: nginx01
    spec:
      containers:
      - name: nginx
        image: nginx:1.18.0
        ports:
        - containerPort: 80

kubectl apply -f deployment.yaml
#创建资源

kubectl get pod -owide
#查看资源信息

kubectl exec -it nginx01-ingress-7d8c7c9f98-4dkgv bash
#进入容器

echo "this is web01" > /usr/share/nginx/html/index.html
#自定义访问页面

kubectl exec -it nginx01-ingress-7d8c7c9f98-cjjv5 bash
#进入容器

echo "this is web02" > /usr/share/nginx/html/index.html
#自定义访问页面
  • 创建service资源
bash 复制代码
#创建service资源yaml配置文件
vim service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
  selector:
    name: nginx01

kubectl apply -f service.yaml 
#创建资源

kubectl get svc nginx-svc
#查看svc资源信息
  • 创建ingress规则
bash 复制代码
#编辑ingress配置文件
vim ingress-nginx.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-test
spec:
  rules:
  #定义ingress规则
  - host: www.liu.com
  #指定当HTTP请求的Host头部为www.liu.com时触发规则
    http:
    #定义HTTP路由规则
      paths:
      #定义路径列表及其对应的后端服务
      - path: /
      #定义要匹配的路径。这里使用了根路径,也就是web服务的站点目录
        pathType: Prefix
        #表示使用前缀匹配方式
        backend:
        #定义与上述路径匹配时应该路由到的后端服务
          service:
          #指定后端服务的名称
            name: nginx-svc
            #指定svc名称
            port:
            #定义后端服务的端口
              number: 80
              #端口号为80

kubectl apply -f ingress-nginx.yaml
#创建资源

kubectl get ingress -w
#查看ingress资源信息
4.2 测试访问
bash 复制代码
kubectl get svc
#查看资源信息

curl 10.96.57.165
#访问验证
4.3 本地 host 添加域名解析
bash 复制代码
#修改hosts文件
vim /etc/hosts
192.168.10.11 master
192.168.10.12 node01
192.168.10.13 node02
192.168.10.13 www.test.com www.liu.com
4.4 外部访问
bash 复制代码
kubectl get svc -n ingress-nginx
#查看ingress-nginx命名空间的资源信息

curl http://www.liu.com:30238
#相当于使用浏览器访问验证

5、Ingress HTTP 代理访问虚拟主机

  • Ingress HTTP 代理访问虚拟主机,使用同一个nginx-ingress-controller,根据不同的域名,代理到不同的后端服务
5.1 创建pod资源
bash 复制代码
mkdir /opt/ingress-nodeport/vhost
#新建目录

cd /opt/ingress-nodeport/vhost
#切换目录

#编辑yaml配置文件
vim 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

kubectl apply -f pod.yaml 
#创建资源

kubectl get pod -owide
#查看pod,svc资源详细信息


kubectl exec -it nginx-01 bash
#进入容器

echo "this is nginx-01" >/usr/share/nginx/html/index.html 
#编辑访问页面

kubectl exec -it nginx-02 bash
#进入容器

echo "this is nginx-02" >/usr/share/nginx/html/index.html
#编辑访问页面

curl 10.244.1.161
curl 10.244.1.162
#验证访问
5.2 创建service资源
bash 复制代码
#编辑yaml配置文件
vim 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

kubectl apply -f service.yaml 
#创建资源

kubectl get svc
#查看svc资源信息
5.3 创建ingress资源
bash 复制代码
#编辑yaml配置文件
vim ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-vhost-ingress
spec:
  rules:
  - host: www.yan.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: service-01
            port:
              number: 80
  - host: www.fen.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: service-02
            port:
              number: 80

kubectl apply -f ingress.yaml 
#创建资源

kubectl get ingress nginx-vhost-ingress 
#查看ingress资源信息
5.4 测试访问
  • 使用客户端访问测试
bash 复制代码
#修改hosts文件
vim /etc/hosts
192.168.10.12 node01 www.yan.com www.fen.com
#添加域名解析

curl www.yan.com:32494
curl www.fen.com:32494
#访问验证

--------------------------------------------------------------------------------------------------------
master节点查看
kubectl get pod,svc -n ingress-nginx
#查看pod,svc资源信息

6、Ingress HTTPS 代理访问

  • 要实现 HTTPS 代理,你需要在Ingress 对象中配置 SSL 证书,并确保 Ingress 控制器支持 HTTPS
6.1 获取SSL证书
bash 复制代码
mkdir /opt/ingress-nodeport/https
#新建目录

cd /opt/ingress-nodeport/https
#切换目录

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
#创建ssl证书

ls
#查看生成的证书
tls.crt  tls.key

---------------------------------------------------------------------------------------------------------
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 应该是域名或服务器名称
6.2 创建Kubernetes Secret
  • 将 SSL 证书和私钥存储在 Kubernetes Secret 中,以便 Ingress 控制器可以访问它们
bash 复制代码
kubectl create secret tls my-tls-secret --key tls.key --cert tls.crt
#创建 secret 资源进行存储


kubectl get secret my-tls-secret 
#查看secret信息

kubectl describe secret my-tls-secret 
#查看资源详细信息

---------------------------------------------------------------------------------------------------------
kubectl create secret tls my-tls-secret --key tls.key --cert tls.crt

#说明:
kubectl
#Kubernetes 的命令行工具,用于与集群进行交互。
create secret tls
#指示 kubectl 创建一个 TLS 类型的 Secret。
my-tls-secret
#要创建的 Secret 的名称。
--key tls.key
#指定私钥文件的路径。文件处在当前路径
--cert tls.crt
#指定证书文件的路径。同样,文件处在当前路径
---------------------------------------------------------------------------------------------------------
6.3 创建pod资源
  • 使用deployment控制器创建,或者直接创建pod
bash 复制代码
#编辑pod资源配置文件
vim 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

kubectl apply -f pod-https.yaml 
#创建资源

kubectl get pod nginx-https -owide
#查看pod资源详细信息

kubectl exec -it nginx-https bash
#进入容器

echo "this is nginx-https" >/usr/share/nginx/html/index.html 
#自定义访问页面

curl 10.244.2.144
#验证访问
6.4 创建service
bash 复制代码
#编辑yaml配置文件
vim service-https.yaml 
apiVersion: v1
kind: Service
metadata:
  name: service-https
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    nginx: nginx-https

kubectl apply -f service-https.yaml 
#创建资源

kubectl get svc service-https 
#查看svc资源信息
6.5 创建ingress规则
bash 复制代码
#编辑yaml配置文件
vim 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

kubectl apply -f ingress-https.yaml 
#创建资源

kubectl get ingress nginx-https-ingress
#查看ingress资源信息
6.6 访问测试
bash 复制代码
vim /etc/hosts
192.168.10.12 node01 www.yan.com www.fen.com www.https.com
#添加客户端的解析信息,而后使用虚拟机的web浏览器访问

kubectl get svc -n ingress-nginx 
#在master节点,查看443端口映射的宿主机端口

#使用浏览器访问https://www.https.com:31641端口

https://www.https.com:31641(访问)---> 高级 ---> 添加例外 ---> 确认安全例外

三、Nginx 进行 BasicAuth

  • BasicAuth是一种用于在客户端和服务器之间进行身份验证的协议,特别是用于HTTP请求的身份验证
  • BasicAuth通过在HTTP请求头中添加一个"Authorization"字段来进行身份验证。这个字段包含了一个Base64编码的用户名和密码信息

1、创建认证文件

1.1 下载htpasswd工具
bash 复制代码
mkdir /opt/ingress-nodeport/basic-auth
cd /opt/ingress-nodeport/basic-auth
#创建并切换目录

yum install httpd-tools.x86_64 -y
#下载httpd-tools工具包,使用htpasswd命令生成证书文件
1.2 创建认证文件
bash 复制代码
htpasswd -c auth liuyanfen
#认证文件名必须为 auth
#设置密码

-----------------------------------------------------------------------------------------------------------
htpasswd  #用于创建和更新存储用户名和密码的文件的实用工具
-c        #创建一个新的密码文件
auth      #存储用户信息的文件,文件名称固定为auth
liuyanfen #添加到密码文件中的用户名,回车之后下面输入密码

2、创建Secret

  • 创建 secret 资源存储用户密码的认证文件
bash 复制代码
kubectl create secret generic basic-auth --from-file=auth
#创建资源
kubectl get secrets basic-auth 
#查看secret资源信息

kubectl describe secrets basic-auth 
#查看secret资源详细信息

3、创建pod资源

bash 复制代码
#编辑yaml配置文件
vim 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

kubectl apply -f pod-auth.yaml 
#创建资源

kubectl get pod nginx-auth -owide
#查看pod资源详细信息

kubectl exec -it nginx-auth bash
#进入容器

echo "this is auth" >/usr/share/nginx/html/index.html
#自定义web界面

4、创建service

bash 复制代码
#编辑service资源yaml配置文件
vim service-auth.yaml 
apiVersion: v1
kind: Service
metadata:
  name: service-auth
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    nginx: nginx-auth

kubectl apply -f service-auth.yaml 
#创建资源信息

kubectl get svc service-auth 
#查看svc资源信息

5、创建ingress资源

bash 复制代码
#编辑ingress资源配置文件
vim 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

kubectl apply -f ingress-auth.yaml
#创建资源

kubectl get ingress nginx-auth-ingress
#查看ingress资源详细信息

6、访问测试

bash 复制代码
kubectl get svc -n ingress-nginx
#查看svc信息

kubectl describe ingress nginx-auth-ingress
#查看详细信息

客户端修改hosts文件
vim /etc/hosts
192.168.10.12 node01 www.auth.com
#添加域名解析

#浏览器访问:http://www.auth.com:32494

四、Nginx 进行重写

  • 当域名更新之后,可以使用重写功能,使旧域名,跳转到新的域名当中
bash 复制代码
#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上定义的路径是否使用正则表达式
  • nginx重写示例
bash 复制代码
#编辑yaml配置文件
vim 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:32494
    #重写目标URL,重写为http://www.auth.com:32494
spec:
  rules:
  - host: www.rewrite.com
  #流量应该匹配的主机名,访问该主机名,将会被重写
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
        #由于www.rewrite.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义
          service: 
            name: nginx-svc
            port:
              number: 80

kubectl apply -f ingress-rewrite.yaml
#创建资源

kubectl get ingress nginx-rewrite
#查看ingress资源信息

#客户端修改/hosts配置文件
vim /etc/hosts
192.168.10.12 node01 www.auth.com www.rewrite.com

#使用浏览器访问:http://www.rewrite.com:32494
总结

k8s集群外部客户端访问k8s集群内部的方案

  • 基于service实现

    NodePort、LoadBalancer、externalIPs,只能支持四层反向代理,如果k8s集群规模较大,运行的业务较多时,nodeport端口和externalIPs管理成本增加

  • 基于ingress实现

    支持七层反向代理,可以自定义规则,根据用户请求的域名或者url路径转发给指定的service进行代理访问

ingress的组成

  • ingress资源对象

    设置转发规则,告诉ingress控制器应该根据设么域名或者url路径转发请求给相应的service资源的endpoint端点

  • ingress控制器(ingress controller)

    根据ingress资源对象配置的规则转发用户请求的组件,以pod形式运行的(podIP:容器的IP)

使用deployment+NodePort方式部署ingress

  • 客户端------>域名访问:NodePort-----> ingress-service----->Ingress-Controller(pod)------>业务应用Service------>业务的应用Pod
相关推荐
字节源流1 小时前
【spring cloud Netflix】Eureka注册中心
云原生·eureka
Brilliant Nemo2 小时前
Docker 镜像相关的基本操作
运维·docker·容器
基哥的奋斗历程3 小时前
kubernetes configMap 存储
云原生·容器·kubernetes
阿里云云原生21 小时前
LLM 不断提升智能下限,MCP 不断提升创意上限
云原生
阿里云云原生21 小时前
GraalVM 24 正式发布阿里巴巴贡献重要特性 —— 支持 Java Agent 插桩
云原生
云上艺旅1 天前
K8S学习之基础七十四:部署在线书店bookinfo
学习·云原生·容器·kubernetes
c无序1 天前
【Docker-7】Docker是什么+Docker版本+Docker架构+Docker生态
docker·容器·架构
FixBug_Nick1 天前
使用Docker安装及使用最新版本的Jenkins
docker·容器·jenkins
ghostwritten1 天前
Run Milvus in Kubernetes with Milvus Operator
容器·kubernetes·milvus
Zero_to_zero12341 天前
解决docker的ubuntu系统中文乱码问题
ubuntu·docker·容器