非常教程

Docker 17参考手册

开始 | Get Started

第2部分:容器 | Part 2: Containers

  • 1:概况介绍
  • 2:集装箱
  • 3:服务
  • 4:成群
  • 5:堆叠
  • 6:部署应用程序

先决条件

  • 安装Docker版本1.13或更高版本...
  • 阅读第1部分中的方向。
  • 给您的环境一个快速测试运行,以确保您已经设置好了:

码头经营哈罗-世界

导言

现在是开始以Docker方式构建应用程序的时候了。我们将从这种应用程序的层次结构的底部开始,该应用程序是一个容器,我们将在此页面上进行介绍。在这个层次上面是一个服务,它定义了容器在生产中的行为方式,在第3部分中进行了讨论。最后,在顶层是堆栈,定义了第5部分中介绍的所有服务的交互。

  • 堆叠
  • 服务
  • 集装箱你在这里

您的新开发环境

在过去,如果您要开始编写Python应用程序,您的首要任务就是将Python运行时安装到您的计算机上。但是,这就造成了这样一种情况:为了使应用程序按预期运行,计算机上的环境必须是这样的;运行应用程序的服务器也是如此。

使用Docker,您只需获取一个可移植的Python运行时作为映像,无需安装。然后,您的构建可以将基本Python映像与应用程序代码放在一起,确保应用程序、其依赖项和运行时都能一起运行。

这些便携式图像是由称为a的东西定义的Dockerfile

使用Dockerfile

Dockerfile将定义容器内环境中发生的事情。在这个环境中,对网络接口和磁盘驱动器等资源的访问是虚拟化的,这与系统的其他部分是隔离的,因此您必须将端口映射到外部世界,并具体说明要将哪些文件“复制”到该环境。但是,在这样做之后,您可以预期您的应用程序的构建是在Dockerfile无论在哪里运行都会表现得完全一样。

Dockerfile

创建一个空目录。将目录(cd)更改为新目录,创建一个名为的文件Dockerfile,将以下内容复制并粘贴到该文件中并保存。注意解释新Dockerfile中每条语句的注释。

# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Dockerfile指我们还没有创建的几个文件,即app.pyrequirements.txt让我们创造下一个。

应用程序本身

再创建两个文件,requirements.txtapp.py,并将它们放在同一个文件夹中,Dockerfile这就完成了我们的应用程序,正如您所看到的,这个应用程序非常简单。当以上Dockerfile被塑造成一幅图像,app.pyrequirements.txt会因为这个而出现DockerfileADD命令的输出。app.py可以通过HTTP访问,这要感谢EXPOSE命令。

requirements.txt

Flask
Redis

app.py

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

现在我们看到了pip install -r requirements.txt安装用于Python的Flask和Redis库,应用程序打印环境变量NAME,以及调用的输出socket.gethostname()最后,由于Redis没有运行%28,我们只安装了Python库,而没有安装Redis本身的%29,因此我们应该期望在这里使用它的尝试会失败并产生错误消息。

:在容器中检索容器ID时访问主机的名称,这就像正在运行的可执行文件的进程ID一样。

而已!您requirements.txt的系统中不需要Python或其他任何东西,也不会在您的系统上安装或运行此映像。看起来你并没有真正用Python和Flask建立一个环境,但是你已经拥有了。

构建应用程序

我们已经准备好构建这个应用程序了。确保您仍然处于新目录的顶层。这是什么ls应显示:

$ ls
Dockerfile		app.py			requirements.txt

现在运行Build命令。这将创建一个Docker映像,我们将使用它进行标记-t所以它有个友好的名字。

docker build -t friendlyhello .

你的形象在哪里?它在您机器的本地Docker映像注册表中:

$ docker images

REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398

运行应用程序

运行应用程序,使用以下方法将机器的端口4000映射到容器的已发布端口80-p*

docker run -p 4000:80 friendlyhello

您应该会看到Python正在为您的应用提供服务的通知http://0.0.0.0:80。但是该消息来自容器内部,它不知道你将该容器的端口80映射到4000,从而制作正确的URL http://localhost:4000

转到Web浏览器中的URL,查看网页上的显示内容,包括“HelloWorld”文本、容器ID和Redis错误消息。

第2部分:容器  |  Part 2: Containers

您还可以使用curl命令在shell中查看相同的内容。

$ curl http://localhost:4000

<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>

*该端口重新映射为4000:80是为了证明你EXPOSEDockerfile,还有你publish使用docker run -p在后面的步骤中,我们将只将主机上的端口80映射到容器中的端口80,然后使用http://localhost...

命中CTRL+C在你的终点站辞职。

现在让我们在后台以分离模式运行该应用程序:

docker run -d -p 4000:80 friendlyhello

你得到你的应用程序的长容器ID,然后被踢回你的终端。您的容器正在后台运行。您还可以看到缩写的容器IDdocker container ls%28并且在运行命令%29时两者都可以互换工作:

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago

你会看到的CONTAINER ID匹配正在进行的http://localhost:4000...

现在用docker stop若要结束该进程,请使用CONTAINER ID,就像这样:

docker stop 1fa4ab2cf395

分享你的形象

为了演示我们刚刚创建的图像的可移植性,让我们上传构建的映像并在其他地方运行它。毕竟,当您想要将容器部署到生产中时,您将需要学习如何推送到注册表。

注册表是存储库的集合,存储库是图像的集合--有点像GitHub存储库,只是代码已经构建。注册中心上的帐户可以创建许多存储库。大docker默认情况下,CLI使用Docker的公共注册表。

:我们在这里使用Docker的公共注册表,仅仅是因为它是免费的和预先配置的,但是有许多公共注册表可供选择,您甚至可以使用码头受信任登记处...

用您的码头ID登录

如果您没有码头帐户,请在Cloud.docker.com请记下你的用户名。

登录到本地计算机上的Docker公共注册表。

docker login

标记图像

将本地映像与注册表上的存储库关联的符号是username/repository:tag标记是可选的,但建议使用它,因为它是注册表用于为Docker图像提供一个版本的机制。为上下文提供存储库和标记有意义的名称,如get-started:part1。这将把图像放在get-started存储库并将其标记为part1...

现在,把它放在一起标记图像。跑docker tag image使用您的用户名、存储库和标签名,以便图像将上载到您想要的目的地。该命令的语法是:

docker tag image username/repository:tag

例如:

docker tag friendlyhello john/get-started:part1

跑码头形象才能看到你的新标记图像。%28你也可以使用docker image ls.%29

$ docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
john/get-started         part1               d9e555c53008        3 minutes ago       195MB
python                   2.7-slim            1c7128a655f6        5 days ago          183MB
...

发布图像

将标记的图像上载到存储库:

docker push username/repository:tag

一旦完成,这个上传的结果是公开的。如果你登录到码头枢纽,您将看到新的图像,在那里,它的拉命令。

从远程存储库中提取并运行映像

从现在开始,你可以用docker run并使用以下命令在任何机器上运行您的应用程序:

docker run -p 4000:80 username/repository:tag

如果映像在机器上本地不可用,Docker将从存储库中提取它。

docker image rm <image id>
$ docker run -p 4000:80 john/get-started:part1
Unable to find image 'john/get-started:part1' locally
part1: Pulling from orangesnap/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for john/get-started:part1
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

*如果不指定:tag这些命令的一部分,标记为:latest将在构建和运行映像时假设。Docker将使用没有指定%28标记而运行的映像的最后一个版本,而不一定是最近的映像%29。

不管在哪里docker run执行时,它将提取您的图像以及Python和requirements.txt运行你的代码。所有这些都是在一个整洁的小包中一起运行的,主机只需要安装Docker就可以运行它了。

第二部分结论

这一页就这么多了。在下一节中,我们将学习如何通过在服务...

继续第3部分

重述和备忘单%28可选%29

这是本页所涵盖内容的终端记录*

下面列出了这个页面中的基本Docker命令,以及一些相关的命令,如果您想在继续之前进行一番探索的话。

docker build -t friendlyname .  # Create image using this directory's Dockerfile
docker run -p 4000:80 friendlyname  # Run "friendlyname" mapping port 4000 to 80
docker run -d -p 4000:80 friendlyname         # Same thing, but in detached mode
docker container ls                                # List all running containers
docker container ls -a             # List all containers, even those not running
docker container stop <hash>           # Gracefully stop the specified container
docker container kill <hash>         # Force shutdown of the specified container
docker container rm <hash>        # Remove specified container from this machine
docker container rm $(docker container ls -a -q)         # Remove all containers
docker image ls -a                             # List all images on this machine
docker image rm <image id>            # Remove specified image from this machine
docker image rm $(docker image ls -a -q)   # Remove all images from this machine
docker login             # Log in this CLI session using your Docker credentials
docker tag <image> username/repository:tag  # Tag <image> for upload to registry
docker push username/repository:tag            # Upload tagged image to registry
docker run username/repository:tag                   # Run image from a registry

容器,python,代码,编码,构建,推送,运行

Docker 17

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

主页 https://docker.com/
源码 https://github.com/docker/docker
版本 17
发布版本 17.06