5. Seccomp / AppArmor
Linux中的所有操作都是通过系统调用来完成的。内核有330个系统调用,执行读取文件、关闭句柄和检查访问权限等操作。所有应用程序都使用这些系统调用的组合来执行所需的操作。
AppArmor
是一个应用程序定义的配置文件,它描述了进程可以访问系统的哪些部分。
可以通过以下方式查看分配给进程的当前AppArmor配置文件
$ cat /proc/$DBPID/attr/current docker-default (enforce)
Docker的默认AppArmor配置文件是docker-default (enforce)
在Docker 1.13之前,它将AppArmor配置文件存储在/etc/ AppArmor.d/Docker-default(在Docker启动时被覆盖,因此用户无法修改它。在v1.13之后,Docker现在在tmpfs中生成Docker -default,使用apparmor_parser将其加载到内核中,然后删除该文件
Seccomp提供了限制系统调用的能力,阻止诸如安装内核模块或更改文件权限等方面。
Docker默认允许的调用可以在https://github.com/moby/moby/blob/a575b0b1384b2ba89b79cbd7e770fbeb616758b3/profiles/seccomp/default.json
当分配给进程时,它意味着进程将被限制在能力系统调用的子集。如果它试图调用一个被阻塞的系统调用将收到错误“操作不允许”。
SecComp的状态也在一个文件中定义。
$ cat /proc/$DBPID/status Name: redis-server State: S (sleeping) Tgid: 1099 Ngid: 0 Pid: 1099 PPid: 1083 TracerPid: 0 Uid: 999 999 999 999 Gid: 1000 1000 1000 1000 FDSize: 64 Groups: 1000 1000 NStgid: 1099 1 NSpid: 1099 1 NSpgid: 1099 1 NSsid: 1099 1 VmPeak: 29156 kB VmSize: 29156 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 11316 kB VmRSS: 7032 kB VmData: 23204 kB VmStk: 132 kB VmExe: 1672 kB VmLib: 1656 kB VmPTE: 56 kB VmPMD: 12 kB VmSwap: 4324 kB HugetlbPages: 0 kB Threads: 5 SigQ: 0/3824 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000001001 SigCgt: 00000000000044ea CapInh: 00000000a80425fb CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 00000000a80425fb CapAmb: 0000000000000000 Seccomp: 2 Cpus_allowed: 3 Cpus_allowed_list: 0-1 Mems_allowed: 00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 24583 nonvoluntary_ctxt_switches: 507
$ cat /proc/$DBPID/status | grep Seccomp Seccomp: 2
标志位含义为:0:关闭。1:严格。2:过滤
6. Capabilities
Capabilities
是关于进程或用户有权做什么的分组。这些功能可能包括多个系统调用或操作,例如更改系统时间或主机名。
状态文件还包含了Capabilities
标志。一个进程可以丢弃尽可能多的capability,以确保其安全。
$ cat /proc/$DBPID/status | grep ^Cap CapInh: 00000000a80425fb CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 00000000a80425fb CapAmb: 0000000000000000
标志被存储为一个可以用capsh解码的位掩码
$ capsh --decode=00000000a80425fb 0x00000000a80425fb=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
7. 容器镜像
容器映像是一个包含tar文件的tar文件。每个tar文件都是一个层。一旦所有tar文件被提取到相同的位置,那么您就拥有了容器的文件系统。
这可以通过Docker进行探索。把这些image放到本地系统上。
$ docker pull redis:3.2.11-alpine 3.2.11-alpine: Pulling from library/redis ff3a5c916c92: Pull complete aae70a2e6027: Pull complete 87c655da471c: Pull complete bc3141806bdc: Pull complete 53616fb426d9: Pull complete 9791c5883c6a: Pull complete Digest: sha256:ebf1948b84dcaaa0f8a2849cce6f2548edb8862e2829e3e7d9e4cd5a324fb3b7 Status: Downloaded newer image for redis:3.2.11-alpine
将images导出为原始tar格式。
docker save redis:3.2.11-alpine > redis.tar
$ tar -xvf redis.tar 46a2fed8167f5d523f9a9c07f17a7cd151412fed437272b517ee4e46587e5557/ 46a2fed8167f5d523f9a9c07f17a7cd151412fed437272b517ee4e46587e5557/VERSION 46a2fed8167f5d523f9a9c07f17a7cd151412fed437272b517ee4e46587e5557/json 46a2fed8167f5d523f9a9c07f17a7cd151412fed437272b517ee4e46587e5557/layer.tar 498654318d0999ce36c7b90901ed8bd8cb63d86837cb101ea1ec9bb092f44e59/ 498654318d0999ce36c7b90901ed8bd8cb63d86837cb101ea1ec9bb092f44e59/VERSION 498654318d0999ce36c7b90901ed8bd8cb63d86837cb101ea1ec9bb092f44e59/json 498654318d0999ce36c7b90901ed8bd8cb63d86837cb101ea1ec9bb092f44e59/layer.tar ad01e7adb4e23f63a0a1a1d258c165d852768fb2e4cc2d9d5e71698e9672093c/ ad01e7adb4e23f63a0a1a1d258c165d852768fb2e4cc2d9d5e71698e9672093c/VERSION ad01e7adb4e23f63a0a1a1d258c165d852768fb2e4cc2d9d5e71698e9672093c/json ad01e7adb4e23f63a0a1a1d258c165d852768fb2e4cc2d9d5e71698e9672093c/layer.tar ca0b6709748d024a67c502558ea88dc8a1f8a858d380f5ddafa1504126a3b018.json da2a73e79c2ccb87834d7ce3e43d274a750177fe6527ea3f8492d08d3bb0123c/ da2a73e79c2ccb87834d7ce3e43d274a750177fe6527ea3f8492d08d3bb0123c/VERSION da2a73e79c2ccb87834d7ce3e43d274a750177fe6527ea3f8492d08d3bb0123c/json da2a73e79c2ccb87834d7ce3e43d274a750177fe6527ea3f8492d08d3bb0123c/layer.tar db1a23fc1daa8135a1c6c695f7b416a0ac0eb1d8ca873928385a3edaba6ac9a3/ db1a23fc1daa8135a1c6c695f7b416a0ac0eb1d8ca873928385a3edaba6ac9a3/VERSION db1a23fc1daa8135a1c6c695f7b416a0ac0eb1d8ca873928385a3edaba6ac9a3/json db1a23fc1daa8135a1c6c695f7b416a0ac0eb1d8ca873928385a3edaba6ac9a3/layer.tar f07352aa34c241692cae1ce60ade187857d0bffa3a31390867038d46b1e7739c/ f07352aa34c241692cae1ce60ade187857d0bffa3a31390867038d46b1e7739c/VERSION f07352aa34c241692cae1ce60ade187857d0bffa3a31390867038d46b1e7739c/json f07352aa34c241692cae1ce60ade187857d0bffa3a31390867038d46b1e7739c/layer.tar manifest.json repositories
所有的tar层文件现在都是可见的。
$ ls 46a2fed8167f5d523f9a9c07f17a7cd151412fed437272b517ee4e46587e5557 498654318d0999ce36c7b90901ed8bd8cb63d86837cb101ea1ec9bb092f44e59 ad01e7adb4e23f63a0a1a1d258c165d852768fb2e4cc2d9d5e71698e9672093c ca0b6709748d024a67c502558ea88dc8a1f8a858d380f5ddafa1504126a3b018.json da2a73e79c2ccb87834d7ce3e43d274a750177fe6527ea3f8492d08d3bb0123c db1a23fc1daa8135a1c6c695f7b416a0ac0eb1d8ca873928385a3edaba6ac9a3 f07352aa34c241692cae1ce60ade187857d0bffa3a31390867038d46b1e7739c manifest.json redis.tar repositories
images还包含关于images的元数据,如版本信息和标记名称.
$ cat repositories {"redis":{"3.2.11-alpine":"46a2fed8167f5d523f9a9c07f17a7cd151412fed437272b517ee4e46587e5557"}} $ cat manifest.json [{"Config":"ca0b6709748d024a67c502558ea88dc8a1f8a858d380f5ddafa1504126a3b018.json","RepoTags":["redis:3.2.11-alpine"],"Layers":["498654318d0999ce36c7b90901ed8bd8cb63d86837cb101ea1ec9bb092f44e59/layer.tar","ad01e7adb4e23f63a0a1a1d258c165d852768fb2e4cc2d9d5e71698e9672093c/layer.tar","da2a73e79c2ccb87834d7ce3e43d274a750177fe6527ea3f8492d08d3bb0123c/layer.tar","db1a23fc1daa8135a1c6c695f7b416a0ac0eb1d8ca873928385a3edaba6ac9a3/layer.tar","f07352aa34c241692cae1ce60ade187857d0bffa3a31390867038d46b1e7739c/layer.tar","46a2fed8167f5d523f9a9c07f17a7cd151412fed437272b517ee4e46587e5557/layer.tar"]}]
tar中文件
$ tar -xvf da2a73e79c2ccb87834d7ce3e43d274a750177fe6527ea3f8492d08d3bb0123c/layer.tar etc/ etc/apk/ etc/apk/world lib/ lib/apk/ lib/apk/db/ lib/apk/db/installed lib/apk/db/lock lib/apk/db/scripts.tar lib/apk/db/triggers sbin/ sbin/su-exec var/ var/cache/ var/cache/misc/
8. 创建空镜像
由于images只是一个tar文件,可以使用下面的命令创建空images
$ tar cv --files-from /dev/null | docker import - empty sha256:ba14edd8949ad44677f1955e37b9a35f9978d2a687b3f8ab86711811d46e2c53
通过导入tar,将创建额外的元数据。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE empty latest ba14edd8949a 24 seconds ago 0B redis 3.2.11-alpine ca0b6709748d 3 years ago 20.7MB
但是,由于容器不包含任何内容,所以它不能启动进程。
9. 不使用Dockerfile创建镜像
可以扩展前面导入Tar文件的想法,从零开始创建整个映像。
首先,我们将使用BusyBox作为基础。这将为我们提供基本的linux命令。它被定义为rootfs。rootfs是……
Docker提供了一个脚本来下载BusyBox rootfs
$ curl -LO https://raw.githubusercontent.com/moby/moby/a575b0b1384b2ba89b79cbd7e770fbeb616758b3/contrib/mkimage/busybox-static && chmod +x busybox-static % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 782 100 782 0 0 2177 0 --:--:-- --:--:-- --:--:-- 2184 $ $ ./busybox-static busybox
运行该脚本将下载rootfs和主二进制文件。
$ ls -lha busybox total 20K drwxr-xr-x 5 root root 4.0K Sep 27 09:43 . drwx------ 15 root root 4.0K Sep 27 09:43 .. drwxr-xr-x 2 root root 4.0K Sep 27 09:43 bin drwxr-xr-x 2 root root 4.0K Sep 27 09:43 sbin drwxr-xr-x 4 root root 4.0K Sep 27 09:43 usr
默认的Busybox rootfs不包含任何版本信息,所以让我们创建一个文件。
$ echo KatacodaPrivateBuild > busybox/release
与前面一样,该目录可以转换为tar,并自动导入到Docker中作为映像。
$ tar -C busybox -c . | docker import - busybox sha256:73b25a6703da535db5cbc43073c2920b60f5f8a76db17de093e851f1a2d5f69c
现在可以将其作为容器启动。
$ docker run busybox cat /release KatacodaPrivateBuild