容器管理
容器概述
- 镜像相当于虚拟机的模板,而容器就相当于虚拟机本身
容器启用流程
- 当执行
docker run等命令启动容器后,会检查本地是否有相应的镜像;- 如果有则会直接启动容器
- 如果没有则会去远程镜像仓库中搜寻并下载镜像到本地而后启动容器
- 如果远程镜像仓库中也没有镜像则启动容器失败。
—
容器管理相关命令:
Usage: docker container COMMAND
Manage containers
Commands:
attach Attach local standard input, output, and error streams to a running container
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
exec Run a command in a running container
export Export a container's filesystem as a tar archive
inspect Display detailed information on one or more containers
kill Kill one or more running containers
logs Fetch the logs of a container
ls List containers
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
prune Remove all stopped containers
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
run Run a command in a new container
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
wait Block until one or more containers stop, then print their exit codes
Run 'docker container COMMAND --help' for more information on a command.启动容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# OPTIONS:
-i # interactive,进入交互模式
-t # tty,分配一个伪TTY
-d # detach,后台运行,默认前台
-e # 设置环境变量
-h # 设置容器内的主机名
--rm # 退出容器后立刻删除(通常用于测试,以避免产生大量exit状态的容器)
--privileged # 以宿主机root的身份运行容器
--restart string # 指定容器的重启策略。重启策略控制 Docker 守护进程是否在退出后重启容器。string可以为以下值:
# no #容器退出时不要自动重启。这是默认设置
# on-failure[:max-retries] #仅当容器以非零退出状态退出时才重新启动。(可选)限制 Docker 守护程序尝试重新启动的次数。
# unless-stopped #除非明确停止或 Docker 本身停止或重新启动,否则重新启动容器。
# always #无论退出状态如何,始终重新启动容器。当您指定 always 时,Docker 守护程序将尝试无限期地重新启动容器。无论容器的当前状态如何,容器也将始终在守护程序启动时启动。注意事项
- 容器启动后,如果容器内没有前台运行的进程将自动停止容器
范例
-
启动容器
-
本地没有镜像的话会去网络中下载并保存到本机
# docker run hello-world-
指定容器名称启动容器
-
注意每个容器的名称要唯一
# docker run --name nginx01 nginx:1.23- 指定ip启动容器
# docker run -it --name nginx01 --ip 172.18.0.66 nginx:1.23 sh- 启动容器后进入容器
# docker run -it busybox-
一次性运行容器中的命令
-
通常用于测试,启动的容器在执行完shell命令就退出(但会残留启动记录)
# docker run busybox echo "hello"
hello-
一次性运行容器测试
-
通常用于测试
# docker run --rm -it centos bash-
设置容器开机启动运行容器
-
默认容器在宿主机重启后不会自动启动
# 容器启动时定义,--restart=always表示宿主机重启后自动启动容器
# docker run -d --name nginx --restart=always -p 80:80 nginx
# 容器启动后定义
# docker update --restart always 容器ID-
以宿主机root的身份运行容器
-
危险慎用!正常运行容器是没有宿主机root权限的
-
–privileged 表示以宿主机root的身份运行容器
# 正常运行容器因为没有宿主机的root权限所以提示权限被拒绝
# docker run -it centos bash
[root@33721cde4bff /]# mount /dev/sda /opt/
mount: /opt: permission denied.
# 加上--privileged选项启动后可以实现以宿主机的root身份运行
# docker run -it --privileged centos bash
[root@dd82dffb97de /]# mount /dev/sda /opt/
mount: /opt: /dev/sda already mounted or mount point busy.容器的启动和停止
docker < start | stop | restart | pause |unpause > 容器ID范例
# 批量正常启动所有容器
# docker start $(docker ps -aq)
# 批量正常关闭所有容器
# docker stop $(docker ps -aq)
# 启动并进入容器
# docker start -i nginx01
# 启动容器运行
# docker start nginx01
# 停止容器运行
# docker stop nginx01
# 暂停容器(暂停后的容器进程会处于D状态)
# docker pause nginx01
# 取消暂停
# docker unpause nginx01退出容器
exit从容器内退出,并停止容器CTRL+p+q从容器内退出,且容器不停止
列出容器
# docker ps --help
Usage: docker ps [OPTIONS]
List containers
Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display container IDs
-s, --size Display total file sizes范例
# 列出运行的容器
# docker ps
# 列出全部容器,包括退出状态的容器
# docker ps -a
# 只列出容器ID
# docker ps -aq
# 列出容器大小
# docker ps -as
# 列出最新创建的容器(停止的容器也能显示)
# docker ps -l
# 列出指定状态的容器
docker ps -f 'status=exited' 查看容器内的进程
# docker top --help
Usage: docker top CONTAINER [ps OPTIONS]
Display the running processes of a container范例
[root@docker ~]# docker run -it alpine
/ # sleep 999
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d3ac3e62b79 alpine "/bin/sh" 17 seconds ago Up 15 seconds frosty_merkle
[root@docker ~]# docker top 1d3ac
UID PID PPID C STIME TTY TIME CMD
root 11451 11433 0 02:11 pts/0 00:00:00 /bin/sh
root 11481 11451 0 02:11 pts/0 00:00:00 sleep 999查看容器资源使用情况
# docker stats --help
Usage: docker stats [OPTIONS] [CONTAINER...]
Display a live stream of container(s) resource usage statistics
Options:
-a, --all Show all containers (default shows just running)
--format string Pretty-print images using a Go template
--no-stream Disable streaming stats and only pull the first result
--no-trunc Do not truncate output范例
# 查看单一容器
# docker stats 容器ID或名称
# 查看全部容器
# docker stats -a查看容器的详细信息
- docker inspect 可以查看 docker 各种对象的详细信息,包括:镜像、容器、网络等
# docker inspect --help
Usage: docker inspect [OPTIONS] NAME|ID [NAME|ID...]
Return low-level information on Docker objects
Options:
-f, --format string Format the output using the given Go template
-s, --size Display total file sizes if the type is container
--type string Return JSON for specified type# 根据容器ID查看
# docker inspect 8f0e1ccddd5a
# 也可以选择性查看
# docker inspect -f "{{.Created}}" 8f0e1ccddd5a
2021-09-30T10:10:41.25926759Z
# 获取容器的IP
# docker inspect -f "{{.NetworkSettings.IPAddress}}" 3f2f791de572给运行中的容器发信号
- 强制关闭容器,极端情况下使用,如:stop停不了,相当于给容器发一个9信号
Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]
Kill one or more running containers
Options:
-s, --signal string Signal to send to the container (default "KILL")范例:
# 强制关闭容器
# docker kill httpd
# 强制关闭所有容器
# docker kill `docker ps -a -q`进入正在运行的容器
使用 exec 命令
- 生产中常用
# exit退出后还可以继续运行
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c280a5924d15 centos "bash" 10 seconds ago Up 8 seconds gifted_wing
# docker exec -it c280a5924d15 bash
[root@c280a5924d15 /]# exit
exit
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c280a5924d15 centos "bash" 33 seconds ago Up 32 seconds gifted_wing
---
# 不进入容器临时执行命令
[root@docker ~]# docker exec a1 cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.15.0
PRETTY_NAME="Alpine Linux v3.15"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
---
# 进入运行的容器(进入容器需要指定shell接口,例如bash、sh等)
# docker exec -it nginx01 bash
root@b8c93de0eb8e:/# 使用 attach 命令
- attach 类似于 VNC,操作会在同一容器的多个会话界面同步显示,所有使用此方式进入容器的操作都是同步显示的,且使用exit退出后容器会自动关闭。
- 不推荐使用
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
13f2cef7f143 centos "bash" 25 minutes ago Up 24 minutes eager_neumann
# docker attach 13f2cef7f143
[root@13f2cef7f143 /]# 使用 nsenter 命令
容器端口管理
查看容器端口
Usage: docker port CONTAINER [PRIVATE_PORT[/PROTO]]
List port mappings or a specific mapping for the container-P 随机端口映射
- 将容器中的私有地址通过DNAT绑定到宿主机的端口上来实现远程访问
- -P 随机派发的端口范围为 49000 ~ 49900?
# 容器内部的端口默认从外部无法访问
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8c93de0eb8e nginx:1.23 "/docker-entrypoint.…" 41 minutes ago Up 41 minutes 80/tcp nginx01
# 映射随机端口到容器,可以看到已经映射到本机的49153端口
# docker run -Pd --name nginx02 nginx:1.23
c06593bb1aa8ae26ad86aa5a6d148965ceb4558da730032ccdaa8efe39a125ac
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3cee0b3d19b7 nginx:1.23 "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:49153->80/tcp, :::49153->80/tcp nginx02
# 查看端口映射
# docker port nginx02
80/tcp -> 0.0.0.0:49153
80/tcp -> :::49153
# 访问测试
# curl -I 127.0.0.1:49153
HTTP/1.1 200 OK
...-p 指定端口映射
多个容器映射到宿主机的端口不能冲突,但容器内使用的端口可以相同
- 方法1:容器80端口映射本地随机端口
# docker run -d -p 80 --name nginx01 nginx:1.23
# docker port nginx01
80/tcp -> 0.0.0.0:49154
80/tcp -> :::49154- 方法2:容器80端口映射到本地81端口
- 常用
# -p 本地端口:容器内端口
# docker run -d -p 81:80 --name nginx01 nginx:1.23
# docker port nginx01
80/tcp -> 0.0.0.0:81
80/tcp -> :::81- 方法3:本地IP:本地端口:容器端口
# docker run -d -p 10.0.0.103:81:80 --name nginx01 nginx:1.23
# docker port nginx01
80/tcp -> 10.0.0.103:81- 方法4:本地IP:本地随机端口:容器端口
# docker run -d -p 10.0.0.103::80 --name nginx01 nginx:1.23
# docker port nginx01
80/tcp -> 10.0.0.103:49153- 方法5:本机ip:本地端口:容器端口/协议,默认为tcp协议
# docker run -d -p 10.0.0.103:81:80/udp --name nginx01 nginx:1.23
# docker port nginx01
80/udp -> 10.0.0.103:81- 方法6:一次性映射多个端口+协议
# docker run -d -p 8080/tcp -p 8443:443/tcp -P --name nginx01 nginx:1.23
# docker port nginx01
8080/tcp -> 0.0.0.0:49155
8080/tcp -> :::49155
443/tcp -> 0.0.0.0:8443
443/tcp -> :::8443
80/tcp -> 0.0.0.0:49156
80/tcp -> :::49156动态修改已创建的容器的端口映射关系
root@ubuntu:~# docker run -d -p 80:80 --name nginx0 nginx
3081387a26687c00ae18042ba3a483707d280838a92165a1806f942982bcfdf5
root@ubuntu:~# docker port nginx0
80/tcp -> 0.0.0.0:80
80/tcp -> :::80
#修改方法
#先关闭docker服务
root@ubuntu:~# systemctl stop docker
#找到容器相关配置文件
root@ubuntu:/home/azheng# grep -R "HostPort" /var/lib/
/var/lib/docker/containers/3081387a26687c00ae18042ba3a483707d280838a92165a1806f942982bcfdf5/hostconfig.json:{"Binds":null,"ContainerIDFile":"","LogConfig":{"Type":"json-file","Config":{}},"NetworkMode":"default","PortBindings":{"80/tcp":[{"HostIp":"","HostPort":"80"}]},
#修改此配置文件
root@ubuntu:~# vim /var/lib/docker/containers/3081387a26687c00ae18042ba3a483707d280838a92165a1806f942982bcfdf5/hostconfig.json
#假设把80端口改为8080
root@ubuntu:~# cat /var/lib/docker/containers/3081387a26687c00ae18042ba3a483707d280838a92165a1806f942982bcfdf5/hostconfig.json
{"Binds":null,"ContainerIDFile":"","LogConfig":{"Type":"json-file","Config":{}},"NetworkMode":"default","PortBindings":{"80/tcp":[{"HostIp":"","HostPort":"8080"}]}
#启动服务再查看
root@ubuntu:~# docker start nginx0
nginx0
root@ubuntu:~# docker port nginx0
80/tcp -> 0.0.0.0:8080
80/tcp -> :::8080查看容器日志
Usage: docker logs [OPTIONS] CONTAINER
Fetch the logs of a container
Options:
--details Show extra details provided to logs
-f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for
42 minutes)
-n, --tail string Number of lines to show from the end of the logs (default "all")
-t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m
for 42 minutes)容器持久化运行
- 容器内PID为1的进程要以前台方式运行,否则启动则关闭
两种持久化运行方式:
- 使用具有前台运行程序的镜像,如:nginx、redis等
- 启动容器时指定一个前台运行的进程:如:tail -f /etc/hosts
- 注意:不要跟踪持续变化的文件,例如:日志文件等。以避免产生不必要的磁盘IO
范例
# 因为没有前台运行的进程,所以启动则退出
# docker run -d alpine
...
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2fff30e34dd0 alpine " " 7 seconds ago Exited (0) 5 seconds ago eager_cori
---
# 指定前台运行的进程,则运行不会退出
# docker run -d alpine tail -f /etc/hosts
...
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6434c04193a0 alpine "tail -f /etc/hosts" 3 seconds ago Up 1 second reverent_curie容器 host 文件管理
- 默认容器会将 container ID 作为主机名,并container IP 和 ID自动生成解析记录
# docker run --rm -it alpine:3.17.0 sh
/ # hostname
750da0c5accb
/ # 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.2 750da0c5accb # 自动生成的解析记录
# 容器ID与主机名一致
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
750da0c5accb alpine:3.17.0 "sh" 43 seconds ago Up 42 seconds awesome_nightingale- 指定容器名称和主机名并启动容器(容器会自动生成域名和IP对应的解析记录)
# docker run --rm -it -h a1.xiangzheng.com alpine:3.17.0 sh
/ # hostname
a1.xiangzheng.com #指定的主机名
/ # 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.2 a1.xiangzheng.com a1 #指定的解析记录
---
# 修改host文件
# docker run --rm -it --name a1 -h alpine --add-host a1.xiangzheng.vip:6.6.6.6 alpine sh
/ # hostname
alpine # 主机名
/ # 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
6.6.6.6 a1.xiangzheng.vip # 修改的host文件
172.17.0.4 alpine # 解析记录容器 DNS 管理
默认策略
- 容器中的DNS服务器,默认采用宿主机的DNS
# cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 10.0.0.2
# docker run --rm -it alpine:3.17.0 cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 10.0.0.2修改默认策略
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://jqm0rnhf.mirror.aliyuncs.com"],
"dns": ["114.114.114.114","223.5.5.5"],
"dns-search": ["azheng.vip","azheng.com"]
}
# systemctl restart docker.service
# docker run --rm -it alpine cat /etc/resolv.conf
search azheng.vip azheng.com
nameserver 114.114.114.114
nameserver 223.5.5.5容器启动时指定DNS
# 指定DNS服务器
# docker run --rm -it --dns 6.6.6.6 alpine:3.17.0 cat /etc/resolv.conf
search localdomain
nameserver 6.6.6.6
# 指定DNS服务器,以及指定domain
# docker run --rm -it --dns 6.6.6.6 --dns-search xiangzheng.vip --dns-search xiangzheng.com alpine:3.17.0 cat /etc/resolv.conf
search xiangzheng.vip xiangzheng.com
nameserver 6.6.6.6容器内和宿主机之间复制文件
# 将容器内的数据拷贝到宿主机
docker cp [选项] 容器:容器内的路径 宿主机路径
# 将宿主机的数据拷贝到容器
docker cp [选项] 宿主机路径 容器:容器内的路径
# 选项:
-a # 保留属性
-L # 复制软连接范例
- 将容器内的数据拷贝到宿主机
# docker run -d --name a1 alpine tail -f /etc/hosts
# docker cp a1:/etc/os-release /data/
# cat /data/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.15.0
PRETTY_NAME="Alpine Linux v3.15"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"- 将宿主机的数据拷贝到容器
# docker run -d --name a1 alpine tail -f /etc/hosts
# docker cp /etc/centos-release a1:/
# docker exec a1 cat /centos-release
CentOS Linux release 8.3.2011向容器传递环境变量
命令行指定
范例一
# docker run -d --name alpine -e AAA=BBB -e CCC=DDD alpine:3.17.0 tail -f /etc/hosts
07fcc3f05cf222627452668bbbe83322168b3ac7ce79fbf8343881277d739598
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
07fcc3f05cf2 alpine:3.17.0 "tail -f /etc/hosts" 2 seconds ago Up 2 seconds alpine
# docker exec alpine env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=07fcc3f05cf2
AAA=BBB
CCC=DDD
HOME=/root范例二
# 运行mysql,通过环境变量指定密码、创建数据库、账号
# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=12345 -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpuser -p 3306:3306 mysql:8.0.31
# 传入的环境变量
# docker exec mysql env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=f2708726a437
MYSQL_ROOT_PASSWORD=12345
MYSQL_DATABASE=wordpress
MYSQL_USER=wpuser
GOSU_VERSION=1.14
MYSQL_MAJOR=8.0
MYSQL_VERSION=8.0.31-1.el8
MYSQL_SHELL_VERSION=8.0.31-1.el8
HOME=/root
# 测试
# mysql -h127.0.0.1 -uroot -p12345
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wordpress | # 通过环境变量生成的库
+--------------------+通过文件指定
- 也可以通过写文件的方式来实现,文件名随意
# 定义环境变量文件
# vim env.list
MYSQL_ROOT_PASSWORD=xiangzheng
MYSQL_DATABASE=testdatabase
MYSQL_USER=xiang
MYSQL_PASSWORD=password
# 运行时指定环境变量文件
# docker run -d --name mysql --env-file=env.list -p 3306:3306 mysql:8.0.31
# 传入的环境变量
# docker exec mysql env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=3ed35b5ae869
MYSQL_ROOT_PASSWORD=xiangzheng
MYSQL_DATABASE=testdatabase
MYSQL_USER=xiang
MYSQL_PASSWORD=password
GOSU_VERSION=1.14
MYSQL_MAJOR=8.0
MYSQL_VERSION=8.0.31-1.el8
MYSQL_SHELL_VERSION=8.0.31-1.el8
HOME=/root
# 测试
# mysql -h127.0.0.1 -P3306 -uroot -pxiangzheng
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdatabase |
+--------------------+
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| root | % |
| xiang | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+容器重命名
-
语法:
-
Usage: docker rename CONTAINER NEW_NAME Rename a container -
范例:
-
[root@docker tomcat-app1]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1c3a716a5a68 tomcat-app1:v1.0 "tail -f /etc/hosts" 11 minutes ago Up 10 minutes 8080/tcp eager_grothendieck [root@docker tomcat-app1]# docker rename eager_grothendieck tomcat-app1 [root@docker tomcat-app1]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1c3a716a5a68 tomcat-app1:v1.0 "tail -f /etc/hosts" 11 minutes ago Up 11 minutes 8080/tcp tomcat-app1
删除容器
# docker rm --help
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]
Remove one or more containers
Options:
-f, --force Force the removal of a running container (uses SIGKILL)
-l, --link Remove the specified link
-v, --volumes Remove anonymous volumes associated with the container范例
# 删除容器
# docker rm -f
# 删除容器,包括数据卷
# docker rm -fv
# 删除全部容器
# docker rm -f `docker ps -qa`
或
# docker ps -aq | xargs docker rm
# 删除全部停止状态的容器
# docker rm -f `docker ps -qaf status=exited`重定向脚本输出到容器的标准输出
echo [$(date)] 'Hello' > /proc/1/fd/1
- 这个命令的作用是输出带有当前日期时间的Hello字符串,并将结果重定向到容器的标准输出。具体而言,"/proc/1/fd/1"表示容器中进程ID为1的标准输出文件描述符,">“符号用于重定向输出,将输出写入到容器的标准输出中。
- 这个命令可以用于在容器中运行的脚本或命令中,将输出打印到容器的标准输出中,以便在容器日志中查看。需要注意的是,如果在宿主机上执行该命令,则将在宿主机的标准输出中看到结果,而不是容器中的标准输出。