前言
lxcfs是一个开源的FUSE(用户态文件系统)实现来支持LXC容器。
LXCFS通过用户态文件系统,在容器中提供下列 procfs 的文件:
- /proc/cpuinfo
- /proc/diskstats
- /proc/meminfo
- /proc/stat
- /proc/swaps
- /proc/uptime
比如,把宿主机的 /var/lib/lxcfs/proc/memoinfo 文件挂载到Docker容器的/proc/meminfo位置后。容器中进程读取相应文件内容时,LXCFS的FUSE实现会从容器对应的Cgroup中 读取正确的内存限制。从而使得应用获得正确的资源约束设定
一、利用LXCFS增强docker容器隔离性和资源可见性
在前面我们做过容器的资源控制,不过我们也要注意到当我们查看系统资源的时候发现出现的数据并不是我们者之的那样,这样明显是不合理的。
1.安装LXCFS
[root@server1 ~]# yum install -y lxcfs-2.0.5-3.el7.centos.x86_64.rpm
2.启动lxcfs
[root@server1 ~]# cd /var/lib/lxcfs/
[root@server1 lxcfs]# ls
[root@server1 lxcfs]# lxcfs /var/lib/lxcfs/ &
##启动lxcfs,但是注意按回车结束,不要使用ctrl+c,否则就直接结束lxcfs进程
[1] 17083
[root@server1 lxcfs]# hierarchies:
0: fd: 5: memory
1: fd: 6: blkio
2: fd: 7: hugetlb
3: fd: 8: pids
4: fd: 9: net_prio,net_cls
5: fd: 10: devices
6: fd: 11: cpuacct,cpu
7: fd: 12: perf_event
8: fd: 13: freezer
9: fd: 14: cpuset
10: fd: 15: name=systemd
[root@server1 lxcfs]# ls
[root@server1 lxcfs]# cd
[root@server1 ~]# cd /var/lib/lxcfs/
[root@server1 lxcfs]# ls
cgroup proc
使用ps ax 命令查看lxcfs进程
3.docker使用lxcfs的数据卷测试
[root@server1 ~]# docker run -it --name vm4 -m 200m \
> -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo \
> -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
root@86771e74bc37:/# free -m
total used free shared buffers cached
Mem: 200 1 198 16 0 0
-/+ buffers/cache: 1 198
Swap: 200 0 200
root@86771e74bc37:/#
##可以看到我们的容器的内存大小是我们设置的那样
注意:
不能直接把/var/lib/lxcfs/proc目录挂载到容器内的/proc目录下,因为容器内的/proc目录下本身是有内容的,是系统的进程信息等等,如果直接把/var/lib/lxcfs/proc目录挂载到容器内的/proc目录下,会覆盖容器内/proc目录下的内容,而/proc目录下记录的是容器的进程信息等等内容,是不能被覆盖的,所以不能直接把/var/lib/lxcfs/proc目录挂载到容器内的/proc目录下。
二、设置特权级运行的容器:–privileged=true
有的时候我们需要容器具备更多的权限,比如操作内核模块,控制swap交换分区,挂载USB磁盘,修改MAC地址等。
我们建立容器后,进入容器的root帐号的权限是受限制的,不是真正的root用户。
加入–privileged=true参数,获得的是具有管理员权限的root用户。
[root@server1 ~]# docker run -it --name vm5 --privileged=true ubuntu
root@70ddfd82331b:/#
root@70ddfd82331b:/# id
uid=0(root) gid=0(root) groups=0(root)
root@70ddfd82331b:/#
root@70ddfd82331b:/# ip link set down eth0
root@70ddfd82331b:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
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
12: eth0@if13: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
root@70ddfd82331b:/#
–privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。此时Docker 提供了权限白名单的机制,使用–cap-add添加必要的权限。
[root@server1 ~]# docker run -it --cap-add=NET_ADMIN --name vm6 ubuntu bash
root@0c9e3667159f:/#
root@0c9e3667159f:/# [root@server1 ~]#
[root@server1 ~]#
[root@server1 ~]# docker inspect -f {{.HostConfig.Privileged}} vm6
false
[root@server1 ~]# docker inspect -f {{.HostConfig.CapAdd}} vm6
[NET_ADMIN]
[root@server1 ~]#
三、安全加固的思路
1.保证镜像的安全
使用安全的基础镜像
删除镜像中的setuid和setgid权限
启用Docker的内容信任
最小安装原则
对镜像进行安全漏洞扫描,镜像安全扫描器:Clair
容器使用非root用户运行
2.保证容器的安全
对docker宿主机进行安全加固
限制容器之间的网络流量
配置Docker守护程序的TLS身份验证
启用用户命名空间支持
限制容器的内存使用量
适当设置容器CPU优先级
3.主要的内核子系统都没有命名空间,如:
SELinux
cgroup
在/sys下的文件系统
/proc/sys, /proc/sysrq-trigger, /proc/irq, /proc/bus
4.设备没有命名空间:
/dev/mem
/dev/sd*文件系统设备
内核模块