目录
docker容器的安全
Docker容器的安全性,很大程度上依赖于Linux系统自身,评估Docker的安全性时,主要考虑以下几个方面:
命名空间隔离的安全:启动一个容器时,Docker将在后台为容器创建一个独立的命名空间,就是隔离,但是ns(namespace)的隔离不够强,容器都是使用的同一个物理机的内核
控制组资源控制的安全:启动容器时,Docker将在后台为容器创建一个独立的控制组策略集合Cgroups,它负责分配内存、CPU、磁盘IO等。确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务攻击(DDoS)方面必不可少
内核能力机制:大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可。默认情况下,Docker采用“白名单”机制,禁用“必需功能”之外的其他权限
容器资源控制
接下来分别对memory、cpu和io进行控制
cpu资源限制
使用20%cpu上限
[root@k8s1 cpu]# docker run -it --rm --cpu-period 100000 --cpu-quota 20000 ubuntu
测试持续消耗cpu,使用top命令,发现始终不能超过20%
root@433a1612a171:/# dd if=/dev/zero of=/dev/null
容器会直接调用cgroup
cpu优先级
创建第一个容器
[root@k8s1 cpu]# docker run -it --rm ubuntu
root@0280fc49f2d0:/# dd if=/dev/zero of=/dev/null
创建第二个,cpu.shares 表示优先级,默认是1024,现在设置为100,大概是原来的十分之一。
[root@k8s1 cpu]# docker run -it --rm --cpu-shares 100 ubuntu
root@b75b4d5066b8:/# dd if=/dev/zero of=/dev/null
测试时只保留一个cpu核心可用,通过以下关掉第二个cpu
[root@k8s1 cpu1]# pwd
/sys/devices/system/cpu/cpu1
[root@k8s1 cpu1]# echo 0 > online
top查看,二者的cpu占用基本是9比1
内存资源限制
物理内存和swap各200m
[root@k8s1 ~]# docker run -d --name demo --memory 200M --memory-swap=200M nginx
在不进容器下操作,进入cgroup,查看设定生效
在/sys/fs/cgroup中有许多的子目录,分别控制每个资源,/sys/fs/cgroup/memory/下的这些变量是是物理机全句的控制
进入memory创建x1,修改memory的最大值为200M。
[root@k8s1 memory]# pwd
/sys/fs/cgroup/memory
[root@k8s1 memory]# mkdir x1
[root@k8s1 memory]# cd x1/
[root@k8s1 x1]# echo 209715200 > memory.limit_in_bytes
安装libcgroup-tools工具,进入shm里,该目录挂的是物理内存,数据往内存写的,使用300m,可以发现多出的100m会写入swap
[root@k8s1 x1]# yum install -y libcgroup-tools.x86_64
[root@k8s1 x1]# cd /dev/shm/
[root@k8s1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300
[root@k8s1 shm]# free -m
total used free shared buff/cache available
Mem: 1980 187 1080 206 712 1389
Swap: 2047 103 1944
再次进入修改,内存加swap总共200m,使用300m,则任务killed
[root@k8s1 shm]# cd /sys/fs/cgroup/memory/x1/
[root@k8s1 x1]# echo 209715200 > memory.memsw.limit_in_bytes
[root@k8s1 x1]# cd -
/dev/shm
[root@k8s1 shm]# cgexec -g memory:x1 dd if=/dev/zero of=bigfile bs=1M count=300
Killed
磁盘io限制
限制读取速度,30m每秒,oflag=direct不走缓存,不通过内存到io设备,直接接入io设备
[root@k8s1 ~]# docker run -it --rm --device-write-bps /dev/sda:30MB ubuntu
root@3226b0fc6231:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.31722 s, 31.6 MB/s
lxcfs隔离
lxcfs 是通过文件挂载的方式,把 cgroup 中关于系统的相关信息读取出来,通过 docker 的 volume 挂载给容器内部的 proc 系统。 然后让 docker 内的应用读取 proc 中信息的时候以为就是读取的宿主机的真实的 proc。
下载依赖包,进入,打到后台
[root@k8s1 ~]# yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm
[root@k8s1 ~]# lxcfs /var/lib/lxcfs &
将以下几个文件挂在容器内
[root@k8s1 ~]# docker run -it -m 256m \
> -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
> -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
> -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
> -v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
> -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
> -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
> ubuntu
可看见可用256m,解决了高度隔离性
root@45edbc92cc1d:/# free -m
total used free shared buff/cache available
Mem: 256 0 255 9 0 255
Swap: 256 0 256
容器特权
默认容器内的用户是受限的,很多操作不被允许
[root@k8s1 ~]# docker run -it --rm busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ # id
uid=0(root) gid=0(root) groups=0(root),10(wheel)
/ # ip link set down eth0
ip: SIOCSIFFLAGS: Operation not permitted
/ # fdisk -l
开启容器特权,成为超户,--privileged权限非常大,近乎于宿主机的权限
[root@k8s1 ~]# docker run -it --rm --privileged busybox
/ # fdisk -l
Disk /dev/sda: 20 GB, 21474836480 bytes, 41943040 sectors
2610 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type
/dev/sda1 * 0,32,33 130,170,40 2048 2099199 2097152 1024M 83 Linux
/dev/sda2 130,170,41 1023,254,63 2099200 41943039 39843840 18.9G 8e Linux LVM
Disk /dev/dm-0: 17 GB, 18249416704 bytes, 35643392 sectors
2218 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/dm-0 doesn't contain a valid partition table
Disk /dev/dm-1: 2048 MB, 2147483648 bytes, 4194304 sectors
261 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 = 512 bytes
Disk /dev/dm-1 doesn't contain a valid partition table
/ # ip link set down eth0
/ # ip link set up eth0
设置容器白名单,添加网络管理权限,此时不能查看磁盘分区,可以操作网络
[root@k8s1 ~]# docker run -it --rm --cap-add=NET_ADMIN busybox
/ # fdisk -l
/ # ip a a 10.0.0.1/24 dev eth0
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
18: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 10.0.0.1/24 scope global eth0
valid_lft forever preferred_lft forever
/ # ip a d 10.0.0.1/24 dev eth0
/ # ip a