赞
踩
我们在内网使用k8s时,有时候需要针对整个集群的节点设置防火墙,阻止一些外部访问,或者是仅允许白名单内的ip访问,传统做法是使用firewall之类的防火墙软件,但是,使用firewall存在如下问题:
如果集群的节点是托管到云平台上的,可以忽略本文章,直接去云平台设置防火墙策略。
如果我们的k8s插件是calico,可以通过calico的扩展功能来设置整个集群所有节点的防火墙,不会有上面两个问题的困扰。
calico网络策略的官方文档是: https://docs.tigera.io/calico/latest/network-policy/get-started/calico-policy/calico-network-policy
想要在安装了calico网络插件的k8s集群里面配置节点防火墙,首先我们需要将节点注册到calico上,在calico这个叫做 Host endpoint
, 一个Host endpoint
指的是节点对外的出口,一般是一块网卡,网卡上带有ip地址,我们需要通过声明HostEndpoint
来注册。
在声明HostEndpoint时,还可以指定该节点的标签,后期在进行防火墙配置时,可以通过标签来批量配置。
当声明HostEndpoint后,节点的网络策略将由Calico接管,默认的规则是拒绝所有连接。Calico为了防止整个节点的网络瘫痪,默认开放了一些端口,比如22等,后面会详细说明。
如前所述,我们首先需要声明一个HostEndpoint,下面是声明的Yaml:
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
name: node1-eth0
labels:
kubernetes-host: ingress
spec:
interfaceName: eth0
node: node1
expectedIPs:
- INSERT_IP_HERE
这个是全局配置,不需要namespace。
metadata.name
是HostEndpoint的名字,一般是节点名-网卡
spec.interfaceName
是节点的网卡名,可以通过 ip addr
或者 ifconfig
等命令查看。
spec.node
是该节点在k8s中的name,可以通过 kubectl get node
来查看
spec.expectedIPs
是该网卡的ip,这个是必填项。
下面是一个配置好的样例:
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
name: localhost.localdomain-enp0s8
labels:
kubernetes-host: ingress
spec:
interfaceName: enp0s8
node: localhost.localdomain
expectedIPs:
- 192.168.88.5
将上述内容保存到hostendpoint.yaml
中执行 kubectl apply -f hostendpoint.yaml
创建:
[root@localhost calico]# kubectl apply -f hostendpoint.yaml
hostendpoint.projectcalico.org/localhost.localdomain-enp0s8 created
接入calico的HostEndpoint
默认开放了一些端口,官方清单如下:
https://docs.tigera.io/calico/latest/reference/host-endpoints/failsafe
下面是摘抄:
如果想要关闭这里面的部分端口,或者默认在所有节点上开放其他端口,可以通过配置 FelixConfiguration
来完成,官方文档地址为: https://docs.tigera.io/calico/latest/reference/resources/felixconfig 。
如果想要修改,可以通过kubectl edit FelixConfiguration default
来修改配置,下面是一个样例,默认开放的端口仅保留了22,其他全部删掉了(实际操作过程不要这么做!这里只是为了方便演示,仅仅保留一个)。
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
name: default
spec:
bpfLogLevel: ""
floatingIPs: Disabled
healthPort: 9099
logSeverityScreen: Info
reportingInterval: 0s
failsafeInboundHostPorts:
- port: 22
protocol: tcp
设置好默认开放的端口后,下一步一般是拒绝其他的ip,仅保留指定的ip可以访问,下面是一个样例:
apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: allow-cluster-internal-ingress-only spec: # 生效顺序从小到大排序,后面再增加开放端口的策略时,order < 20, 即可在这之前生效 order: 20 preDNAT: true applyOnForward: true ingress: # 首先接受白名单的所有请求 - action: Allow source: # source 配置方法可以参考 https://docs.tigera.io/calico/latest/reference/resources/networkpolicy#entityrule nets: - 192.168.88.0/24 # 然后拒绝白名单ip以外的所有请求 - action: Deny source: # Deny规则要加上排除白名单的网段,理论上不需要这个,但是遇到过奇怪的BUG,没加上导致把上面开放的ip都Drop掉了 notNets: - 192.168.88.0/24 selector: has(kubernetes-host) # 选择器。选择了包含kubernetes-host标签的所有HostEndpoint
apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: allow-external-port-ingress spec: order: 10 preDNAT: true applyOnForward: true ingress: # 放通目标是指定端口的所有请求 当然也可以增加source字段指定来源ip/ip段 - action: Allow destination: # 配置方法可以参考 https://docs.tigera.io/calico/latest/reference/resources/networkpolicy#entityrule ports: - 3306 - 30030 selector: has(kubernetes-host) # 选择器。选择了包含kubernetes-host标签的所有HostEndpoint
注意这里的selector可以给某一两个节点打上特殊标签,选择到指定的一两个节点,给他们开放端口。
更多细节请查阅官方文档,这里仅给出了少量用法,官方支持的功能还是很多的。
查看已有的网络策略:
kubectl get GlobalNetworkPolicy
kubectl describe GlobalNetworkPolicy xxx
修改已有的网络策略
kubectl edit GlobalNetworkPolicy xxx
删除网络策略
kubectl delete GlobalNetworkPolicy xx
HostEndpoint的操作也是一样的,只是把GlobalNetworkPolicy
改成HostEndpoint
就可以了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。