image
Docker 从 2013 年发布至今, 一直是广受瞩目, 所以我们或多或少也应该了解一些 Docker 的技术原理, 而学习一项技术有了兴趣才能更好的让你持续学习下去. 如果让你体会到 Docker 的神奇之处那么兴趣或许会大一点, 接下来我们就先从自定义一个自己的 Docker 容器镜像来开启学习 Docker 的第一步.
自定义 Docker 容器镜像
在开始我们的实践之前, 我们当然得在机器上安装 Docker, 请参考官方文档
Mac 安装方法 https://docs.docker.com/docker-for-mac/install/
Windows 安装方法
安装完 Docker 以后我们就需要编写我们要部署的项目代码了, 我们简单的部署一个用 Python 编写的 web 应用, 如果是之前部署到虚拟机中的话我们得在虚拟机中安装各种环境才能将此项目部署成功. 而现在在 Docker 中我们只需要一个文件就能将环境全部打包成一个镜像并且运行.
- from flask import Flask
- import socket
- import os
- App = Flask(__name__)
- @App.route('/')
- def hello():
- html = "<h3>Hello {name}!</h3>" \
- "<b>Hostname:</b> {hostname}<br/>"
- return HTML.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname())
- if __name__ == "__main__":
- App.run(host='0.0.0.0', port=80)
这个程序我们在本机启动的话在浏览器中输入 http://0.0.0.0:80 / 即可访问到后台打印的信息. 接下来我们就将其制作成镜像.
制作镜像的关键一步就是制作 Dockerfile 文件, 在 Dockerfile 中通过 Docker 提供的一些命令编写一套执行流程来制作镜像.
- # 使用官方提供的 Python 作为我们镜像的基础环境
- FROM python:2.7-slim
- # 将工作目录切换为 /Users/hupengfei/Downloads/docker/test
- WORKDIR /Users/hupengfei/Downloads/docker/test
- # 将当前目录下的所有内容复制到 /Users/hupengfei/Downloads/docker/test 下
- ADD . /Users/hupengfei/Downloads/docker/test
- # 使用 pip 命令安装这个应用所需要的依赖
- RUN pip install --trusted-host pypi.python.org -r requirements.txt
- # 允许外界访问容器的 80 端口
- EXPOSE 80
- # 设置环境变量
- ENV NAME World
- # 设置容器进程为: python App.py, 即: 这个 Python 应用的启动命令
- CMD ["python", "app.py"]
下面介绍一些上面 Dockerfile 中用到的命令作用
FROM: 用于指定其后构建新镜像所使用的基础镜像. FROM 指令必是 Dockerfile 文件中的首条命令, 启动构建流程后, Docker 将会基于该镜像构建新镜像, FROM 后的命令也会基于这个基础镜像.
WORKDIR: 用于在容器内设置一个工作目录.
ADD: 更高级的复制命令, 将原路径文件赋值到目标路径中
RUN: 在容器中执行 Shell 命令, requirements.txt 中放着所要下载依赖的名字 Flask
EXPOSE: 为构建的镜像设置监听端口, 使容器在运行时监听.
ENV: 设置环境变量而已, 无论是后面的其它指令, 如 RUN, 还是运行时的应用, 都可以直接使用这里定义的环境变量.
CMD: 用于指定在容器启动时所要执行的命令.
此时我们看到我们的目录中存放的文件为
hupengfei@localhost ~/Downloads/docker ls
Dockerfile App.py requirements.txt test
此时在存放 Dockerfile 目录下执行一下命令
docker build -t helloworld .
其中 - t 是为此镜像起一个名字, 其中此命令会自动的加载本路径下的 Dockerfile 文件中内容, 按顺序执行命令来创建镜像. 此时可以通过以下命令查看已经创建的镜像
hupengfei@localhost ~/Downloads/docker docker image ls
- REPOSITORY TAG IMAGE ID CREATED SIZE
- helloworld latest c91cf8925eba 34 seconds ago 130MB
接下来通过 dokcer run 命令进行启动镜像
hupengfei@localhost ~/Downloads/docker docker run -p 4000:80 helloworld
- * Serving Flask App "app" (lazy loading)
- * Environment: production
- WARNING: Do not use the development server in a production environment.
- Use a production WSGI server instead.
- * Debug mode: off
- * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
其中 4000:80 意思是将宿主机的 4000 端口映射到镜像中的 80 端口上, 此时我们用 docker ps 就可以看到启动的 docker 镜像了
hupengfei@localhost ~ docker ps
- CONTAINER ID IMAGE COMMAND CREATED
- 1f1e5affd99e helloworld "python app.py" 23 seconds ago
此时访问页面也能够访问到
hupengfei@localhost ~ curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> 1f1e5affd99e<br/>%
如果我们不指定绑定 4000 端口的话, 那么就会在宿主机上随机分配一个端口与镜像进行连接
hupengfei@localhost ~/Downloads/docker docker run -p :80 helloworld
- * Serving Flask App "app" (lazy loading)
- * Environment: production
- WARNING: Do not use the development server in a production environment.
- Use a production WSGI server instead.
- * Debug mode: off
- * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
此时我们通过 docker port id 号能够查询到宿主机与镜像对应连接的端口号
hupengfei@localhost ~ docker port 1a93958d31b1
80/tcp -> 0.0.0.0:32769
上传镜像到 DockerHub 中
在 Docker Hub https://hub.docker.com/ 上注册账号
登录进去后在主页点击 Create a Repository
image
填写信息
image
在本机登录自己的 Docker Hub 账号, 命令是 docker login
image
用 docker tag 命令为自己的镜像取一个完整的名字包括版本号, v1 为版本号
docker tag helloworld 刚才创建的账户名字 / helloworld:v1
将刚才所自定义的镜像上传上去, 命令是 docker push buxuewushu/helloworld:v1, 其中 buxuewushu 是换成自己的账号, 后面是刚才打的标签名
image
此时你就可以在 Docker Hub https://hub.docker.com/ 中看到自己上传的镜像了
image
参考文章
本文的例子参考自极客时间中张磊写的深入剖析 Kubernetes, 有兴趣的可以查看
image
来源: http://www.jianshu.com/p/c09bdf9b24ca