Docker 基础知识
Docker基础命令

Docker基础命令

镜像

镜像(Image)是一个轻量级、独立的软件包,它包含了运行特定应用程序或服务所需的一切内容。简而言之,镜像是一种虚拟容器,可以在主机上被实例化和执行。 一个 Docker 镜像是通常包含以下内容:

  • 应用程序代码:你想要运行的实际软件或服务。
  • 依赖项:应用程序所需的任何库、框架或其他依赖关系。
  • 操作系统:一层轻量级的操作系统(例如 Linux),提供了应用程序的运行环境。

当一个 Docker 镜像被创建时,实际上是构建了一种自包含的软件包,包括了应用程序的一切内容。这个包装然后被存储在镜像仓库中,如 Docker Hub,那样它可以轻松地下载并在其他机器上运行。

Docker 镜像是设计为:

  • 可移植:它们可以在任何安装了 Docker 的机器上运行,不管底层操作系统是什么。
  • 可复制:你可以通过从同一个镜像创建新的容器来创建多个 identical 的副本。
  • 安全:镜像之间和主机之间都是隔离的,这减少了冲突或安全问题的风险。

Docker 镜像的类型:

  • 官方镜像:由 Docker 团队维护的镜像,广泛使用和支持。
  • 社区维护的镜像:由开发者和组织贡献的镜像,涵盖了许多应用程序和用例。
  • 私有镜像:用于特定用途或内部使用的自定义镜像。

镜像下载

用法:

$ docker pull --help

Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Pull an image or a repository from a registry

Options:
  -a, --all-tags                Download all tagged images in the repository
      --disable-content-trust   Skip image verification (default true)
      --platform string         Set platform if server is multi-platform capable
  -q, --quiet                   Suppress verbose output

docker pull 命令用于从 Docker Hub 或其他 registry 中下载指定的镜像。 下面我们将从Docker Hub中下载mysql 5.7.

docker pull mysql:5.7

镜像查看

下面两个命令是等价的,都可以查看本机所有的镜像清单。

docker images
docker image list

容器

容器(Container)是一个轻量级、独立的实例,它运行于一个已经安装了 Docker 的机器上,并且可以与主机进行交互。 容器是基于镜像(Image)的实例。镜像是一个包含了应用程序或服务所需的一切内容的包装,而容器则是一个将镜像运行起来的实例。 当你从一个镜像创建一个容器时,Docker 会:

  • 创建一个新的文件系统:容器会获得一个独立的文件系统,从而隔离与主机的文件系统。
  • 安装操作系统:容器会安装一个操作系统层(例如 Linux),提供了应用程序的运行环境。
  • 执行应用程序:容器会执行应用程序或服务,使用该应用程序的依赖关系和配置。

运行容器

用法:

sudo docker run --help

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

常用的Options:      
  -d, --detach                         Run container in background and print container ID      
  -e, --env list                       Set environment variables   
  -i, --interactive                    Keep STDIN open even if not attached
  -t, --tty                            Allocate a pseudo-TTY
sudo docker run -d  -e MYSQL_ROOT_PASSWORD=mysqlpwd --name mysql-container mysql:5.7

Docker run 命令用于创建并启动一个新的容器。以下是命令的详细解释:

  • docker run: 这个命令用于创建一个新的 Docker 容器从一个映像中。
  • -d: 这个标志 detached 模式,即将容器运行在背景(daemon 模式)下。这意味着您不会看到容器的任何输出,除非您显式地 attach 到容器中。
  • -e MYSQL_ROOT_PASSWORD=mysqlpwd: 使用环境变量来设置mysql的密码。
  • --name mysql-container: 这个标志给容器一个名称(mysql-container)。这对识别和管理容器很有用。您可以使用这个名称来停止、启动或删除容器。
  • mysql:latest: 这是一个映像名称和标签,指定要使用的 MySQL 映像。在这个例子中,我们使用最新版本的 MySQL 映像。

当你运行这个命令时,Docker 将:

  • 如果映像还没有下载, 下载MySQL 映像(从 Docker Hub 等注册表)。
  • 创建一个新的容器来自映像。
  • 在 detached 模式下运行容器(-d)。
  • 给容器起名为 mysql-container。

查看容器进程

sudo docker ps 

输入类似结果:

CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS          PORTS                 NAMES
78ac36d3e2c0   mysql:5.7     "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds    3306/tcp, 33060/tcp   mysql-container

如果看到名为mysql-container进程,代表容器启动成功了。

进入容器

用法:

sudo docker exec --help

Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

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

通常使用docker exec -ti 容器名称 bash或sh来进入容器内部

sudo docker exec -ti mysql-container bash

输出:

bash-4.2# 
``

看到bash提示符代表已经进入容器内部,我们可以再使用mysql命令连接一下数据库:
```exec
mysql -pmysqlpwd

输出:

mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.44 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

至此,已经成功能进入容器,并连接上了MySQL服务器,一切工作正常。按两次Ctrl + D回到Ubuntu命令行。

查看容器日志

用法:

$ docker logs --help
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)

容器日志(Container Logs)是 Docker container 的输出记录,这些记录包含了容器的运行信息、错误信息和其他重要数据。 在 Docker 中,容器日志可以通过以下命令来查看:

docker logs:显示容器的 stdout 和 stderr 输出

sudo docker logs mysql-container

输出:

2024-07-18 09:10:16+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.44-1.el7 started.
2024-07-18 09:10:17+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2024-07-18 09:10:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.44-1.el7 started.
2024-07-18 09:10:17+00:00 [Note] [Entrypoint]: Initializing database files
...
2024-07-18T09:10:29.683481Z 0 [Note] mysqld: ready for connections.
Version: '5.7.44'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
2024-07-18T09:17:24.613508Z 2 [Note] Access denied for user 'root'@'localhost' (using password: NO)

这将显示 MySQL 容器的输出记录,包括启动信息、错误信息和查询结果等。

-f 选项:使用 -f 选项可以跟踪容器的实时日志输出。

sudo docker logs -f mysql-container

这将显示 MySQL 容器的实时日志输出,包括任何新的输出记录。

--tail 选项:使用 --tail 选项可以查看容器的最后 N 条记录

sudo docker logs --tail=100 mysql-container

停止容器

用法:

$ docker stop --help

Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]

Stop one or more running containers

Options:
  -t, --time int   Seconds to wait for stop before killing it (default 10)

当你运行这个命令时,Docker 会:

  • 找到正在运行的 MySQL 容器名为 mysql-container。
  • 发送信号给容器,让它停止运行。
  • 等待容器完成任何 ongoing 任务并退出。

停止容器是有用的情况:

  • 你已经使用容器且想要释放系统资源。
  • 你需要重新启动容器,以更新配置或新数据。
  • 你想 troubleshoot 容器问题,并需要暂停其执行。
docker stop mysql-container

容器停止后,可以使用docker ps进行确认没有活跃的进程了。

docker ps

启动已停止的容器

当容器补创建后,容器就已经存在于系统中,可以通过docker ps -a查看到处于停止状态的容器,我们可以通过docker start 容器名称再次启动 容器。

docker start mysql-container

删除容器

用法:

$ 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

删除mysql-container):

docker rm mysql-container

常见问题

  1. Conatiner运行后,使用docker ps查不到相应的容器进程? 举个例子,运行一个ubuntu的容器:
docker run -d  --name my-ubuntu-container ubuntu

使用docker ps查看,发现并没有my-ubuntu-container的进程:

docker ps

再用docker ps -a查看所有容器进程:

docker ps -a

结果如下:

CONTAINER ID   IMAGE    COMMAND     CREATED          STATUS                     NAMES
9a84b94dae90   ubuntu   "/bin/bash" 19 seconds ago   Exited (0) 18 seconds ago  my-ubuntu-container

可以看到容器的状态为Exited (0),说明容器启动后又退出了。

问题原因:

  • 无命令:当你使用 run 命令时,Docker 会执行容器中的默认命令(通常是 /bin/sh 或 /bin/bash)。如果你不提供任何命令,容器将退出,因为它什么都不做。
  • 缺少守护进程: Ubuntu 镜像中没有包含一个守护进程来保持容器运行。因此,当容器启动后,它会自动退出。

解决方法:

  • 添加守护进程:可以使用 run 命令时添加 -t 选项,这将分配一个伪终端到容器中,使得你可以在容器中交互。例如:
docker run -d -t --name my-ubuntu-container ubuntu /bin/bash

这将启动一个交互式的 bash shellsession 在容器中。

  • 使用 tail -f:tail 是一个简单的命令,-f 选项告诉 tail 持续跟踪文件并显示新的内容。在 Ubuntu 容器中, tail -f 可以用于保持 shell 会话:
docker run -d --name my-ubuntu-container ubuntu tail -f

这将启动 tail -f 命令,并使得容器保持运行状态。类似的,也可用其它可持续执行的命令来保持容器的运行状态, 如:

docker run -d --name my-ubuntu-container ubuntu cat /dev/zero
docker run -d --name my-ubuntu-container ubuntu sleep 3600
  • 使用守护进程:通常情况下,在使用容器发布一个应用时,应用本身就是一个守护进程类型的应用,这个可以直接使用应用的名称作为容器运行命令。 如常见的nginx,apache,mysql,redis容器,运行这些容器时,我们不需要提定容器运行命令,使用镜像的默认配置就可以启动容器,并能保持容器一直处行状态。
  1. 启动Conatiner时,出现The container name "/my-ubuntu-container" is already in use by container?
docker: Error response from daemon: Conflict. The container name "/my-ubuntu-container" is already in use by container "29a901f267a7b83894b8c5bb82e92b5763a8b9a21744652c505aef9d454f3e9a". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

这是因为容器的名称不能重复,之前已经有相同的容器名称了,包含启动失败和启动后又退出的容器。 解决方法:

# 删除已经停止的容器
sudo docker rm my-ubuntu-container
 
# 强制删除还在运行的容器
sudo docker rm my-ubuntu-container -f

构建

构建镜像

搭建镜像仓库

上传镜像

更多镜像命令

镜像导出

镜像导入