1
2
3
4
5
作者:李晓辉

微信联系:lxh_chat

联系邮箱: 939958092@qq.com

你知道吗?默认情况下,同一个 namespace 里的 pod,基本谁都能随便连其他 pod;甚至别的 namespace 里的 pod 也能连进来!这就有点“门太敞”的意思了。

如果你不想别人随便乱连你的服务,那就得靠 network policy 来帮你立规矩。

network policy 是 Kubernetes 的“防火墙规则”,你可以给 pod 或 VM 打上标签(label),也可以给 namespace 打标签,然后设置“谁可以进,谁不能进”。

管理员可以用命令行或者 OpenShift 的 Web 控制台来给 namespace 添加标签,像这样操作:

1
oc label namespace your-namespace-name purpose=secure

当然,你也可以图形界面操作(GUI 党也友好~),比如在 OpenShift 控制台的 Administration → Namespaces 页面,点开某个 namespace,在 Details 页签里,找到 Labels 部分,点 Edit,然后加上你要的标签就好啦。

ns-labels

add-nslabel

你要是想通过命令行给一个 namespace 打标签,其实非常简单,用 oc label namespace 命令就行。

比如下面这条命令,就是给 prod-front 这个 namespace 加了一个标签:name=client-ns

1
[lxh@host ~]$ oc label namespace prod-front name=client-ns

加完标签之后,咱们就可以开始写 network policy 啦。

网络策略样例

Kubernetes 的网络策略是“命名空间级别的资源”,意思就是它只对当前 namespace 下的 pod 生效。

下面这个例子就特别实用:

我们打算写一个网络策略,让当前命名空间中所有标签是 tier=backend 的 pod(或者 VM)能被访问,但有点限制——只能让两个特定命名空间里的前端 pod 来访问它们的 8080 端口。

这个策略包括两个 ingress 规则:

  • 第一条:允许那些在打了 name=client-ns 标签的 namespace 中,标签是 tier=front 的 pod 或 VM,来访问 tier=backend 的服务(端口 8080)。
  • 第二条:再放行一个打了 name=server-ns 标签的 namespace 里的所有 pod 或 VM,它们也能连 8080 端口。

是不是感觉有点像“凭通行证进门”的设定?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
kind: NetworkPolicy  # 声明资源类型是网络策略
apiVersion: networking.k8s.io/v1 # 使用的 API 版本
metadata:
name: network-1-policy # 策略的名字

spec:
podSelector: # 目标 pod 的选择器
matchLabels:
tier: backend # 只作用于打了 tier=backend 标签的 pod(也就是后端 pod)

ingress: # 定义允许哪些流量进来
- from: # 下面这些来源可以访问上面选中的 pod
- namespaceSelector: # 来源命名空间匹配的规则
matchLabels:
name: client-ns # 第一个允许来源:标签为 name=client-ns 的 namespace
podSelector:
matchLabels:
tier: front # 并且这个 pod 必须是前端 pod(tier=front)

- namespaceSelector: # 第二个允许来源:标签为 name=server-ns 的 namespace
matchLabels:
name: server-ns # 不限制 pod 标签,整个 namespace 里的 pod 都可以访问

ports: # 允许的端口设置
- port: 8080 # 仅放行 8080 端口
protocol: TCP # 协议类型是 TCP

这段策略的意思就是:

“backend 兄弟们,你们只能接受从 client-ns 命名空间的front pod 和 server-ns 命名空间的任意 pod 发来的 TCP 8080 请求,其他的一律不准进!”

你要是觉得写 YAML 太头疼,也没事儿,OpenShift 的 Web 控制台也能帮你搞定网络策略!

步骤如下👇:

  1. 打开控制台左侧菜单里的 Networking → NetworkPolicies
  2. 点一下右上角的 Create Network Policy
  3. 然后就会弹出一个表单啦~

这个表单其实挺智能的,能让你图形化添加 ingress、egress 规则,设置 namespace selector、pod selector、端口啥的。

form-np

但是!注意一件事⚠️:

从 OpenShift 4.16 开始,这个表单不会自动识别你当前在哪个命名空间(真有点迷惑😅)。也就是说,你得自己手动指定这个 NetworkPolicy 属于哪个 namespace。

解决办法也很简单:

点进去之后,切换到 YAML 视图,然后在 metadata 里补上你想让它作用的 namespace,比如这样:

1
2
3
metadata:
name: my-policy
namespace: my-namespace # 自己加上这行!

搞定后点 Create 就大功告成啦 🙌

yaml-np

好的!下面是我们接下来的轻松语气改写内容,这一部分是讲 OpenShift 中的集群范围网络策略(AdminNetworkPolicy,简称 ANP),我已经帮你整理好并保留表格形式。


设置集群级别的网络策略

OpenShift 除了普通的 namespace 网络策略外,还有个更厉害的玩法 —— AdminNetworkPolicy,简称 ANP。

这个 ANP 可不是随便谁都能搞的,因为它作用范围是整个集群(cluster-scoped)!也就是说,它可以在某个 namespace 还没创建出来之前,就提前把“进出规则”给定好了,堪称“先下手为强”。

ANP 跟我们之前说的普通网络策略差不多,但它多了三个超关键的配置:

  1. subject:你要对谁施加政策?是哪些 namespace 或哪些 pod?靠它来锁定目标
  2. priority:冲突规则先后怎么处理?这个优先级说了算,值越小优先级越高(0 是最高,99 是最低)
  3. action:这是核心操作,有三个选项 —— AllowDenyPass,我们来看看分别啥意思:
Action意思
Allow放行进出流量
Deny拒绝所有流量
Pass不干预,让 namespace 自己的 network policy 决定

⚠️ 有一点要特别注意哦:

如果一个 ANP 设置了 AllowDeny,那就算你在 namespace 里再加 network policy 也没用了,它说了算!

也就是说,只有当 ANP 设置成 Pass,你才可以在命名空间级别用 network policy 来接管控制权。

举个例子:

你可以写一个 ANP,让 monitoring 命名空间能访问任何打了 security=unrestricted 标签的命名空间。这时候,如果某个被访问的命名空间想“关门谢客”,那就得先把那个 security=unrestricted 的标签去掉,才有资格写 network policy 来挡住 monitoring 的访问。

是不是有种“总管先发话,房东再决定”的感觉?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: policy.networking.k8s.io/v1alpha1
kind: AdminNetworkPolicy
metadata:
name: sample-anp-allow-monitoring # 这是给这个管理员网络策略起的名字,方便辨认
spec:
priority: 50 # 优先级数字越大,这条规则的优先级越高,先生效
subject:
namespaces:
matchLabels:
security: unrestricted # 选中所有带有这个标签的命名空间,规则就作用在这些空间上
ingress: # 这是入口流量规则,管谁可以进来
- name: "allow-monitoring-unrestricted" # 给这条规则也起个名字,方便以后查
action: "Allow" # 允许来自下面指定的命名空间的流量
from:
- namespaces:
matchLabels:
kubernetes.io/metadata.name: monitoring # 只允许监控这个命名空间的访问

简单总结一下哈,这条管理员网络策略的意思就是:只要你是打了security=unrestricted 标签的 namespace,monitoring命名空间就能自由访问你。普通的名字空间网络策略是没法盖过这个“超级管理员”的。如果你想挡monitoring的访问,先得把自己标签摘了,然后才能用普通网络策略阻止它。