容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
Docker容器
启动容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(exited
)的容器重新启动。
因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。
新建并启动
所需要的命令主要为 docker run
。
PS D:\hexoBlog> docker run ubuntu:18.04 /bin/echo 'Hello world'
Unable to find image 'ubuntu:18.04' locally
18.04: Pulling from library/ubuntu
284055322776: Pull complete
Digest: sha256:0fedbd5bd9fb72089c7bbca476949e10593cebed9b1fb9edf5b79dbbacddd7d6
Status: Downloaded newer image for ubuntu:18.04
Hello world
PS D:\hexoBlog>
下面的命令则启动一个 bash 终端,允许用户进行交互。
PS D:\hexoBlog> docker run -t -i ubuntu:18.04 /bin/bash
root@90c7e77fd36f:/#
-t
选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i
则让容器的标准输入保持打开。
在交互模式下,用户可以通过所创建的终端来输入命令,例如
PS D:\hexoBlog> docker run -t -i ubuntu:18.04 /bin/bash
root@90c7e77fd36f:/# pwd
/
当利用 docker run
来创建容器时,Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从 registry 下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个 ip 地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
启动已终止容器
可以利用 docker start [OPTIONS] 容器 [容器2...]
命令,直接将一个已经终止(exited
)的容器启动运行。
PS D:\hexoBlog> docker start 90c7e77fd36fe91b84dcf4b400ebc99b84875bcd7eb4df4646bf4b3e44e43b61
90c7e77fd36fe91b84dcf4b400ebc99b84875bcd7eb4df4646bf4b3e44e43b61
PS D:\hexoBlog> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
90c7e77fd36f ubuntu:18.04 "/bin/bash" 6 minutes ago Up 5 seconds awesome_dijkstra
PS D:\hexoBlog>
守护态运行
更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。
此时,可以通过添加 -d
参数来实现。
如果不使用 -d
参数运行容器。
PS D:\hexoBlog> docker run ubuntu:18.04 /bin/bash -c "while true; do echo hello world; sleep 1; done"
hello world
hello world
hello world
容器会把输出的结果 (STDOUT) 打印到宿主机上面
如果使用了 -d
参数运行容器。
PS D:\hexoBlog> docker run -d ubuntu:18.04 /bin/bash -c "while true; do echo hello world; sleep 1; done"
088422d392d10c33c0607f0b324d22ed77ee50e6f84b59e980d31bb8be08a146
PS D:\hexoBlog> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
088422d392d1 ubuntu:18.04 "/bin/bash -c 'while…" 28 seconds ago Up 27 seconds awesome_shirley
PS D:\hexoBlog> docker container logs 088
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
此时容器会在后台运行并不会把输出的结果 (STDOUT) 打印到宿主机上面(输出结果可以用 docker logs
查看)。
使用 -d
参数启动后会返回一个唯一的 id,也可以通过 docker container ls
命令来查看容器信息。
要获取容器的输出信息,可以通过 docker container logs
命令。
终止
可以使用 docker container stop
来终止一个运行中的容器。
PS D:\hexoBlog> docker container stop 088
088
PS D:\hexoBlog>
例如对于上一章节中只启动了一个终端的容器,用户通过 exit
命令或 Ctrl+d
来退出终端时,所创建的容器立刻终止。
终止状态的容器可以用 docker container ls -a
命令看到。例如
PS D:\hexoBlog> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
PS D:\hexoBlog> docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
088422d392d1 ubuntu:18.04 "/bin/bash -c 'while…" 8 minutes ago Exited (137) 50 seconds ago awesome_shirley
PS D:\hexoBlog>
处于终止状态的容器,可以通过 docker container start
命令来重新启动。
此外,docker container restart
命令会将一个运行态的容器终止,然后再重新启动它。
PS D:\hexoBlog> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
088422d392d1 ubuntu:18.04 "/bin/bash -c 'while…" 6 minutes ago Up 6 minutes awesome_shirley
PS D:\hexoBlog> docker container restart 088
088
进入容器
exec
命令
-i
-t
参数
docker exec
后边可以跟多个参数,这里主要说明 -i
-t
参数。
只用 -i
参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。
当 -i
-t
参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。
PS D:\hexoBlog> docker exec -it 088 /bin/bash
root@088422d392d1:/# exit
exit
docker exec 无法进入容器问题解决
docker run -d -P --name web --mount source=my-vol,target=/usr/share/nginx/html nginx:alpine
PS C:\Users\wang> docker exec -it f9f /bin/bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "/bin/bash": stat /bin/bash: no such file or directory: unknown
经过各种求教,得到的答案,nginx:alpine精简版,在做镜像的时候,只装了sh,没有装bash,所以用不了bash。shell类型有很多种,但是sh类型的shell是最基础的,所以大部分镜像都支持。这就不难理解为什么docker exec -it 可以使用 /bin/sh进入镜像内部了。
docker exec使用小技巧:后面的/bin/或者/usr/bin/可以省略掉,直接写sh 或者 bash。
导入和导出
导出容器
PS C:\Users\wang> docker export 088 > dead.tar
PS C:\Users\wang> docker import dead.tar test20210608ubuntu:v3
Error response from daemon: Error processing tar file(exit status 1): archive/tar: invalid tar header
windows下会导出到当前D:\hexoBlog路径下
>“符号仅在linux下使用 windows中只能用-o导出
导入容器快照
PS C:\Users\wang> docker export 088 -o dead.tar
PS C:\Users\wang> docker import dead.tar test20210ntu:v3
sha256:1888c816f59ea7288cfd82be6922e493f67f05e5fbbc754a4046efb541c83197
PS C:\Users\wang>
删除
可以使用 docker container rm
来删除一个处于终止状态的容器。
如果要删除一个运行中的容器,可以添加 -f
参数。Docker 会发送 SIGKILL
信号给容器。
PS C:\Users\wang> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
088422d392d1 ubuntu:18.04 "/bin/bash -c 'while…" 47 minutes ago Up 6 minutes awesome_shirley
PS C:\Users\wang> docker container rm -f 088
088
PS C:\Users\wang> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
PS C:\Users\wang> docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
PS C:\Users\wang>
清理所有处于终止状态的容器
用 docker container ls -a
命令可以查看所有已经创建的包括终止状态的容器,如果数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。
docker container prune
容器自启动
新建容器时自启动
# 新建容器时 --restart=always
docker run -d --restart=always --name mynginx -p 8080:80 nginx
已有容器设置自启动
PS C:\Users\wang> docker update --restart=always portainer
portainer
PS C:\Users\wang>
如果docker本身不是开机自启动,请先设置docker开机自启
systemctl enable docker
查看日志
PS C:\Users\wang> docker logs -f portainer
2023/04/13 16:07:19 Warning: the --template-file flag is deprecated and will likely be removed in a future version of Portainer.
2023/04/13 16:07:23 [ERROR] [http,client] [message: unexpected status code] [status_code: 403]
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的主机路径