Ubuntu K8s集群安全加固方案
在Ubuntu系统上部署Kubernetes集群时,若服务器拥有外网IP,需采取多层次安全防护措施以确保集群安全。本方案通过系统防火墙配置、TLS通信启用、网络策略实施和RBAC权限控制四个核心层面,构建安全的Kubernetes环境。安全防护不应仅停留在单点措施,而应形成纵深防御体系,从物理主机到集群控制面再到应用层进行全面保护。在生产环境中,需确保所有安全配置均符合最小权限原则,并定期进行审计与监控。
一、基础系统安全配置
Ubuntu服务器作为Kubernetes集群节点,其基础系统安全至关重要。首先,需确保系统时间同步,这可以通过安装NTP服务并配置可靠的NTP服务器实现。在Ubuntu上,可使用以下命令安装并配置NTP服务:
bash
sudo apt update
sudo apt install ntpdate ntp
sudo ntpdate ntp1.aliyun.com
其次,应禁用Swap功能。Kubernetes要求所有节点禁用Swap,可通过编辑/etc/fstab
文件并注释掉Swap行实现,然后执行swapoff --all
命令。
然后,配置容器运行时环境。对于Ubuntu系统,推荐使用Docker或Containerd作为容器运行时。Docker安装命令如下:
bash
sudo apt-get update
sudo apt-get install docker.io
Containerd安装命令如下:
bash
sudo apt-get update
sudo apt-get install containerd
此外,还需调整Linux内核参数以支持Kubernetes网络需求。在Ubuntu上,可通过以下命令修改内核参数:
bash
cat >> /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl -p
这些内核参数确保了容器网络和Kubernetes组件之间的正常通信。
二、防火墙规则配置
Ubuntu服务器的防火墙规则是保护集群的第一道防线,需对非必要端口进行限制,仅开放API Server等必需端口。默认情况下,UFW(Uncomplicated Firewall)是Ubuntu的默认防火墙配置工具,提供了一个用户友好的界面来管理Linux系统的Netfilter防火墙。
首先,安装并启用UFW防火墙:
bash
sudo apt update
sudo apt install ufw
sudo ufw enable
启用UFW后,默认拒绝所有入站连接,仅允许已明确允许的连接。这是符合安全原则的默认策略。
针对Kubernetes集群,需开放以下关键端口:
端口 | 协议 | 用途 | 访问控制 |
---|---|---|---|
22 | TCP | SSH管理 | 仅允许特定IP或子网访问 |
6443 | TCP | API Server | 仅允许集群内节点或管理IP访问 |
10250 | TCP | Kubelet API | 仅允许集群内节点访问 |
10255 | TCP | Kubelet只读端口 | 仅允许集群内节点访问 |
53 | TCP/UDP | DNS服务 | 仅允许集群内节点访问 |
2379/2380 | TCP | etcd集群通信 | 仅允许主节点间通信 |
具体UFW规则配置示例如下:
bash
# 允许SSH管理访问
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp
# 允许API Server访问(仅限集群内节点)
sudo ufw allow from 10.0.0.0/24 to any port 6443 proto tcp
# 允许etcd集群通信(仅限主节点间)
sudo ufw allow from <主节点IP1> to any port 2379 proto tcp
sudo ufw allow from <主节点IP2> to any port 2379 proto tcp
# 允许kubelet API访问(仅限集群内节点)
sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp
# 允许DNS服务访问(仅限集群内节点)
sudo ufw allow from 10.0.0.0/24 to any port 53 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 53 proto udp
# 设置默认策略为拒绝所有入站连接
sudo ufw default deny incoming
特别注意:NodePort服务端口范围(30000-32767)仅在必要时开放,且建议限制访问来源为特定管理IP。若集群不使用NodePort服务,应完全关闭此端口范围。
最后,保存并应用UFW规则:
bash
sudo ufw reload
sudo ufw status numbered
通过UFW规则配置,确保了只有授权流量才能访问服务器,大大降低了被攻击的可能性。
三、TLS安全通信配置
在Kubernetes集群中,TLS安全通信是保护控制平面和数据传输的关键机制 。在初始化集群时,通过kubeadm init
命令启用TLS通信,并配置证书管理及设置token有效期。
首先,使用以下命令初始化主节点:
bash
sudo kubeadm init \
--apiserver-advertise-address=内网IP \
--apiserver-cert-extra-sans=外网IP \
--pod-network-cidr=10.244.0.0/16
其中,--apiserver-cert-extra-sans
参数至关重要,它允许为API Server证书添加额外的Subject Alternative Name(SAN),确保API Server可通过外网IP或域名安全访问。
初始化完成后,立即创建带有效期的引导token:
bash
sudo kubeadm token create --validity 24h --print-join-command
建议将默认token有效期设置为24小时 ,而非使用永久有效的token。这可以通过修改kubeadm
配置文件并指定--token-ttl
参数实现。
接下来,检查证书有效期:
bash
sudo kubeadm certs check-expiration
控制面证书默认有效期为1年,这符合生产环境的安全要求。若需延长有效期,可通过修改kubeadm
配置文件中的certificates.duration
字段实现,但不建议超过1年,以降低维护复杂性。
最后,手动续签证书(若需要):
bash
sudo kubeadm certs renew all
续签证书后,需重启相关组件:
bash
systemctl restart kubelet
kubectl delete pod -n kube-system -l k8s-app=kube-apiserver
kubectl delete pod -n kube-system -l k8s-app=kube-controller-manager
kubectl delete pod -n kube-system -l k8s-app=kube-scheduler
通过以上配置,确保了Kubernetes集群内部通信的安全性,避免了未经加密的HTTP流量传输。
四、网络策略插件部署与配置
部署网络策略插件如Calico是实施Pod间通信限制和命名空间隔离的关键步骤。Calico不仅提供CNI(容器网络接口)功能,还支持强大的网络策略功能,能够实现细粒度的Pod间通信控制。
首先,下载Calico的YAML配置文件:
bash
curl https://docs.projectcalico.org/manifests/calico.yaml -O
然后,应用Calico配置:
bash
kubectl apply -f calico.yaml
部署完成后,验证Calico组件状态:
bash
kubectl get pods -n calico-system
确保所有Calico Pod均处于Running
状态。
接下来,实施网络策略。建议首先启用全局拒绝策略,作为安全基线:
yaml
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-deny
spec:
selector: all()
types:
- Ingress
- Egress
应用全局拒绝策略:
bash
kubectl apply -f global-network-policy.yaml
然后,针对DNS服务创建例外策略:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: kube-system
- podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
应用DNS例外策略:
bash
kubectl apply -f dns-policy.yaml
命名空间隔离示例 :对于敏感命名空间如database
,可创建完全隔离策略:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: database
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- ipBlock:
cidr: 10.0.0.0/16
- ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
此策略拒绝所有入站流量,并仅允许出站流量访问集群内DNS服务。
网络策略实施应遵循分阶段原则:首先在测试命名空间验证策略,确认策略生效且不影响正常功能后,再逐步扩展到生产环境。避免因策略配置错误导致集群网络中断。
五、RBAC权限控制与审计
Kubernetes的RBAC(基于角色的访问控制)是实现权限最小化的核心机制。通过Role、ClusterRole、RoleBinding和ClusterRoleBinding,可为不同用户和服务账户分配精确的权限。
首先,为开发人员创建最小权限角色:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev-namespace
name: dev-namespace-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list", "create", "update", "delete"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "update", "delete"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
然后,将角色绑定到开发人员:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-namespace-binding
namespace: dev-namespace
subjects:
- kind: User
name: dev-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: dev-namespace-role
apiGroup: rbac.authorization.k8s.io
限制默认账户权限 是关键安全措施。对于default
ServiceAccount,可创建只读角色:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
然后,将只读角色绑定到default
ServiceAccount:
yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: Role
name: pod-reader-role
apiGroup: rbac.authorization.k8s.io
定期审计集群资源和日志是安全运维的重要环节。可通过以下步骤启用API Server审计日志:
- 创建审计策略文件
/etc/kubernetes/audit/audit-policy.yaml
:
yaml
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: RequestResponse
verbs: ["delete", "deletecollection", "patch", "update"]
- level: Metadata
verbs: ["get", "list", "watch"]
users: ["system:kube-proxy"]
- level: None
verbs: ["watch"]
users: ["system:kube-proxy"]
resources:
- group: ""
resources: ["endpoints", "services"]
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*"
- "/version"
- 修改
kube-apiserver
配置文件:
yaml
- --audit-policy-file=/etc/kubernetes/audit/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit.log
- --audit-log-maxsize=100
- --audit-log-maxbackup=5
- --audit-log-maxage=30
- 重启kubelet服务使配置生效:
bash
systemctl restart kubelet
审计日志文件位于/var/log/kubernetes/audit.log
,可通过以下命令查看:
bash
kubectl get --raw /api/v1/namespaces/kube-system/pods/kube-apiserver-<节点名称>/log?container=kube-apiserver
审计日志分析 可通过kube-audit
等工具实现。首先安装kube-audit
:
bash
go get -u github.com/Shopify/kube-audit
然后分析审计日志:
bash
kube-audit -f /var/log/kubernetes/audit.log
定期审计流程建议包括:
- 每周检查审计日志中的敏感操作(如资源删除、角色绑定变更)。
- 每月审查RBAC权限配置,确保所有账户和服务账户均遵循最小权限原则。
- 每季度进行全集群安全评估,使用工具如
kube-bench
检查Kubernetes安全配置。
通过以上措施,可有效监控集群中的权限使用情况,及时发现并阻止未授权操作。
六、安全加固的最佳实践
在Ubuntu上部署Kubernetes集群时,应遵循以下最佳安全实践:
-
使用专用网络:将集群节点部署在专用网络上,避免直接暴露于互联网。若必须通过外网访问API Server,应配置负载均衡器或反向代理,并通过IP白名单限制访问来源。
-
启用Pod安全策略(PSP):虽然Kubernetes 1.25+已弃用Pod安全策略API,但可通过准入控制器(如OPA Gatekeeper)实现类似功能,限制Pod的特权操作。
-
使用加密的Secret :敏感信息如数据库密码、API密钥等应使用Kubernetes Secret存储,并通过
kubectl create secret
命令创建。 -
定期更新系统:保持Ubuntu系统和Kubernetes组件的最新版本,及时修复已知漏洞。
-
使用安全的容器镜像:从可信来源获取容器镜像,并通过镜像扫描工具(如Trivy、Clair)检查镜像安全。
-
实施定期备份:对集群关键数据(如etcd、证书)进行定期备份,确保在出现安全事件时能够快速恢复。
-
配置监控与告警:使用Prometheus和Grafana监控集群运行状态,设置告警规则(如异常API调用、资源使用异常)。
-
使用网络策略插件:除Calico外,还可考虑使用Cilium等支持更复杂网络策略的插件,实现东西向流量控制和零信任网络架构。
安全措施 | 实施步骤 | 预期效果 |
---|---|---|
防火墙配置 | 使用UFW限制非必要端口访问 | 降低外部攻击面 |
TLS启用 | 通过kubeadm init配置证书 | 确保控制平面通信安全 |
网络策略 | 部署Calico并配置全局拒绝策略 | 实现Pod间通信限制和命名空间隔离 |
RBAC控制 | 创建最小权限角色并定期审计 | 确保权限最小化和使用合规 |
审计日志 | 启用API Server审计日志并分析 | 监控集群操作行为,及时发现异常 |
安全加固是一个持续的过程,而非一次性任务。建议建立安全运维的SOP(标准操作流程),定期更新安全策略,应对不断变化的安全威胁。
七、安全加固后的集群验证
完成安全加固后,需进行以下验证以确保配置生效:
-
防火墙规则验证 :使用
ufw status
查看当前规则,确认仅开放必要端口。通过nc -zv <服务器IP> <端口>
测试端口连通性,确保非授权IP无法访问受限端口。 -
TLS通信验证 :使用
kubectl cluster-info
检查API Server是否通过HTTPS访问。访问https://<API Server IP>:6443
并检查证书是否有效。 -
网络策略验证 :创建两个测试Pod,分别位于不同命名空间,尝试相互访问。通过
kubectl exec -it <pod名称> -- ping <目标pod IP>
测试通信是否被策略阻止。 -
RBAC权限验证:使用不同账户尝试执行敏感操作(如创建命名空间、删除资源),确认权限控制是否生效。
-
审计日志验证 :检查审计日志文件
/var/log/kubernetes/audit.log
,确认审计事件是否被正确记录,并使用kube-audit
分析日志内容。
通过以上验证步骤,可确保安全加固措施已正确实施,并为后续安全运维奠定基础。
八、结论与建议
在Ubuntu系统上部署Kubernetes集群时,外网IP的存在增加了安全风险,需采取多层次安全防护措施。从系统防火墙到TLS通信,再到网络策略和RBAC权限控制,每一层都至关重要。生产环境中应遵循最小权限原则,定期进行安全审计与监控,确保集群安全。
建议在部署Kubernetes集群前,先完成基础系统安全加固,包括禁用Swap、配置NTP同步时间等。然后,通过UFW防火墙限制非必要端口访问,仅开放API Server等必需端口。初始化集群时,启用TLS安全通信,并设置引导token有效期。部署网络策略插件如Calico,实施Pod间通信限制和命名空间隔离。最后,配置RBAC权限控制,限制默认账户权限,建立定期审计与日志分析流程。
安全防护不应仅停留在配置层面,而应形成持续的安全运维文化。建议定期参加安全培训,关注Kubernetes安全动态,及时更新安全策略。同时,建立安全事件响应机制,确保在出现安全问题时能够快速应对和恢复。
说明:报告内容由通义AI生成,仅供参考。