Docker环境
Docker有两个版本:
- 社区版(CE)
- 企业版(EE)
Docker Community Edition(CE)非常适合希望开始使用Docker并尝试使用基于容器的应用程序的个人开发人员和小型团队。
Docker企业版(EE)专为企业开发和IT团队而设计,他们可以在生产中大规模构建,发布和运行业务关键型应用程序。
Docker操作参数
- 用户在使用Docker时,使用Docker命令行工具
docker
与Docker daemon建立通讯。Docker daemon是Docker守护进程,负责接收并分发Docker命令。 - 使用
docker
命令或docker help
命令获取docker的命令清单。 - 用户可以使用
docker COMMAND --help
命令查看该子命令的详细信息。
子命令分类 | 子命令 |
---|---|
Docker环境信息 | info、version |
容器生命周期管理 | create、exec、kill、pause、restart、rm、run、start、stop、unpause |
镜像仓库命令 | login、logout、pull、push、search |
镜像管理 | build、images、import、load、rmi、save、tag、commit |
容器运维操作 | attach、export、inspect、port、ps、rename、stats、top、wait、cp、diff |
系统日志信息 | events、history、logs |
安装Docker
安装环境:
Apple macOS Sierra 10.13.5
安装步骤:
1. 下载Docker for Mac。
官方下载链接:https://download.docker.com/mac/stable/Docker.dmg
2. 安装Docker for Mac并启动。
测试Docker版本
- 运行
docker --version
并确保您拥有受支持的Docker版本:
docker --version
Docker version 18.03.1-ce, build 9ee9f40
- 列出
hello-world
下载到您的计算机的图像:
docker images ls
测试Docker安装
- 通过运行简单的Docker镜像hello-world来测试您的安装是否有效 :
docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
- 列出
hello-world
下载到您的计算机的图像:
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest f2a91732366c 7 months ago 1.85kB
- 列出
hello-world
在显示其消息后退出的容器(由图像生成)。如果它仍在运行,您将不需要--all
选项:
docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5855345a28b8 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago focused_swartz
6a18ff436995 hello-world "/hello" 2 hours ago Exited (0) 2 hours ago distracted_poincare
4094ae71e095 hello-world "/hello" 6 months ago Exited (0) 6 months ago ecstatic_poincare
Docker镜像加速
Docker在国内下载镜像的速度太慢,经常失败,所以使用阿里云提供的容器镜像仓库服务。如果不愿意配置镜像,直接进入https://dev.aliyun.com/search.html中寻找镜像使用。 接下来介绍阿里云Docker镜像加速器,使用加速器将会提升您在国内获取Docker官方镜像的速度!
- 进入阿里云容器Hub服务的控制台,并申请成为开发者。
- 点击左侧的加速器帮助页面就会显示您的专属加速器地址。
- 复制地址您的专属加速器地址,将地址填入Docker的配置中,路径如下:Preferences–>Daemon–>Basic–>Registry mirrors,然后重启。
命令备忘录
查看帮助
docker
docker container --help
查看版本和信息
docker --version
docker version
docker info
运行Docker镜像
docker run hello-world
查看Docker镜像列表
docker image ls
列出Docker容器
running ==> 正在运行,all ==> 全部,all in quiet mode ==> 处于安静模式
docker container ls
docker container ls --all
docker container ls -aq
Docker容器
现在是时候开始使用Docker方式构建应用程序了。我们从这样一个应用程序层次结构的底部开始,这是一个容器,我们将在此页面上介绍它。
您的新开发环境
在过去,如果您要开始编写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 --trusted-host pypi.python.org -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.py
和requirements.txt
。让我们创建下一个。
应用程序本身
再创建两个文件,requirements.txt
和app.py
,并将它们与Dockerfile放在同一个文件夹中。 这完成了我们的应用程序,您可以看到它非常简单。 当上面的Dockerfile
内置到镜像中时,由于Dockerfile
的ADD
命令,app.py
和requirements.txt
存在,并且由于EXPOSE
命令,app.py
的输出可通过HTTP访问。
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没有运行(因为我们只安装了Python库,而不是Redis本身),我们应该期望在这里使用它的尝试失败并产生错误消息。
注意:在容器内部访问容器ID时,访问主机名称,这类似于正在运行的可执行文件的进程ID。
仅此而已!您不需要Python或requirements.txt
系统中的任何内容,也不需要构建或运行此映像将它们安装在您的系统上。看起来你并没有真正建立一个Python和Flask的环境,但你有。
构建应用程序
我们准备构建应用程序。确保您仍处于新目录的顶层。这是ls
应该显示的内容:
$ ls
Dockerfile app.py requirements.txt
现在运行build命令。这会创建一个Docker镜像,我们将使用-t
它来标记,因此它具有友好的名称。
docker build -t friendlyhello .
你构建的镜像在哪里?它位于您机器的本地Docker镜像仓库中:
$ docker image ls
REPOSITORY TAG IMAGE ID
friendlyhello latest 326387cea398
Linux用户的故障排除
代理服务器设置
代理服务器可以在启动并运行后阻止与Web应用程序的连接。如果您位于代理服务器后面,请使用以下
ENV
命令将以下行添加到Dockerfile中,以指定代理服务器的主机和端口:sh# Set proxy server, replace host:port with values for your servers ENV http_proxy host:port ENV https_proxy host:port
DNS设置
DNS配置错误可能会产生与
pip
相关问题。您需要设置自己的DNS服务器地址才能使pip
正常工作。您可能想要更改Docker守护程序的DNS设置。您可以/etc/docker/daemon.json
使用dns
密钥编辑(或创建)配置文件,如下所示:sh{ "dns": ["your_dns_address", "8.8.8.8"] }
在上面的示例中,列表的第一个元素是DNS服务器的地址。第二项是Google的DNS,可在第一项无法使用时使用。
在继续之前,请保存
daemon.json
并重新启动docker服务。
sudo service docker restart
修复后,重试运行该
build
命令。
运行该应用程序
运行应用程序,使用-p
将计算机的端口4000映射到容器的已发布端口80:
docker run -p 4000:80 friendlyhello
您应该看到Python正在为您的应用程序提供服务的消息http://0.0.0.0:80
。但是该消息来自容器内部,它不知道您将该容器的端口80映射到4000,从而生成正确的URL http://localhost:4000
。
在Web浏览器中转到该URL,以查看在网页上提供的显示内容。
注意:如果您在Windows 7上使用Docker Toolbox,请使用Docker Machine IP而不是
localhost
。例如,http://192.168.99.100:4000 /。要查找IP地址,请使用该命令docker-machine ip
。
您还可以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
是为了演示您EXPOSE
内部Dockerfile
和您publish
使用的 内容之间的差异docker run -p
。在后面的步骤中,我们只是将主机上的端口80映射到容器中的端口80并使用http://localhost
。
点击CTRL+C
你的终端退出。
在Windows上,显式停止容器
在Windows系统上,
CTRL+C
不会停止容器。因此,首先键入CTRL+C
以获取提示(或打开另一个shell),然后键入docker container ls
以列出正在运行的容器,然后docker container stop <Container NAME or ID>
停止容器。否则,当您尝试在下一步中重新运行容器时,会从守护程序收到错误响应。
现在让我们以分离模式在后台运行应用程序:
docker run -d -p 4000:80 friendlyhello
您获得应用程序的长容器ID,然后被踢回终端。您的容器正在后台运行。您还可以看到缩写的容器ID docker container ls
(并且在运行命令时都可以互换):
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED
1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago
请注意,CONTAINER ID
匹配的是什么http://localhost:4000
。
现在docker container stop
用来结束这个过程,使用CONTAINER ID
如下:
docker container stop 1fa4ab2cf395
分享你的形象
为了演示我们刚刚创建的内容的可移植性,让我们上传我们构建的图像并在其他地方运行它。毕竟,当您想要将容器部署到生产环境时,您需要知道如何推送到注册表。
注册表是存储库的集合,存储库是图像的集合 - 类似于GitHub存储库,除了代码已经构建。注册表上的帐户可以创建许多存储库。该docker
CLI使用泊坞窗的公共注册表默认情况下。
注意:我们在这里使用Docker的公共注册表只是因为它是免费和预先配置的,但有许多公共注册表可供选择,您甚至可以使用Docker Trusted Registry设置自己的私有注册表。
使用您的Docker ID登录
如果您没有Docker帐户,请在hub.docker.com上注册一个帐户 。记下您的用户名。
登录本地计算机上的Docker公共注册表。
$ docker login
标记图像
将本地映像与注册表上的存储库相关联的表示法是 username/repository:tag
。标签是可选的,但建议使用,因为它是注册管理机构用来为Docker镜像提供版本的机制。为上下文提供存储库和标记有意义的名称,例如 get-started:part2
。这会将图像放入get-started
存储库并将其标记为part2
。
现在,把它们放在一起来标记图像。docker tag image
使用您的用户名,存储库和标记名称运行,以便将图像上载到所需的目标位置。该命令的语法是:
docker tag image username/repository:tag
例如:
docker tag friendlyhello gordon/get-started:part2
运行docker image ls以查看新标记的图像。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest d9e555c53008 3 minutes ago 195MB
gordon/get-started part2 d9e555c53008 3 minutes ago 195MB
python 2.7-slim 1c7128a655f6 5 days ago 183MB
...
发布镜像
将标记的镜像上传到存储库:
docker push username/repository:tag
完成后,此上传的结果将公开发布。如果您登录到Docker Hub,则会在其中看到新图像及其pull命令。
从远程存储库中拉出并运行镜像
从现在开始,您可以使用docker run
以下命令在任何计算机上使用和运行您的应用程序:
docker run -p 4000:80 username/repository:tag
如果映像在计算机上不可用,则Docker会从存储库中提取映像。
$ docker run -p 4000:80 gordon/get-started:part2
Unable to find image 'gordon/get-started:part2' locally
part2: Pulling from gordon/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 gordon/get-started:part2
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
无论在哪里docker run
执行,它都会提取您的图像,以及Python和所有依赖项requirements.txt
,并运行您的代码。它们都在一个整洁的小包中一起旅行,你不需要在主机上安装任何东西,以便Docker运行它。
命令备忘录
以下是此页面中基本Docker命令的列表,以及一些相关的命令,如果您想在继续之前稍微探索一下。
使用该目录的Dockerfile创建映像
docker build -t friendlyhello .
运行“friendlyname”映射端口4000到80
docker run -p 4000:80 friendlyhello
运行“friendlyname”映射端口4000到80,但在分离模式
docker run -d -p 4000:80 friendlyhello
列出所有正在运行的容器
docker container ls
列出所有容器,甚至包括那些没有运行的容器
docker container ls -a
优雅地停止指定的容器
docker container stop <hash>
强制关闭指定容器
docker container kill <hash>
从机器中删除指定容器
docker container rm <hash>
删除所有容器
docker container rm $(docker container ls -a -q)
列出该机器上的所有镜像
docker image ls -a
从机器中删除指定的图像
docker image rm <image id>
从机器中删除所有镜像
docker image rm $(docker image ls -a -q)
使用Docker凭证在这个CLI会话中记录日志
docker login
标签<镜像>上传至仓库
docker tag <image> username/repository:tag
上传带标签的镜像到仓库
docker push username/repository:tag
从仓库运行镜像
docker run username/repository:tag