【Docker教程】进入docker容器的外壳
(一)
1.了解Docker映像和容器之间的区别
Docker是用于轻松创建,部署和运行应用程序的工具。它允许我们使用所有依赖关系打包应用程序,并将它们作为单独的分发包分发。Docker保证我们的应用程序将在每个Docker实例上以相同的方式运行。
当我们开始使用Docker时,我们需要明确两个主要概念 - 图像和容器。
我们将了解它们是什么以及它们之间的区别。
2. Docker镜像
映像是代表打包的应用程序的文件,具有正确运行所需的所有依赖项。换句话说,我们可以说Docker映像就像Java类。
图像构建为一系列图层。层被组装在一起。那么,什么是层?简而言之,层就是图像。
假设我们要创建一个Hello World Java应用程序的Docker映像。我们需要考虑的第一件事是我们的应用程序需要什么。
首先,它是一个Java应用程序,因此我们需要一个JVM。好的,这似乎很简单,但是JVM需要运行什么?它需要一个操作系统。因此,我们的Docker映像将具有一个操作系统层,一个JVM和我们的Hello World应用程序。
Docker的主要优势在于其庞大的社区。如果要构建映像,可以转到Docker Hub并搜索所需的映像是否可用。
假设我们要使用PostgreSQL数据库创建一个数据库。我们不需要从头开始创建新的PostgreSQL映像。我们只是去Docker Hub,搜索postgres,这是PostgresSQL的Docker官方映像名称,选择我们需要的版本,然后运行它。
我们从Docker Hub创建或提取的每个映像都存储在我们的文件系统中,并通过其名称和标记进行标识。也可以通过其图像ID进行标识。
使用docker images命令,我们可以查看文件系统中可用的映像列表:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
postgres 11.6 d3d96b1e5d48 4 weeks ago 332MB
mongo latest 9979235fc504 6 weeks ago 364MB
rabbitmq 3-management 44c4867e4a8b 8 weeks ago 180MB
mysql 8.0.18 d435eee2caa5 2 months ago 456MB
jboss/wildfly 18.0.1.Final bfc71fe5d7d1 2 months ago 757MB
flyway/flyway 6.0.8 0c11020ffd69 3 months ago 247MB
java 8-jre e44d62cf8862 3 years ago 311MB
3.运行Docker映像
使用带有映像名称和标签的docker run命令运行映像。假设我们要运行postgres 11.6图像:
docker run -d postgres:11.6
注意,我们提供了-d选项。这告诉Docker在后台运行映像-也称为分离模式。
使用docker ps命令,我们可以检查映像是否正在运行,我们应该使用以下命令:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3376143f0991 postgres:11.6 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 5432/tcp tender_heyrovsky
请注意上面输出中的容器ID。让我们看一下什么是容器以及它与图像的关系。
4. Docker容器
容器是图像的实例。每个容器都可以通过其ID进行标识。回到我们的Java开发类比,我们可以说容器就像类的实例。
Docker为容器定义了七个状态:创建,重新启动,运行,移除,暂停,退出和已死。这一点很重要。由于容器只是图像的一个实例,因此它不需要运行。
现在,让我们再次考虑上面已经看到的run命令。我们已经说过,它是用来运行图像的,但这并不完全准确。事实是,运行命令用于创建 和启动 图像的新容器。
一大优势是容器就像轻量级的VM。他们的行为是完全相互隔离的。这意味着我们可以运行同一图像的多个容器,使每个容器处于不同的状态,并具有不同的数据和不同的ID。
能够同时运行同一图像的多个容器是一个很大的优势,因为它使我们能够轻松地扩展应用程序。例如,让我们考虑微服务。如果将每个服务打包为Docker映像,则意味着可以根据需要将新服务部署为容器。
5.容器生命周期
之前,我们提到了容器的七个状态,现在,让我们看看如何使用docker命令行工具来处理不同的生命周期状态。
启动新容器需要我们先创建它,然后再启动它。这意味着它必须先经过创建状态,然后才能运行。我们可以通过显式创建和启动容器来做到这一点:
docker container create <image_name>:<tag>
docker container start <container_id>
或者我们可以使用run命令轻松地做到这一点:
docker run <image_name>:<tag>
我们可以暂停一个正在运行的容器,然后再次将其置于运行状态:
docker pause <container_id>
docker unpause <container_id>
当我们检查进程时,已暂停的容器将显示“已暂停”作为状态:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9bef2edcad7b postgres:11.6 "docker-entrypoint.s…" 5 minutes ago Up 4 minutes (Paused) 5432/tcp tender_heyrovsky
我们还可以停止正在运行的容器,然后重新运行它:
docker stop <container_id>
docker start <container_id>
最后,我们可以删除一个容器:
docker container rm <container_id>
只能删除处于停止或创建状态的容器。
(二)如何进入Docker容器的外壳
1.概述
我们知道Docker是一个易于创建,部署和运行应用程序的强大工具。
那么,可以连接到容器的操作系统吗?答案是:是的,现在我们将学习如何做。
2.连接到现有容器
如果要连接到现有容器,则应该使任何容器处于运行状态。为此,我们必须使用docker ps命令检查系统中的容器状态:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4b9d83040f4a hello-world "/hello" 8 days ago Exited (0) 8 days ago dazzling_perlman
由于我们没有正在运行的容器,因此我们以启动RabbitMQ容器为例:
$ docker run -d rabbitmq:3
启动容器后,我们将从另一个对docker ps的调用中看到它:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7a9f5eb6b85 rabbitmq:3 "docker-entrypoint.s…" 25 minutes ago Up 25 minutes 4369/tcp, 5671-5672/tcp, 25672/tcp trusting_bose
现在连接到这个容器就像执行一样简单:
$ docker exec -it b7a9f5eb6b85 sh
至此,我们在容器内部有了一个交互式shell:
- docker exec告诉Docker我们要在正在运行的容器中执行命令
- 该-IT说法意味着它将在交互模式下执行-它使STIN开放
- b7a9f5eb6b85是容器ID
- sh是我们要执行的命令
让我们探索一下我们新创建的容器的操作系统:
$ cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL=``"[https://www.ubuntu.com/](https://www.ubuntu.com/)"
SUPPORT_URL=``"[https://help.ubuntu.com/](https://help.ubuntu.com/)"
BUG_REPORT_URL=``"[https://bugs.launchpad.net/ubuntu/](https://bugs.launchpad.net/ubuntu/)"
PRIVACY_POLICY_URL=``"[https://www.ubuntu.com/legal/terms-and-policies/privacy-policy](https://www.ubuntu.com/legal/terms-and-policies/privacy-policy)"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
它似乎是仿生海狸Ubuntu。如果检查RabbitMQ Dockerfile中的FROM指令,我们将意识到该映像是使用Ubuntu 18.04构建的。
我们可以使用exit命令或仅按CTRL + d与容器断开连接。
这个例子很简单,因为当我们启动RabbitMQ容器时,它一直运行直到停止它。另一方面,有时我们必须处理无法存活的容器,例如操作系统容器。
3.以交互模式运行容器
如果我们尝试启动一个新的操作系统容器,例如一个18.04 Ubuntu,我们将发现它并没有存活:
$ docker run ubuntu:18.04
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
08c26636709f ubuntu:18.04 "/bin/bash" 10 seconds ago Exited (0) 7 seconds ago heuristic_dubinsky
b7a9f5eb6b85 rabbitmq:3 "docker-entrypoint.s…" About an hour ago Up About an hour 4369/tcp, 5671-5672/tcp, 25672/tcp trusting_bose
RabbitMQ容器仍在运行时,Ubuntu容器已停止。因此,我们无法使用docker exec命令连接到此容器。
避免这种情况的一种方法是以交互方式运行此容器:
$ docker run -it ubuntu:18.04
因此,既然我们位于容器内,就可以检查外壳类型:
$ echo $0
/bin/bash
实际上,当我们以交互方式启动容器时,使用–rm参数很方便。退出时,请确保删除容器:
$ docker run -it --rm ubuntu:18.04
4.保持容器运行
有时,我们会遇到一些奇怪的情况,需要启动并连接到容器,但是交互模式不起作用。
如果我们遇到这些情况之一,可能是因为出了点问题,应予以纠正。
但是,如果需要快速解决方法,可以在容器中运行tail命令:
$ docker run -d ubuntu:18.04 tail -f /dev/null
使用此命令,我们将以分离/后台方式(-d)启动一个新容器,并在容器内执行tail -f / dev / null命令。结果,这将迫使我们的容器永远运行。
现在,我们只需要使用docker exec命令以以前看到的相同方式进行连接:
$ docker exec -it CONTAINER_ID sh
请记住,这是一种解决方法,应仅在开发环境中使用。
5.结论
在本教程中,我们已经看到了如何连接到正在运行的容器的外壳,以及如何以交互方式启动容器。
6.最后
欢迎大家讨论,喜欢的话可以关注收藏,以后会持续为大家更新优质内容。