Kubernetes安全防御,三项原则要谨记

Kubernetes通过以集成方式管理众多容器的能力,在部署、运行和管理容器服务方面提供了许多优势,已经成为很多云平台不可或缺的重要组件和关键服务。

然而Kubernetes的这一特性也可能使应用程序面临安全漏洞。事实上,针对容器的安全攻击呈上升趋势,而且影响越来越严重。因此Kubernetes环境的安全性与任何其他开发或生产环境中的安全性一样重要。

Kubernetes环境中的安全性意味着要维护Kubernetes集群的稳定性和安全性。Kubernetes提供了基础安全功能,以确保集群的安全。这种与安全相关的功能有很多,比如:

  • 网络安全
  • 节点安全
  • 身份验证
  • 授权
  • 安全镜像管理
  • 机密管理
  • 日志和监控
  • 灾难恢复
  • 其他……

本文将介绍其中最具代表性的三项:控制Kubernetes集群访问的网络策略、基于角色的访问控制(RBAC)和安全存储敏感信息的机密信息。

1.借助网络策略控制Pod的通信

Kubernetes的通信策略默认允许所有Pod之间进行通信。虽然这种策略对通信很有用,但也有可能使Pod暴露于不必要的连接中。因此,如果想防止未经授权的访问并保护Pod,就该使用网络策略。

网络策略是一种控制Pod之间或Pod与其他网络端点之间通信的功能。通过网络策略,我们可以根据IP地址、端口、协议和标签等各种条件定义允许或拒绝流量的规则。此外,还可以通过网络策略设置只允许来自某些命名空间的流量。

网络策略是使用Kubernetes网络插件架构实现的。因此,不同网络插件对网络策略的支持程度可能各异。

Kubernetes网络策略

一些流行的网络插件(如Calico、Cilium和Weave Net)原生支持网络策略,而其他插件可能需要额外配置或定制开发。

设置网络策略时,有三个元素非常重要:

  • podSelector:指定策略适用的Pod
  • policyTypes:指定将应用策略的流量。分为入口流量和出口流量
  • ingress/egress:指定入口/出口流量的详细信息。

让我们通过一个示例来了解这三个元素。下面的示例是一个设置网络策略的YAML文件。查看示例中的podSelector,可以看到“database”被指定为应用策略的Pod。通过policyTypes设置,网络策略将同时应用于传入和传出的流量。

最后,定义入口和出口流量的详细策略,定义允许流量的命名空间、Pod、协议和端口号以及IP段。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-nwpolicy
  namespace: default
spec:
  podSelector:                       
    matchLabels:
      role: database
  policyTypes:                       
  - Ingress
  - Egress
  ingress:                            
  - from:
    - ipBlock:                          
        cidr: 10.17.0.0/16
    - namespaceSelector:        
        matchLabels:
          name: my-ns
    - podSelector:               
        matchLabels:
          app: my-pod
    ports:                             
    - protocol: TCP
      port: 6379
  egress:                         
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

通过上述示例可以看出,它对入站和出站流量的控制就像网络服务器上的防火墙或云实例上的安全组一样。这样,通过网络策略,Kubernetes可以确定并控制安装在Pod中的应用程序可以接收哪些网络请求,以及这些请求来自哪里。通过限制集群中Pod的网络流量,即可保护集群免受各种安全攻击。

2. 基于角色的访问控制(RBAC)权限

Kubernetes由许多资源组成,包括服务、网络、命名空间、Pod、节点和容器。限制哪些用户和服务可以访问每种资源对保证集群安全至关重要。

Kubernetes中基于角色的访问控制(RBAC)通过为用户和服务账户定义角色,并根据角色授予权限来控制对集群资源的访问。我们可以使用Roles(为用户或服务账户设置角色)和ClusterRole(在集群级别设置角色)定义安全规则,并将这些规则添加到组(用户集合)中。

基于角色的访问控制包括三个主要概念:

  • Role:是一组授予集群资源访问权限的特权。例如,我们可以定义一个名为“pod-reader”的角色,并授予同一命名空间内所有Pod的读取权限。
  • RoleBinding:将角色分配给特定用户或服务账户。换句话说,是一个将角色和账户进行绑定的函数。例如,将“pod-reader”角色附加给用户“user-1”,这样用户“user-1”就可以读取同一命名空间中的所有Pod。
  • ClusterRole:与Role类似,但权限范围不同。Role分配的权限仅在特定命名空间内有效,而ClusterRole分配的权限在整个集群范围内有效。需要通过ClusterRoleBinding来定义ClusterRole与用户或服务账户之间的关联。

下图展示了基于角色的访问控制的实现机制。

命名空间中的角色和K8s集群中的ClusterRole

我们还可以通过一个例子来了解基于角色的访问控制。下面的示例是一个YAML文件,其中定义了一个名为dev-team的角色。

<role.yaml>
apiVersion: rbac.authorization.k8s.io/v1    
kind: Role
metadata:
  namespace: development        
  name: dev-team            
rules:                     
- apiGroups: ["core", "extensions", "apps"]          
  resources: ["deployments", "replicasets", "pods"]         
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

该角色指定了特定用户或服务账户可以在“开发”命名空间内执行的任务和目标。仔细观察会发现,它将可访问的API组定义为Core、Extensions和Apps,它还提供了对Deployments、ReplicaSets和Pods资源的访问权限。最后,它为资源授予了权限,如get、list和watch。通过这些设置,名为dev-team的角色就可以访问属于apps API组的部署资源,并执行get操作来检查资源的信息和状态。

接下来,我们需要用一个RoleBinding来将创建的角色分配给特定用户。下面的示例声明了一个名称为dev-team-binding的RoleBinding,并设置用户来分配特定角色。该示例为名为dev1的用户分配了一个角色。最后,我们赋予dev1用户dev-team角色。这将允许dev1用户承担上述role.yaml示例文件中定义的角色。

<user-role.yaml>
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: development
  name: dev-team-binding       
subjects:
- kind: User      
   name: dev1
   apiGroup: ""
roleRef:
  kind: Role      
  name: dev-team
  apiGroup: ""

此外,我们还将举例说明如何使用YAML文件创建Role和RoleBinding。下面的示例代码是kubectl命令的运行结果,该命令创建了“development”命名空间,并在该命名空间内创建了Role和RoleBinding。

$kubectl create namespace development
namespace/development created

$kubectl create -f role.yaml   
role.rbac.authorization.k8s.io/dev-team created

$kubectl create -f user-role.yaml   
rolebinding.rbac.authorization.k8s.io/dev-team-binding created

Kubernetes基于角色的访问控制允许集群管理员管理资源的访问。这可以增强安全性,防止滥用造成的风险。我们还可以隔离不同用户和服务账户之间的访问权限,以保护敏感数据不被未经授权的用户查看。

3. 安全地存储敏感数据

Kubernetes Secret是一种用于安全存储敏感数据(如加密信息、令牌和密码)的资源。在Kubernetes中,机密通常用于管理API密钥、数据库密码、OAuth标记等身份验证信息。如果这些敏感信息以纯文本形式包含在Pod的规范文件或容器镜像中,可能会对安全造成威胁。因此,机密信息不会包含在容器镜像中,而是在运行应用程序时通过环境变量或卷挂载传递给容器。

机密存储在ETCD中,通过卷和变量的方式使用

机密通常定义为base64编码的键值对。机密会在容器运行时解密和使用,因此无需在使用机密的应用程序中实施单独的解密逻辑。机密的创建与使用敏感信息的Pod无关,相反,我们需要将敏感信息安全地存储在单独的etcd存储库中,并在Pod需要时将其提供给容器。

让我们创建一个简单的机密示例。创建并保存特定用户的ID和密码作为机密。假设有用户数据"USER_NAME=admin"、"PASSWORD=1f2d1e2e67df"。首先,对信息进行 base64 编码,如下所示:

$echo -n "admin" | base64
YWRtaW4=

$echo -n "1f2d1e2e67df" | base64
MWYyZDFlMmU2N2Rm

然后创建一个YAML文件,用编码后的数据创建一个机密。USER_NAME和PASSWORD的值是base64编码值,但当Pod使用它们时,工作节点上的kubelet会对它们进行解码,并提供给Pod和容器。

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:                                            
  USER_NAME: YWRtaW4=
  PASSWORD: MWYyZDFlMmU2N2Rm

以这种方式创建的机密信息存储在Kubernetes集群控制平面的etcd数据库中。etcd是Kubernetes集群的中央数据存储库,其中存储了多种数据,包括所有Kubernetes资源信息、配置信息和运行时信息。机密也以base64编码方式存储在ETCD中。

请注意,Secret使用的是编码和解码技术,而不是加密技术。因此这并不是一种完美的数据保护方法。一些情况下可能还需要额外的安全措施。

例如,我们可以使用前面学到的RBAC来限制只有授权用户才能访问和使用机密。还可以使用单独的加密插件对机密数据进行完全加密。但这需要外部服务,如密钥管理服务(KMS)。

总之,Kubernetes Secret是保护和管理应用程序使用的敏感信息的重要工具,我们可以借此保护Kubernetes集群中的敏感信息,从而规避很多安全隐患。


至此,我们已经介绍了确保Kubernetes安全的基本功能。事实上,Kubernetes的安全性是一个庞大的话题,本文只是介绍了三个最基本的关键领域。好好利用这三个安全功能,确保Kubernetes的基本安全。

  • 17
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值