​在 OS X 系统上快速上手 Docker 技术 (对 Docker 还不够熟悉? 从这里开始吧!)

原文作者:Chase Seibert

原文地址:https://dzone.com/articles/dockerosx-quickstart-not

Docker(容器技术)直到2013年才开始受到关注,但现在在我的 Twitter 消息流和 RSS 阅读器中似乎到处都是有关 Docker 技术的文章。我曾经尝试学习过它的 “Hello World” 入门示例,但其实我却从未真正地理解 Docker 技术的核心价值和它到底是如何工作的。直到这一周,我才有一些时间好好坐下来将我的注意力放在它的身上。随后我发现,Docker 技术并没有我想象的那么神秘,那么复杂。

在 Mac 上进行安装

Docker 技术原本诞生于 Linux 平台上,并使用 Linux 原生的工具如 LXC Linux 容器工具 来展现它的精妙之处。在 Windows 平台上也有原生的 Windows 版本以供使用。但在被 Mac 系统占领主导地位的软件开发界,还是让我们来看一下如何在 OS X (现 macOS)平台上安装并运行 Docker。

首先,请不要尝试通过 brew 来进行安装,或者是任何其他类似的包管理工具。Docker 本身是使用 Go 语言编写的,有着在编译为二进制文件后,不需要外部依赖即可使用的优点。此外,Docker 项目的开发进展如此之快,以至于包管理工具中的 Docker 版本都已经过时了。因此,请忘掉这些工具,动手 下载二进制版本 进行安装吧!

如果你在 Terminal (终端)中能正确执行 docker --version 的话,那么你已经准备好进行接下来的步骤了。这篇教程中使用的 Docker 版本是 1.5.0

使用 Boot2Docker

如果你现在就尝试启动一个 Docker 镜像的话,你会看到一条类似 docker max dial unix /var/run/docker.sock: no such file or directory 的神秘错误信息。这是因为 Docker 的守护进程还没有运行。但是实际上,它的守护进程没办法在 Mac 上运行!作为替代,你需要使用 boot2docker 这个程序,这是一个微型的虚拟机程序,运行在 VirtualBox 虚拟机软件中,并运行着 Docker 的守护进程。再一次的,请使用二进制安装包来安装 boot2docker 这个程序(我很抱歉你需要这么做!)。

为了启动 boot2docker,打开 Terminal 终端,并执行下述的几条指令。

boot2docker init
boot2docker up
eval "$(boot2docker shellinit)"
docker run ubuntu:14.04 /bin/echo 'Hello world'

上述的指令就是一个简单的 "Hello world" 程序。接下来让我们逐条分析一下这里究竟发生了什么。

boot2docker init 这条指令在 VirtualBox 中初始化创建了一个新的虚拟机。

boot2docker.png

下一步,boot2docker up 启动了刚刚创建的虚拟机。随后的 eval "$(boot2docker shellinit)" 这条指令的作用是设置好一些环境变量,这些环境变量用于告知 Docker 当前所属容器的上下文信息。如果你直接在 Terminal 内执行 boot2docker shellinit,你能看到以下的原始输出:

Writing /Users/chase/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/chase/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/chase/.boot2docker/certs/boot2docker-vm/key.pem
export DOCKER_HOST=tcp://192.168.59.104:2376
export DOCKER_CERT_PATH=/Users/chase/.boot2docker/certs/boot2docker-vm
export DOCKER_TLS_VERIFY=1

前三行只是一些提示性的消息,只有后三行内容会被输出到标准输出 stdout。

最后一条指令 docker run ubuntu:14.04 /bin/echo 'Hello world' 实际上创建了一个新的 Docker 容器(运行 Ubuntu 14.04),并在容器内执行了一行命令 /bin/echo 'Hello world'

有关容器的一些介绍

容器(Container)是小型的沙盒化的 Linux 实例。镜像文件(Image)是经序列化的定义文件,而容器是依附于这些镜像文件生成的。Docker 技术的精妙之处就在于镜像文件是非常容易转移的。而我在最初没有真正感受到这个概念的意义,而是想当然的认为,你需要现在你的 Mac 上制作好镜像文件并运行它,然后在你的亚马逊 EC2 云服务器上另外制作一个镜像文件并运行它。

实际上,你只需要在你的 Mac 上制作好一个镜像文件,然后本质上只需要一条 scp 指令将镜像文件传送到云服务器上运行就可以了。事实上,你甚至不需要手动的执行复制操作,这恰恰是 Docker Hub 容器中枢在行的事情。

此外,在你的 Docker 容器中运行的 Linux 发行版本甚至不需要和宿主机操作系统的版本一致。例如,你可以在一台运行着 CentOS 系统的宿主机上运行一个 Ubuntu 容器,反过来也同样可行。

最后,镜像文件自带有有一个 分层机制。从本质上来说,你可以在一个原始的镜像文件基础上,添加任意数量的对镜像文件的微小修改。这为 Docker 技术带来了强大的优化能力和抽象能力,我们会在稍后再次讲到这一点。

运行 Python Flask 应用的实例

对于想要开始使用 Docker 技术的 Python 开发者来说,这是一个非常经典有实际意义的教程,但到目前为止我还未能通过我找到的文档资料来成功地完成这个例子。以下是我自己完成的一个特殊的 snowflake 版本。

首先,创建一个叫 flask 的文件夹,在这个文件夹内,你将会要创建以下3个文件。

第一个文件叫 app.py ,这个文件的内容是一个简单的 “Hello world ” Flask 应用。

from flask import Flask
import os
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

然后,创建第二个叫 requirements.txt 的文件,在这个文件内将 Flask 列为依赖项:

Flask==0.10.1

最后,创建你的 Dockerfile 文件:

FROM python:2.7
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
EXPOSE 5000
CMD python app.py

让我们用一些时间来逐句分析一下最后这个文件的内容。第一行 FROM python:2.7 告诉 Docker 程序从公共仓库里查找一个叫 python 的镜像文件,并使用名字标签为 2.7pyhton 镜像文件(类似于版本号的含义)创建容器。

第二行的 ADD 指令将当前目录下 . 的所有文件,即你的代码,复制到 Docker 容器内的 Linux 实例中的 /code 路径下。第三行的 WORKDIR 同时将 /code 这个目录设置为工作路径。

RUN 这个关键词可以被使用若干次。它的含义是告诉 Docker 在第一次建立容器的时候执行这些代码。需要注意的是,多个 RUN 的步骤实际上是被缓存处理的,这意味着当你之后对一条 RUN 指令做出修改时,只有被修改的指令会被重新运行,这一特性很可能是由我们之前提到的容器分层机制导致的。

EXPOSE 指令告诉 Docker 这个容器向外部开放 5000 端口进行服务。我们稍后也会将 flask 应用运行在同一个端口上。

最后,CMD 指令指明了在容器的主守护进程运行的命令。如果你需要多个守护进程,请参阅 docker-compose 了解更多这方面的资料。

运行你的 Docker

为了运行刚才的示例,你需要执行接下来的这些命令:

open "http://$(boot2docker ip):5000"
docker build -t flask-example .
docker run -it -p 5000:5000 -v $(pwd):/code:ro flask-example

执行完这些命令之后,一个浏览器标签会在 flask 运行之前打开。这时浏览器的内容很可能是一个 “网页无法访问” 的错误界面,但如果你刷新一下当前页面,你就应该能看到 “Hello World!” 这句话。

刚才运行的这些代码创建了一个名为 flask-example 的镜像文件,并随后运行了它。你甚至可以直接在你的本地文件系统内编辑这些代码,这些改动会同步到 Docker 内(参数 -v 起到的作用)并重新启动 flask 。

在云服务器上运行相同的容器

现在,让我们看一下如何在云服务器上运行之前我们使用的容器。首先,你需要在 Docker Hub 注册一个账号,这一步是免费的。

在这里我们假设你的 Docker Hub 用户名是 foobar ,首先,重新创建并发布你的镜像文件:

docker build -t foobar/flask-example .
docker login
docker push foobar/flask-example

然后,在亚马逊云服务控制台创建一个新的 EC2 云服务器实例。请确保新的云服务器使用的是 “Amazon Linux” 基础镜像,因为在这个镜像上安装 Docker 会更简单一些。使用 SSH 工具连接到你的云服务器上,并启动 Docker 容器:

sudo yum install -y docker; sudo service docker start
sudo docker run -it -p 8000:5000 foobar/flask-example

第一行指令只是简单的安装 Docker 服务并启动了它。第二行指令从 Docker Hub 抓取了你的镜像文件(备注:并不需要进行身份验证!),然后在一个交互式命令行内运行它,最后将宿主机 EC2 服务器的外部 8000 端口映射到容器的 5000 端口。

如果你的服务器安全组配置放行了 8000 端口,那么你应该能够用浏览器访问你的云服务器的 8000 端口了。

写在最后

当我开始着手于学习 Docker 时,我马上就尝试着去阅读 docker-composedocker-machine 的文档并尝试去使用这两个工具,但过早的去研究他们其实是我犯的一个错误。这两个官方插件的功能是能让你在配置 Docker 的多服务和多机器功能时轻松不少。我建议在你刚开始学习的时候不要去深入研究这些工具,直到你能把上面介绍的基础知识都弄清楚。我在初学的时候就因为执着于学习这些工具而导致我没能理解清楚 Docker 技术真正做到的事情是什么。

本文的版权归 Weston Wu 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Youngxj

PHP新浪图床系统源码分享

4444
来自专栏zhangdd.com

升级Windows 10常见问题解决方案汇总

微软已经正式向全球推送了Windows 10操作系统,与以往Windows产品不同的是,微软对windows7和Windows 8.1 的用户施行免费升级的策略...

542
来自专栏编程

Spark之搜狗日志查询实战

1、下载搜狗日志文件: 地址:http://www.sogou.com/labs/resource/chkreg.php 2、利用WinSCP等工具将文件上传至...

20910
来自专栏Python、Flask、Django

搭建自己的jetbrains全家桶认证服务

1232
来自专栏杂烩

GitHug备忘 原

作为开源代码库以及版本控制系统,Github拥有140多万开发者用户。随着越来越多的应用程序转移到了云上,Github已经成为了管理软件开发以及发现已有代码的首...

515
来自专栏漏斗社区

业务逻辑漏洞探索之暴力破解

最近斗哥在整理一些业务逻辑漏洞,突然发现好多问题,所以决心和大家一起探讨探讨,今天先从暴力破解开始。

621
来自专栏前端新视界

node-sass 安装失败的解决措施

在测试gulp-webapp的时候遇到了 styles 不能被正常编译的问题,究其原因是node-sass没有被正常安装。 根本原因是国内网络的原因。 最终的解...

22110
来自专栏杨建荣的学习笔记

在eclipse中配置MySQL源码环境(r12笔记第14天)

今天费了些周折,总算搭建好了MySQL源码的调试环境,主要的目的就是想在看代码的时候有一些头绪,让这些开发技巧派上用场。不至于盲人摸象一般的拿着命令肉眼扫...

3626
来自专栏北京马哥教育

让你的Git水平更上一层楼的10个小贴士

最近,我们发表了关于Git基础知识和在团队中使用Git的教程。我们之前讨论的那些命令,已经足够让帮助一个开发者在Git世界里生存了。本篇文章,我们将尝试探索如何...

2905
来自专栏我是攻城师

如何在Intellij IDEA中集成Gitlab

据说在微软收购github当天,一大批用户纷纷转向了gitlab和bitbucket,这两者也都是比较不错的代码托管网站,针对个人和企业都有对应的免费和收费版本...

851

扫码关注云+社区