4.2. 创建网络策略
您可以为命名空间创建网络策略。
4.2.1. 示例 NetworkPolicy 对象
下文解释了示例 NetworkPolicy 对象:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-27107 spec: podSelector: matchLabels: app: mongodb ingress: - from: - podSelector: matchLabels: app: app ports: - protocol: TCP port: 27017
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-27107
spec:
podSelector:
matchLabels:
app: mongodb
ingress:
- from:
- podSelector:
matchLabels:
app: app
ports:
- protocol: TCP
port: 27017
4.2.2. 使用 CLI 创建网络策略
要定义细致的规则来描述集群中命名空间允许的入口或出口网络流量,您可以创建一个网络策略。
先决条件
-
已安装 OpenShift CLI(
oc
)。 - 您在网络策略要应用到的命名空间中。
流程
创建策略规则:
创建一个
<policy_name>.yaml
文件:touch <policy_name>.yaml
$ touch <policy_name>.yaml
Copy to Clipboard Copied! 其中:
<policy_name>
- 指定网络策略文件名。
在您刚才创建的文件中定义网络策略,如下例所示:
拒绝来自所有命名空间中的所有 pod 的入口流量
这是一个基本的策略,阻止配置其他网络策略所允许的跨 pod 流量以外的所有跨 pod 网络。
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default spec: podSelector: {} policyTypes: - Ingress ingress: []
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default spec: podSelector: {} policyTypes: - Ingress ingress: []
Copy to Clipboard Copied! 允许来自所有命名空间中的所有 pod 的入口流量
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-same-namespace spec: podSelector: ingress: - from: - podSelector: {}
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-same-namespace spec: podSelector: ingress: - from: - podSelector: {}
Copy to Clipboard Copied! 允许从特定命名空间中到一个 pod 的入口流量
此策略允许流量从在
namespace-y
中运行的容器集到标记pod-a
的 pod。kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-traffic-pod spec: podSelector: matchLabels: pod: pod-a policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: namespace-y
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: allow-traffic-pod spec: podSelector: matchLabels: pod: pod-a policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: namespace-y
Copy to Clipboard Copied!
运行以下命令来创建网络策略对象:
oc apply -f <policy_name>.yaml -n <namespace>
$ oc apply -f <policy_name>.yaml -n <namespace>
Copy to Clipboard Copied! 其中:
<policy_name>
- 指定网络策略文件名。
<namespace>
- 可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
输出示例
networkpolicy.networking.k8s.io/deny-by-default created
networkpolicy.networking.k8s.io/deny-by-default created
Copy to Clipboard Copied!
4.2.3. 创建默认拒绝所有网络策略
此策略会阻止由配置其他部署的网络策略和主机网络 pod 间的网络流量允许的所有跨 pod 网络。此流程通过在 my-project
命名空间中应用 deny-by-default
策略来强制实施强大的拒绝策略。
如果没有配置允许流量通信的 NetworkPolicy
自定义资源(CR),以下策略可能会导致集群中的通信问题。
先决条件
-
已安装 OpenShift CLI(
oc
)。 - 您在网络策略要应用到的命名空间中。
流程
创建以下 YAML,以定义
deny-by-default
策略,以拒绝所有命名空间中的所有 pod 的入口流量。将 YAML 保存到deny-by-default.yaml
文件中:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default namespace: my-project spec: podSelector: {} ingress: []
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: deny-by-default namespace: my-project
1 spec: podSelector: {}
2 ingress: []
3 Copy to Clipboard Copied! 输入以下命令应用策略:
oc apply -f deny-by-default.yaml
$ oc apply -f deny-by-default.yaml
Copy to Clipboard Copied! 输出示例
networkpolicy.networking.k8s.io/deny-by-default created
networkpolicy.networking.k8s.io/deny-by-default created
Copy to Clipboard Copied!
4.2.4. 创建网络策略以允许来自外部客户端的流量
使用 deny-by-default
策略,您可以继续配置策略,允许从外部客户端到带有标签 app=web
的 pod 的流量。
在强制任何 NetworkPolicy
前运行 firewalld 规则。
按照以下步骤配置策略,以直接从公共互联网允许外部服务,或使用 Load Balancer 访问 pod。只有具有标签 app=web
的 pod 才允许流量。
先决条件
-
已安装 OpenShift CLI(
oc
)。 - 您在网络策略要应用到的命名空间中。
流程
创建策略,以直接从公共互联网的流量或使用负载均衡器访问 pod。将 YAML 保存到
web-allow-external.yaml
文件中:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-allow-external namespace: default spec: policyTypes: - Ingress podSelector: matchLabels: app: web ingress: - {}
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-allow-external namespace: default spec: policyTypes: - Ingress podSelector: matchLabels: app: web ingress: - {}
Copy to Clipboard Copied! 输入以下命令应用策略:
oc apply -f web-allow-external.yaml
$ oc apply -f web-allow-external.yaml
Copy to Clipboard Copied! 输出示例
networkpolicy.networking.k8s.io/web-allow-external created
networkpolicy.networking.k8s.io/web-allow-external created
Copy to Clipboard Copied!
4.2.5. 创建网络策略,允许从所有命名空间中到应用程序的流量
按照以下步骤配置允许从所有命名空间中的所有 pod 流量到特定应用程序的策略。
先决条件
-
已安装 OpenShift CLI(
oc
)。 - 您在网络策略要应用到的命名空间中。
流程
创建一个策略,允许从所有命名空间中的所有 pod 流量到特定应用。将 YAML 保存到
web-allow-all-namespaces.yaml
文件中:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-allow-all-namespaces namespace: default spec: podSelector: matchLabels: app: web policyTypes: - Ingress ingress: - from: - namespaceSelector: {}
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-allow-all-namespaces namespace: default spec: podSelector: matchLabels: app: web
1 policyTypes: - Ingress ingress: - from: - namespaceSelector: {}
2 Copy to Clipboard Copied! 注意默认情况下,如果您省略了指定
namespaceSelector
而不是选择任何命名空间,这意味着策略只允许从网络策略部署到的命名空间的流量。输入以下命令应用策略:
oc apply -f web-allow-all-namespaces.yaml
$ oc apply -f web-allow-all-namespaces.yaml
Copy to Clipboard Copied! 输出示例
networkpolicy.networking.k8s.io/web-allow-all-namespaces created
networkpolicy.networking.k8s.io/web-allow-all-namespaces created
Copy to Clipboard Copied!
验证
输入以下命令在
default
命名空间中启动 web 服务:oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
$ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
Copy to Clipboard Copied! 运行以下命令在
secondary
命名空间中部署alpine
镜像并启动 shell:oc run test-$RANDOM --namespace=secondary --rm -i -t --image=alpine -- sh
$ oc run test-$RANDOM --namespace=secondary --rm -i -t --image=alpine -- sh
Copy to Clipboard Copied! 在 shell 中运行以下命令,并观察是否允许请求:
wget -qO- --timeout=2 http://web.default
# wget -qO- --timeout=2 http://web.default
Copy to Clipboard Copied! 预期输出
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
Copy to Clipboard Copied!
4.2.6. 创建网络策略,允许从一个命名空间中到应用程序的流量
按照以下步骤配置允许从特定命名空间中到带有 app=web
标签的 pod 的策略。您可能需要进行以下操作:
- 将流量限制为部署生产工作负载的命名空间。
- 启用部署到特定命名空间的监控工具,以从当前命名空间中提取指标。
先决条件
-
已安装 OpenShift CLI(
oc
)。 - 您在网络策略要应用到的命名空间中。
流程
创建一个策略,允许来自特定命名空间中所有 pod 的流量,其标签为
purpose=production
。将 YAML 保存到web-allow-prod.yaml
文件中:kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-allow-prod namespace: default spec: podSelector: matchLabels: app: web policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: purpose: production
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name: web-allow-prod namespace: default spec: podSelector: matchLabels: app: web
1 policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: purpose: production
2 Copy to Clipboard Copied! 输入以下命令应用策略:
oc apply -f web-allow-prod.yaml
$ oc apply -f web-allow-prod.yaml
Copy to Clipboard Copied! 输出示例
networkpolicy.networking.k8s.io/web-allow-prod created
networkpolicy.networking.k8s.io/web-allow-prod created
Copy to Clipboard Copied!
验证
输入以下命令在
default
命名空间中启动 web 服务:oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
$ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
Copy to Clipboard Copied! 运行以下命令来创建
prod
命名空间:oc create namespace prod
$ oc create namespace prod
Copy to Clipboard Copied! 运行以下命令来标记
prod
命名空间:oc label namespace/prod purpose=production
$ oc label namespace/prod purpose=production
Copy to Clipboard Copied! 运行以下命令来创建
dev
命名空间:oc create namespace dev
$ oc create namespace dev
Copy to Clipboard Copied! 运行以下命令来标记
dev
命名空间:oc label namespace/dev purpose=testing
$ oc label namespace/dev purpose=testing
Copy to Clipboard Copied! 运行以下命令在
dev
命名空间中部署alpine
镜像并启动 shell:oc run test-$RANDOM --namespace=dev --rm -i -t --image=alpine -- sh
$ oc run test-$RANDOM --namespace=dev --rm -i -t --image=alpine -- sh
Copy to Clipboard Copied! 在 shell 中运行以下命令,并观察请求是否被阻止:
wget -qO- --timeout=2 http://web.default
# wget -qO- --timeout=2 http://web.default
Copy to Clipboard Copied! 预期输出
wget: download timed out
wget: download timed out
Copy to Clipboard Copied! 运行以下命令,在
prod
命名空间中部署alpine
镜像并启动 shell:oc run test-$RANDOM --namespace=prod --rm -i -t --image=alpine -- sh
$ oc run test-$RANDOM --namespace=prod --rm -i -t --image=alpine -- sh
Copy to Clipboard Copied! 在 shell 中运行以下命令,并观察是否允许请求:
wget -qO- --timeout=2 http://web.default
# wget -qO- --timeout=2 http://web.default
Copy to Clipboard Copied! 预期输出
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
Copy to Clipboard Copied!