目录
一.认识Ingress——控制器
1.1Ingress介绍
1.2Ingress Controller介绍
二.Ingress-nginx
2.1简单介绍
2.2部署Ingress-nginx
2.3修改Ingress-nginx的Service类型
三.基于Daemonet+Hostnetwork部署Ingress-nginx(可选)
四.基于虚拟机名称访问
4.1简单介绍
4.2创建Ingress规则
4.3多域名访问
4.3.1编写Ingress规则
4.3.2上传镜像文件
4.3.3创建Service
4.3.4访问Pod
五.基于路径访问
5.1简单介绍
5.2创建Ingress规则
5.3访问后端Pod
六.default backend
6.1编写yaml文件
6.2运行yml文件
6.3修改 ingress-nginx-controller 的 DS 控制器配置
6.4测试错误页面返回情况
七.TLS证书
7.1简单介绍
7.1创建证书
7.2创建Ingeress-tls
7.4测试访问
7.5配置登录用户,认证访问
7.6访问加密网站
八.重定向——rewrite
8.1基于路径的重定向
8.2基于正则表达式的重定向
一.认识Ingress——控制器
1.1Ingress介绍
1.产生原因:Service 的表现形式为IP地址和端口号(ClusterIP:Port),即工作在TCP/IP层。而对于基于 HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过 Kubernetes 的 Service 机制是无法实现的。
2.概念:Ingress是一个 API 对象,用来定义从集群外部访问集群内部服务的 HTTP/HTTPS 路由规则。它的核心目标是:用一个统一的入口(通常一个 IP 或域名),根据 HTTP 请求的域名和路径,把流量分发给不同的后端 Service,节省IP地址。你可以把它理解成集群的“七层反向代理”或“智能大门”:外部请求先到达 Ingress,再根据域名、路径等规则,被转发到对应的内部 Service。
1.2Ingress Controller介绍
1.概念:Kubernetes 集群里一个真正干活的组件——它监听 Ingress 资源(Ingress规则)的变化,并把其中的路由规则翻译成底层反向代理(如 Nginx、Traefik)的实际配置,从而让外部流量能够按照规则进入集群内部的服务
2.工作机制:Ingress Controller会持续监控API Server的/ingress接口(即用户定义的到后端服务的转发规则)的变化。当 ingress 接口后端的服务信息发生变化时,Ingress Controller 会自动更新其转发规则。
3.流量进入流程:首先,外部流量通过NodePort或者LoadBalancer的Service类型进入 k8s集群中,Ingress Controller不断监听APIServer,用户运行ingress.yaml文件更新Ingress规则。流量进入Ingress Controller依据Ingress规则的host/path匹配,进入不同的Service,最终进入对应的Pod中。这种方式不需要暴露太多的IP或者端口,只需要一个统一入口使流量进入集群,再对集群内部的流量根据域名和路径进行二次划分。
二.Ingress-nginx
2.1简单介绍
概念:Ingress-nginx是 Kubernetes 社区中最流行的 Ingress Controller 实现之一,基于Nginx构建,由 Kubernetes 官方社区(kubernetes/ingress-nginx)维护。
2.2部署Ingress-nginx
1.下载并修改yaml文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.15.1/deploy/static/provider/baremetal/deploy.yaml修改镜像位置:
reg.westos.org/ingress-nginx/controller:v1.13.3reg.westos.org/ingress-nginx/kube-webhook-certgen:v1.6.3reg.westos.org/ingress-nginx/kube-webhook-certgen:v1.6.32.下载镜像文件
docker pull registry.k8s.io/ingress-nginx/controller:v1.13.3 docker pull registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.33.新建项目,并上传镜像文件
docker images| grep ingress-nginx | awk '{print $1":"$2}' | awk -F/ '{system("docker tag "$0" reg.westos.org/"$(NF-1)"/"$NF"")}' #修改镜像名 docker images | grep reg.westos.org/ingress-nginx | awk '{system("docker pull "$1":"$2"")}'添加参数:
--publish-service=$(POD_NAMESPACE)/ingress-nginx-controller4.运行部署文件,部署Ingress-Nginx
kubectl apply -f deploy.yaml kubectl get -n ingress-nginx all kubectl get ingressclasses curl 10.104.89.632.3修改Ingress-nginx的Service类型
说明:默认新建的Ingress的Service类型是NodePort,这里我们修改成LoadBalancer
注意:外部能否访问内部的k8s集群的方式,取决于暴露Ingress-Controller的Service类型。如果是NodePort或LoadBalancer,则通过对应的暴露接口,访问后端Pod。
kubectl edit svc ingress-nginx-controller -n ingress-nginx修改type类型:
type: LoadBalancer查看Service类型
kubectl get svc -n ingress-nginx curl 192.168.7.101三.基于Daemonet+Hostnetwork部署Ingress-nginx(可选)
说明:默认部署的是deployment。Daemonet用于在每一个符合条件的节点上都运行一个Pod,适合部署Agent。通过让 Ingress Controller Pod 占用宿主机的80/443 端口,外部流量通过节点 IP 直接进入。注意,其他服务不可占用这个端口,会报端口冲突。
Hostnetwork:使用主机网络,性能更好,但没有高可用和负载均衡。
准备工作,回收Ingress-Nginx:
kubectl delete -f deploy.yaml #回收Ingress-Nginx修改deploy.yaml文件:
cp deploy.yaml deploy_daemonSet.yaml vim deploy_daemonSet.yaml修改下面的内容:
kind: DaemonSet updateStrategy: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: kubernetes.io/os: linux ingress-node: "true"参数介绍:
kind: DaemonSet #使用 DaemonSet 控制器
updateStrategy #更新策略
hostNetwork: true # 使用主机网络
dnsPolicy: ClusterFirstWith HostNet # 优先集群 DNS(内部域名),再用节点 DNS,设置“hostNetwork: true”时是必须要配置的。
nodeSelector: #选择专用节点
添加节点标签:
kubectl label node k8s1 ingress-node="true" #用于节点筛选和部署 kubectl get node -l ingress-node部署ingress-nginx:
kubectl apply -f deploy_daemonSet.yaml kubectl get all -n ingress-nginx四.基于虚拟机名称访问
4.1简单介绍
概述:用同一个入口 IP / 端口,根据 HTTP 请求头里的Host字段(域名),把流量分发到不同的后端 Service。
注意:ServiceA和B的类型与外部集群能否访问到内部无关,外部服务主要是通过 Ingress Contorller访问到内部集群的Service上,再通过Service访问到后端集群
4.2创建Ingress规则
说明:当外部访问web1.example.com时,对应的Service是 web-service-lb。
1.编写yaml文件:
vim ingress-virtual-host.yml vim service-web-lb.yml添加以下内容:
#ingress-virtual-host.yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-virtual-host spec: ingressClassName: nginx rules: - host: web.example.com http: paths: - path: / #外机域名后要访问的具体url pathType: Prefix #前缀匹配 backend: service: name: web-service-lb port: number: 80#service-web-lb.yml apiVersion: "v1" kind: "Service" metadata: name: "web-service-lb" spec: allocateLoadBalancerNodePorts: false type: "LoadBalancer" ports: - name: "http" protocol: "TCP" port: 80 targetPort: 80 selector: app: "web"运行Ingress规则:
kubectl apply -f service-web-lb.yml #运行web-service-lb服务 kubectl get svc web-service-lb kubectl apply -f ingress-virtual-host.yml #运行ingress kubectl get ingress ingress-virtual-host kubectl describe ingress ingress-virtual-host基于域名访问后端server:
查看Ingress-nginx的Server类型IP:
说明:外部服务能否访问取决于Service是否向外暴露接口,如果是Cluster IP只能内部集群访问。
kubectl get svc -n ingress-nginx ingress-nginx-controller完成域名解析:
vim /etc/hosts添加以下解析:
192.168.7.101 web.example.com域名访问后端服务
curl -H "Host: web.example.com" http://192.168.7.101 #使用-H指定Host头 curl web.example.com4.3多域名访问
说明:当外部访问web1.example.com时,对应的Service是 web-v1;当外部访问web2.example.com时,对应的Service是 web-v2。
4.3.1编写Ingress规则
vim ingress-vhost.yml添加以下内容:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-vhost spec: ingressClassName: nginx rules: - host: web1.example.com #host字段 http: paths: - path: / pathType: Prefix backend: service: name: web-v1 #访问service port: number: 80 - host: web2.example.com #host字段 http: paths: - path: / pathType: Prefix backend: service: name: web-v2 #访问service port: number: 804.3.2上传镜像文件
docker pull docker.1ms.run/yakexi007/myapp:v1 docker pull docker.1ms.run/yakexi007/myapp:v2 docker tag docker.1ms.run/yakexi007/myapp:v1 reg.westos.org/library/myapp:v1 docker tag docker.1ms.run/yakexi007/myapp:v2 reg.westos.org/library/myapp:v2 docker push reg.westos.org/library/myapp:v1 docker push reg.westos.org/library/myapp:v24.3.3创建Service
说明:我这里的Service是Cluster IP类型,只能供集群内部访问。
1.编写yaml文件
vim deploy-web1.yml vim deploy-web2.yml添加以下内容:
#deploy-web1.yml apiVersion: "v1" kind: "Pod" metadata: name: "web1" labels: app: "web1" spec: containers: - name: "web1" image: "reg.westos.org/library/myapp:v1" ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: labels: app: web-v1 name: web-v1 spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: web1 type: ClusterIP#deploy-web2.yml apiVersion: "v1" kind: "Pod" metadata: name: "web2" labels: app: "web2" spec: containers: - name: "web2" image: "reg.westos.org/library/myapp:v2" ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: labels: app: web-v2 name: web-v2 spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: web2 type: ClusterIP运行Service:
kubectl apply -f deploy-web1.yml kubectl apply -f deploy-web2.yml kubectl get svc web-v1 kubectl get svc web-v24.3.4访问Pod
说明:后端有两个服务,但是暴露的外部IP只有一个
1.查看Ingress-nginx-controller的ServiceIP
kubectl get svc ingress-nginx-controller -n ingress-nginx2.添加host解析
vim /etc/hosts添加以下内容:
192.168.7.101 web1.example.com web2.example.com3.访问域名,访问后端Pod
访问myapp:v1
curl -H "Host: web1.example.com" http://192.168.7.101 curl web1.example.com访问myapp:v2
curl -H "Host: web2.example.com" http://192.168.7.101 curl web2.example.com五.基于路径访问
5.1简单介绍
1.概念:用同一个入口 IP/端口,根据不同的路径,访问到后端不同的Service。
2.工作流程:
5.2创建Ingress规则
vim ingress-rewrite-1.yml vim ingress-rewrite-2.yml添加以下内容:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-virtual-path annotations: nginx.ingress.kubernetes.io/rewrite-target: / #把匹配到的路径部分替换成 /,再转发给后端 spec: ingressClassName: nginx rules: - host: web.example.com #统一入口 http: paths: - path: /v1 #路径1 pathType: Prefix backend: service: name: web-v1 port: number: 80 - path: /v2 #路径2 pathType: Prefix backend: service: name: web-v2 port: number: 80运行规则:
kubectl apply -f ingress-virtual-path.yml kubectl get ingress5.3访问后端Pod
1.创建域名解析
vim /etc/hosts添加以下内容:
2.访问后端服务
curl web.example.com/v1 curl web.example.com/v2六.default backend
说明:添加返回错误页面,更新新的返回页面(如404、503)。
6.1编写yaml文件
vim custom-default-backend.yml添加以下内容:
--- apiVersion: v1 kind: Service metadata: name: nginx-errors labels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx spec: selector: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx ports: - port: 80 targetPort: 8080 name: http --- apiVersion: v1 kind: ConfigMap metadata: name: custom-error-pages data: 404: | #404返回下述错误 <!DOCTYPE html> <html> <head><title>PAGE NOT FOUND</title></head> <body>PAGE NOT FOUND</body> </html> 503: | #503返回下述错误 <!DOCTYPE html> <html> <head><title>CUSTOM SERVICE UNAVAILABLE</title></head> <body>CUSTOM SERVICE UNAVAILABLE</body> </html> --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-errors labels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx template: metadata: labels: app.kubernetes.io/name: nginx-errors app.kubernetes.io/part-of: ingress-nginx spec: containers: - name: nginx-error-server image: reg.westos.org/ingress-nginx/custom-error-pages:v1.2.4 #下载镜像文件 ports: - containerPort: 8080 # Setting the environment variable DEBUG we can see the headers sent # by the ingress controller to the backend in the client response. env: - name: DEBUG value: "true" # Mounting custom error page from configMap volumeMounts: - name: custom-error-pages mountPath: /www # Mounting custom error page from configMap volumes: - name: custom-error-pages configMap: name: custom-error-pages items: - key: "404" path: "404.html" - key: "503" path: "503.html"6.2运行yml文件
kubectl -n ingress-nginx create -f custom-default-backend.yml kubectl -n ingress-nginx get pod,svc,deploy6.3修改ingress-nginx-controller的DS控制器配置
kubectl -n ingress-nginx edit ds ingress-nginx-controller添加以下内容:
- --default-backend-service=ingress-nginx/nginx-errors6.4测试错误页面返回情况
curl web.example.com curl 192.168.7.101七.TLS证书
7.1简单介绍
1.概念:TLS 证书(Transport Layer Security Certificate)是用于在互联网上证明服务器身份并加密通信的数字文件。你可以把它理解成网站的“电子身份证 + 加密钥匙”。
2.核心功能
1.加密通信:没有 TLS 时,HTTP 请求是明文传输的,中间人可以看到你发的所有内容(密码、信用卡号、聊天记录);有了 TLS 时,浏览器和服务器之间建立一条加密通道。
2.证明服务身份:防止“中间人攻击”
3.浏览器信任:现代浏览器对 HTTP 网站会标记“不安全”,对 HTTPS 网站显示锁图标。
7.1创建证书
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc" #生成一个自签名的 TLS 证书(包含私钥和证书两个文件) kubectl create secret tls tls-secret --key tls.key --cert tls.crt #生成证书后,创建TLS Secret kubectl get secret tls-secret7.2创建Ingeress-tls
说明:给两个网站域名加上“HTTPS 加密”,把它们分别转发到不同的后端服务。
1.编写yaml文件
vim ingress-web-tls.yml添加以下内容:
#ingress-web-tls.yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-web-tls spec: tls: #开启 HTTPS(TLS),访问这两个域名时,浏览器会弹出用户名密码输入框。 - hosts: #让 web1.example.com 和 web2.example.com 支持 https://访问。 - web1.example.com - web2.example.com secretName: tls-secret #证书名称 ingressClassName: nginx rules: - host: web1.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-v1 port: number: 80 - host: web2.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-v2 port: number: 802.运行yaml文件
kubectl apply -f ingress-web-tls.yml kubectl get ingress ingress-web-tls kubectl describe ingress ingress-web-tls7.4测试访问
说明:直接通过http协议访问域名,会强制重定向到https上
curl -I web1.example.com curl -I web2.example.com说明:跳过密码验证,直接访问443
curl -k https://web1.example.com curl -k https://web2.example.com如果不跳过密码认证,直接访问,会报错,因为我们没有配置登录的用户和密码:
7.5配置登录用户,认证访问
1.安装httpd-tools
yum install -y httpd-tools2.创建用户
htpasswd -c auth wxh #-c :创建新文件 cat authkubectl create secret generic basic-auth --from-file=auth3.创建证书
说明:把本地文件auth的内容,打包成一个 Kubernetes Secret
kubectl create secret generic basic-auth --from-file=auth kubectl get secrets basic-auth4.添加登录用户
vim ingress-web-tls.yml添加以下内容:
annotations: #开启登录认证(Basic Auth) nginx.ingress.kubernetes.io/auth-type: basic #启用 Basic Auth nginx.ingress.kubernetes.io/auth-secret: basic-auth #引用名为 basic-auth 的 Secret,里面存用户名密码 nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - wxh' #浏览器弹窗里显示的提示文字5.运行yaml文件
kubectl apply -f ingress-web-tls.yml kubectl get ingress ingress-web-tls kubectl describe ingress ingress-web-tls7.6访问加密网站
curl -u wxh:123456 -k https://web1.example.com curl -u wxh:123456 -k https://web2.example.com直接使用-k,会提示需要登录用户:
八.重定向——rewrite
说明:访问到pod中的某个文件,默认分为路径重定向和正则表达式重定向
8.1基于路径的重定向
1.编写yaml文件
说明:设定访问域名,进入后,重定向到pod的另一个路径中,类似nginx的重定向
vim ingress-rewrite-1.yml添加以下内容:
#ingress-rewrite-1.yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-rewrite-1 annotations: nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: basic-auth nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - wxh' nginx.ingress.kubernetes.io/app-root: /cgi-bin/action #访问域名,进入内部Pod的cgi-bin/action中 spec: tls: - hosts: - web.example.com secretName: tls-secret ingressClassName: nginx rules: - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-service port: number: 802.运行Ingress
kubectl apply -f ingress-rewrite-1.yml kubectl get ingress ingress-rewrite-13.查看重定向
curl -I web.example.com4.浏览器访问:
进入系统的路径: "C:\Windows\System32\drivers\etc\hosts"
添加以下内容:
192.168.7.101 web.example.comweb.example.com #访问域名,重定向到cgi-bin/action8.2基于正则表达式的重定向
说明:基于正则表达式,重定向到另一个路径中
1.编写yaml文件
vim ingress-rewrite-2.yml添加以下内容:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-rewrite-2 annotations: nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: basic-auth nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - wxh' nginx.ingress.kubernetes.io/use-regex: "true" #path 字段里写的是正则表达式。 nginx.ingress.kubernetes.io/rewrite-target: /$2 #把匹配部分替换成 /$2,$2是第2个捕获组 spec: tls: - hosts: - web.example.com secretName: tls-secret ingressClassName: nginx rules: - host: web.example.com http: paths: - path: /testing(/|$)(.*) #重写路径 访问域名/teting/.* ,访问域名/.* pathType: ImplementationSpecific backend: service: name: web-service port: number: 802.运行Ingress
kubectl apply -f ingress-rewrite-2.yml kubectl get ingress ingress-rewrite-2 kubectl describe ingress ingress-rewrite-23.访问域名
curl -k -u wxh:123456 https://web.example.com/testinghttps://web.example.com/testing