网络
配置和管理集群网络
摘要
第 1 章 了解网络
Kubernetes 可确保 pod 能够相互联网,并从内部网络为每个 pod 分配一个 IP 地址。这样可保证 pod 中所有容器的行为如同它们在同一主机上一样。为每个 pod 指定专属的 IP 地址,意味着在端口分配、联网、命名、服务发现、负载均衡、应用程序配置和迁移方面,可以像物理主机或虚拟机一样来对待 pod。
一些云平台提供侦听 169.254.169.254 IP 地址的元数据 API,它是 IPv4 169.254.0.0/16
CIDR 块中的 连接内部 IP 地址。
此 CIDR 块无法从 pod 网络访问。需要访问这些 IP 地址的 Pod 必须通过将 pod spec 中的 spec.hostnetwork
字段设置为 true
来获得主机网络访问。
如果允许 pod 主机网络访问,则将授予 pod 对底层网络基础架构的访问权限。
1.1. OpenShift Container Platform DNS
如果您运行多个服务,比如使用多个 pod 的前端和后端服务,则要为用户名和服务 IP 等创建环境变量,使前端 pod 可以跟后端服务通信。如果删除并重新创建服务,可以为该服务分配一个新的 IP 地址,而且需要重新创建前端 pod 来获取服务 IP 环境变量的更新值。另外,必须在任何前端 pod 之前创建后端服务,以确保正确生成服务 IP,并将它作为环境变量提供给前端 pod。
因此,OpenShift Container Platform 具有一个内置 DNS,以便服务 DNS 以及服务 IP/端口能够访问这些服务。
第 2 章 访问主机
了解如何创建堡垒主机来访问 OpenShift Container Platform 实例,以及使用安全 shell (SSH) 访问 master 节点。
2.1. 访问安装程序置备的基础架构集群中 Amazon Web Services 上的主机
OpenShift Container Platform 安装程序不会为任何置备 OpenShift Container Platform 集群的 Amazon Elastic Compute Cloud (Amazon EC2) 实例创建公共 IP 地址。为了可以 SSH 到 OpenShift Container Platform 主机,您必须按照以下步骤操作。
流程
-
创建一个安全组,允许 SSH 访问由
openshift-install
命令创建的虚拟私有云 (VPC) 。 - 在安装程序创建的某个公共子网中创建 Amazon EC2 实例。
将公共 IP 地址与您创建的 Amazon EC2 实例相关联。
与 OpenShift Container Platform 安装不同,您应该将您创建的 Amazon EC2 实例与 SSH 密钥对关联。这与您为这个实例选择的操作系统无关,因为它只是一个 SSH 堡垒将互联网桥接到 OpenShift Container Platform 集群的 VPC。它与您使用的 Amazon Machine Image (AMI) 相关。例如,在 Red Hat Enterprise Linux CoreOS 中,您可以像安装程序一样通过 Ignition 提供密钥。
一旦置备了 Amazon EC2 实例并可以 SSH 到它,您必须添加与 OpenShift Container Platform 安装关联的 SSH 密钥。这个密钥可以与堡垒实例的密钥不同,也可以相同。
注意直接通过 SSH 访问仅建议在灾难恢复时使用。当 Kubernetes API 正常工作时,应该使用特权 Pod。
-
运行
oc get nodes
,查看输出结果,然后选择一个 master 节点。主机名类似于ip-10-0-1-163.ec2.internal
。 从您手动部署到 Amazon EC2 的堡垒 SSH 主机中,SSH 部署到那个 master 主机。确定您使用了在安装过程中指定的相同的 SSH 密钥:
$ ssh -i <ssh-key-path> core@<master-hostname>
第 3 章 OpenShift Container Platform 中的 Cluster Network Operator
Cluster Network Operator(CNO)在 OpenShift Container Platform 集群上部署和管理集群网络组件,包括在安装过程中为集群选择的 Container Network Interface(CNI)默认网络供应商插件。
3.1. Cluster Network Operator
Cluster Network Operator 从 operator.openshift.io
API 组实现 network
API。Operator 通过使用守护进程集,部署 OpenShift SDN 默认 Container Network Interface(CNI)网络供应商插件,或部署您在集群安装过程中选择的默认网络供应商插件。
流程
Cluster Network Operator 在安装过程中被部署为一个 Kubernetes 部署
。
运行以下命令,以查看部署状态:
$ oc get -n openshift-network-operator deployment/network-operator
输出示例
NAME READY UP-TO-DATE AVAILABLE AGE network-operator 1/1 1 1 56m
运行以下命令,以查看 Cluster Network Operator 的状态:
$ oc get clusteroperator/network
输出示例
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE network 4.4.0 True False False 50m
以下字段提供有关 Operator 状态的信息:
AVAILABLE
、Progressing
和DEGRADED
。当 Cluster Network Operator 报告可用状态条件时,AVAILABLE
字段为True
。
3.2. 查看集群网络配置
每个 OpenShift Container Platform 新安装都有一个名为 cluster
的 network.config
对象。
流程
使用
oc describe
命令查看集群网络配置:$ oc describe network.config/cluster
输出示例
Name: cluster Namespace: Labels: <none> Annotations: <none> API Version: config.openshift.io/v1 Kind: Network Metadata: Self Link: /apis/config.openshift.io/v1/networks/cluster Spec: 1 Cluster Network: Cidr: 10.128.0.0/14 Host Prefix: 23 Network Type: OpenShiftSDN Service Network: 172.30.0.0/16 Status: 2 Cluster Network: Cidr: 10.128.0.0/14 Host Prefix: 23 Cluster Network MTU: 8951 Network Type: OpenShiftSDN Service Network: 172.30.0.0/16 Events: <none>
3.3. 查看 Cluster Network Operator 状态
您可以使用 oc describe
命令来检查状态并查看 Cluster Network Operator 的详情。
流程
运行以下命令,以查看 Cluster Network Operator 的状态:
$ oc describe clusteroperators/network
3.4. 查看 Cluster Network Operator 日志
您可以使用 oc logs
命令来查看 Cluster Network Operator 日志。
流程
运行以下命令,以查看 Cluster Network Operator 的日志:
$ oc logs --namespace=openshift-network-operator deployment/network-operator
Open Virtual Networking (OVN) Kubernetes 网络插件只是技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
如需 OVN 技术预览支持范围的更多信息,请参阅 https://access.redhat.com/articles/4380121。
3.5. Cluster Network Operator (CNO) 配置
集群网络的配置作为 Cluster Network Operator (CNO) 配置的一部分被指定,并存储在名为 cluster
的 CR 对象中。CR 指定 operator.openshift.io
API 组中的 Network
API 的参数。
您可以通过在 CNO CR 中设置 defaultNetwork
参数的值,为 OpenShift Container Platform 集群指定集群网络配置。以下 CR 显示了 CNO 的默认配置,并列出了您可以配置的参数和有效的参数值:
Cluster Network Operator CR
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: clusterNetwork: 1 - cidr: 10.128.0.0/14 hostPrefix: 23 serviceNetwork: 2 - 172.30.0.0/16 defaultNetwork: 3 ... kubeProxyConfig: 4 iptablesSyncPeriod: 30s 5 proxyArguments: iptables-min-sync-period: 6 - 0s
- 1
- 用于指定从哪些 IP 地址块分配 Pod IP 地址以及分配给每个节点的子网前缀长度的列表。
- 2
- 服务的 IP 地址块。OpenShift SDN Container Network Interface (CNI) 网络供应商只支持服务网络具有单个 IP 地址块。
- 3
- 为集群网络配置默认 CNI 供应商。
- 4
- 此对象的参数指定 Kubernetes 网络代理 (kube-proxy) 配置。如果您使用 OVN-Kubernetes 默认 CNI 网络供应商,则 kube-proxy 的配置不会起作用。
- 5
- 注意
由于 OpenShift Container Platform 4.3 及更高版本中引进了性能上的改进,现在不再需要调整
iptablesSyncPeriod
参数。 - 6
3.5.1. OpenShift SDN 网络供应商的配置参数
以下 YAML 对象描述了 OpenShift SDN 默认 Container Network Interface (CNI) 网络供应商的配置参数。
您只能在集群安装过程中更改默认 CNI 网络供应商的配置。
defaultNetwork: type: OpenShiftSDN 1 openshiftSDNConfig: 2 mode: NetworkPolicy 3 mtu: 1450 4 vxlanPort: 4789 5
3.5.2. OVN-Kubernetes 默认 CNI 网络供应商的配置参数
以下 YAML 对象描述了 OVN-Kubernetes 默认 CNI 网络供应商的配置参数。
您只能在集群安装过程中更改默认 CNI 网络供应商的配置。
defaultNetwork: type: OVNKubernetes 1 ovnKubernetesConfig: 2 mtu: 1400 3 genevePort: 6081 4
3.5.3. Cluster Network Operator 配置示例
下例中显示了 CNO 的一个完整 CR:
Cluster Network Operator 示例 CR
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: clusterNetwork: - cidr: 10.128.0.0/14 hostPrefix: 23 serviceNetwork: - 172.30.0.0/16 defaultNetwork: type: OpenShiftSDN openshiftSDNConfig: mode: NetworkPolicy mtu: 1450 vxlanPort: 4789 kubeProxyConfig: iptablesSyncPeriod: 30s proxyArguments: iptables-min-sync-period: - 0s
第 4 章 OpenShift Container Platform 中的 DNS Operator
DNS Operator 部署并管理 CoreDNS,以便为 Pod 提供名称解析服务,从而在 OpenShift 中启用基于 DNS 的 Kubernetes 服务发现。
4.1. DNS Operator
DNS Operator 从 operator.openshift.io
API 组实现 dns
API。Operator 使用守护进程集部署 CoreDNS,为守护进程集创建一个服务,并将 kubelet 配置为指示 pod 使用 CoreDNS 服务 IP 地址进行名称解析。
流程
在安装过程中使用 Deployment
对象部署 DNS Operator。
使用
oc get
命令查看部署状态:$ oc get -n openshift-dns-operator deployment/dns-operator
输出示例
NAME READY UP-TO-DATE AVAILABLE AGE dns-operator 1/1 1 1 23h
使用
oc get
命令来查看 DNS Operator 的状态:$ oc get clusteroperator/dns
输出示例
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE dns 4.1.0-0.11 True False False 92m
AVAILABLE
、PROGRESSING
和DEGRADED
提供了有关 Operator 状态的信息。当 CoreDNS 守护进程中至少有一个 pod 被设置为Available
状态时,AVAILABLE
为True
。
4.2. 查看默认 DNS
每个 OpenShift Container Platform 新安装都有一个名为 default
的 dns.operator
。
流程
使用
oc describe
命令来查看默认dns
:$ oc describe dns.operator/default
输出示例
Name: default Namespace: Labels: <none> Annotations: <none> API Version: operator.openshift.io/v1 Kind: DNS ... Status: Cluster Domain: cluster.local 1 Cluster IP: 172.30.0.10 2 ...
要查找集群的服务 CIDR,使用
oc get
命令:$ oc get networks.config/cluster -o jsonpath='{$.status.serviceNetwork}'
输出示例
[172.30.0.0/16]
4.3. 使用 DNS 转发
您可以针对一个区(zone),使用 DNS 转发来覆盖 etc/resolv.conf
中指定的转发配置,方法是指定这个区使用哪个名称解析服务器。
流程
修改名为
default
的 DNS Operator 对象:$ oc edit dns.operator/default
这允许 Operator 使用基于
Server
的额外服务器配置块来创建和更新名为dns-default
的 ConfigMap。如果没有服务器带有与查询匹配的区,则命名解析功能会返回到由/etc/resolv.conf
中指定的名称服务器。DNS 示例
apiVersion: operator.openshift.io/v1 kind: DNS metadata: name: default spec: servers: - name: foo-server 1 zones: 2 - foo.com forwardPlugin: upstreams: 3 - 1.1.1.1 - 2.2.2.2:5353 - name: bar-server zones: - bar.com - example.com forwardPlugin: upstreams: - 3.3.3.3 - 4.4.4.4:5454
注意如果
servers
未定义或无效,则 ConfigMap 只包括默认服务器。查看 ConfigMap:
$ oc get configmap/dns-default -n openshift-dns -o yaml
基于以上 DNS 示例的 DNS ConfigMap 示例
apiVersion: v1 data: Corefile: | foo.com:5353 { forward . 1.1.1.1 2.2.2.2:5353 } bar.com:5353 example.com:5353 { forward . 3.3.3.3 4.4.4.4:5454 1 } .:5353 { errors health kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure upstream fallthrough in-addr.arpa ip6.arpa } prometheus :9153 forward . /etc/resolv.conf { policy sequential } cache 30 reload } kind: ConfigMap metadata: labels: dns.operator.openshift.io/owning-dns: default name: dns-default namespace: openshift-dns
- 1
- 对
forwardPlugin
的更改会触发 CoreDNS 守护进程集的滚动更新。
其他资源
- 有关 DNS 转发的详情,请查看 CoreDNS 转发文档。
4.4. DNS Operator 状态
您可以使用 oc describe
命令来检查状态并查看 DNS Operator 的详情。
流程
查看 DNS Operator 的状态:
$ oc describe clusteroperators/dns
4.5. DNS Operator 日志
您可以使用 oc logs
命令来查看 DNS Operator 日志。
流程
查看 DNS Operator 的日志:
$ oc logs -n openshift-dns-operator deployment/dns-operator -c dns-operator
第 5 章 OpenShift Container Platform 中的 Ingress Operator
Ingress Operator 实现了 ingresscontroller
API,它是负责启用对 OpenShift Container Platform 集群服务的外部访问的组件。Operator 通过部署和管理一个或多个基于 HAProxy 的 Ingress Controller 来处理路由,从而达成这个目标。您可以通过指定 OpenShift Container Platform Route
和 Kubernetes Ingress
资源,来使用 Ingress Operator 路由流量。
5.1. Ingress 配置资产
安装程序在 config.openshift.io
API 组中生成带有 Ingress
资源的资产,cluster-ingress-02-config.yml
。
Ingress
资源的 YAML 定义
apiVersion: config.openshift.io/v1 kind: Ingress metadata: name: cluster spec: domain: apps.openshiftdemos.com
安装程序将这个资产保存在 manifests/
目录下的 cluster-ingress-02-config.yml
文件中。此 Ingress
资源定义 Ingress 的集群范围配置。此 Ingress 配置的用法如下所示:
- Ingress Operator 使用集群 Ingress 配置中的域,作为默认 Ingress Controller 的域。
-
OpenShift API 服务器 Operator 使用集群 Ingress 配置中的域,作为在为未指定显式主机的
Route
资源生成默认主机时使用的域。
5.2. Ingress 控制器配置参数
ingresscontrollers.operator.openshift.io
资源提供了以下配置参数。
参数 | 描述 |
---|---|
|
一个
如果为空,默认值为 |
|
|
|
如果没有设置,则默认值基于
|
|
secret 必须包含以下密钥和数据:*
如果没有设置,则自动生成和使用通配符证书。该证书对 Ingress Controller 的 内部证书(无论是生成的证书还是用户指定的证书)自动与 OpenShift Container Platform 内置的 OAuth 服务器集成。 |
|
|
|
|
|
如果没有设置,则使用默认值。 注意
nodePlacement: nodeSelector: matchLabels: beta.kubernetes.io/os: linux tolerations: - effect: NoSchedule operator: Exists |
|
如果没有设置,则默认值基于
当使用
Ingress 控制器的 TLS 的最低版本是 重要
HAProxy Ingress controller 镜像不支持 TLS
Ingress Operator 还会将 注意
加密器和配置的安全配置集的最小 TLS 版本反映在 |
|
|
所有参数都是可选的。
5.2.1. Ingress 控制器 TLS 配置集
tlsSecurityProfile
参数定义 TLS 安全配置集的 schema。Operator 使用这个对象将 TLS 安全设置应用到操作对象。
有四个 TLS 安全配置集类型:
-
Old
-
Intermediate
-
Modern
-
Custom
Old
、Intermediate
和 Modern
配置集基于推荐的配置。Custom
配置集可以用来指定独立 TLS 安全配置集参数。
Old
配置集配置示例
spec: tlsSecurityProfile: type: Old
Intermediate
配置集配置示例
spec: tlsSecurityProfile: type: Intermediate
Modern
配置集配置示例
spec: tlsSecurityProfile: type: Modern
Custom
配置集是一个用户定义的 TLS 安全配置集。
您需要小心使用 Custom
配置集,因为无效的配置可能会造成问题。
Custom
配置集示例
spec: tlsSecurityProfile: type: Custom custom: ciphers: - ECDHE-ECDSA-AES128-GCM-SHA256 - ECDHE-RSA-AES128-GCM-SHA256 minTLSVersion: VersionTLS11
5.2.2. Ingress 控制器端点发布策略
NodePortService
端点发布策略
NodePortService
端点发布策略使用 Kubernetes NodePort 服务发布 Ingress Controller。
在这个配置中,Ingress Controller 部署使用容器网络。创建了一个
NodePortService 来发布部署。特定的节点端口由 OpenShift Container Platform 动态分配; 但是,为了支持静态端口分配,您会保留对受管 NodePortService 的节点端口字段的更改
。
Ingress Operator 忽略对服务的 .spec.ports[].nodePort
字段的任何更新。
默认情况下,端口会自动分配,您可以访问集成的端口分配。但是,有时需要静态分配端口来与现有基础架构集成,这些基础架构可能无法根据动态端口进行重新配置。要实现与静态节点端口的集成,您可以直接更新受管服务资源。
如需有关 daemonset 的更多信息,请参阅关于 NodePort
的 Kubernetes 服务文档。
HostNetwork
端点发布策略
HostNetwork
端点发布策略会在部署 Ingress Controller 的节点端口上发布 Ingress Controller。
带有 HostNetwork
端点发布策略的 Ingress 控制器每个节点只能有一个 pod 副本。如果您想要 n 个副本,则必须至少使用可调度这些副本的 n 个节点。因为每个 Pod 副本都会通过调度的节点主机上的端口 80
和 443
进行请求,所以如果同一节点上的其他 pod 使用这些端口,则无法将副本调度到该节点。
5.3. 查看默认的 Ingress Controller
Ingress Operator 是 OpenShift Container Platform 的一个核心功能,开箱即用。
每个 OpenShift Container Platform 新安装都有一个名为 default 的 ingresscontroller
。它可以通过额外的 Ingress Controller 来补充。如果删除了默认的 ingresscontroller
,Ingress Operator 会在一分钟内自动重新创建。
流程
查看默认的 Ingress Controller:
$ oc describe --namespace=openshift-ingress-operator ingresscontroller/default
5.4. 查看 Ingress Operator 状态
您可以查看并检查 Ingress Operator 的状态。
流程
查看您的 Ingress Operator 状态:
$ oc describe clusteroperators/ingress
5.5. 查看 Ingress Controller 日志
您可以查看 Ingress Controller 日志。
流程
查看 Ingress Controller 日志:
$ oc logs --namespace=openshift-ingress-operator deployments/ingress-operator
5.6. 查看 Ingress Controller 状态
您可以查看特定 Ingress Controller 的状态。
流程
查看 Ingress Controller 的状态:
$ oc describe --namespace=openshift-ingress-operator ingresscontroller/<name>
5.7. 设置自定义默认证书
作为管理员,您可以通过创建 Secret 资源并编辑 IngressController
自定义资源 (CR),将 Ingress Controller 配置为使用自定义证书。
先决条件
- 您必须在 PEM 编码文件中有一个证书/密钥对,其中该证书由可信证书认证机构签名,或者由您在一个自定义 PKI 中配置的私有可信证书认证机构签名。
- 您的证书对 Ingress 域有效。
您必须有一个
IngressController
CR。您可以使用默认值:$ oc --namespace openshift-ingress-operator get ingresscontrollers
输出示例
NAME AGE default 10m
如果您有中间证书,则必须将其包含在包含自定义默认证书的 secret 的 tls.crt
文件中。指定证书时指定的顺序是相关的; 在任意服务器证书后列出您的中间证书。
流程
以下步骤假定自定义证书和密钥对位于当前工作目录下的 tls.crt
和 tls.key
文件中。替换 tls.crt
和 tls.key
的实际路径名。在创建 Secret 资源并在 IngressController CR 中引用它时,您也可以将 custom-certs-default
替换成另一名称。
此操作会导致使用滚动部署策略重新部署 Ingress Controller。
使用
tls.crt
和tls.key
文件,创建在openshift-ingress
命名空间中包含自定义证书的 Secret 资源。$ oc --namespace openshift-ingress create secret tls custom-certs-default --cert=tls.crt --key=tls.key
更新 IngressController CR,以引用新的证书 Secret:
$ oc patch --type=merge --namespace openshift-ingress-operator ingresscontrollers/default \ --patch '{"spec":{"defaultCertificate":{"name":"custom-certs-default"}}}'
验证更新是否已生效:
$ oc get --namespace openshift-ingress-operator ingresscontrollers/default \ --output jsonpath='{.spec.defaultCertificate}'
输出示例
map[name:custom-certs-default]
证书 Secret 名称应该与用来更新 CR 的值匹配。
修改了 IngressController CR 后,Ingress Operator 将更新 Ingress Controller 的部署以使用自定义证书。
5.8. 扩展 Ingress Controller
手动扩展 Ingress Controller 以满足路由性能或可用性要求,如提高吞吐量的要求。oc
命令用于扩展 IngressController
资源。以下流程提供了扩展默认 IngressController
的示例。
流程
查看默认
IngressController
的当前可用副本数:$ oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}'
输出示例
2
使用
oc patch
命令,将默认IngressController
扩展至所需的副本数。以下示例将默认IngressController
扩展至 3 个副本:$ oc patch -n openshift-ingress-operator ingresscontroller/default --patch '{"spec":{"replicas": 3}}' --type=merge
输出示例
ingresscontroller.operator.openshift.io/default patched
验证默认
IngressController
是否已扩展至您指定的副本数:$ oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}'
输出示例
3
扩展不是立刻就可以完成的操作,因为它需要时间来创建所需的副本数。
5.9. 通过路由标签(label)配置 Ingress Controller 分片
使用路由标签进行 Ingress Controller 分片,意味着 Ingress Controller 提供由路由选择器选择的任意命名空间中的所有路由。
在一组 Ingress Controller 之间平衡传入的流量负载时,以及在将流量隔离到特定 Ingress Controller 时,Ingress Controller 分片会很有用处。例如,A 公司的流量使用一个 Ingress Controller,B 公司的流量则使用另外一个 Ingress Controller。
流程
编辑
router-internal.yaml
文件:# cat router-internal.yaml apiVersion: v1 items: - apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: sharded namespace: openshift-ingress-operator spec: domain: <apps-sharded.basedomain.example.net> nodePlacement: nodeSelector: matchLabels: node-role.kubernetes.io/worker: "" routeSelector: matchLabels: type: sharded status: {} kind: List metadata: resourceVersion: "" selfLink: ""
应用 Ingress Controller
router-internal.yaml
文件:# oc apply -f router-internal.yaml
Ingress Controller 选择具有
type: sharded
标签的任意命名空间中的路由。
5.10. 使用命名空间标签配置 Ingress Controller 分片
使用命名空间标签进行 Ingress Controller 分片,意味着 Ingress Controller 提供由命名空间选择器选择的任意命名空间中的所有路由。
在一组 Ingress Controller 之间平衡传入的流量负载时,以及在将流量隔离到特定 Ingress Controller 时,Ingress Controller 分片会很有用处。例如,A 公司的流量使用一个 Ingress Controller,B 公司的流量则使用另外一个 Ingress Controller。
流程
编辑
router-internal.yaml
文件:# cat router-internal.yaml
输出示例
apiVersion: v1 items: - apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: sharded namespace: openshift-ingress-operator spec: domain: <apps-sharded.basedomain.example.net> nodePlacement: nodeSelector: matchLabels: node-role.kubernetes.io/worker: "" namespaceSelector: matchLabels: type: sharded status: {} kind: List metadata: resourceVersion: "" selfLink: ""
应用 Ingress Controller
router-internal.yaml
文件:# oc apply -f router-internal.yaml
Ingress Controller 选择由命名空间选择器选择的具有
type: sharded
标签的任意命名空间中的路由。
5.11. 配置 Ingress Controller 以使用内部负载均衡器
当在云平台上创建 Ingress Controller 时,Ingress Controller 默认由一个公共云负载均衡器发布。作为管理员,您可以创建一个使用内部云负载均衡器的 Ingress Controller。
如果云供应商是 Microsoft Azure,则必须至少有一个指向节点的公共负载均衡器。如果不这样做,所有节点都将丢失到互联网的出站连接。
如果要更改 IngressController
对象的 scope
,您必须删除并重新创建 IngressController
对象。您无法在创建自定义资源 (CR) 后更改 .spec.endpointPublishingStrategy.loadBalancer.scope
参数。
有关实现详情请查看 Kubernetes 服务文档 。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
在名为
<name>-ingress-controller.yaml
的文件中创建IngressController
自定义资源 (CR) ,如下例所示:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: namespace: openshift-ingress-operator name: <name> 1 spec: domain: <domain> 2 endpointPublishingStrategy: type: LoadBalancerService loadBalancer: scope: Internal 3
运行以下命令,创建上一步中定义的 Ingress Controller:
$ oc create -f <name>-ingress-controller.yaml 1
- 1
- 将
<name>
替换为IngressController
对象的名称。
可选:通过运行以下命令确认创建了 Ingress Controller:
$ oc --all-namespaces=true get ingresscontrollers
5.12. 将集群的默认 Ingress Controller 配置为内部
您可以通过删除并重新它来将默认
Ingress Controller 配置为内部。
如果云供应商是 Microsoft Azure,则必须至少有一个指向节点的公共负载均衡器。如果不这样做,所有节点都将丢失到互联网的出站连接。
如果要更改 IngressController
对象的 scope
,您必须删除并重新创建 IngressController
对象。您无法在创建自定义资源 (CR) 后更改 .spec.endpointPublishingStrategy.loadBalancer.scope
参数。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
通过删除并重新创建集群,将
默认
Ingress Controller 配置为内部。$ oc replace --force --wait --filename - <<EOF apiVersion: operator.openshift.io/v1 kind: IngressController metadata: namespace: openshift-ingress-operator name: default spec: endpointPublishingStrategy: type: LoadBalancerService loadBalancer: scope: Internal EOF
5.13. 配置路由准入策略
管理员和应用程序开发人员可在多个命名空间中运行具有相同域名的应用程序。这是针对多个团队开发的、在同一个主机名上公开的微服务的机构。
只有在命名空间间有信任的集群才会启用跨命名空间之间的声明,否则恶意用户可能会接管主机名。因此,默认的准入策略不允许在命名空间间声明主机名。
先决条件
- 必须具有集群管理员权限。
流程
使用以下命令编辑
ingresscontroller
资源变量的.spec.
routeAdmission 字段:$ oc -n openshift-ingress-operator patch ingresscontroller/default --patch '{"spec":{"routeAdmission":{"namespaceOwnership":"InterNamespaceAllowed"}}}' --type=merge
Ingress 控制器配置参数
spec: routeAdmission: namespaceOwnership: InterNamespaceAllowed ...
5.14. 其他资源
第 6 章 在裸机集群中使用流控制传输协议 (SCTP)
作为集群管理员,您可以使用集群中的流控制传输协议 (SCTP)。
6.1. 支持 OpenShift Container Platform 上的流控制传输协议 (SCTP)
作为集群管理员,您可以在集群中的主机上启用 SCTP。在 Red Hat Enterprise Linux CoreOS (RHCOS) 上,SCTP 模块被默认禁用。
SCTP 是基于信息的可靠协议,可在 IP 网络之上运行。
启用后,您可以使用 SCTP 作为带有 pod、服务和网络策略的协议。Service
对象必须通过将 type
参数设置为 ClusterIP
或 NodePort
值来定义。
6.1.1. 使用 SCTP 协议的示例配置
您可以通过将 pod 或服务对象中的 protocol
参数设置为 SCTP
来将 pod 或服务配置为使用 SCTP。
在以下示例中,pod 被配置为使用 SCTP:
apiVersion: v1 kind: Pod metadata: namespace: project1 name: example-pod spec: containers: - name: example-pod ... ports: - containerPort: 30100 name: sctpserver protocol: SCTP
在以下示例中,服务被配置为使用 SCTP:
apiVersion: v1 kind: Service metadata: namespace: project1 name: sctpserver spec: ... ports: - name: sctpserver protocol: SCTP port: 30100 targetPort: 30100 type: ClusterIP
在以下示例中,NetworkPolicy
对象配置为对来自具有特定标签的任何 pod 的端口 80
应用 SCTP 网络流量:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-sctp-on-http spec: podSelector: matchLabels: role: web ingress: - ports: - protocol: SCTP port: 80
6.2. 启用流控制传输协议 (SCTP)
作为集群管理员,您可以在集群中的 worker 节点上加载并启用列入黑名单的 SCTP 内核模块。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
角色的用户访问集群。
流程
创建名为
load-sctp-module.yaml
的文件,其包含以下 YAML 定义:apiVersion: machineconfiguration.openshift.io/v1 kind: MachineConfig metadata: labels: machineconfiguration.openshift.io/role: worker name: load-sctp-module spec: config: ignition: version: 2.2.0 storage: files: - contents: source: data:, verification: {} filesystem: root mode: 420 path: /etc/modprobe.d/sctp-blacklist.conf - contents: source: data:text/plain;charset=utf-8,sctp filesystem: root mode: 420 path: /etc/modules-load.d/sctp-load.conf
运行以下命令来创建
MachineConfig
对象:$ oc create -f load-sctp-module.yaml
可选: 要在 MachineConfig Operator 应用配置更改时监测节点的状态,请使用以下命令。当节点状态变为
Ready
时,则代表配置更新已被应用。$ oc get nodes
6.3. 验证流控制传输协议 (SCTP) 已启用
您可以通过创建一个 pod 以及侦听 SCTP 流量的应用程序,将其与服务关联,然后连接到公开的服务,来验证 SCTP 是否在集群中工作。
先决条件
-
从集群访问互联网来安装
nc
软件包。 -
安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
角色的用户访问集群。
流程
创建 pod 启动 SCTP 侦听程序:
创建名为
sctp-server.yaml
的文件,该文件使用以下 YAML 定义 pod:apiVersion: v1 kind: Pod metadata: name: sctpserver labels: app: sctpserver spec: containers: - name: sctpserver image: registry.access.redhat.com/ubi8/ubi command: ["/bin/sh", "-c"] args: ["dnf install -y nc && sleep inf"] ports: - containerPort: 30102 name: sctpserver protocol: SCTP
运行以下命令来创建 pod:
$ oc create -f sctp-server.yaml
为 SCTP 侦听程序 pod 创建服务。
创建名为
sctp-service.yaml
的文件,该文件使用以下 YAML 定义服务:apiVersion: v1 kind: Service metadata: name: sctpservice labels: app: sctpserver spec: type: NodePort selector: app: sctpserver ports: - name: sctpserver protocol: SCTP port: 30102 targetPort: 30102
要创建服务,请输入以下命令:
$ oc create -f sctp-service.yaml
为 SCTP 客户端创建 pod。
使用以下 YAML 创建名为
sctp-client.yaml
的文件:apiVersion: v1 kind: Pod metadata: name: sctpclient labels: app: sctpclient spec: containers: - name: sctpclient image: registry.access.redhat.com/ubi8/ubi command: ["/bin/sh", "-c"] args: ["dnf install -y nc && sleep inf"]
运行以下命令来创建
Pod
对象:$ oc apply -f sctp-client.yaml
在服务器中运行 SCTP 侦听程序。
要连接到服务器 pod,请输入以下命令:
$ oc rsh sctpserver
要启动 SCTP 侦听程序,请输入以下命令:
$ nc -l 30102 --sctp
连接到服务器上的 SCTP 侦听程序。
- 在终端程序里打开一个新的终端窗口或标签页。
获取
sctpservice
服务的 IP 地址。使用以下命令:$ oc get services sctpservice -o go-template='{{.spec.clusterIP}}{{"\n"}}'
要连接到客户端 pod,请输入以下命令:
$ oc rsh sctpclient
要启动 SCTP 客户端,请输入以下命令。将
<cluster_IP>
替换为sctpservice
服务的集群 IP 地址。# nc <cluster_IP> 30102 --sctp
第 7 章 网络策略
7.1. 关于网络策略
作为集群管理员,您可以定义网络策略以限制到集群中的 pod 的网络通讯。
7.1.1. 关于网络策略
在使用支持 Kubernetes 网络策略的 Kubernetes Container Network Interface(CNI)插件的集群中,网络隔离完全由 NetworkPolicy
对象控制。在 OpenShift Container Platform 4.4 中,OpenShift SDN 支持在默认的网络隔离模式中使用网络策略。
OpenShift Container Platform 中提供了 Kubernetes v1
网络策略功能,但出口策略类型和 IPBlock 除外。
网络策略不适用于主机网络命名空间。启用主机网络的 Pod 不受网络策略规则的影响。
默认情况下,项目中的所有 pod 都可被其他 pod 和网络端点访问。要在一个项目中隔离一个或多个 Pod,您可以在该项目中创建 NetworkPolicy
对象来指示允许的入站连接。项目管理员可以在自己的项目中创建和删除 NetworkPolicy
对象。
如果一个 pod 由一个或多个 NetworkPolicy
对象中的选择器匹配,那么该 pod 将只接受至少被其中一个 NetworkPolicy
对象所允许的连接。未被任何 NetworkPolicy
对象选择的 pod 可以完全访问。
以下示例 NetworkPolicy
对象演示了支持不同的情景:
拒绝所有流量:
要使项目默认为拒绝流量,请添加一个匹配所有 pod 但不接受任何流量的
NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default spec: podSelector: ingress: []
只允许 OpenShift Container Platform Ingress Controller 的连接:
要使项目只允许 OpenShift Container Platform Ingress Controller 的连接,请添加以下
NetworkPolicy
对象:apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress
如果 Ingress Controller 配置了
endpointPublishingStrategy: HostNetwork
,则 Ingress Controller pod 在主机网络中运行。在主机网络中运行时,来自 Ingress Controller 的网络流量会被分配netid:0
Virtual Network ID (VNID) 。与 Ingress Operator 关联的命名空间的netid
不同,因此allow-from-openshift-ingress
中的matchLabel
网络策略与default
Ingress Controller 的流量不匹配。因为default
命名空间被分配了netid:0
VNID,所以可以通过把default
命名空间标记(label)为network.openshift.io/policy-group: ingress
来允许来自于default
Ingress Controller 的网络流量。只接受项目中 pod 的连接:
要使 pod 接受同一项目中其他 pod 的连接,但拒绝其他项目中所有 pod 的连接,请添加以下
NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-same-namespace spec: podSelector: ingress: - from: - podSelector: {}
仅允许基于 pod 标签的 HTTP 和 HTTPS 流量:
要对带有特定标签(以下示例中的
role=frontend
)的 pod 仅启用 HTTP 和 HTTPS 访问,请添加类似如下的NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-http-and-https spec: podSelector: matchLabels: role: frontend ingress: - ports: - protocol: TCP port: 80 - protocol: TCP port: 443
使用命名空间和 pod 选择器接受连接:
要通过组合使用命名空间和 pod 选择器来匹配网络流量,您可以使用类似如下的
NetworkPolicy
对象:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-pod-and-namespace-both spec: podSelector: matchLabels: name: test-pods ingress: - from: - namespaceSelector: matchLabels: project: project_name podSelector: matchLabels: name: test-pods
NetworkPolicy
对象是可添加的;也就是说,您可以组合多个 NetworkPolicy
对象来满足复杂的网络要求。
例如,对于以上示例中定义的 NetworkPolicy
对象,您可以在同一个项目中定义 allow-same-namespace
和 allow-http-and-https
策略。因此,允许带有标签 role=frontend
的 pod 接受每一策略所允许的任何连接。即,任何端口上来自同一命名空间中的 pod 的连接,以及端口 80
和 443
上的来自任意命名空间中 pod 的连接。
7.1.2. 网络策略优化
使用一个网络策略来通过 pod 上的不同标签来在命名空间中将不同 pod 进行隔离。
有效使用网络策略规则的指南只适用于 OpenShift SDN 集群网络供应商。
将 NetworkPolicy
对象应用到单一命名空间中的大量 pod 时,效率较低。因为 Pod 标签不存在于 IP 地址一级,因此网络策略会为使用 podSelector
选择的每个 pod 之间生成单独的 Open vSwitch(OVS)流量规则 。
例如,在一个 NetworkPolicy
对象中,如果 spec podSelector
和 ingress podSelector
每个都匹配 200 个 pod,则会产生 40,000 (200*200) OVS 流规则。这可能会减慢节点的速度。
在设计您的网络策略时,请参考以下指南:
使用命名空间使其包含需要隔离的 pod 组,可以减少 OVS 流规则数量。
使用
namespaceSelector
或空podSelector
选择整个命名空间的NetworkPolicy
对象会只生成 一个与命名空间的 VXLAN 虚拟网络 ID(VNID)匹配的 OVS 流量规则。- 保留不需要在原始命名空间中隔离的 pod,并将需要隔离的 pod 移到一个或多个不同的命名空间中。
- 创建额外的目标跨命名空间网络策略,以允许来自不同隔离的 pod 的特定流量。
7.1.3. 后续步骤
7.1.4. 其他资源
7.2. 创建网络策略
作为集群管理员,您可以为命名空间创建网络策略。
7.2.1. 创建网络策略
要定义细致的规则描述集群中项目允许的 ingress 网络流量,您可以创建一个网络策略。
先决条件
-
集群使用支持
NetworkPolicy
对象的默认 CNI 网络供应商,如设置了mode: NetworkPolicy
的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。 -
已安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
权限的用户登陆到集群。
流程
创建策略规则:
-
创建一个
<policy-name>.yaml
文件,其中<policy-name>
描述策略规则。 在刚才创建的文件中,定义一个策略对象,如下例所示:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: <policy-name> 1 spec: podSelector: ingress: []
- 1
- 为策略对象指定一个名称。
-
创建一个
运行以下命令来创建策略对象:
$ oc create -f <policy-name>.yaml -n <project>
在以下示例中,在名为
project1
的项目中创建一个新的NetworkPolicy
对象:$ oc create -f default-deny.yaml -n project1
输出示例
networkpolicy "default-deny" created
7.2.2. 示例 NetworkPolicy 对象
下文解释了示例 NetworkPolicy 对象:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-27107 1 spec: podSelector: 2 matchLabels: app: mongodb ingress: - from: - podSelector: 3 matchLabels: app: app ports: 4 - protocol: TCP port: 27017
7.3. 查看网络策略
作为集群管理员,您可以查看命名空间的网络策略。
7.3.1. 查看网络策略
您可以列出集群中的网络策略。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
权限的用户登陆到集群。
流程
要查看集群中定义的
NetworkPolicy
对象,请运行以下命令:$ oc get networkpolicy
7.3.2. 示例 NetworkPolicy 对象
下文解释了示例 NetworkPolicy 对象:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-27107 1 spec: podSelector: 2 matchLabels: app: mongodb ingress: - from: - podSelector: 3 matchLabels: app: app ports: 4 - protocol: TCP port: 27017
7.4. 编辑网络策略
作为集群管理员,您可以编辑命名空间的现有网络策略。
7.4.1. 编辑网络策略
您可以编辑命名空间中的网络策略。
先决条件
-
集群使用支持
NetworkPolicy
对象的默认 CNI 网络供应商,如设置了mode: NetworkPolicy
的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。 -
已安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
权限的用户登陆到集群。
流程
可选:列出当前
NetworkPolicy 对象
。如果要列出特定命名空间中的策略对象,请输入以下命令。将
<namespace>
替换为一个项目的命名空间。$ oc get networkpolicy -n <namespace>
如果要列出整个集群的策略对象,请输入以下命令:
$ oc get networkpolicy --all-namespaces
编辑
NetworkPolicy
对象。如果您在文件中保存了网络策略定义,请编辑该文件并进行必要的更改,然后输入以下命令。将
<policy-file>
替换为包含对象定义的文件名称。$ oc apply -f <policy-file>.yaml
如果需要直接更新
NetworkPolicy
对象,可以输入以下命令。将<policy-name>
替换为NetworkPolicy
对象的名称,将<namespace>
替换为对象存在的项目的名称。$ oc edit <policy-name> -n <namespace>
确认
NetworkPolicy
对象已更新。将<namespace>
替换为对象存在的项目的名称。$ oc get networkpolicy -n <namespace> -o yaml
7.4.2. 示例 NetworkPolicy 对象
下文解释了示例 NetworkPolicy 对象:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-27107 1 spec: podSelector: 2 matchLabels: app: mongodb ingress: - from: - podSelector: 3 matchLabels: app: app ports: 4 - protocol: TCP port: 27017
7.4.3. 其他资源
7.5. 删除网络策略
作为集群管理员,您可以从命名空间中删除网络策略。
7.5.1. 删除网络策略
您可以删除网络策略。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
权限的用户登陆到集群。
流程
要删除
NetworkPolicy
对象,请输入以下命令。将<policy-name>
替换为项目名称。$ oc delete networkpolicy <policy-name>
7.6. 为新项目创建默认网络策略
作为集群管理员,您可以在创建新项目时修改新项目模板,使其自动包含网络策略。如果您还没有新项目的自定义模板,则需要首先创建一个。
7.6.1. 为新项目修改模板
作为集群管理员,您可以修改默认项目模板,以便使用自定义要求创建新项目。
创建自己的自定义项目模板:
流程
-
以具有
cluster-admin
特权的用户身份登录。 生成默认项目模板:
$ oc adm create-bootstrap-project-template -o yaml > template.yaml
-
使用文本编辑器,通过添加对象或修改现有对象来修改生成的
template.yaml
文件。 项目模板必须创建在
openshift-config
命名空间中。加载修改后的模板:$ oc create -f template.yaml -n openshift-config
使用 Web 控制台或 CLI 编辑项目配置资源。
使用 Web 控制台:
- 导航至 Administration → Cluster Settings 页面。
- 点击 Global Configuration,查看所有配置资源。
- 找到 Project 的条目,并点击 Edit YAML。
使用 CLI:
编辑
project.config.openshift.io/cluster
资源:$ oc edit project.config.openshift.io/cluster
更新
spec
部分,使其包含projectRequestTemplate
和name
参数,再设置您上传的项目模板的名称。默认名称为project-request
。带有自定义项目模板的项目配置资源
apiVersion: config.openshift.io/v1 kind: Project metadata: ... spec: projectRequestTemplate: name: <template_name>
- 保存更改后,创建一个新项目来验证是否成功应用了您的更改。
7.6.2. 在新项目模板中添加网络策略
作为集群管理员,您可以在新项目的默认模板中添加网络策略。OpenShift Container Platform 将自动创建项目中模板中指定的所有 NetworkPolicy
对象。
先决条件
-
集群使用支持
NetworkPolicy
对象的默认 CNI 网络供应商,如设置了mode: NetworkPolicy
的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。 -
已安装 OpenShift CLI(
oc
)。 -
您需要使用具有
cluster-admin
权限的用户登陆到集群。 - 您必须已为新项目创建了自定义的默认项目模板。
流程
运行以下命令来编辑新项目的默认模板:
$ oc edit template <project_template> -n openshift-config
将
<project_template>
替换为您为集群配置的缺省模板的名称。默认模板名称为project-request
。在模板中,将每个
NetworkPolicy
对象作为一个元素添加到objects
参数中。objects
参数可以是一个或多个对象的集合。在以下示例中,
objects
参数集合包括几个NetworkPolicy
对象:objects: - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-same-namespace spec: podSelector: ingress: - from: - podSelector: {} - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress ...
可选:通过运行以下命令创建一个新项目,来确认您的网络策略对象已被成功创建:
创建一个新项目
$ oc new-project <project> 1
- 1
- 将
<project>
替换为您要创建的项目的名称。
确认新项目模板中的网络策略对象存在于新项目中:
$ oc get networkpolicy NAME POD-SELECTOR AGE allow-from-openshift-ingress <none> 7s allow-from-same-namespace <none> 7s
7.7. 使用网络策略配置多租户模式
作为集群管理员,您可以配置网络策略以为多租户网络提供隔离功能。
7.7.1. 使用网络策略配置多租户隔离
您可以配置项目,使其与其他项目命名空间中的 pod 和服务分离。
先决条件
-
集群使用支持
NetworkPolicy
对象的默认 CNI 网络供应商,如设置了mode: NetworkPolicy
的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。 -
已安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
权限的用户登陆到集群。
流程
创建以下
NetworkPolicy
对象:名为
allow-from-openshift-ingress
的策略:$ cat << EOF| oc create -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress EOF
名为
allow-from-openshift-monitoring
的策略:$ cat << EOF| oc create -f - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-monitoring spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: monitoring podSelector: {} policyTypes: - Ingress EOF
名为
allow-same-namespace
的策略:$ cat << EOF| oc create -f - kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-same-namespace spec: podSelector: ingress: - from: - podSelector: {} EOF
如果
default
Ingress Controller 配置设置了spec.endpointPublishingStrategy: HostNetwork
值,您需要为default
OpenShift Container Platform 命名空间添加一个标记来允许 Ingress Controller 和项目间的网络流量:确定您的
default
Ingress Controller 是否使用了HostNetwork
端点发布策略:$ oc get --namespace openshift-ingress-operator ingresscontrollers/default \ --output jsonpath='{.status.endpointPublishingStrategy.type}'
如果上个命令报告了端点发布策略为
HostNetwork
,在default
命名空间中设置一个标记:$ oc label namespace default 'network.openshift.io/policy-group=ingress'
运行以下命令确认当前项目中存在
NetworkPolicy
对象:$ oc get networkpolicy <policy-name> -o yaml
在以下示例中会显示
allow-from-openshift-ingress
NetworkPolicy
对象:$ oc get -n project1 networkpolicy allow-from-openshift-ingress -o yaml
输出示例
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-from-openshift-ingress namespace: project1 spec: ingress: - from: - namespaceSelector: matchLabels: network.openshift.io/policy-group: ingress podSelector: {} policyTypes: - Ingress
7.7.2. 后续步骤
第 8 章 多网络
8.1. 了解多网络
在 Kubernetes 中,容器联网由实现了 Container Network Interface (CNI) 的网络插件负责。
OpenShift Container Platform 使用 Multus CNI 插件来实现对 CNI 插件的链接。在集群安装过程中,您要配置 default pod 网络。默认网络处理集群中的所有一般网络流量。您可以基于可用的 CNI 插件定义额外网络,并将一个或多个这种网络附加到 pod。您可以根据需要为集群定义多个额外网络。这可让您灵活地配置提供交换或路由等网络功能的 pod。
8.1.1. 额外网络使用场景
您可以在需要网络隔离的情况下使用额外网络,包括分离数据平面与控制平面。隔离网络流量对以下性能和安全性原因很有用:
- 性能
- 您可以在两个不同的平面上发送流量,以管理每个平面上流量的多少。
- 安全性
- 您可以将敏感的流量发送到专为安全考虑而管理的网络平面,也可隔离不能在租户或客户间共享的私密数据。
集群中的所有 pod 仍然使用集群范围的默认网络,以维持整个集群中的连通性。每个 pod 都有一个 eth0
接口,附加到集群范围的 pod 网络。您可以使用 oc exec -it <pod_name> -- ip a
命令来查看 pod 的接口。如果您添加使用 Multus CNI 的额外网络接口,则名称为 net1
、net2
、…、netN
。
要将额外网络接口附加到 pod,您必须创建配置来定义接口的附加方式。您可以使用 NetworkAttachmentDefinition
自定义资源(CR)来指定各个接口。各个 CR 中的 CNI 配置定义如何创建该接口。
8.1.2. OpenShift Container Platform 中的额外网络
OpenShift Container Platform 提供以下 CNI 插件,以便在集群中创建额外网络:
- bridge:创建基于网桥的额外网络可让同一主机中的 pod 相互通信,并与主机通信。
- host-device:创建 host-device 额外网络可让 Pod 访问主机系统上的物理以太网网络设备。
- macvlan:创建基于 macvlan 的额外网络可让主机上的 Pod 通过使用物理网络接口与其他主机和那些主机上的 Pod 通信。附加到基于 macvlan 的额外网络的每个 Pod 都会获得一个唯一的 MAC 地址。
- ipvlan:创建基于 ipvlan 的额外网络可让主机上的 Pod 与其他主机和那些主机上的 Pod 通信,这类似于基于 macvlan 的额外网络。与基于 macvlan 的额外网络不同,每个 pod 共享与父级物理网络接口相同的 MAC 地址。
- SR-IOV:创建基于 SR-IOV 的额外网络可让 Pod 附加到主机系统上支持 SR-IOV 的硬件的虚拟功能 (VF) 接口。
8.2. 将 pod 附加到额外网络
作为集群用户,您可以将 pod 附加到额外网络。
8.2.1. 将 pod 添加到额外网络
您可以将 pod 添加到额外网络。pod 继续通过默认网络发送与集群相关的普通网络流量。
创建 pod 时会附加额外网络。但是,如果 pod 已存在,您无法为其附加额外网络。
pod 必须与额外网络处于相同的命名空间。
先决条件
-
安装 OpenShift CLI(
oc
)。 - 登录到集群。
流程
为
Pod
对象添加注解。只能使用以下注解格式之一:要在没有自定义的情况下附加额外网络,请使用以下格式添加注解。将
<network>
替换为要与 pod 关联的额外网络的名称:metadata: annotations: k8s.v1.cni.cncf.io/networks: <network>[,<network>,...] 1
- 1
- 要指定多个额外网络,请使用逗号分隔各个网络。逗号之间不可包括空格。如果您多次指定同一额外网络,则该 pod 会将多个网络接口附加到该网络。
要通过自定义来附加额外网络,请添加具有以下格式的注解:
metadata: annotations: k8s.v1.cni.cncf.io/networks: |- [ { "name": "<network>", 1 "namespace": "<namespace>", 2 "default-route": ["<default-route>"] 3 } ]
运行以下命令来创建 pod。将
<name>
替换为 pod 的名称。$ oc create -f <name>.yaml
可选: 要确认
Pod
CR 中是否存在注解,请输入以下命令将<name>
替换为 pod 的名称。$ oc get pod <name> -o yaml
在以下示例中,
example-pod
pod 附加到net1
额外网络:$ oc get pod example-pod -o yaml apiVersion: v1 kind: Pod metadata: annotations: k8s.v1.cni.cncf.io/networks: macvlan-bridge k8s.v1.cni.cncf.io/networks-status: |- 1 [{ "name": "openshift-sdn", "interface": "eth0", "ips": [ "10.128.2.14" ], "default": true, "dns": {} },{ "name": "macvlan-bridge", "interface": "net1", "ips": [ "20.2.2.100" ], "mac": "22:2f:60:a5:f8:00", "dns": {} }] name: example-pod namespace: default spec: ... status: ...
- 1
k8s.v1.cni.cncf.io/networks-status
参数是对象的 JSON 数组。每个对象描述附加到 pod 的额外网络的状态。注解值保存为纯文本值。
8.2.1.1. 指定特定于 pod 的地址和路由选项
将 pod 附加到额外网络时,您可能需要在特定 pod 中指定有关该网络的其他属性。这可让您更改路由的某些方面,并指定静态 IP 地址和 MAC 地址。要达到此目的,您可以使用 JSON 格式的注解。
先决条件
- pod 必须与额外网络处于相同的命名空间。
-
安装 OpenShift 命令行界面(
oc
)。 - 您必须登录集群。
流程
要在指定地址和/或路由选项的同时将 pod 添加到额外网络,请完成以下步骤:
编辑
Pod
资源定义。如果要编辑现有Pod
资源,请运行以下命令在默认编辑器中编辑其定义。将<name>
替换为要编辑的Pod
资源的名称。$ oc edit pod <name>
在
Pod
资源定义中,将k8s.v1.cni.cncf.io/networks
参数添加到 podmetadata
映射中。k8s.v1.cni.cncf.io/networks
接受 JSON 字符串,该字符串除指定附加属性外,还引用NetworkAttachmentDefinition
自定义资源(CR)名称的对象。metadata: annotations: k8s.v1.cni.cncf.io/networks: '[<network>[,<network>,...]]' 1
- 1
- 将
<network>
替换为 JSON 对象,如下例所示。单引号是必需的。
在以下示例中,通过
default-route
参数,注解指定了哪个网络附加将使用默认路由。apiVersion: v1 kind: Pod metadata: name: example-pod annotations: k8s.v1.cni.cncf.io/networks: ' { "name": "net1" }, { "name": "net2", 1 "default-route": ["192.0.2.1"] 2 }' spec: containers: - name: example-pod command: ["/bin/bash", "-c", "sleep 2000000000000"] image: centos/tools
默认路由将导致任何没有在其它路由中指定的流量被路由到网关。
将 OpenShift Container Platform 的默认路由设置为默认网络接口以外的接口时,可能会导致应该是 pod 和 pod 间的网络流量被路由到其他接口。
要验证 pod 的路由属性,可使用 oc
命令在 pod 中执行 ip
命令。
$ oc exec -it <pod_name> -- ip route
您还可以引用 pod 的 k8s.v1.cni.cncf.io/networks-status
来查看哪个额外网络已经分配了默认路由,这可以通过 JSON 格式的对象列表中的 default-route
键实现。
要为 pod 设置静态 IP 地址或 MAC 地址,您可以使用 JSON 格式的注解。这要求您创建允许此功能的网络。这可以在 CNO 的 rawCNIConfig 中指定。
运行以下命令来编辑 CNO CR:
$ oc edit networks.operator.openshift.io cluster
以下 YAML 描述了 CNO 的配置参数:
Cluster Network Operator YAML 配置
name: <name> 1 namespace: <namespace> 2 rawCNIConfig: '{ 3 ... }' type: Raw
以下对象描述了使用 macvlan CNI 插件的静态 MAC 地址和 IP 地址的配置参数:
使用静态 IP 和 MAC 地址的 macvlan CNI 插件 JSON 配置对象
{ "cniVersion": "0.3.1", "plugins": [{ 1 "type": "macvlan", "capabilities": { "ips": true }, 2 "master": "eth0", 3 "mode": "bridge", "ipam": { "type": "static" } }, { "capabilities": { "mac": true }, 4 "type": "tuning" }] }
然后,以上网络附加可能会以 JSON 格式的注解引用,同时使用相关的键来指定将哪些静态 IP 和 MAC 地址分配给指定 pod。
使用以下内容编辑所需的 pod:
$ oc edit pod <name>
使用静态 IP 和 MAC 地址的 macvlan CNI 插件 JSON 配置对象
apiVersion: v1 kind: Pod metadata: name: example-pod annotations: k8s.v1.cni.cncf.io/networks: '[ { "name": "<name>", 1 "ips": [ "192.0.2.205/24" ], 2 "mac": "CA:FE:C0:FF:EE:00" 3 } ]'
静态 IP 地址和 MAC 地址不需要同时使用,您可以单独使用,也可以一起使用。
要验证一个带有额外网络的 pod 的 IP 地址和 MAC 属性,请使用 oc
命令在 pod 中执行 ip 命令。
$ oc exec -it <pod_name> -- ip a
8.3. 从额外网络中删除 pod
作为集群用户,您可以从额外网络中删除 pod。
8.3.1. 从额外网络中删除 pod
您只能通过删除 pod 来从额外网络中删除 pod。
先决条件
- 一个额外网络被附加到 pod。
-
安装 OpenShift CLI(
oc
)。 - 登录到集群。
流程
要删除 pod,输入以下命令:
$ oc delete pod <name> -n <namespace>
-
<name>
是 pod 的名称。 -
<namespace>
是包含 pod 的命名空间。
-
8.4. 配置桥接网络
作为集群管理员,您可以使用 bridge Container Network Interface (CNI) 插件为集群配置额外网络。配置之后,节点上的所有 Pod 都会连接到虚拟交换机。每个 pod 都会在额外网络上分配一个 IP 地址。
8.4.1. 使用 bridge CNI 插件创建额外网络附加
Cluster Network Operator (CNO) 管理额外网络定义。当您指定要创建的额外网络时,CNO 会自动创建 NetworkAttachmentDefinition
对象。
不要编辑 Cluster Network Operator 所管理的 NetworkAttachmentDefinition
对象。这样做可能会破坏额外网络上的网络流量。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
要为集群创建额外网络,请完成以下步骤:
运行以下命令来编辑 CNO CR:
$ oc edit networks.operator.openshift.io cluster
通过为要创建的额外网络添加配置来修改您要创建的 CR,如以下示例 CR 中所示。
以下 YAML 配置 bridge CNI 插件:
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: additionalNetworks: 1 - name: test-network-1 namespace: test-1 type: Raw rawCNIConfig: '{ "cniVersion": "0.3.1", "name": "test-network-1", "type": "bridge", "ipam": { "type": "static", "addresses": [ { "address": "191.168.1.23/24" } ] } }'
- 1
- 指定额外网络附加定义的配置。
- 保存您的更改,再退出文本编辑器以提交更改。
可选:通过运行以下命令确认 CNO 创建了
NetworkAttachmentDefinition
对象。CNO 创建 CR 之前可能会有延迟。$ oc get network-attachment-definitions -n <namespace>
输出示例
NAME AGE test-network-1 14m
8.4.1.1. 配置网桥
使用 bridge Container Network Interface (CNI) 插件的额外网络附加配置由以下两个部分提供:
- Cluster Network Operator (CNO) 配置
- CNI 插件配置
CNO 配置指定额外网络附加的名称,以及用于在其中创建网络附加的命名空间。该插件由 CNO 配置中 rawCNIConfig
参数指定的 JSON 对象进行配置。
以下 YAML 描述了 CNO 的配置参数:
Cluster Network Operator YAML 配置
name: <name> 1 namespace: <namespace> 2 rawCNIConfig: '{ 3 ... }' type: Raw
以下对象描述了 bridge CNI 插件的配置参数:
bridge CNI 插件 JSON 配置对象
{ "cniVersion": "0.3.1", "name": "<name>", 1 "type": "bridge", "bridge": "<bridge>", 2 "ipam": { 3 ... }, "ipMasq": false, 4 "isGateway": false, 5 "isDefaultGateway": false, 6 "forceAddress": false, 7 "hairpinMode": false, 8 "promiscMode": false, 9 "vlan": <vlan>, 10 "mtu": <mtu> 11 }
- 1
- 为您之前为 CNO 配置提供的
name
参数指定值。 - 2
- 指定要使用的虚拟网桥名称。如果主机上不存在网桥接口,则进行创建。默认值为
cni0
。 - 3
- 为 ipam CNI 插件指定配置对象。该插件为网络附加定义管理 IP 地址分配。
- 4
- 设置为
true
,从而为离开虚拟网络的流量启用 IP 伪装。所有流量的源 IP 地址都会改写为网桥 IP 地址。如果网桥没有 IP 地址,此设置无效。默认值为false
。 - 5
- 设置为
true
,从而为网桥分配 IP 地址。默认值为false
。 - 6
- 设置为
true
,从而将网桥配置为虚拟网络的默认网关。默认值为false
。如果isDefaultGateway
设置为true
,则isGateway
也会自动设置为true
。 - 7
- 设置为
true
,从而允许将之前分配的 IP 地址分配给虚拟网桥。设置为false
时,如果将来自于重叠子集的 IPv4 地址或者 IPv6 地址分配给虚拟网桥,则会发生错误。默认值为false
。 - 8
- 设置为
true
,从而允许虚拟网桥通过接收了以太网帧的虚拟端口将其重新发送回去。这个模式也被称为反射中继。默认值为false
。 - 9
- 设置为
true
,从而在网桥上启用混杂模式。默认值为false
。 - 10
- 以整数值形式指定虚拟 LAN (VLAN) 标签。默认情况下不分配 VLAN 标签。
- 11
- 将最大传输单位 (MTU) 设置为指定的值。默认值由内核自动设置。
8.4.1.1.1. 网桥配置示例
以下示例配置了名为 bridge-net
的额外网络:
name: bridge-net
namespace: work-network
type: Raw
rawCNIConfig: '{ 1
"cniVersion": "0.3.1",
"name": "work-network",
"type": "bridge",
"isGateway": true,
"vlan": 2,
"ipam": {
"type": "dhcp"
}
}'
- 1
- 以 YAML 字符串形式指定 CNI 配置对象。
8.4.1.2. 配置 ipam CNI 插件
ipam Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址管理 (IPAM)。您可以配置 ipam 以进行静态 IP 地址分配或使用 DHCP 进行动态 IP 地址分配。您指定的 DHCP 服务器必须可从额外网络访问。
以下 JSON 配置对象描述了您可以设置的参数。
8.4.1.2.1. 静态 IP 地址分配配置
以下 JSON 描述了静态 IP 地址分配的配置:
静态分配配置
{ "ipam": { "type": "static", "addresses": [ 1 { "address": "<address>", 2 "gateway": "<gateway>" 3 } ], "routes": [ 4 { "dst": "<dst>", 5 "gw": "<gw>" 6 } ], "dns": { 7 "nameservers": ["<nameserver>"], 8 "domain": "<domain>", 9 "search": ["<search_domain>"] 10 } } }
- 1
- 定义分配给虚拟接口的 IP 地址的数组。支持 IPv4 和 IPv6 IP 地址。
- 2
- 您指定的 IP 地址和网络前缀。例如:如果您指定
10.10.21.10/24
,那么会为额外网络分配 IP 地址10.10.21.10
,网掩码为255.255.255.0
。 - 3
- 出口网络流量要路由到的默认网关。
- 4
- 描述要在 pod 中配置的路由的数组。
- 5
- CIDR 格式的 IP 地址范围,如
192.168.17.0/24
,或默认路由0.0.0.0/0
。 - 6
- 网络流量路由的网关。
- 7
- 可选: DNS 配置。
- 8
- 用来发送 DNS 查询的一个或多个 IP 地址的数组。
- 9
- 附加到主机名的默认域。例如,如果将域设置为
example.com
,对example-host
的 DNS 查找查询将被改写为example-host.example.com
。 - 10
- 在 DNS 查找查询过程中,附加到非限定主机名(如
example-host
)的域名的数组。
8.4.1.2.2. 动态 IP 地址分配配置
以下 JSON 描述了使用 DHCP 进行动态 IP 地址地址分配的配置:
pod 在创建时获取其原始 DHCP 租期。该租期必须由集群中运行的一个小型的 DHCP 服务器部署定期续订。
要触发 DHCP 服务器的部署,您必须编辑 Cluster Network Operator 配置来创建 shim 网络附加,如下例所示:
shim 网络附加定义示例
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: ... additionalNetworks: - name: dhcp-shim namespace: default rawCNIConfig: |- { "name": "dhcp-shim", "cniVersion": "0.3.1", "type": "bridge", "master": "ens5", "ipam": { "type": "dhcp" } }
DHCP 分配配置
{ "ipam": { "type": "dhcp" } }
8.4.1.2.3. 静态 IP 地址分配配置示例
您可以配置 ipam 以进行静态 IP 地址分配:
{ "ipam": { "type": "static", "addresses": [ { "address": "191.168.1.7" } ] } }
8.4.1.2.4. 使用 DHCP 的动态 IP 地址分配配置示例
您可以配置 ipam 以使用 DHCP:
{ "ipam": { "type": "dhcp" } }
8.4.2. 后续步骤
8.5. 配置 macvlan 网络
作为集群管理员,您可以使用 macvlan CNI 插件为集群配置额外网络。将 pod 附加到网络时,插件会从主机上的父接口创建一个子接口。为每个子设备生成一个唯一的硬件 MAC 地址。
此插件为子接口生成的这种唯一 MAC 地址可能与您的云供应商的安全策略不兼容。
8.5.1. 使用 macvlan CNI 插件创建额外网络附加
Cluster Network Operator (CNO) 管理额外网络定义。当您指定要创建的额外网络时,CNO 会自动创建 NetworkAttachmentDefinition
对象。
不要编辑 Cluster Network Operator 所管理的 NetworkAttachmentDefinition
对象。这样做可能会破坏额外网络上的网络流量。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
要为集群创建额外网络,请完成以下步骤:
运行以下命令来编辑 CNO CR:
$ oc edit networks.operator.openshift.io cluster
通过为要创建的额外网络添加配置来修改您要创建的 CR,如以下示例 CR 中所示。
以下 YAML 配置 macvlan CNI 插件:
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: additionalNetworks: 1 - name: test-network-1 namespace: test-1 type: SimpleMacvlan simpleMacvlanConfig: ipamConfig: type: static staticIPAMConfig: addresses: - address: 10.1.1.7/24
- 1
- 指定额外网络附加定义的配置。
- 保存您的更改,再退出文本编辑器以提交更改。
可选:通过运行以下命令确认 CNO 创建了
NetworkAttachmentDefinition
对象。CNO 创建 CR 之前可能会有延迟。$ oc get network-attachment-definitions -n <namespace>
输出示例
NAME AGE test-network-1 14m
8.5.1.1. 配置 macvlan CNI 插件
以下 YAML 描述了 macvlan Container Network Interface (CNI) 插件的配置参数:
macvlan YAML 配置
name: <name> 1 namespace: <namespace> 2 type: SimpleMacvlan simpleMacvlanConfig: master: <master> 3 mode: <mode> 4 mtu: <mtu> 5 ipamConfig: 6 ...
8.5.1.1.1. macvlan 配置示例
以下示例配置了名为 macvlan-net
的额外网络:
name: macvlan-net namespace: work-network type: SimpleMacvlan simpleMacvlanConfig: ipamConfig: type: DHCP
8.5.1.2. 配置 ipam CNI 插件
ipam Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址管理 (IPAM)。您可以配置 ipam 以进行静态 IP 地址分配或使用 DHCP 进行动态 IP 地址分配。您指定的 DHCP 服务器必须可从额外网络访问。
以下 YAML 配置描述了您可以设置的参数。
ipam CNI 插件 YAML 配置对象
ipamConfig: type: <type> 1 ... 2
8.5.1.2.1. 静态 ipam 配置 YAML
以下 YAML 描述了静态 IP 地址分配的配置:
静态 ipam 配置 YAML
ipamConfig: type: static staticIPAMConfig: addresses: 1 - address: <address> 2 gateway: <gateway> 3 routes: 4 - destination: <destination> 5 gateway: <gateway> 6 dns: 7 nameservers: 8 - <nameserver> domain: <domain> 9 search: 10 - <search_domain>
- 1
- 定义分配给虚拟接口的 IP 地址的一系列映射。支持 IPv4 和 IPv6 IP 地址。
- 2
- 您指定的 IP 地址和网络前缀。例如:如果您指定
10.10.21.10/24
,那么会为额外网络分配 IP 地址10.10.21.10
,网掩码为255.255.255.0
。 - 3
- 出口网络流量要路由到的默认网关。
- 4
- 描述要在 pod 中配置的路由的一系列映射。
- 5
- CIDR 格式的 IP 地址范围,如
192.168.17.0/24
,或默认路由0.0.0.0/0
。 - 6
- 网络流量路由的网关。
- 7
- 可选:DNS 配置。
- 8
- 用于发送 DNS 查询的一个或多个 IP 地址的集合。
- 9
- 附加到主机名的默认域。例如,如果将域设置为
example.com
,对example-host
的 DNS 查找查询将被改写为example-host.example.com
。 - 10
- 在 DNS 查找查询过程中,附加到非限定主机名(如
example-host
)的域名的数组。
8.5.1.2.2. 动态 ipam 配置 YAML
以下 YAML 描述了静态 IP 地址分配的配置:
动态 ipam 配置 YAML
ipamConfig: type: DHCP
8.5.1.2.3. 静态 IP 地址分配配置示例
以下示例显示了静态 IP 地址的 ipam 配置:
ipamConfig: type: static staticIPAMConfig: addresses: - address: 10.51.100.11 gateway: 10.51.100.10 routes: - destination: 0.0.0.0/0 gateway: 10.51.100.1 dns: nameservers: - 10.51.100.1 - 10.51.100.2 domain: testDNS.example search: - testdomain1.example - testdomain2.example
8.5.1.2.4. 动态 IP 地址分配配置示例
以下示例显示了 DHCP 的 ipam 配置:
ipamConfig: type: DHCP
8.5.2. 后续步骤
8.6. 配置 ipvlan 网络
作为集群管理员,您可以使用 ipvlan Container Network Interface (CNI) 插件为集群配置额外网络。此插件创建的虚拟网络与您指定的物理接口关联。
8.6.1. 使用 ipvlan CNI 插件创建额外网络附加
Cluster Network Operator (CNO) 管理额外网络定义。当您指定要创建的额外网络时,CNO 会自动创建 NetworkAttachmentDefinition
对象。
不要编辑 Cluster Network Operator 所管理的 NetworkAttachmentDefinition
对象。这样做可能会破坏额外网络上的网络流量。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
要为集群创建额外网络,请完成以下步骤:
运行以下命令来编辑 CNO CR:
$ oc edit networks.operator.openshift.io cluster
通过为要创建的额外网络添加配置来修改您要创建的 CR,如以下示例 CR 中所示。
以下 YAML 配置 ipvlan CNI 插件:
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: additionalNetworks: 1 - name: test-network-1 namespace: test-1 type: Raw rawCNIConfig: '{ "cniVersion": "0.3.1", "name": "test-network-1", "type": "ipvlan", "master": "eth1", "mode": "l2", "ipam": { "type": "static", "addresses": [ { "address": "191.168.1.23/24" } ] } }'
- 1
- 指定额外网络附加定义的配置。
- 保存您的更改,再退出文本编辑器以提交更改。
可选:通过运行以下命令确认 CNO 创建了
NetworkAttachmentDefinition
对象。CNO 创建 CR 之前可能会有延迟。$ oc get network-attachment-definitions -n <namespace>
输出示例
NAME AGE test-network-1 14m
8.6.1.1. 配置 ipvlan
使用 ipvlan Container Network Interface (CNI) 插件的额外网络附加配置由以下两个部分提供:
- Cluster Network Operator (CNO) 配置
- CNI 插件配置
CNO 配置指定额外网络附加的名称,以及用于在其中创建网络附加的命名空间。该插件由 CNO 配置中 rawCNIConfig
参数指定的 JSON 对象进行配置。
以下 YAML 描述了 CNO 的配置参数:
Cluster Network Operator YAML 配置
name: <name> 1 namespace: <namespace> 2 rawCNIConfig: '{ 3 ... }' type: Raw
以下对象描述了 ipvlan CNI 插件的配置参数:
ipvlan CNI 插件 JSON 配置对象
{ "cniVersion": "0.3.1", "name": "<name>", 1 "type": "ipvlan", "mode": "<mode>", 2 "master": "<master>", 3 "mtu": <mtu>, 4 "ipam": { 5 ... } }
8.6.1.1.1. ipvlan 配置示例
以下示例配置了名为 ipvlan -net
的额外网络:
name: ipvlan-net
namespace: work-network
type: Raw
rawCNIConfig: '{ 1
"cniVersion": "0.3.1",
"name": "work-network",
"type": "ipvlan",
"master": "eth1",
"mode": "l3",
"ipam": {
"type": "dhcp"
}
}'
- 1
- 以 YAML 字符串形式指定 CNI 配置对象。
8.6.1.2. 配置 ipam CNI 插件
ipam Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址管理 (IPAM)。您可以配置 ipam 以进行静态 IP 地址分配或使用 DHCP 进行动态 IP 地址分配。您指定的 DHCP 服务器必须可从额外网络访问。
以下 JSON 配置对象描述了您可以设置的参数。
8.6.1.2.1. 静态 IP 地址分配配置
以下 JSON 描述了静态 IP 地址分配的配置:
静态分配配置
{ "ipam": { "type": "static", "addresses": [ 1 { "address": "<address>", 2 "gateway": "<gateway>" 3 } ], "routes": [ 4 { "dst": "<dst>", 5 "gw": "<gw>" 6 } ], "dns": { 7 "nameservers": ["<nameserver>"], 8 "domain": "<domain>", 9 "search": ["<search_domain>"] 10 } } }
- 1
- 定义分配给虚拟接口的 IP 地址的数组。支持 IPv4 和 IPv6 IP 地址。
- 2
- 您指定的 IP 地址和网络前缀。例如:如果您指定
10.10.21.10/24
,那么会为额外网络分配 IP 地址10.10.21.10
,网掩码为255.255.255.0
。 - 3
- 出口网络流量要路由到的默认网关。
- 4
- 描述要在 pod 中配置的路由的数组。
- 5
- CIDR 格式的 IP 地址范围,如
192.168.17.0/24
,或默认路由0.0.0.0/0
。 - 6
- 网络流量路由的网关。
- 7
- 可选: DNS 配置。
- 8
- 用来发送 DNS 查询的一个或多个 IP 地址的数组。
- 9
- 附加到主机名的默认域。例如,如果将域设置为
example.com
,对example-host
的 DNS 查找查询将被改写为example-host.example.com
。 - 10
- 在 DNS 查找查询过程中,附加到非限定主机名(如
example-host
)的域名的数组。
8.6.1.2.2. 动态 IP 地址分配配置
以下 JSON 描述了使用 DHCP 进行动态 IP 地址地址分配的配置:
pod 在创建时获取其原始 DHCP 租期。该租期必须由集群中运行的一个小型的 DHCP 服务器部署定期续订。
要触发 DHCP 服务器的部署,您必须编辑 Cluster Network Operator 配置来创建 shim 网络附加,如下例所示:
shim 网络附加定义示例
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: ... additionalNetworks: - name: dhcp-shim namespace: default rawCNIConfig: |- { "name": "dhcp-shim", "cniVersion": "0.3.1", "type": "bridge", "master": "ens5", "ipam": { "type": "dhcp" } }
DHCP 分配配置
{ "ipam": { "type": "dhcp" } }
8.6.1.2.3. 静态 IP 地址分配配置示例
您可以配置 ipam 以进行静态 IP 地址分配:
{ "ipam": { "type": "static", "addresses": [ { "address": "191.168.1.7" } ] } }
8.6.1.2.4. 使用 DHCP 的动态 IP 地址分配配置示例
您可以配置 ipam 以使用 DHCP:
{ "ipam": { "type": "dhcp" } }
8.6.2. 后续步骤
8.7. 配置 host-device 网络
作为集群管理员,您可以使用 host-device Container Network Interface (CNI) 插件为集群配置额外网络。该插件允许您将指定网络设备从主机的网络命名空间移到 Pod 的网络命名空间。
8.7.1. 使用 host-device CNI 插件创建额外网络附加
Cluster Network Operator (CNO) 管理额外网络定义。当您指定要创建的额外网络时,CNO 会自动创建 NetworkAttachmentDefinition
对象。
不要编辑 Cluster Network Operator 所管理的 NetworkAttachmentDefinition
对象。这样做可能会破坏额外网络上的网络流量。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
要为集群创建额外网络,请完成以下步骤:
运行以下命令来编辑 CNO CR:
$ oc edit networks.operator.openshift.io cluster
通过为要创建的额外网络添加配置来修改您要创建的 CR,如以下示例 CR 中所示。
以下 YAML 配置 host-device CNI 插件:
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: additionalNetworks: 1 - name: test-network-1 namespace: test-1 type: Raw rawCNIConfig: '{ "cniVersion": "0.3.1", "name": "test-network-1", "type": "host-device", "device": "eth1" }'
- 1
- 指定额外网络附加定义的配置。
- 保存您的更改,再退出文本编辑器以提交更改。
可选:通过运行以下命令确认 CNO 创建了
NetworkAttachmentDefinition
对象。CNO 创建 CR 之前可能会有延迟。$ oc get network-attachment-definitions -n <namespace>
输出示例
NAME AGE test-network-1 14m
8.7.1.1. 配置 host-device
使用 host-device Container Network Interface (CNI) 插件的额外网络附加配置由以下两个部分提供:
- Cluster Network Operator (CNO) 配置
- CNI 插件配置
CNO 配置指定额外网络附加的名称,以及用于在其中创建网络附加的命名空间。该插件由 CNO 配置中 rawCNIConfig
参数指定的 JSON 对象进行配置。
以下 YAML 描述了 CNO 的配置参数:
Cluster Network Operator YAML 配置
name: <name> 1 namespace: <namespace> 2 rawCNIConfig: '{ 3 ... }' type: Raw
仅设置以下参数之一来指定您的网络设备:device
、HWaddr
、kernelpath
或 pciBusID
。
以下对象描述了 host-device CNI 插件的配置参数:
host-device CNI 插件 JSON 配置对象
{ "cniVersion": "0.3.1", "name": "<name>", 1 "type": "host-device", "device": "<device>", 2 "hwaddr": "<hwaddr>", 3 "kernelpath": "<kernelpath>", 4 "pciBusID": "<pciBusID>", 5 "ipam": { 6 ... } }
8.7.1.1.1. host-device 配置示例
以下示例配置了名为 hostdev-net
的额外网络:
name: hostdev-net
namespace: work-network
type: Raw
rawCNIConfig: '{ 1
"cniVersion": "0.3.1",
"name": "work-network",
"type": "host-device",
"device": "eth1"
}'
- 1
- 以 YAML 字符串形式指定 CNI 配置对象。
8.7.1.2. 配置 ipam CNI 插件
ipam Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址管理 (IPAM)。您可以配置 ipam 以进行静态 IP 地址分配或使用 DHCP 进行动态 IP 地址分配。您指定的 DHCP 服务器必须可从额外网络访问。
以下 JSON 配置对象描述了您可以设置的参数。
8.7.1.2.1. 静态 IP 地址分配配置
以下 JSON 描述了静态 IP 地址分配的配置:
静态分配配置
{ "ipam": { "type": "static", "addresses": [ 1 { "address": "<address>", 2 "gateway": "<gateway>" 3 } ], "routes": [ 4 { "dst": "<dst>", 5 "gw": "<gw>" 6 } ], "dns": { 7 "nameservers": ["<nameserver>"], 8 "domain": "<domain>", 9 "search": ["<search_domain>"] 10 } } }
- 1
- 定义分配给虚拟接口的 IP 地址的数组。支持 IPv4 和 IPv6 IP 地址。
- 2
- 您指定的 IP 地址和网络前缀。例如:如果您指定
10.10.21.10/24
,那么会为额外网络分配 IP 地址10.10.21.10
,网掩码为255.255.255.0
。 - 3
- 出口网络流量要路由到的默认网关。
- 4
- 描述要在 pod 中配置的路由的数组。
- 5
- CIDR 格式的 IP 地址范围,如
192.168.17.0/24
,或默认路由0.0.0.0/0
。 - 6
- 网络流量路由的网关。
- 7
- 可选: DNS 配置。
- 8
- 用来发送 DNS 查询的一个或多个 IP 地址的数组。
- 9
- 附加到主机名的默认域。例如,如果将域设置为
example.com
,对example-host
的 DNS 查找查询将被改写为example-host.example.com
。 - 10
- 在 DNS 查找查询过程中,附加到非限定主机名(如
example-host
)的域名的数组。
8.7.1.2.2. 动态 IP 地址分配配置
以下 JSON 描述了使用 DHCP 进行动态 IP 地址地址分配的配置:
pod 在创建时获取其原始 DHCP 租期。该租期必须由集群中运行的一个小型的 DHCP 服务器部署定期续订。
要触发 DHCP 服务器的部署,您必须编辑 Cluster Network Operator 配置来创建 shim 网络附加,如下例所示:
shim 网络附加定义示例
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: ... additionalNetworks: - name: dhcp-shim namespace: default rawCNIConfig: |- { "name": "dhcp-shim", "cniVersion": "0.3.1", "type": "bridge", "master": "ens5", "ipam": { "type": "dhcp" } }
DHCP 分配配置
{ "ipam": { "type": "dhcp" } }
8.7.1.2.3. 静态 IP 地址分配配置示例
您可以配置 ipam 以进行静态 IP 地址分配:
{ "ipam": { "type": "static", "addresses": [ { "address": "191.168.1.7" } ] } }
8.7.1.2.4. 使用 DHCP 的动态 IP 地址分配配置示例
您可以配置 ipam 以使用 DHCP:
{ "ipam": { "type": "dhcp" } }
8.7.2. 后续步骤
8.8. 编辑额外网络
作为集群管理员,您可以修改现有额外网络的配置。
8.8.1. 修改额外网络附加定义
作为集群管理员,您可以对现有额外网络进行更改。任何附加到额外网络的现有 pod 都不会被更新。
先决条件
- 已为集群配置了额外网络。
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
要为集群编辑额外网络,请完成以下步骤:
运行以下命令,在默认文本编辑器中编辑 Cluster Network Operator (CNO) CR:
$ oc edit networks.operator.openshift.io cluster
-
在
additionalNetworks
集合中,用您的更改更新额外网络。 - 保存您的更改,再退出文本编辑器以提交更改。
可选:运行以下命令确认 CNO 更新了
NetworkAttachmentDefinition
对象。将<network-name>
替换为要显示的额外网络名称。CNO 根据您的更改更新NetworkAttachmentDefinition
对象前可能会有延迟。$ oc get network-attachment-definitions <network-name> -o yaml
例如,以下控制台输出显示名为
net1
的NetworkAttachmentDefinition
对象:$ oc get network-attachment-definitions net1 -o go-template='{{printf "%s\n" .spec.config}}' { "cniVersion": "0.3.1", "type": "macvlan", "master": "ens5", "mode": "bridge", "ipam": {"type":"static","routes":[{"dst":"0.0.0.0/0","gw":"10.128.2.1"}],"addresses":[{"address":"10.128.2.100/23","gateway":"10.128.2.1"}],"dns":{"nameservers":["172.30.0.10"],"domain":"us-west-2.compute.internal","search":["us-west-2.compute.internal"]}} }
8.9. 删除额外网络
作为集群管理员,您可以删除额外网络附加。
8.9.1. 删除额外网络附加定义
作为集群管理员,您可以从 OpenShift Container Platform 集群中删除额外网络。额外网络不会从它所附加的任何 pod 中删除。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
要从集群中删除额外网络,请完成以下步骤:
运行以下命令,在默认文本编辑器中编辑 Cluster Network Operator (CNO):
$ oc edit networks.operator.openshift.io cluster
从您要删除的网络附加定义的
additionalNetworks
集合中删除配置,以此修改 CR。apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: additionalNetworks: [] 1
- 1
- 如果要删除
additionalNetworks
集合中唯一额外网络附加定义的配置映射,您必须指定一个空集合。
- 保存您的更改,再退出文本编辑器以提交更改。
可选:通过运行以下命令确认删除了额外网络 CR:
$ oc get network-attachment-definition --all-namespaces
8.10. 配置 PTP
精确时钟协议 (PTP) 硬件只是技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的详情,请参阅 https://access.redhat.com/support/offerings/techpreview/。
8.10.1. 关于 PTP 硬件
OpenShift Container Platform 包含在节点上使用 PTP 硬件的能力。您可以使用 PTP 硬件在节点上配置 linuxptp 服务。
PTP Operator 可以与在裸机基础架构上置备的集群中的带有 PTP 功能的设备一同工作。
您可以通过部署 PTP Operator,使用 OpenShift Container Platform 控制台来安装 PTP。PTP Operator 会创建和管理 linuxptp 服务。Operator 提供以下功能:
- 在集群中发现具有 PTP 功能的设备。
- 管理 linuxptp 服务的配置。
8.10.2. 安装 PTP Operator
作为集群管理员,您可以使用 OpenShift Container Platform CLI 或 Web 控制台来安装 PTP Operator。
8.10.2.1. CLI:安装 PTP Operator
作为集群管理员,您可以使用 CLI 安装 Operator。
先决条件
- 在裸机中安装有支持 PTP 硬件的节点的集群。
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
要为 PTP Operator 创建命名空间,输入以下命令:
$ cat << EOF| oc create -f - apiVersion: v1 kind: Namespace metadata: name: openshift-ptp labels: openshift.io/run-level: "1"
要为 Operator 创建 Operator 组,输入以下命令:
$ cat << EOF| oc create -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: ptp-operators namespace: openshift-ptp spec: targetNamespaces: - openshift-ptp EOF
订阅 PTP Operator。
运行以下命令,将 OpenShift Container Platform 主版本和次版本设置为环境变量,该变量在下一步中作为
channel
的值。$ OC_VERSION=$(oc version -o yaml | grep openshiftVersion | \ grep -o '[0-9]*[.][0-9]*' | head -1)
要为 PTP Operator 创建订阅,输入以下命令:
$ cat << EOF| oc create -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: ptp-operator-subscription namespace: openshift-ptp spec: channel: "${OC_VERSION}" name: ptp-operator source: redhat-operators sourceNamespace: openshift-marketplace EOF
要验证是否已安装 Operator,请输入以下命令:
$ oc get csv -n openshift-ptp \ -o custom-columns=Name:.metadata.name,Phase:.status.phase
输出示例
Name Phase ptp-operator.4.4.0-202006160135 Succeeded
8.10.2.2. Web 控制台:安装 PTP Operator
作为集群管理员,您可以使用 Web 控制台安装 Operator。
如上一节所述,您必须创建命名空间和 operator 组。
流程
使用 OpenShift Container Platform Web 控制台安装 PTP Operator:
- 在 OpenShift Container Platform Web 控制台中,点击 Operators → OperatorHub。
- 从可用的 Operator 列表中选择 PTP Operator,然后点 Install。
- 在 Create Operator Subscription 页面中,在 A specific namespace on the cluster 下选择 openshift-ptp。然后,点击 Subscribe。
可选:验证是否成功安装了 PTP Operator:
- 切换到 Operators → Installed Operators 页面。
确保 openshift-ptp 项目中列出的 PTP Operator 的 Status 为 InstallSucceeded。
注意在安装过程中,Operator 可能会显示 Failed 状态。如果安装过程结束后有 InstallSucceeded 信息,您可以忽略这个 Failed 信息。
如果 Operator 没有被成功安装,请按照以下步骤进行故障排除:
- 进入 Operators → Installed Operators 页面,检查 Operator Subscriptions 和 Install Plans 选项卡中的 Status 项中是否有任何错误。
-
进入 Workloads → Pods 页面,检查
openshift-ptp
项目中 pod 的日志。
8.10.3. 自动发现 PTP 网络设备
PTP Operator 将 NodePtpDevice.ptp.openshift.io
自定义资源定义(CRD)添加到 OpenShift Container Platform。PTP Operator 将搜索集群中每个节点上的具有 PTP 功能的网络设备。Operator 会为每个提供兼容 PTP 设备的节点创建和更新 NodePtpDevice
自定义资源(CR)对象。
为每个节点创建一个 CR,并共享与该节点相同的名称。.status.devices
列表提供有关节点上 PTP 设备的信息。
以下是由 PTP Operator 创建的 NodePtpDevice
CR 示例:
apiVersion: ptp.openshift.io/v1 kind: NodePtpDevice metadata: creationTimestamp: "2019-11-15T08:57:11Z" generation: 1 name: dev-worker-0 1 namespace: openshift-ptp 2 resourceVersion: "487462" selfLink: /apis/ptp.openshift.io/v1/namespaces/openshift-ptp/nodeptpdevices/dev-worker-0 uid: 08d133f7-aae2-403f-84ad-1fe624e5ab3f spec: {} status: devices: 3 - name: eno1 - name: eno2 - name: ens787f0 - name: ens787f1 - name: ens801f0 - name: ens801f1 - name: ens802f0 - name: ens802f1 - name: ens803
8.10.4. 配置 Linuxptp 服务
PTP Operator 将 PtpConfig.ptp.openshift.io
自定义资源定义 (CRD) 添加至 OpenShift Container Platform。您可以通过创建 PtpConfig
自定义资源(CR)对象来配置 Linuxptp 服务(ptp4l、phc2sys)。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。 - 已安装了 PTP Operator。
流程
创建以下
PtpConfig
CR,然后在<name>-ptp-config.yaml
文件中保存 YAML。使用配置的实际名称替换<name>
。apiVersion: ptp.openshift.io/v1 kind: PtpConfig metadata: name: <name> 1 namespace: openshift-ptp 2 spec: profile: 3 - name: "profile1" 4 interface: "ens787f1" 5 ptp4lOpts: "-s -2" 6 phc2sysOpts: "-a -r" 7 recommend: 8 - profile: "profile1" 9 priority: 10 10 match: 11 - nodeLabel: "node-role.kubernetes.io/worker" 12 nodeName: "dev-worker-0" 13
- 1
- 为
PtpConfig
CR 指定名称。 - 2
- 指定安装 PTP Operator 的命名空间。
- 3
- 指定包括一个或多个
profile
的数组。 - 4
- 指定用于唯一标识配置集(profile)对象的配置集对象名称。
- 5
- 指定
ptp4l
服务要使用的网络接口名称,如ens787f1
。 - 6
- 为
ptp4l
服务指定系统配置选项,如-s -2
。这不应该包含接口名称-i <interface>
和服务配置文件-f /etc/ptp4l.conf
,因为这些文件会被自动附加。 - 7
- 为
phc2sys
服务指定系统配置选项,如-a -r
。 - 8
- 指定包括一个或多个
recommend
对象的数组,该数组定义了如何将配置集
应用到节点的规则。 - 9
- 指定
profile
部分中定义的profile
对象名称。 - 10
- 使用
0
到99
之间的一个整数值指定priority
。大数值的优先级较低,因此优先级99
低于优先级10
。如果根据match
项中定义的规则,节点可以与多个配置集相匹配,具有最高优先级的配置集将被应用到那个节点。 - 11
- 使用
nodeLabel
或nodeName
指定match
规则。 - 12
- 使用节点对象中的
node.Labels
的key
指定nodeLabel
。 - 13
- 使用节点对象的
node.Name
指定nodeName
。
运行以下命令来创建 CR:
$ oc create -f <filename> 1
- 1
- 将
<filename>
替换为您在上一步中创建的文件的名称。
可选:检查
PtpConfig
配置集是否应用到与nodeLabel
或nodeName
匹配的节点。$ oc get pods -n openshift-ptp -o wide
输出示例
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES linuxptp-daemon-4xkbb 1/1 Running 0 43m 192.168.111.15 dev-worker-0 <none> <none> linuxptp-daemon-tdspf 1/1 Running 0 43m 192.168.111.11 dev-master-0 <none> <none> ptp-operator-657bbb64c8-2f8sj 1/1 Running 0 43m 10.128.0.116 dev-master-0 <none> <none> $ oc logs linuxptp-daemon-4xkbb -n openshift-ptp I1115 09:41:17.117596 4143292 daemon.go:107] in applyNodePTPProfile I1115 09:41:17.117604 4143292 daemon.go:109] updating NodePTPProfile to: I1115 09:41:17.117607 4143292 daemon.go:110] ------------------------------------ I1115 09:41:17.117612 4143292 daemon.go:102] Profile Name: profile1 1 I1115 09:41:17.117616 4143292 daemon.go:102] Interface: ens787f1 2 I1115 09:41:17.117620 4143292 daemon.go:102] Ptp4lOpts: -s -2 3 I1115 09:41:17.117623 4143292 daemon.go:102] Phc2sysOpts: -a -r 4 I1115 09:41:17.117626 4143292 daemon.go:116] ------------------------------------ I1115 09:41:18.117934 4143292 daemon.go:186] Starting phc2sys... I1115 09:41:18.117985 4143292 daemon.go:187] phc2sys cmd: &{Path:/usr/sbin/phc2sys Args:[/usr/sbin/phc2sys -a -r] Env:[] Dir: Stdin:<nil> Stdout:<nil> Stderr:<nil> ExtraFiles:[] SysProcAttr:<nil> Process:<nil> ProcessState:<nil> ctx:<nil> lookPathErr:<nil> finished:false childFiles:[] closeAfterStart:[] closeAfterWait:[] goroutine:[] errch:<nil> waitDone:<nil>} I1115 09:41:19.118175 4143292 daemon.go:186] Starting ptp4l... I1115 09:41:19.118209 4143292 daemon.go:187] ptp4l cmd: &{Path:/usr/sbin/ptp4l Args:[/usr/sbin/ptp4l -m -f /etc/ptp4l.conf -i ens787f1 -s -2] Env:[] Dir: Stdin:<nil> Stdout:<nil> Stderr:<nil> ExtraFiles:[] SysProcAttr:<nil> Process:<nil> ProcessState:<nil> ctx:<nil> lookPathErr:<nil> finished:false childFiles:[] closeAfterStart:[] closeAfterWait:[] goroutine:[] errch:<nil> waitDone:<nil>} ptp4l[102189.864]: selected /dev/ptp5 as PTP clock ptp4l[102189.886]: port 1: INITIALIZING to LISTENING on INIT_COMPLETE ptp4l[102189.886]: port 0: INITIALIZING to LISTENING on INIT_COMPLETE
第 9 章 硬件网络
9.1. 关于单根 I/O 虚拟化(SR-IOV)硬件网络
Single Root I/O 虚拟化 (SR-IOV) 规范是针对一类 PCI 设备分配的标准,可与多个 pod 共享单个设备。
通过 SR-IOV,您可以将主机节点上识别为物理功能 (PF) 的兼容网络设备分段为多个虚拟功能 (VF)。VF 和其它网络设备一样使用。该设备的 SR-IOV 设备驱动程序决定了如何公开容器中的 VF:
-
netdevice
驱动程序: 容器netns
中的常规内核网络设备 -
vfio-pci
驱动程序: 挂载到容器中的字符设备
您可以将 SR-IOV 网络设备与 OpenShift Container Platform 集群中的其他网络搭配,用于需要高带宽或低延迟的应用程序。
9.1.1. 负责管理 SR-IOV 网络设备的组件
SR-IOV Network Operator 会创建和管理 SR-IOV 堆栈的组件。它执行以下功能:
- 编配 SR-IOV 网络设备的发现和管理
-
为 SR-IOV Container Network Interface(CNI)生成
NetworkAttachmentDefinition
自定义资源 - 创建和更新 SR-IOV 网络设备插件的配置
-
创建节点特定的
SriovNetworkNodeState
自定义资源 -
更新每个
SriovNetworkNodeState
自定义资源中的spec.interfaces
字段
Operator 置备以下组件:
- SR-IOV 网络配置守护进程
- SR-IOV Operator 启动时在 worker 节点上部署的 DaemonSet。守护进程负责在集群中发现和初始化 SR-IOV 网络设备。
- SR-IOV Operator Webhook
- 这是动态准入控制器 Webhook,用于验证 Operator 自定义资源,并为未设置的字段设置适当的默认值。
- SR-IOV Network Resources Injector(网络资源注入器)。
- 这是一个动态准入控制器 Webhook,它提供通过请求和限制为自定义网络资源(如 SR-IOV VF)应用 Kubernetes pod 规格的功能。
- SR-IOV 网络设备插件
- 这个设备插件用于发现、公告并分配 SR-IOV 网络虚拟功能 (VF) 资源。在 Kubernetes 中使用设备插件能够利用有限的资源,这些资源通常为于物理设备中。设备插件可以使 Kubernetes 调度程序了解资源可用性,因此调度程序可以在具有足够资源的节点上调度 pod。
- SR-IOV CNI 插件
- SR-IOV CNI 插件会附加从 SR-IOV 设备插件中直接分配给 pod 的 VF 接口。
SR-IOV Network resources injector 和 SR-IOV Operator Webhook 会被默认启用,可通过编辑 default
SriovOperatorConfig
CR 来禁用。
9.1.1.1. 支持的设备
OpenShift Container Platform 支持以下网络接口卡 (NIC) 模式:
-
Intel XXV710 25GbE SFP28 卡,厂商 ID
0x8086
,设备 ID0x158b
-
Mellanox MT27710 系列 [ConnectX-4 Lx] 25G dual-port SFP28 卡,厂商 ID
0x15b3
,设备 ID0x1015
-
Mellanox MT27800 系列 [ConnectX-5] 25GbE dual-port SFP28 卡,厂商 ID
0x15b3
,设备 ID0x1017
-
Mellanox MT27800 系列 [ConnectX-5] 100GbE 卡,厂商 ID
0x15b3
,设备 ID0x1017
9.1.1.2. 自动发现 SR-IOV 网络设备
SR-IOV Network Operator 将搜索集群以获取 worker 节点上的 SR-IOV 功能网络设备。Operator 会为每个提供兼容 SR-IOV 网络设备的 worker 节点创建并更新一个 SriovNetworkNodeState 自定义资源 (CR) 。
为 CR 分配了与 worker 节点相同的名称。status.interfaces
列表提供有关节点上网络设备的信息。
不要修改 SriovNetworkNodeState
对象。Operator 会自动创建和管理这些资源。
9.1.1.2.1. SriovNetworkNodeState
对象示例
以下 YAML 是由 SR-IOV Network Operator 创建的 SriovNetworkNodeState
对象的示例:
一 个 SriovNetworkNodeState 对象
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodeState metadata: name: node-25 1 namespace: openshift-sriov-network-operator ownerReferences: - apiVersion: sriovnetwork.openshift.io/v1 blockOwnerDeletion: true controller: true kind: SriovNetworkNodePolicy name: default spec: dpConfigVersion: "39824" status: interfaces: 2 - deviceID: "1017" driver: mlx5_core mtu: 1500 name: ens785f0 pciAddress: "0000:18:00.0" totalvfs: 8 vendor: 15b3 - deviceID: "1017" driver: mlx5_core mtu: 1500 name: ens785f1 pciAddress: "0000:18:00.1" totalvfs: 8 vendor: 15b3 - deviceID: 158b driver: i40e mtu: 1500 name: ens817f0 pciAddress: 0000:81:00.0 totalvfs: 64 vendor: "8086" - deviceID: 158b driver: i40e mtu: 1500 name: ens817f1 pciAddress: 0000:81:00.1 totalvfs: 64 vendor: "8086" - deviceID: 158b driver: i40e mtu: 1500 name: ens803f0 pciAddress: 0000:86:00.0 totalvfs: 64 vendor: "8086" syncStatus: Succeeded
9.1.1.3. 在 pod 中使用虚拟功能的示例
您可以在附加了 SR-IOV VF 的 pod 中运行远程直接内存访问 (RDMA) 或 Data Plane Development Kit (DPDK) 应用程序。
本示例演示了在 RDMA 模式中使用虚拟功能 (VF) 的 pod:
使用 RDMA 模式的 Pod
规格
apiVersion: v1 kind: Pod metadata: name: rdma-app annotations: k8s.v1.cni.cncf.io/networks: sriov-rdma-mlnx spec: containers: - name: testpmd image: <RDMA_image> imagePullPolicy: IfNotPresent securityContext: capabilities: add: ["IPC_LOCK"] command: ["sleep", "infinity"]
以下示例演示了在 DPDK 模式中使用 VF 的 pod:
使用 DPDK 模式的 Pod
规格
apiVersion: v1 kind: Pod metadata: name: dpdk-app annotations: k8s.v1.cni.cncf.io/networks: sriov-dpdk-net spec: containers: - name: testpmd image: <DPDK_image> securityContext: capabilities: add: ["IPC_LOCK"] volumeMounts: - mountPath: /dev/hugepages name: hugepage resources: limits: memory: "1Gi" cpu: "2" hugepages-1Gi: "4Gi" requests: memory: "1Gi" cpu: "2" hugepages-1Gi: "4Gi" command: ["sleep", "infinity"] volumes: - name: hugepage emptyDir: medium: HugePages
可以使用一个可选的库来协助容器中运行的应用程序收集与 pod 关联的网络信息。这个程序库名为 'app-netutil'。这个库的源代码包括在 app-netutil
GitHub repo 中。
这个库的目的是简化将 SR-IOV VF 整合到 DPDK 模式中的操作。该程序库提供 GO API 和 C API,并包括了使用这两种语言的示例。
还有一个 Docker 镜像示例 'dpdk-app-centos',它可以根据 pod-spec: l2fwd 、l3wd 或 testpmd 中的环境变量运行以下 DPDK 示例应用程序之一。这个 Docker 镜像提供了将 'app-netutil' 整合到容器镜像本身的示例。这个库也可以整合到初始容器(init-container)中,该容器收集所需数据并将数据传递给现有的 DPDK 工作负载。
9.1.2. 后续步骤
9.2. 安装 SR-IOV Network Operator
您可以在集群上安装单根 I/O 虚拟化(SR-IOV)网络 Operator,以管理 SR-IOV 网络设备和网络附加。
9.2.1. 安装 SR-IOV Network Operator
作为集群管理员,您可以使用 OpenShift Container Platform CLI 或 web 控制台安装 SR-IOV Network Operator。
9.2.1.1. CLI:安装 SR-IOV Network Operator
作为集群管理员,您可以使用 CLI 安装 Operator。
先决条件
- 在裸机环境中安装的集群,其中的节点带有支持 SR-IOV 的硬件。
-
安装 OpenShift CLI(
oc
)。 -
具有
cluster-admin
特权的帐户
流程
要创建
openshift-sriov-network-operator
命名空间,输入以下命令:$ cat << EOF| oc create -f - apiVersion: v1 kind: Namespace metadata: name: openshift-sriov-network-operator labels: openshift.io/run-level: "1" EOF
运行以下命令来创建 OperatorGroup CR:
$ cat << EOF| oc create -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: sriov-network-operators namespace: openshift-sriov-network-operator spec: targetNamespaces: - openshift-sriov-network-operator EOF
订阅 SR-IOV Network Operator。
运行以下命令以获取 OpenShift Container Platform 的主版本和次版本。下一步中需要
channel
值。$ OC_VERSION=$(oc version -o yaml | grep openshiftVersion | \ grep -o '[0-9]*[.][0-9]*' | head -1)
要为 SR-IOV Network Operator 创建 Subscription CR,输入以下命令:
$ cat << EOF| oc create -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: sriov-network-operator-subsription namespace: openshift-sriov-network-operator spec: channel: "${OC_VERSION}" name: sriov-network-operator source: redhat-operators sourceNamespace: openshift-marketplace EOF
要验证是否已安装 Operator,请输入以下命令:
$ oc get csv -n openshift-sriov-network-operator \ -o custom-columns=Name:.metadata.name,Phase:.status.phase
输出示例
Name Phase sriov-network-operator.4.4.0-202006160135 Succeeded
9.2.1.2. web 控制台:安装 SR-IOV Network Operator
作为集群管理员,您可以使用 Web 控制台安装 Operator。
您必须使用 CLI 创建 operator 组。
先决条件
- 在裸机环境中安装的集群,其中的节点带有支持 SR-IOV 的硬件。
-
安装 OpenShift CLI(
oc
)。 -
具有
cluster-admin
特权的帐户
流程
为 SR-IOV Network Operator 创建一个命名空间:
- 在 OpenShift Container Platform web 控制台中,点 Administration → Namespaces。
- 点 Create Namespace。
-
在 Name 字段中输入
openshift-sriov-network-operator
,然后点击 Create。 -
在 Filter by name 字段中输入
openshift-sriov-network-operator
。 -
在结果列表中,点
openshift-sriov-network-operator
,然后点 YAML。 通过在命名空间定义中添加以下小节来更新命名空间:
labels: openshift.io/run-level: "1"
- 点 Save。
安装 SR-IOV Network Operator:
- 在 OpenShift Container Platform Web 控制台中,点击 Operators → OperatorHub。
- 从可用的 Operators 列表中选择 SR-IOV Network Operator,然后点击 Install。
- 在 Create Operator Subscription 页面中,在集群的一个特定的命名空间中 选择openshift-sriov-network-operator。
- 点 Subscribe.
验证 SR-IOV Network Operator 是否已成功安装:
- 导航到 Operators → Installed Operators 页面。
确保 SR-IOV Network Operator 在 openshift-sriov-network-operator 项目中列出,状态 为 InstallSucceeded。
注意在安装过程中,Operator 可能会显示 Failed 状态。如果安装过程结束后有 InstallSucceeded 信息,您可以忽略这个 Failed 信息。
如果 Operator 没有被成功安装,请按照以下步骤进行故障排除:
- 检查 Operator Subscriptions 和 Install Plans 选项卡中的 Status 项中是否有任何错误。
-
进入 Workloads → Pods 页面,在
openshift-sriov-network-operator
项目中检查 pod 的日志。
9.2.2. 后续步骤
9.3. 配置 SR-IOV Network Operator
Single Root I/O Virtualization(SR-IOV)Network Operator 管理集群中的 SR-IOV 网络设备和网络附加。
9.3.1. 配置 SR-IOV Network Operator
通常不需要修改 SR-IOV Network Operator 配置。我们推荐在大多数用例中使用默认配置。只有 Operator 的默认行为与您的用例不兼容时,才需要按照以下步骤修改相关配置。
SR-IOV Network Operator 添加了 SriovOperatorConfig.sriovnetwork.openshift.io
自定义资源定义 (CRD)。Operator 会在 openshift-sriov-network-operator
命名空间中自动创建一个名为 default
的 SriovOperatorConfig 自定义资源 (CR)。
default
CR 包含集群的 SR-IOV Network Operator 配置。要更改 Operator 配置,您必须修改这个 CR。
SriovOperatorConfig
对象为配置 Operator 提供以下几个字段:
-
enableInjector
允许项目管理员启用或禁用 Network Resources Injector 守护进程集。 -
enableOperatorWebhook
允许项目管理员启用或禁用 Operator Admission Controller webhook 守护进程集。 -
configDaemonNodeSelector
允许项目管理员在所选节点上调度 SR-IOV 网络配置守护进程。
9.3.1.1. 关于 Network Resources Injector(网络资源注入器)。
Network Resources Injector 是一个 Kubernetes Dynamic Admission Controller 应用。它提供以下功能:
-
根据 SR-IOV 网络附加定义注解,对
Pod
规格中的资源请求和限值进行修改,以添加 SR-IOV 资源名称。 -
使用下游 API 卷修改
Pod
规格,将 pod 注解和标签作为/etc/podnetinfo
路径下的文件提供给正在运行的容器。
默认情况下,Network Resources Injector 由 SR-IOV operator 启用,并作为在所有 master 节点上以守护进程集的形式运行。以下是在具有三个 master 节点的集群中运行的 Network Resources Injector pod 示例:
$ oc get pods -n openshift-sriov-network-operator
输出示例
NAME READY STATUS RESTARTS AGE network-resources-injector-5cz5p 1/1 Running 0 10m network-resources-injector-dwqpx 1/1 Running 0 10m network-resources-injector-lktz5 1/1 Running 0 10m
9.3.1.2. 关于 SR-IOV Operator admission controller webhook
SR-IOV Operator Admission Controller Webhook 是一个 Kubernetes Dynamic Admission Controller 应用程序。它提供以下功能:
-
在创建或更新时,验证
SriovNetworkNodePolicy
CR。 -
修改
SriovNetworkNodePolicy
CR,在创建或更新 CR 时为priority
和deviceType
项设置默认值。
默认情况下,SR-IOV Operator Admission Controller webhook 由操作员启用,并作为守护进程集在所有 master 节点上运行。以下是运行在具有三个 master 节点的集群中的 Operator Admission Controller webhook pod 的示例:
$ oc get pods -n openshift-sriov-network-operator
输出示例
NAME READY STATUS RESTARTS AGE operator-webhook-9jkw6 1/1 Running 0 16m operator-webhook-kbr5p 1/1 Running 0 16m operator-webhook-rpfrl 1/1 Running 0 16m
9.3.1.3. 关于自定义节点选择器
SR-IOV 网络配置守护进程在集群节点上发现并配置 SR-IOV 网络设备。默认情况下,它将部署到集群中的所有 worker
节点。您可以使用节点标签指定 SR-IOV 网络配置守护进程在哪些节点上运行。
9.3.1.4. 禁用或启用网络资源注入器
要禁用或启用默认启用的网络资源注入器,请完成以下步骤。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。 - 您必须已安装了 SR-IOV Operator。
流程
设置
enableInjector
字段。将<value>
替换为false
来禁用这个功能;或替换为true
来启用这个功能。$ oc patch sriovoperatorconfig default \ --type=merge -n openshift-sriov-network-operator \ --patch '{ "spec": { "enableInjector": <value> } }'
9.3.1.5. 禁用或启用 SR-IOV Operator 准入控制器 Webhook
要禁用或启用默认启用的准入控制器 Webhook,请完成以下步骤。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。 - 您必须已安装了 SR-IOV Operator。
流程
设置
enableOperatorWebhook
字段。将<value>
替换为false
来禁用这个功能;或替换为true
来启用这个功能:$ oc patch sriovoperatorconfig default --type=merge \ -n openshift-sriov-network-operator \ --patch '{ "spec": { "enableOperatorWebhook": <value> } }'
9.3.1.6. 为 SR-IOV 网络配置守护进程配置自定义 NodeSelector
SR-IOV 网络配置守护进程在集群节点上发现并配置 SR-IOV 网络设备。默认情况下,它将部署到集群中的所有 worker
节点。您可以使用节点标签指定 SR-IOV 网络配置守护进程在哪些节点上运行。
要指定部署了 SR-IOV 网络配置守护进程的节点,请完成以下步骤。
当您更新 configDaemonNodeSelector
字段时,SR-IOV 网络配置守护进程会在所选节点中重新创建。在重新创建守护进程时,集群用户无法应用任何新的 SR-IOV 网络节点策略或创建新的 SR-IOV Pod。
流程
要为 Operator 更新节点选择器,请输入以下命令:
$ oc patch sriovoperatorconfig default --type=json \ -n openshift-sriov-network-operator \ --patch '[{ "op": "replace", "path": "/spec/configDaemonNodeSelector", "value": {<node-label>} }]'
将
<node-label>
替换为一个标签以应用它,例如:"node-role.kubernetes.io/worker": ""
。
9.3.2. 后续步骤
9.4. 配置 SR-IOV 网络设备
您可以在集群中配置单一根 I/O 虚拟化(SR-IOV)设备。
9.4.1. SR-IOV 网络节点配置对象
您可以通过定义 SriovNetworkNodePolicy
对象来指定节点的 SR-IOV 网络设备配置。该对象是 sriovnetwork.openshift.io
API 组的一部分。
以下 YAML 描述了 SriovNetworkNodePolicy
对象:
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: <name> 1 namespace: openshift-sriov-network-operator 2 spec: resourceName: <sriov_resource_name> 3 nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" 4 priority: <priority> 5 mtu: <mtu> 6 numVfs: <num> 7 nicSelector: 8 vendor: "<vendor_code>" 9 deviceID: "<device_id>" 10 pfNames: ["<pf_name>", ...] 11 rootDevices: ["<pci_bus_id>", "..."] 12 deviceType: <device_type> 13 isRdma: false 14
- 1
- CR 对象的名称。
- 2
- 安装 SR-IOV Operator 的命名空间。
- 3
- SR-IOV 设备插件的资源名称。您可以为一个资源名称创建多个
SriovNetworkNodePolicy
对象。 - 4
- 选择要配置哪些节点的节点选择器。只有所选节点上的 SR-IOV 网络设备才会被配置。SR-IOV Container Network Interface(CNI)插件和设备插件仅在所选节点上部署。
- 5
- 可选:
0
到99
之间的整数。较小的数值具有较高的优先权,优先级10
高于优先级99
。默认值为99
。 - 6
- 可选:虚拟功能的最大传输单元(MTU)。最大 MTU 值可能因不同的 NIC 型号而有所不同。
- 7
- 为 SR-IOV 物理网络设备创建的虚拟功能((VF)的数量。对于 Intel 网络接口卡 (NIC) ,VF 的数量不能超过该设备支持的 VF 总数。对于 Mellanox NIC,VF 的数量不能超过
128
。 - 8
nicSelector
映射为 Operator 选择要配置的设备。您不必为所有参数指定值。建议您足够精确地识别网络设备以避免意外选择设备。如果指定了rootDevices
,则必须同时为vendor
、deviceID
或pfNames
指定一个值。如果您同时指定了pfNames
和rootDevices
,请确定它们指向同一设备。- 9
- 可选: SR-IOV 网络设备的厂商十六进制代码。允许的值只能是
8086
和15b3
。 - 10
- 可选: SR-IOV 网络设备的设备十六进制代码。允许的值只能是
158b
、1015
和1017
。 - 11
- 可选:该设备的一个或多个物理功能(PF)名称的数组。
- 12
- 用于该设备的 PF 的一个或多个 PCI 总线地址的数组。使用以下格式提供地址:
0000:02:00.1
。 - 13
- 可选:虚拟功能的驱动程序类型。允许的值只能是
netdevice
和vfio-pci
。默认值为netdevice
。注意对于裸机节点上的 Data Plane Development Kit(DPDK)模式中的 Mellanox 卡,请使用
netdevice
驱动程序类型,并将isRdma
设为true
。 - 14
- 可选:是否启用远程直接访问(RDMA)模式。默认值为
false
。注意如果将
isRDMA
参数设定为true
,您可以继续使用启用了 RDMA 的 VF 作为普通网络设备。设备可在其中的一个模式中使用。
9.4.1.1. SR-IOV 设备的虚拟功能 (VF) 分区
在某些情况下,您可能想要将同一个物理功能 (PF) 的虚拟功能 (VF) 分成多个资源池。例如: 您可能想要某些 VF 使用默认驱动程序载入,而其他的 VF 负载使用 vfio-pci
驱动程序。在这样的部署中,您可以使用SriovNetworkNodePolicy 自定义资源 (CR) 中的 pfNames
选项器(selector)来为池指定 VF 的范围,其格式为: <pfname>#<first_vf>-<last_vf>
。
例如,以下 YAML 显示名为 netpf0
的、带有 VF 2
到 7
的接口的选择器:
pfNames: ["netpf0#2-7"]
-
netpf0
是 PF 接口名称。 -
2
是包含在范围内的第一个 VF 索引(基于 0)。 -
7
是包含在范围内的最后一个 VF 索引(基于 0)。
如果满足以下要求,您可以使用不同的策略 CR 从同一 PF 中选择 VF:
-
选择相同 PF 的不同策略的
numVfs
值必须相同。 -
VF 索引范围是从
0
到<numVfs>-1
之间。例如,如果您有一个策略,它的numVfs
被设置为8
,则<first_vf>
的值不能小于0
,<last_vf>
的值不能大于7
。 - 不同策略中的 VF 范围不得互相重叠。
-
<first_vf>
不能大于<last_vf>
。
以下示例演示了 SR-IOV 设备的 NIC 分区。
策略 policy-net-1
定义了一个资源池 net-1
,其中包含带有默认 VF 驱动的 PF netpf0
的 VF 0
。策略 policy-net-1-dpdk
定义了一个资源池 net-1-dpdk
,其中包含带有 vfio
VF 驱动程序的 PF netpf0
的 VF 8
到 15
。
策略 policy-net-1
:
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: policy-net-1 namespace: openshift-sriov-network-operator spec: resourceName: net1 nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" numVfs: 16 nicSelector: pfNames: ["netpf0#0-0"] deviceType: netdevice
策略 policy-net-1-dpdk
:
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: policy-net-1-dpdk namespace: openshift-sriov-network-operator spec: resourceName: net1dpdk nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" numVfs: 16 nicSelector: pfNames: ["netpf0#8-15"] deviceType: vfio-pci
9.4.2. 配置 SR-IOV 网络设备
SR-IOV Network Operator 把 SriovNetworkNodePolicy.sriovnetwork.openshift.io
CRD 添加到 OpenShift Container Platform。您可以通过创建一个 SriovNetworkNodePolicy 自定义资源 (CR) 来配置 SR-IOV 网络设备。
在应用由 SriovNetworkNodePolicy
对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。
它可能需要几分钟时间来应用配置更改。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
您可以使用具有
cluster-admin
角色的用户访问集群。 - 已安装 SR-IOV Network Operator。
- 集群中有足够的可用节点,用于处理从排空节点中驱除的工作负载。
- 您还没有为 SR-IOV 网络设备配置选择任何 control plane 节点。
流程
-
创建一个
SriovNetworkNodePolicy
对象,然后在<name>-sriov-node-network.yaml
文件中保存 YAML。使用配置的实际名称替换<name>
。 创建 SriovNetworkNodePolicy CR:
$ oc create -f <name>-sriov-node-network.yaml
其中
<name>
指定这个配置的名称。在应用配置更新后,
sriov-network-operator
命名空间中的所有 Pod 都会变为Running
状态。要验证是否已配置了 SR-IOV 网络设备,请输入以下命令。将
<node_name>
替换为带有您刚才配置的 SR-IOV 网络设备的节点名称。$ oc get sriovnetworknodestates -n openshift-sriov-network-operator <node_name> -o jsonpath='{.status.syncStatus}'
9.4.3. 后续步骤
9.5. 配置 SR-IOV 以太网网络附加
您可以为集群中的单根 I/O 虚拟化(SR-IOV)设备配置以太网网络附加。
9.5.1. 以太网设备配置对象
您可以通过定义 SriovNetwork
对象来配置以太网网络设备。
以下 YAML 描述了 SriovNetwork
对象:
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: <name> 1 namespace: openshift-sriov-network-operator 2 spec: resourceName: <sriov_resource_name> 3 networkNamespace: <target_namespace> 4 vlan: <vlan> 5 spoofChk: "<spoof_check>" 6 ipam: |- 7 {} linkState: <link_state> 8 maxTxRate: <max_tx_rate> 9 minTxRate: <min_tx_rate> 10 vlanQoS: <vlan_qos> 11 trust: "<trust_vf>" 12 capabilities: <capabilities> 13
- 1
- 对象的名称。SR-IOV Network Operator 创建一个名称相同的
NetworkAttachmentDefinition
对象。 - 2
- 安装 SR-IOV Network Operator 的命名空间。
- 3
- 用于为这个额外网络定义 SR-IOV 硬件的
SriovNetworkNodePolicy
对象中的spec.resourceName
参数的值。 - 4
SriovNetwork
对象的目标命名空间。只有目标命名空间中的 pod 可以附加到额外网络。- 5
- 可选:额外网络的虚拟 LAN(VLAN)ID。它需要是一个从
0
到4095
范围内的一个整数值。默认值为0
。 - 6
- 可选:VF 的 spoof 检查模式。允许的值是字符串
"on"
和"off"
。重要指定的值必须由引号包括,否则 SR-IOV Network Operator 将拒绝对象。
- 7
- 为 IPAM CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理网络附加定义的 IP 地址分配。
- 8
- 可选:虚拟功能(VF)的链接状态。允许的值是
enable
、disable
和auto
。 - 9
- 可选:VF 的最大传输率(以 Mbps 为单位)。
- 10
- 可选:VF 的最低传输率(以 Mbps 为单位)。这个值必须小于或等于最大传输率。注意
Intel NIC 不支持
minTxRate
参数。如需更多信息,请参阅 BZ#1772847。 - 11
- 可选:VF 的 IEEE 802.1p 优先级级别。默认值为
0
。 - 12
- 可选:VF 的信任模式。允许的值是字符串
"on"
和"off"
。重要您必须在引号中包含指定的值,或者 SR-IOV Network Operator 拒绝对象。
- 13
- 可选:为这个额外网络配置功能。您可以指定
"{ "ips": true }"
来启用 IP 地址支持,或指定"{ "mac": true }"
来启用 MAC 地址支持。
9.5.1.1. 配置 ipam CNI 插件
ipam Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址管理 (IPAM)。您可以配置 ipam 以进行静态 IP 地址分配或使用 DHCP 进行动态 IP 地址分配。您指定的 DHCP 服务器必须可从额外网络访问。
以下 JSON 配置对象描述了您可以设置的参数。
9.5.1.1.1. 静态 IP 地址分配配置
以下 JSON 描述了静态 IP 地址分配的配置:
静态分配配置
{ "ipam": { "type": "static", "addresses": [ 1 { "address": "<address>", 2 "gateway": "<gateway>" 3 } ], "routes": [ 4 { "dst": "<dst>", 5 "gw": "<gw>" 6 } ], "dns": { 7 "nameservers": ["<nameserver>"], 8 "domain": "<domain>", 9 "search": ["<search_domain>"] 10 } } }
- 1
- 定义分配给虚拟接口的 IP 地址的数组。支持 IPv4 和 IPv6 IP 地址。
- 2
- 您指定的 IP 地址和网络前缀。例如:如果您指定
10.10.21.10/24
,那么会为额外网络分配 IP 地址10.10.21.10
,网掩码为255.255.255.0
。 - 3
- 出口网络流量要路由到的默认网关。
- 4
- 描述要在 pod 中配置的路由的数组。
- 5
- CIDR 格式的 IP 地址范围,如
192.168.17.0/24
,或默认路由0.0.0.0/0
。 - 6
- 网络流量路由的网关。
- 7
- 可选: DNS 配置。
- 8
- 用来发送 DNS 查询的一个或多个 IP 地址的数组。
- 9
- 附加到主机名的默认域。例如,如果将域设置为
example.com
,对example-host
的 DNS 查找查询将被改写为example-host.example.com
。 - 10
- 在 DNS 查找查询过程中,附加到非限定主机名(如
example-host
)的域名的数组。
9.5.1.1.2. 动态 IP 地址分配配置
以下 JSON 描述了使用 DHCP 进行动态 IP 地址地址分配的配置:
pod 在创建时获取其原始 DHCP 租期。该租期必须由集群中运行的一个小型的 DHCP 服务器部署定期续订。
SR-IOV Network Operator 不创建 DHCP 服务器部署。Cluster Network Operator 负责创建小型的 DHCP 服务器部署。
要触发 DHCP 服务器的部署,您必须编辑 Cluster Network Operator 配置来创建 shim 网络附加,如下例所示:
shim 网络附加定义示例
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: ... additionalNetworks: - name: dhcp-shim namespace: default rawCNIConfig: |- { "name": "dhcp-shim", "cniVersion": "0.3.1", "type": "bridge", "master": "ens5", "ipam": { "type": "dhcp" } }
DHCP 分配配置
{ "ipam": { "type": "dhcp" } }
9.5.1.1.3. 静态 IP 地址分配配置示例
您可以配置 ipam 以进行静态 IP 地址分配:
{ "ipam": { "type": "static", "addresses": [ { "address": "191.168.1.7" } ] } }
9.5.1.1.4. 使用 DHCP 的动态 IP 地址分配配置示例
您可以配置 ipam 以使用 DHCP:
{ "ipam": { "type": "dhcp" } }
9.5.2. 配置 SR-IOV 额外网络
您可以通过创建一个 SriovNetwork
对象来配置使用 SR-IOV 硬件的额外网络。创建 SriovNetwork
对象时,SR-IOV Operator 会自动创建一个 NetworkAttachmentDefinition
对象。
如果一个 SriovNetwork
对象已被附加到状态为 running
的 pod,则不要修改或删除它。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
创建一个
SriovNetwork
对象,然后在<name>.yaml
文件中保存 YAML,其中<name>
是这个额外网络的名称。对象规格可能类似以下示例:apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: attach1 namespace: openshift-sriov-network-operator spec: resourceName: net1 networkNamespace: project2 ipam: |- { "type": "host-local", "subnet": "10.56.217.0/24", "rangeStart": "10.56.217.171", "rangeEnd": "10.56.217.181", "gateway": "10.56.217.1" }
运行以下命令来创建对象:
$ oc create -f <name>.yaml
这里的
<name>
指定额外网络的名称。可选: 要确认与您在上一步中创建的
SriovNetwork
对象关联的NetworkAttachmentDefinition
对象是否存在,请输入以下命令。将<namespace>
替换为您在SriovNetwork
对象中指定的 networkNamespace。$ oc get net-attach-def -n <namespace>
9.5.3. 后续步骤
9.5.4. 其他资源
9.6. 将 pod 添加到额外网络
您可以将 pod 添加到现有的单根 I/O 虚拟化(SR-IOV)网络。
9.6.1. 网络附加的运行时配置
将 pod 附加到额外网络时,您可以指定运行时配置来为 pod 进行特定的自定义。例如,,您可以请求特定的 MAC 硬件地址。
您可以通过在 pod 规格中设置注解来指定运行时配置。注解键是 k8s.v1.cni.cncf.io/network
,它接受一个 JSON 对象来描述运行时配置。
9.6.1.1. 基于以太网的 SR-IOV 附加的运行时配置
以下 JSON 描述了基于以太网的 SR-IOV 网络附加的运行时配置选项。
[ { "name": "<name>", 1 "mac": "<mac_address>", 2 "ips": ["<cidr_range>"] 3 } ]
运行时配置示例
apiVersion: v1 kind: Pod metadata: name: sample-pod annotations: k8s.v1.cni.cncf.io/networks: |- [ { "name": "net1", "mac": "20:04:0f:f1:88:01", "ips": ["192.168.10.1/24", "2001::1/64"] } ] spec: containers: - name: sample-container image: <image> imagePullPolicy: IfNotPresent command: ["sleep", "infinity"]
9.6.2. 将 pod 添加到额外网络
您可以将 pod 添加到额外网络。pod 继续通过默认网络发送与集群相关的普通网络流量。
创建 pod 时会附加额外网络。但是,如果 pod 已存在,您无法为其附加额外网络。
pod 必须与额外网络处于相同的命名空间。
如果网络附加由 SR-IOV Network Operator 管理,SR-IOV 网络资源注入器会自动将 resource
字段添加到 Pod
对象中。
当为 Deployment
对象或 ReplicationController
对象指定 SR-IOV 硬件网络时,必须指定 NetworkAttachmentDefinition
对象的命名空间。如需更多信息,请参阅以下 bug: BZ#1846333 和 BZ#1840962。
先决条件
-
安装 OpenShift CLI(
oc
)。 - 登录到集群。
- 安装 SR-IOV Operator。
-
创建一个将 pod 附加到的
SriovNetwork
对象。
流程
为
Pod
对象添加注解。只能使用以下注解格式之一:要在没有自定义的情况下附加额外网络,请使用以下格式添加注解。将
<network>
替换为要与 pod 关联的额外网络的名称:metadata: annotations: k8s.v1.cni.cncf.io/networks: <network>[,<network>,...] 1
- 1
- 要指定多个额外网络,请使用逗号分隔各个网络。逗号之间不可包括空格。如果您多次指定同一额外网络,则该 pod 会将多个网络接口附加到该网络。
要通过自定义来附加额外网络,请添加具有以下格式的注解:
metadata: annotations: k8s.v1.cni.cncf.io/networks: |- [ { "name": "<network>", 1 "namespace": "<namespace>", 2 "default-route": ["<default-route>"] 3 } ]
运行以下命令来创建 pod。将
<name>
替换为 pod 的名称。$ oc create -f <name>.yaml
可选: 要确认
Pod
CR 中是否存在注解,请输入以下命令将<name>
替换为 pod 的名称。$ oc get pod <name> -o yaml
在以下示例中,
example-pod
pod 附加到net1
额外网络:$ oc get pod example-pod -o yaml apiVersion: v1 kind: Pod metadata: annotations: k8s.v1.cni.cncf.io/networks: macvlan-bridge k8s.v1.cni.cncf.io/networks-status: |- 1 [{ "name": "openshift-sdn", "interface": "eth0", "ips": [ "10.128.2.14" ], "default": true, "dns": {} },{ "name": "macvlan-bridge", "interface": "net1", "ips": [ "20.2.2.100" ], "mac": "22:2f:60:a5:f8:00", "dns": {} }] name: example-pod namespace: default spec: ... status: ...
- 1
k8s.v1.cni.cncf.io/networks-status
参数是对象的 JSON 数组。每个对象描述附加到 pod 的额外网络的状态。注解值保存为纯文本值。
9.6.3. 创建与 SR-IOV pod 兼容的非统一内存访问 (NUMA)
您可以通过限制 SR-IOV 和从相同 NUMA 节点分配的 CPU 资源,使用 restricted
或 single-numa-node
Topology Manager 来创建与 SR-IOV pod 兼容的 NUMA。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
启用 LatencySensitive 配置集,并将 CPU Manager 策略配置为
static
。
流程
创建以下 SR-IOV pod 规格,然后在
<name>-sriov-pod.yaml
文件中保存 YAML。将<name>
替换为这个 pod 的名称。以下示例显示了 SR-IOV pod 规格:
apiVersion: v1 kind: Pod metadata: name: sample-pod annotations: k8s.v1.cni.cncf.io/networks: <name> 1 spec: containers: - name: sample-container image: <image> 2 command: ["sleep", "infinity"] resources: limits: memory: "1Gi" 3 cpu: "2" 4 requests: memory: "1Gi" cpu: "2"
运行以下命令来创建 SR-IOV pod 示例:
$ oc create -f <filename> 1
- 1
- 将
<filename>
替换为您在上一步中创建的文件的名称。
确认
sample-pod
配置为带有保证 QoS。$ oc describe pod sample-pod
确认
sample-pod
被分配了独有的 CPU。$ oc exec sample-pod -- cat /sys/fs/cgroup/cpuset/cpuset.cpus
确认为
sample-pod
分配的 SR-IOV 设备和 CPU 位于相同的 NUMA 节点上。$ oc exec sample-pod -- cat /sys/fs/cgroup/cpuset/cpuset.cpus
9.6.4. 其他资源
9.7. 配置高性能多播
您可以在您的单根 I/O 虚拟化(SR-IOV)硬件网络中使用多播。
9.7.1. 配置高性能多播
OpenShift SDN 默认 Container Network Interface (CNI) 网络供应商支持默认网络上的 pod 间的多播。目前,多播最适用于低带宽协调或服务发现。它不适用于高带宽的应用程序。对于流传输介质应用程序,如 IPTV 和多方视频会议,可以使用 Single Root I/O Virtualization(SR-IOV)硬件来提供接近原生的性能。
使用额外的 SR-IOV 接口进行多播时:
- pod 必须通过额外的 SR-IOV 接口发送或接收多播软件包。
- 连接 SR-IOV 接口的物理网络决定了多播路由和拓扑结构,不受 OpenShift Container Platform 的控制。
9.7.2. 使用 SR-IOV 接口进行多播
以下步骤为多播创建一个 SR-IOV 接口示例。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
创建一个
SriovNetworkNodePolicy
对象:apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: policy-example namespace: openshift-sriov-network-operator spec: resourceName: example nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" numVfs: 4 nicSelector: vendor: "8086" pfNames: ['ens803f0'] rootDevices: ['0000:86:00.0']
创建一个
SriovNetwork
对象:apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: net-example namespace: openshift-sriov-network-operator spec: networkNamespace: default ipam: | 1 { "type": "host-local", 2 "subnet": "10.56.217.0/24", "rangeStart": "10.56.217.171", "rangeEnd": "10.56.217.181", "routes": [ {"dst": "224.0.0.0/5"}, {"dst": "232.0.0.0/5"} ], "gateway": "10.56.217.1" } resourceName: example
创建带有多播应用程序的 pod:
apiVersion: v1 kind: Pod metadata: name: testpmd namespace: default annotations: k8s.v1.cni.cncf.io/networks: nic1 spec: containers: - name: example image: rhel7:latest securityContext: capabilities: add: ["NET_ADMIN"] 1 command: [ "sleep", "infinity"]
- 1
- 只有在应用程序需要为 SR-IOV 接口分配多播 IP 地址时,才需要
NET_ADMIN
功能。否则,可以省略它。
9.8. 在 DPDK 和 RDMA 模式中使用虚拟功能(VF)的示例
您可以使用单一根 I/O 虚拟化(SR-IOV)网络硬件和 Data Plane Development Kit (DPDK) 以及远程直接内存访问 (RDMA) 。
9.8.1. 在 DPDK 和 RDMA 模式中使用虚拟功能(VF)的示例
Data Plane Development Kit (DPDK) 只是一个技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的详情,请参阅 https://access.redhat.com/support/offerings/techpreview/。
远程直接内存访问 (RDMA) 只是一个技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的详情,请参阅 https://access.redhat.com/support/offerings/techpreview/。
9.8.2. 先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。 - 您必须已安装了 SR-IOV Network Operator。
9.8.3. 在 Intel NIC 的 DPDK 模式中使用虚拟功能 (VF) 示例
流程
创建以下
SriovNetworkNodePolicy
对象,然后在intel-dpdk-node-policy.yaml
文件中保存 YAML。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: intel-dpdk-node-policy namespace: openshift-sriov-network-operator spec: resourceName: intelnics nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" priority: <priority> numVfs: <num> nicSelector: vendor: "8086" deviceID: "158b" pfNames: ["<pf_name>", ...] rootDevices: ["<pci_bus_id>", "..."] deviceType: vfio-pci 1
- 1
- 将虚拟功能(VF)的驱动器类型指定为
vfio-pci
。
注意请参阅
Configuring SR-IOV network devices
一节以了解SriovNetworkNodePolicy
中的每个选项的信息。当应用由
SriovNetworkNodePolicy
对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。它可能需要几分钟时间来应用配置更改。确保集群中有足够的可用节点,用以预先处理被驱除的工作负载。应用配置更新后,
openshift-sriov-network-operator
命名空间中的所有 pod 将变为Running
状态。运行以下命令来创建
SriovNetworkNodePolicy
对象:$ oc create -f intel-dpdk-node-policy.yaml
创建以下
SriovNetwork
对象,然后在intel-dpdk-network.yaml
文件中保存 YAML。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: intel-dpdk-network namespace: openshift-sriov-network-operator spec: networkNamespace: <target_namespace> ipam: "{}" 1 vlan: <vlan> resourceName: intelnics
- 1
- 为 ipam CNI 插件指定一个空对象
"{}"
。DPDK 在用户空间模式下工作,不需要 IP 地址。
注意请参阅
Configuring SR-IOV additional network
部分以了解SriovNetwork
中的每个选项的信息。运行以下命令来创建
SriovNetworkNodePolicy
对象:$ oc create -f intel-dpdk-network.yaml
创建以下
Pod
spec,然后在intel-dpdk-pod.yaml
文件中保存 YAML。apiVersion: v1 kind: Pod metadata: name: dpdk-app namespace: <target_namespace> 1 annotations: k8s.v1.cni.cncf.io/networks: intel-dpdk-network spec: containers: - name: testpmd image: <DPDK_image> 2 securityContext: capabilities: add: ["IPC_LOCK"] 3 volumeMounts: - mountPath: /dev/hugepages 4 name: hugepage resources: limits: openshift.io/intelnics: "1" 5 memory: "1Gi" cpu: "4" 6 hugepages-1Gi: "4Gi" 7 requests: openshift.io/intelnics: "1" memory: "1Gi" cpu: "4" hugepages-1Gi: "4Gi" command: ["sleep", "infinity"] volumes: - name: hugepage emptyDir: medium: HugePages
- 1
- 指定
target_namespace
,它与SriovNetwork
对象intel-dpdk-network
创建于的命令空间相同。如果要在其他命名空间中创建 pod,在Pod
spec 和SriovNetowrk
对象中更改target_namespace
。 - 2
- 指定包含应用程序和应用程序使用的 DPDK 库的 DPDK 镜像。
- 3
- 指定应用程序在容器内分配巨页内存所需的
IPC_LOCK
功能。 - 4
- 在
/dev/hugepages
下将巨页卷挂载到 DPDK pod。巨页卷由 emptyDir 卷类型支持,medium 为Hugepages
。 - 5
- 可选:指定分配给 DPDK pod 的 DPDK 设备数。如果未明确指定,则此资源请求和限制将被 SR-IOV 网络资源注入程序自动添加。SR-IOV 网络资源注入程序是由 SR-IOV Operator 管理的准入控制器组件。它默认是启用的,可以通过把默认的
SriovOperatorConfig
CR 中的enableInjector
选项设置为false
来禁用它。 - 6
- 指定 CPU 数量。DPDK pod 通常需要从 kubelet 分配专用 CPU。这可以通过将 CPU Manager 策略设置为
static
,并创建带有有保障的
QoS 的 pod 来实现。 - 7
- 指定巨页大小
hugepages-1Gi
或hugepages-2Mi
以及分配给 DPDK pod 的巨页数量。单独配置2Mi
和1Gi
巨页。配置1Gi
巨页需要在节点中添加内核参数。例如:添加内核参数default_hugepagesz=1GB
,hugepagesz=1G
和hugepages=16
将在系统引导时分配16*1Gi
巨页。
运行以下命令来创建 DPDK pod:
$ oc create -f intel-dpdk-pod.yaml
9.8.4. 使用带有 Mellanox NIC 的 DPDK 模式的虚拟功能(VF)示例
流程
创建以下
SriovNetworkNodePolicy
对象,然后在mlx-dpdk-node-policy.yaml
文件中保存 YAML。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: mlx-dpdk-node-policy namespace: openshift-sriov-network-operator spec: resourceName: mlxnics nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" priority: <priority> numVfs: <num> nicSelector: vendor: "15b3" deviceID: "1015" 1 pfNames: ["<pf_name>", ...] rootDevices: ["<pci_bus_id>", "..."] deviceType: netdevice 2 isRdma: true 3
注意请参阅
Configuring SR-IOV network devices
一节以了解SriovNetworkNodePolicy
中的每个选项的信息。当应用由
SriovNetworkNodePolicy
对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。它可能需要几分钟时间来应用配置更改。确保集群中有足够的可用节点,用以预先处理被驱除的工作负载。应用配置更新后,
openshift-sriov-network-operator
命名空间中的所有 pod 将变为Running
状态。运行以下命令来创建
SriovNetworkNodePolicy
对象:$ oc create -f mlx-dpdk-node-policy.yaml
创建以下
SriovNetwork
对象,然后在mlx-dpdk-network.yaml
文件中保存 YAML。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: mlx-dpdk-network namespace: openshift-sriov-network-operator spec: networkNamespace: <target_namespace> ipam: |- 1 ... vlan: <vlan> resourceName: mlxnics
- 1
- 为 ipam CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理网络附加定义的 IP 地址分配。
注意请参阅
Configuring SR-IOV additional network
部分以了解SriovNetwork
中的每个选项的信息。运行以下命令来创建
SriovNetworkNodePolicy
对象:$ oc create -f mlx-dpdk-network.yaml
创建以下
Pod
spec,然后在mlx-dpdk-pod.yaml
文件中保存 YAML。apiVersion: v1 kind: Pod metadata: name: dpdk-app namespace: <target_namespace> 1 annotations: k8s.v1.cni.cncf.io/networks: mlx-dpdk-network spec: containers: - name: testpmd image: <DPDK_image> 2 securityContext: capabilities: add: ["IPC_LOCK","NET_RAW"] 3 volumeMounts: - mountPath: /dev/hugepages 4 name: hugepage resources: limits: openshift.io/mlxnics: "1" 5 memory: "1Gi" cpu: "4" 6 hugepages-1Gi: "4Gi" 7 requests: openshift.io/mlxnics: "1" memory: "1Gi" cpu: "4" hugepages-1Gi: "4Gi" command: ["sleep", "infinity"] volumes: - name: hugepage emptyDir: medium: HugePages
- 1
- 指定
target_namespace
,它与SriovNetwork
对象mlx-dpdk-network
创建于的命令空间相同。如果要在其他命名空间中创建 pod,在Pod
spec 和SriovNetowrk
对象中更改target_namespace
。 - 2
- 指定包含应用程序和应用程序使用的 DPDK 库的 DPDK 镜像。
- 3
- 指定应用程序在容器内分配巨页内存所需的
IPC_LOCK
功能,以及用于应用程序访问网络接口的NET_RAW
。 - 4
- 在
/dev/hugepages
下将巨页卷挂载到 DPDK pod。巨页卷由 emptyDir 卷类型支持,medium 为Hugepages
。 - 5
- 可选:指定分配给 DPDK pod 的 DPDK 设备数。如果未明确指定,则此资源请求和限制将被 SR-IOV 网络资源注入程序自动添加。SR-IOV 网络资源注入程序是由 SR-IOV Operator 管理的准入控制器组件。它默认是启用的,可以通过把默认的
SriovOperatorConfig
CR 中的enableInjector
选项设置为false
来禁用它。 - 6
- 指定 CPU 数量。DPDK pod 通常需要从 kubelet 分配专用 CPU。这可以通过将 CPU Manager 策略设置为
static
,并创建带有有保障的
QoS 的 pod 来实现。 - 7
- 指定巨页大小
hugepages-1Gi
或hugepages-2Mi
以及分配给 DPDK pod 的巨页数量。单独配置2Mi
和1Gi
巨页。配置1Gi
巨页需要在节点中添加内核参数。
运行以下命令来创建 DPDK pod:
$ oc create -f mlx-dpdk-pod.yaml
9.8.5. 带有 Mellanox NIC 的 RDMA 模式中的虚拟功能(VF)示例
在 OpenShift Container Platform 上使用 RDMA 时,RDMA over Converged Ethernet (RoCE) 是唯一支持的模式。
流程
创建以下
SriovNetworkNodePolicy
对象,然后在mlx-rdma-node-policy.yaml
文件中保存 YAML。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: mlx-rdma-node-policy namespace: openshift-sriov-network-operator spec: resourceName: mlxnics nodeSelector: feature.node.kubernetes.io/network-sriov.capable: "true" priority: <priority> numVfs: <num> nicSelector: vendor: "15b3" deviceID: "1015" 1 pfNames: ["<pf_name>", ...] rootDevices: ["<pci_bus_id>", "..."] deviceType: netdevice 2 isRdma: true 3
注意请参阅
Configuring SR-IOV network devices
一节以了解SriovNetworkNodePolicy
中的每个选项的信息。当应用由
SriovNetworkNodePolicy
对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。它可能需要几分钟时间来应用配置更改。确保集群中有足够的可用节点,用以预先处理被驱除的工作负载。应用配置更新后,
openshift-sriov-network-operator
命名空间中的所有 pod 将变为Running
状态。运行以下命令来创建
SriovNetworkNodePolicy
对象:$ oc create -f mlx-rdma-node-policy.yaml
创建以下
SriovNetwork
对象,然后在mlx-rdma-network.yaml
文件中保存 YAML。apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: mlx-rdma-network namespace: openshift-sriov-network-operator spec: networkNamespace: <target_namespace> ipam: |- 1 ... vlan: <vlan> resourceName: mlxnics
- 1
- 为 ipam CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理网络附加定义的 IP 地址分配。
注意请参阅
Configuring SR-IOV additional network
部分以了解SriovNetwork
中的每个选项的信息。运行以下命令来创建
SriovNetworkNodePolicy
对象:$ oc create -f mlx-rdma-network.yaml
创建以下
Pod
spec,然后在mlx-rdma-pod.yaml
文件中保存 YAML。apiVersion: v1 kind: Pod metadata: name: rdma-app namespace: <target_namespace> 1 annotations: k8s.v1.cni.cncf.io/networks: mlx-rdma-network spec: containers: - name: testpmd image: <RDMA_image> 2 securityContext: capabilities: add: ["IPC_LOCK"] 3 volumeMounts: - mountPath: /dev/hugepages 4 name: hugepage resources: limits: memory: "1Gi" cpu: "4" 5 hugepages-1Gi: "4Gi" 6 requests: memory: "1Gi" cpu: "4" hugepages-1Gi: "4Gi" command: ["sleep", "infinity"] volumes: - name: hugepage emptyDir: medium: HugePages
- 1
- 指定
target_namespace
,它与SriovNetwork
对象mlx-rdma-network
创建于的命令空间相同。如果要在其他命名空间中创建 pod,在Pod
spec 和SriovNetowrk
对象中更改target_namespace
。 - 2
- 指定包含应用程序和应用程序使用的 RDMA 库的 RDMA 镜像。
- 3
- 指定应用程序在容器内分配巨页内存所需的
IPC_LOCK
功能。 - 4
- 在
/dev/hugepages
下将巨页卷挂载到 RDMA pod。巨页卷由 emptyDir 卷类型支持,medium 为Hugepages
。 - 5
- 指定 CPU 数量。RDMA pod 通常需要从 kubelet 分配专用 CPU。这可以通过将 CPU Manager 策略设置为
static
,并创建带有有保障的
QoS 的 pod 来实现。 - 6
- 指定巨页大小
hugepages-1Gi
或hugepages-2Mi
以及分配给 RDMA pod 的巨页数量。单独配置2Mi
和1Gi
巨页。配置1Gi
巨页需要在节点中添加内核参数。
运行以下命令来创建 RDMA pod:
$ oc create -f mlx-rdma-pod.yaml
第 10 章 OpenShift SDN 默认 CNI 网络供应商
10.1. 关于 OpenShift SDN 默认 CNI 网络供应商
OpenShift Container Platform 使用软件定义网络 (SDN) 方法来提供一个统一的集群网络,它允许 OpenShift Container Platform 集群中的不同 pod 相互间进行通信。此 pod 网络是由 OpenShift SDN 建立和维护的,它使用 Open vSwitch (OVS) 配置覆盖网络。
OpenShift SDN 提供三种 SDN 模式来配置 pod 网络:
- 网络策略模式允许项目管理员使用 NetworkPolicy 对象配置其自身的隔离策略。NetworkPolicy 是 OpenShift Container Platform 4.4 的默认模式。
- 多租户 模式为 pod 和服务提供项目级别的隔离。来自不同项目的 Pod 不能与不同项目的 pod 和服务发送数据包或接收数据包。您可以针对项目禁用隔离,允许它将网络流量发送到整个集群中的所有 pod 和服务,并从那些 pod 和服务接收网络流量。
- 子网模式提供一个扁平 pod 网络,每个 pod 都可以与所有其他 pod 和服务通信。网络策略模式提供与子网模式相同的功能。
10.1.1. 支持的默认 CNI 网络供应商功能列表
OpenShift Container Platform 为默认的 Container Network Interface (CNI) 网络供应商提供两个支持的选择:OpenShift SDN 和 OVN-Kubernetes。下表总结了这两个网络供应商当前支持的功能:
功能 | OpenShift SDN | OVN-Kubernetes [1] |
---|---|---|
出口 IP | 支持 | 不支持 |
出口防火墙 [2] | 支持 | 不支持 |
出口路由器 | 支持 | 不支持 |
Kubernetes 网络策略 | 部分支持 [3] | 支持 |
多播 | 支持 | 支持 |
- 当前仅在 OpenShift Container Platform 4.4 中作为技术预览功能提供。
- 在 OpenShift SDN 中,出口防火墙也称为出口网络策略。这和网络策略出口不同。
-
不支持出口规则和一些
ipBlock
规则。
10.2. 为项目配置出口 IP
作为集群管理员,您可以配置 OpenShift SDN 默认 Container Network Interface (CNI) 网络供应商,为项目分配一个或多个出口 IP 地址。
10.2.1. 项目出口流量的出口 IP 地址分配
通过为项目配置出口 IP 地址,来自指定项目的所有出站外部连接将共享相同的固定源 IP 地址。外部资源可以根据出口 IP 地址识别来自特定项目的流量。分配给项目的出口 IP 地址与用来向特定目的地发送流量的出口路由器不同。
出口 IP 地址是作为额外 IP 地址在节点的主网络接口中实现的,且必须与节点的主 IP 地址处于同一个子网中。
不能在任何 Linux 网络配置文件中配置出口 IP 地址,比如 ifcfg-eth0
。
在主网络接口上允许额外 IP 地址可能需要在使用某些云或虚拟机解决方案时进行额外的配置。
您可以通过设置 NetNamespace
对象的 egressIPs
参数,将出口 IP 地址分配给命名空间。在出口 IP 与项目关联后,OpenShift SDN 允许您以两种方式为主机分配出口 IP:
- 在自动分配方法中,给节点分配一个出口 IP 地址范围。
- 在手动分配方法中,给节点分配包含一个或多个出口 IP 地址的列表。
请求出口 IP 地址的命名空间与可以托管那些出口 IP 地址的节点匹配,然后为那些节点分配出口 IP 地址。如果在 NetNamespace
对象中设置了 egressIPs
参数,但没有节点托管该出口 IP 地址,则会丢弃来自该命名空间的出口流量。
节点高可用性是自动的。如果托管出口 IP 地址的节点不可访问,并且有可以托管那些出口 IP 地址的节点,那么出口 IP 地址将会移到新节点。当无法访问的托管原始出口 IP 地址的节点恢复正常后,出口 IP 地址会自动转移,以在不同节点之间均衡出口 IP 地址。
您不能在同一节点上同时使用手动分配和自动分配的出口 IP 地址。如果手动从 IP 地址范围分配出口 IP 地址,则不得将该范围用于自动 IP 分配。
如果您以多租户模式使用 OpenShift SDN,则无法将出口 IP 地址与与其关联的项目附加到另一个命名空间的任何命名空间一起使用。例如,如果 project1
和 project2
通过运行 oc adm pod-network join-projects --to=project1 project2
命令被连接,则这两个项目都不能使用出口 IP 地址。如需更多信息,请参阅 BZ#1645577。
10.2.1.1. 使用自动分配的出口 IP 地址时的注意事项
当对出口 IP 地址使用自动分配方法时,请注意以下事项:
-
您可以设置每个节点的
HostSubnet
资源的egressCIDRs
参数,以指明节点可以托管的出口 IP 地址范围。OpenShift Container Platform 根据您指定的 IP 地址范围设置HostSubnet
资源的egressIPs
参数。 - 使用自动分配模式时,支持每个命名空间具有一个出口 IP 地址。
如果托管命名空间的出口 IP 地址的节点不可访问,OpenShift Container Platform 会将出口 IP 地址重新分配给具有兼容出口 IP 地址范围的另外一个节点。自动分配方法最适合在把额外的 IP 地址与节点进行关联时具有灵活性的环境中安装的集群。
10.2.1.2. 使用手动分配出口 IP 地址时的注意事项
当手动分配出口 IP 地址时,请考虑以下事项:
-
您可以设置每个节点的
HostSubnet
资源的egressIPs
参数,以指明节点可以托管的 IP 地址。 - 支持一个命名空间带有多个出口 IP 地址。
当命名空间有多个出口 IP 地址时,如果托管第一个出口 IP 地址的节点不可访问,OpenShift Container Platform 将自动切换到使用下一个可用的出口 IP 地址,直到可以再次访问第一个出口 IP 地址。
建议在公共云环境中(可能有将额外 IP 地址与节点关联的限制)安装的集群使用这个方法。
10.2.2. 为一个命名空间启用自动分配出口 IP 地址
在 OpenShift Container Platform 中,可以为一个或多个节点上的特定命名空间启用自动分配出口 IP 地址。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
角色的用户访问集群。
流程
使用以下 JSON,用出口 IP 地址更新
NetNamespace
资源:$ oc patch netnamespace <project_name> --type=merge -p \ 1 '{ "egressIPs": [ "<ip_address>" 2 ] }'
例如,将
project1
分配给 IP 地址 192.168.1.100,将project2
分配给 IP 地址 192.168.1.101:$ oc patch netnamespace project1 --type=merge -p \ '{"egressIPs": ["192.168.1.100"]}' $ oc patch netnamespace project2 --type=merge -p \ '{"egressIPs": ["192.168.1.101"]}'
使用以下 JSON 设置每一主机的
egressCIDRs
参数,以指明哪些节点可以托管出口 IP 地址:$ oc patch hostsubnet <node_name> --type=merge -p \ 1 '{ "egressCIDRs": [ "<ip_address_range_1>", "<ip_address_range_2>" 2 ] }'
例如,将
node1
和node2
设置为托管范围为 192.168.1.0 到 192.168.1.255 的出口 IP 地址:$ oc patch hostsubnet node1 --type=merge -p \ '{"egressCIDRs": ["192.168.1.0/24"]}' $ oc patch hostsubnet node2 --type=merge -p \ '{"egressCIDRs": ["192.168.1.0/24"]}'
OpenShift Container Platform 会自动以均衡的方式将特定的出口 IP 地址分配给可用的节点。在本例中,它会将出口 IP 地址 192.168.1.100 分配给
node1
,并将出口 IP 地址 192.168.1.101 分配给node2
,或反之。
10.2.3. 为一个命名空间配置手动分配出口 IP 地址
在 OpenShift Container Platform 中,您可以将一个或多个出口 IP 与一个项目关联。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
角色的用户访问集群。
流程
通过使用所需 IP 地址指定以下 JSON 对象来更新
NetNamespace
对象:$ oc patch netnamespace <project> --type=merge -p \ 1 '{ "egressIPs": [ 2 "<ip_address>" ] }'
例如,将
project1
项目分配给 IP 地址192.168.1.100
:$ oc patch netnamespace project1 --type=merge \ -p '{"egressIPs": ["192.168.1.100"]}'
您可以将
egressIPs
设置为位于不同节点上的两个或多个 IP 地址,以提供高可用性。如果设置了多个出口 IP 地址,Pod 会将列表中的第一个 IP 用于出口,但如果托管该 IP 地址的节点失败,Pod 会在短暂的延迟后切换到使用列表中的下一个 IP。手动将出口 IP 分配给节点主机。在节点主机上的
HostSubnet
对象中设置egressIPs
参数。使用以下 JSON,尽可能纳入您要分配给该节点主机的所有 IP:$ oc patch hostsubnet <node_name> --type=merge -p \ 1 '{ "egressIPs": [ 2 "<ip_address_1>", "<ip_address_N>" ] }'
例如,指定
node1
应具有出口 IP192.168.1.100
、192.168.1.101
和192.168.1.102
:$ oc patch hostsubnet node1 --type=merge -p \ '{"egressIPs": ["192.168.1.100", "192.168.1.101", "192.168.1.102"]}'
在上例中,
project1
的所有出口流量都会被路由到托管指定出口 IP 地址的节点,然后(使用 NAT)连接到那个 IP 地址。
10.3. 配置出口防火墙来控制对外部 IP 地址的访问
作为集群管理员,您可以为项目创建一个出口防火墙,用于限制离开 OpenShift Container Platform 集群的出口流量。
10.3.1. 出口防火墙在一个项目中的工作原理
作为集群管理员,您可以使用一个出口防火墙来限制集群内的一些 pod 或所有 pod 可以访问的外部主机。出口防火墙适用于以下情况:
- pod 只能连接到内部主机,且无法启动到公共互联网的连接。
- pod 只能连接到公共互联网,且无法启动到 OpenShift Container Platform 集群以外的内部主机的连接。
- pod 无法访问 OpenShift Container Platform 集群外的特定内部子网或主机。
- pod 只能连接到特定的外部主机。
您可以通过创建一个 EgressNetworkPolicy 自定义资源 (CR) 对象并指定 CIDR 格式的 IP 地址范围或指定 DNS 名称来配置出口防火墙策略。例如,您可以允许某一个项目访问指定的 IP 范围,但拒绝其他项目对同一 IP 范围的访问。或者您可以限制应用程序开发人员从 Python pip 的镜像点进行更新,并强制要求更新只能来自于批准的源。
您必须将 OpenShift SDN 配置为使用网络策略或多租户模式来配置出口防火墙策略。
如果使用网络策略模式,egress 策略只与每个命名空间的一个策略兼容,且无法在需要共享网络的项目中使用,如全局项目。
出口防火墙规则不适用于通过路由器的网络流量。任何有权创建 Route CR 对象的用户,都可以通过创建指向禁止访问的目的地的路由,来绕过出口网络策略规则。
10.3.1.1. 出口防火墙的限制
出口防火墙有以下限制:
- 项目不能有多个 EgressNetworkPolicy 对象。
- 每个项目最多只能定义一个具有最多 50 个规则的 EgressNetworkPolicy 对象。
-
default
项目无法使用出口网络策略。 当在多租户模式下使用 OpenShift SDN 默认 Container Network Interface (CNI) 网络供应商时,会有以下限制:
-
全局项目无法使用出口防火墙。您可以使用
oc adm pod-network make-projects-global
把一个项目设置为全局项目。 -
通过
oc adm pod-network join-projects
命令合并的项目,无法在任何合并的项目中使用出口防火墙。
-
全局项目无法使用出口防火墙。您可以使用
违反这些限制会导致项目的出口策略中断,并可能导致所有外部网络流量被丢弃。
10.3.1.2. 出口网络策略规则的匹配顺序
egress 网络策略规则是按照它们定义的顺序来评估的,从第一个到最后一个的顺序。第一个与 pod 的出口连接匹配的规则会被应用。该连接会忽略后续的所有规则。
10.3.1.3. 域名服务器 (DNS) 解析如何工作
如果您在 egress 防火墙策略规则中使用 DNS 名称,则正确解析域名会受到以下限制:
- 域名更新根据本地非授权服务器返回的域的 TTL(time to live)值进行轮询。
- 在需要时,pod 必须通过相同的本地名称服务器解析域名。否则,egress 防火墙控制器和 pod 已知的域的 IP 地址可能会有所不同。如果主机名的 IP 地址不同,则出口防火墙所起的强制作用可能会不一致。
- 因为出口防火墙控制器和 pod 异步轮询相同的本地名称服务器,所以 pod 可能会在出口控制器执行前获取更新的 IP 地址,从而导致竞争条件。由于这个限制,仅建议在 EgressNetworkPolicy 对象中使用域名来更改 IP 地址的域。
出口防火墙始终允许 pod 访问 pod 所在的用于 DNS 解析的节点的外部接口。
如果您在出口防火墙策略中使用域名,且您的 DNS 解析不是由本地节点上的 DNS 服务器处理,那么您必须添加出口防火墙规则,允许访问您的 DNS 服务器的 IP 地址。如果您在 pod 中使用域名。
10.3.2. EgressNetworkPolicy 自定义资源 (CR) 对象
以下 YAML 描述了一个 EgressNetworkPolicy CR 对象:
apiVersion: network.openshift.io/v1 kind: EgressNetworkPolicy metadata: name: <name> 1 spec: egress: 2 ...
10.3.2.1. EgressNetworkPolicy 规则
以下 YAML 描述了一个出口防火墙规则对象。egress
键需要一个包括一个或多个对象的数组。
egress: - type: <type> 1 to: 2 cidrSelector: <cidr> 3 dnsName: <dns-name> 4
10.3.2.2. EgressNetworkPolicy CR 对象示例
以下示例定义了几个出口防火墙策略规则:
apiVersion: network.openshift.io/v1 kind: EgressNetworkPolicy metadata: name: default-rules 1 spec: egress: 2 - type: Allow to: cidrSelector: 1.2.3.0/24 - type: Allow to: dnsName: www.example.com - type: Deny to: cidrSelector: 0.0.0.0/0
10.3.3. 创建出口防火墙策略对象
作为集群管理员,您可以为项目创建一个出口防火墙策略对象。
如果项目已经定义了一个 EgressNetworkPolicy 对象,您必须编辑现有的策略来更改出口防火墙规则。
先决条件
- 使用 OpenShift SDN 默认 Container Network Interface (CNI) 网络供应商插件的集群。
-
安装 OpenShift CLI(
oc
)。 - 您需要使用集群管理员身份登陆到集群。
流程
创建策略规则:
-
创建一个
<policy-name>.yaml
文件,其中<policy-name>
描述出口策略规则。 - 在您创建的文件中,定义出口策略对象。
-
创建一个
运行以下命令来创建策略对象:
$ oc create -f <policy-name>.yaml -n <project>
在以下示例中,在名为
project1
的项目中创建一个新的 EgressNetworkPolicy 对象:$ oc create -f default-rules.yaml -n project1
输出示例
egressnetworkpolicy.network.openshift.io/default-rules created
-
可选:保存
<policy-name>.yaml
,以便在以后进行修改。
10.4. 为项目编辑出口防火墙
作为集群管理员,您可以修改现有出口防火墙的网络流量规则。
10.4.1. 编辑 EgressNetworkPolicy 对象
作为集群管理员,您可以更新一个项目的出口防火墙。
先决条件
- 使用 OpenShift SDN 网络插件的集群。
-
安装 OpenShift CLI(
oc
)。 - 您需要使用集群管理员身份登陆到集群。
流程
要编辑项目的现有出口网络策略对象,请完成以下步骤:
查找项目的 EgressNetworkPolicy 对象的名称。将
<project>
替换为项目的名称。$ oc get -n <project> egressnetworkpolicy
可选,如果您在创建出口网络防火墙时没有保存 EgressNetworkPolicy 对象的副本,请输入以下命令来创建副本。
$ oc get -n <project> \ 1 egressnetworkpolicy <name> \ 2 -o yaml > <filename>.yaml 3
输入以下命令替换 EgressNetworkPolicy 对象。将
<filename>
替换为包含更新的 EgressNetworkPolicy 对象的文件名称。$ oc replace -f <filename>.yaml
10.4.2. EgressNetworkPolicy 自定义资源 (CR) 对象
以下 YAML 描述了一个 EgressNetworkPolicy CR 对象:
apiVersion: network.openshift.io/v1 kind: EgressNetworkPolicy metadata: name: <name> 1 spec: egress: 2 ...
10.4.2.1. EgressNetworkPolicy 规则
以下 YAML 描述了一个出口防火墙规则对象。egress
键需要一个包括一个或多个对象的数组。
egress: - type: <type> 1 to: 2 cidrSelector: <cidr> 3 dnsName: <dns-name> 4
10.4.2.2. EgressNetworkPolicy CR 对象示例
以下示例定义了几个出口防火墙策略规则:
apiVersion: network.openshift.io/v1 kind: EgressNetworkPolicy metadata: name: default-rules 1 spec: egress: 2 - type: Allow to: cidrSelector: 1.2.3.0/24 - type: Allow to: dnsName: www.example.com - type: Deny to: cidrSelector: 0.0.0.0/0
10.5. 从项目中删除出口防火墙
作为集群管理员,您可以从项目中删除出口防火墙,从而删除对项目的离开 OpenShift Container Platform 集群的网络流量的限制。
10.5.1. 删除 EgressNetworkPolicy 对象
作为集群管理员,您可以从项目中删除出口防火墙。
先决条件
- 使用 OpenShift SDN 网络插件的集群。
-
安装 OpenShift CLI(
oc
)。 - 您需要使用集群管理员身份登陆到集群。
流程
要为项目删除出口网络策略对象,请完成以下步骤:
查找项目的 EgressNetworkPolicy 对象的名称。将
<project>
替换为项目的名称。$ oc get -n <project> egressnetworkpolicy
输入以下命令删除 EgressNetworkPolicy 对象。将
<project>
替换为项目名称,<name>
替换为对象名称。$ oc delete -n <project> egressnetworkpolicy <name>
10.6. 使用出口路由器 pod 的注意事项
10.6.1. 关于出口路由器 pod
OpenShift Container Platform 出口路由器(egress router ) pod 使用一个专用的私有源 IP 地址,将网络流量重定向到指定的远程服务器。这可让您将网络流量发送到设定仅允许从特定 IP 地址访问的服务器。
出口路由器 pod 并不适用于所有外向的连接。创建大量出口路由器 pod 可能会超过您的网络硬件的限制。例如,为每个项目或应用程序创建出口路由器 pod 可能会导致,在转换为使用软件来进行 MAC 地址过滤前超过了网络接口可以处理的本地 MAC 地址的数量。
出口路由器镜像与 Amazon AWS、Azure Cloud 或其他不支持第 2 层操作的云平台不兼容,因为它们与 macvlan 流量不兼容。
10.6.1.1. 出口路由器模式
在重定向模式中,出口路由器 pod 会设置 iptables 规则将流量从其自身 IP 地址重定向到一个或多个目标 IP 地址。需要使用保留源 IP 地址的客户端 pod 必须修改来连接到出口路由器,而不是直接连接到目标 IP。
在 HTTP 代理模式 中,出口路由器 pod 作为一个 HTTP 代理在端口 8080
上运行。这个模式只适用于连接到基于 HTTP 或基于 HTTPS 服务的客户端,但通常需要较少的更改就可以使客户端 pod 正常工作。很多程序可以通过设置环境变量来使用 HTTP 代理服务器。
在 DNS 代理模式 中,出口路由器 pod 作为基于 TCP 服务的 DNS 代理运行,将其自身的 IP 地址转换到一个或多个目标 IP 地址。要使用保留的源 IP 地址,客户端 pod 必须进行修改来连接到出口路由器 pod,而不是直接连接到目标 IP 地址。此修改确保了外部的目的地将流量视为来自一个已知源的流量。
重定向模式可用于除 HTTP 和 HTTPS 以外的所有服务。对于 HTTP 和 HTTPS 服务,请使用 HTTP 代理模式。对于使用 IP 地址或域名的基于 TCP 的服务,请使用 DNS 代理模式。
10.6.1.2. 出口路由器 pod 的实现
出口路由器 pod 的设置由一个初始化容器执行。该容器在特权环境中运行,以便可以配置 macvlan 接口并设置 iptables
规则。在初始化容器完成设置 iptables
规则后会退出。接下来,出口路由器 pod 会执行容器来处理出口路由器流量。取决于出口路由器的模式,所使用的镜像会有所不同。
环境变量决定 egress-router 镜像使用的地址。镜像将 macvlan 接口配置为使用 EGRESS_SOURCE
作为其 IP 地址,并将 EGRESS_GATEWAY
作为网关的 IP 地址。
网络地址转换(NAT)规则被设置,使任何到 TCP 或 UDP 端口上的 pod 的集群 IP 地址的连接被重新指向由 EGRESS_DESTINATION
变量指定的 IP 地址的同一端口。
如果集群中只有部分节点能够声明指定的源 IP 地址并使用指定的网关,您可以指定一个 nodeName
或 nodeSelector
来表示哪些节点可以接受。
10.6.1.3. 部署注意事项
出口路由器 pod 会为节点的主网络接口添加额外的 IP 地址和 MAC 地址。因此,您可能需要配置虚拟机监控程序或云供应商来允许额外的地址。
- Red Hat OpenStack Platform (RHOSP)
如果要在 RHOSP 上部署 OpenShift Container Platform,则必须将 OpenStack 环境中的 IP 和 MAC 地址列入白名单,否则 通信将失败:
$ openstack port set --allowed-address \ ip_address=<ip_address>,mac_address=<mac_address> <neutron_port_uuid>
- Red Hat Virtualization (RHV)
- 如果您使用 RHV,必须为虚拟网络接口卡(vNIC)选择 No Network Filter。
- VMware vSphere
- 如果您使用 VMware vSphere,请参阅 VMWare 文档来保证 vSphere 标准交换器的安全。通过从 vSphere Web 客户端中选择主机虚拟交换机来查看并更改 VMWare vSphere 默认设置。
具体来说,请确保启用了以下功能:
10.6.1.4. 故障切换配置
为了避免停机,可以使用 Deployment
资源部署出口路由器 pod,如下例所示。要为示例部署创建新 Service
对象,使用 oc expose deployment/egress-demo-controller
命令。
apiVersion: v1 kind: Deployment metadata: name: egress-demo-controller spec: replicas: 1 1 selector: name: egress-router template: metadata: name: egress-router labels: name: egress-router annotations: pod.network.openshift.io/assign-macvlan: "true" spec: 2 initContainers: ... containers: ...
10.6.2. 其他资源
10.7. 以重定向模式部署出口路由器 pod
作为集群管理员,您可以部署一个出口路由器 pod,该 pod 被配置为将流量重新定向到指定的目的地 IP 地址。
10.7.1. 重定向模式的出口路由器 pod 规格
为 Pod
对象中的一个出口路由器 pod 定义其配置。以下 YAML 描述了以重定向模式配置出口路由器 pod 的字段:
apiVersion: v1 kind: Pod metadata: name: egress-1 labels: name: egress-1 annotations: pod.network.openshift.io/assign-macvlan: "true" 1 spec: initContainers: - name: egress-router image: registry.redhat.io/openshift4/ose-egress-router securityContext: privileged: true env: - name: EGRESS_SOURCE 2 value: <egress_router> - name: EGRESS_GATEWAY 3 value: <egress_gateway> - name: EGRESS_DESTINATION 4 value: <egress_destination> - name: EGRESS_ROUTER_MODE value: init containers: - name: egress-router-wait image: registry.redhat.io/openshift3/ose-pod
- 1
- 在启动
egress-router
容器前,在主网络接口上创建一个 macvlan 网络接口,并将该接口移到 pod 网络命名空间中。您必须把"true"
值包括在引号中。要在主接口以外的网络接口上创建 macvlan 接口,请将注解值设置为该接口的名称。例如:eth1
。 - 2
- 保留给出口路由器 pod 使用的物理网络的 IP 地址。可选:您可以包括子网长度(
/24
后缀),以便正确路由到本地子网。如果没有指定子网长度,则出口路由器只能访问使用EGRESS_GATEWAY
变量指定的主机,且子网上没有其他主机。 - 3
- 值与节点使用的默认网关相同。
- 4
- 将流量定向到的外部服务器。使用这个示例,连接到 pod 流量被重新定向到
203.0.113.25
,源 IP 地址为192.168.12.99
。
出口路由器 pod 规格示例
apiVersion: v1 kind: Pod metadata: name: egress-multi labels: name: egress-multi annotations: pod.network.openshift.io/assign-macvlan: "true" spec: initContainers: - name: egress-router image: registry.redhat.io/openshift4/ose-egress-router securityContext: privileged: true env: - name: EGRESS_SOURCE value: 192.168.12.99/24 - name: EGRESS_GATEWAY value: 192.168.12.1 - name: EGRESS_DESTINATION value: | 80 tcp 203.0.113.25 8080 tcp 203.0.113.26 80 8443 tcp 203.0.113.26 443 203.0.113.27 - name: EGRESS_ROUTER_MODE value: init containers: - name: egress-router-wait image: registry.redhat.io/openshift3/ose-pod
10.7.2. 出口目的地配置格式
当出口路由器 pod 被部署为重定向模式时,您可以使用以下一种或多种格式指定重定向规则:
-
<port> <protocol> <ip_address>
- 到给定<port>
的内向连接应该被重新定向到给定<ip_address>
上的同一端口。<protocol>
可以是tcp
或udp
。 -
<port> <protocol> <ip_address> <remote_port>
- 和以上一样,除了连接被重新定向到<ip_address>
上的一个不同的<remote_port>
中。 -
<ip_address>
- 如果最后一行是一个 IP 地址,那么其它端口上的所有连接都会被重新指向那个 IP 地址的对应端口。如果没有故障切换 IP 地址,则其它端口上的连接将被拒绝。
在示例中定义了几个规则:
-
第一行将流量从本地端口
80
重定向到203.0.113.25
的端口80
。 -
第二行和第三行将本地端口
8080
和8443
重定向到203.0.113.26
的远程端口80
和443
。 - 最后一行与之前规则中没有指定的端口的流量匹配。
配置示例
80 tcp 203.0.113.25 8080 tcp 203.0.113.26 80 8443 tcp 203.0.113.26 443 203.0.113.27
10.7.3. 以重定向模式部署出口路由器 pod
在重定向模式中,出口路由器 pod 会设置 iptables 规则将流量从其自身 IP 地址重定向到一个或多个目标 IP 地址。需要使用保留源 IP 地址的客户端 pod 必须修改来连接到出口路由器,而不是直接连接到目标 IP。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
- 创建出口路由器 pod。
为确保其他 pod 可以查找出口路由器 pod 的 IP 地址,请创建一个服务指向出口路由器 pod,如下例所示:
apiVersion: v1 kind: Service metadata: name: egress-1 spec: ports: - name: http port: 80 - name: https port: 443 type: ClusterIP selector: name: egress-1
您的 pod 现在可以连接到此服务。使用保留的出口 IP 地址将其连接重新指向外部服务器的对应端口。
10.7.4. 其他资源
10.8. 以 HTTP 代理模式部署出口路由器 pod
作为集群管理员,您可以将出口路由器 pod 配置为代理流量到指定的 HTTP 和基于 HTTPS 的服务。
10.8.1. HTTP 模式的出口路由器 pod 规格
为 Pod
对象中的一个出口路由器 pod 定义其配置。以下 YAML 描述了以 HTTP 模式配置出口路由器 pod 的字段:
apiVersion: v1 kind: Pod metadata: name: egress-1 labels: name: egress-1 annotations: pod.network.openshift.io/assign-macvlan: "true" 1 spec: initContainers: - name: egress-router image: registry.redhat.io/openshift4/ose-egress-router securityContext: privileged: true env: - name: EGRESS_SOURCE 2 value: <egress-router> - name: EGRESS_GATEWAY 3 value: <egress-gateway> - name: EGRESS_ROUTER_MODE value: http-proxy containers: - name: egress-router-pod image: registry.redhat.io/ose-egress-http-proxy env: - name: EGRESS_HTTP_PROXY_DESTINATION 4 value: |- ... ...
- 1
- 在启动
egress-router
容器前,在主网络接口上创建一个 macvlan 网络接口,并将该接口移到 pod 网络命名空间中。您必须把"true"
值包括在引号中。要在主接口以外的网络接口上创建 macvlan 接口,请将注解值设置为该接口的名称。例如:eth1
。 - 2
- 保留给出口路由器 pod 使用的物理网络的 IP 地址。可选:您可以包括子网长度(
/24
后缀),以便正确路由到本地子网。如果没有指定子网长度,则出口路由器只能访问使用EGRESS_GATEWAY
变量指定的主机,且子网上没有其他主机。 - 3
- 值与节点使用的默认网关相同。
- 4
- 一个字符串或 YAML 多行字符串指定如何配置代理。请注意,这作为 HTTP 代理容器中的环境变量指定,而不是与 init 容器中的其他环境变量指定。
10.8.2. 出口目的地配置格式
当出口路由器 pod 以 HTTP 代理模式部署时,您可以使用以下一个或多个格式指定重定向规则。配置中的每行都指定允许或者拒绝的连接组:
-
IP 地址允许连接到那个 IP 地址,如
192.168.1.1
。 -
CIDR 范围允许连接到那个 CIDR 范围,如
192.168.1.0/24
。 -
主机名允许代理该主机,如
www.example.com
。 -
前面带有
*
的域名允许代理到那个域及其所有子域,如*.example.com
。 -
!
再加上以前匹配的表达式会拒绝连接。 -
如果最后一行是
*
,则任何没有被显式拒绝的都会被允许。否则,任何没有被允许的都会被拒绝。
您还可以使用 *
允许到所有远程目的地的连接。
配置示例
!*.example.com !192.168.1.0/24 192.168.2.1 *
10.8.3. 以 HTTP 代理模式部署出口路由器 pod
在 HTTP 代理模式 中,出口路由器 pod 作为一个 HTTP 代理在端口 8080
上运行。这个模式只适用于连接到基于 HTTP 或基于 HTTPS 服务的客户端,但通常需要较少的更改就可以使客户端 pod 正常工作。很多程序可以通过设置环境变量来使用 HTTP 代理服务器。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
- 创建出口路由器 pod。
为确保其他 pod 可以查找出口路由器 pod 的 IP 地址,请创建一个服务指向出口路由器 pod,如下例所示:
apiVersion: v1 kind: Service metadata: name: egress-1 spec: ports: - name: http-proxy port: 8080 1 type: ClusterIP selector: name: egress-1
- 1
- 确定
http
端口被设置为8080
。
要将客户端 pod(不是出口代理 Pod)配置为使用 HTTP 代理,设置
http_proxy
或https_proxy
变量:apiVersion: v1 kind: Pod metadata: name: app-1 labels: name: app-1 spec: containers: env: - name: http_proxy value: http://egress-1:8080/ 1 - name: https_proxy value: http://egress-1:8080/ ...
- 1
- 上一步中创建的服务。
注意不需要在所有设置中使用
http
环境变量。如果以上内容没有创建可以正常工作设置,请查阅 pod 中运行的工具或软件的文档。_proxy
和 https_proxy
10.8.4. 其他资源
10.9. 以 DNS 代理模式部署出口路由器 pod
作为集群管理员,您可以将配置为代理流量的出口路由器 pod 部署到指定的 DNS 名称和 IP 地址。
10.9.1. DNS 模式的出口路由器 pod 规格
为 Pod
对象中的一个出口路由器 pod 定义其配置。以下 YAML 描述了在 DNS 模式中配置出口路由器 pod 的字段:
apiVersion: v1 kind: Pod metadata: name: egress-1 labels: name: egress-1 annotations: pod.network.openshift.io/assign-macvlan: "true" 1 spec: initContainers: - name: egress-router image: registry.redhat.io/openshift4/ose-egress-router securityContext: privileged: true env: - name: EGRESS_SOURCE 2 value: <egress-router> - name: EGRESS_GATEWAY 3 value: <egress-gateway> - name: EGRESS_ROUTER_MODE value: dns-proxy containers: - name: egress-router-pod image: registry.redhat.io/openshift4/ose-egress-dns-proxy securityContext: privileged: true env: - name: EGRESS_DNS_PROXY_DESTINATION 4 value: |- ... - name: EGRESS_DNS_PROXY_DEBUG 5 value: "1" ...
- 1
- 在启动
egress-router
容器前,在主网络接口上创建一个 macvlan 网络接口,并将该接口移到 pod 网络命名空间中。您必须把"true"
值包括在引号中。要在主接口以外的网络接口上创建 macvlan 接口,请将注解值设置为该接口的名称。例如:eth1
。 - 2
- 保留给出口路由器 pod 使用的物理网络的 IP 地址。可选:您可以包括子网长度(
/24
后缀),以便正确路由到本地子网。如果没有指定子网长度,则出口路由器只能访问使用EGRESS_GATEWAY
变量指定的主机,且子网上没有其他主机。 - 3
- 值与节点使用的默认网关相同。
- 4
- 指定一个或多个代理目的地列表。
- 5
- 可选:指定输出 DNS 代理日志输出到
stdout
。
10.9.2. 出口目的地配置格式
当路由器以 DNS 代理模式部署时,您会指定一个端口和目标映射列表。目的地可以是 IP 地址,也可以是 DNS 名称。
出口路由器 pod 支持以下格式来指定端口和目的地映射:
- 端口和远程地址
-
您可以使用两个字段格式来指定源端口和目标主机:
<port> <remote_address>
。
主机可以是 IP 地址或 DNS 名称。如果提供了 DNS 名称,DNS 解析会在运行时进行。对于给定主机,代理在连接到目标主机的 IP 地址时连接到目标主机上指定的源端口。
端口和远程地址对示例
80 172.16.12.11 100 example.com
- 端口、远程地址和远程端口
-
您可以使用三字段格式
<port> <remote_address> <remote_port>
指定源端口、目标主机和目的地端口。
三字段格式的行为与两字段版本相同,但目的地端口可能与源端口不同。
端口、远程地址和远程端口示例
8080 192.168.60.252 80 8443 web.example.com 443
10.9.3. 以 DNS 代理模式部署出口路由器 pod
在 DNS 代理模式 中,出口路由器 pod 作为基于 TCP 服务的 DNS 代理运行,将其自身的 IP 地址转换到一个或多个目标 IP 地址。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
- 创建出口路由器 pod。
为出口路由器 pod 创建服务:
创建名为
egress-router-service.yaml
的文件,其包含以下 YAML。将spec.ports
设置为您之前为EGRESS_DNS_PROXY_DESTINATION
环境变量定义的端口列表。apiVersion: v1 kind: Service metadata: name: egress-dns-svc spec: ports: ... type: ClusterIP selector: name: egress-dns-proxy
例如:
apiVersion: v1 kind: Service metadata: name: egress-dns-svc spec: ports: - name: con1 protocol: TCP port: 80 targetPort: 80 - name: con2 protocol: TCP port: 100 targetPort: 100 type: ClusterIP selector: name: egress-dns-proxy
要创建服务,请输入以下命令:
$ oc create -f egress-router-service.yaml
Pod 现在可以连接至此服务。使用保留的出口 IP 地址将其代理到外部服务器的对应端口。
10.9.4. 其他资源
10.10. 从配置映射配置出口路由器 pod 目的地列表
作为集群管理员,您可以定义一个 ConfigMap
对象来指定出口路由器 pod 的目标映射。配置的特定格式取决于出口路由器 pod 的类型。有关格式的详情,请参阅特定出口路由器 pod 的文档。
10.10.1. 使用配置映射配置出口路由器目的地映射
对于大量或经常更换的目标映射集合,您可以使用配置映射来外部维护列表。这种方法的优点是可将编辑配置映射的权限委派给没有 cluster-admin
特权的用户。因为出口路由器 pod 需要特权容器,没有 cluster-admin
特权的用户无法直接编辑 pod 定义。
配置映射更改时,出口路由器 pod 不会自动更新。您必须重启出口路由器 pod 来获得更新。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
创建包含出口路由器 pod 映射数据的文件,如下例所示:
# Egress routes for Project "Test", version 3 80 tcp 203.0.113.25 8080 tcp 203.0.113.26 80 8443 tcp 203.0.113.26 443 # Fallback 203.0.113.27
您可以在这个文件中放入空白行和评论。
从文件创建
ConfigMap
对象:$ oc delete configmap egress-routes --ignore-not-found
$ oc create configmap egress-routes \ --from-file=destination=my-egress-destination.txt
在以前的版本中,
egress-routes
值是要创建的ConfigMap
对象的名称,my-egress-destination.txt
是数据从中读取的文件的名称。创建出口路由器 pod 定义,并为环境片段中的
EGRESS_DESTINATION
字段指定configMapKeyRef
小节:... env: - name: EGRESS_DESTINATION valueFrom: configMapKeyRef: name: egress-routes key: destination ...
10.10.2. 其他资源
10.11. 为项目启用多播
10.11.1. 关于多播
通过使用 IP 多播,数据可同时广播到许多 IP 地址。
目前,多播最适用于低带宽协调或服务发现。它不是一个高带宽解决方案。
默认情况下,OpenShift Container Platform pod 之间多播流量被禁用。如果使用 OpenShift SDN 默认 Container Network Interface (CNI) 网络供应商,可以根据每个项目启用多播。
以 networkpolicy
隔离模式使用 OpenShift SDN 网络插件时:
-
pod 发送的多播数据包将传送到项目中的所有其他 pod,而无需考虑
NetworkPolicy
对象。即使在无法通过单播通信时,Pod 也能通过多播进行通信。 -
一个项目中的 pod 发送的多播数据包不会传送到任何其他项目中的 pod,即使存在允许项目间通信的
NetworkPolicy
对象。
以 multitenant
隔离模式使用 OpenShift SDN 网络插件时:
- pod 发送的多播数据包将传送到项目中的所有其他 pod。
- 只有在各个项目接合在一起并且每个接合的项目上都启用了多播时,一个项目中的 pod 发送的多播数据包才会传送到其他项目中的 pod。
10.11.2. 启用 pod 间多播
您可以为项目启用 pod 间多播。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
运行以下命令,为项目启用多播。使用您要启用多播的项目的名称替换
<namespace>
。$ oc annotate netnamespace <namespace> \ netnamespace.network.openshift.io/multicast-enabled=true
验证步骤
要验证项目是否启用了多播,请完成以下步骤:
将您的当前项目更改为启用多播的项目。使用项目名替换
<project>
。$ oc project <project>
创建 pod 以作为多播接收器:
$ cat <<EOF| oc create -f - apiVersion: v1 kind: Pod metadata: name: mlistener labels: app: multicast-verify spec: containers: - name: mlistener image: registry.access.redhat.com/ubi8 command: ["/bin/sh", "-c"] args: ["dnf -y install socat hostname && sleep inf"] ports: - containerPort: 30102 name: mlistener protocol: UDP EOF
创建 pod 以作为多播发送器:
$ cat <<EOF| oc create -f - apiVersion: v1 kind: Pod metadata: name: msender labels: app: multicast-verify spec: containers: - name: msender image: registry.access.redhat.com/ubi8 command: ["/bin/sh", "-c"] args: ["dnf -y install socat && sleep inf"] EOF
启动多播监听程序。
获得 Pod 的 IP 地址:
$ POD_IP=$(oc get pods mlistener -o jsonpath='{.status.podIP}')
要启动多播监听程序,在新的终端窗口或标签页里输入以下命令:
$ oc exec mlistener -i -t -- \ socat UDP4-RECVFROM:30102,ip-add-membership=224.1.0.1:$POD_IP,fork EXEC:hostname
启动多播传输。
获取 pod 网络 IP 地址范围:
$ CIDR=$(oc get Network.config.openshift.io cluster \ -o jsonpath='{.status.clusterNetwork[0].cidr}')
要发送多播信息,请输入以下命令:
$ oc exec msender -i -t -- \ /bin/bash -c "echo | socat STDIO UDP4-DATAGRAM:224.1.0.1:30102,range=$CIDR,ip-multicast-ttl=64"
如果多播正在工作,则上一个命令会返回以下输出:
mlistener
10.12. 为项目禁用多播
10.12.1. 禁用 pod 间多播
您可以为项目禁用 pod 间多播。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
运行以下命令来禁用多播:
$ oc annotate netnamespace <namespace> \ 1 netnamespace.network.openshift.io/multicast-enabled-
- 1
- 您要禁用多播的项目的
namespace
。
10.13. 使用 OpenShift SDN 配置网络隔离
将集群配置为使用 OpenShift SDN CNI 插件的多租户隔离模式时,每个项目会被默认隔离。在多租户隔离模式下,不同项目中的 pod 或服务间不允许网络流量。
您可以通过两种方式更改项目的多租户隔离行为:
- 您可以接合一个或多个项目,允许不同项目中的 pod 和服务间的网络流量。
- 您可以对项目禁用网络隔离。它可全局访问,接受所有其他项目中的 pod 和服务的网络流量。可全局访问的项目可以访问所有其他项目中的 pod 和服务。
10.13.1. 先决条件
- 您必须将集群配置为以多租户隔离模式使用 OpenShift SDN Container Network Interface (CNI) 插件。
10.13.2. 接合项目
您可以接合两个或多个项目,以允许不同项目中的 Pod 和服务间的网络流量。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
使用以下命令,将项目接合到现有项目网络中:
$ oc adm pod-network join-projects --to=<project1> <project2> <project3>
另外,除了指定具体的项目名称,也可以使用
--selector=<project_selector>
选项来基于关联标签指定项目。可选:运行以下命令来查看您接合在一起的 Pod 网络:
$ oc get netnamespaces
在 NETID 列中,同一 Pod 网络中的项目具有相同的网络 ID。
10.13.3. 隔离项目
您可以隔离项目,使其他项目中的 pod 和服务无法访问这个项目中的 pod 和服务。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
要隔离集群中的项目,请运行以下命令:
$ oc adm pod-network isolate-projects <project1> <project2>
另外,除了指定具体的项目名称,也可以使用
--selector=<project_selector>
选项来基于关联标签指定项目。
10.13.4. 对项目禁用网络隔离
您可以对项目禁用网络隔离。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
对项目运行以下命令:
$ oc adm pod-network make-projects-global <project1> <project2>
另外,除了指定具体的项目名称,也可以使用
--selector=<project_selector>
选项来基于关联标签指定项目。
10.14. 配置 kube-proxy
Kubernetes 网络代理 (kube-proxy) 在每个节点上运行,并由 Cluster Network Operator (CNO) 管理。kube-proxy 维护网络规则,以转发与服务关联的端点的连接。
10.14.1. 关于 iptables 规则同步
同步周期决定 Kubernetes 网络代理 (kube-proxy) 在节点上同步 iptables 规则的频率。
同步在发生以下事件之一时开始:
- 发生某一事件,例如服务或端点添加到集群中或从集群中删除。
- 距最后一次同步的时间已超过为 kube-proxy 定义的同步周期。
10.14.2. kube-proxy 配置参数
您可以修改以下 kubeProxyConfig
参数。
由于 OpenShift Container Platform 4.3 及更高版本中引进了性能上的改进,现在不再需要调整 iptablesSyncPeriod
参数。
参数 | 描述 | 值 | 默认值 |
---|---|---|---|
|
|
一个时间间隔,如 |
|
|
刷新 |
一个时间间隔,如 |
|
10.14.3. 修改 kube-proxy 配置
您可以为集群修改 Kubernetes 网络代理配置。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
使用
cluster-admin
角色登录正在运行的集群。
流程
运行以下命令来编辑
Network.operator.openshift.io
自定义资源(CR):$ oc edit network.operator.openshift.io cluster
利用您对 kube-proxy 配置的更改修改 CR 中的
kubeProxyConfig
参数,如以下示例 CR 中所示:apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: kubeProxyConfig: iptablesSyncPeriod: 30s proxyArguments: iptables-min-sync-period: ["30s"]
保存文件并退出文本编辑器。
保存文件并退出编辑器时,
oc
命令会验证其语法。如果您的修改含有语法错误,编辑器会打开该文件并显示错误消息。运行以下命令来确认配置更新:
$ oc get networks.operator.openshift.io -o yaml
输出示例
apiVersion: v1 items: - apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: clusterNetwork: - cidr: 10.128.0.0/14 hostPrefix: 23 defaultNetwork: type: OpenShiftSDN kubeProxyConfig: iptablesSyncPeriod: 30s proxyArguments: iptables-min-sync-period: - 30s serviceNetwork: - 172.30.0.0/16 status: {} kind: List
可选:运行以下命令,确认 Cluster Network Operator 已接受配置更改:
$ oc get clusteroperator network
输出示例
NAME VERSION AVAILABLE PROGRESSING DEGRADED SINCE network 4.1.0-0.9 True False False 1m
成功应用配置更新后,
AVAILABLE
字段为True
。
第 11 章 OVN-Kubernetes 默认 CNI 网络供应商
11.1. 关于 OVN-Kubernetes 默认 Container Network Interface (CNI) 网络供应商
OpenShift Container Platform 集群在 pod 和服务网络中使用虚拟网络。OVN-Kubernetes Container Network Interface (CNI) 插件是默认集群网络的一个网络供应商。
11.1.1. OVN-Kubernetes 特性
OVN-Kubernetes 默认 Container Network Interface (CNI) 网络供应商实现以下功能:
- 使用 OVN(开源虚拟网络)管理网络流量。OVN 是一个有社区开发、没有与特定厂商绑定的网络虚拟化解决方案。
- 实现 Kubernetes 网络策略支持,包括入口和出口规则。
- 使用 Geneve(通用网络虚拟化封装)协议而不是 VXLAN 在节点间创建覆盖网络。
11.1.2. 支持的默认 CNI 网络供应商功能列表
OpenShift Container Platform 为默认的 Container Network Interface (CNI) 网络供应商提供两个支持的选择:OpenShift SDN 和 OVN-Kubernetes。下表总结了这两个网络供应商当前支持的功能:
功能 | OVN-Kubernetes [1] | OpenShift SDN |
---|---|---|
出口 IP | 不支持 | 支持 |
出口防火墙 [2] | 不支持 | 支持 |
出口路由器 | 不支持 | 支持 |
Kubernetes 网络策略 | 支持 | 部分支持 [3] |
多播 | 支持 | 支持 |
- 当前仅在 OpenShift Container Platform 4.4 中作为技术预览功能提供。
- 在 OpenShift SDN 中,出口防火墙也称为出口网络策略。这和网络策略出口不同。
-
不支持出口规则和一些
ipBlock
规则。
11.1.3. OVN-Kubernetes 公开的指标
OVN-Kubernetes 默认 Container Network Interface (CNI) 网络供应商会公开某些特定的指标数据,供基于 Prometheus 的 OpenShift Container Platform 集群监控堆栈使用。
名称 | 描述 |
---|---|
| 在 pod 被创建和 pod 被 OVN-Kubernetes 注解之间会有一个延迟。这个延迟时间越长,等待 pod 可用于网络连接的时间就越长。 |
11.2. 为项目启用多播
Open Virtual Networking (OVN) Kubernetes 网络插件只是技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
如需 OVN 技术预览支持范围的更多信息,请参阅 https://access.redhat.com/articles/4380121。
在 OpenShift Container Platform 4.4 中,存在一个程序错误。它会造成同一命名空间中的分配给不同节点的 Pod 无法通过多播进行通信。如需更多信息,请参阅 BZ#1843695。
11.2.1. 关于多播
通过使用 IP 多播,数据可同时广播到许多 IP 地址。
目前,多播最适用于低带宽协调或服务发现。它不是一个高带宽解决方案。
默认情况下,OpenShift Container Platform pod 之间多播流量被禁用。如果使用 OVN-Kubernetes 默认 Container Network Interface (CNI) 网络供应商,则可以根据每个项目启用多播。
11.2.2. 启用 pod 间多播
您可以为项目启用 pod 间多播。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
运行以下命令,为项目启用多播。使用您要启用多播的项目的名称替换
<namespace>
。$ oc annotate namespace <namespace> \ k8s.ovn.org/multicast-enabled=true
验证步骤
要验证项目是否启用了多播,请完成以下步骤:
将您的当前项目更改为启用多播的项目。使用项目名替换
<project>
。$ oc project <project>
创建 pod 以作为多播接收器:
$ cat <<EOF| oc create -f - apiVersion: v1 kind: Pod metadata: name: mlistener labels: app: multicast-verify spec: containers: - name: mlistener image: registry.access.redhat.com/ubi8 command: ["/bin/sh", "-c"] args: ["dnf -y install socat hostname && sleep inf"] ports: - containerPort: 30102 name: mlistener protocol: UDP EOF
创建 pod 以作为多播发送器:
$ cat <<EOF| oc create -f - apiVersion: v1 kind: Pod metadata: name: msender labels: app: multicast-verify spec: containers: - name: msender image: registry.access.redhat.com/ubi8 command: ["/bin/sh", "-c"] args: ["dnf -y install socat && sleep inf"] EOF
启动多播监听程序。
获得 Pod 的 IP 地址:
$ POD_IP=$(oc get pods mlistener -o jsonpath='{.status.podIP}')
要启动多播监听程序,在新的终端窗口或标签页里输入以下命令:
$ oc exec mlistener -i -t -- \ socat UDP4-RECVFROM:30102,ip-add-membership=224.1.0.1:$POD_IP,fork EXEC:hostname
启动多播传输。
获取 pod 网络 IP 地址范围:
$ CIDR=$(oc get Network.config.openshift.io cluster \ -o jsonpath='{.status.clusterNetwork[0].cidr}')
要发送多播信息,请输入以下命令:
$ oc exec msender -i -t -- \ /bin/bash -c "echo | socat STDIO UDP4-DATAGRAM:224.1.0.1:30102,range=$CIDR,ip-multicast-ttl=64"
如果多播正在工作,则上一个命令会返回以下输出:
mlistener
11.3. 为项目禁用多播
Open Virtual Networking (OVN) Kubernetes 网络插件只是技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
如需 OVN 技术预览支持范围的更多信息,请参阅 https://access.redhat.com/articles/4380121。
11.3.1. 禁用 pod 间多播
您可以为项目禁用 pod 间多播。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
您必须作为
cluster-admin
角色用户登录集群。
流程
运行以下命令来禁用多播:
$ oc annotate namespace <namespace> \ 1 k8s.ovn.org/multicast-enabled-
- 1
- 您要禁用多播的项目的
namespace
。
第 12 章 配置路由
12.1. 路由配置
12.1.1. 配置路由超时
如果您的服务需要低超时(满足服务级别可用性 (SLA) 目的)或高超时(具有慢速后端的情况),您可以为现有路由配置默认超时。
先决条件
- 您需要在运行的集群中部署了 Ingress Controller。
流程
使用
oc annotate
命令,为路由添加超时:$ oc annotate route <route_name> \ --overwrite haproxy.router.openshift.io/timeout=<timeout><time_unit> 1
- 1
- 支持的时间单位是微秒 (us)、毫秒 (ms)、秒钟 (s)、分钟 (m)、小时 (h)、或天 (d)。
以下示例在名为
myroute
的路由上设置两秒的超时:$ oc annotate route myroute --overwrite haproxy.router.openshift.io/timeout=2s
12.1.2. 启用 HTTP 严格传输安全性
HTTP 严格传输安全性 (HSTS) 策略是一种安全增强,可确保主机上只允许 HTTPS 流量。所有 HTTP 请求都会默认丢弃。这可用于确保与网站安全交互,或提供安全应用程序让用户受益。
当 HSTS 启用时,HSTS 会添加一个 Strict Transport Security 标头到站点的 HTTPS 响应。您可以在要重定向的路由中使用 insecureEdgeTerminationPolicy
值,以将 HTTP 发送到 HTTPS。但是,当启用 HSTS 时,客户端会在发送请求前将所有来自 HTTP URL 的请求更改为 HTTPS,从而消除对重定向的需求。客户端不需要支持此功能,而且也可通过设置 max-age=0
来禁用。
HSTS 仅适用于安全路由(边缘终止或重新加密)。其配置在 HTTP 或传递路由上无效。
流程
要在路由上启用 HSTS,请将
haproxy.router.openshift.io/hsts_header
值添加到边缘终止或重新加密路由:apiVersion: v1 kind: Route metadata: annotations: haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload 1 2 3
- 1
max-age
是唯一的必要参数。它会测量 HSTS 策略生效的时间长度,以秒为单位。每当从主机收到含有 HSTS 标头的响应时,客户端会更新max-age
。如果max-age
超时,客户端会丢弃该策略。- 2
includeSubDomains
是可选的。含有此参数时,它会告知客户端应像主机一样对待主机上的所有子域。- 3
preload
是可选的。当max-age
大于 0 时,在haproxy.router.openshift.io/hsts_header
中包含preload
会使外部服务将这个站点包括在 HSTS 预加载列表中。例如,Google 等站点可以构造设有preload
的站点的列表。浏览器可以使用这些列表来决定哪些站点可通过 HTTPS 进行通信,然后再与站点交互。如果没有设置preload
,浏览器必须通过 HTTPS 与站点交互才能获取该标头。
12.1.3. 吞吐量问题错误排解
有时,通过 OpenShift Container Platform 部署的应用程序可能会导致网络吞吐量问题,如特定服务间的延迟异常高。
如果 pod 日志未能揭示造成问题的原因,请使用以下方法分析性能问题:
使用 ping 或 tcpdump 等数据包分析器,分析 pod 与其节点之间的流量。
例如,在每个 pod 上运行 tcpdump 工具,同时重现导致问题的行为。检查两端的捕获信息,以便比较发送和接收时间戳来分析与 pod 往来的流量的延迟。如果节点接口被其他 pod、存储设备或者数据平面的流量过载,则 OpenShift Container Platform 中可能会出现延迟。
$ tcpdump -s 0 -i any -w /tmp/dump.pcap host <podip 1> && host <podip 2> 1
- 1
podip
是 pod 的 IP 地址。运行oc get pod <pod_name> -o wide
命令来获取 pod 的 IP 地址。
tcpdump 在
/tmp/dump.pcap
中生成一个包含这两个 pod 间所有流量的文件。最好在运行分析器后立即重现问题,并在问题重现完成后马上停止分析器,从而尽量减小文件的大小。您还可以通过以下命令,在节点之间运行数据包分析器(从考量范围中剔除 SDN):$ tcpdump -s 0 -i any -w /tmp/dump.pcap port 4789
使用 iperf 等带宽测量工具来测量数据流吞吐量和 UDP 吞吐量。先从 pod 运行该工具,再从节点运行,以此来查找瓶颈。
- 如需有关安装和使用 iperf 的信息,请参阅此红帽解决方案。
12.1.4. 使用 Cookie 来保持路由有状态性
OpenShift Container Platform 提供粘性会话,通过确保所有流量都到达同一端点来实现有状态应用程序流量。但是,如果端点 pod 以重启、扩展或更改配置的方式被终止,这种有状态性可能会消失。
OpenShift Container Platform 可以使用 Cookie 来配置会话持久性。Ingress Controller 选择一个端点来处理任何用户请求,并为会话创建一个 Cookie。Cookie 在响应请求时返回,用户则通过会话中的下一请求发回 Cookie。Cookie 告知 Ingress Controller 哪个端点正在处理会话,确保客户端请求使用这个 Cookie 使请求路由到同一个 pod。
12.1.4.1. 使用 Cookie 标注路由
您可以设置 Cookie 名称来覆盖为路由自动生成的默认名称。这样,接收路由流量的应用程序就能知道 Cookie 名称。通过删除 Cookie,它可以强制下一请求重新选择端点。因此,如果服务器过载,它会尝试从客户端中删除请求并重新分发它们。
流程
使用所需 Cookie 名称标注路由:
$ oc annotate route <route_name> router.openshift.io/<cookie_name>="-<cookie_annotation>"
例如,使用注解
my_cookie_annotation
将 Cookie 名称my_cookie
标注为my_route
:$ oc annotate route my_route router.openshift.io/my_cookie="-my_cookie_annotation"
保存 Cookie,再访问路由:
$ curl $my_route -k -c /tmp/my_cookie
12.1.5. 特定于路由的注解
Ingress Controller 可以为它公开的所有路由设置默认选项。单个路由可以通过在其注解中提供特定配置来覆盖这些默认设置。
变量 | 描述 | 默认的环境变量 |
---|---|---|
|
设置负载平衡算法。可用选项包括 |
passthrough 路由 使用 |
|
禁用使用 cookie 来跟踪相关连接。如果设置为 | |
| 指定一个可选的、用于此路由的 cookie。名称只能包含大写字母和小写字母、数字、"_" 和 "-"。默认为路由的内部密钥进行哈希处理。 | |
| 设置路由器支持的 pod 允许的最大连接数。注意:如果存在多个 pod,则每个 pod 都可允许这里设置的连接数量。但是,如果有多个路由器,它们之间没有协调关系,每个路由器都可能会多次连接。如果没有设置,或者将其设定为 0,则没有限制。 | |
|
设置 | |
| 限制一个 IP 地址共享的并行 TCP 连接数。 | |
| 限制 IP 地址可以发出 HTTP 请求的速率。 | |
| 限制 IP 地址可以进行 TCP 连接的速率。 | |
| 为路由设定服务器端超时。(TimeUnits) |
|
| 为后端健康检查设定间隔。(TimeUnits) |
|
| 为路由设置白名单。白名单是以空格分开的 IP 地址和 CIDR 范围列表,用来代表批准的源地址。来自白名单以外的 IP 地址的请求会被丢弃。 | |
| 为 edge terminated 或 re-encrypt 路由设置 Strict-Transport-Security 标头。 |
环境变量不能编辑。
设置自定义超时的路由
apiVersion: v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/timeout: 5500ms 1
...
- 1
- 使用 HAProxy 支持的时间单位(
us
,ms
,s
,m
,h
,d
)指定新的超时时间。如果没有提供时间单位,ms
会被默认使用。
如果为 passthrough 路由设置的服务器端的超时值太低,则会导致 WebSocket 连接在那个路由上经常出现超时的情况。
只允许一个特定 IP 地址的路由
metadata: annotations: haproxy.router.openshift.io/ip_whitelist: 192.168.1.10
允许多个 IP 地址的路由
metadata: annotations: haproxy.router.openshift.io/ip_whitelist: 192.168.1.10 192.168.1.11 192.168.1.12
允许 IP 地址 CIDR 网络的路由
metadata: annotations: haproxy.router.openshift.io/ip_whitelist: 192.168.1.0/24
允许 IP 地址和 IP 地址 CIDR 网络的路由
metadata: annotations: haproxy.router.openshift.io/ip_whitelist: 180.5.61.153 192.168.1.0/24 10.0.0.0/8
12.1.6. 配置路由准入策略
管理员和应用程序开发人员可在多个命名空间中运行具有相同域名的应用程序。这是针对多个团队开发的、在同一个主机名上公开的微服务的机构。
只有在命名空间间有信任的集群才会启用跨命名空间之间的声明,否则恶意用户可能会接管主机名。因此,默认的准入策略不允许在命名空间间声明主机名。
先决条件
- 必须具有集群管理员权限。
流程
使用以下命令编辑
ingresscontroller
资源变量的.spec.
routeAdmission 字段:$ oc -n openshift-ingress-operator patch ingresscontroller/default --patch '{"spec":{"routeAdmission":{"namespaceOwnership":"InterNamespaceAllowed"}}}' --type=merge
Ingress 控制器配置参数
spec: routeAdmission: namespaceOwnership: InterNamespaceAllowed ...
12.2. 安全路由
以下部分介绍如何使用自定义证书创建重新加密和边缘路由。
如果您在 Microsoft Azure 中创建通过公共端点的路由,则资源名称会受到限制。您不能创建使用某些词语的资源。如需 Azure 限制词语的列表,请参阅 Azure 文档中的解决预留资源名称错误。
12.2.1. 使用自定义证书创建重新加密路由
您可以通过 oc create route
命令,使用重新加密 TLS 终止和自定义证书配置安全路由。
先决条件
- 您必须在 PEM 编码文件中有一个证书/密钥对,其中的证书对路由主机有效。
- 您可以在 PEM 编码文件中有一个单独的 CA 证书来补全证书链。
- 您必须在 PEM 编码文件中有单独的目标 CA 证书。
- 您必须具有要公开的服务。
不支持密码保护的密钥文件。要从密钥文件中删除密码,使用以下命令:
$ openssl rsa -in password_protected_tls.key -out tls.key
流程
此流程使用自定义证书和重新加密 TLS 终止创建 Route
资源。以下步骤假定证书/密钥对位于当前工作目录下的 tls.crt
和 tls.key
文件中。您还必须指定一个目标 CA 证书,使 Ingress Controller 信任服务的证书。您也可以根据需要指定 CA 证书来补全证书链。替换 tls.crt
、tls.key
、cacert.crt
和(可选)ca.crt
的实际路径名称。替换您要为 frontend
公开的 Service
资源的名称。使用正确的主机名替换 www.example.com
。
使用重新加密 TLS 终止和自定义证书,创建安全
Route
资源:$ oc create route reencrypt --service=frontend --cert=tls.crt --key=tls.key --dest-ca-cert=destca.crt --ca-cert=ca.crt --hostname=www.example.com
如果您检查生成的
Route
资源,它应该类似于如下:安全路由 YAML 定义
apiVersion: v1 kind: Route metadata: name: frontend spec: host: www.example.com to: kind: Service name: frontend tls: termination: reencrypt key: |- -----BEGIN PRIVATE KEY----- [...] -----END PRIVATE KEY----- certificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- caCertificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- destinationCACertificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE-----
如需了解更多选项,请参阅
oc create route reencrypt --help
。
12.2.2. 使用自定义证书创建边缘路由
您可以通过 oc create route
命令,使用边缘 TLS 终止和自定义证书配置安全路由。使用边缘路由时,Ingress Controller 在将流量转发到目标 pod 之前终止 TLS 加密。该路由指定了 Ingress Controller 用于路由的 TLS 证书和密钥。
先决条件
- 您必须在 PEM 编码文件中有一个证书/密钥对,其中的证书对路由主机有效。
- 您可以在 PEM 编码文件中有一个单独的 CA 证书来补全证书链。
- 您必须具有要公开的服务。
不支持密码保护的密钥文件。要从密钥文件中删除密码,使用以下命令:
$ openssl rsa -in password_protected_tls.key -out tls.key
流程
此流程使用自定义证书和边缘 TLS 终止创建 Route
资源。以下步骤假定证书/密钥对位于当前工作目录下的 tls.crt
和 tls.key
文件中。您也可以根据需要指定 CA 证书来补全证书链。替换 tls.crt
、tls.key
和(可选)ca.crt
的实际路径名称。替换您要为 frontend
公开的服务名称。使用正确的主机名替换 www.example.com
。
使用边缘 TLS 终止和自定义证书,创建安全
Route
资源:$ oc create route edge --service=frontend --cert=tls.crt --key=tls.key --ca-cert=ca.crt --hostname=www.example.com
如果您检查生成的
Route
资源,它应该类似于如下:安全路由 YAML 定义
apiVersion: v1 kind: Route metadata: name: frontend spec: host: www.example.com to: kind: Service name: frontend tls: termination: edge key: |- -----BEGIN PRIVATE KEY----- [...] -----END PRIVATE KEY----- certificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- caCertificate: |- -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE-----
如需了解更多选项,请参阅
oc create route edge --help
。
第 13 章 配置集群入口流量
13.1. 集群入口流量配置概述
OpenShift Container Platform 提供了以下从集群外部与集群中运行的服务进行通信的方法。
建议采用以下方法,它们按顺序或首选程度排列:
- 如果您有 HTTP/HTTPS,请使用 Ingress Controller。
- 如果您有 HTTPS 之外的 TLS 加密协议,比如对于使用 SNI 标头的 TLS,请使用 Ingress Controller。
-
否则,请使用负载均衡器、外部 IP 或
NodePort
。
方法 | 用途 |
---|---|
允许访问 HTTP/HTTPS 流量和 HTTPS 以外的 TLS 加密协议(例如,使用 SNI 标头的 TLS)。 | |
允许流量通过从池分配的 IP 地址传到非标准端口。 | |
允许流量通过特定的 IP 地址传到非标准端口。 | |
在集群中的所有节点上公开某一服务。 |
13.2. 为服务配置 ExternalIP
作为集群管理员,您可以指定可向集群中服务发送流量的集群外部 IP 地址块。
这个功能通常最适用于在裸机硬件上安装的集群。
13.2.1. 先决条件
- 您的网络基础架构必须将外部 IP 地址的流量路由到集群。
13.2.2. 关于 ExternalIP
对于非云环境,OpenShift Container Platform 支持通过 ExternalIP 工具将外部 IP 地址分配给 Service
对象的 spec.externalIPs
字段。这会公开分配给服务的额外虚拟 IP 地址,这些地址可能不在为集群定义的服务网络之外。使用外部 IP 功能配置的服务,和带有 type=NodePort
的服务相似,允许您将流量定向到本地节点以进行负载平衡。
您必须配置网络基础架构,以确保您定义的外部 IP 地址块路由到集群。
OpenShift Container Platform 通过添加以下功能来扩展 Kubernetes 中的 ExternalIP 功能:
- 通过可配置策略对使用外部 IP 地址的限制
- 根据请求自动将外部 IP 地址分配给服务
默认情况下,只有具有 cluster-admin
特权的用户才能创建一个 Service
对象,并将 spec.externalIPs[]
设置为外部 IP 地址块中定义的 IP 地址。
默认情况下禁用,使用 ExternalIP 功能可能会造成安全隐患,因为集群内到一个外部 IP 地址的流量会定向到那个服务。这可让集群用户拦截用于外部资源的敏感流量。
这个功能只在非云部署中被支持。对于云部署,使用负载均衡器服务自动部署云负载均衡器,以服务端点为目标。
您可以使用以下方法分配外部 IP 地址:
- 自动分配一个外部 IP
-
当创建了一个带有
spec.type=LoadBalancer
设置的Service
对象时,OpenShift Container Platform 会从autoAssignCIDRs
CIDR 块中自动为spec.externalIPs[]
分配一个 IP 地址。在本例中,OpenShift Container Platform 实现了负载均衡器服务类型的非云版本,并为服务分配 IP 地址。默认情况下,自动分配被禁用,且必须由集群管理员配置,如以下部分所述。 - 手动分配外部 IP
-
OpenShift Container Platform 在创建
Service
对象时使用分配给spec.externalIPs[]
数组的 IP 地址。您不能指定已经被其他服务使用的 IP 地址。
13.2.2.1. 配置 ExternalIP
在 OpenShift Container Platform 中使用外部 IP 地址取决于名为 cluster
的 Network.config.openshift.io
CR 中的以下字段:
-
spec.externalIP.autoAssignCIDRs
定义了一个负载均衡器在为服务选择外部 IP 地址时使用的 IP 地址块。OpenShift Container Platform 只支持单个 IP 地址块进行自动分配。当手工为服务分配 ExternalIPs 时,这比管理有限共享 IP 地址的端口空间更简单。如果启用了自动分配,则会为带有spec.type=LoadBalancer
的Service
对象分配一个外部 IP 地址。 -
在手动指定 IP 地址时,
spec.externalIP.policy
定义了允许的 IP 地址块。OpenShift Container Platform 不会将策略规则应用到spec.externalIP.autoAssignCIDRs
定义的 IP 地址块。
如果路由正确,来自配置的外部 IP 地址块的外部流量可以通过服务公开的任何 TCP 或 UDP 端口访问服务端点。
您必须确保分配的 IP 地址块在集群中的一个或多个节点上终止。
OpenShift Container Platform 支持自动和手动分配 IP 地址,并且保证每个地址都被分配到最多一个服务。这样可保证,无论由其他服务公开的端口是什么,每个服务都可以公开选择的端口。
要使用 OpenShift Container Platform 中由 autoAssignCIDRs
定义 的 IP 地址块,您必须为主机网络配置必要的 IP 地址分配和路由。
以下 YAML 描述了配置了外部 IP 地址的服务:
带有 spec.externalIPs[]
设置的示例 Service
对象
apiVersion: v1 kind: Service metadata: name: http-service spec: clusterIP: 172.30.163.110 externalIPs: - 192.168.132.253 externalTrafficPolicy: Cluster ports: - name: highport nodePort: 31903 port: 30102 protocol: TCP targetPort: 30102 selector: app: web sessionAffinity: None type: LoadBalancer status: loadBalancer: ingress: - ip: 192.168.132.253
13.2.2.2. 对外部 IP 地址分配的限制
作为集群管理员,您可以指定允许和拒绝的 IP 地址块。
您可以使用一个通过指定 spec.ExternalIP.policy
字段来定义的一个policy
对象来配置 IP 地址策略。策略对象有以下内容:
{ "policy": { "allowedCIDRs": [], "rejectedCIDRs": [] } }
在配置策略限制时,会应用以下规则:
-
如果设置了
policy={}
,那么创建带有spec.ExternalIPs[]
设置的Service
对象将失败。这是 OpenShift Container Platform 的默认设置。 -
如果设置了
policy=null
,则允许创建一个将spec.ExternalIPs[]
设置为任何 IP 地址的Service
对象。 如果设置了
policy
,并且设置了policy.allowedCIDRs[]
或policy.rejectedCIDRs[]
,则应用以下规则:-
如果同时设置了
allowedCIDRs[]
和rejectedCIDRs[]
,则allowedCIDRs[]
的设置高于rejectedCIDRs[]
。 -
如果设置了
allowedCIDRs[]
,只有在允许指定的 IP 地址时,创建带有spec.ExternalIPs[]
的Service
对象才能成功。 -
如果设置了
rejectedCIDRs[]
,只有在指定的 IP 地址未被拒绝时,创建带有spec.ExternalIPs[]
的Service
对象才能成功。
-
如果同时设置了
13.2.2.3. 策略对象示例
下面的例子演示了几个不同的策略配置。
在以下示例中,策略会防止 OpenShift Container Platform 使用指定的外部 IP 地址创建任何服务:
拒绝为
Service
对象spec.externalIPs[]
指定的任何值的策略示例apiVersion: config.openshift.io/v1 kind: Network metadata: name: cluster spec: externalIP: policy: {} ...
在以下示例中,设置了
allowedCIDRs
和rejectedCIDRs
字段。包括允许和拒绝 CIDR 块的策略示例
apiVersion: config.openshift.io/v1 kind: Network metadata: name: cluster spec: externalIP: policy: allowedCIDRs: - 172.16.66.10/23 rejectedCIDRs: - 172.16.66.10/24 ...
在以下示例中,
policy
被设置为null
。如果设为null
,则通过输入oc get network.config.openshift.io -o yaml
来检查配置对象时,policy
项不会出现在输出中。允许为
Service
对象spec.externalIPs[]
指定的任何值的示例策略apiVersion: config.openshift.io/v1 kind: Network metadata: name: cluster spec: externalIP: policy: null ...
13.2.3. ExternalIP 地址块配置
ExternalIP 地址块的配置由名为 cluster
的网络自定义资源(CR)定义。Network CR 是 config.openshift.io
API 组的一部分。
在集群安装过程中,Cluster Version Operator(CVO)会自动创建一个名为 cluster
的网络 CR。不支持创建此类型的任何其他 CR 对象。
以下 YAML 描述了 ExternalIP 配置:
network.config.openshift.io CR 名为 cluster
apiVersion: config.openshift.io/v1 kind: Network metadata: name: cluster spec: externalIP: autoAssignCIDRs: [] 1 policy: 2 ...
以下 YAML 描述了 policy
小节的字段:
network.config.openshift.io policy
小节
policy: allowedCIDRs: [] 1 rejectedCIDRs: [] 2
外部 IP 配置示例
以下示例中显示了外部 IP 地址池的一些可能配置:
以下 YAML 描述了启用自动分配外部 IP 地址的配置:
带有
spec.externalIP.autoAssignCIDRs
的配置示例apiVersion: config.openshift.io/v1 kind: Network metadata: name: cluster spec: ... externalIP: autoAssignCIDRs: - 192.168.132.254/29
以下 YAML 为允许的和被拒绝的 CIDR 范围配置策略规则:
带有
spec.externalIP.policy
的示例配置apiVersion: config.openshift.io/v1 kind: Network metadata: name: cluster spec: ... externalIP: policy: allowedCIDRs: - 192.168.132.0/29 - 192.168.132.8/29 rejectedCIDRs: - 192.168.132.7/32
13.2.4. 为集群配置外部 IP 地址块
作为集群管理员,可以配置以下 ExternalIP 设置:
-
OpenShift Container Platform 用来自动填充
Service
对象的spec.clusterIP
字段的 ExternalIP 地址块。 -
用于限制可手动分配给
Service
对象的spec.clusterIP
数组的 IP 地址的策略对象。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
使用具有
cluster-admin
角色的用户访问集群。
流程
可选: 要显示当前的外部 IP 配置,请输入以下命令:
$ oc describe networks.config cluster
要编辑配置,请输入以下命令:
$ oc edit networks.config cluster
修改 ExternalIP 配置,如下例所示:
apiVersion: config.openshift.io/v1 kind: Network metadata: name: cluster spec: ... externalIP: 1 ...
- 1
- 指定
externalIP
小节的配置。
要确认更新的 ExternalIP 配置,请输入以下命令:
$ oc get networks.config cluster -o go-template='{{.spec.externalIP}}{{"\n"}}'
13.2.5. 后续步骤
13.3. 使用 Ingress Controller 配置集群入口流量
OpenShift Container Platform 提供了从集群外部与集群中运行的服务进行通信的方法。此方法使用了 Ingress Controller。
13.3.1. 使用 Ingress Controller 和路由
Ingress Operator 管理 Ingress Controller 和通配符 DNS。
使用 Ingress Controller 是允许从外部访问 OpenShift Container Platform 集群的最常用方法。
Ingress Controller 配置为接受外部请求并根据配置的路由进行代理。这仅限于 HTTP、使用 SNI 的 HTTPS 以及使用 SNI 的 TLS,对于通过使用 SNI 的 TLS 工作的 Web 应用程序和服务而言已经足够。
与管理员合作将 Ingress Controller 配置为接受外部请求并根据配置的路由进行代理。
管理员可以创建通配符 DNS 条目,再设置 Ingress Controller。然后,您可以处理边缘 Ingress Controller,无需与管理员联系。
在不同项目中创建一组路由时,整组路由都可用于这一组 Ingress Controller。每个 Ingress Controller 准许来自这一组路由的路由。默认情况下,所有 Ingress Controller 都准许所有路由。
Ingress Controller:
- 默认有两个副本;即,它应该在两个 worker 节点上运行。
- 可以纵向扩张,以在更多节点上具有更多副本。
这部分中的流程需要由集群管理员执行先决条件。
13.3.2. 先决条件
在开始以下流程前,管理员必须:
- 设置集群联网环境的外部端口,使请求能够到达集群。
确定至少有一个用户具有集群管理员角色。要将此角色添加到用户,请运行以下命令:
oc adm policy add-cluster-role-to-user cluster-admin username
- 有一个 OpenShift Container Platform 集群,其至少有一个 master 和至少一个节点,并且集群外有一个对集群具有网络访问权限的系统。此流程假设外部系统与集群位于同一个子网。不同子网上外部系统所需要的额外联网不在本主题的讨论范围内。
13.3.3. 创建项目和服务
如果您要公开的项目和服务尚不存在,请首先创建项目,再创建服务。
如果项目和服务都已存在,跳到公开服务以创建路由这一步。
先决条件
-
按照
oc
CLI 并以一个集群管理员身份登陆。
流程
为您的服务创建一个新项目:
$ oc new-project <project_name>
例如:
$ oc new-project myproject
使用
oc new-app
命令来创建服务。例如:$ oc new-app \ -e MYSQL_USER=admin \ -e MYSQL_PASSWORD=redhat \ -e MYSQL_DATABASE=mysqldb \ registry.redhat.io/rhscl/mysql-80-rhel7
运行以下命令,以查看新服务是否已创建:
$ oc get svc -n myproject
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-80-rhel7 ClusterIP 172.30.63.31 <none> 3306/TCP 4m55s
默认情况下,新服务没有外部 IP 地址。
13.3.4. 通过创建路由公开服务
您可以使用 oc expose
命令,将服务公开为路由。
流程
公开服务:
- 登录 OpenShift Container Platform。
登录您想公开的服务所在的项目。
$ oc project project1
运行以下命令以公开路由:
$ oc expose service <service_name>
例如:
$ oc expose service mysql-80-rhel7
输出示例
route "mysql-80-rhel7" exposed
使用 cURL 等工具来确保您可以使用服务的集群 IP 地址来访问该服务:
$ curl <pod_ip>:<port>
例如:
$ curl 172.30.131.89:3306
此部分中的示例使用 MySQL 服务,这需要客户端应用程序。如果您得到一串字符并看到
Got packets out of order
消息,则您已连接到该服务。如果您有 MySQL 客户端,请使用标准 CLI 命令登录:
$ mysql -h 172.30.131.89 -u admin -p
输出示例
Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. MySQL [(none)]>
13.3.5. 通过路由标签(label)配置 Ingress Controller 分片
使用路由标签进行 Ingress Controller 分片,意味着 Ingress Controller 提供由路由选择器选择的任意命名空间中的所有路由。
在一组 Ingress Controller 之间平衡传入的流量负载时,以及在将流量隔离到特定 Ingress Controller 时,Ingress Controller 分片会很有用处。例如,A 公司的流量使用一个 Ingress Controller,B 公司的流量则使用另外一个 Ingress Controller。
流程
编辑
router-internal.yaml
文件:# cat router-internal.yaml apiVersion: v1 items: - apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: sharded namespace: openshift-ingress-operator spec: domain: <apps-sharded.basedomain.example.net> nodePlacement: nodeSelector: matchLabels: node-role.kubernetes.io/worker: "" routeSelector: matchLabels: type: sharded status: {} kind: List metadata: resourceVersion: "" selfLink: ""
应用 Ingress Controller
router-internal.yaml
文件:# oc apply -f router-internal.yaml
Ingress Controller 选择具有
type: sharded
标签的任意命名空间中的路由。
13.3.6. 使用命名空间标签配置 Ingress Controller 分片
使用命名空间标签进行 Ingress Controller 分片,意味着 Ingress Controller 提供由命名空间选择器选择的任意命名空间中的所有路由。
在一组 Ingress Controller 之间平衡传入的流量负载时,以及在将流量隔离到特定 Ingress Controller 时,Ingress Controller 分片会很有用处。例如,A 公司的流量使用一个 Ingress Controller,B 公司的流量则使用另外一个 Ingress Controller。
流程
编辑
router-internal.yaml
文件:# cat router-internal.yaml
输出示例
apiVersion: v1 items: - apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: sharded namespace: openshift-ingress-operator spec: domain: <apps-sharded.basedomain.example.net> nodePlacement: nodeSelector: matchLabels: node-role.kubernetes.io/worker: "" namespaceSelector: matchLabels: type: sharded status: {} kind: List metadata: resourceVersion: "" selfLink: ""
应用 Ingress Controller
router-internal.yaml
文件:# oc apply -f router-internal.yaml
Ingress Controller 选择由命名空间选择器选择的具有
type: sharded
标签的任意命名空间中的路由。
13.3.7. 其他资源
- Ingress Operator 管理通配符 DNS。如需更多信息,请参阅 OpenShift Container Platform 中的 Ingress Operator、在裸机上安装集群和在 vSphere 上安装集群。
13.4. 使用负载均衡器配置集群入口流量
OpenShift Container Platform 提供了从集群外部与集群中运行的服务进行通信的方法。此方法使用了负载均衡器。
13.4.1. 使用负载均衡器使流量进入集群
如果不需要具体的外部 IP 地址,您可以配置负载均衡器服务,以便从外部访问 OpenShift Container Platform 集群。
负载均衡器服务分配唯一 IP。负载均衡器有单一边缘路由器 IP,它可以是虚拟 IP (VIP),但仍然是一台用于初始负载均衡的计算机。
如果配置了池,则会在基础架构一级进行,而不是由集群管理员完成。
这部分中的流程需要由集群管理员执行先决条件。
13.4.2. 先决条件
在开始以下流程前,管理员必须:
- 设置集群联网环境的外部端口,使请求能够到达集群。
确定至少有一个用户具有集群管理员角色。要将此角色添加到用户,请运行以下命令:
oc adm policy add-cluster-role-to-user cluster-admin username
- 有一个 OpenShift Container Platform 集群,其至少有一个 master 和至少一个节点,并且集群外有一个对集群具有网络访问权限的系统。此流程假设外部系统与集群位于同一个子网。不同子网上外部系统所需要的额外联网不在本主题的讨论范围内。
13.4.3. 创建项目和服务
如果您要公开的项目和服务尚不存在,请首先创建项目,再创建服务。
如果项目和服务都已存在,跳到公开服务以创建路由这一步。
先决条件
-
按照
oc
CLI 并以一个集群管理员身份登陆。
流程
为您的服务创建一个新项目:
$ oc new-project <project_name>
例如:
$ oc new-project myproject
使用
oc new-app
命令来创建服务。例如:$ oc new-app \ -e MYSQL_USER=admin \ -e MYSQL_PASSWORD=redhat \ -e MYSQL_DATABASE=mysqldb \ registry.redhat.io/rhscl/mysql-80-rhel7
运行以下命令,以查看新服务是否已创建:
$ oc get svc -n myproject
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-80-rhel7 ClusterIP 172.30.63.31 <none> 3306/TCP 4m55s
默认情况下,新服务没有外部 IP 地址。
13.4.4. 通过创建路由公开服务
您可以使用 oc expose
命令,将服务公开为路由。
流程
公开服务:
- 登录 OpenShift Container Platform。
登录您想公开的服务所在的项目。
$ oc project project1
运行以下命令以公开路由:
$ oc expose service <service_name>
例如:
$ oc expose service mysql-80-rhel7
输出示例
route "mysql-80-rhel7" exposed
使用 cURL 等工具来确保您可以使用服务的集群 IP 地址来访问该服务:
$ curl <pod_ip>:<port>
例如:
$ curl 172.30.131.89:3306
此部分中的示例使用 MySQL 服务,这需要客户端应用程序。如果您得到一串字符并看到
Got packets out of order
消息,则您已连接到该服务。如果您有 MySQL 客户端,请使用标准 CLI 命令登录:
$ mysql -h 172.30.131.89 -u admin -p
输出示例
Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. MySQL [(none)]>
13.4.5. 创建负载均衡器服务
使用以下流程来创建负载均衡器服务。
先决条件
- 确保您要公开的项目和服务已经存在。
流程
创建负载均衡器服务:
- 登录 OpenShift Container Platform。
加载您要公开的服务所在的项目。
$ oc project project1
在 master 节点上打开一个文本文件并粘贴以下文本,根据需要编辑该文件:
负载均衡器配置文件示例
apiVersion: v1 kind: Service metadata: name: egress-2 1 spec: ports: - name: db port: 3306 2 loadBalancerIP: type: LoadBalancer 3 selector: name: mysql 4
- 保存并退出文件。
运行以下命令来创建服务:
$ oc create -f <file-name>
例如:
$ oc create -f mysql-lb.yaml
执行以下命令以查看新服务:
$ oc get svc
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE egress-2 LoadBalancer 172.30.22.226 ad42f5d8b303045-487804948.example.com 3306:30357/TCP 15m
如果启用了云供应商,该服务会自动分配到一个外部 IP 地址。
在 master 上,使用 cURL 等工具来确保您可以通过公共 IP 地址访问该服务:
$ curl <public-ip>:<port>
例如:
$ curl 172.29.121.74:3306
此部分中的示例使用 MySQL 服务,这需要客户端应用程序。如果您得到一串字符并看到
Got packets out of order
消息,则您已连接到该服务。如果您有 MySQL 客户端,请使用标准 CLI 命令登录:
$ mysql -h 172.30.131.89 -u admin -p
输出示例
Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. MySQL [(none)]>
13.5. 为服务外部 IP 配置 ingress 集群流量
您可以将外部 IP 地址附加到服务,使其可用于集群外的流量。这通常只适用于在裸机硬件上安装的集群。必须正确配置外部网络基础架构,将流量路由到该服务。
13.5.1. 先决条件
- 您的集群被配置为启用了 ExternalIP。如需更多信息,请参阅 为服务配置 ExternalIPs。
13.5.2. 将 ExternalIP 附加到服务
您可以将 ExternalIP 附加到服务。如果您的集群被配置为自动分配 ExternalIP,您可能不需要手动将 ExternalIP 附加到该服务。
流程
可选: 要确认为 ExternalIP 配置了哪些 IP 地址范围,请输入以下命令:
$ oc get networks.config cluster -o jsonpath='{.spec.externalIP}{"\n"}'
如果设置了
autoAssignCIDRs
,在没有指定spec.externalIPs
字段的情况下,OpenShift Container Platform 会自动为新的Service
对象分配一个 ExternalIP。为服务附加一个 ExternalIP。
如果要创建新服务,请指定
spec.externalIPs
字段,并提供包括一个或多个有效 IP 地址的数组。例如:apiVersion: v1 kind: Service metadata: name: svc-with-externalip spec: ... externalIPs: - 192.174.120.10
如果您要将 ExternalIP 附加到现有服务中,请输入以下命令。将
<name>
替换为服务名称。将<ip_address>
替换为有效的 ExternalIP 地址。您可以提供多个以逗号分开的 IP 地址。$ oc patch svc <name> -p \ '{ "spec": { "externalIPs": [ "<ip_address>" ] } }'
例如:
$ oc patch svc mysql-55-rhel7 -p '{"spec":{"externalIPs":["192.174.120.10"]}}'
输出示例
"mysql-55-rhel7" patched
要确认一个 ExternalIP 地址已附加到该服务,请输入以下命令。如果为新服务指定 ExternalIP,您必须首先创建该服务。
$ oc get svc
输出示例
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-55-rhel7 172.30.131.89 192.174.120.10 3306/TCP 13m
13.5.3. 其他资源
13.6. 使用 NodePort 配置集群入口流量
OpenShift Container Platform 提供了从集群外部与集群中运行的服务进行通信的方法。此方法使用了 NodePort
。
13.6.1. 使用 NodePort 使流量进入集群
使用 NodePort
类型的 Service
资源,在集群中所有节点的特定端口上公开服务。端口在 Service
资源的 .spec.ports[*].nodePort
字段中指定。
使用节点端口需要额外的端口资源。
NodePort
在节点 IP 地址的静态端口上公开服务。默认情况下,NodePort
在 30000
到 32767
的范围内,这意味着,NodePort
不可能与服务的预期端口匹配。例如:端口 8080
可能会在节点的端口 31020
中公开。
管理员必须确保外部 IP 地址路由到节点。
NodePort
和外部 IP 地址互相独立,可以同时使用它们。
这部分中的流程需要由集群管理员执行先决条件。
13.6.2. 先决条件
在开始以下流程前,管理员必须:
- 设置集群联网环境的外部端口,使请求能够到达集群。
确定至少有一个用户具有集群管理员角色。要将此角色添加到用户,请运行以下命令:
$ oc adm policy add-cluster-role-to-user cluster-admin <user_name>
- 有一个 OpenShift Container Platform 集群,其至少有一个 master 和至少一个节点,并且集群外有一个对集群具有网络访问权限的系统。此流程假设外部系统与集群位于同一个子网。不同子网上外部系统所需要的额外联网不在本主题的讨论范围内。
13.6.3. 创建项目和服务
如果您要公开的项目和服务尚不存在,请首先创建项目,再创建服务。
如果项目和服务都已存在,跳到公开服务以创建路由这一步。
先决条件
-
按照
oc
CLI 并以一个集群管理员身份登陆。
流程
为您的服务创建一个新项目:
$ oc new-project <project_name>
例如:
$ oc new-project myproject
使用
oc new-app
命令来创建服务。例如:$ oc new-app \ -e MYSQL_USER=admin \ -e MYSQL_PASSWORD=redhat \ -e MYSQL_DATABASE=mysqldb \ registry.redhat.io/rhscl/mysql-80-rhel7
运行以下命令,以查看新服务是否已创建:
$ oc get svc -n myproject
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-80-rhel7 ClusterIP 172.30.63.31 <none> 3306/TCP 4m55s
默认情况下,新服务没有外部 IP 地址。
13.6.4. 通过创建路由公开服务
您可以使用 oc expose
命令,将服务公开为路由。
流程
公开服务:
- 登录 OpenShift Container Platform。
登录您想公开的服务所在的项目。
$ oc project project1
要为应用程序公开节点端口,请输入以下命令。OpenShift Container Platform 会自动在
30000-32767
范围内选择可用端口。$ oc expose dc mysql-80-rhel7 --type=NodePort --name=mysql-ingress
可选: 要使用公开的节点端口确认该服务可用,请输入以下命令:
$ oc get svc -n myproject
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-80-rhel7 ClusterIP 172.30.217.127 <none> 3306/TCP 9m44s mysql-ingress NodePort 172.30.107.72 <none> 3306:31345/TCP 39s
可选: 要删除由
oc new-app
命令自动创建的服务,请输入以下命令:$ oc delete svc mysql-80-rhel7
第 14 章 配置集群范围代理
生产环境可能会拒绝直接访问互联网,而是提供 HTTP 或 HTTPS 代理。您可以通过修改现有集群的 Proxy 对象或在新集群的 install-config.yaml
文件中配置代理设置,将 OpenShift Container Platform 配置为使用代理。
只有在使用用户置备的基础架构安装,或者为支持的供应商提供自己的网络(如虚拟私有云或 virual 网络)时,集群范围的代理才会被支持。
14.1. 先决条件
查看 集群需要访问的站点中的内容,决定这些站点中的任何站点是否需要绕过代理。默认情况下,所有集群出站流量都需经过代理,包括对托管集群的云供应商 API 的调用。若有需要,将站点添加到 Proxy 对象的
spec.noProxy
字段来绕过代理服务器。注意Proxy 对象
status.noProxy
字段使用安装配置中的networking.machineNetwork[].cidr
、networking.clusterNetwork[].cidr
和networking.serviceNetwork[]
字段的值填充。对于在 Amazon Web Services(AWS)、Google Cloud Platform(GCP)、Microsoft Azure 和 Red Hat OpenStack Platform(RHOSP)上安装,
Proxy
对象status.noProxy
字段也会使用实例元数据端点填充(169.254.169.254
)。
14.2. 启用集群范围代理
Proxy 对象用于管理集群范围出口代理。如果在安装或升级集群时没有配置代理,则 Proxy 对象仍会生成,但它会有一个空的 spec
。例如:
apiVersion: config.openshift.io/v1 kind: Proxy metadata: name: cluster spec: trustedCA: name: "" status:
集群管理员可以通过修改这个 cluster
Proxy 对象来配置 OpenShift Container Platform 的代理。
只支持名为 cluster
的 Proxy 对象,且无法创建额外的代理。
先决条件
- 集群管理员权限
-
已安装 OpenShift Container Platform
oc
CLI 工具
流程
创建包含代理 HTTPS 连接所需的额外 CA 证书的 ConfigMap。
注意如果代理的身份证书由来自 RHCOS 信任捆绑包的颁发机构签名,您可以跳过这一步。
利用以下内容,创建一个名为
user-ca-bundle.yaml
的文件,并提供 PEM 编码证书的值:apiVersion: v1 data: ca-bundle.crt: | 1 <MY_PEM_ENCODED_CERTS> 2 kind: ConfigMap metadata: name: user-ca-bundle 3 namespace: openshift-config 4
从此文件创建 ConfigMap:
$ oc create -f user-ca-bundle.yaml
使用
oc edit
命令修改 Proxy 对象:$ oc edit proxy/cluster
为代理配置所需的字段:
apiVersion: config.openshift.io/v1 kind: Proxy metadata: name: cluster spec: httpProxy: http://<username>:<pswd>@<ip>:<port> 1 httpsProxy: http://<username>:<pswd>@<ip>:<port> 2 noProxy: example.com 3 readinessEndpoints: - http://www.google.com 4 - https://www.google.com trustedCA: name: user-ca-bundle 5
- 1
- 用于创建集群外 HTTP 连接的代理 URL。URL 必须是
http
。 - 2
- 用于创建集群外 HTTPS 连接的代理 URL。如果没有指定,则
httpProxy
会同时用于 HTTP 和 HTTPS 连接。 - 3
- 要排除代理的目标域名、域、IP 地址或其他网络 CIDR 的逗号分隔列表。域之前加上前缀
.
可包含该域的所有子域。使用*
可对所有目的地绕过所有代理。请注意,如果您要纵向扩展未包含在安装配置的networking.machineNetwork[].cidr
中的 worker,您必须将它们添加到此列表中,以防止连接问题。 - 4
- 将
httpProxy
和httpsProxy
值写进状态之前,执行就绪度检查时要使用的一个或多个集群外部 URL。 - 5
- 引用
openshift-config
命名空间中的 ConfigMap,其包含代理 HTTPS 连接所需的额外 CA 证书。注意 ConfigMap 必须已经存在,然后才能在这里引用它。此字段是必需的,除非代理的身份证书由来自 RHCOS 信任捆绑包的颁发机构签名。
- 保存文件以应用更改。
14.3. 删除集群范围代理服务器
cluster
Proxy 对象不能被删除。要从集群中删除代理,请删除 Proxy 对象的所有 spec
字段。
先决条件
- 集群管理员权限
-
已安装 OpenShift Container Platform
oc
CLI 工具
流程
使用
oc edit
命令来修改代理:$ oc edit proxy/cluster
删除 Proxy 对象的所有
spec
字段。例如:apiVersion: config.openshift.io/v1 kind: Proxy metadata: name: cluster spec: {} status: {}
- 保存文件以使改变生效。
第 15 章 配置自定义 PKI
有些平台组件,如 Web 控制台,使用 Routes 进行通信,且必须信任其他组件的证书与其交互。如果您使用的是自定义公钥基础架构 (PKI) ,您必须将其配置为在集群中识别其私有签名的 CA 证书。
您可以使用 Proxy API 添加集群范围的可信 CA 证书。您必须在安装过程中或运行时执行此操作。
在 安装过程 中,配置集群范围的代理。您需要在
install-config.yaml
文件中的additionalTrustBundle
设置中定义私有签名的 CA 证书。安装程序生成名为
user-ca-bundle
的 ConfigMap,其中包含您定义的附加 CA 证书。然后,Cluster Network Operator 会创建trusted-ca-bundle
ConfigMap,将这些内容与 Red Hat Enterprise Linux CoreOS (RHCOS) 信任捆绑包合并,Proxy 对象的trustedCA
字段中也会引用此 ConfigMap。-
在运行时,,修改默认 Proxy 对象使其包含您私有签名的 CA 证书 (集群代理启用工作流程的一部分)。这涉及创建包含集群应信任的私有签名 CA 证书的 ConfigMap,然后使用
trustedCA
引用私有签名证书的 ConfigMap 修改代理服务器资源。
安装程序配置的 additionalTrustBundle
字段和 proxy 资源的 trustedCA
字段被用来管理集群范围信任捆绑包; 在安装时会使用 additionalTrustBundle
,并在运行时使用代理的trustedCA
。
trustedCA
字段是对包含集群组件使用的自定义证书和密钥对的 ConfigMap
的引用。
15.1. 在安装过程中配置集群范围代理
生产环境可能会拒绝直接访问互联网,而是提供 HTTP 或 HTTPS 代理。您可以通过在 install-config.yaml
文件中配置代理设置,将新的 OpenShift Container Platform 集群配置为使用代理。
先决条件
-
现有的
install-config.yaml
文件。 查看集群需要访问的站点,并决定是否需要绕过代理。默认情况下代理所有集群出口流量,包括对托管云供应商 API 的调用。如果需要,在
Proxy
对象的spec.noProxy
字段中添加站点来绕过代理。注意Proxy
对象status.noProxy
字段使用安装配置中的networking.machineNetwork[].cidr
、networking.clusterNetwork[].cidr
和networking.serviceNetwork[]
字段的值填充。对于在 Amazon Web Services(AWS)、Google Cloud Platform(GCP)、Microsoft Azure 和 Red Hat OpenStack Platform(RHOSP)上安装,
Proxy
对象status.noProxy
字段也会使用实例元数据端点填充(169.254.169.254
)。
流程
编辑
install-config.yaml
文件并添加代理设置。例如:apiVersion: v1 baseDomain: my.domain.com proxy: httpProxy: http://<username>:<pswd>@<ip>:<port> 1 httpsProxy: http://<username>:<pswd>@<ip>:<port> 2 noProxy: example.com 3 additionalTrustBundle: | 4 -----BEGIN CERTIFICATE----- <MY_TRUSTED_CA_CERT> -----END CERTIFICATE----- ...
- 1
- 用于创建集群外 HTTP 连接的代理 URL。URL 必须是
http
。如果您使用不要求额外代理配置但需要额外 CA 的 MITM 透明代理网络,则不得指定httpProxy
值。 - 2
- 用于创建集群外 HTTPS 连接的代理 URL。如果未指定此字段,
httpProxy
会同时用于 HTTP 和 HTTPS 连接。如果您使用不要求额外代理配置但需要额外 CA 的 MITM 透明代理网络,则不得指定httpsProxy
值。 - 3
- 要排除代理的目标域名、域、IP 地址或其他网络 CIDR 的逗号分隔列表。域之前加上前缀
.
可包含该域的所有子域。使用*
可对所有目的地绕过所有代理。 - 4
- 如果提供,安装程序会在
openshift-config
命名空间中生成名为user-ca-bundle
的配置映射,其包含代理 HTTPS 连接所需的一个或多个额外 CA 证书。然后,Cluster Network Operator 会创建trusted-ca-bundle
配置映射,将这些内容与 Red Hat Enterprise Linux CoreOS(RHCOS)信任捆绑包合并,Proxy
对象的trustedCA
字段中也会引用此配置映射。additionalTrustBundle
字段是必需的,除非代理的身份证书由来自 RHCOS 信任捆绑包的颁发机构签名。如果您使用不要求额外代理配置但需要额外 CA 的 MITM 透明代理网络,您必须提供 MITM CA 证书。
注意安装程序不支持代理的
readinessEndpoints
字段。- 保存该文件,并在安装 OpenShift Container Platform 时引用。
安装程序会创建一个名为 cluster
的集群范围代理,该代理使用提供的 install-config.yaml
文件中的代理设置。如果没有提供代理设置,仍然会创建一个 cluster
Proxy
对象,但它会有一个空 spec
。
只支持名为 cluster
的 Proxy
对象,且无法创建额外的代理。
15.2. 启用集群范围代理
Proxy 对象用于管理集群范围出口代理。如果在安装或升级集群时没有配置代理,则 Proxy 对象仍会生成,但它会有一个空的 spec
。例如:
apiVersion: config.openshift.io/v1 kind: Proxy metadata: name: cluster spec: trustedCA: name: "" status:
集群管理员可以通过修改这个 cluster
Proxy 对象来配置 OpenShift Container Platform 的代理。
只支持名为 cluster
的 Proxy 对象,且无法创建额外的代理。
先决条件
- 集群管理员权限
-
已安装 OpenShift Container Platform
oc
CLI 工具
流程
创建包含代理 HTTPS 连接所需的额外 CA 证书的 ConfigMap。
注意如果代理的身份证书由来自 RHCOS 信任捆绑包的颁发机构签名,您可以跳过这一步。
利用以下内容,创建一个名为
user-ca-bundle.yaml
的文件,并提供 PEM 编码证书的值:apiVersion: v1 data: ca-bundle.crt: | 1 <MY_PEM_ENCODED_CERTS> 2 kind: ConfigMap metadata: name: user-ca-bundle 3 namespace: openshift-config 4
从此文件创建 ConfigMap:
$ oc create -f user-ca-bundle.yaml
使用
oc edit
命令修改 Proxy 对象:$ oc edit proxy/cluster
为代理配置所需的字段:
apiVersion: config.openshift.io/v1 kind: Proxy metadata: name: cluster spec: httpProxy: http://<username>:<pswd>@<ip>:<port> 1 httpsProxy: http://<username>:<pswd>@<ip>:<port> 2 noProxy: example.com 3 readinessEndpoints: - http://www.google.com 4 - https://www.google.com trustedCA: name: user-ca-bundle 5
- 1
- 用于创建集群外 HTTP 连接的代理 URL。URL 必须是
http
。 - 2
- 用于创建集群外 HTTPS 连接的代理 URL。如果没有指定,则
httpProxy
会同时用于 HTTP 和 HTTPS 连接。 - 3
- 要排除代理的目标域名、域、IP 地址或其他网络 CIDR 的逗号分隔列表。域之前加上前缀
.
可包含该域的所有子域。使用*
可对所有目的地绕过所有代理。请注意,如果您要纵向扩展未包含在安装配置的networking.machineNetwork[].cidr
中的 worker,您必须将它们添加到此列表中,以防止连接问题。 - 4
- 将
httpProxy
和httpsProxy
值写进状态之前,执行就绪度检查时要使用的一个或多个集群外部 URL。 - 5
- 引用
openshift-config
命名空间中的 ConfigMap,其包含代理 HTTPS 连接所需的额外 CA 证书。注意 ConfigMap 必须已经存在,然后才能在这里引用它。此字段是必需的,除非代理的身份证书由来自 RHCOS 信任捆绑包的颁发机构签名。
- 保存文件以使改变生效。
15.3. 使用 Operator 进行证书注入
在您的自定义 CA 证书通过 ConfigMap 添加到集群中后,Cluster Network Operator 会将用户提供的证书和系统 CA 证书合并到单一捆绑包中,并将合并的捆绑包注入请求信任捆绑包注入的 Operator。
Operator 通过创建一个带有以下标签的空 ConfigMap 来请求此注入:
config.openshift.io/inject-trusted-cabundle="true"
Operator 将这个 ConfigMap 挂载到容器的本地信任存储中。
只有在 Red Hat Enterprise Linux CoreOS (RHCOS) 信任捆绑包中没有包括证书时才需要添加可信的 CA 证书。
证书注入不仅限于 Operator。当使用 config.openshift.io/inject-trusted-cabundle=true
标记(label) 创建一个空的 ConfigMap 时,Cluster Network Operator会跨命名空间注入证书 。
ConfigMap 可以驻留在任何命名空间中,但 ConfigMap 必须作为卷挂载到需要自定义 CA 的 Pod 中的每个容器。例如:
apiVersion: apps/v1 kind: Deployment metadata: name: my-example-custom-ca-deployment namespace: my-example-custom-ca-ns spec: ... spec: ... containers: - name: my-container-that-needs-custom-ca volumeMounts: - name: trusted-ca mountPath: /etc/pki/ca-trust/extracted/pem readOnly: true volumes: - name: trusted-ca configMap: name: trusted-ca items: - key: ca-bundle.crt 1 path: tls-ca-bundle.pem 2