
目录一.认识Ingress——控制器1.1Ingress介绍1.2Ingress Controller介绍二.Ingress-nginx2.1简单介绍2.2部署Ingress-nginx2.3修改Ingress-nginx的Service类型三.基于DaemonetHostnetwork部署Ingress-nginx可选四.基于虚拟机名称访问4.1简单介绍4.2创建Ingress规则4.3多域名访问4.3.1编写Ingress规则4.3.2上传镜像文件4.3.3创建Service4.3.4访问Pod五.基于路径访问5.1简单介绍5.2创建Ingress规则5.3访问后端Pod六.default backend6.1编写yaml文件6.2运行yml文件6.3修改 ingress-nginx-controller 的 DS 控制器配置6.4测试错误页面返回情况七.TLS证书7.1简单介绍7.1创建证书7.2创建Ingeress-tls7.4测试访问7.5配置登录用户,认证访问7.6访问加密网站八.重定向——rewrite8.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-nginx2.1简单介绍概念Ingress-nginx是 Kubernetes 社区中最流行的 Ingress Controller 实现之一基于Nginx构建由 Kubernetes 官方社区kubernetes/ingress-nginx维护。2.2部署Ingress-nginx1.下载并修改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-Nginxkubectl 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三.基于DaemonetHostnetwork部署Ingress-nginx可选说明默认部署的是deployment。Daemonet用于在每一个符合条件的节点上都运行一个Pod,适合部署Agent。通过让 Ingress Controller Pod 占用宿主机的80/443 端口外部流量通过节点 IP 直接进入。注意其他服务不可占用这个端口会报端口冲突。Hostnetwork使用主机网络性能更好但没有高可用和负载均衡。准备工作回收Ingress-Nginxkubectl 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-nodetrue #用于节点筛选和部署 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运行Servicekubectl 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的ServiceIPkubectl get svc ingress-nginx-controller -n ingress-nginx2.添加host解析vim /etc/hosts添加以下内容192.168.7.101 web1.example.com web2.example.com3.访问域名访问后端Pod访问myapp:v1curl -H Host: web1.example.com http://192.168.7.101 curl web1.example.com访问myapp:v2curl -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访问后端Pod1.创建域名解析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 headtitlePAGE NOT FOUND/title/head bodyPAGE NOT FOUND/body /html 503: | #503返回下述错误 !DOCTYPE html html headtitleCUSTOM SERVICE UNAVAILABLE/title/head bodyCUSTOM 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.html6.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-serviceingress-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 /CNnginxsvc/Onginxsvc #生成一个自签名的 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: #开启 HTTPSTLS访问这两个域名时浏览器会弹出用户名密码输入框。 - 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说明跳过密码验证直接访问443curl -k https://web1.example.com curl -k https://web2.example.com如果不跳过密码认证直接访问会报错因为我们没有配置登录的用户和密码7.5配置登录用户,认证访问1.安装httpd-toolsyum install -y httpd-tools2.创建用户htpasswd -c auth wxh #-c 创建新文件 cat authkubectl create secret generic basic-auth --from-fileauth3.创建证书说明把本地文件auth的内容打包成一个 Kubernetes Secretkubectl create secret generic basic-auth --from-fileauth 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.运行Ingresskubectl 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.运行Ingresskubectl 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