Ingress

文章目录

    • 环境准备
    • [什么是 Ingress](#什么是 Ingress)
    • [认识 Ingress 资源](#认识 Ingress 资源)
    • [Ingress 控制器(controller)](#Ingress 控制器(controller))
    • [Ingress 规则](#Ingress 规则)
    • [pathType 路径类型](#pathType 路径类型)
    • 多重匹配
    • [Ingress 类](#Ingress 类)
    • TLS

环境准备

下面的 yaml 文件内容,是使用 sts 创建两个 web 服务,并配置对应的 servcie。web 服务的首页内容使用 configmap 配置并挂载到各自的 POD 中。

yaml 复制代码
apiVersion: v1
kind: Namespace
metadata:
  name: shark-test
---
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: shark-test
  name: index.html
data:
  # 类属性键;每一个键都映射到一个简单的值
  web1.index.html: |
    web1 站点

  web2.index.html: |
    web2 站点
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: shark-test
  name: web1
spec:
  selector:
    matchLabels:
      app: web1 # 必须匹配 .spec.template.metadata.labels
  serviceName: "web1"
  replicas: 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: web1 # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: web1
        image: nginx:1.21.6-alpine
        ports:
        - containerPort: 80
          name: web1
        volumeMounts:
        - name: index-html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: index-html          # 给 volumeMounts[].name使用
        configMap:
          name: index.html   # configmap 的名称
          items:
          - key: web1.index.html  # configmap 对象中 data 中的一个 key
            path: index.html      # 挂载到 pod 后,被创建的文件名称
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: shark-test
  name: web2
spec:
  selector:
    matchLabels:
      app: web2 # 必须匹配 .spec.template.metadata.labels
  serviceName: "web2"
  replicas: 1
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: web2 # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: web2
        image: nginx:1.21.6-alpine
        ports:
        - containerPort: 80
          name: web2
        volumeMounts:
        - name: index-html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: index-html          # 给 volumeMounts[].name使用
        configMap:
          name: index.html   # configmap 的名称
          items:
          - key: web2.index.html  # configmap 对象中 data 中的一个 key
            path: index.html      # 挂载到 pod 后,被创建的文件名称
---
apiVersion: v1
kind: Service
metadata:
  namespace: shark-test
  name: web1
  labels:
    app: web1
spec:
  type: ClusterIP
  ports:
  - port: 8080
    name: web1-http
    targetPort: 80
  clusterIP: None
  selector:
    app: web1
---
apiVersion: v1
kind: Service
metadata:
  namespace: shark-test
  name: web2
  labels:
    app: web2
spec:
  type: ClusterIP
  ports:
  - port: 8080
    name: web2-http
    targetPort: 80
  clusterIP: None
  selector:
    app: web2

什么是 Ingress

Ingress 是管理集群外部访问集群内部服务的流量的 API 对象,是 kubernetes 中对 service 的反向代理。 流量的去向由 Ingress 资源所定义的规则来控制。

可提供负载均衡、SSL 和基于名称的虚拟主机功能。

主要的访问方式是 HTTP/HTTPS,不支持四层协议。下一代替代 Ingress 的产品 Gateway API 可以实现 四层和七层协议流量管理。
Ingress 在 kubernentes v1.28 版本停止更新,并推出了可以实现更多功能的 Gateway API
集群 负载均衡器 Ingress 的路由规则 Ingress Pod Service Pod 客户端

认识 Ingress 资源

Ingress 资源的 YAML 文件,可以理解为是对 Nginx 子配置文件的抽象,因为它和 nginx 中关于虚拟机主机 server 配置块的功能一致 。

下面是 Nginx 子配置文件和Ingress 的 yaml 文件的对比图。

  1. 红色框就是请求中的 url
  2. 黄色框就是 nginx 的 rewrite ,用于实现地址(url)重写,这里实现的功能是去掉请求 url 中的前缀。
  3. 绿色框就是 后端服务的连接信息,nginx 中是 upstream 的名称,kubernetes 中是 service 名称
  4. 紫色框就是后端服务的监听端口。

资源名称: Ingress 对象的命名必须是合法的 DNS 子域名名称。

  • 不能超过 253 个字符
  • 只能包含小写字母、数字,以及 '-' 和 '.'
  • 必须以字母数字开头
  • 必须以字母数字结尾
    注解(annotations) : Ingress 经常使用一些注解来配置一些选项,以便扩展功能,例如 rewrite-target 注解。 不同的 Ingress 控制器支持不同的注解。

规则(rule): 其中包含对所有入站请求进行匹配的规则列表。

Ingress 控制器(controller)

为了让 Ingress 对象有效的创建和工作,需要有一个 Ingress Controller 。

Ingress Controller 的角色是用一个反向代理实现的。反向代理可以是 nginx、haproxy 等其中的一个,因此 Ingress Controller 可以有很多种。

这里我用最常用的 Ingress-Nginx Controller 为例说明。

当一个 Ingress 对象被成功创建后,Ingress Controller 会把 Ingress 对象中的内容转换成 nginx 的子配置文件,并让 Ingress Controller 使用。

后续会详细介绍。

Ingress 规则

一个简单的 Ingress 资源示例。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
  - http:
      paths:
      - path: "/web1"
        pathType: Prefix
        backend:
          service:
            name: web1
            port:
              number: 8080

每个 HTTP 规则都包含以下信息:

  • 可选的 host。在此示例中,未指定 host,因此该规则适用于使用指定 IP 地址进行入站 HTTP 请求的情况。 如果提供了 host(例如 foo.shark.com),则 rules 适用于所指定的主机( foo.shark.com)。
  • path 路径列表(例如 /web1)。每个路径都有一个由 service.nameservice.port.nameservice.port.number 确定的关联后端。入站请求的内容都必须与 hostpath 的值相匹配,负载均衡器才会将流量引导到所引用的 Service,
  • backend(后端)是 Service 中所定义的 名称和端口的组合, 或者是通过 CRD 方式来实现的自定义资源后端。

通常会在 Ingress 控制器中配置 defaultBackend(默认后端), 以便为无法与规约中任何路径匹配的所有请求提供服务,也就是通常会返回 404 页面。

pathType 路径类型

Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 pathType 的路径无法通过合法性检查。当前支持的路径类型有三种:

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

  2. Exact:精确匹配 URL 路径,且区分大小写。

  3. Prefix :基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写, 并且对路径中各个元素逐个执行匹配操作。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。

说明: 如果 path 值的最后一个元素是请求路径中最后一个元素的子字符串,则不会被视为匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。

多重匹配

有的时候,一个请求会和一个 Ingress 中的多个 path 匹配,这时 path 最长者优先匹配。 如果仍然有两条同等的匹配路径,则精确路径类型优先于前缀路径类型。

Ingress 类

Ingress 可以由不同的控制器实现,通常使用不同的配置。 每个 Ingress 应当指定一个类,也就是一个对 IngressClass 资源的引用。 IngressClass 资源包含额外的配置,其中包括应当实现该类的控制器名称。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    app.kubernetes.io/component: controller
  name: nginx-example
spec:
  controller: k8s.io/ingress-nginx

设置默认的 Ingress 类,只需要在注解中添加:
ingressclass.kubernetes.io/is-default-class: "true"

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  labels:
    app.kubernetes.io/component: controller
  name: nginx-example
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: k8s.io/ingress-nginx

TLS

生成证书

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=itheima.com"

创建密钥

可以通过设定包含 TLS 私钥和证书的Secret 来保护 Ingress。TLS Secret 的数据中必须包含键名为 tls.crt 的证书和键名为 tls.key 的私钥, 才能用于 TLS 目的。例如:

yaml 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
data:
  tls.crt: base64 编码的证书
  tls.key: base64 编码的私钥
type: kubernetes.io/tls

也可以使用下面的方法创建

bash 复制代码
kubectl create secret tls tls-secret --key tls.key --cert tls.crt

注意,不能针对默认规则使用 TLS,因为这样做需要为所有可能的子域名签发证书。 因此,tls 字段中的 hosts 的取值需要与 rules 字段中的 host 完全匹配。

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
      - https-example.foo.com
    secretName: testsecret-tls
  rules:
  - host: https-example.foo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80
相关推荐
二宝1528 小时前
黑马商城day4-微服务02
微服务·云原生·架构
数据库知识分享者小北10 小时前
云栖重磅|瑶池数据库:从云原生数据底座向“AI就绪”的多模态数据底座演进
数据库·人工智能·云原生
阿里云云原生14 小时前
Higress v2.1.8:30 项引擎更新 + 4 项控制台更新
云原生
阿里云云原生17 小时前
移动端性能监控探索:iOS RUM SDK 技术架构与实践
云原生
阿里云云原生17 小时前
Nacos 3.1.0 正式发布,支持 A2A 注册中心与 MCP 注册协议增强
微服务·云原生
阿里云云原生17 小时前
Qoder 上线提示词增强功能,将开发者从“提示词”的负担中解放出来
云原生
suknna18 小时前
通过命令模拟pod创建
kubernetes
维诺菌18 小时前
k8s java应用pod内存占用过高问题排查
java·jvm·云原生·容器·性能优化·kubernetes
回忆是昨天里的海18 小时前
k8s安装-kubeadm join,将工作节点加入k8s集群
java·服务器·kubernetes
浪飘18 小时前
k8s device plugin
java·docker·kubernetes