K8s Ingress 详解

文章目录

  • [K8s Ingress 详解](#K8s Ingress 详解)
    • [Ingress 资源清单](#Ingress 资源清单)
    • [Ingress 基于URL 实现路由](#Ingress 基于URL 实现路由)
    • [Ingress 基于名称虚拟主机](#Ingress 基于名称虚拟主机)
    • [Ingress 实现HTTPS](#Ingress 实现HTTPS)
    • [Ingress Rewrite](#Ingress Rewrite)
    • [Ingress 灰度发布](#Ingress 灰度发布)
    • [Ingress 配置认证](#Ingress 配置认证)

K8s Ingress 详解

Ingress 资源清单

yaml 复制代码
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

yaml 复制代码
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

yaml 复制代码
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

yaml 复制代码
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

yaml 复制代码
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 证书

sh 复制代码
 # 使用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

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

配置ingress

yaml 复制代码
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 配置。

yaml 复制代码
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 > 权重

生产版本

yaml 复制代码
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

灰度版本

yaml 复制代码
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 设置账户密码

yaml 复制代码
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
相关推荐
Karoku0661 小时前
【CI/CD】CI/CD环境搭建流程和持续集成环境配置
运维·ci/cd·docker·容器·kubernetes·prometheus
Bright16687 小时前
centos9安装k8s集群
云原生·容器·kubernetes
!!!5258 小时前
华为云镜像加速器
docker·容器·华为云
xidianjiapei0019 小时前
Kubernetes的Ingress 资源是什么?
云原生·容器·kubernetes
林的快手10 小时前
CSS列表属性
前端·javascript·css·ajax·firefox·html5·safari
sszdzq11 小时前
Docker
运维·docker·容器
dmy11 小时前
docker 快速构建开发环境
后端·docker·容器
土豆沒加12 小时前
K8S的Dashboard登录及验证
云原生·容器·kubernetes
终端行者14 小时前
kubernetes1.28部署mysql5.7主从同步,使用Nfs制作持久卷存储,适用于centos7/9操作系统,
数据库·容器·kubernetes
伪装成塔的小兵19 小时前
Windows使用docker部署fastgpt出现的一些问题
windows·docker·容器·oneapi·fastgpt