使用Kubespray进行集群加固(保护Kubespray的安全性!)

首先

在kubespray.io这个看起来像是官方文档页面的网站上,为什么还没有指向相关页面的链接呢(难道还在测试中?)?但是,从Kubespray的Github页面上可以看到,从2022年5月30日起,Kubespray已经添加了一个名为”Cluster Hardening”的页面,用于在CIS Benchmarks方面通过Kubespray进行部署时的配置。这次的目的是介绍这个页面并分享一些小技巧。根据我的观察范围,我没有找到日语解释相关内容的文章…

以下是相关链接:
https://kubespray.io/#/docs/hardening
https://github.com/kubernetes-sigs/kubespray/blob/master/docs/hardening.md

Kubespray到底是什么?

作为创建非托管Kubernetes环境的一种方法之一,它是通过ansible-playbook来进行构建的(参考:Ansible Playbook 是什么)。
它可以用于云环境中准备的虚拟机,也可以用于为家庭Kubernetes群体准备的本地实体机器或虚拟机。
有关ansible的说明和Kubespray本身,请参考先前文章的相关内容。

讲解

暂时的,以下内容是关于“集群加固(Cluster Hardening)”的(截至2022/12/17)。

Kubespray提供了“集群加固”设置集,用于增强安全性。
通过在调用playbook时,使用加固设置覆盖默认配置,以应用这些设置,因此可能需要根据个人环境进行一些微小的更改。

该设置包括启用RBAC和审计、加密密码等,通过仅仅研究相关术语,您将了解Kubernetes中的安全性,并得到一个良好的起点。

硬化.yaml:

# Hardening
---

## kube-apiserver
authorization_modes: ['Node', 'RBAC']
# AppArmor-based OS
# kube_apiserver_feature_gates: ['AppArmor=true']
kube_apiserver_request_timeout: 120s
kube_apiserver_service_account_lookup: true

# enable kubernetes audit
kubernetes_audit: true
audit_log_path: "/var/log/kube-apiserver-log.json"
audit_log_maxage: 30
audit_log_maxbackups: 10
audit_log_maxsize: 100

tls_min_version: VersionTLS12
tls_cipher_suites:
  - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305

# enable encryption at rest
kube_encrypt_secret_data: true
kube_encryption_resources: [secrets]
kube_encryption_algorithm: "secretbox"

kube_apiserver_enable_admission_plugins:
  - EventRateLimit
  - AlwaysPullImages
  - ServiceAccount
  - NamespaceLifecycle
  - NodeRestriction
  - LimitRanger
  - ResourceQuota
  - MutatingAdmissionWebhook
  - ValidatingAdmissionWebhook
  - PodNodeSelector
  - PodSecurity
kube_apiserver_admission_control_config_file: true
# EventRateLimit plugin configuration
kube_apiserver_admission_event_rate_limits:
  limit_1:
    type: Namespace
    qps: 50
    burst: 100
    cache_size: 2000
  limit_2:
    type: User
    qps: 50
    burst: 100
kube_profiling: false

## kube-controller-manager
kube_controller_manager_bind_address: 127.0.0.1
kube_controller_terminated_pod_gc_threshold: 50
# AppArmor-based OS
# kube_controller_feature_gates: ["RotateKubeletServerCertificate=true", "AppArmor=true"]
kube_controller_feature_gates: ["RotateKubeletServerCertificate=true"]

## kube-scheduler
kube_scheduler_bind_address: 127.0.0.1
kube_kubeadm_scheduler_extra_args:
  profiling: false
# AppArmor-based OS
# kube_scheduler_feature_gates: ["AppArmor=true"]

## etcd
etcd_deployment_type: kubeadm

## kubelet
kubelet_authentication_token_webhook: true
kube_read_only_port: 0
kubelet_rotate_server_certificates: true
kubelet_protect_kernel_defaults: true
kubelet_event_record_qps: 1
kubelet_rotate_certificates: true
kubelet_streaming_connection_idle_timeout: "5m"
kubelet_make_iptables_util_chains: true
kubelet_feature_gates: ["RotateKubeletServerCertificate=true", "SeccompDefault=true"]
kubelet_seccomp_default: true
kubelet_systemd_hardening: true
# In case you have multiple interfaces in your
# control plane nodes and you want to specify the right
# IP addresses, kubelet_secure_addresses allows you
# to specify the IP from which the kubelet
# will receive the packets.
kubelet_secure_addresses: "192.168.10.110 192.168.10.111 192.168.10.112"

# additional configurations
kube_owner: root
kube_cert_group: root

# create a default Pod Security Configuration and deny running of insecure pods
# kube_system namespace is exempted by default
kube_pod_security_use_default: true
kube_pod_security_default_enforce: restricted

适用命令示例:

ansible-playbook -v cluster.yml \
        -i inventory.ini \
        -b --become-user=root \
        --private-key ~/.ssh/id_ecdsa \
        -e "@vars.yaml" \
        -e "@hardening.yaml"

关于一些小技巧(如在进行“集群硬化”并在Kubernetes上托管“Prometheus”等时的注意事项)。

如上所述,进行”集群加固”将确保最低限度的安全性,并且我建议您考虑这个选项,但需要注意的是:由于配置重点放在提升安全性上,所以一些应用程序可能无法正常工作。例如,Prometheus在配置上与kubelet进行通信以进行抓取,但直接应用上述配置将导致被防火墙阻止而无法运行。为了应对这个情况,我将介绍需要进行修正的位置。

kube-controller-manager的绑定配置

# kube_controller_manager_bind_address: 127.0.0.1
kube_controller_manager_bind_address: 0.0.0.0 # 127.0.0.1の場合、prometheusからのscrapeに失敗するので、変更します。その代わりに別途FWやNetworkPolicy等で保護する必要があるので注意。

kube-scheduler的绑定配置

# kube_scheduler_bind_address: 127.0.0.1
kube_scheduler_bind_address: 0.0.0.0 # 127.0.0.1の場合、prometheusからのscrapeに失敗するので、変更します。その代わりに別途FWやNetworkPolicy等で保護する必要があるので注意。

etcd的绑定配置

如果不添加下面的设置,将会绑定到127.0.0.1(可能为localhost),导致从prometheus进行抓取失败,因此需要进行更改。请注意,需要通过其他方式如防火墙或网络策略来保护。

etcd_extra_vars:
  listen-metrics-urls: http://0.0.0.0:2381

关于kubelet的防火墙。

kubelet_secure_addresses是使用systemd和iptables的协作功能,根据连接源IP地址限制可以连接kubelet的应用程序的配置。
如果只需要控制平面连接每个工作节点的kubelet,可以选择不设置并注释掉,kubespray会自动为控制平面设置IP地址。
只有在允许来自控制平面以外的IP地址进行通信时才需要进行设置。
但是,如果在Kubernetes集群内自托管Prometheus时,需要允许Prometheus的Pod与kubelet进行通信,因此需要进行额外的配置以允许此通信。
在kubespray设置阶段,无法预测将分配给Prometheus的Pod的IP地址,因此需要一次性设置用于分配给Pod的CIDR。但仅有这一项配置会降低安全性,因此请注意需要通过其他防火墙或NetworkPolicy进行保护。
在我的情况下,我使用Cilium作为CNI,通过使用CiliumClusterwideNetworkPolicy和NodeSelector的主机策略来进行通信控制(实体等非常方便),除了”集群加固”之外。

kubelet_secure_addresses: "[control-plane1のIP] [control-plane2のIP] [control-plane3のIP] [PodのCIDR]"

总结

我在Kubespray的Kubernetes环境部署中介绍了有关安全性的内容。特别是有关bind和FW设置的提示,如果直接应用”Cluster Hardening”可能会遇到问题,希望能对某些人有所帮助。另外,如果我心情好的话,我也许会解释一下本次同时设置的”CiliumClusterwideNetworkPolicy”的内容。如果有兴趣的人,请不要抱太大期待,耐心等待一下。

广告
将在 10 秒后关闭
bannerAds