容器是独立运行的一个或者一组应用,以及他们的运行态环境。
容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必修的。除此之外,没有其他的资源
docker的启动和停止
systemctl**命令是系统服务管理器指令
>* systemctl start docker
>* systemctl stop docker
>* systemctl restart docker
>* systemctl status docker
>* systemctl enable docker【开机启动】
Docker帮助命令
> * sudo docker version
> * sudo docker info 【docker具体信息】
> * sudo docker --help 【帮助命令】
Docker容器命令
什么是容器
- 简单来说,容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层,同时,容器中的应用进程处于运行状态。
- 镜像相当于可执行文件,容器相当于一个进程。一个镜像可以启动多个容器
- docker container run是启动容器的命令,这个命令可以携带很多参数
操作
准备
(1)先确保docker是否正在运行:
$ service docker status
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2022-06-08 15:00:39 CST; 5h 56min ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 1254 (dockerd)
// 或者
$ systemctl is-active docker
active
active (running)表示容器正常运行了。
创建容器
创建,然后启动一个容器(不看,因为不实用)
可以使用docker create新建一个容器。使用 docker create命令新建的容器处于停止状态,可以使用 docker start命令来启动它。
$ docker create -it ubuntu:latest
d16fe1d1838499a8e371877bf2bbcc94812a04ecf7045c9b22ce8951ea057d3e
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d16fe1d18384 ubuntu:latest "bash" 17 seconds ago Created
$ docker start d16fe1d18384
d16fe1d18384
$ docker ps // 查看运行中的日期哦你
docker create相关选项
创建并启动容器(推荐)
比如下面命令输出一个Hello“”之后自动终止:
$ docker run ubuntu /bin/echo "Hello"
Hello
如下两个命令都是:以镜像ubuntu为模板,启动一个容器,名字叫做mycentos,-it表示这个容器是可以进行交互的。容器会运行/bin/bash。这会使得bash称为容器中运行的而且唯一运行的进程
$ docker run -it --name myubuntu ubuntu
root@dbafb74644c6:/# exit
$ docker run -it ubuntu /bin/bash
root@5fd34130042c:/# pwd
/
root@5fd34130042c:/# ping www.baidu.com
bash: ping: command not found
root@5fd34130042c:/# ps -elf
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S root 1 0 0 80 0 - 1157 do_wai 13:11 pts/0 00:00:00 /bin/bash
4 R root 10 1 0 80 0 - 1765 - 13:12 pts/0 00:00:00 ps -elf
root@5fd34130042c:/# exit
exit
- 5fd34130042c是容器的id的前12个字符
(1)
(2)对于ps -elf的结果:
、、
可以使用如下命令等待容器退出,并打印返回结果:
$ docker wait b140c9dc86af
0
守护态运行
更多的时候,需要让 Docker 容器在后台以守护态 形式运行。此时,可以通过添加-d
参数来实现(后台运行的方式不会将当前终端连接到容器中)。但是仅仅只有bin是不行的,比如,执行如下命令:
$ docker run -d --name hcentos centos
会发现只运行一下就马上退出了,执行docker ps也没有发现hcentos。为什么呢?Docker容器后台运行必须有前台进程,如果没有前台进程,也就是那些一直挂起的命令如top,tail等,容器后台启动之后,会立即自杀因为没事可做
我们来执行如下命令:
$ docker run centos /bin/sh -c "while true; do echo hello world; sleep 1; done"
可以发现容器在前台每隔1s在终端打印hello world
$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done;"
50ed4f9647f6c9d195b73b780f2232624497badbadaa0d39d374751c39290729
容器启动后,没有打印hello world,只是会返回了一个唯一的 id, 可以通过 docker ps 或 docker container ls命令来查看容器信息:
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
50ed4f9647f6 ubuntu "/bin/sh -c 'while t…" 15 minutes ago Up 15 minutes ecstatic_nash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
50ed4f9647f6 ubuntu "/bin/sh -c 'while t…" 34 seconds ago Up 33 seconds ecstatic_nash
要获取容器的输出信息,可以通过 docker logs 命令。
$ docker logs 50
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
docker logs支持的选项包括:
小结
当利用 docker run
来创建并启动容器时, Docker 在后台运行的标准操作包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载;
- 利用镜像创建一个容器,并启动该容器;
- 分配一个文件系统给容器,并在只读的镜像层外面挂载一层可读写层;
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去;
- 从网桥的地址池配置一个 IP 地址给容器;
- 执行用户指定的应用程序;
- 执行完毕后容器被自动终止。
一些子项:
- -i表示交互
- -t表示终端
- -d 表示以守护方式打开(即非交互模式,后台运行)
- –name表示为容器指定一个名称
- -p 80:8080,将主机的80端口映射到容器内的8080端口。这意味着当有流量访问主机的80端口的时候,流量会直接映射到容器内的8080端口,可以通过
docker container ls
查看端口映射情况
更多的命令选项可以通过 man docker-run
或者 docker run --help
命令来查看。
$ man docker run
$ docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
停止容器
暂停容器
可以使用 docker pause 命令来暂停一个运行中的容器。使用docker unpause来恢复容器运行
$ docker run --name test --rm -it ubuntu bash
root@ccc1b9bcd27a:/#
//另一个终端
$ docker pause test
test
// 从下面命令STATUS列可以看出容器处于pause暂停
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ccc1b9bcd27a ubuntu "bash" About a minute ago Up About a minute (Paused) test
终止容器
有三种方法。
(1)停止容器(给进程清理自己的资源的机会)
$ docker stop ccc1b9bcd27a
ccc1b9bcd27a
(2)强制停止容器
docker kill 5e7ac06ea9be
(3)退出容器
- exit:容器停止退出
- ctrl+P+Q:容器不停止退出
- 会断开shell与容器终端之间的连接,并在退出之后保存容器在后台运行状态(Up)
可以用 docker ps -qa命令看到所有容器的 ID。
docker ps -qa
50ed4f9647f6
0bfd8c4e1249
cd8d540effdf
重启容器
处于终止状态的容器,可以通过docker start重启:
$ docker container start 50ed4f9647f6
可以使用docker restart重启容器:
$ docker container restart 50ed4f9647f6
语法:
sudo docker [container] start/restart 容器名或者容器ID
备注:虽然container是可选的,但是建议加上,发现加上的话命令执行速度更快
进入容器
在使用-d
参数时,容器启动后会进入后台,用户无法看到容器中的信息,也无法进行操作。
这个时候如果需要进入容器进行操作,推荐使用官方的attach 或 exec 命令。
docker attach
看个例子
(1)运行容器(d表示后台运行,it表示交互):
$ sudo docker run -dit ubuntu
06f6eb10c381b539f6576fc5b3dd715c65d60496ec8c4518bc14abfa32ece789
(2)进入容器:
$ docker attach 06f6eb10c
root@06f6eb10c381:/#
root@06f6eb10c381:/# exit
exit
$
备注:不推荐使用。因为当多个窗口同时attach 到同一个容器的时候,所有窗口都会同步显示;当某个窗口因命令阻塞时,其他窗口也无法执行操作了。
docker exec
$ docker container exec -it 50ed /bin/bash
root@06f6eb10c381:/#
50ed 是一个正在运行的容器的id
总结:attach和exec命令对比
相同点:
- 都是进入正在运行的容器内
不同点
- attach可以直接进入容器命令行,但是exec命令需要使用-it,bash才能打开可交互命令行
docker rm:删除容器
看个例子:
$ docker container ps -a
.....
d24d4dd757a8 5d1686b1730f "sh run.sh" 11 hours ago Created 554/tcp, 1935/tcp, 0.0.0.0:5060->5060/tcp, :::5060->5060/tcp, 6379/tcp, 0.0.0.0:18080->18080/tcp, 0.0.0.0:5060->5060/udp, :::18080->18080/tcp, :::5060->5060/udp, 18081/tcp, 554/udp, 0.0.0.0:30000-30500->30000-30500/tcp, 0.0.0.0:30000-30500->30000-30500/udp, :::30000-30500->30000-30500/tcp, :::30000-30500->30000-30500/udp, 0.0.0.0:8090->80/tcp, :::8090->80/tcp determined_hermann
$ docker rm d24d4dd757a8
- 默认情况下, docker rm 命令只能删除已经处于终止或退出状态的容器,并不能删除还处于运行状态的容器。
- 如果要直接删除一个运行中的容器,可以添加
-f
参数。 Docker 会先发送 SIGKILL信号给容器,终止其中的应用,之后强行删除
docker rm -f 2ea
批量删除容器
(1) 可以终止所有处于终止状态的容器:
$ docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
......
Total reclaimed space: 16.08MB
(2)删除全部容器
$ docker container rm $(docker container ls -aq) -f
导入和导出容器
某些时候,需要将容器从一个系统迁移到另外一个系统,此时可以使用 Docker 的导入和导出功能
docker export:导出容器
导出容器是指,导出一个巳经创建的容器到一个文件,不管此时这个容器是否处于运行状态。可以用docker export来指定
>docker export --help
Usage: docker export [OPTIONS] CONTAINER
Export a container's filesystem as a tar archive
Options:
--help Print usage
-o, --output string Write to a file, instead of STDOUT
从帮助可以看出:
- docker export是用来将container的文件系统进行打包的。
- 可以通过-o 选项来指定导出的tar 文件名,也可以直接通过重定向来实现。
看个例子:
$ docker export -o gb28181-`date +%Y%m%d`.tar cbed1583f0d8
$ docker export cbed1583f0d8 > gb28181-`date +%Y%m%d`.tar
docker export需要指定container,不能像docker save那样指定image或container都可以。
之后,可将导出的tar 文件传输到其他机器上,然后再通过导入命令导入到系统中,实现容器的迁移。
docker import:导入容器
docker import --help
Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Import the contents from a tarball to create a filesystem image
Options:
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Set commit message for imported image
--platform string Set platform if server is multi-platform capable
用户可以通过-c
选项在导入的同时执行对容器进行修改的 Dockerfile指令
例如:
docker import gb28181-20220608.tar gb28181:latest
- 从上面的命令可以看出,docker import将container导入后会成为一个image,而不是恢复为一个container。
- 另外一点是,docker import可以指定IMAGE[:TAG],说明我们可以为镜像指定新名称。如果本地镜像库中已经存在同名的镜像,则原有镜像的名称将会被剥夺,赋给新的镜像。原有镜像将成为孤魂野鬼,只能通过IMAGE ID进行操作。
docker load VS docker export
实际上,既可以使用 docker load 命令来导入镜像本地镜像库,也可以使用 docker import江命令来导入一个容器快照到本地镜像库。这两者的区别在于:容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积更大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
查看容器
docker inspect :查看容器详情
$ docker container inspect xxxx
docker top:查看容器内进程
$ docker container top 50ed4f9647f6
UID PID PPID C STIME TTY TIME CMD
root 4759 4738 0 19:42 ? 00:00:00 /bin/sh -c while true; do echo hello world; sleep 1; done;
root 8773 4759 0 20:39 ? 00:00:00 sleep 1
docker stats:查看统计信息
$ docker container stats 50
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
50ed4f9647f6 ecstatic_nash 0.07% 1.238MiB / 7.73GiB 0.02% 4.34kB / 0B 0B / 0B 2
^C
docker ls
- 查看当前正在运行的容器
docker container ls
docker container ps
- 查看所有容器包括已经终止的容器
·
docker container ls -a
docker container ps -a
其他容器命令
docker cp:复制文件
docker cp 命令支持在容器和主机之间复制文件
$ docker cp --help
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Copy files/folders between a container and the local filesystem
Use '-' as the source to read a tar archive from stdin
and extract it to a directory destination in a container.
Use '-' as the destination to stream a tar archive of a
container source to stdout.
Options:
-a, --archive Archive mode (copy all uid/gid information)
-L, --follow-link Always follow symbol link in SRC_PATH
-
-a, --archive
:打包模式,复制文件会带有原始的 uid/gid 信息; -
-L, --follow-link
:跟随软连接。当原路径为软连接时,默认只复制链接信息,使用该选项会复制链接的目标内容。
比如:
docker cp data 3eff:/tmp/
docker cp 3eff:/tmp/ data
docker diff:查看变更
# docker diff --help
Usage: docker diff CONTAINER
Inspect changes to files or directories on a container's filesystem
比如
$ docker diff 50
C /root
A /root/.bash_history
docker port:查看容器的端口映射情况
$ docker port 50ef
docker update:更新配置
利用重启策略进行容器的自我修复
有三种重启策略
- always
- unless-stop
- on-failed
(1)关于docker
$ docker container run --name neverdie -it --restart always ubuntu sh
#
#
#
// 等待几秒后输入exit
# exit
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b7de4266fb2 ubuntu "sh" About a minute ago Up 1 second neverdie
从上面看到,容器在1分钟之前被创建,但是在1s前才启动。这是因为在容器中输入退出命令的时候,容器被杀死,然后docker又重新启动了该容器
(2)unless-stop
看个例子:
(3) on-failed
容器的生命周期
(1)启动容器:
$ docker container run --name percy -it ubuntu /bin/bash
root@5cd50eecf8ad:/#
(2)写入部分数据到容器中
root@5cd50eecf8ad:/# cd tmp
root@5cd50eecf8ad:/tmp# ls -l
total 0
root@5cd50eecf8ad:/tmp# echo "devops" > newfile
root@5cd50eecf8ad:/tmp# ls -l
total 4
-rw-r--r-- 1 root root 7 Jun 8 13:22 newfile
root@5cd50eecf8ad:/tmp# cat newfile
devops
(3)ctrl+P+Q:容器不停止退出
(4)停止容器
$ docker ps
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cd50eecf8ad ubuntu "/bin/bash" About a minute ago Up About a minute percy
$ docker container stop percy
percy
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
(5)查看所有容器,包括处于停止状态的容器
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cd50eecf8ad ubuntu "/bin/bash" 5 minutes ago Exited (137) About a minute ago percy
- ·
docker container ls
只能查看处于状态状态的容器,但是percy已经停止了 - 因此加上
-a
选项,就会显示出全部的容器,包括处于停止状态的容器,从上面可以看出percy已经处于Exited
了 - 这个时候虽然已经停止运行,但是容器的全部配置和内容仍然保存在docker主机的文件系统中,并且随时可以重启
(6)重启容器
$ docker container start percy
percy
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cd50eecf8ad ubuntu "/bin/bash" 10 minutes ago Up 14 seconds percy
(8)确认之前的文件是否还在
使用docker container exec命令连接到重启后的容器
$ docker container exec -it percy bash
root@5cd50eecf8ad:/# cd tmp/
root@5cd50eecf8ad:/tmp# ls -l
total 4
-rw-r--r-- 1 root root 7 Jun 8 13:22 newfile
文件还在!也就是说,停止容器运行并不会损坏容器或者其中的数据。
(9)停止并删除容器
$ docker container stop percy
percy
$ docker container rm percy
percy
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
小结:
- 可以根据需要多次停止、启动、暂停、重启容器,并且这些操作执行得很快
- 但是容器以及其数据是安全的,直到明确删除容器前,容器都不会丢弃其中的数据。
- 就算容器被删除了,如果将容器数据存储到卷中,数据也会保存下来