有时候我们需要容器具有更多的权限,像如操作内核模块,控制swap交换分区,挂载usb磁盘,修改mac地址等。所以我们今天进行docker的安全设定。
一、使用docker命令设置docker的安全机制
1、设置特特权级运行的容器: --privileged=true
---> docker run -it --name vm4 --privileged=true ubuntu # 使用权限之后,可以对eth0进行down操作。
2、设置允许容器占用的内存大小和swap分区大小 (首先我们需要安装stress包,进行压测试)
---> docker run --rm -it --name vm1 -m 100M --memory-swap 100M stress --vm 1 --vm-bytes 90M # 设置提供给vm1的内容大小为100M,内存加交换分区为100M,最大的压测也为100.若内存大与100时,或出现失败
注意:内存不能大与内存加swap分区的大小;若只有内存大小,没有memory-swap的值时,则默认情况下swap分区大小和memor相同。
3、限制容器占用的cpu
---> docker run --rm -it --cpu-shares 512 stress -c 4 # 可以使用lscpu命令查看系统的内核数(此时为4)
---> docker run --rm -it --cpu-shares 1024 stress -c 4
# cpu-shares为容器的优先级,-c参数表示容器的内核数 。此时我们可以看到1024的优先级高(若在内核数充足的情况下,则看不出优先级)
4、为每秒写入块设备的数据设定上限
---> docker run --rm -it --privileged=true --device-write-bps /dev/sda:10M ubuntu
---> dd if=/dev/zero of=file bs=1M count=100 oflag=direct # 在容器中截取100M的文件,此时我们可以看到每秒写入的为10M左右
注意:direct 模式就是把写入请求直接封装成io指令发到磁盘;非direct 就把数据写入系统缓存,然后就认为io成功,由操作系统决定缓存中的数据什么时候被写入磁盘
二、利用cgroup对docker做权限限制
LINUX Cgroup是linux内核提供的用于限制、记录、隔离进程组可以使用的资源(cpu、memory、io等)的一种机制。
1)对mem内存进行限制
1、首先安装cgroup管理工具、并启动服务。此时我们在rhel6.5的进行操作
---> yum search cgroup
---> yum install -y libcgroup.x86_64 # 安装之后,我们可以在根目录下看到名为cgroup的空文件
---> /etc/init.d/cgconfig start # 启动服务(若是出现启动问题,可以切换到~目录下重新启动)
# 当启动服务之后,会在/cgroup目录下产生文件
2、对内存资源使用进行编写
---> cd /cgroup/memory
---> cat memory.limit_in_bytes # 该文件存放内存的吞吐量(无穷大)
---> vim /etc/cgconfig.conf # 编写配置文件(在最后一行添加如下内容)
group x1 {
memory.limit_in_bytes = 209715200; # 限制使用的最大内存数2MB
memory.memsw.limit_in_bytes = 209715200; # 限制内存和交换分区之和;与内存大小相同表示swap分区为0
}
}
---> cd ~ # 启动服务要切换目录
---> /etc/init.d/cgconfig restart # 我们可以在/cgroup/memory目录下看到x1目录
3、测试
---> cd /dev/shm
---> cgexec -g memory:x1 dd if=/dev/zero of=file bs=1M count=100 # 截取100M的文件(此时全部使用memory的空间)
# 截取200M的时候会出现文件大小超额,被killed。虽然说我们设置的文件大小为200M的,但实际使用的要比200M少一点;不过文件大小已经改变了。
2)对cpu的限制
1、查看系统中默认cpu的限制
2、编辑资源配置文件
---> vim /etc/cgconfig.conf # 在最后一行添加如下内容
group x2 {
cpu.shares = 100; #对进程调度程序所处理的进程组设置cpu时间分配的比重。(默认为1024)
}
}
---> cd ~
---> /etc/init.d/cgconfig restart # 重启服务
3、测试
---> cd /dev/shm
3)对磁盘空间的读写速度的限制
Cgroup中每个子系统(SubSystem)对应一种资源,其中Cgroup blkio子系统用于限制块设备I/O速率。相比io调度权重,iops和bps限制更加直接和量化,更适合用于限制docker容器磁盘IO上限。
1、首先查看blkio的的参数
2、编辑配置文件,对块设备的读写速度进行限制
---> vim /etc/cgconfig.conf
group x3 {
blkio.throttle.read_bps_device = "252:0 1000000"; # 250:0是/dev/vda块设备的信息
}
}
---> cd
---> /etc/init.d/cgconfig.conf # 重启服务
3、测试(读取数据的速度维持在了1000K左右)
---> yum install -y iotop # 方便查看io的实时状态
---> cd /dev/shm
---> cgexec -g blkio:x3 dd if=/dev/vda of=/dev/null & # 在/dev/vda中读取数据,并且查看读取速度
---> iotop
4)freezer子系统
freezer子系统用于挂起和恢复cgroup中的进程。我们知道freezer中有一个控件freezer.state,将FROZEN写入该文件,可以将cgroup中的进程挂起,将THAWED写入该文件,可以将已挂起的进程恢复。该文件可能读出的值有三种,其中两种就是前面已提到的FROZEN和THAWED,分别代表进程已挂起和已恢复(正常运行),还有一种可能的值为FREEZING,显示该值表示该cgroup中有些进程现在不能被frozen。当这些不能被frozen的进程从该cgroup中消失的时候,FREEZING会变成FROZEN,或者手动将FROZEN或THAWED写入一次。
1、编辑配置文件
---> vim /etc/cgconfig.conf
group x4 {
}
---> /etc/init.d/cgconfig restart
2、在freezer目录下查看文件的状态
---> cd /cgroup/freezer/x4
---> cat freezer.state # 此时的状态为THAWED
---> dd if=/dev/zero of=/dev/null & # 截取一个空间大小,并使用 top查看命令的cpu利用率(大致消耗百分之百)
3、当出现这种情况的时候,我们不能立即杀死该进程(由于他和某些进程占用某些资源,若现在是他使用资源,则kill之后,占用的资源会进行释放,此时会影响别的进程);此时,我们应该将该进程进行“冰冻”,然后检查对其他进程是否有影响,然后判断之后的执行。。。
---> ps -ax # 查看该进程的信息。并修改该进程的状态为frozen
三、Docker中私有镜像库的创建
1.在网上拉取仓库的镜像registry
---> docker pull registry # 注意此时要有镜像加速器
2、设定仓库对外的端口号为5000
---> docker run -d -p 5000:5000 -v /opt/registry:/var/lib/registry registry
---> netstat -natlp | grep 5000 # 查看为docker开启的端口
3、将nginx上传到自己的镜像仓库中
---> docker tag nginx localhost:5000/nginx # tag可以改变镜像的名称
---> docker pull localhost:5000/nginx # push可以将docker中的镜像上传到仓库(此时可在/opt/registry中看到镜像信息)
4、在/opt/registry中目录如下显示(上传的方式是逐层上传)
---> yum install -y tree
---> cd /opt/registry
---> tree . # 这里只截取部分内容
5、删除镜像库中的镜像
---> docker rmi localhost:5000/nginx # 删除自己tag出来的nginx(执行后状态为untagged,并不是真正的删除)
---> docker rmi nginx # 删除nginx镜像
6、重新上传nginx镜像
---> docker pull localhost:5000/nginx # 从仓库中拉取nginx镜像,端口是5000
---> docker tag localhost:5000/nginx nginx # 修改镜像库名称(原镜像也会存在)
---> docker images nginx # 查看nginx镜像的信息