容器管理
一、容器,镜像,进程的关系
1、容器与镜像的关系
- 容器是基于镜像创建的,一个镜像可以构建多个容器
2、容器与进程的关系
- 容器里面运行就是进程,进程结束后,这个容器的生命周期也就结束了
二、容器管理
1、docker run
1、tid选项
- 使用命令创建一个容器,不加参数的话,回车后容器就会退出
[root@docker ~]# docker run alpine
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1c16fc0b0dc2 alpine "/bin/sh" 3 seconds ago Exited (0) 2 seconds ago loving_tesla
- 因此的话需要加上一个伪终端,让这个创建的容器一直运行,这个时候就需要加上一个t的选项
[root@docker ~]# docker run -t alpine
/ # ^[[10;5R
# 无法与容器进行交互
- 但是了,上面又出现了一个问题,就是无法与这个容器进行交互,因此需要添加一个i的选项,就能进行交互了,进入到容器里面
[root@docker ~]# docker run -ti alpine
/ # ls
bin etc lib mnt proc run srv tmp var
dev home media opt root sbin sys usr
/ # exit
# 退出,容器自动退出
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b1cc4d4024b4 alpine "/bin/sh" 18 seconds ago Exited (0) 2 seconds ago jolly_edison
- 但是了,如果退出了这个容器,这个容器就自动退出了,需要一个d的选项,放在后台的运行的参数,不自动进入容器
[root@docker ~]# docker run -tid alpine
607430bb4f67eea8ec890ce6f7d3f86bab5489b905c0e619164492bf374fab4b
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
607430bb4f67 alpine "/bin/sh" 3 seconds ago Up 2 seconds competent_hugle
2、restart选项
- always选项
# attach进入容器后,容器会自动关闭,但是有always,容器会自动的启动
[root@docker ~]# docker run -tid --name a1 --restart always alpine
a49f7bd39ce58dec40db752bf73bffc46af80005cb0dff9d4f599b642ebf0757
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a49f7bd39ce5 alpine "/bin/sh" 2 seconds ago Up 1 second a1
[root@docker ~]# docker attach a1
/ # exit
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a49f7bd39ce5 alpine "/bin/sh" 18 seconds ago Up Less than a second a1
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a49f7bd39ce5 alpine "/bin/sh" 23 seconds ago Up 6 seconds a1
# 关闭容器,容器会自动重启
2、name选项
# 给容器起名字
3、进入容器
- attach进入容器,退出时,容器也就退出了
[root@docker ~]# docker attach a2
/ # exit
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d0170a27f89 alpine "/bin/sh" 2 minutes ago Exited (0) 1 second ago a2
17f5401805f2 alpine "/bin/sh" 3 minutes ago Exited (0) 3 minutes ago a1
- exec进入容器,退出后,容器不会关闭。加上选项-ti
[root@docker ~]# docker exec -ti a2 /bin/sh
/ # exit
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d0170a27f89 alpine "/bin/sh" 4 minutes ago Up 14 seconds a2
17f5401805f2 alpine "/bin/sh" 5 minutes ago Exited (0) 5 minutes ago a1
[root@docker ~]# docker exec --help
# 命令选项,要加上命令
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Execute a command in a running container
Aliases:
docker container exec, docker exec
Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a container
-e, --env list Set environment variables
--env-file list Read in a file of environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: "<name|uid>[:<group|gid>]")
-w, --workdir string Working directory inside the container
4、指定容器生命周期(启动容器的时候,指定命令)
# 休眠30秒,自动退出
[root@docker ~]# docker run -tid --name a2 alpine sleep 30
0195bac442a7ff8f74404d85949ff23673914a14624d536c99f32bb596008344
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0195bac442a7 alpine "sleep 30" 44 seconds ago Exited (0) 12 seconds ago a2
a49f7bd39ce5 alpine "/bin/sh" 4 minutes ago Up 4 minutes a1
5、--rm选项
-
测试容器,容器退出的时候,自动删除该容器
-
但是了,必须使用attach进入容器后,退出容器,会自动删除容器,不能使用exec
[root@docker ~]# docker run -tid --name a1 --rm alpine
c6cf4873f5e3c0c9c0f68fb3856c65e15fd606fa6558729538635f7140c8177f
do[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6cf4873f5e3 alpine "/bin/sh" 3 seconds ago Up 1 second a1
[root@docker ~]# docker attach a1
/ # exit
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]#
- 当然,创建容器时,不加上-d的话,退出容器时,会自动删除容器
6、指定容器的环境变量
-
创建mysql容器时,需要传入一些环境变量
-
e容器,指定环境变量即可
[root@docker ~]# docker run -tid --name a1 -e name=h1 --restart always alpine
59d0bed118590af97642d45f517f8488ac96c4e497830b1c4d3929ee434945b2
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
59d0bed11859 alpine "/bin/sh" 2 seconds ago Up 1 second a1
[root@docker ~]# docker exec -ti a1 /bin/sh
/ # env
HOSTNAME=59d0bed11859
SHLVL=1
HOME=/root
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
name=h1
PWD=/
/ # echo $name
h1
/ #
7、暴露端口-p选项
- nginx容器内部暴露80端口,外面想要访问的页面的话,可以将宿主机的端口映射到容器上面,这样访问宿主机的ip加宿主机的端口就能访问到容器上了
# -p 宿主机端口:容器端口
[root@docker ~]# docker run -tid --name web --restart always -p 8080:80 nginx
8、-q只显示容器id
[root@docker ~]# docker ps -qa
a66f4f6cf246
2、容器其他操作
1、删除所有容器
[root@docker ~]# docker rm -f $(docker ps -qa)
82010b19bfa2
2、容器启动,重启,停止
docker restart 容器
docker stop 容器
3、查看容器的详细信息
[root@docker ~]# docker inspect web
4、查看容器日志信息
docker logs 容器名
5、docker cp命令
- 将虚拟机的文件拷贝到容器里面去
[root@docker ~]# docker cp /etc/hosts web:/tmp
Successfully copied 2.05kB to web:/tmp
[root@docker ~]# docker exec -ti web ls /tmp
hosts
6、commit操作
- 就是将正在运行的容器打成一个镜像
[root@docker ~]# docker run -tid --name n1 nginx
0939a43969d4815f11c14e1fa030813591f42d5bf014f3b9adba74bf24058350
[root@docker ~]# echo 123 > index.html
[root@docker ~]# docker cp ./index.html n1:/usr/share/nginx/html/index.html
Successfully copied 2.05kB to n1:/usr/share/nginx/html/index.html
# 将这个容器做成一个镜像
[root@docker ~]# docker commit n1 nginx:v1
sha256:d67643cd8922dcf05615e64dee6ea654d695fa176ede0d0450f232b802ac0cde
# 基于这个新镜像创建一个容器
[root@docker ~]# docker run -tid --name n2 -P nginx:v1
57cec2a8a2292be4775fffede773e06dc9f50299fc894076530b8eb1c0f8db42
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57cec2a8a229 nginx:v1 "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 0.0.0.0:32769->80/tcp, :::32769->80/tcp n2
0939a43969d4 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp
# 访问页面 n1
[root@docker ~]# curl localhost:32769
123
10、save和load
- 主要用于离线导入,将一个镜像save成一个tar.gz包,然后load导入进去即可
[root@docker ~]# docker save -o nginx.tar.gz nginx:latest
[root@docker ~]# docker load -i nginx.tar.gz
Loaded image: nginx:latest
11、export和import
-
一个基础镜像,再次基础上进行了修改然后export成一个tar包,然后import将其变成一个新的镜像
-
基于这个新的镜像run一个新的容器
-
但是的话,这个之前镜像层的信息就不会被保留,就只保留新增的操作,这样的话,不是很好,之前的信息就会丢失
[root@docker ~]# docker export n1 > n1.tar
[root@docker ~]# docker import n1.tar nginx:v1
sha256:2e5c2bdcaea5d994d51c970e4ff18d20aff312545dd8ba9e84eb6285c19e2d32
# 镜像层信息
[root@docker ~]# docker history nginx:v1
IMAGE CREATED CREATED BY SIZE COMMENT
2e5c2bdcaea5 47 minutes ago 186MB Imported from -
3、小实验
- 创建一个mysql容器
[root@docker ~]# docker run -tid --name db --restart always mysql
# 发现这个容器一直在重启
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b215e5e2b00 mysql "docker-entrypoint.s…" 2 minutes ago Restarting (1) 2 seconds ago db
a66f4f6cf246 nginx "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp web
# 查看日志发现,需要指定环境变量才能启动
[root@docker ~]# docker logs db
2025-05-27 11:38:31+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of the following as an environment variable:
- MYSQL_ROOT_PASSWORD
- MYSQL_ALLOW_EMPTY_PASSWORD
- MYSQL_RANDOM_ROOT_PASSWORD
- 重新创建一个mysql容器,指定环境变量
[root@docker ~]# docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=123 mysql
# 发现mysql正常运行
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bf320ccdff46 mysql "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp db
a66f4f6cf246 nginx "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp web
# 登录mysql
[root@docker ~]# mysql -uroot -p123 -h 172.17.0.3
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 9.3.0 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.004 sec)
- 如果想要第三方工具连接的话,就需要映射端口,这样外面访问宿主机的ip加宿主机映射的端口就能连接到容器的数据库服务了
docker run -tid --name db --restart always -e MYSQL_ROOT_PASSWORD=123 -e MYSQL_USER=qq -e MYSQL_PASSWORD=qq -e MYSQL_DATAVASE=ww -p 3306:3306 mysql
1、总结
-
虚拟机和容器都是在一个平台上面的,容器是运行在虚拟机上面的,因此虚拟机和容器都是可以互相访问的,但是宿主机(买的电脑)不能与容器互相访问,如果想要访问的话,可以使用虚拟机上面的端口映射到容器上面的端口
-
因此访问虚拟机的ip和端口就能访问到容器里面了
-
生产环境中,服务器是公网ip,在服务器里面搭建一个nginx容器,端口映射到容器里面,这样客户访问的时候公网ip+端口就能访问到这个容器了
-
那么这个容器自带的ip就是用于内网之间通信的,容器mysql和容器nginx,之间通过自己的内网ip进行通信
-
容器运行在虚拟机上面
# 除了/bin/bash之外,其他命令也可以,添加命令即可
docker exec -ti 容器名 命令
[root@docker ~]# docker exec -ti web ls /tmp
anaconda-ks.cfg
[root@docker ~]# docker exec -ti web rm -rf /tmp/anaconda-ks.cfg
[root@docker ~]# docker exec -ti web ls /tmp

浙公网安备 33010602011771号