$ oc adm policy add-cluster-role-to-user cluster-admin username
OpenShift Container Platform提供了一些方法,用于与在集群中运行的服务进行集群外部的通信。此方法使用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
) 并以集群管理员身份登录。
通过运行oc new-project
命令创建一个新项目
$ oc new-project <project_name>
使用oc new-app
命令创建您的服务
$ oc new-app nodejs:12~https://github.com/sclorg/nodejs-ex.git
要验证服务是否已创建,请运行以下命令
$ 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。
登录到包含您要公开的服务的项目
$ oc project <project_name>
运行oc expose service
命令来公开路由
$ oc expose service nodejs-ex
route.route.openshift.io/nodejs-ex exposed
要验证服务是否已公开,您可以使用curl
等工具来检查服务是否可以从集群外部访问。
要查找路由的主机名,请输入以下命令
$ oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
nodejs-ex nodejs-ex-myproject.example.com nodejs-ex 8080-tcp None
要检查主机是否响应GET请求,请输入以下命令
curl
命令示例$ curl --head nodejs-ex-myproject.example.com
HTTP/1.1 200 OK
...
在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控制器finops-router
示例,其标签选择器spec.namespaceSelector.matchExpressions
的键值设置为finance
和ops
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:finance
、name:ops
和name:dev
,则该配置有效地将您的路由分布在两个Ingress控制器之间。不应处理控制台、身份验证和其他用途的OpenShift Container Platform路由。
在之前的场景中,分片成为分区的一个特例,没有重叠的子集。路由在路由器分片之间划分。
|
已配置的Ingress控制器devops-router
示例,其标签选择器spec.namespaceSelector.matchExpressions
的键值设置为dev
和ops
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:dev
和name:ops
的命名空间中的路由由两个不同的Ingress控制器服务。通过此配置,您拥有重叠的路由子集。
使用重叠的路由子集,您可以创建更复杂的路由规则。例如,您可以将更高优先级的流量转移到专用的finops-router
,同时将较低优先级的流量发送到devops-router
。
创建新的Ingress分片后,可能会有被您的新Ingress分片接收的路由,这些路由也被默认Ingress控制器接收。这是因为默认Ingress控制器没有选择器,默认情况下会接收所有路由。
您可以使用命名空间选择器或路由选择器来限制Ingress控制器服务具有特定标签的路由。以下过程使用命名空间选择器来限制默认Ingress控制器服务您新分片的finance
、ops
和dev
路由。这为Ingress分片增加了进一步的隔离。
您必须将所有OpenShift Container Platform的管理路由保留在同一个Ingress控制器上。因此,请避免向默认Ingress控制器添加额外的选择器来排除这些必要的路由。 |
您已安装OpenShift CLI(oc
)。
您已以项目管理员身份登录。
通过运行以下命令修改默认Ingress控制器
$ oc edit ingresscontroller -n openshift-ingress-operator default
编辑Ingress控制器以包含一个namespaceSelector
,该选择器将排除具有任何finance
、ops
和dev
标签的路由
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:finance
、name:ops
和name:dev
的命名空间。
集群管理员负责为项目中的每个路由器创建单独的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 控制器之间平衡传入流量负载以及将流量隔离到特定 Ingress 控制器时,Ingress 控制器分片非常有用。例如,公司 A 连接到一个 Ingress 控制器,而公司 B 连接到另一个。
编辑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 控制器域名不同。 |
应用 Ingress 控制器router-internal.yaml
文件
# oc apply -f router-internal.yaml
Ingress 控制器选择任何命名空间中具有标签type: sharded
的路由。
使用在router-internal.yaml
中配置的域名创建一个新的路由
$ oc expose svc <service-name> --hostname <route-name>.apps-sharded.basedomain.example.net
使用命名空间标签进行 Ingress 控制器分片意味着 Ingress 控制器将服务于命名空间选择器选择的任何命名空间中的任何路由。
当在多个 Ingress 控制器之间平衡传入流量负载以及将流量隔离到特定 Ingress 控制器时,Ingress 控制器分片非常有用。例如,公司 A 连接到一个 Ingress 控制器,而公司 B 连接到另一个。
编辑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 控制器域名不同。 |
应用 Ingress 控制器router-internal.yaml
文件
$ oc apply -f router-internal.yaml
Ingress 控制器选择命名空间选择器选择的任何命名空间中具有标签type: sharded
的路由。
使用在router-internal.yaml
中配置的域名创建一个新的路由
$ oc expose svc <service-name> --hostname <route-name>.apps-sharded.basedomain.example.net
路由允许您在 URL 上托管您的应用程序。在这种情况下,未设置主机名,路由使用子域名。当您指定子域名时,您会自动使用公开路由的 Ingress 控制器的域名。对于由多个 Ingress 控制器公开路由的情况,路由将在多个 URL 上托管。
以下步骤描述了如何使用hello-openshift
应用程序为例创建 Ingress 控制器分片的路由。
当在多个 Ingress 控制器之间平衡传入流量负载以及将流量隔离到特定 Ingress 控制器时,Ingress 控制器分片非常有用。例如,公司 A 连接到一个 Ingress 控制器,而公司 B 连接到另一个。
您已安装OpenShift CLI(oc
)。
您已以项目管理员身份登录。
您有一个 Web 应用程序,它公开一个端口和一个 HTTP 或 TLS 端点,用于监听该端口上的流量。
您已为分片配置了 Ingress 控制器。
通过运行以下命令创建一个名为hello-openshift
的项目
$ oc new-project hello-openshift
通过运行以下命令在项目中创建一个 Pod
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
通过运行以下命令创建一个名为hello-openshift
的服务
$ oc expose pod/hello-openshift
创建一个名为hello-openshift-route.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 字段时,必须将主机名留空。如果您同时指定host 和subdomain 字段,则路由将使用host 字段的值,并忽略subdomain 字段。 |
使用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 。 |