Kubernetes NetworkPolicy:打造更安全的容器运行环境

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 传统上,通常使用防火墙实现网络层的访问控制,比如iptables rule,部署应用之后,通过iptables设置运行的ip白名单。在使用Kubernetes之后,由于Pod是动态分配到机器上,而且在运行过程中随时可能迁移到其他机器,显然不适合继续使用手工配置iptables的方式。

常见的应用可以分为两大类:Job和Service。Job比较简单,就是一个普通的任务,完成之后就退出,一般不需要暴露对外服务的网络监听端口。Service是指长期运行的进程,监听某个网络端口,其他服务可以通过网络连过来。生产环境里,将服务暴露在网络上存在安全风险:必须限制只有信任的用户才能访问服务。我们肯定不希望未授权的用户能调用某个删除数据的接口,把DB里的数据删光。访问控制可以在应用层做,客户端访问服务时,带上身份校验信息,服务端校验客户身份,判断客户是否有权限完成请求的操作,如果有权限,执行客户端请求,否则返回一个拒绝信息。访问控制还可以在网络层做,只允许受信的网络段访问服务。两种方式各有优劣,应用层可以做到更细粒度的权限控制,但需要开发,并且要求能客户端/服务器在通信协议上支持鉴权。网络层鉴权不依赖具体应用,还有一个额外的好处是能防DDoS。今天的主题NetworkPolicy,就是一种网络层的访问控制机制。

传统上,通常使用防火墙实现网络层的访问控制,比如iptables rule,部署应用之后,通过iptables设置运行的ip白名单。在使用Kubernetes之后,由于Pod是动态分配到机器上,而且在运行过程中随时可能迁移到其他机器,显然不适合继续使用手工配置iptables的方式。好在Kubernetes考虑到这个需求,提供了Network Policy,通过Network Policy,我们不仅能限制哪些Pod能被哪些来源访问,甚至还能控制Pod能访问哪些外部服务。Kubernetes中的Network Policy只定义了规范,并没有提供实现,而是把实现留给了网络插件。阿里云容器服务的Terway支持Network Policy,接下来我们基于Terway介绍几个使用Network Policy的场景。

创建Terway集群

首先,我们要创建一个使用Terway的集群,也就是在创建集群的时候,网络插件选Terway。

Screen_Shot_2018_09_14_at_2_38_47_PM

等待一会,集群创建好。这是我刚刚创建好的集群,名字就叫terway

Screen_Shot_2018_09_14_at_2_39_35_PM

为了操作方便,我们直接用命令行的方式,先下载kubeconfig文件,保存到本地的$HOME/.kube/config

场景1: 限制服务只能被带有特定label的应用访问

首先部署一个nginx,两个实例,附带一个service

~ % kubectl run nginx --image=nginx
deployment.apps "nginx" created
~ % kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
nginx-65899c769f-c9s8z   1/1       Running   0          24s
~ % kubectl expose deployment nginx --port=80
service "nginx" exposed
~ % kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   172.19.0.1      <none>        443/TCP   21h
nginx        ClusterIP   172.19.32.113   <none>        80/TCP    20s

现在,起一个新应用,访问刚刚创建nginx service

~ % kubectl run busybox --rm -ti --image=busybox /bin/sh

If you don't see a command prompt, try pressing enter.
/ # wget nginx
Connecting to nginx (172.19.32.113:80)
index.html           100% |***************************************************************************************************************************************************|   612  0:00:00 ETA
/ #

看上去没问题,网络是通的。接下来我们设置一个Network Policy,只允许带有label access=true的应用访问nginx,其他都不行。开一个新终端

~ % cat policy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      run: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"
~ % kubectl apply -f policy.yaml
networkpolicy.networking.k8s.io "access-nginx" created

回到运行busybox的终端,再执行一次wget nginx

/ # wget nginx
Connecting to nginx (172.19.32.113:80)

^C
/ #

可以看到,在设置完Policy之后,之前启动的busybox已经不能访问nginx了。我们重新启动一个带有label access=true的busybox

~ % kubectl run busybox --rm -ti --labels="access=true" --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget nginx
Connecting to nginx (172.19.32.113:80)
index.html           100% |***************************************************************************************************************************************************|   612  0:00:00 ETA
/ #

成功!

场景2: 限制能够访问暴露了公网SLB服务的来源IP

给上个场景中的nginx再创建一个LoadBalance类型的service,LoadBalance类型的service会创建一个SLB

~ % cat nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    run: nginx
  name: nginx-slb
spec:
  externalTrafficPolicy: Local
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: nginx
  type: LoadBalancer
~ % kubectl apply -f nginx-service.yaml
service "nginx-slb" created
~ % kubectl get svc nginx-slb
NAME        TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
nginx-slb   LoadBalancer   172.19.89.136   47.95.180.200   80:31967/TCP   17s

我们创建了LoadBalance类型的service,SLB的IP是 47.95.180.200,先从本地请求一下试试:

~ % wget 47.95.180.200
--2018-09-14 08:07:23--  http://47.95.180.200/
Connecting to 47.95.180.200:80... ^C
~ %

网络不通,因为刚才我们设置了nginx只允许带有label access=true的应用访问,现在是我们从外部访问Kubernetes,根本不是Pod,更不要说设置label了。怎么办?

方案是修改之前创建的Network Policy,增加一个允许访问的来源IP段。把自己本地的IP地址加到白名单里去。先拿到自己的IP地址

~ % curl myip.ipip.net
当前 IP:1.2.3.4  来自于:中国 浙江 #我的实际IP不是这个,根据自己的实际情况处理。

然后编辑policy.yaml,把IP地址加进去。有些网络的出口IP有多个,所以这里加上了一个/24的段。100.64.0.0/10必须要带上,SLB健康检查地址在这个段里,不加上的话SLB健康检查会出错。

~ % cat policy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      run: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"
    - ipBlock:
        cidr: 100.64.0.0/10
    - ipBlock:
        cidr: 1.2.3.0/24
~ % kubectl apply -f policy.yaml
networkpolicy.networking.k8s.io "access-nginx" configured

好了,再访问一次

~ % wget 47.95.180.200
--2018-09-14 08:15:03--  http://47.95.180.200/
Connecting to 47.95.180.200:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 612 [text/html]
Saving to: 'index.html'

index.html                                       100%[=========================================================================================================>]     612  --.-KB/s    in 0s

2018-09-14 08:15:03 (67.6 MB/s) - 'index.html' saved [612/612]

网络又通了,完美!

场景3: 限制一个Pod只能访问www.aliyun.com

除了限制当前应用能被谁访问,有时候还要限制应用能访问谁,有时候我们要运行第三方应用,不希望这些应用访问到不该访问的网络。通过Network Policy,也能实现这个需求。

Network Policy只能通过IP地址配置规则,首先我们通过dig获取www.aliyun.com的地址

~ % dig +short www.aliyun.com
www-jp-de-intl-adns.aliyun.com.
www-jp-de-intl-adns.aliyun.com.gds.alibabadns.com.
v6wagbridge.aliyun.com.
v6wagbridge.aliyun.com.gds.alibabadns.com.
140.205.34.3
106.11.93.21
140.205.32.4
140.205.230.13

这样就拿到了域名解析到的IP列表。然后编写如下的Network Policy规则:

~ % cat busybox-policy.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: busybox-policy
spec:
  podSelector:
    matchLabels:
      run: busybox
  egress:
  - to:
    - ipBlock:
        cidr: 140.205.230.13/32
    - ipBlock:
        cidr: 140.205.34.3/32
    - ipBlock:
        cidr: 106.11.93.21/32
    - ipBlock:
        cidr: 140.205.32.4/32
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
    ports:
    - protocol: UDP
      port: 53

~ % kubectl apply -f busybox-policy.yaml
networkpolicy.networking.k8s.io "busybox-policy" configured

在这个规则里,我们配置了egress规则,也就是出网规则,限制应用对外访问。允许UDP请求,否则没法做DNS解析。

验证一下

~ % kubectl run busybox --rm -ti --image=busybox /bin/sh
If you don't see a command prompt, try pressing enter.
/ # wget www.aliyun.com
Connecting to www.aliyun.com (106.11.93.21:80)
Connecting to www.aliyun.com (140.205.230.13:443)
wget: note: TLS certificate validation not implemented
index.html           100% |***************************************************************************************************************************************************|  526k  0:00:00 ETA
/ #
相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
5天前
|
存储 Kubernetes C++
【专栏】Kubernetes VS Docker Swarm了解两者特点,助力选取合适容器编排工具
【4月更文挑战第27天】对比Kubernetes和Docker Swarm:K8s在可扩展性和自动化方面出色,有强大社区支持;Swarm以简易用著称,适合初学者。选择取决于项目需求、团队技能和预期收益。高度复杂项目推荐Kubernetes,快速上手小项目则选Docker Swarm。了解两者特点,助力选取合适容器编排工具。
|
4天前
|
存储 Java Serverless
ACK One Argo 工作流集群:玩转容器对象存储
ACK One Argo 工作流集群:玩转容器对象存储
ACK One Argo 工作流集群:玩转容器对象存储
|
4天前
|
存储 Kubernetes 监控
使用Kubernetes进行容器编排:技术详解与实践
【5月更文挑战第16天】Kubernetes,简称K8s,是开源容器编排系统,用于自动化部署、扩展和管理容器化应用。核心概念包括节点、Pod(最小部署单元)、服务、标签和副本集。其特点有高可用性、可扩展性、自动化和可移植性。实践使用涉及安装配置集群、编写YAML部署清单、应用部署、监控管理和扩展更新。Kubernetes帮助提升应用的可用性、可扩展性和可移植性。
|
5天前
|
分布式计算 Kubernetes 监控
容器服务Kubernetes版产品使用合集之怎么实现把 spark 跑在k8s
容器服务Kubernetes版,作为阿里云提供的核心服务之一,旨在帮助企业及开发者高效管理和运行Kubernetes集群,实现应用的容器化与微服务化。以下是关于使用这些服务的一些建议和合集,涵盖基本操作、最佳实践、以及一些高级功能的使用方法。
28 1
|
5天前
|
Kubernetes Java 调度
Java容器技术:Docker与Kubernetes
Java容器技术:Docker与Kubernetes
35 0
|
5天前
|
监控 安全 数据安全/隐私保护
【Docker专栏】Docker容器安全:防御与加固策略
【5月更文挑战第7天】本文探讨了Docker容器安全,指出容器化技术虽带来便利,但也存在安全隐患,如不安全的镜像、容器逃逸、网络配置不当等。建议采取使用官方镜像、镜像扫描、最小权限原则等防御措施,并通过安全的Dockerfile编写、运行时安全策略、定期更新和访问控制等加固容器安全。保持警惕并持续学习安全实践至关重要。
【Docker专栏】Docker容器安全:防御与加固策略
|
5天前
|
存储 缓存 安全
Golang深入浅出之-Go语言中的并发安全容器:sync.Map与sync.Pool
Go语言中的`sync.Map`和`sync.Pool`是并发安全的容器。`sync.Map`提供并发安全的键值对存储,适合快速读取和少写入的情况。注意不要直接遍历Map,应使用`Range`方法。`sync.Pool`是对象池,用于缓存可重用对象,减少内存分配。使用时需注意对象生命周期管理和容量控制。在多goroutine环境下,这两个容器能提高性能和稳定性,但需根据场景谨慎使用,避免不当操作导致的问题。
35 4
|
5天前
|
存储 安全 Cloud Native
容器安全-镜像扫描
容器镜像安全至关重要,镜像扫描能检查镜像中的安全漏洞,防范云原生环境风险。72%客户拥有超过100个容器,安全问题日益凸显。两种扫描方案:定期扫描镜像注册表或集成到Pipeline中。此外,蜂巢提供全生命周期镜像扫描,包括漏洞、病毒检测,实时更新补丁数据库,并给出修复建议,助力企业保障容器安全。目前已服务100+头部客户。
|
5天前
|
运维 Kubernetes Linux
10分钟搭建Kubernetes容器集群平台(kubeadm)
10分钟搭建Kubernetes容器集群平台(kubeadm)
|
5天前
|
Kubernetes 应用服务中间件 Docker
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件
Kubernetes学习-集群搭建篇(二) 部署Node服务,启动JNI网络插件

相关产品

  • 容器服务Kubernetes版