docker(四)docker安全
为什么资源的隔离和限制在云时代更加重要?在默认情况下,一个操作系统里所有运行的进程共享CPU和内存资源,如果程序设计不当,最极端的情况,某进程出现死循环可能会耗尽CPU资源,或者由于内存泄漏消耗掉大部分系统资源,这在企业级产品场景下是不可接受的,所以进程的资源隔离技术是非常必要的
Linux操作系统本身从操作系统层面就支持虚拟化技术,叫做Linux container,也就是大家到处能看到的LXC的全称
LXC的三大特色:cgroup,namespace和unionFS
Cgroup
Cgroup是control group,又称为控制组,它主要是做资源控制。原理是将一组进程放在放在一个控制组里,通过给这个控制组分配指定的可用资源,达到控制这一组进程可用资源的目的。
Namespace
Namespace又称为命名空间,它主要做访问隔离。其原理是针对一类资源进行抽象,并将其封装在一起提供给一个容器使用,对于这类资源,因为每个容器都有自己的抽象,而他们彼此之间是不可见的,所以就可以做到访问隔离
unionFS:
顾名思义,unionFS可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。
要理解unionFS,我们首先要认识bootfs和rootfs。
1.boot file system (bootfs):包含操作系统boot loader 和 kernel。用户不会修改这个文件系统。
一旦启动完成后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放出内存。
同样内核版本的不同的 Linux 发行版,其bootfs都是一致的。
2.root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tm
实际上这就是Docker容器镜像分层实现的技术基础。如果我们浏览Docker hub,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如debian基础镜像。
理解docker安全
docker容器的安全性,很大程度上依赖于linux系统自身,评估Docker的安全性时,主要考虑以下几个方面
Linux内核的命令空间(namespace)机制提供的容器隔离安全
Linux控制组机制对容器资源的控制能力安全
Linux内核的能力机制所带来的操作权限安全
Docker程序(特别是服务端)本身的抗攻击性
其他安全增强机制对容器安全性的影响
命名空间隔离安全
当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间,命名空间提供了最基础也最直接的隔离
与虚拟机方式相比,通过Linux namespace来实现的隔离不是那么彻底
容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的还是同一个宿主机的操作系统内核
在Linux内核中,有很多资源和对象是不能被Namespace化的 比如 时间
容器与资源的关系
# 不能停掉容器 与资源会被释放掉
[root@docker docker]# docker run -it --name vm1 ubuntu
root@06a3c366c16b:/#
root@06a3c366c16b:/#
[root@docker docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06a3c366c16b ubuntu "/bin/bash" 14 seconds ago Up 13 seconds vm1
[root@docker docker]# docker inspect vm1 | grep Pid
"Pid": 1504,
"PidMode": "",
"PidsLimit": 0,
[root@docker docker]# ps aux |grep 1504
root 1504 0.0 0.1 18164 1960 pts/0 Ss+ 10:43 0:00 /bin/bash
root 1589 0.0 0.1 112704 1024 pts/0 R+ 10:44 0:00 grep --color=auto 1504
[root@docker docker]# cd /proc/1504
[root@docker 1504]# ls
attr cwd map_files oom_adj schedstat task
autogroup environ maps oom_score sessionid timers
auxv exe mem oom_score_adj setgroups uid_map
cgroup fd mountinfo pagemap smaps wchan
clear_refs fdinfo mounts patch_state stack
cmdline gid_map mountstats personality stat
comm io net projid_map statm
coredump_filter limits ns root status
cpuset loginuid numa_maps sched syscall
[root@docker 1504]# cd ns/
# namespace
"""
namespace 主要用作环境的隔离,主要有以下namespace:
UTS: 主机名与域名
IPC: 信号量、消息队列和共享内存
PID: 进程编号
Network:网络设备、网络栈、端口等等
Mount: 挂载点
User: 用户和用户组
"""
[root@docker ns]# ls
ipc mnt net pid user uts
控制组资源控制安全
当docker run启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合
Linux Cgroup提供了很多有用的特性,确保各容器可以公平地分享主机的内存,cpu,磁盘io等资源
确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务DDos方面必不可少
[root@docker ns]# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
[root@docker ns]# cd /sys/fs/cgroup/
[root@docker cgroup]# ls
blkio cpu,cpuacct freezer net_cls perf_event
cpu cpuset hugetlb net_cls,net_prio pids
cpuacct devices memory net_prio systemd
[root@docker cgroup]# cd cpu
[root@docker cpu]# ls
cgroup.clone_children cpuacct.usage cpu.rt_runtime_us release_agent
cgroup.event_control cpuacct.usage_percpu cpu.shares system.slice
cgroup.procs cpu.cfs_period_us cpu.stat tasks
cgroup.sane_behavior cpu.cfs_quota_us docker user.slice
cpuacct.stat cpu.rt_period_us notify_on_release
[root@docker cpu]# cd docker/
[root@docker docker]# ls
06a3c366c16be682286ca31da43026615db1b053d394fb0f8b08dc9c9126ae47
cgroup.clone_children
cgroup.event_control
cgroup.procs
cpuacct.stat
cpuacct.usage
cpuacct.usage_percpu
cpu.cfs_period_us
cpu.cfs_quota_us
cpu.rt_period_us
cpu.rt_runtime_us
cpu.shares
cpu.stat
notify_on_release
tasks
内核能力机制
能力机制(Capability)是linux内核一个强大的特性,可以提供细粒度的访问权限控制
大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可
默认情况下,docker采用“白名单”机制,禁用“必需功能”之外的其他权限
[root@docker docker]# docker container attach vm1
root@06a3c366c16b:/#
root@06a3c366c16b:/#
root@06a3c366c16b:/# id #你所看到的root并不具备真正的root身份权限
uid=0(root) gid=0(root) groups=0(root)
root@