×

使用Ingress控制器和路由

Ingress操作符管理Ingress控制器和通配符DNS。

使用Ingress控制器是允许外部访问OpenShift Container Platform集群的最常见方法。

Ingress控制器被配置为接受外部请求并根据配置的路由代理它们。这仅限于使用SNI的HTTP、HTTPS和使用SNI的TLS,这对于通过使用SNI的TLS工作的Web应用程序和服务来说已经足够了。

与您的管理员协作,配置Ingress控制器以接受外部请求并根据配置的路由代理它们。

管理员可以创建一个通配符DNS条目,然后设置一个Ingress控制器。然后,您可以使用边缘Ingress控制器,而无需联系管理员。

默认情况下,集群中的每个Ingress控制器都可以接收在集群中任何项目中创建的任何路由。

Ingress控制器

  • 默认情况下有两个副本,这意味着它应该运行在两个工作节点上。

  • 可以扩展到在更多节点上拥有更多副本。

本节中的过程需要由集群管理员执行的先决条件。

先决条件

在开始以下过程之前,管理员必须

  • 将外部端口设置到集群网络环境,以便请求可以到达集群。

  • 确保至少有一个具有集群管理员角色的用户。要将此角色添加到用户,请运行以下命令

    $ oc adm policy add-cluster-role-to-user cluster-admin username
  • 您拥有一个OpenShift Container Platform集群,该集群至少有一个主节点和至少一个节点,以及一个具有对集群的网络访问权限的集群外部系统。此过程假设外部系统与集群位于同一子网中。对于位于不同子网上的外部系统所需的附加网络配置,不在本主题的讨论范围之内。

创建项目和服务

如果要公开的项目和服务不存在,请创建项目,然后创建服务。

如果项目和服务已存在,请跳到关于公开服务以创建路由的过程。

先决条件
  • 安装OpenShift CLI (oc) 并以集群管理员身份登录。

步骤
  1. 通过运行oc new-project命令创建一个新项目

    $ oc new-project <project_name>
  2. 使用oc new-app命令创建您的服务

    $ oc new-app nodejs:12~https://github.com/sclorg/nodejs-ex.git
  3. 要验证服务是否已创建,请运行以下命令

    $ oc get svc -n <project_name>
    示例输出
    NAME        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    nodejs-ex   ClusterIP   172.30.197.157   <none>        8080/TCP   70s

    默认情况下,新服务没有外部IP地址。

通过创建路由来公开服务

您可以使用oc expose命令将服务公开为路由。

先决条件
  • 您已登录到OpenShift Container Platform。

步骤
  1. 登录到包含您要公开的服务的项目

    $ oc project <project_name>
  2. 运行oc expose service命令来公开路由

    $ oc expose service nodejs-ex
    示例输出
    route.route.openshift.io/nodejs-ex exposed
  3. 要验证服务是否已公开,您可以使用curl等工具来检查服务是否可以从集群外部访问。

    1. 要查找路由的主机名,请输入以下命令

      $ oc get route
      示例输出
      NAME        HOST/PORT                        PATH   SERVICES    PORT       TERMINATION   WILDCARD
      nodejs-ex   nodejs-ex-myproject.example.com         nodejs-ex   8080-tcp                 None
    2. 要检查主机是否响应GET请求,请输入以下命令

      curl命令示例
      $ curl --head nodejs-ex-myproject.example.com
      示例输出
      HTTP/1.1 200 OK
      ...

OpenShift Container Platform中的Ingress分片

在OpenShift Container Platform中,Ingress控制器可以服务所有路由,也可以服务一部分路由。默认情况下,Ingress控制器服务集群中任何命名空间中创建的任何路由。您可以向集群添加额外的Ingress控制器,通过创建分片(基于所选特征的路由子集)来优化路由。要将路由标记为分片成员,请在路由或命名空间的metadata字段中使用标签。Ingress控制器使用选择器(也称为选择表达式)从整个路由池中选择要服务的路由子集。

当您想要跨多个Ingress控制器负载均衡传入流量,想要隔离要路由到特定Ingress控制器的流量,或者出于下一节中描述的各种其他原因时,Ingress分片非常有用。

默认情况下,每个路由都使用集群的默认域。但是,可以将路由配置为使用路由器的域。

Ingress控制器分片

您可以使用Ingress分片(也称为路由器分片)通过向路由、命名空间或两者都添加标签来将一组路由分布到多个路由器。Ingress控制器使用一组相应的选择器来仅接收具有指定标签的路由。每个Ingress分片包含使用给定选择表达式过滤的路由。

作为流量进入集群的主要机制,对Ingress控制器的需求可能很大。作为集群管理员,您可以将路由分片到

  • 平衡Ingress控制器或路由器,并使用多个路由来加快对更改的响应速度。

  • 分配某些路由以获得与其他路由不同的可靠性保证。

  • 允许某些Ingress控制器定义不同的策略。

  • 仅允许特定路由使用附加功能。

  • 例如,在不同的地址上公开不同的路由,以便内部和外部用户可以看到不同的路由。

  • 在蓝绿部署期间将流量从一个版本的应用程序转移到另一个版本。

当Ingress控制器被分片时,给定的路由被组中的零个或多个Ingress控制器接收。路由的状态描述了Ingress控制器是否已接收它。只有当路由对其分片唯一时,Ingress控制器才会接收该路由。

Ingress控制器可以使用三种分片方法

  • 仅向Ingress控制器添加命名空间选择器,以便具有与命名空间选择器匹配的标签的命名空间中的所有路由都在Ingress分片中。

  • 仅向Ingress控制器添加路由选择器,以便具有与路由选择器匹配的标签的所有路由都在Ingress分片中。

  • 向Ingress控制器添加命名空间选择器和路由选择器,以便具有与路由选择器匹配的标签且位于具有与命名空间选择器匹配的标签的命名空间中的路由都在Ingress分片中。

通过分片,您可以将路由子集分布到多个Ingress控制器。这些子集可以是不重叠的,也称为传统分片,也可以是重叠的,也称为重叠分片。

传统分片示例

已配置的Ingress控制器finops-router示例,其标签选择器spec.namespaceSelector.matchExpressions的键值设置为financeops

finops-router的YAML定义示例
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: finops-router
  namespace: openshift-ingress-operator
spec:
  namespaceSelector:
    matchExpressions:
    - key: name
      operator: In
      values:
      - finance
      - ops

已配置的Ingress控制器dev-router示例,其标签选择器spec.namespaceSelector.matchLabels.name的键值设置为dev

dev-router的YAML定义示例
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: dev-router
  namespace: openshift-ingress-operator
spec:
  namespaceSelector:
    matchLabels:
      name: dev

如果所有应用程序路由都在单独的命名空间中,例如每个命名空间都标有name:financename:opsname:dev,则该配置有效地将您的路由分布在两个Ingress控制器之间。不应处理控制台、身份验证和其他用途的OpenShift Container Platform路由。

在之前的场景中,分片成为分区的一个特例,没有重叠的子集。路由在路由器分片之间划分。

default Ingress控制器将继续服务所有路由,除非namespaceSelectorrouteSelector字段包含用于排除的路由。有关如何从默认Ingress控制器中排除路由的更多信息,请参阅此Red Hat知识库解决方案和“分片默认Ingress控制器”部分。

重叠分片示例

已配置的Ingress控制器devops-router示例,其标签选择器spec.namespaceSelector.matchExpressions的键值设置为devops

devops-router的YAML定义示例
apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: devops-router
  namespace: openshift-ingress-operator
spec:
  namespaceSelector:
    matchExpressions:
    - key: name
      operator: In
      values:
      - dev
      - ops

现在,标记为name:devname:ops的命名空间中的路由由两个不同的Ingress控制器服务。通过此配置,您拥有重叠的路由子集。

使用重叠的路由子集,您可以创建更复杂的路由规则。例如,您可以将更高优先级的流量转移到专用的finops-router,同时将较低优先级的流量发送到devops-router

分片默认Ingress控制器

创建新的Ingress分片后,可能会有被您的新Ingress分片接收的路由,这些路由也被默认Ingress控制器接收。这是因为默认Ingress控制器没有选择器,默认情况下会接收所有路由。

您可以使用命名空间选择器或路由选择器来限制Ingress控制器服务具有特定标签的路由。以下过程使用命名空间选择器来限制默认Ingress控制器服务您新分片的financeopsdev路由。这为Ingress分片增加了进一步的隔离。

您必须将所有OpenShift Container Platform的管理路由保留在同一个Ingress控制器上。因此,请避免向默认Ingress控制器添加额外的选择器来排除这些必要的路由。

先决条件
  • 您已安装OpenShift CLI(oc)。

  • 您已以项目管理员身份登录。

步骤
  1. 通过运行以下命令修改默认Ingress控制器

    $ oc edit ingresscontroller -n openshift-ingress-operator default
  2. 编辑Ingress控制器以包含一个namespaceSelector,该选择器将排除具有任何financeopsdev标签的路由

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: default
      namespace: openshift-ingress-operator
    spec:
      namespaceSelector:
        matchExpressions:
          - key: name
            operator: NotIn
            values:
              - finance
              - ops
              - dev

默认Ingress控制器将不再服务标记为name:financename:opsname:dev的命名空间。

Ingress分片和DNS

集群管理员负责为项目中的每个路由器创建单独的DNS条目。路由器不会将未知路由转发到另一个路由器。

考虑以下示例

  • 路由器A位于主机192.168.0.5上,并具有*.foo.com路由。

  • 路由器B位于主机192.168.1.9上,并具有*.example.com路由。

单独的DNS条目必须将*.foo.com解析为主机路由器A的节点,并将*.example.com解析为主机路由器B的节点

  • *.foo.com A IN 192.168.0.5

  • *.example.com A IN 192.168.1.9

使用路由标签配置 Ingress 控制器分片

使用路由标签进行 Ingress 控制器分片意味着 Ingress 控制器将服务于路由选择器选择的任何命名空间中的任何路由。

A diagram showing multiple Ingress Controllers with different route selectors serving any route containing a label that matches a given route selector regardless of the namespace a route belongs to
图 1. 使用路由标签进行 Ingress 分片

当在多个 Ingress 控制器之间平衡传入流量负载以及将流量隔离到特定 Ingress 控制器时,Ingress 控制器分片非常有用。例如,公司 A 连接到一个 Ingress 控制器,而公司 B 连接到另一个。

步骤
  1. 编辑router-internal.yaml文件

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: sharded
      namespace: openshift-ingress-operator
    spec:
      domain: <apps-sharded.basedomain.example.net> (1)
      nodePlacement:
        nodeSelector:
          matchLabels:
            node-role.kubernetes.io/worker: ""
      routeSelector:
        matchLabels:
          type: sharded
    1 指定 Ingress 控制器要使用的域名。此域名必须与默认的 Ingress 控制器域名不同。
  2. 应用 Ingress 控制器router-internal.yaml文件

    # oc apply -f router-internal.yaml

    Ingress 控制器选择任何命名空间中具有标签type: sharded的路由。

  3. 使用在router-internal.yaml中配置的域名创建一个新的路由

    $ oc expose svc <service-name> --hostname <route-name>.apps-sharded.basedomain.example.net

使用命名空间标签配置 Ingress 控制器分片

使用命名空间标签进行 Ingress 控制器分片意味着 Ingress 控制器将服务于命名空间选择器选择的任何命名空间中的任何路由。

A diagram showing multiple Ingress Controllers with different namespace selectors serving routes that belong to the namespace containing a label that matches a given namespace selector
图 2. 使用命名空间标签进行 Ingress 分片

当在多个 Ingress 控制器之间平衡传入流量负载以及将流量隔离到特定 Ingress 控制器时,Ingress 控制器分片非常有用。例如,公司 A 连接到一个 Ingress 控制器,而公司 B 连接到另一个。

步骤
  1. 编辑router-internal.yaml文件

    $ cat router-internal.yaml
    示例输出
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: sharded
      namespace: openshift-ingress-operator
    spec:
      domain: <apps-sharded.basedomain.example.net> (1)
      nodePlacement:
        nodeSelector:
          matchLabels:
            node-role.kubernetes.io/worker: ""
      namespaceSelector:
        matchLabels:
          type: sharded
    1 指定 Ingress 控制器要使用的域名。此域名必须与默认的 Ingress 控制器域名不同。
  2. 应用 Ingress 控制器router-internal.yaml文件

    $ oc apply -f router-internal.yaml

    Ingress 控制器选择命名空间选择器选择的任何命名空间中具有标签type: sharded的路由。

  3. 使用在router-internal.yaml中配置的域名创建一个新的路由

    $ oc expose svc <service-name> --hostname <route-name>.apps-sharded.basedomain.example.net

创建 Ingress 控制器分片的路由

路由允许您在 URL 上托管您的应用程序。在这种情况下,未设置主机名,路由使用子域名。当您指定子域名时,您会自动使用公开路由的 Ingress 控制器的域名。对于由多个 Ingress 控制器公开路由的情况,路由将在多个 URL 上托管。

以下步骤描述了如何使用hello-openshift应用程序为例创建 Ingress 控制器分片的路由。

当在多个 Ingress 控制器之间平衡传入流量负载以及将流量隔离到特定 Ingress 控制器时,Ingress 控制器分片非常有用。例如,公司 A 连接到一个 Ingress 控制器,而公司 B 连接到另一个。

先决条件
  • 您已安装OpenShift CLI(oc)。

  • 您已以项目管理员身份登录。

  • 您有一个 Web 应用程序,它公开一个端口和一个 HTTP 或 TLS 端点,用于监听该端口上的流量。

  • 您已为分片配置了 Ingress 控制器。

步骤
  1. 通过运行以下命令创建一个名为hello-openshift的项目

    $ oc new-project hello-openshift
  2. 通过运行以下命令在项目中创建一个 Pod

    $ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
  3. 通过运行以下命令创建一个名为hello-openshift的服务

    $ oc expose pod/hello-openshift
  4. 创建一个名为hello-openshift-route.yaml的路由定义

    创建的分片路由的 YAML 定义
    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      labels:
        type: sharded (1)
      name: hello-openshift-edge
      namespace: hello-openshift
    spec:
      subdomain: hello-openshift (2)
      tls:
        termination: edge
      to:
        kind: Service
        name: hello-openshift
    1 标签键及其对应的标签值必须与 Ingress 控制器中指定的标签键和值匹配。在此示例中,Ingress 控制器具有标签键和值type: sharded
    2 路由将使用subdomain字段的值公开。当您指定subdomain字段时,必须将主机名留空。如果您同时指定hostsubdomain字段,则路由将使用host字段的值,并忽略subdomain字段。
  5. 使用hello-openshift-route.yaml通过运行以下命令为hello-openshift应用程序创建一个路由

    $ oc -n hello-openshift create -f hello-openshift-route.yaml
验证
  • 使用以下命令获取路由的状态

    $ oc -n hello-openshift get routes/hello-openshift-edge -o yaml

    生成的Route资源应类似于以下内容

    示例输出
    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      labels:
        type: sharded
      name: hello-openshift-edge
      namespace: hello-openshift
    spec:
      subdomain: hello-openshift
      tls:
        termination: edge
      to:
        kind: Service
        name: hello-openshift
    status:
      ingress:
      - host: hello-openshift.<apps-sharded.basedomain.example.net> (1)
        routerCanonicalHostname: router-sharded.<apps-sharded.basedomain.example.net> (2)
        routerName: sharded (3)
    1 Ingress 控制器(或路由器)用于公开路由的主机名。host字段的值由 Ingress 控制器自动确定,并使用其域名。在此示例中,Ingress 控制器的域名是<apps-sharded.basedomain.example.net>
    2 Ingress 控制器的主机名。
    3 Ingress 控制器的名称。在此示例中,Ingress 控制器的名称为sharded

其他资源