转载

第4章 运行容器

运行容器

在Docker中运行任何应用程序的第一步是从一个镜像中运行一个容器。在官方的Docker registry (即 https://hub.docker.com [Docker Hub])中有大量可用的镜像。为了运行其中的任意一个镜像,你仅需要让Docker客户端运行它。客户端会检查镜像文件是否已经存在了Docker 主机上了。如果已经存在,那么就运行它,如果没有Docker主机就会下载镜像然后运行它。

拉镜像

让我们先检查一下是否有可用的镜像:

[source, text]

docker images

首先,列表中仅包含Docker swarm镜像,我们以前用过。

[source, text]

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

swarm latest 556c60f87888 33 hours ago 10.2 MB

现在,让我们获得一个普通的 jboss/wildfly 镜像:

[source, text]

#From Internet

docker pull jboss/wildfly:latest

From Instructor

docker pull classroom.example.com:5000/wildfly:latest

默认,从 https://hub.docker.com [Docker Hub]中检索镜像。在我们案例中,我们通过导师的笔记本提供一个所谓的私有registry。

可可用看到,Docker正在下载带有不同层的镜像。

[NOTE 注意]

In a traditional Linux boot, the Kernel first mounts the root File System as read-only, checks its integrity, and then switches the whole rootfs volume to read-write mode.

When Docker mounts the rootfs, it starts read-only, as in a traditional Linux boot, but then, instead of changing the file system to read-write mode, it takes advantage of a union mount to add a read-write file system over the read-only file system. In fact there may be multiple read-only file systems stacked on top of each other. Consider each one of these file systems as a layer.

At first, the top read-write layer has nothing in it, but any time a process creates a file, this happens in the top layer. And if something needs to update an existing file in a lower layer, then the file gets copied to the upper layer and changes go into the copy. The version of the file on the lower layer cannot be seen by the applications anymore, but it is there, unchanged.

We call the union of the read-write layer and all the read-only layers a _union file system_.

.Docker Layers

image::images/plain-wildfly0.png[]

In our particular case, the https://github.com/jboss-docke ... rfile [jboss/wildfly] image extends the https://github.com/jboss-docke ... rfile [jboss/base-jdk:8] image which adds the OpenJDK distribution on top of the https://github.com/jboss-docke ... rfile [jboss/base] image.

The base image is used for all JBoss community images. It provides a base layer that includes:在我们特定的情况下, https://github.com/jboss-docke ... rfile [jboss/wildfly]镜像扩展自 https://github.com/jboss-docke ... rfile [jboss/base-jdk:8] 镜像,这个镜像在 https://github.com/jboss-docke ... rfile [jboss/base]镜像基础上添加了OpenJDK分发版本。基础镜像用在所有的JBoss社区镜像中。它提供的基础层包括:

. 一个jboss用户 (uid/gid 1000),家目录是 /opt/jboss

. 一些软件,可能在扩展镜或者安装软件时有用,比如,unzip。

" jboss/base-jdk:8 "镜像添加了:

. OpenJDK 8分发

. 添加了一个 JAVA_HOME 环境变量

当下载完成后,你可以再一次列出镜像,将会看到下面:

[source, text]

docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

jboss/wildfly latest 7688aaf382ab 6 weeks ago 581.4 MB

swarm latest 207e8b983242 9 weeks ago 10.2 MB

### 运行容器

目前,我们所做的是拉取容器描述(即镜像)到我们本地笔记本。现在我们想实际的运行镜像的一个实例作为一个所谓的“容器”。

交互式容器

通常容器在后台运行。他们得启动,然后就忘记它们的存在了。这是Docker的默认行为。但是我们可以采用一种方法使得容器像带有交互式控制台的实例。

[source, text]

#From Internet

docker run -it jboss/wildfly

From Instructor

docker run -it classroom.example.com:5000/wildfly

会像下面一样显示结果:

[source, text]

=========================================================================

JBoss Bootstrap Environment

JBOSS_HOME: /opt/jboss/wildfly

JAVA: /usr/lib/jvm/java/bin/java

JAVA_OPTS: -server -XX:+UseCompressedOops -server -XX:+UseCompressedOops -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true

=========================================================================

OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0

17:02:58,000 INFO [org.jboss.modules] (main) JBoss Modules version 1.4.3.Final

17:02:58,251 INFO [org.jboss.msc] (main) JBoss MSC version 1.2.6.Final

17:02:58,311 INFO [org.jboss.as] (MSC service thread 1-2) WFLYSRV0049: WildFly Full 9.0.1.Final (WildFly Core 1.0.1.Final) starting

17:02:59,558 INFO [org.jboss.as.controller.management-deprecated] (ServerService Thread Pool -- 11) WFLYCTL0028: Attribute 'job-repository-type' in the resource at address '/subsystem=batch' is deprecated, and may be removed in future version. See the attribute description in the output of the read-resource-description operation to learn more about the deprecation.

17:02:59,560 INFO [org.jboss.as.controller.management-deprecated] (ServerService Thread Pool -- 3) WFLYCTL0028: Attribute 'enabled' in the resource at address '/subsystem=datasources/data-source=ExampleDS' is deprecated, and may be removed in future version. See the attribute description in the output of the read-resource-description operation to learn more about the deprecation.

...

17:03:00,610 INFO [org.wildfly.extension.undertow] (MSC service thread 1-2) WFLYUT0006: Undertow HTTP listener default listening on /0.0.0.0:8080

17:03:00,715 INFO [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-2) WFLYJCA0001: Bound data source [java:jboss/datasources/ExampleDS]

17:03:00,881 INFO [org.jboss.ws.common.management] (MSC service thread 1-1) JBWS022052: Starting JBoss Web Services - Stack CXF Server 5.0.0.Final

17:03:00,891 INFO [org.jboss.as.server.deployment.scanner] (MSC service thread 1-2) WFLYDS0013: Started FileSystemDeploymentService for directory /opt/jboss/wildfly/standalone/deployments

17:03:01,131 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management

17:03:01,133 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990

17:03:01,138 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 9.0.1.Final (WildFly Core 1.0.1.Final) started in 3431ms - Started 203 of 379 services (210 services are lazy, passive or on-demand)

控制台显示了服务器正确启动,恭喜!

开关标记做了下面事情: -i 允许和STDIN交互, -t 把一个TTY附着在进程上。开关标记可以组合在一个,成为 -it

按下Ctrl+C停止容器。

分离容器

使用分离模式重启容器:

[source, text]

#From Internet

docker run --name mywildfly -d jboss/wildfly

From Instructor

docker run --name mywildfly -d classroom.example.com:5000/wildfly

972f51cc8422eec0a7ea9a804a55a2827b5537c00a6bfd45f8646cb764bc002a

使用 -d 而不是 -it 在分离模式下运行容器。

输出是分配给容器的唯一的标识。你可以在各种上下文中使用它来引用容器。检查日志像:

[source, text]

> docker logs 972f51cc8422eec0a7ea9a804a55a2827b5537c00a6bfd45f8646cb764bc002a

JBoss Bootstrap Environment

JBOSS_HOME: /opt/jboss/wildfly

. . .

我们可以使用 docker ps 命令检查正在运行的镜像进程和进程占用的端口:

[source, text]

> docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

7da1c7614edf jboss/wildfly "/opt/jboss/wildfly/ About a minute ago Up About a minute 8080/tcp mywildfly

注意“NAMES” 列,这是引用你的容器的快速方法。让我们试着再看一次日志:

[source, text]

docker logs mywildfly

That looks easier. 这看起来更容易些。

可以试着运行 ps -a 来查看这台电脑上的所有容器。

使用默认端口运行容器

它也显示了公共接口绑定到了 0.0.0.0 地址,同时管理接口绑定到 localhost 上。这些信息对学习如果定制服务器有用。

docker-machine ip <machine-name> 返回Docker主机的IP地址,这地址已经添加到了hosts文件。所以,可以尝试访问 http://dockerhost:8080 。但是,这也不会工作。

如果你想要容器接收传入的连接,你需要在运行 docker run 的时候提供特定的选项。我们刚刚启动的容器,不能通过浏览器访问。我们需要停止它,然后使用不同的选项重启。

[source, text]

docker stop mywildfly

Restart the container as: 重启容器:

[source, text]

#From Internet

docker run --name mywildfly-exposed-ports -d -P jboss/wildfly

From Instructor

docker run --name mywildfly-exposed-ports -d -P classroom.example.com:5000/wildfly

-P 映射镜像内部暴露的任意一个端口到Docker主机上的一个随机端口。这可以通过下面命令来验证:

[source, text]

> docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

7f41a5a0cfd6 jboss/wildfly "/opt/jboss/wildfly/ 52 seconds ago Up 52 seconds 0.0.0.0:32768->8080/tcp mywildfly-exposed-ports

端口映射在 PORTS 显示。使用 http://dockerhost:32768 访问WildFly服务器。请确保使用你控制台上显示的端口号。

注意:你显示的端口号可能和这里的不同。

使用指定的端口运行容器

让我们停止运行前面正在运行的容器:

[source, text]

docker stop mywildfly-exposed-ports

重新启动容器:

[source, text]

#From Internet

docker run --name mywildfly-mapped-ports -d -p 8080:8080 jboss/wildfly

From Instructor

docker run --name mywildfly-mapped-ports -d -p 8080:8080 classroom.example.com:5000/wildfly

格式是 -p hostPort:containerPort .这个选项映射容器端口到主机端口,同时允许你主机上的其他容器访问他们。

. Docker端口映射

[注意]

端口暴露和映射是成功使用Docker的关键。

关于更多Docker的网络知识,参考: https://docs.docker.com/articles/networking/ [Advanced Networking]

现在我们在一次准备测试 http://dockerhost:8080 。正如我们所期望的,在了暴露的端口上,这工作了。

让我们停止运行前面正在运行的容器:

[source, text]

docker stop mywildfly-mapped-ports

.Welcome WildFly

image::images/plain-wildfly1.png[]

[[Enabling_WildFly_Administration]]

启用WildFly管理

默认WildFly镜像仅暴露8080端口,因此不能使用CLI和Admin Console进行管理。让我们使用不同的方法来暴露端口。

默认的端口映射

下面的命令会覆盖Docker文件中默认命令,启动WildFly,绑定应用程序和管理程序的端口到所有的网络接口。

[source, text]

#From Internet

docker run --name managed-wildfly -P -d jboss/wildfly /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0

From Instructor

docker run --name managed-wildfly -P -d classroom.example.com:5000/wildfly /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0

访问WildFly Administration Console需要用户在管理域。一个预先创建的镜像,带有合适的username/password凭证,用来启动WildFly:

[source, text]

#From Internet

docker run --name managed-wildfly-from-image -P -d rafabene/wildfly-admin

From Instructor

docker run --name managed-wildfly-from-image -P -d classroom.example.com:5000/wildfly-management

-P 映射镜像内任意暴露的端口到Docker主机上的随机的一个端口。

Look at the exposed ports as: 查看暴露的端口:

[source, text]

docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

5fdedef5573b rafabene/wildfly-admin "/bin/sh -c '/opt/jb 15 seconds ago Up 15 seconds 0.0.0.0:32772->8080/tcp, 0.0.0.0:32771->9990/tcp managed-wildfly-from-image

ee30433b5414 jboss/wildfly "/opt/jboss/wildfly/ 59 seconds ago Up 59 seconds 0.0.0.0:32769->8080/tcp managed-wildfly

Look for the host port that is mapped in the container, 32769 in this case. Access the admin console at http://dockerhost:32769. 查找主机端口,被映射到容器内的 32769 在本例中。访问管理控制台 http://dockerhost:32769 。

NOTE: Exact port number may be different in your case. 注意:在你的控制台上,端口号可能不同。

The username/password credentials are: username/password 凭证是:

[[WildFly_Administration_Credentials]]

[options="header"]

|====

| Field | Value

| Username | admin

| Password | docker#admin

|====

这显示管理控制台:

.Welcome WildFly

image::images/wildfly-admin-console.png[

第4章 运行容器

]

Additional Ways To Find Port Mapping 查找端口映射的其它方法

精确的映射的端口可以通过下面的命令查到:

使用 docker port

+

[source, text]

docker port managed-wildfly-from-image

+

to see the output as:

+

[source, text]

0.0.0.0:32769->8080/tcp

0.0.0.0:32770->9990/tcp

+

. 使用 docker inspect

+

[source, text]

docker inspect --format='{{(index (index .NetworkSettings.Ports "9990/tcp") 0).HostPort}}' managed-wildfly-from-image

[[Management_Fixed_Port_Mapping]]

固定端口映射

这个管理镜像可以使用预定义的端口映射启动:

[source, text]

#From Internet

docker run -p 8080:8080 -p 9990:9990 -d rafabene/wildfly-admin

From Instructor

docker run -p 8080:8080 -p 9990:9990 -d classroom.example.com:5000/wildfly-management

在这种情况下,Docker端口映射显示如下:

[source, text]

8080/tcp -> 0.0.0.0:8080

9990/tcp -> 0.0.0.0:9990

### 停止和移除容器

停止容器

. 停止特定的容器

+

[source, text]

docker stop <CONTAINER ID>

+

. 停止所有证照运行的容器

+

[source, text]

docker stop docker ps -aq

+

. 仅停止已经退出的容器

+

[source, text]

docker ps -a -f "exited=-1"

#### 移除容器

. 移除指定的容器:

+

[source, text]

docker rm 0bc123a8ece0

+

. 移除匹配正则表达式的容器:

+

[source, text]

docker ps -a | grep wildfly | awk '{print $1}' | xargs docker rm

+

. 移除所有的容器,不使用任何准则:

+

[source, text]

docker rm docker ps -aq

正文到此结束
Loading...