IBM Cloud Docs
使用 Ingress 公开暴露应用程序

使用 Ingress 公开暴露应用程序

通过创建由 Ingress 控制器管理的 Ingress 资源,在Red Hat® OpenShift® on IBM Cloud®集群中公开发布多个应用程序。

先决条件

开始使用 Ingress 之前,请查看以下先决条件。

  • 设置 Ingress 需要以下 IBM Cloud IAM 角色
    • IBM Cloud Kubernetes Service中集群的 管理员 平台访问角色。
    • 所有 IBM Cloud Kubernetes Service 名称空间 (Red Hat OpenShift 项目) 中的 管理者 服务访问角色。
  • 如果某个区域发生故障,那么您可能会在对该区域中的 Ingress 控制器所公开的应用程序的请求中看到间歇性故障。
  • 为确保高可用性,建议每个专区至少有两个工作程序节点。

使用公共云服务端点在集群中公开应用程序

经典集群 虚拟私有云

如果集群是在经典基础架构上创建的,或者如果集群是在 VPC 基础架构上创建的,并且您在创建时启用了公共云服务端点,那么可以使用缺省公共 Ingress 控制器来公开集群中的应用程序,以接收来自公用网络的请求。

开始之前:

步骤 1:部署应用程序并创建应用程序服务

首先部署应用程序,并创建 Kubernetes 服务来公开这些应用程序。

  1. 将应用程序部署到集群。 确保在配置文件的 metadata 部分中向部署添加标签,例如 app: code。 需要使用此标签来标识运行应用程序的所有 pod,以便让这些 pod 进入 Ingress 负载平衡。

  2. 对于要公开的每个应用程序部署,创建 Kubernetes ClusterIP 服务。 您的应用程序必须由Kubernetes服务公开,才能包含在 Ingress 负载平衡中。

oc expose deploy <app_deployment_name> --name my-app-svc --port <app_port> -n <namespace>

步骤 2: 使用 TLS 证书和 Kubernetes 私钥设置 TLS 终止

TLS 证书必须存储为应用程序所在的每个名称空间中的 Kubernetes 私钥。

步骤 3:创建入口资源

Ingress 资源定义了 Ingress 控制器用于将流量路由到应用程序服务的路由规则。

  1. 定义输入资源配置文件,使用IBM域或您自定义的域将传入网络流量路由到您先前创建的服务。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: myingressresource
    spec:
      tls:
      - hosts:
        - <domain>
        secretName: <secret_name>
      rules:
      - host: <domain>
        http:
          paths:
          - path: /<app1_path>
            pathType: Prefix
            backend:
                service:
                    name: test
                    port:
                        number: 80
          - path: /<app2_path>
            backend:
                service:
                    name: <app2_service>
                    port:
                        number: 80
    
    tls
    如果要使用 TLS,请在资源中包含此 TLS 部分。 将 <domain> 替换为子域。 请勿使用 "* 作为主机或将主机属性留空,以免在创建 Ingress 时出现故障。 将 <tls_secret_name> 替换为先前创建的私钥,该私钥用于保存定制域的 TLS 证书和密钥,或者用于自动为 IBM提供的子域生成的 TLS 私钥。
    host
    将 "<domain> 替换为IBM Ingress 子域或您的自定义域。 如果您的集群有多个暴露应用程序的项目,则每个项目需要一个 Ingress 资源。 可以在每个资源中使用相同的子域,也可以在每个资源中使用不同的子域。 例如,如果使用通配符域,那么可以将通配符子域附加到域的开头,例如 subdomain1.custom_domain.netsubdomain1.mycluster-<hash>-0000.us-south.containers.appdomain.cloud。 不要为主机使用 * 或将主机属性留空,以避免在创建 Ingress 时出现故障。
    path
    <app_path> 替换为应用程序正在侦听的路径。 该路径将附加到 IBM 提供的域或定制域,以创建应用程序的唯一路径。 在 Web 浏览器中输入此路径时,网络流量会路由到 Ingress 控制器。 Ingress 控制器会查找关联的服务,并且 Ingress 控制器会将网络流量发送到该服务。 然后,服务会将流量转发到应用程序运行所在的 pod。 许多应用程序并不监听特定路径,而是使用根路径和特定端口。 在这种情况下,请将根路径定义为 "/,而不要为应用程序指定单独的路径。 对于“http://domain/,输入”/ 作为路径。 对于“http://domain/app1_path,输入”/app1_path 作为路径。
    pathType
    URL 路径匹配方法。 支持的值为 ImplementationSpecificExactPrefix。 有关每种路径类型的详细信息和示例,请参阅 社区 Kubernetes 文档
    name
    将“<app1_service> 和”<app2_service> 替换为您创建的用于公开应用程序的服务名称,以此类推。 如果您的应用程序由群集中不同项目的服务暴露,则只包含同一项目中的应用程序服务。 您必须为每个项目创建一个 Ingress 资源,因为每个项目都有您要公开的应用程序。
    port
    服务侦听的端口。 使用针对应用程序创建 Kubernetes 服务时定义的端口。
  2. 为集群创建 Ingress 资源。 确保资源部署到与资源中指定的应用程序服务相同的项目中。

    oc apply -f myingressresource.yaml -n <project>
    
  3. 验证 Ingress 资源是否已成功创建。 如果事件中的信息描述了资源配置中的错误,请修复资源文件中的值,并重新应用资源文件。

    oc describe ingress myingressresource
    

将在应用程序服务所在的项目中创建 Ingress 资源,并向 Ingress 控制器注册应用程序。

第 4 步:从互联网访问应用程序

在 Web 浏览器中,输入要访问的应用程序服务的 URL。

https://<domain>/<app1_path>

如果公开了多个应用程序,请通过更改附加到该 URL 的路径来访问这些应用程序。

https://<domain>/<app2_path>

如果使用通配符域,请使用这些应用程序自己的子域来访问这些应用程序。

http://<subdomain1>.<domain>/<app1_path>
http://<subdomain2>.<domain>/<app1_path>

无法通过 Ingress 连接到应用程序? 请尝试 对 Ingress 进行故障诊断

仅使用私有云服务端点在 VPC 集群中公开应用程序

虚拟私有云

如果在 VPC 基础结构上创建了集群,并且在创建集群时仅启用了私有云服务端点,那么缺省情况下将仅使用私有 Ingress 控制器来创建集群。 要公开应用程序,必须首先创建公共 Ingress 控制器。 然后,必须向子域注册 Ingress 控制器,并 (可选) 导入您自己的 TLS 证书。

步骤 1:部署应用程序并创建应用程序服务

首先部署应用程序,并创建 Kubernetes 服务来公开这些应用程序。

  1. 将应用程序部署到集群。 确保在配置文件的 metadata 部分中向部署添加标签,例如 app: code。 需要使用此标签来标识运行应用程序的所有 pod,以便让这些 pod 进入 Ingress 负载平衡。

  2. 对于要公开的每个应用程序部署,创建 Kubernetes ClusterIP 服务。 您的应用程序必须由Kubernetes服务公开,才能包含在 Ingress 负载平衡中。

oc expose deploy <app_deployment_name> --name my-app-svc --port <app_port> -n <namespace>

步骤 2: 使用 TLS 证书和 Kubernetes 私钥设置 TLS 终止

TLS 证书必须存储为应用程序所在的每个名称空间中的 Kubernetes 私钥。

定制 Ingress 域的 TLS 私钥

要使用您自己创建的域 (例如,向外部提供程序注册的域),请参阅 为定制子域设置 TLS 私钥

IBM管理的 Ingress 域的 TLS 私钥

遵循步骤为 IBM管理的 Ingress 域设置 TLS 私钥。

  1. 列出集群中的现有子域。 在输出的 子域 列中,复制具有最高 000<n> 值的子域。
    ibmcloud oc nlb-dns ls --cluster <cluster_name_or_id>
    
    在此示例输出中, mycluster-a1b2cdef345678g9hi012j3kl4567890-0002.us-south.containers.appdomain.cloud 子域具有最高 000<n>0002
    Subdomain                                                                               Load Balancer Hostname                        Health Monitor   SSL Cert Status           SSL Cert Secret Name
    mycluster-a1b2cdef345678g9hi012j3kl4567890-0000.us-south.containers.appdomain.cloud     ["1234abcd-us-south.lb.appdomain.cloud"]      None             created                   mycluster-a1b2cdef345678g9hi012j3kl4567890-0000
    mycluster-a1b2cdef345678g9hi012j3kl4567890-0001.us-south.containers.appdomain.cloud     ["5678efgh-us-south.lb.appdomain.cloud"]      None             created                   mycluster-a1b2cdef345678g9hi012j3kl4567890-0001
    mycluster-a1b2cdef345678g9hi012j3kl4567890-0002.us-south.containers.appdomain.cloud     ["9012ijkl-us-south.lb.appdomain.cloud"]      None             created                   mycluster-a1b2cdef345678g9hi012j3kl4567890-0002
    
  2. 在复制的子域中,将子域中的 000<n> 值更改为 000<n+1>。 例如,mycluster-a1b2cdef345678g9hi012j3kl4567890-0002.us-south.containers.appdomain.cloud 子域将更改为 mycluster-a1b2cdef345678g9hi012j3kl4567890-0003.us-south.containers.appdomain.cloudn+1 值指示您在此集群中创建的下一个连续子域。 您可以在后续步骤中注册此子域。 注册域时,将自动生成域的 TLS 私钥。 私钥名称遵循子域的截断格式,例如 mycluster-a1b2cdef345678g9hi012j3kl4567890-0003

步骤 3: 创建和配置公共 Ingress 控制器

在准备好域和 TLS 证书之后,必须创建公共 Ingress 控制器并使用域配置控制器。

  1. 为公共 Ingress 控制器创建配置文件。

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: public-ingress-controller
      namespace: openshift-ingress-operator
    spec:
      replicas: 2
      domain: <domain>
      endpointPublishingStrategy:
        loadBalancer:
          scope: External
        type: LoadBalancerService
    
  2. 在集群的 openshift-ingress-operator 项目中创建 IngressController 资源。 创建 IngressController, 会根据 IngressController 设置在 openshift-ingress 项目中自动创建和部署公共 Ingress 控制器。 此外,将创建 Ingress 控制器服务以公开 Ingress 控制器。

    oc create -f public-ingress-controller.yaml -n openshift-ingress-operator
    
  3. 运行 oc get 命令并在 router-public-ingress-controller 服务的 EXTERNAL IP 字段中查找 VPC 主机名。 在 VPC 集群中,服务的外部 IP 地址不是静态的,而是保留在 VPC 分配的主机名后面。

    oc get svc router-public-ingress-controller -n openshift-ingress
    

    示例输出

    NAME                                  TYPE           CLUSTER-IP       EXTERNAL-IP                             PORT(S)                      AGE
    router-public-ingress-controller     LoadBalancer   172.21.57.132    1234abcd-us-south.lb.appdomain.cloud    80/TCP,443/TCP,1940/TCP      3m
    
  4. 向先前选择的域注册服务的 VPC 主机名。

    • 定制域: 使用 DNS 提供者将 router-public-ingress-controller 服务的 VPC 主机名添加为映射到定制域的 CNAME。
    • IBM提供的域: 为 router-public-ingress-controller 服务的 VPC 主机名创建 DNS 条目。 运行以下命令时,将自动生成在 public-ingress-controller.yaml 文件中指定的子域,并向 router-public-ingress-controller 服务注册该子域。 将在指定应用程序运行位置的项目中自动生成域的 TLS 私钥。 私钥名称遵循子域的截断格式,例如 mycluster-a1b2cdef345678g9hi012j3kl4567890-0003
      ibmcloud oc nlb-dns create vpc-gen2 --cluster <cluster_name_or_ID> --lb-host <VPC_hostname> --secret-namespace <project>
      

步骤 4:创建 Ingress 资源

Ingress 资源定义了 Ingress 控制器用于将流量路由到应用程序服务的路由规则。

  1. 定义输入资源配置文件,使用IBM域或您自定义的域将传入网络流量路由到您先前创建的服务。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: myingressresource
    spec:
      tls:
      - hosts:
        - <subdomain>
        secretName: <custom_secret_name>
      rules:
      - host: <subdomain>
        http:
          paths:
          - path: /<app1_path>
            pathType: Prefix
            backend:
                service:
                  name: <app1_service>
                  port:
                    number: 80
          - path: /<app2_path>
            backend:
                service:
                  name: <app2_service>
                  port:
                    number: 80
    
    tls
    如果要使用 TLS,请在资源中包含此 TLS 部分。
    <domain> 替换为子域。 不要为主机使用 * 或将主机属性留空,以避免在创建 Ingress 时出现故障。
    <tls_secret_name> 替换为先前创建的私钥,该私钥包含定制域的 TLS 证书和密钥,或为 IBM提供的子域自动生成的 TLS 私钥。
    host
    <domain> 替换为子域。 如果您的集群有多个暴露应用程序的项目,则每个项目需要一个 Ingress 资源。 可以在每个资源中使用相同的子域,也可以在每个资源中使用不同的子域。 例如,如果使用通配符域,那么可以将通配符子域追加到域的开头,例如 subdomain1.custom_domain.net。 不要为主机使用 * 或将主机属性留空,以避免在创建 Ingress 时出现故障。
    path
    <app_path> 替换为应用程序正在侦听的路径。 该路径将附加到 IBM 提供的域或定制域,以创建应用程序的唯一路径。 在 Web 浏览器中输入此路径时,网络流量会路由到 Ingress 控制器。 入口控制器会查找相关服务,并将网络流量发送到该服务。 然后,服务会将流量转发到应用程序运行所在的 pod。 许多应用程序并不监听特定路径,而是使用根路径和特定端口。 在这种情况下,请将根路径定义为 "/,而不要为应用程序指定单独的路径。 例如,要使用 http://domain/,请输入 / 作为路径。 对于“http://domain/app1_path,输入”/app1_path 作为路径。
    pathType
    URL 路径匹配方法。 支持的值为 ImplementationSpecificExactPrefix。 有关每种路径类型的详细信息和示例,请参阅 社区 Kubernetes 文档
    name
    将“<app1_service> 和”<app2_service> 替换为您创建的用于公开应用程序的服务名称,以此类推。 如果您的应用程序由群集中不同项目的服务暴露,则只包含同一项目中的应用程序服务。 您必须为每个项目创建一个 Ingress 资源,因为每个项目都有您要公开的应用程序。
    port
    服务侦听的端口。 使用针对应用程序创建 Kubernetes 服务时定义的端口。
  2. 为集群创建 Ingress 资源。 确保资源部署到与资源中指定的应用程序服务相同的项目中。

    oc apply -f myingressresource.yaml -n <project>
    
  3. 验证 Ingress 资源是否已成功创建。 如果事件中的信息描述了资源配置中的错误,请修复资源文件中的值,并重新应用资源文件。

    oc describe ingress myingressresource
    

将在应用程序服务所在的项目中创建 Ingress 资源,并向 Ingress 控制器注册应用程序。

步骤 5:通过因特网访问应用程序

在 Web 浏览器中,输入要访问的应用程序服务的 URL。

https://<domain>/<app1_path>

如果公开了多个应用程序,请通过更改附加到该 URL 的路径来访问这些应用程序。

https://<domain>/<app2_path>

如果使用通配符域,请使用这些应用程序自己的子域来访问这些应用程序。

http://<subdomain1>.<domain>/<app1_path>
http://<subdomain2>.<domain>/<app1_path>

无法通过 Ingress 连接到应用程序? 请尝试 对 Ingress 进行故障诊断

公开公开集群外部的应用程序

通过将集群外的应用程序纳入公共 Ingress 负载均衡,让它们向公众开放。 IBM 提供的域或定制域上的入局公共请求会自动转发到外部应用程序。

开始之前,请确保您要纳入群集负载平衡的外部应用程序可以使用公共 IP 地址访问。

要向公众公开集群外部的应用程序,请执行以下步骤。

  1. 为 Ingress 控制器公开的应用程序定义 Kubernetes 服务配置文件。 此服务会将入局请求转发到您在后续步骤中创建的外部端点。

    apiVersion: v1
    kind: Service
    metadata:
      name: myexternalservice
    spec:
      ports:
       - protocol: TCP
         port: <app_port>
    
  2. 在集群中创建服务。

    oc apply -f myexternalservice.yaml
    
  3. 定义外部端点配置文件。 包括所有可用于访问外部应用程序的公共 IP 地址和端口。 请注意,端点的名称必须与您在上一步中创建的服务的名称相同,例如 myexternalservice

    kind: Endpoints
    apiVersion: v1
    metadata:
      name: myexternalservice
    subsets:
      - addresses:
          - ip: <external_IP1>
          - ip: <external_IP2>
        ports:
          - port: <external_port>
    
    name
    将 "<myexternalendpoint> 替换为之前创建的Kubernetes服务名称。
    ip
    将 "<external_IP> 替换为连接外部应用程序的公共 IP 地址。
    port
    将 "<external_port> 替换为外部应用程序监听的端口。
  4. 在群集中创建端点。

    oc apply -f myexternalendpoint.yaml
    
  5. 继续执行 仅使用私有云服务端点在 VPC 集群中公开应用程序使用公共云服务端点在集群中公开应用程序 中的第二步。