Docker 入门
确保Docker就绪
调用info命令,查看所有容器和镜像的数量、执行驱动、存储驱动和基本配置。
[root@ecs-wangxing ~]# docker info
Containers: 43
Running: 1
Paused: 0
Stopped: 42
Images: 43
Server Version: 1.13.1
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: journald
Cgroup Driver: systemd
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: docker-runc runc
Default Runtime: docker-runc
Init Binary: /usr/libexec/docker/docker-init-current
containerd version: (expected: aa8187dbd3b7ad67d8e5e3a15115d3eef43a7ed1)
runc version: 9c3c5f853ebf0ffac0d087e94daef462133b69c7 (expected: 9df8b306d01f59d3a8029be411de015b7304dd8f)
init version: fec3683b971d9c3ef73f284f176672c44b448662 (expected: 949e6facb77383876aeff8a6944dde66b3089574)
Security Options:
seccomp
WARNING: You're not using the default seccomp profile
Profile: /etc/docker/seccomp.json
Kernel Version: 3.10.0-1062.1.1.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 3
CPUs: 2
Total Memory: 3.7 GiB
Name: ecs-wangxing
ID: 43ZI:MWIQ:RHL2:AFXS:5JKN:ZMVT:IDMA:HKXW:OCH2:33TK:3HFL:TZ2T
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Registries: docker.io (secure)
运行第一个容器
# 指令为:sudo docker run -i -t ubuntu /bin/bash, 下面是根用户
[root@ecs-wangxing ~]# docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
Trying to pull repository docker.io/library/ubuntu ...
latest: Pulling from docker.io/library/ubuntu
7ddbc47eeb70: Pull complete
c1bbdc448b72: Pull complete
8c3b70e39044: Pull complete
45d437916d57: Pull complete
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Downloaded newer image for docker.io/ubuntu:latest
-i
是保证容器中的STDIN是开启的,-t
为分配的容器分配一个伪tty终端,这样 新创建的容器才能提供一个交互式的shell。
若要在命令行下创建一个我们能与之交互的容器,而不是一个运行后台服务的容器,则这两个参数是最基本的参数。- 实例中用的是centos镜像,为基础镜像,可以以此为基础,在选择的操作系统上构建自己的镜像。
- 目前为止,我们基于此基础镜像启动了一个容器,并且没有对容器增加任何东西。
- 背后操作:Docker首先会检查本地是否存在ubuntu镜像,若不存在,则会连接官方维护的Docker Hub Registry,查看其Hub中是否存在。 一旦找到,就会将此镜像下载并保存到宿主主机中。
- 创建完毕后,Docker就会执行容器中的/bin/bash 命令,这样就可以看到容器内的shell了。如下图:
root@d113c9a7c46a:/#
使用第一个容器
容器主机名
root@d113c9a7c46a:/# hostname
d113c9a7c46a
查看 /etc/hosts 文件
root@d113c9a7c46a:/# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4 d113c9a7c46a
容器内运行的进程
root@d113c9a7c46a:/# ps -aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 18496 2080 ? Ss 08:40 0:00 /bin/bash
root 15 0.0 0.0 34388 1460 ? R+ 08:47 0:00 ps -aux
安装软件包 vim
root@d113c9a7c46a:/# apt-get update && apt-get install vim
所有工作结束时,输入exit
就可以返回到宿主主机的命令提示符中了,此容器也会停止运行。
可用 docker ps -a 查看容器列表
[root@ecs-wangxing ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d113c9a7c46a ubuntu "/bin/bash" 21 minutes ago Exited (127) 5 seconds ago elated_almeida
187bd41d814b centos "/bin/bash" About an hour ago Up About an hour hungry_poincare
04b7da861d84 django-uwsgi-nginx "supervisord -n" 10 days ago Exited (0) 10 days ago practical_pare
容器命名 – 创建新容器并起个别字
sudo docker run --name my_container -i -t ubuntu /bin/bash
启动已经停止运行的容器,也可以通过id来启动。
也可以用 restart 来重启一个容器
类似的,也可以用docker create 来创建一个容器,但是不运行
sudo docker start my_container
附着在容器上
在宿主主机start 或者 restart 容器之后,只是启动(重启)了这个容器,命令行光标还是停留在宿主主机的terminal中,把光标附在容器上的命令是 attach
# 可以观察下面两行光标的区别
root@ecs-wangxing ~]# docker attach d113c9a7c46a
root@d113c9a7c46a:/#
创建守护式 容器
除了上述的交互式容器(interactive container)之外,也可以创建长期运行的容器。
守护式容器(daemonized container)没有交互式会话,非常适合运行应用程序和服务。大多数时候都需要 守护式 来运行我们的容器
下面展示一个 创建长期运行的容器的例子
[root@ecs-wangxing ~]# sudo docker run --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
c7b14bcb5ef00940f476385618133e7203e375559436ae133a77491e1c827d38
[root@ecs-wangxing ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7b14bcb5ef0 ubuntu "/bin/sh -c 'while..." 5 seconds ago Up 4 seconds daemon_dave
-d
参数会使容器在后台运行,上面的容器中包含一个while循环,该循环会一直打印hello world,直到容器或其进程停止运行。
容器内部都在干些什么
docker logs
可以获取容器的日志
[root@ecs-wangxing ~]# docker logs daemon_dave
hello world
hello world
hello world
可以在命令后加 -f
参数来监控Docker日志
然后通过 ctrl+c 退出日志跟踪
也可以跟踪日志的某一片段
# 获取日志的最后10行内容
sudo docker logs --tail 10 daemon_dave
# 跟踪日志的最新内容, 而不必读取整个日志
sudo docker logs --tail 0 -f daemon_dave
# 可以用 -t 参数加上时间戳
[root@ecs-wangxing ~]# sudo docker logs --tail 1 -ft daemon_dave
2019-12-06T10:50:09.647285000Z hello world
2019-12-06T10:50:10.648264000Z hello world
2019-12-06T10:50:11.649094000Z hello world
Docker 日志驱动
- 自docker1.6开始,也可以控制docker守护进程和容器所用的日志驱动。
- 通过
--log-driver
选项来实现。可以在启动docker守护进程或者执行docker run
命令时使用这个选项。 - 参数有好几个选项,比如默认的
json-file
以及syslog
,后者将禁用docker logs
指令,并将所有容器的日志都重定向到Syslog
。 可以在启动docker守护进程时指定该选项,也可以通过docker run
对个别的容器进行日志重定向输出。
[root@ecs-wangxing ~]# sudo docker run --log-driver="syslog" --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
c7b14bcb5ef00940f476385618133e7203e375559436ae133a77491e1c827d38
上述命令会将daemon_dave 容器的日志都输出到Syslog,导致docker logs
不输出任何东西。
- 还有一个选项是
none
,会禁用所有容器的日志,导致docker logs
命令也被禁用。
查看容器内的进程
除了容器日志,也可以查看容器内运行的进程,使用docker top
命令。
[root@ecs-wangxing ~]# docker top daemon_dave
Error response from daemon: Container c7b14bcb5ef00940f476385618133e7203e375559436ae133a77491e1c827d38 is not running
[root@ecs-wangxing ~]# docker start daemon_dave
daemon_dave
[root@ecs-wangxing ~]# docker top daemon_dave
UID PID PPID C STIME TTY TIME CMD
root 4314 4297 0 10:54 ? 00:00:00 /bin/sh -c while true; do echo hello world; sleep 1; done
root 4354 4314 0 10:54 ? 00:00:00 sleep 1
Docker统计信息
docker stats
用来显示一个或多个容器的统计信息。
可以展示容器列表的CPU、内存、网络I/O 和 存储I/O 的性能和指标
[root@ecs-wangxing ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7b14bcb5ef0 ubuntu "/bin/sh -c 'while..." 5 days ago Up 6 minutes daemon_dave
b6eca068ee89 neo4j:3.5 "/sbin/tini -g -- ..." 2 weeks ago Up 2 weeks 0.0.0.0:7474->7474/tcp, 7473/tcp, 0.0.0.0:7687->7687/tcp musing_shannon
[root@ecs-wangxing ~]# docker stats daemon_dave musing_shannon
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
daemon_dave 0.08% 192 KiB / 3.7 GiB 0.00% 656 B / 656 B 0 B / 0 B 2
musing_shannon 0.24% 1.438 GiB / 3.7 GiB 38.86% 361 MB / 3.19 GB 5.19 GB / 258 kB 42
- 注意 这里的daemon_dave 是守护进程
在容器内部运行进程
- 在docker1.3之后,也可以通过
docker exec
在容器内部额外启动新进程。 - 可以在容器内运行的进程有两种类型:后台任务 和 交互式任务
在容器中运行后台任务
[root@ecs-wangxing ~]# docker start my_container_12_12
my_container_12_12
[root@ecs-wangxing ~]# docker exec -d my_container_12_12 touch /etc/new_config_file
[root@ecs-wangxing ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c18b745e58c ubuntu "/bin/bash" About an hour ago Up 43 seconds my_container_12_12
c7b14bcb5ef0 ubuntu "/bin/sh -c 'while..." 5 days ago Up 39 minutes daemon_dave
b6eca068ee89 neo4j:3.5 "/sbin/tini -g -- ..." 2 weeks ago Up 2 weeks 0.0.0.0:7474->7474/tcp, 7473/tcp, 0.0.0.0:7687->7687/tcp musing_shannon
[root@ecs-wangxing ~]# docker attach my_container_12_12
root@2c18b745e58c:/# cd etc/
root@2c18b745e58c:/etc# ls -l
lrwxrwxrwx 1 root root 12 Dec 12 02:19 mtab -> /proc/mounts
-rw-r--r-- 1 root root 91 Apr 9 2018 networks
-rw-r--r-- 1 root root 0 Dec 12 03:33 new_config_file
……
-
上面的例子会在my_container_12_12中
etc/
目录下创建一个空文件new_config_file
-
通过docker exec 后台命令,可以在正在运行的容器中进行维护、监控以及管理任务
也可以在守护式容器中启动一个诸如打开 shell的交互式任务
在容器中运行交互式命令
[root@ecs-wangxing ~]# docker exec -t -i daemon_dave /bin/bash
root@c7b14bcb5ef0:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@c7b14bcb5ef0:/# hostname
c7b14bcb5ef0
- 上述命令在daemon_dave中创建了一个新的bash对话,根据这个会话,就可以在该容器中运行其他命令了。
- 注意这里的daemon_dave是守护进程
停止守护式容器
docker stop daemon_dave
# 或者
docker stop container_id
- 如果想快速停止某个容器,也可以使用
docker kill
指令 docker ps -n 3
会显示最后3个使用的容器,不论该容器是正在运行还是被关闭
自动重启容器
如果由于某种错误导致容器停止运行,还可以通过 --restart
标志,让docker自动重启该容器。--restart
标志会检查容器的退出代码返回值,并据此来判断是否需要重启容器。
- 默认行为是Docker不会自动重启容器
sudo docker run --restart=always --name daemon_dave -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
- 上述
--restart
标志被设置为always
,无论容器退出代码的返回值为什么,docker都会自动重启容器。 on-failure
只有当退出代码返回值非0值时,才重启容器。
也可以加入count参数
--restart=on-failure:5
上述表示当退出代码返回值非0时,会自动重启容器,最多重启5次
深入容器
docker inspect
获取更多容器信息
[root@ecs-wangxing ~]# docker inspect daemon_dave
[
{
"Id": "c7b14bcb5ef00940f476385618133e7203e375559436ae133a77491e1c827d38",
"Created": "2019-12-06T10:19:15.754389976Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true; do echo hello world; sleep 1; done"
],
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 137,
"Error": "",
"StartedAt": "2019-12-12T02:54:28.631296481Z",
"FinishedAt": "2019-12-12T06:03:27.919208017Z"
},
……
docker inspect
会对容器进行详细的检查,返回其配置信息,包括名称、命令和网络配置等信息。- 也可以用
-f
或者--format
来选定查看结果。
[root@ecs-wangxing ~]# docker inspect --format='{{ .Args}}' daemon_dave
[-c while true; do echo hello world; sleep 1; done]
删除容器
[root@ecs-wangxing ~]# docker rm daemon_dave
daemon_dave
可以通过一些小技巧(指令的组合)来删除全部容器
sudo docker rm `sudo docker ps -a -q`
sudo docker ps -a -q
会返回所有容器的id信息,然后由 docker rm
删除