在本文中,我们将学习如何使用Calico CNI网络策略构建防火墙功能,来保护Kubernetes集群中的主机。
Kubernetes集群的管理员希望保护其免受集群外部流量的侵害。Calico是一个容器网络接口(CNI)插件,除CNI功能外,还提供网络策略来控制Pod之间的流量以及防火墙功能以保护节点。
为了利用Calico作为防火墙的功能来保护节点,需要基于Calico的GlobalNetworkPolicy在节点上的每个网络接口创建一个HostEndpoint。这是一项一次性工作,可以在安装程序中自动进行。由于节点是短暂的,并且策略可以是动态的,因此即使在安装后,我们也需要一种方法来管理每个主机上的HostEndpoint对象。
有多种Kubernetes方法来完成此任务,例如,
在Kubernetes之外,传统的端点保护方法包括在主机上安装代理,并通过该代理实施策略。
与DaemonSet不同,静态Pod无法通过kubectl或其他Kubernetes API客户端来管理。DaemonSet确保Pod的副本始终在所有或某些主机上运行,并在其他Pod之前开始。本文,我们将使用DaemonSet方式。
DaemonSet解决方案概述
提出的解决方案包括创建一个DaemonSet,它将为每个主机启动一个Pod。如果需要,该Pod将运行一个应用程序来为该主机创建HostEndpoint对象。
例如,我们决定使用HostEndpoint对象实施以下示例策略:
- 允许来自节点的所有出口流量。
- 允许从特定IP地址访问所有节点的入口流量。
- 拒绝任何其他流量。
步骤如下:
创建应用程序
我们将使用Shell脚本编写应用程序。该脚本无限循环,并检查是否为运行它的主机创建了HostEndpoint对象。如果不是,它将使用kubectl客户端为满足需求的主机创建HostEndpoint对象。如果主机已经存在HostEndpoint对象,则它将休眠10秒钟,然后再继续。
请注意,节点的名称是通过环境变量注入到脚本中的。节点名称是使用Downward API获取的,该API允许容器使用有关其自身或Kubernetes集群的信息。
#!/bin/sh while [ true ]; do echo $NODE_NAME kubectl get hostendpoint $NODE_NAME if [ $? -eq 0 ]; then echo "Found hep for node $NODE_NAME" sleep 10 continue fi echo "Creating hep for node $NODE_NAME" kubectl apply -f - kubectl get po NAME READY STATUS RESTARTS AGE hep-ds-9jjtq 1/1 Running 0 2s hep-ds-c97jz 1/1 Running 0 2s hep-ds-fbghm 1/1 Running 0 2s hep-ds-nbllb 1/1 Running 0 2s
检查Pod的日志,以确保其正在为该节点创建HostEndpoint。
> kubectl logs hep-ds-9jjtq k8s-node-2 Error from server (NotFound): hostendpoints.crd.projectcalico.org "k8s-node-2" not found Creating hep for node k8s-node-2 hostendpoint.crd.projectcalico.org/k8s-node-2 created k8s-node-2 NAME AGE k8s-node-2 0s Found hep for node k8s-node-2 k8s-node-2 NAME AGE k8s-node-2 8s Found hep for node k8s-node-2
验证是否为每个节点创建了HostEndpoint。
> kubectl get hostendpoint NAME AGE k8s-master-nf-1 36s k8s-master-nf-2 39s k8s-master-nf-3 36s k8s-node-1 38s k8s-node-2 36s
结论
Kubernetes不提供防火墙功能来保护Kubernetes集群中的主机。我们使用Calico来实现。Calico除了CNI功能之外,它还提供网络策略来控制Pod之间的流量以及防火墙功能以保护节点。该解决方案是Kubernetes原生的,不需要安装任何外部软件。
译文链接:https://dzone.com/articles/protecting-hosts-in-kubernetes-cluster