首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设置Kubernetes网络政策 - 详细指南

设置Kubernetes网络政策 - 详细指南

作者头像
CNCF
发布2019-12-04 11:19:49
4400
发布2019-12-04 11:19:49
举报
文章被收录于专栏:CNCFCNCF

这篇客座文章由StackRox技术人员Viswajith Venugopal撰写,最初发布在Stackrox上。

https://www.stackrox.com/post/2019/04/setting-up-kubernetes-network-policies-a-detailed-guide/

容器编排战争结束了,Kubernetes赢了。随着大大小小的公司迅速采用该平台,安全性已成为一个重要问题 - 部分原因在于了解任何新基础架构所固有的学习曲线,部分原因是最近公布的漏洞。

Kubernetes带来另一种安全考虑 - 它的默认设置旨在使用户能够轻松地快速启动和运行,以及向后兼容缺乏重要安全功能的早期版本的Kubernetes。因此,默认情况下,许多重要的Kubernetes配置都不安全。

从安全角度来看需要注意的一个重要配置是网络政策功能。网络政策指定允许pod组与彼此和其他网络端点进行通信的方式。你可以将它们视为Kubernetes等同于防火墙。

另外,如果你还没有这样做,请升级到最新的Kubernetes版本,因为最近的Kubernetes更新已经解决了一些最关键的Kubernetes安全问题。

如何设置网络政策

我们在此列出了有关如何设置网络政策的分步指南。网络政策规范错综复杂,可能难以正确理解和使用。在本指南中,我们提供了可显着提高安全性的建议。用户可以轻松应用这些建议,而无需详细了解规范。

快速说明:本指南仅关注入口(ingress)网络政策。在开始时,最大的安全性收益来自应用入口政策,因此我们建议首先关注它们,然后添加出口(egress)政策。我们将详细讨论出口政策,并在本系列的后续文章中提供建议。

使用支持网络政策的网络插件

首先要做的事情 - 使用实际执行网络政策的网络插件。虽然Kubernetes总是支持对NetworkPolicy资源的操作,只是创建没有实现它的插件的资源将没有任何效果。示例插件包括Calico、Cilium、Kube-router、Romana和Weave Net。

“隔离”你的pod

每个网络政策都有一个podSelector字段,用于选择一组(零个或多个)pod。当网络政策选择了pod时,称该网络政策适用于该pod。

每个网络政策还指定允许(入口和出口)连接的列表。创建网络政策后,其应用到的所有pod允许建立或接受列出的连接。换句话说,网络政策本质上是允许连接的白名单 - 如果至少有一个适用于该pod的网络政策允许,则允许与pod之间的连接。

然而,这个故事有一个重要的转折:基于到目前为止所描述的所有内容,人们会认为,如果没有网络政策应用于pod,则不允许与其进行任何连接。事实恰恰相反:如果没有网络政策适用于pod,则允许与其进行的所有网络连接。

这种行为与“隔离”的概念有关:如果至少有一个网络政策适用于它们,那么它就是“隔离的”;如果没有适用的政策,它们是“非隔离的”。不对非隔离的pod执行网络政策。尽管有些反直觉,这种行为的存在使得集群的启动和运行变得更加容易 - 不了解网络政策的用户可以运行他们的应用程序而无需创建网络政策。

因此,我们建议你首先应用“default-deny-all”网络政策。以下政策规范的作用是隔离所有pod,这意味着只允许其他网络政策明确列入白名单的连接。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress

如果没有这样的政策,很容易遇到删除网络政策的情况,希望禁止其中列出的连接,但发现结果是所有与某些pod的连接突然被允许 - 包括那些没有以前不允许。当你删除的网络政策是唯一应用于特定pod的网络政策时,会出现这种情况,这意味着删除网络政策会导致pod变为“非隔离”。

重要说明:由于网络政策是命名空间资源,因此你需要为每个命名空间创建此政策。你可以通过为每个命名空间运行kubectl -n create -f来实现。

明确允许需要访问Internet的pod

使用default-deny-all政策,你的任何pod都不能相互通信或从Internet接收流量。要使大多数应用程序正常工作,你需要允许一些pod从外部源接收流量。允许此设置的一种便捷方式是指定你希望允许从Internet访问的那些pod的标签,并创建以这些标签为目标的网络政策。例如,以下网络政策允许具有“networking/allow-internet-access=true”标签的pod的所有(包括外部)源的流量:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internet-access
spec:
  podSelector:
    matchLabels:
      networking/allow-internet-access: "true"
  policyTypes:
  - Ingress
  ingress:
  - {}

对于更加锁定的政策集,理想地你希望指定更细粒度的CIDR块以及明确列出允许的端口和协议。但是,此政策提供了一个良好的起点,具有比默认值更高的安全性。

明确允许必要的pod-to-pod通信

完成上述步骤后,你还需要添加网络政策以允许pod相互通信。根据你的具体情况,你可以选择如何启用pod-to-pod通信:

如果你不知道哪个Pod需要互相交谈

在这种情况下,一个好的起点是允许同一命名空间中的所有pod相互通信并明确地将命名空间列入命名空间,因为这通常更为罕见。你可以使用以下网络政策允许命名空间内的所有pod-to-pod通信:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

如果你知道沟通的来源和汇点

通常,应用程序中的pod之间的通信遵循hub-and-spoke范例,其中有许多其他pod需要与之交谈的中央pod。在这种情况下,你可以考虑创建一个标签,指定允许与“hub集线器”通信的pod。例如,如果你的集线器是数据库pod并且具有app=db标签,则可以通过应用以下政策,仅允许具有networking/allow-db-access=true标签的pod访问数据库:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-db-access
spec:
  podSelector:
    matchLabels:
      app: "db"
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          networking/allow-db-access: "true"

如果你的服务器启动与许多其他pod的连接,你可以执行类似的操作。如果要明确将允许服务器与之通信的pod列入白名单,可以在其上设置networking/allow-server-to-access=true标签,并应用以下网络政策(假设你的服务器具有app=server标签):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-server-to-access
spec:
  podSelector:
    matchLabels:
      networking/allow-server-to-access: "true"
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: "server"

如果你确切知道应该允许哪些连接

在同一名称空间内

准确了解应用程序中应允许哪些pod-to-pod连接的高级用户可以明确允许每个此类连接。如果你希望部署A中的pod能够与部署B中的Pod进行通信,则可以在使用特定部署的标签替换标签后,创建以下政策以将该连接列入白名单:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-server-to-access
spec:
  podSelector:
    matchLabels:
      deployment-b-pod-label-1-key: deployment-b-pod-label-1-value
      deployment-b-pod-label-2-key: deployment-b-pod-label-2-value
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          deployment-a-pod-label-1-key: deployment-a-pod-label-1-value
          deployment-a-pod-label-2-key: deployment-a-pod-label-2-value

跨命名空间

要允许跨命名空间的连接,你需要为源命名空间创建标签(遗憾的是,Kubernetes默认情况下在命名空间上没有任何标签),并在podSelector查询旁边添加namespaceSelector查询。 要标记命名空间,只需运行命令:kubectl label namespace networking/namespace =

使用此命名空间标签,你可以通过应用以下网络政策,允许命名空间N1中的部署A与命名空间N2中的部署B通信:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-n1-a-to-n2-b
  namespace: N2
spec:
  podSelector:
    matchLabels:
      deployment-b-pod-label-1-key: deployment-b-pod-label-1-value
      deployment-b-pod-label-2-key: deployment-b-pod-label-2-value
  policyTypes:
  - Ingress
  ingress:
  - from:
    -  namespaceSelector:
        matchLabels:
          networking/namespace: N1
       podSelector:
        matchLabels:
          deployment-a-pod-label-1-key: deployment-a-pod-label-1-value
          deployment-a-pod-label-2-key: deployment-a-pod-label-2-value

新部署怎么样?

虽然以这种方式明确地将连接列入白名单对于安全性很有用,但这种方法确实会影响可用性。创建新部署时,默认情况下,在应用网络政策之前,它们将无法与任何内容进行通信。为了缓解这种可能令人沮丧的用户体验,你可以创建以下一对网络政策,这些政策允许标记为networking/allow-all-connections=true的pod与同一名称空间中的所有其他pod进行通信:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-from-new
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          networking/allow-all-connections: "true"
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-to-new
spec:
  podSelector:
    matchLabels:
      networking/allow-all-connections: "true"
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector: {}

然后,你可以将networking/allow-all-connections=true标签应用于所有新创建的部署,以便你的应用程序可以运行,直到你为它们创建特制的网络政策,此时你可以删除标签。

总结

虽然这些建议提供了一个良好的起点,但网络政策涉及的范围更广。如果你有兴趣更详细地探索它们,请务必查看Kubernetes教程以及一些方便的网络政策配方。

https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/

https://github.com/ahmetb/kubernetes-network-policy-recipes

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CNCF 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档