|
| 1 | +# Docker 快速指南 |
| 2 | + |
| 3 | +## Orientation |
| 4 | + |
| 5 | +### 概念 |
| 6 | + |
| 7 | +Docker 是一个让开发者或系统管理员使用容器来**开发**、**部署**和**运行**应用的平台。 |
| 8 | + |
| 9 | +容器化即使用 linux 容器来部署应用。 |
| 10 | + |
| 11 | +#### Docker 的优点 |
| 12 | + |
| 13 | +* 灵活的:即使是最复杂的应用也可以容器化。 |
| 14 | +* 轻量级:容器利用和共享主机内核。 |
| 15 | +* 可交换:你可以随意部署更新和升级。 |
| 16 | +* 可移植:你可以本地构建,部署到云端,并在任何地方运行。 |
| 17 | +* 可扩展:你可以添加并自动分配容器拷贝。 |
| 18 | +* 可堆叠:你可以随意垂直堆叠服务。 |
| 19 | + |
| 20 | +#### 容器和镜像 |
| 21 | + |
| 22 | +镜像是一个可执行的包,这个包中含有运行一个应用所需要的一切:代码、运行环境、库、环境变量、配置文件。 |
| 23 | + |
| 24 | +容器是一个镜像的实例。镜像和容器的关系就好像面向对象语言中类和对象的关系。 |
| 25 | + |
| 26 | +### 容器和虚拟机 |
| 27 | + |
| 28 | +一个容器在Linux上本地运行,并与其他容器共享主机的内核。它运行一个独立的进程,不占用任何其他可执行文件的内存,使其轻量化。 |
| 29 | + |
| 30 | +相比之下,虚拟机(VM)运行一个完整的“客户”操作系统,通过虚拟机管理程序虚拟访问主机资源。一般来说,虚拟机提供的环境比大多数应用程序需要的资源更多。 |
| 31 | + |
| 32 | + |
| 33 | + |
| 34 | +## Containers |
| 35 | + |
| 36 | +在以往的开发中,运行一个应用,首先需要准备好它的运行环境。 |
| 37 | + |
| 38 | +使用 Docker,可以将应用的运行环境(如 JDK、Maven等)打包为一个可移植的镜像。然后,运行应用的同时,运行基础运行环境镜像。 |
| 39 | + |
| 40 | +这种可移植的镜像定义在一个叫做 `Dockerfile` 的文件。 |
| 41 | + |
| 42 | +### Dockerfile |
| 43 | + |
| 44 | +Dockerfile定义了容器内环境中发生的事情。访问网络接口和磁盘驱动器等资源是在此环境中虚拟化的,与系统的其余部分隔离,因此您需要将端口映射到外部世界,并明确要将哪些文件“复制”到那个环境。但是,在完成这些之后,您可以预期,在此Dockerfile中定义的应用程序构建在运行时的行为完全相同。 |
| 45 | + |
| 46 | +### 创建并运行一个镜像 |
| 47 | + |
| 48 | +(1)创建一个目录 |
| 49 | + |
| 50 | +```sh |
| 51 | +mkdir -p /home/zp/dockerdemo |
| 52 | +cd /home/zp/dockerdemo |
| 53 | +``` |
| 54 | + |
| 55 | +(2)定义一个 Dockerfile |
| 56 | + |
| 57 | +```docker |
| 58 | +# Use an official Python runtime as a parent image |
| 59 | +FROM python:2.7-slim |
| 60 | +
|
| 61 | +# Set the working directory to /app |
| 62 | +WORKDIR /app |
| 63 | +
|
| 64 | +# Copy the current directory contents into the container at /app |
| 65 | +ADD . /app |
| 66 | +
|
| 67 | +# Install any needed packages specified in requirements.txt |
| 68 | +RUN pip install --trusted-host pypi.python.org -r requirements.txt |
| 69 | +
|
| 70 | +# Make port 80 available to the world outside this container |
| 71 | +EXPOSE 80 |
| 72 | +
|
| 73 | +# Define environment variable |
| 74 | +ENV NAME World |
| 75 | +
|
| 76 | +# Run app.py when the container launches |
| 77 | +CMD ["python", "app.py"] |
| 78 | +``` |
| 79 | + |
| 80 | +> 代理服务器在启动并运行后可以阻止与您的网络应用程序的连接。如果您位于代理服务器的后面,请使用 `ENV` 命令为您的代理服务器指定主机和端口,将以下行添加到 Dockerfile 中: |
| 81 | +> |
| 82 | +> ```docker |
| 83 | +> # Set proxy server, replace host:port with values for your servers |
| 84 | +> ENV http_proxy host:port |
| 85 | +> ENV https_proxy host:port |
| 86 | +> ``` |
| 87 | +
|
| 88 | +(3)创建一个 app |
| 89 | +
|
| 90 | +这里以创建一个 python 应用为例。 |
| 91 | +
|
| 92 | +在 Dockerfile 同目录下新建 `requirements.txt` 文件和 `app.py` 文件。 |
| 93 | +
|
| 94 | +创建一个 `requirements.txt` 文件 |
| 95 | +
|
| 96 | +``` |
| 97 | +Flask |
| 98 | +Redis |
| 99 | +``` |
| 100 | +
|
| 101 | +创建一个 `app.py` 文件 |
| 102 | +
|
| 103 | +```py |
| 104 | +from flask import Flask |
| 105 | +from redis import Redis, RedisError |
| 106 | +import os |
| 107 | +import socket |
| 108 | +
|
| 109 | +# Connect to Redis |
| 110 | +redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) |
| 111 | +
|
| 112 | +app = Flask(__name__) |
| 113 | +
|
| 114 | +@app.route("/") |
| 115 | +def hello(): |
| 116 | + try: |
| 117 | + visits = redis.incr("counter") |
| 118 | + except RedisError: |
| 119 | + visits = "<i>cannot connect to Redis, counter disabled</i>" |
| 120 | +
|
| 121 | + html = "<h3>Hello {name}!</h3>" \ |
| 122 | + "<b>Hostname:</b> {hostname}<br/>" \ |
| 123 | + "<b>Visits:</b> {visits}" |
| 124 | + return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) |
| 125 | +
|
| 126 | +if __name__ == "__main__": |
| 127 | + app.run(host='0.0.0.0', port=80) |
| 128 | +``` |
| 129 | + |
| 130 | +(4)构建应用 |
| 131 | + |
| 132 | +创建一个 Docker 镜像,执行命令: |
| 133 | + |
| 134 | +```sh |
| 135 | +docker build -t friendlyhello . |
| 136 | +``` |
| 137 | + |
| 138 | +查看 Docker 镜像,执行命令: |
| 139 | + |
| 140 | +```sh |
| 141 | +$ docker image ls |
| 142 | + |
| 143 | +REPOSITORY TAG IMAGE ID |
| 144 | +friendlyhello latest 326387cea398 |
| 145 | +``` |
| 146 | + |
| 147 | +(5)运行 app |
| 148 | + |
| 149 | +使用 `-p` 将您的机器的端口4000映射到容器的已发布端口80 |
| 150 | + |
| 151 | +```sh |
| 152 | +docker run -d -p 4000:80 friendlyhello |
| 153 | +``` |
| 154 | + |
| 155 | +然后,可以访问 http://localhost:4000 |
| 156 | + |
| 157 | +### 共享镜像 |
| 158 | + |
| 159 | +(1)注册登录 |
| 160 | + |
| 161 | +在 [cloud.docker.com](https://cloud.docker.com/) 注册账户,然后使用 Docker ID 登录。 |
| 162 | + |
| 163 | +```sh |
| 164 | +docker login |
| 165 | +``` |
| 166 | + |
| 167 | +> 注册 Docker ID ,要访问 google ,国内无法访问。要命。 |
| 168 | +
|
| 169 | +(2)给镜像打标签 |
| 170 | + |
| 171 | +``` |
| 172 | +docker tag image username/repository:tag |
| 173 | +``` |
| 174 | + |
| 175 | +例: |
| 176 | + |
| 177 | +``` |
| 178 | +docker tag friendlyhello john/get-started:part2 |
| 179 | +``` |
| 180 | + |
| 181 | +(3)发布镜像 |
| 182 | + |
| 183 | +``` |
| 184 | +docker push username/repository:tag |
| 185 | +``` |
| 186 | + |
| 187 | +(4)从远程仓库拉取并运行镜像 |
| 188 | + |
| 189 | +``` |
| 190 | +docker run -p 4000:80 username/repository:tag |
| 191 | +``` |
| 192 | + |
| 193 | +## Services |
| 194 | + |
| 195 | +## Swarms |
| 196 | + |
| 197 | +## Stacks |
| 198 | + |
| 199 | +## Deploy |
| 200 | + |
| 201 | +## 常用命令行 |
| 202 | + |
| 203 | +```sh |
| 204 | +docker # 列出所有 Docker 命令 |
| 205 | + |
| 206 | +docker version # 显示 docker 版本 |
| 207 | +docker info # 显示 docker 信息 |
| 208 | + |
| 209 | +docker build -t friendlyhello . # 使用当前目录下的 Dockerfile 创建 Docker 镜像 |
| 210 | +docker run -p 4000:80 friendlyhello # 运行 "friendlyname" ,并映射端口 4000 到 80 |
| 211 | +docker run -d -p 4000:80 friendlyhello # 同样的事,但是使用分离的模式 |
| 212 | + |
| 213 | +docker container --help # 列出 docker container 相关命令 |
| 214 | +docker container ls # 列出所有运行的容器 |
| 215 | +docker container ls -a # 列出所有的容器 |
| 216 | +docker container stop <hash> # 优雅的停止所有指定的容器 |
| 217 | +docker container kill <hash> # 强制停止所有指定的容器 |
| 218 | +docker container rm <hash> # 从本机中溢出指定的容器 |
| 219 | +docker container rm $(docker container ls -a -q) # 移除所有容器 |
| 220 | + |
| 221 | +docker image --help # 列出 docker image 相关命令 |
| 222 | +docker image ls -a # 列出本机中所有的镜像 |
| 223 | +docker image rm <image id> # 从本机中溢出指定的镜像 |
| 224 | +docker image rm $(docker image ls -a -q) # 移除本机中所有镜像 |
| 225 | +docker login # 使用您的 Docker ID 登录以从 Docker Hub push 和 pull 图像。 |
| 226 | +docker tag <image> username/repository:tag # 标记 <image> 以上传到注册中心 |
| 227 | +docker push username/repository:tag # 上传标记过的镜像到注册中心 |
| 228 | +docker run username/repository:tag # 运行一个注册中心上的镜像 |
| 229 | +``` |
0 commit comments