19.13. 以重定向模式部署出口路由器 pod
作为集群管理员,您可以部署出口路由器 Pod,将流量重新指向来自保留源 IP 地址的指定目标 IP 地址。
出口路由器实施使用出口路由器 Container Network Interface(CNI)插件。
19.13.1. 出口路由器自定义资源
在出口路由器自定义资源中定义出口路由器 pod 的配置。以下 YAML 描述了以重定向模式配置出口路由器的字段:
apiVersion: network.operator.openshift.io/v1 kind: EgressRouter metadata: name: <egress_router_name> namespace: <namespace> <.> spec: addresses: [ <.> { ip: "<egress_router>", <.> gateway: "<egress_gateway>" <.> } ] mode: Redirect redirect: { redirectRules: [ <.> { destinationIP: "<egress_destination>", port: <egress_router_port>, targetPort: <target_port>, <.> protocol: <network_protocol> <.> }, ... ], fallbackIP: "<egress_destination>" <.> }
<.> 可选:namespace
字段指定要在其中创建出口路由器的命名空间。如果您没有在文件或命令行中指定值,则会使用 default
命名空间。
<.> address
字段指定要在第二个网络接口上配置的 IP 地址。
<.> ip
字段指定节点用于出口路由器 pod 的物理网络中保留源 IP 地址和子网掩码。使用 CIDR 表示法指定 IP 地址和网络掩码。
<.> gateway
字段指定网络网关的 IP 地址。
<.> 可选: redirectRules
字段指定出口目的地 IP 地址、出口路由器端口和协议的组合。到指定端口和协议中的出口路由器的传入连接路由到目标 IP 地址。
<.> 可选: targetPort
字段指定目标 IP 地址上的网络端口。如果没有指定此字段,流量将路由到它到达的同一网络端口。
<.> protocol
字段支持 TCP、UDP 或 SCTP。
<.> 可选: fallbackIP
字段指定目标 IP 地址。如果没有指定任何重定向规则,出口路由器会将所有流量发送到这个回退 IP 地址。如果您指定了重定向规则,则出口路由器将任何与规则中定义的网络端口的连接发送到这个回退 IP 地址。如果没有指定此字段,出口路由器会拒绝与规则中没有定义的网络端口的连接。
出口路由器规格示例
apiVersion: network.operator.openshift.io/v1 kind: EgressRouter metadata: name: egress-router-redirect spec: networkInterface: { macvlan: { mode: "Bridge" } } addresses: [ { ip: "192.168.12.99/24", gateway: "192.168.12.1" } ] mode: Redirect redirect: { redirectRules: [ { destinationIP: "10.0.0.99", port: 80, protocol: UDP }, { destinationIP: "203.0.113.26", port: 8080, targetPort: 80, protocol: TCP }, { destinationIP: "203.0.113.27", port: 8443, targetPort: 443, protocol: TCP } ] }
19.13.2. 以重定向模式部署出口路由器
您可以部署出口路由器,将其自身保留源 IP 地址的流量重定向到一个或多个目标 IP 地址。
添加出口路由器后,需要使用保留源 IP 地址的客户端 pod 必须修改为连接到出口路由器,而不是直接连接到目标 IP。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
- 创建出口路由器定义。
为确保其他 pod 可以找到出口路由器 pod 的 IP 地址,请创建一个使用出口路由器的服务,如下例所示:
apiVersion: v1 kind: Service metadata: name: egress-1 spec: ports: - name: web-app protocol: TCP port: 8080 type: ClusterIP selector: app: egress-router-cni <.>
<.> 指定出口路由器的标签。显示的值由 Cluster Network Operator 添加,且不可配置。
创建服务后,您的 Pod 可以连接到该服务。出口路由器 pod 将流量重定向到目标 IP 地址中对应的端口。连接来自保留的源 IP 地址。
验证
要验证 Cluster Network Operator 是否启动了出口路由器,请完成以下步骤:
查看 Operator 为出口路由器创建的网络附加定义:
$ oc get network-attachment-definition egress-router-cni-nad
网络附加定义的名称不可配置。
输出示例
NAME AGE egress-router-cni-nad 18m
查看出口路由器 pod 的部署:
$ oc get deployment egress-router-cni-deployment
部署的名称不可配置。
输出示例
NAME READY UP-TO-DATE AVAILABLE AGE egress-router-cni-deployment 1/1 1 1 18m
查看出口路由器 pod 的状态:
$ oc get pods -l app=egress-router-cni
输出示例
NAME READY STATUS RESTARTS AGE egress-router-cni-deployment-575465c75c-qkq6m 1/1 Running 0 18m
- 查看出口路由器 pod 的日志和路由表。
获取出口路由器 pod 的节点名称:
$ POD_NODENAME=$(oc get pod -l app=egress-router-cni -o jsonpath="{.items[0].spec.nodeName}")
在目标节点上进入一个 debug 会话。此步骤被实例化为一个名为
<node_name>-debug
的 debug pod:$ oc debug node/$POD_NODENAME
将
/host
设为 debug shell 中的根目录。debug pod 在 pod 中的/host
中挂载主机 的 root 文件系统。将根目录改为/host
,您可以从主机的可执行路径中运行二进制文件:# chroot /host
在
chroot
环境控制台中显示出口路由器日志:# cat /tmp/egress-router-log
输出示例
2021-04-26T12:27:20Z [debug] Called CNI ADD 2021-04-26T12:27:20Z [debug] Gateway: 192.168.12.1 2021-04-26T12:27:20Z [debug] IP Source Addresses: [192.168.12.99/24] 2021-04-26T12:27:20Z [debug] IP Destinations: [80 UDP 10.0.0.99/30 8080 TCP 203.0.113.26/30 80 8443 TCP 203.0.113.27/30 443] 2021-04-26T12:27:20Z [debug] Created macvlan interface 2021-04-26T12:27:20Z [debug] Renamed macvlan to "net1" 2021-04-26T12:27:20Z [debug] Adding route to gateway 192.168.12.1 on macvlan interface 2021-04-26T12:27:20Z [debug] deleted default route {Ifindex: 3 Dst: <nil> Src: <nil> Gw: 10.128.10.1 Flags: [] Table: 254} 2021-04-26T12:27:20Z [debug] Added new default route with gateway 192.168.12.1 2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p UDP --dport 80 -j DNAT --to-destination 10.0.0.99 2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p TCP --dport 8080 -j DNAT --to-destination 203.0.113.26:80 2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p TCP --dport 8443 -j DNAT --to-destination 203.0.113.27:443 2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat -o net1 -j SNAT --to-source 192.168.12.99
当您启动出口路由器时,通过创建
EgressRouter
对象来启动出口路由器时,日志文件位置和日志记录级别不可配置,如下所述。在
chroot
环境控制台中获取容器 ID:# crictl ps --name egress-router-cni-pod | awk '{print $1}'
输出示例
CONTAINER bac9fae69ddb6
确定容器的进程 ID。在本例中,容器 ID 是
bac9fae69ddb6
:# crictl inspect -o yaml bac9fae69ddb6 | grep 'pid:' | awk '{print $2}'
输出示例
68857
输入容器的网络命名空间:
# nsenter -n -t 68857
显示路由表:
# ip route
在以下示例输出中,
net1
网络接口是默认路由。集群网络的流量使用eth0
网络接口。192.168.12.0/24
网络的流量使用net1
网络接口,并源自保留源 IP 地址192.168.12.99
。pod 将所有其他流量路由到网关,地址为192.168.12.1
。不显示服务网络的路由。输出示例
default via 192.168.12.1 dev net1 10.128.10.0/23 dev eth0 proto kernel scope link src 10.128.10.18 192.168.12.0/24 dev net1 proto kernel scope link src 192.168.12.99 192.168.12.1 dev net1