zhuhaiqiang
作者zhuhaiqiang2020-01-03 14:07
项目经理, 银行

Kubernetes 容器平台安全实施方案

字数 5853阅读 4255评论 0赞 2

Kubernetes 容器平台的安全,牵涉到平台的各个层面:服务器,操作系统, Docker 运行环境,容器, Kubernetes 运行环境等。
容器运行在服务器上,服务器和操作系统安全应该是容器平台安全的第一道防线。关于主机和内核安全的资料和文档已经非常的丰富,不是我们这篇文档关注的重点,我们以下就其他几个层面展开。

Docker 运行环境

Docker 运行环境是和运行 Docker 进程相关的操作系统环境,安全实施方案如下:

  1. 参考 CIS 的 Docker 安全基线[1] 对 Docker 运行环境进行安全审计,比如不使用 Aufs,为容器存储建立单独的系统分区等。另外,Docker-bench-security[2] 是基于 CIS 安全基线定制的检测脚本,可以用于安全基线的审计。
  2. 运行 Docker 进程监听在 UNIX 套接字,一般是 /var/run/docker. sock,不使用网络套接字。
  3. 尽量避免把 Docker 套接字挂接到容器里。

容器运行安全

容器不运行的时候叫做镜像,运行的时候叫做容器。容器运行安全自然也包括镜像安全。安全实施方案如下:

  1. 只从信任的镜像仓库获取镜像,避免随意下载镜像。
  2. 对私有镜像仓库的镜像进行安全扫描。比如 CoreOS 的 Clair,已经集成到 Harbor 里。
  3. 上传镜像的时候对镜像进行签名。容器内容信任机制[3]能够保证镜像发布者和镜像内容的完整性,Docker 集成了 Notray[4] 来管理镜像签名。
  4. 客户端开启内容安全机制。设置环境变量 DOCKERCONTENTTRUST 为 1 ,开启内容安全机制,只下载签名的镜像。
  5. 生产和预生产系统只允许从私有镜像仓库下载镜像。
  6. 尽量用非 root 用户运行容器。
  7. 如果用 root 用户运行容器,避免使用 priviledged 模式,而是根据应用的需求把特定的 Linux 能力授权给容器。
  8. 在容器中设置 Seccomp、AppArmor、SELinux 安全策略,减少能够调用的系统资源,增强容器安全边界。

Kubernetes 运行安全

Kubernetes 运行安全包括两个主要方面,一是 Kubernetes 核心控制组件运行安全,二是通过配置、策略保障运行在 Kubernetes 集群中的应用、服务、数据的安全。下面我们分别描述其安全实施方案。
Kubernetes 核心组件安全
Kubernetes 集群核心组件包括 etcd 集群、API Server、Controller Manager、Scheduler、Kubelet、Kube-proxy、Calico 网络插件,这些组件共同构成了 Kubernetes 控制平面。其安全主要是通过 TLS 双向验证和通信加密来实现。
etcd 集群

  • 配置参数 cert-file、key-file、trusted-ca-file,并将 client-cert-auth 设置为 true ,对所有来自客户端的 https 请求进行 CA 验证。
  • 配置参数 peer-cert-file、 peer-key-file、 peer-trusted-ca-file,并将 peer-client-cert-auth 设置为 true,对所有来自对端的 https 请求进行 CA 验证。
    * API Server*
  • 设置参数 tls-cert-file、-tls-private-key-file、client-ca-file,对所有来自客户端的 https 请求进行 CA 验证。
  • 设置参数 etcd-certfile、etcd-keyfile、etcd-cafile,并设置 etcd-servers 的访问方式为 https ,用 TLS 加密协议访问 etcd 集群。
  • 设置参数 kubelet-client-certificate、 kubelet-client-key、kubelet-certificate-authority,用 TLS 加密协议访问 Kubelet。

Controller Manager

  • 设置 kubeconfig 参数,在 kubeconfig 配置文件中使用 TLS 加密协议访问 API Server,并设置 CA,cert,key 等密钥。

Scheduler

  • 设置 kubeconfig 参数,在 kubeconfig 配置文件中使用 TLS 加密协议访问 API Server ,并设置 CA,cert,key 等密钥。
    * Kubelet*
  • 设置 kubeconfig 参数,在 kubeconfig 配置文件中使用 TLS 加密协议访问 API Server ,并设置 CA,cert,key 等密钥。
  • 设置参数 anonymous-auth 为 false,禁止非授权访问。同时设置 client-ca-file 参数,对由该 CA 签发的客户端请求进行身份认证。
  • 设置参数 read-only-port 为 0 ,关闭不安全的只读端口。
  • 设置参数 tls-cert-file、tls-private-key-file,提供 Kubelet 服务端密钥。

如果不设置这两个参数, Kubelet 会自动生成自签名证书和密钥,这时 Prometheus 无法直接访问其安全端口 10250 获取 Kubelet 服务指标和 cAdvisor 指标。
Kube-proxy

  • 设置 kubeconfig 参数,在 kubeconfig 配置文件中使用 TLS 加密协议访问 API Server,并设置 CA,cert,key 等密钥。

Calico 网络插件

  • 设置参数 etcd ca cert_ file、etcd certfile、etcdkeyfile,并设置 etcd _endpoint 参数使用 TLS 加密协议访问 etcd 集群。

Kubernetes 应用环境安全

* API 认证*
Kubernetes 集群有两类用户:服务帐号、普通用户。
普通用户认证建议采用以下几种方式:

  • X509 客户端证书,通过 CA 进行双向授权,具有很好的安全性。
  • OpenID Connect Tokens,支持通过第三方平台,比如 LDAP 来进行用户身份认证;
  • Webhook 令牌认证,可以让用户使用自己订制的认证方式,用户只需要按照约定的请求格式和应答格式提供 HTTPS 服务。当用户把承载令牌放到请求的头部, Kubernetes 会把令牌发送给事先配置的地址进行认证,如果认证结果成功,则认为请求用户合法。

服务帐号应用程序身份认证通过服务帐号来实现。对服务帐号的使用建议如下:

  • 为每个需要访问 API Server 的应用设置独立的服务帐号
  • 不需要访问 API Server 的应用可以在 Pod 里设置参数 automountServiceAccountToken 为 false 来避免挂载服务帐号。
    * API 授权*
    在 Kubernetes 中,用户通过认证之后,还需要授权,来确定在集群中能干些什么。API 授权通过配置 API Server 参数 authorization-mode 来指定要运行的授权模块插件。
    建议的 authorization-mode 配置是:Node,RBAC 。
    其中,Node 模块用于对 Kubelet 授权,设定 Kubelet 允许对 API 进行的操作。结合准入控制插件 NodeRestriction,可以限制 Kubelet 只能修改本节点的 Node API 对象,和运行在本节点的 Pod API 对象。前提是 Kubelet 的身份认证为属于“ system: nodes ”组,并且具有“ system :node:”格式的用户名。
    RBAC 模块对所有的用户基予角色授权。每个用户和一个或多个角色绑定,角色具有对 API 对象的各种操作权限,从而灵活地赋予每个用户不同的权限。
    准入控制
    在用户认证、授权之后,还需要经过准入控制插件处理通过,API Server 才会处理用户的请求。
    准入控制插件可以对用户请求的资源对象进行校验、修改,提高集群安全性。通过设置 API Server 参数 enable-admission-plugins(Kubernetes v 1.10 之前使用参数 admission-controller)来开启准入控制插件,系统默认和我们推荐开启的准入控制插件列表为( Kubernetes v1.13 为例):
    NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeClaimResize,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,Priority ,NodeRes triction
    这些准入控制插件的具体功能请参考 Kubernetes 官方文档[5]。* 限制集群资源使用*
    结合准入控制插件 ResourceQuota 和 LimitRanger,我们可以限制一个命名空间允许使用的资源,避免恶意攻击或者用户的失误大量使用各种资源导致集群的崩溃。
    这些资源包括内存、CPU、存储、Pods、Services、卷和 PVC 等。
    例如,为命名空间 default 创建一个 ResourceQuota:
  1. apiVersion: v1
  2. kind: ResourceQuota
  3. metadata:
  4. name: compute-resources
  5. spec:
  6. hard:
  7. pods: "500"
  8. requests.cpu: "100"
  9. requests.memory: 500Gi
  10. limits.cpu: "200"
  11. limits.memory: 2000Gi
  12. glusterfs.storageclass.storage.k8s.io/requests.storage: 5000Gi

以上 Resource Quota 创建后,要在这个命名空间运行的所有 Pod 必须设置内存和 CPU 资源需求。建议设置 LimitRange 为没有配置计算资源的 Pod 设置缺省值。
例 如:

  1. apiVersion: v1
  2. kind: LimitRange
  3. metadata:
  4. name: custom-limit-range
  5. spec:
  6. limits:
    • default:
  7. memory: 512Mi
  8. cpu: "1"
  9. defaultRequest:
  10. memory: 128Mi
  11. cpu: "0. 1 "
  12. type: Container

制网络访问
使用网络策略来限制 Pod 之间的网络访问,特别是命名空间之间的网络隔离,对 Kubernetes 生产环境的安全尤为重要。
控制容器安全级别
使用 Pod Security Policy(PSP)来控制容器运行的安全级别。
PSP 能够限制容器以非 root 身份,或是以非特权模式运行,还能屏蔽运行时的系统特权,如访问主机网络,主机进程空间等,特别是限制对主机文件系统目录的挂载,极大地增强了 Kubernetes 容器平台的安全性。
同时, PSP 还能够和节点操作系统的安全特性 Seccomp、AppArmor、SELinux 相结合,进一步加强容器的隔离性。* 控制 Pod 运行的节点分布和优先级*
Kubernetes 提供了丰富的策略来控制 Pod 在集群节点上的分布,如节点亲和特性、Pod 间亲和和反亲和性、Taints 和 Tolerations 等。我们可以灵活运用这些能力来实现以下安全策略:

  • 节点分组,把对隔离性要求很高的应用运行在单独的节点组里,实现物理上的隔离。
  • 把关键服务的多个副本运行在不同的物理节点,甚至是不同的故障域内,增强对安全风险的抵抗力。
  • 系统服务以高优先级运行,优先得到调度,除了保证 Kubernetes 生产环境的稳定性,也提高了对 DDOS 攻击的承压能力。
    * 输出审计日志*
    Kuberentes 审计功能提供了一组与安全相关的记录,按照时间顺序,记录了各个用户、系统管理员或各系统组件对系统有影响的活动。这些审计日志建议保存到独立的安全服务器,以便在安全事件发生的时候可以进行事后分析和追溯。* 密码保护*
    密码在各种应用中使用非常广泛,尤其在 Kubernetes 环境中,密码必须通过非常安全的方式传递到 Pod 里面,并且不能记录在 yaml 文件中,因为 yaml 文件可能会被上传到 Git 代码仓库里。
    我们对密码保护有以下建议:
  • 对需要密码的应用,如数据库,最好采用 Helm 来部署,可以通过命令行参数把密码传递进去,并且尽量采用随机生成密码。
  • 密码统一存放在 Secret 资源里, Pod 通过环境变量从 Secret 读入密码。
  • 为 Secret 资源设定更高的访问权限,不开放给普通用户。
  • 配置 Encryption at rest 功能,对存放在 etcd 中的 Secret 加密。
  • 使用密码管理软件 Hashicorp Vault[6] 来集中管理密码。
    * 节点安全*
    关于集群节点的安全建议如下:
  • 通过防火墙或 Iptables 限制对集群节点的访问。
  • 不使用口令,而是采用 SSH 密钥登录节点。

相关链接:

  1. https://www.cisecurity.org/cis-benchmarks/
  2. https://github.com/docker/docker-bench-security
  3. https://docs.docker.com/engine/security/trust/content_trust/
  4. https://github.com/theupdateframework/notary
  5. https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
  6. https://www.vaultproject.io/

作者:鲁肃,来自瑞幸咖啡基础架构团队。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

2

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广