0%


作者: 耗子007


安装python和ss

1
2
3
apt-get update
apt-get install python-pip
pip install shadowsocks

开启ss服务

直接前台开启

1
ssserver -p 443 -k password -m aes-256-cfb

优点:可以看到连接输出日志
缺点:端口ssh连接会导致服务中断,root权限启动

后台开启并使用其他权限启动

1
ssserver -p 443 -k password -m aes-256-cfb –user nobody -d start

配置文件设置服务
配置文件格式:

1
2
3
4
5
6
7
8
9
10
11
12
{
“server”:”0.0.0.0″,
“port_password”:{
“8381”:”haozi001″,
“8382”:”haozi001″,
“8383”:”haozi001″
},
“local_address”: “127.0.0.1”,
“local_port”:1080,
“timeout”:600,
“method”:”aes-256-cfb”
}

注意:如果是在google cloud platform上面设置,需要打开设置的端口号(如8381等)

优点:可以同时配置多个端口和密码,支持多用户

启动和停止命令:

1
2
ssserver -c /etc/shadowsocks.json -d start
ssserver -c /etc/shadowsocks.json -d stop


作者: 耗子007


awk文件格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
\#!/bin/awk -f  #注意头部

BEGIN {

\#定义初始化变量
}

{

\#处理逻辑
}

END {
}

使用方法

1
awk -f my.awk filename

语法

split( String, A, [Ere] ): 将 String 参数指定的参数分割为数组元素 A[1], A[2], . . ., A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,
或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。

split函数:以Ere分隔String并动态生成一个数组A(获取数组长度的方法,参考注意事项)。

substr( String, M, [ N ] ) :返回具有 N 参数指定的字符数量子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。
如果未指定 N 参数,则子串的长度将是 M 参数指定的位置到 String 参数的末尾 的长度。

函数substr用于截取部分字符串,注意index从1开始。

````substr ( string, starting position, [ length of string ] )`

注意事项:

  • length函数不能用于数组长度计算,可以通过for(k in arry) count++;
  • $1,2,3变量如果是用于字符串用途,不能用双引号括起来;


作者: 耗子007


while read

read命令接收标准输入,或其他文件描述符的输入,得到输入后,read命令将数据放入一个标准变量中.

利用read读取文件时,每次调用read命令都会读取文件中的”一行”文本.

当文件没有可读的行时,read命令将以非零状态退出.

1
2
3
4
5
6
7
8
9
cat filename| while read line
do
echo${line}
done

while read line
do
echo${line}
done < filename

for var in file

for var in file 表示变量var在file中循环取值.取值的分隔符由$IFS确定.

1
2
3
4
5
6
7
8
9
for line in $(cat filename)
do
echo “File:${line}”
done

for line in `cat filename`
do
echo “${line}”
done

如果输入文本每行中没有空格,则line在输入文本中按换行符分隔符循环取值.

如果输入文本中包括空格或制表符,则不是换行读取,line在输入文本中按空格分隔符或制表符或换行符特环取值.

可以通过把IFS设置为换行符来达到逐行读取的功能.

IFS的默认值为:空白(包括:空格,制表符,换行符).

注意:如何设置IFS为换行符

1
2
OLD_IFS=”$IFS”
IFS=$’\x0A’

awk工具变量

1
awk -f my.awk filename


作者: 耗子007


所有命令均基于docker1.11版本

运行时特权和Linux能力

run命令与特权相关的几个选项:

  • –cap-add: Add Linux capabilities
  • –cap-drop: Drop Linux capabilities
  • –privileged=false: Give extended privileges to this container
  • –device=[]: Allows you to run devices inside the container without the –privileged flag.

注:默认的容器都是unprivileged,因此很多系统调用、设备等特权相关的操作都是干不了的。而且1.10版本之后增加了seccomp安全控制,
可能导致容器有了权限,但是一些系统调用被安全策略禁止了。关于安全策略seccomp可以参考文档Docker安全策略

docker run –privileged启动的容器,具有访问host上所有设备的能力,当然需要同时设置AppArmor或者SELinux允许容器相同的权限。

–device可以指定一个或者多个设备在容器中能正常使用,默认情况,容器对这些设备具有read、write和mknod的权限,这些权限可以通过”:rwm”来修改。
mknod可以参考这篇博客

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk  /dev/xvdc

Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk /dev/xvdc
You will not be able to write the partition table.

Command (m for help): q

$ docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk /dev/xvdc
crash....

$ docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk /dev/xvdc
fdisk: unable to open /dev/xvdc: Operation not permitted

相对于privileged的暴力权限,cap-add和cap-drop对权限的控制更细腻。
Docker目前支持的权限设置列表如下:

Capability Key Capability Description
SETPCAP Modify process capabilities.
SYS_MODULE Load and unload kernel modules.
SYS_RAWIO Perform I/O port operations (iopl(2) and ioperm(2)).
SYS_PACCT Use acct(2), switch process accounting on or off.
SYS_ADMIN Perform a range of system administration operations.
SYS_NICE Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes.
SYS_RESOURCE Override resource Limits.
SYS_TIME Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock.
SYS_TTY_CONFIG Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals.
MKNOD Create special files using mknod(2).
AUDIT_WRITE Write records to kernel auditing log.
AUDIT_CONTROL Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules.
MAC_OVERRIDE Allow MAC configuration or state changes. Implemented for the Smack LSM.
MAC_ADMIN Override Mandatory Access Control (MAC). Implemented for the Smack Linux Security Module (LSM).
NET_ADMIN Perform various network-related operations.
SYSLOG Perform privileged syslog(2) operations.
CHOWN Make arbitrary changes to file UIDs and GIDs (see chown(2)).
NET_RAW Use RAW and PACKET sockets.
DAC_OVERRIDE Bypass file read, write, and execute permission checks.
FOWNER Bypass permission checks on operations that normally require the file system UID of the process to match the UID of the file.
DAC_READ_SEARCH Bypass file read permission checks and directory read and execute permission checks.
FSETID Don’t clear set-user-ID and set-group-ID permission bits when a file is modified.
KILL Bypass permission checks for sending signals.
SETGID Make arbitrary manipulations of process GIDs and supplementary GID list.
SETUID Make arbitrary manipulations of process UIDs.
LINUX_ IMMUTABLE Set the FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags.
NET_BIND_SERVICE Bind a socket to internet domain privileged ports (port numbers less than 1024).
NET_BROADCAST Make socket broadcasts, and listen to multicasts.
IPC_LOCK Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)).
IPC_OWNER Bypass permission checks for operations on System V IPC objects.
SYS_CHROOT Use chroot(2), change root directory.
SYS_PTRACE Trace arbitrary processes using ptrace(2).
SYS_ BOOT Use reboot(2) and kexec_load(2), reboot and load a new kernel for later execution.
LEASE Establish leases on arbitrary files (see fcntl(2)).
SETFCAP Set file capabilities.
WAKE_ALARM Trigger something that will wake up the system.
BLOCK_SUSPEND Employ features that can block system suspend.

cap-add和cap-drop都支持ALL,表示加上或者去掉所有能力。例如,加上所有能力,但是去掉MKNOD:

1
$ docker run --cap-add=ALL --cap-drop=MKNOD ...


作者: 耗子007


Secure computing mode (Seccomp)是Linux内核的特性。可以使用Seccomp来限制容器内的行为。
该特性的有效基于:

  • Docker编译时加上了seccomp
  • 内核打开了CONFIG_SECCOMP配置

修改默认Seccomp配置文件

默认的Seccomp配置文件禁止了44个系统调用。
可以参考默认的配置文件,自定义然后在docker run的时候用–security-opt设置自定义的配置文件,例如:

1
$ docker run --rm -it --security-opt seccomp=/path/to/seccomp/profile.json hello-world

默认的Seccomp配置文件是一个白名单,没有指定的则是被禁止的。下表给出一些被禁止的系统调用(不是全部),以及原因。

Syscall Description
acct Accounting syscall which could let containers disable their own resource limits or process accounting. Also gated by CAP_SYS_PACCT.
add_key Prevent containers from using the kernel keyring, which is not namespaced.
adjtimex Similar to clock_settime and settimeofday, time/date is not namespaced. Also gated by CAP_SYS_TIME.
bpf Deny loading potentially persistent bpf programs into kernel, already gated by CAP_SYS_ADMIN.
clock_ adjtime Time/date is not namespaced. Also gated by CAP_SYS_TIME.
clock_ settime Time/date is not namespaced. Also gated by CAP_SYS_TIME.
clone Deny cloning new namespaces. Also gated by CAP_SYS_ADMIN for CLONE_* flags, except CLONE_USERNS.
create_ module Deny manipulation and functions on kernel modules. Obsolete. Also gated by CAP_SYS_MODULE.
delete_ module Deny manipulation and functions on kernel modules. Also gated by CAP_SYS_MODULE.
finit_ module Deny manipulation and functions on kernel modules. Also gated by CAP_SYS_MODULE.
get_kernel_syms Deny retrieval of exported kernel and module symbols. Obsolete.
get_ mempolicy Syscall that modifies kernel memory and NUMA settings. Already gated by CAP_SYS_NICE.
init_ module Deny manipulation and functions on kernel modules. Also gated by CAP_SYS_MODULE.
ioperm Prevent containers from modifying kernel I/O privilege levels. Already gated by CAP_SYS_RAWIO.
iopl Prevent containers from modifying kernel I/O privilege levels. Already gated by CAP_SYS_RAWIO.
kcmp Restrict process inspection capabilities, already blocked by dropping CAP_PTRACE.
kexec_file_load Sister syscall of kexec_load that does the same thing, slightly different arguments. Also gated by CAP_SYS_BOOT.
kexec_ load Deny loading a new kernel for later execution. Also gated by CAP_SYS_BOOT.
keyctl Prevent containers from using the kernel keyring, which is not namespaced.
lookup_ dcookie Tracing/profiling syscall, which could leak a lot of information on the host. Also gated by CAP_SYS_ADMIN.
mbind Syscall that modifies kernel memory and NUMA settings. Already gated by CAP_SYS_NICE.
mount Deny mounting, already gated by CAP_SYS_ADMIN.
move_pages Syscall that modifies kernel memory and NUMA settings.
name_to_handle_at Sister syscall to open_by_handle_at. Already gated by CAP_SYS_NICE.
nfsservctl Deny interaction with the kernel nfs daemon. Obsolete since Linux 3.1.
open_by_handle_at Cause of an old container breakout. Also gated by CAP_DAC_READ_SEARCH.
perf_event_open Tracing/profiling syscall, which could leak a lot of information on the host.
personality Prevent container from enabling BSD emulation. Not inherently dangerous, but poorly tested, potential for a lot of kernel vulns.
pivot_ root Deny pivot_root, should be privileged operation.
process_vm_readv Restrict process inspection capabilities, already blocked by dropping CAP_PTRACE.
process_vm_writev Restrict process inspection capabilities, already blocked by dropping CAP_PTRACE.
ptrace Tracing/profiling syscall, which could leak a lot of information on the host. Already blocked by dropping CAP_PTRACE.
query_module Deny manipulation and functions on kernel modules. Obsolete.
quotactl Quota syscall which could let containers disable their own resource limits or process accounting. Also gated by CAP_SYS_ADMIN.
reboot Don’t let containers reboot the host. Also gated by CAP_SYS_BOOT.
request_key Prevent containers from using the kernel keyring, which is not namespaced.
set_ mempolicy Syscall that modifies kernel memory and NUMA settings. Already gated by CAP_SYS_NICE.
setns Deny associating a thread with a namespace. Also gated by CAP_SYS_ADMIN.
settimeofday Time/date is not namespaced. Also gated by CAP_SYS_TIME.
stime Time/date is not namespaced. Also gated by CAP_SYS_TIME.
swapon Deny start/stop swapping to file/device. Also gated by CAP_SYS_ADMIN.
swapoff Deny start/stop swapping to file/device. Also gated by CAP_SYS_ADMIN.
sysfs Obsolete syscall.
_sysctl Obsolete, replaced by /proc/sys.
umount Should be a privileged operation. Also gated by CAP_SYS_ADMIN.
umount2 Should be a privileged operation. Also gated by CAP_SYS_ADMIN.
unshare Deny cloning new namespaces for processes. Also gated by CAP_SYS_ADMIN, with the exception of unshare –user.
uselib Older syscall related to shared libraries, unused for a long time.
userfaultfd Userspace page fault handling, largely needed for process migration.
ustat Obsolete syscall.
vm86 In kernel x86 real mode virtual machine. Also gated by CAP_SYS_ADMIN.
vm86old In kernel x86 real mode virtual machine. Also gated by CAP_SYS_ADMIN.

禁用Seccomp

1
2
$ docker run --rm -it --security-opt seccomp=unconfined debian:jessie \
unshare --map-root-user --user sh -c whoami


作者: 耗子007


所有命令均基于docker1.11版本

容器最常用,也最复杂的命令应该是run命令了,这篇文章主要对docker run进行简单的分析。

使用手册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

-a, --attach=[] Attach to STDIN, STDOUT or STDERR
--add-host=[] Add a custom host-to-IP mapping (host:ip)
--blkio-weight=0 Block IO weight (relative weight)
--blkio-weight-device=[] Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)
--cpu-shares=0 CPU shares (relative weight)
--cap-add=[] Add Linux capabilities
--cap-drop=[] Drop Linux capabilities
--cgroup-parent="" Optional parent cgroup for the container
--cidfile="" Write the container ID to the file
--cpu-period=0 Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota=0 Limit CPU CFS (Completely Fair Scheduler) quota
--cpuset-cpus="" CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems="" Memory nodes (MEMs) in which to allow execution (0-3, 0,1)
-d, --detach Run container in background and print container ID
--detach-keys Specify the escape key sequence used to detach a container
--device=[] Add a host device to the container
--device-read-bps=[] Limit read rate (bytes per second) from a device (e.g., --device-read-bps=/dev/sda:1mb)
--device-read-iops=[] Limit read rate (IO per second) from a device (e.g., --device-read-iops=/dev/sda:1000)
--device-write-bps=[] Limit write rate (bytes per second) to a device (e.g., --device-write-bps=/dev/sda:1mb)
--device-write-iops=[] Limit write rate (IO per second) to a device (e.g., --device-write-bps=/dev/sda:1000)
--disable-content-trust=true Skip image verification
--dns=[] Set custom DNS servers
--dns-opt=[] Set custom DNS options
--dns-search=[] Set custom DNS search domains
-e, --env=[] Set environment variables
--entrypoint="" Overwrite the default ENTRYPOINT of the image
--env-file=[] Read in a file of environment variables
--expose=[] Expose a port or a range of ports
--group-add=[] Add additional groups to run as
-h, --hostname="" Container host name
--help Print usage
-i, --interactive Keep STDIN open even if not attached
--ip="" Container IPv4 address (e.g. 172.30.100.104)
--ip6="" Container IPv6 address (e.g. 2001:db8::33)
--ipc="" IPC namespace to use
--isolation="" Container isolation technology
--kernel-memory="" Kernel memory limit
-l, --label=[] Set metadata on the container (e.g., --label=com.example.key=value)
--label-file=[] Read in a file of labels (EOL delimited)
--link=[] Add link to another container
--log-driver="" Logging driver for container
--log-opt=[] Log driver specific options
-m, --memory="" Memory limit
--mac-address="" Container MAC address (e.g. 92:d0:c6:0a:29:33)
--memory-reservation="" Memory soft limit
--memory-swap="" A positive integer equal to memory plus swap. Specify -1 to enable unlimited swap.
--memory-swappiness="" Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
--name="" Assign a name to the container
--net="bridge" Connect a container to a network
'bridge': create a network stack on the default Docker bridge
'none': no networking
'container:<name|id>': reuse another container's network stack
'host': use the Docker host network stack
'<network-name>|<network-id>': connect to a user-defined network
--net-alias=[] Add network-scoped alias for the container
--oom-kill-disable Whether to disable OOM Killer for the container or not
--oom-score-adj=0 Tune the host's OOM preferences for containers (accepts -1000 to 1000)
-P, --publish-all Publish all exposed ports to random ports
-p, --publish=[] Publish a container's port(s) to the host
--pid="" PID namespace to use
--pids-limit=-1 Tune container pids limit (set -1 for unlimited), kernel >= 4.3
--privileged Give extended privileges to this container
--read-only Mount the container's root filesystem as read only
--restart="no" Restart policy (no, on-failure[:max-retry], always, unless-stopped)
--rm Automatically remove the container when it exits
--shm-size=[] Size of `/dev/shm`. The format is `<number><unit>`. `number` must be greater than `0`. Unit is optional and can be `b` (bytes), `k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses `64m`.
--security-opt=[] Security Options
--sig-proxy=true Proxy received signals to the process
--stop-signal="SIGTERM" Signal to stop a container
-t, --tty Allocate a pseudo-TTY
-u, --user="" Username or UID (format: <name|uid>[:<group|gid>])
--userns="" Container user namespace
'host': Use the Docker host user namespace
'': Use the Docker daemon user namespace specified by `--userns-remap` option.
--ulimit=[] Ulimit options
--uts="" UTS namespace to use
-v, --volume=[host-src:]container-dest[:<options>]
Bind mount a volume. The comma-delimited
`options` are [rw|ro], [z|Z],
[[r]shared|[r]slave|[r]private], and
[nocopy]. The 'host-src' is an absolute path
or a name value.
--volume-driver="" Container's volume driver
--volumes-from=[] Mount volumes from the specified container(s)
-w, --workdir="" Working directory inside the container

上面的手册可以使用“docker run –help”或者到Docker官网查看。
run用于在新容器中执行一条命令,首先会创建一个新容器然后执行一条指令,其实这里包含了create、start以及exec命令的作用。
基本用法是:“docker run [OPTIONS] IMAGE [COMMAND] [ARG…]”
注:

  • 可选选项OPTIONS:run具有丰富的选项,可以设置容器的一些特性
  • IMAGE:指定容器运行的基础镜像
  • 可选命令COMMAND:容器运行时执行的命令
  • 可选参数ARG:命令带的参数

基础用法

指定容器名并分配伪终端

1
2
3
$ docker run --name hello -it ubuntu
root@a37b3b659c24:/#
root@a37b3b659c24:/#

创建一个名字为hello的容器,并且分配一个伪终端,-i链接到容器的STDIN。

获取容器ID(–cidfile)

1
2
3
4
5
6
$ docker run --cidfile ./test.cid --name hello ubuntu
$ cat test.cid
b504823b5a2d281e0f8ee329e14a8052bbeb171f7e50720fe0dab98ebd75587fV2R1C00B003
$ docker run --cidfile ./test.cid --name hello ubuntu
docker: Container ID file found, make sure the other container isn't running or delete ./test.cid.
See 'docker run --help'.

通过–cidfile指定写入容器ID的文件路径,如果test.cid文件存在,命令会返回错误。

特权容器

1
2
3
$ docker run -t -i --rm ubuntu bash
root@bc338942ef20:/# mount -t tmpfs none /mnt
mount: permission denied

默认,大部分危险的内核能力是对容器关闭的,因此上面执行失败。关于具体权限分析,参考run的权限设置文章

1
2
3
4
5
$ docker run -t -i --privileged ubuntu bash
root@50e3f57e16e6:/# mount -t tmpfs none /mnt
root@50e3f57e16e6:/# df -h
Filesystem Size Used Avail Use% Mounted on
none 1.9G 0 1.9G 0% /mnt

–privileged选项会赋给容器所有的能力,此时的容器具有和host相同的能力,这种用法是很危险,不建议这么使用。
细分权限,可以参考run的权限设置文章

设置工作目录

1
2
3
4
$ docker run --rm --name hello -it ubuntu pwd
/
$ docker run -w /test --rm --name hello -it ubuntu pwd
/test

默认情况下,容器的工作目录是根目录,-w可以设置该目录,如果该目录不存在,docker会在容器中创建该目录。

挂载数据卷

1
2
3
4
5
6
--volume=[host-src:]container-dest[:<options>]
Bind mount a volume. The comma-delimited
`options` are [rw|ro], [z|Z],
[[r]shared|[r]slave|[r]private], and
[nocopy]. The 'host-src' is an absolute path
or a name value.

可以把host上的文件或者目录透传到容器内指定路径,例如:

1
2
$ docker  run  -v `pwd`:`pwd` -w `pwd` -i -t  ubuntu pwd
$ docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/static-docker-binary:/usr/bin/docker busybox sh

可以设置容器内对该数据卷的读写权限。

可以从另外的容器挂载数据卷:

1
$ docker run --volumes-from 777f7dc92da7 --volumes-from ba8c0c54f0f2:ro -i -t ubuntu pwd

设置容器的元数据

1
2
$ docker run -l my-label --label com.example.foo=bar ubuntu bash
$ docker run --label-file ./labels ubuntu bash

三种方式设置:-l、–label以及–label-file。
label的格式为key=value,可以没有value,如果key相同,value不同,后面的会覆盖前面的value。

透传设备到容器

1
2
3
4
$ docker run --device=/dev/sdc:/dev/xvdc --device=/dev/sdd --device=/dev/zero:/dev/nulo -i -t ubuntu ls -l /dev/{xvdc,sdd,nulo}
brw-rw---- 1 root disk 8, 2 Feb 9 16:05 /dev/xvdc
brw-rw---- 1 root disk 8, 3 Feb 9 16:05 /dev/sdd
crw-rw-rw- 1 root root 1, 5 Feb 9 16:05 /dev/nulo

–device可以把host的设备透传到容器。

设置容器的ulimit

ulimit可以设置soft和hard限制,格式如:=[:]
例如:

1
2
3
4
$ docker run --ulimit nofile=1024:1024 --rm ubuntu sh -c "ulimit -n"
1024
$ docker run --rm ubuntu sh -c "ulimit -n"
1048576

注意:

  • 如果没有指定hard limit,那么soft limit的值也会被设置给hard limit
  • 如果没有设置ulimit,继承daemon设置的默认ulimit

退出自动清理容器

默认情况下,容器退出后,容器的数据都是保存的。如果要删除退出不用的容器,需要手动用rm命令删除。
有时候,可能容器退出就没有意义了,可以设置–rm,保证容器退出之后,会被自动清理掉。例如:

1
docker run --rm ubuntu sh -c "ulimit -n"

注意:不能和-d一起使用


作者: 耗子007


所有命令均基于docker1.11版本

上面的分析基本包含了容器相关的大部分命令,剩余一些系统信息、容器底层信息、容器插件或者其他组件相关的命令。
但是本章只关注系统信息和容器底层信息相关的命令,其他命令就不做介绍,后续有时间可能会补充。

获取Docker系统相关信息

1
2
3
4
5
Usage: docker info [OPTIONS]

Display system-wide information

--help Print usage

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ docker -D info
Containers: 14
Running: 3
Paused: 1
Stopped: 10
Images: 52
Server Version: 1.9.0
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 545
Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge null host
Kernel Version: 3.19.0-22-generic
OSType: linux
Architecture: x86_64
Operating System: Ubuntu 15.04
CPUs: 24
Total Memory: 62.86 GiB
Name: docker
ID: I54V:OLXT:HVMM:TPKO:JPHQ:CQCD:JNLC:O3BZ:4ZVJ:43XJ:PFHZ:6N2S
Docker Root Dir: /var/lib/docker
Debug mode (client): true
Debug mode (server): true
File Descriptors: 59
Goroutines: 159
System Time: 2015-09-23T14:04:20.699842089+08:00
EventsListeners: 0
Init SHA1:
Init Path: /usr/bin/docker
Docker Root Dir: /var/lib/docker
Http Proxy: http://test:test@localhost:8080
Https Proxy: https://test:test@localhost:8080
WARNING: No swap limit support
Username: svendowideit
Registry: [https://index.docker.io/v1/]
Labels:
storage=ssd

这些信息里面,一般比较关注的是Storage和Logging驱动、插件、Registry地址等。
注:全局-D可以是docker命令输出调试信息,在发送问题报告的时候,最好带上-D。

容器或镜像的底层信息

有时可能需要知道容器或者镜像的一些底层信息,可以使用inspect命令获取。

1
2
3
4
5
6
7
8
9
Usage: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...]

Return low-level information on a container or image

-f, --format="" Format the output using the given go template
--help Print usage
--type=container|image Return JSON for_specified_type, permissible
values are "image" or "container"
-s, --size Display total file sizes if the type is container

format命令默认会把结果以JSON格式输出。
注意:

  • 默认情况下,当容器名和镜像名相同时,format会输容器的结果
  • 当时如果指定了–format,format会返回两个的格式化结果

关于–format选项可以参考Go语言的模板,这里只介绍简单的用法,例如获取容器的ID:

1
docker inspect -f='{ {.Id} }' haozi

获取Docker版本信息

1
2
3
4
5
6
Usage: docker version [OPTIONS]

Show the Docker version information.

-f, --format="" Format the output using the given go template
--help Print usage

version命令可以获取Docker版本相关信息,可以用–format来格式化输出,如方法前面。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ docker version
Client:
Version: 1.11.2
UnicornVersion: 1.11.2.11.ict
API version: 1.23
Go version: go1.7.4
Git commit: 008dfcd
Built: Tue Feb 7 10:58:04 2017
OS/Arch: linux/amd64

Server:
Version: 1.11.2
UnicornVersion: 1.11.2.11.ict
API version: 1.23
Go version: go1.7.4
Git commit: 008dfcd
Built: Tue Feb 7 10:58:04 2017
OS/Arch: linux/amd64

这里比较重要的信息是Docker、API、Go等的版本,例如,Client和Server的版本号不一致可能有各种问题。


作者: 耗子007


所有命令均基于docker1.11版本

这里主要分析容器维测相关的几个命令:

  • stats:获取容器资源使用状态
  • top:容器内运行进程信息

容器资源状态

1
2
3
4
5
6
7
Usage: docker stats [OPTIONS] [CONTAINER...]

Display a live stream of one or more containers’ resource usage statistics

-a, --all Show all containers (default shows just running)
--help Print usage
--no-stream Disable streaming stats and only pull the first result

stats命令会返回一个持续的容器资源统计数据流,可以通过指定一些容器ID或者name来限制检测的数量。
注:

  • 你可以指定一个停止的容器,但是不会返回任何数据。
  • 更详细的统计数据可以通过/containers/(id)/stats API获取

例如,获取所有运行的容器资源数据:

1
2
3
4
5
$ docker stats
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
1285939c1fd3 0.07% 796 KB / 64 MB 1.21% 788 B / 648 B 3.568 MB / 512 KB
9c76f7834ae2 0.07% 2.746 MB / 64 MB 4.29% 1.266 KB / 648 B 12.4 MB / 0 B
d1ea048f04e4 0.03% 4.583 MB / 64 MB 6.30% 2.854 KB / 648 B 27.7 MB / 0 B

容器内进程信息

1
2
3
4
5
Usage: docker top [OPTIONS] CONTAINER [ps OPTIONS]

Display the running processes of a container

--help Print usage

top命令会显示容器内运行进程的一些信息,例如:

1
2
3
4
5
6
# docker top hexo
UID PID PPID C STIME TTY TIME CMD
root 3999 3983 0 Feb25 pts/24 00:00:00 /bin/sh -c hexo generate && hexo server
root 4097 3999 0 Feb25 pts/24 00:12:31 hexo
root 17660 17644 0 Feb27 pts/30 00:00:00 /bin/bash
root 28408 28392 0 Feb27 pts/31 00:00:00 /bin/bash

注意:top只会返回一次结果,和stats的结果不一样。


作者: 耗子007


所有命令均基于docker1.11版本

容器相关的命令,主要包括容器的管理、日志、信息查看以及内容操作。
注:由于有些命令比较复杂,限于篇幅可能需要单独开一章,进行详细分析。

容器管理

容器的管理涉及容器的整个生命周期:创建、启动、运行、挂起、唤醒、重启、停止、杀死以及删除。本文以容器的生命周期为主线一个个罗列相关命令。

容器的创建

1
2
3
4
5

Usage: docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

Create a new container
......

注意:由于docker create的选项和docker run是一样的,因此这里不详细说明,等到docker run分析的时候,再详细分析。
create用于创建一个新的容器,主要工作有:

  • 在指定镜像之上,创建容器的可写层;
  • 并且准备容器运行指定的命令
  • 输出容器ID到STDOUT

“docker create”和”docker run -d”是基本一样的,除了不启动容器外,当然,你可以在任何时候用docker start启动创建的容器。
介绍几个简单的使用示例:
创建并启动一个可交互的容器

1
2
3
4
$ docker create -t -i fedora bash
6d8af538ec541dd581ebc2a24153a28329acb5268abe5ef868c1f1a261221752
$ docker start -a -i 6d8af538ec5
bash-4.2#

创建数据卷容器

这是由于v1.4.0后容器的数据卷是在create的阶段进行初始化的,因此create容器数据卷,然后直接在其他容器使用,如下:

1
2
3
4
5
6
$ docker create -v /data --name data ubuntu
240633dfbb98128fa77473d3d9018f6123b99c454b3251427ae190a7d951ad57
$ docker run --rm --volumes-from data ubuntu ls -la /data
total 8
drwxr-xr-x 2 root root 4096 Dec 5 04:10 .
drwxr-xr-x 48 root root 4096 Dec 5 04:11 ..

更详细的分析参考docker runDocker run refrence

容器的启动

1
2
3
4
5
6
7
8
Usage: docker start [OPTIONS] CONTAINER [CONTAINER...]

Start one or more containers

-a, --attach Attach STDOUT/STDERR and forward signals
--detach-keys Specify the escape key sequence used to detach a container
--help Print usage
-i, --interactive Attach container STDIN

start命令用于启动一个或者多个容器。start命令的几个参数选项的含义和其他命令的含义是一致的:

  • -a:链接到容器的STDOUT/STDERR,而且可以接收到容器的信号
  • –detach-keys:这个指定detach的快捷键
  • -i:表示连接到容器的STDIN,这样才能做一些输入操作,例如敲bash命令

注意:这里的-a只是能接收STDOUT/STDERR的数据,如果另外一个shell窗口用docker exec -it连到一个容器,exec里面对容器的操作不会反抗到start -a的窗口。
有点类似于-a是串口,而exec是ssh登录进去的情况。

容器的运行

run命令可以用于直接运行容器,可以理解为run = create + start,由于这部分内容比较多,单独用一篇文章描述

容器的挂起

1
2
3
4
5
Usage: docker pause [OPTIONS] CONTAINER [CONTAINER...]

Pause all processes within a container

--help Print usage

pause命令可以暂停一个容器内所有的进程。

容器的唤醒

1
2
3
4
5
Usage: docker unpause [OPTIONS] CONTAINER [CONTAINER...]

Unpause all processes within a container

--help Print usage

unpause命令与pause命令相对应,用于唤醒一个容器内所有的进程。

容器的重启

1
2
3
4
5
6
Usage: docker restart [OPTIONS] CONTAINER [CONTAINER...]

Restart a container

--help Print usage
-t, --time=10 Seconds to wait-for-stop before killing the container

restart命令用于重启一个容器,可以用-t设置等待容器停止的时间,超时则杀死容器。

容器的停止

1
2
3
4
5
6
7
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop a container by sending SIGTERM and then SIGKILL after a
grace period

--help Print usage
-t, --time=10 Seconds to wait-for-stop before killing it

stop命令可以通过发送SIGTERM以及合理间隔后发送的SIGKILL来停止一个容器,-t选项和restart的用法一致。
注:只有容器的主进程才会收到SIGTERM信号,并且在合理间隔之后收到SIGKILL信号。

容器的杀死

1
2
3
4
5
6
Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]

Kill a running container using SIGKILL or a specified signal

--help Print usage
-s, --signal="KILL" Signal to send to the container

kill命令通过SIGKILL或者其他指定信号来杀死一个运行中的容器,-s选项可以指定一个发送给容器的信号。
和stop一样,主进程会收到信号。

注意:如果ENTRYPOINT和CMD是以shell格式运行的,那么他们是不会收到信号的。这是由于这种情况下bash才是主进程,
只有PID为1的进程能收到。关于ENTRYPOINT和CMD可以参考官方文档

容器的删除

1
2
3
4
5
6
7
8
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers

-f, --force Force the removal of a running container (uses SIGKILL)
--help Print usage
-l, --link Remove the specified link
-v, --volumes Remove the volumes associated with the container

rm可以删除一个或者多个容器。
可以通过指定–force选项,通过发送SIGKILL信号强制删除一个运行的容器,例如:docker rm –force redis
可以通过–link删除默认网桥上指定的link,删除所有的网络配置,例如:docker rm –link /webapp/redis
注意:–link不能删除用户指定的网络,只能删除默认网桥上的link。
可以通过–volumes删除容器关联的数据卷,这里需要注意下面的情况:

1
2
3
$ docker create -v awesome:/foo -v /bar --name hello redis
hello
$ docker rm -v hello

这里只会删除/bar数据卷,/foo数据卷不会被删除,是由于/foo关联到host的文件或者目录awesome。

删除所有停止的容器:docker rm $(docker ps -a -q)

容器的重命名

1
2
3
4
5
Usage: docker rename [OPTIONS] OLD_NAME NEW_NAME

Rename a container

--help Print usage

rename命令可以用于重命名容器。
注意:如果你启动的时候没有指定容器的名字,docker会生成一个,但是你也可以用容器的ID作为OLD_NAME来重命名该容器。
例如:docker rename b8929ca5eda3 haozi

容器的更新

update命令用于更新容器的一些配置,详细可以参考update命令分析

关于容器生命周期相关的命令,就结束了。下面看看其他和容器相关的一些常用的命令。

attach和exec命令

首先,attach可以挂到一个运行的容器上,而exec可以在容器内执行指定的命令。

1
2
3
4
5
6
7
8
Usage: docker attach [OPTIONS] CONTAINER

Attach to a running container

--detach-keys="<sequence>" Set up escape key sequence
--help Print usage
--no-stdin Do not attach STDIN
--sig-proxy=true Proxy all received signals to the process

attach命令可以挂到一个运行中的容器上,然后你可以看到该容器正在输出的内容,或者以交互的方式控制它。

停止一个容器默认使用Ctrl-c,这个组合键会发送一个SIGKILL信号给容器。但是–sig-proxy=true被设置的话,
Ctrl-c会发送SIGINT给容器。可以通过Ctrl+p,Ctrl+q端口连接并保持容器运行。

注意:通过attach连接到容器的stdio,Docker提供1MB的缓存接收应用的输出,如果buffer满了,会影响attach的输出速度。

然后,exec可以在运行的容器中运行一条命令。当容器运行的第一条命令不是bash或者没有指定-it的时候,用attach连到容器是不能做一些输入或者指令操作的。
但是我们可以用exec在容器内运行bash或者其他指令来达到操作容器的目的。

1
2
3
4
5
6
7
8
9
10
11
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

-d, --detach Detached mode: run command in the background
--detach-keys Specify the escape key sequence used to detach a container
--help Print usage
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended Linux capabilities to the command
-t, --tty Allocate a pseudo-TTY
-u, --user= Username or UID (format: <name|uid>[:<group|gid>])

注:exec只有在容器的第一个进程在运行时,才能执行。如果容器是pause状态,exec会返回失败。
各选项作用:

  • –detach:后台执行命令
  • –detach-keys:指定断开连接的快捷键
  • –interactive:支持输入
  • –privileged:设置运行命令在特权模式下运行
  • –tty:分配一个伪终端
  • –user:设置执行命令用户名

容器的日志

1
2
3
4
5
6
7
8
9
Usage: docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

-f, --follow Follow log output
--help Print usage
--since="" Show logs since timestamp
-t, --timestamps Show timestamps
--tail="all" Number of lines to show from the end of the logs

logs命令可以获取容器的日志信息。logs的日志信息保存位置取决于日志的驱动
默认容器日志的驱动为json,数据保存在/var/lib/docker/containers/container-ID/container-ID-json.log文件。
日志驱动可以通过docker run和docker daemon的–log-driver选项设置。

logs命令的选项作用:

  • –follow:命令可以持续获取容器的STDOUT和STDERR的信息。
  • –since:命令值显示指定时间戳之后的日志
  • –timestamps:命令在每条日志之前加上时间戳
  • –tail:命令只显示日志最后的指定行数


作者: 耗子007


错误日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
INFO  Start processing
FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html
Template render error: (unknown path) [Line 191, Column 51]
unexpected token: .
at Object.exports.prettifyError (/blog/node_modules/nunjucks/src/lib.js:34:15)
at new_cls.render (/blog/node_modules/nunjucks/src/environment.js:469:27)
at new_cls.renderString (/blog/node_modules/nunjucks/src/environment.js:327:21)
at /blog/node_modules/hexo/lib/extend/tag.js:66:9
at Promise._execute (/blog/node_modules/bluebird/js/release/debuggability.js:299:9)
at Promise._resolveFromExecutor (/blog/node_modules/bluebird/js/release/promise.js:481:18)
at new Promise (/blog/node_modules/bluebird/js/release/promise.js:77:14)
at Tag.render (/blog/node_modules/hexo/lib/extend/tag.js:64:10)
at Object.tagFilter [as onRenderEnd] (/blog/node_modules/hexo/lib/hexo/post.js:253:16)
at /blog/node_modules/hexo/lib/hexo/render.js:65:19
at tryCatcher (/blog/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/blog/node_modules/bluebird/js/release/promise.js:510:31)
at Promise._settlePromise (/blog/node_modules/bluebird/js/release/promise.js:567:18)
at Promise._settlePromise0 (/blog/node_modules/bluebird/js/release/promise.js
FROM node
:612:10)
at Promise._settlePromises (/blog/node_modules/bluebird/js/release/promise.js:691:18)
at Async._drainQueue (/blog/node_modules/bluebird/js/release/async.js:138:16)
at Async._drainQueues (/blog/node_modules/bluebird/js/release/async.js:148:10)
at Immediate.Async.drainQueues (/blog/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:649:20)
at tryOnImmediate (timers.js:622:5)
at processImmediate [as _immediateCallback] (timers.js:594:5)
FATAL (unknown path) [Line 191, Column 51]
unexpected token: .
Template render error: (unknown path) [Line 191, Column 51]
unexpected token: .
at Object.exports.prettifyError (/blog/node_modules/nunjucks/src/lib.js:34:15)
at new_cls.render (/blog/node_modules/nunjucks/src/environment.js:469:27)
at new_cls.renderString (/blog/node_modules/nunjucks/src/environment.js:327:21)
at /blog/node_modules/hexo/lib/extend/tag.js:66:9
at Promise._execute (/blog/node_modules/bluebird/js/release/debuggability.js:299:9)
at Promise._resolveFromExecutor (/blog/node_modules/bluebird/js/release/promise.js:481:18)
at new Promise (/blog/node_modules/bluebird/js/release/promise.js:77:14)
at Tag.render (/blog/node_modules/hexo/lib/extend/tag.js:64:10)
at Object.tagFilter [as onRenderEnd] (/blog/node_modules/hexo/lib/hexo/post.js:253:16)
at /blog/node_modules/hexo/lib/hexo/render.js:65:19
at tryCatcher (/blog/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/blog/node_modules/bluebird/js/release/promise.js:510:31)
at Promise._settlePromise (/blog/node_modules/bluebird/js/release/promise.js:567:18)
at Promise._settlePromise0 (/blog/node_modules/bluebird/js/release/promise.js:612:10)
at Promise._settlePromises (/blog/node_modules/bluebird/js/release/promise.js:691:18)
at Async._drainQueue (/blog/node_modules/bluebird/js/release/async.js:138:16)
at Async._drainQueues (/blog/node_modules/bluebird/js/release/async.js:148:10)
at Immediate.Async.drainQueues (/blog/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:649:20)
at tryOnImmediate (timers.js:622:5)
at processImmediate [as _immediateCallback] (timers.js:594:5)

解决方法

由于markdown文件中包含了“{ { *** } }”(注意括号之间没有空格),可以在“{加一个空格{”。