16.ingress

ingress

外部访问

在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的规则

在这里插入图片描述

externalIP

  • 实现外部网络访问node内部
##创建deployment
kubectl create deployment deploy-demo1 --image=nginx:1.14 --port=80 --replicas=3
##创建  service
kubectl expose deployment deploy-demo1 --port=80 --target-port=80

在这里插入图片描述

apiVersion: v1
kind: Service
metadata:
  labels:
    app: deploy-demo1
  name: deploy-demo1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: deploy-demo1
  externalIPs:                   ##设置  externalIP
  - 192.168.10.22
status:
  loadBalancer: {}

在这里插入图片描述

组成

  • ingress

    • ingress是一个API对象,通过yaml文件来配置,ingress对象的作用是定义请求如何转发到service的规则,可以理解为配置模板。
    • ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS能力以及基于域名的反向代理。ingress要依靠 ingress-controller 来具体实现以上功能。
  • ingress-controller:

    • ingress-controller是具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
    • 一般来说,ingress-controller的形式都是一个pod,里面跑着daemon程序和反向代理程序。daemon负责不断监控集群的变化,根据 ingress对象生成配置并应用新配置到反向代理,比如ingress-nginx就是动态生成nginx配置,动态更新upstream,并在需要的时候reload程序应用新配置
  • Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx

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

  • 总结

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

在这里插入图片描述

Ingress-Nginx

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

在这里插入图片描述

部署 nginx-ingress-controller

###在线下载ingress-controller Pod及相关资源
wget https://gitee.com/mirrors/ingress-nginx/raw/controller-v1.3.0/deploy/static/provider/cloud/deploy.yaml
##修改镜像地址

修改镜像地址为:
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.3.0@sha256:d1707ca76d3b044ab8a28277a2466a02100ee9f58a86af1535a3edf9323ea1b5


image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660

DaemonSet+HostNetwork

  • 用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。
  • 这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。
  • 比较适合大并发的生产环境使用。

创建 ingress控制器

##修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络

vim deploy.yaml
...
apiVersion: apps/v1
# 修改 kind
#kind: Deployment
kind: DaemonSet
......
spec:
  ......
  template:
    ......
    spec:
      # 使用宿主机网络
      hostNetwork: true
      # 修改选择节点选择器
      nodeSelector:
        ingress: "true"
......

在这里插入图片描述

##创建
kubectl apply -f deploy.yaml

在这里插入图片描述

##在随便一个 node节点中查看
netstat -lntp | grep nginx

在这里插入图片描述

由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。

其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。

这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了

创建ingress资源

##创建pod资源
kubectl create deployment deploy-demo1 --image=nginx:1.14 --port=80 --replicas=3
##为pod节点创建service资源
kubectl expose deployment deploy-demo1 --port=8080 --target-port=80

在这里插入图片描述

##创建ingress
kubectl create ingress ingress-demo1 --class=nginx --rule="www.a.com/=deploy-demo1:8080" --dry-run=client -o yaml > ingress-demo1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-demo1
spec:
  ingressClassName: nginx
  rules:
  - host: www.a.com
    http:
      paths:
      - backend:
          service:
            name: deploy-demo1
            port:
              number: 8080
        path: /
        pathType: Prefix
status:
  loadBalancer: {}
ingressClassName 指定 IngressClass,用来指定选择的 Ingress Controller

host 主机名可以是精确匹配,或者使用通配符来匹配,但通配符仅覆盖一个 DNS 标签(例如 *.foo.com 不匹配 baz.bar.foo.com)。

pathType 支持的路径类型有三种:
Exact:精确匹配 URL 路径,且区分大小写。

Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写。如果路径的最后一个元素是请求路径中最后一个元素的子字符串,则不会匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。

ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。

具体可详见:https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/#the-ingress-resource

在这里插入图片描述

在这里插入图片描述

##在另外一台主机上
##修改host
vim /etc/hosts
192.168.10.20 www.a.com

##访问网址查看
curl http://www.a.com

在这里插入图片描述

###在创建一个  deployment和servoce

kubectl create deployment deploy-demo2 --image=nginx:1.15 --port=80 --replicas=3

kubectl expose deployment deploy-demo2 --port=9090 --target-port=80

在这里插入图片描述

##创建ingress

kubectl create ingress ingress-demo1 --class=nginx --rule="www.b.com/=deploy-demo2:9090" --dry-run=client -o yaml > ingress-demo2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-demo2
spec:
  ingressClassName: nginx
  rules:
  - host: www.b.com
    http:
      paths:
      - backend:
          service:
            name: deploy-demo2
            port:
              number: 9090
        path: /
        pathType: Prefix
status:
  loadBalancer: {}

在这里插入图片描述

在这里插入图片描述

Deployment+NodePort模式

  • 同样用deployment模式部署ingress-controller,并创建对应的service,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。
  • 由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
  • NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响
##修改配置文件
vim deploy.yaml


kind: Deployment

type: NodePort

externalTrafficPolicy: Cluster

在这里插入图片描述

##创建ingress资源
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-demo1
spec:
  ingressClassName: nginx
  rules:
  - host: www.a.com
    http:
      paths:
      - backend:
          service:
            name: deploy-demo1
            port:
              number: 8080
        path: /
        pathType: Prefix
  - host: www.b.com
    http:
      paths:
      - backend:
          service:
            name: deploy-demo2
            port:
              number: 9090
        path: /
        pathType: Prefix

status:
  loadBalancer: {}

在这里插入图片描述

##访问验证

curl http://www.a.com:30080
curl http://www.b.com:30080

在这里插入图片描述

Ingress HTTPS 代理访问

生成证书和私钥

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

在这里插入图片描述

创建secret资源

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

在这里插入图片描述

创建Ingress资源

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-https
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - www.a.com
    secretName: tls-secret
  rules:
  - host: www.a.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service: 
            name: deploy-demo1
            port:
              number: 8080
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-http
spec:
  ingressClassName: nginx
  rules:
  - host: www.b.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service: 
            name: deploy-demo2
            port:
              number: 9090

在这里插入图片描述

Nginx 进行 BasicAuth

yum -y install httpd-tools
htpasswd -c auth zhangsan


New password:  123
Re-type new password: 123
Adding password for user zhangsan
kubectl create secret generic basic-auth --from-file=auth

在这里插入图片描述

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-http
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - zhangsan'
spec:
  ingressClassName: nginx
  rules:
  - host: www.b.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service: 
            name: deploy-demo2
            port:
              number: 9090

在这里插入图片描述

nginx进行重写

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  ingressClassName: nginx
  rules:
  - host: www.a.com
    http:
      paths:
      - path: /something(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: deply-demo1
            port: 
              number: 8080

在这里插入图片描述

在这里插入图片描述

总结

  • K8S集群外的客户端应用访问K8S集群内部服务的方案

    • Service:NodePort LoadBalancer externalIPs 只支持四层反向代理,端口数量有限,如果业务服务应用很多时端口的管理成本会比较高
    • Ingress:支持七层反向代理,可自定义规则根据用户请求的 域名 或 URL路径 转发给指定的 Service
  • ingress 的组成:

    • ingress资源对象:设置转发规则,告诉 ingress控制器应该根据什么域名或URL路径转发给相应的 Service 资源
    • ingress控制器(ingress-controller):根据 ingress 资源配置的转发规则转发用户请求的组件,以 Pod 形式运行的
  • ingress 的使用:

    • DaemonSet + Host网络模式 部署 ingress-controller
    • 数据流向:
      • 客户端 -> 防火墙、前端负载均衡器 -> Node节点的80/443端口进入ingress-controller -> 根据转发规则 -> 业务Pod的Service -> 业务Pod
    • Deployment + NodePort/LoadBalancer类型的Service 部署 ingress-controller
    • 数据流向:
      • 客户端 -> 防火墙、前端负载均衡器 -> ingress-controller的Service(NodeIP:NodePort)-> ingress-controller -> 根据转发规则 -> 业务Pod的Service -> 业务Pod
ingress 的配置:
kubectl create ingress <资源名称> --rule=<域名>/<URL路径>=<Service名称>:<Service端口> --class=<ingress控制器类>

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: 资源名称
spec:
  ingressClassName: 指定ingress控制器类
  rules:
  - host: 目标域名(可以精确匹配或通配符匹配,比如 *.kgc.com 可以匹配www.kgc.com或mail.kgc.com等,但不能匹配ky22.www.kgc.com)
    http:
      paths:
      - path: 目标域名后的URL路径(比如 / 代表网页根路径,或者 /test)
        pathType: Prefix|Exact(Exact用于精确匹配URL路径;Prefix用于前缀匹配,且只能匹配完整的字符串,/abc能匹配/abc/123,但不能匹配/abc123)
        backend:
          service:
            name: 目标Service资源的名称
            port:
              number: 目标Service的端口
      
	  #基于不同的 URL路径 的代理转发
      - path: URL路径2
	    ....
  #基于不同的 域名 的代理转发
  - host: 域名2
    http:
	....
#基于 https 代理转发
1)先获取 tls 证书和私钥文件
2)创建 tls 类型的 Secret资源   kubectl create secret tls <资源名称> --cert=证书文件路径  --key=私钥文件路径
3)创建 ingress 资源,引用 tls 类型的 Secret资源
spec:
  tls:
  - hosts:
    - 指定使用 https 访问的目标域名
    secretName: 指定tls类型的Secret资源
#基于 basic-auth 访问认证
1)使用 htpasswd 创建用户数据文件,固定文件名为 auth
2)创建 Secret资源 kubectl create secret generic <资源名称> --from-file=auth
3)创建 ingress 资源,在 annotations 注释字段中添加配置信息
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: Secret资源名称
    nginx.ingress.kubernetes.io/auth-realm: '窗口提示信息'
#基于 rewrite 重写访问路径
创建 ingress 资源,在 annotations 注释字段中添加配置信息
metadata:
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  ....
spec:
  rules:
  - host: "www.kgc.com"
    http:
      paths:
      - pathType: Prefix
        path: /something(/|$)(.*)
        backend:
          service:
            name: myapp-ky29
            port:
              number: 9090
捕获的正则表达式 任何字符(.*) 将其分配给占位符 $2,然后将其用作注释中的参数 rewrite-target
www.kgc.com[:端口]/something 重写为 www.kgc.com[:端口]/
www.kgc.com[:端口]/something/ 重写为 www.kgc.com[:端口]/
www.kgc.com[:端口]/something/new 重写为 www.kgc.com[:端口]/new
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: https://www.accp.com:30443
spec:
  rules:
  - host: "www.kgc.com"

将任何使用 www.kgc.com 作域名的访问请求,都重写成 https://www.accp.com:30443
metadata:
  annotations:
    nginx.ingress.kubernetes.io/app-root: /app1
spec:
  rules:
  - host: "www.kgc.com"
    http:
      paths:
      - pathType: Prefix
        path: /

将访问 www.kgc.com[:端口]/ 的请求,都重写成 www.kgc.com[:端口]/app1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜海赤竹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值