K8s Ingress 详解

K8s Ingress 详解

Ingress 资源清单

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: 
  name: <string>
  namespace: <string>
spec:
  ingressClassName: "nginx"   # 适配的Ingress控制器
  rules: <[]Object>   #  Ingress 规则列表
  - host: <string>
    http: <Object>  
      paths: <[]Object>   # 虚拟主机PATH 定义列表,列表由path 和 backend 组成
      - path: <string>    # 匹配以什么开头,类似nginx 中的location的作用
        pathType: <string>  # Prefix 前缀匹配,不区分大小写 Exact 精确匹配URL, 区分大小写
        backend: <Object>   
          service: <Object>  # 关联的后端Service
            name: <string>   # 后端Service 的名称
            port: <Object>   # 后端Service 端口的对象
              name: <string>  # 端口的名称
              number: <integr>  # 端口号

Ingress 基于URL 实现路由

注: 同一域名,不同的URL调度到不同的 Service

在这里插入图片描述

部署demoapp

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-prod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demoapp
  template:
    metadata:
      labels:
        app: demoapp
    spec:
      containers:
      - name: demo
        image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: app-svc
spec:
  type: ClusterIP
  selector:
    app: demoapp
  ports:
  - port: 80
    targetPort: 80

部署demo tomcat

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-prod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: java
        image: tomcat:9.0.6
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  type: ClusterIP
  selector:
    app: tomcat
  ports:
  - port: 8080
    targetPort: 8080

部署ingress

  • 默认URL:用户请求foo.ingress.net/app,代理到后端请求也会带上/app,后端无法处理该UrL,就会报错
  • 修改URL:用户请求foo.ingress.net/app,代理到后端后,将请求的/app删除,foo.ingress,net/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: foo-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2  # 配置Rewrite规则
spec:
  ingressClassName: "nginx"
  rules:
  - host: foo.ingress.net
    http:
      paths:
      - path: /app(/|$)(.*)  # 匹配的URL的第二部分(由第二个括号捕获的部分)作为新的目标路径。
        pathType: Prefix
        backend:
          service:
            name: app-svc
            port:
              number: 80
      - path: /java(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: tomcat-svc
            port:
              number: 8080

Ingress 基于名称虚拟主机

在这里插入图片描述

配置Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: foo-ingress
spec:
  ingressClassName: "nginx"
  rules:
  - host: app.ingress.net
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-svc
            port:
              number: 80
  - host: java.ingress.net
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-svc
            port:
              number: 8080

Ingress 实现HTTPS

在 Ingress 中引入 Secret 资源,然后告诉 Ingress 控制器使用 TLS 加密从客户端到负载均衡器的通道

创建TLS 证书

 # 使用openssl命令充当CA权威机构创建证书(生产不使用此方式生成证书,不被互联网认可的黑户证书)
openssl需要下载
[root@web01 ssl_key]# openssl genrsa -idea -out server.key 2048
Enter pass phrase for server.key: 123456
Verifying - Enter pass phrase for server.key: 123456
 
[root@web01 ssl_key]# ll
total 4
-rw-r--r--. 1 root root 1739 Dec  9 11:27 server.key

#生成自签证书(公钥),同时去掉私钥的密码
[root@web01 ssl_key]# openssl req -days 36500 -x509 -sha256 -nodes -newkey rsa:2048 -keyout server.key -out server.crt
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:meiguo
Locality Name (eg, city) [Default City]:riben
Organization Name (eg, company) [Default Company Ltd]:heishoudang
Organizational Unit Name (eg, section) []:oldboy
Common Name (eg, your name or your server's hostname) []:oldboy
Email Address []:123@qq.com

创建Secrets

[root@k8s-master ssl]# kubectl create secret tls java-ingress-tls --key=server.key --cert=server.crt 
secret/java-ingress-tls created

配置ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: java-ingress
spec:
  ingressClassName: "nginx"

# https
  tls:
  - hosts: 
    - java.ingress.net
    secretName: "java-ingress-tls"

  rules:
  - host: java.oldxu.net
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-svc
            port:
              number: 8080

Ingress Rewrite

  • Ingress Rewrite:Rancher(一个流行的Kubernetes管理平台)中提供的一项功能,通过改写HTTP请求和响应的URL路径,实现请求重定向、负载均衡以及URL路径的重写。
  • 请求重定向:可以将请求导向到不同的后端服务,实现简单的负载均衡。
  • URL路径重写:修改请求的URL路径,使其匹配实际需要的后端服务。

上面基于URL实现路由方案中,就应用到了 ingress rewrite 方案,下面示例插入自定义的 Nginx 配置。

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: my-app-ingress  
  annotations:  
    nginx.ingress.kubernetes.io/rewrite-target: /$2  # 如果需要基于路径重写,可以使用这个注解,但这里仅作为示例  
    nginx.ingress.kubernetes.io/configuration-snippet: |  
      location /old-path/ {  
          rewrite ^/old-path/(.*)$ /new-path/$1 break;  
          proxy_pass http://my-app-service;  
      }  
spec:  
  rules:  
  - http:  
      paths:  
      - path: /  
        pathType: Prefix  
        backend:  
          service:  
            name: my-app-service  
            port:  
              number: 80

Ingress 灰度发布

Ingress 灰度发布就是通过两套ingress 配置同一个域名,来实现

Ingress 灰度发布可以通过三个方式实现,

  1. 基于Request Header的流量切分

    • 使用nginx.ingress.kubernetes.io/canary-by-headernginx.ingress.kubernetes.io/canary-by-header-value annotations。
    • 客户端请求时,根据Request Header的值决定是否将请求路由到灰度版本。
  2. 基于Cookie的流量切分

    • 使用nginx.ingress.kubernetes.io/canary-by-cookie annotation。
    • 根据客户端Cookie的值来决定是否将请求路由到灰度版本。
  3. 基于服务权重的流量切分

    • 使用nginx.ingress.kubernetes.io/canary-weight annotation。
    • 设定灰度版本的权重(0-100%),按权重比例将请求路由到灰度版本。
  4. 流量切分的优先级 header 和 cookie > 权重

生产版本

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demoapp-ingress-prod
spec:
  ingressClassName: "nginx"
  rules:
  - host: "demoapp.ingress.net"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demoapp-prod-svc
            port:
              number: 80

灰度版本

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demoapp-ingress-canary
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"                  # 启动灰度发布
    #nginx.ingress.kubernetes.io/canary-by-header: "deploy"    # 基于header
    #nginx.ingress.kubernetes.io/canary-by-header-value: "new"
    #nginx.ingress.kubernetes.io/canary-weight: "30"    # 权重 30%流量调度到这个灰度的版本上
    nginx.ingress.kubernetes.io/canary-by-cookie: "request_from_wh"  # cookie
spec:
  ingressClassName: "nginx"
  rules:
  - host: "demoapp.ingress.net"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demoapp-canary-svc
            port:
              number: 80

Ingress 配置认证

先生成一个 basic-auth secret ,再引入nginx 就能给 nginx 设置账户密码

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: java-ingress
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic  # 认证类型
    nginx.ingress.kubernetes.io/auth-secret: basic-auth  # 包含用户和密码的 secret 资源名称
    nginx.ingress.kubernetes.io/auth-realm: 'Please User password'  # 要显示的信息
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/configuration-snippet: |        # 自定义跳转规则
      rewrite ^/docs/(.*)$  /java/docs/$1 redirect;
      rewrite ^/manager/(.*)$  /java/manager/$1 redirect;
      rewrite ^/examples/(.*)$  /java/examples/$1 redirect;
    nginx.ingress.kubernetes.io/server-snippet: |
          set $agentflag 0;
          if ($http_user_agent ~* "(iPhone|android)" ){
                set $agentflag 1;
          }
          if ( $agentflag = 1 ) {
                return 301 http://app.ingress.net;
          }

spec:
  ingressClassName: "nginx"
  rules:
  - host: java.ingress.net
    http:
      paths:
      - path: /java(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: tomcat-svc
            port:
              number: 8080
  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
K8s ingress(进入)是KubernetesK8s)中负责管理和控制入口流量的一种资源对象。它允许我们灵活地将外部流量路由Kubernetes集群中的不同服务和后端容器K8s ingress作为一种API对象,定义了一组规则,用于指定流量如何从集群外部进入特定的服务。它可以基于IP地址、主机名、URL路径等信息来进行路由和转发。 K8s ingress使用了标准的HTTP和HTTPS协议,并可以与一些标准的负载均衡器(如Nginx、HAProxy等)进行集成。在创建ingress资源时,常常会指定一个负载均衡器作为入口流量的进入点。该负载均衡器可以在集群外部接收流量,并将其转发到Kubernetes内部的不同服务上。 K8s ingress不仅提供了流量路由和负载均衡的功能,还支持请求的TLS终结(也称为SSL终结),即可以通过TLS协议对传入的TLS流量进行解密并转发至后端的服务。这极大地简化了为服务配置和管理SSL证书的过程。 另外,K8s ingress还支持多种流量处理的方式,如:会话粘滞、重试和故障转移等。这些功能使得在Kubernetes集群中实现高可用和灵活的流量管理变得更加容易。 总之,K8s ingress为我们提供了管理Kubernetes集群入口流量的强大工具。通过定义一些规则和策略,我们可以根据流量的特点和需求将其精确地路由和转发到后端服务上,并提供一些额外的功能,如负载均衡、SSL终结和多流量处理等。这使得我们可以更好地管理和控制流量,提高服务的可用性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

go&Python

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

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

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

打赏作者

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

抵扣说明:

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

余额充值