完成docker相关文档的阅读
This commit is contained in:
235
docker/docker guide.md
Normal file
235
docker/docker guide.md
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
- [docker guide](#docker-guide)
|
||||||
|
- [Push image to docker hub](#push-image-to-docker-hub)
|
||||||
|
- [volume mount](#volume-mount)
|
||||||
|
- [volume detail](#volume-detail)
|
||||||
|
- [bind mount](#bind-mount)
|
||||||
|
- [bind mount和volume mount区别](#bind-mount和volume-mount区别)
|
||||||
|
- [docker run -v](#docker-run--v)
|
||||||
|
- [multi container app](#multi-container-app)
|
||||||
|
- [container networking](#container-networking)
|
||||||
|
- [create network](#create-network)
|
||||||
|
- [nicolaka/netshoot](#nicolakanetshoot)
|
||||||
|
|
||||||
|
|
||||||
|
# docker guide
|
||||||
|
## Push image to docker hub
|
||||||
|
1. 通过命令`docker login -u ${username}`登录docker hub
|
||||||
|
2. 使用`docker tag`命令给镜像`getting-started`一个新的名称。需要用docker hub id替换`YOUR-USER-NAME`。
|
||||||
|
```shell
|
||||||
|
$ docker tag getting-started YOUR-USER-NAME/getting-started
|
||||||
|
```
|
||||||
|
3. 如果`git push`操作未指定tagname,那么默认会使用tag `latest`
|
||||||
|
```shell
|
||||||
|
$ docker push YOUR-USER-NAME/getting-started
|
||||||
|
```
|
||||||
|
## volume mount
|
||||||
|
在一个容器中对文件进行的操作(修改、删除、新增)在容器被删除后都会丢失,即使两个容器从同一镜像启动,一个容器的修改对另一个容器仍然不可见。
|
||||||
|
`volume`提供了将容器中文件系统指定路径连接到宿主机的功能。在容器中被挂载的目录下,对文件的修改也会同步到宿主机的路径下。如果在不同的容器启动时挂载相同的目录,那么目录下的文件将会在容器之间进行共享。
|
||||||
|
volume可以看作是一个不透明的数据桶,volume完全由docker管理,docker会管理volume在磁盘中存储的位置。用户只需要指定volume的name即可。
|
||||||
|
1. 创建docker volume:
|
||||||
|
```shell
|
||||||
|
docker volume create todo-db
|
||||||
|
```
|
||||||
|
2. 通过`--mount`选项将volume挂载到容器中。使用示例如下所示:
|
||||||
|
```shell
|
||||||
|
<!--
|
||||||
|
src指定volume的name
|
||||||
|
target指定挂载路径
|
||||||
|
-->
|
||||||
|
# docker run -dp 3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started
|
||||||
|
```
|
||||||
|
### volume detail
|
||||||
|
如果想要知道volume的详细信息,例如在宿主机中的存储位置,可以调用`docker volume inspect`命令:
|
||||||
|
```shell
|
||||||
|
$ docker volume inspect todo-db
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"CreatedAt": "2019-09-26T02:18:36Z",
|
||||||
|
"Driver": "local",
|
||||||
|
"Labels": {},
|
||||||
|
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
|
||||||
|
"Name": "todo-db",
|
||||||
|
"Options": {},
|
||||||
|
"Scope": "local"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
## bind mount
|
||||||
|
相对于volume mount,bind mount能够让同一目录在宿主机和容器之间进行共享,宿主机对于路径下文件的修改能对容器可见。
|
||||||
|
1. 执行如下命令创建bind mount,将宿主机路径挂载到容器中:
|
||||||
|
```shell
|
||||||
|
<!--
|
||||||
|
当mount type为bind时,
|
||||||
|
src为宿主机路径
|
||||||
|
target为容器的目标路径
|
||||||
|
-->
|
||||||
|
docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash
|
||||||
|
```
|
||||||
|
### bind mount和volume mount区别
|
||||||
|
对于bind mount,不管宿主机中是否由内容,宿主机路径对应的文件内容都会覆盖容器目录中的内容。
|
||||||
|
对于volume mount,如果volume中没有内容,会将容器目录下的内容复制到宿主机的volume中,如果volume中有内容,volume中内容会覆盖容器目录中的内容。
|
||||||
|
### docker run -v
|
||||||
|
`docker run -v`命令后由三部分组成,形式为`src:dest:mode`,当src为宿主机的一个路径时,使用的是bind mount,如果src为一个name时,使用的是volume mount。第三块是可选的,为读写权限,默认情况下mode为rw。
|
||||||
|
## multi container app
|
||||||
|
通常情况下,每个容器之应该做一件事情。故而,例如一个应用需要mysql,应该将mysql置于另一个容器中进行部署。
|
||||||
|
### container networking
|
||||||
|
容器在默认情况下是隔离运行的,不知道位于同一机器上的其他容器和进程。故而,容器之间通过网络进行通信。
|
||||||
|
如果多个容器需要通过network进行通信,那么需要将多个容器放置到同一个network中。
|
||||||
|
### create network
|
||||||
|
可以通过如下命令创建一个网络:
|
||||||
|
```shell
|
||||||
|
$ docker network create todo-app
|
||||||
|
```
|
||||||
|
如下命令会启动一个mysql容器并且将其添加到todo-app的网络中:
|
||||||
|
```shell
|
||||||
|
$ docker run -d \
|
||||||
|
--network todo-app --network-alias mysql \
|
||||||
|
-v todo-mysql-data:/var/lib/mysql \
|
||||||
|
-e MYSQL_ROOT_PASSWORD=secret \
|
||||||
|
-e MYSQL_DATABASE=todos \
|
||||||
|
mysql:8.0
|
||||||
|
```
|
||||||
|
`--network todo-app`选项会将mysql容器添加到`todo-app`网络中,而`--network-alias mysql`则会创建一条dns `mysql`,该条dns指向mysql容器的ip地址。
|
||||||
|
> 在上述指令中,并没有调用`docker volume create`命令来创建volume,docker知道我们要使用命名好的volume并会为我们自动创建。
|
||||||
|
### nicolaka/netshoot
|
||||||
|
nicolaka/netshoot容器中集成了很多网络工具,在解决网络问题时会很有用。
|
||||||
|
1. 将netshoot容器添加到指定网络中:
|
||||||
|
```shell
|
||||||
|
$ docker run -it --network todo-app nicolaka/netshoot
|
||||||
|
```
|
||||||
|
2. 在netshoot容器中使用dig命令,dig是很有用的DNS工具:
|
||||||
|
```shell
|
||||||
|
$ dig mysql
|
||||||
|
```
|
||||||
|
dig命令输出如下:
|
||||||
|
```shell
|
||||||
|
; <<>> DiG 9.18.8 <<>> mysql
|
||||||
|
;; global options: +cmd
|
||||||
|
;; Got answer:
|
||||||
|
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32162
|
||||||
|
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
|
||||||
|
|
||||||
|
;; QUESTION SECTION:
|
||||||
|
;mysql. IN A
|
||||||
|
|
||||||
|
;; ANSWER SECTION:
|
||||||
|
mysql. 600 IN A 172.23.0.2
|
||||||
|
|
||||||
|
;; Query time: 0 msec
|
||||||
|
;; SERVER: 127.0.0.11#53(127.0.0.11)
|
||||||
|
;; WHEN: Tue Oct 01 23:47:24 UTC 2019
|
||||||
|
;; MSG SIZE rcvd: 44
|
||||||
|
```
|
||||||
|
其中ANSWER SECTION输出了network-alias mysql对应的ip地址。
|
||||||
|
> mysql并不是一个有效的域名,但是docker能将该network-alias解析为对应容器的ip地址
|
||||||
|
## docker compose
|
||||||
|
docker compose是用于定义和共享多容器应用的工具。通过compose,可以通过一个yaml文件来定义应用服务,并且通过单行命令启动和停止多容器应用服务。
|
||||||
|
### 创建compose file
|
||||||
|
1. 定义container的service条目和对应image,我们可以为service指定任何名称。该指定的名称会自动成为network-alias
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: node:18-alpine
|
||||||
|
```
|
||||||
|
2. 在为service定义name和image之后,可以为service指定command
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: node:18-alpine
|
||||||
|
command: sh -c "yarn install && yarn run dev"
|
||||||
|
```
|
||||||
|
3. 为service指定ports:
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: node:18-alpine
|
||||||
|
command: sh -c "yarn install && yarn run dev"
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
```
|
||||||
|
4. 为service设置workdir或挂载卷时,通过如下方式进行:
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: node:18-alpine
|
||||||
|
command: sh -c "yarn install && yarn run dev"
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
working_dir: /app
|
||||||
|
volumes:
|
||||||
|
- ./:/app
|
||||||
|
```
|
||||||
|
5. 如果需要为service指定环境变量,如果如下方式进行配置:
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: node:18-alpine
|
||||||
|
command: sh -c "yarn install && yarn run dev"
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
working_dir: /app
|
||||||
|
volumes:
|
||||||
|
- ./:/app
|
||||||
|
environment:
|
||||||
|
MYSQL_HOST: mysql
|
||||||
|
MYSQL_USER: root
|
||||||
|
MYSQL_PASSWORD: secret
|
||||||
|
MYSQL_DB: todos
|
||||||
|
```
|
||||||
|
6. 在docker run时,通过-v选项指定的volume name不存在,那么volume会自动被创建,但是在compose file中,通过volumes指定的volume name并不会被自动创建。想要创建volume,必须yml文件的顶层`volumes:`中指定volume 。
|
||||||
|
通常情况下,只用指定`volume-name:`即可,会使用默认的选项。
|
||||||
|
示例如下所示:
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
# The app service definition
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
volumes:
|
||||||
|
- todo-mysql-data:/var/lib/mysql
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
todo-mysql-data:
|
||||||
|
```
|
||||||
|
7. 最终,整合两个docker container的应用yml文件配置如下所示:
|
||||||
|
```yml
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: node:18-alpine
|
||||||
|
command: sh -c "yarn install && yarn run dev"
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
working_dir: /app
|
||||||
|
volumes:
|
||||||
|
- ./:/app
|
||||||
|
environment:
|
||||||
|
MYSQL_HOST: mysql
|
||||||
|
MYSQL_USER: root
|
||||||
|
MYSQL_PASSWORD: secret
|
||||||
|
MYSQL_DB: todos
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
volumes:
|
||||||
|
- todo-mysql-data:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: secret
|
||||||
|
MYSQL_DATABASE: todos
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
todo-mysql-data:
|
||||||
|
```
|
||||||
|
### run application stack
|
||||||
|
可以通过`docker compose up`命令来启动application stack。可以通过添加-d选项在后台运行:
|
||||||
|
```shell
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
**默认情况下,docker compose会自动为compose文件中的application stack创建一个network。**
|
||||||
|
如果想要停止application stack,可以调用`docker compose down`命令。
|
||||||
|
> 默认情况下,docker compose down并不会移除创建的volume,如果想要移除volume,可以指定选项--volumes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user