index
# docker
# 1. docker 介绍
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。
Docker 官网 (opens new window) Docker 文档 (opens new window) Github Docker 源码 (opens new window)
# 1.1 docker 的应用场景
- Web 应用的自动打包和发布
- 自动化测试和持续集成、发布
- 在服务型环境中部署和调整数据库或其他的后台应用
# 1.2 docker 优点
Docker 是一个用于开发,交付和运行应用程序的开放平台。Docker 使您能够将应用程序和基础架构分开,从而可以快速交付软件。借助 Docker,可以与管理应用程序相同的方式管理基础架构。通过利用 Docker 的方法来快速交付、测试和部署代码,可以大大减少编写代码和在生产环境中运行代码之间的延迟
- 快速、一致地交付应用程序
- 响应式部署和扩展,docker 是基于容器的平台,有高度的可移植性和轻量级的特性
- 基于虚拟机的管理提供了可行、经济、高效的解决方案,Docker 非常适合于高密度环境以及中小型快速部署
# 1.3 主要概念
- Docker Images,镜像,用于创建 Docker 容器的模板
- Docker Container,容器,是独立运行的一个或一组应用,是镜像运行的实体
- Docker Client,客户端,通过命令行或其他工具与守护进程通信
- Docker Host,主机,一个物理或者虚拟的机器用于执行 Docker 守护进程和容器
- Docker Registry,镜像仓库,Docker Hub 提供了庞大的镜像集合
- Docker Machine,命令行工具
# 2. 应用
- hello world 测试
docker --version #查看版本信息
docker run hello-world #运行hello-world镜像
2
- 启动 docker web 服务器
$ docker run --detach --publish=80:80 --name=webserver nginx
docker run --publish=3306:3306 --name=local_mysql -e MYSQL_ROOT_PASSWORD=123123 -d mysql:8.0
2
3
- --detach 后台运行容器
- --publish 要求 Docker 将主机端口 80 上传入的流量转发到容器的 80 端口,容器具有自己的端口集
- --name 给 启动后可以在 web 浏览器中查看,输入地址 http://localhost/
- 在 web 服务器运行时,查看容器上的详细信息
docker container ls
docker ps
2
- 使用以下命令停止并删除容器和镜像,使用all标志(--all 或-a)查看停止的容器
$ docker container ls
$ docker container stop webserver
$ docker container ls -a
$ docker container rm webserver
$ docker image ls
$ docker images
$ docker image rm nginx
$ docker rm --force webserver # --force 可用来删除正在运行的容器
$ docker container start webserber # 重新启动容器
$ docker exec -it mydocker /bin/bash # 在容器内启动bash
2
3
4
5
6
7
8
9
10
11
12
- 其他命令
docker build -t friendlyhello . # Create image using this directory's Dockerfile
docker run -p 4000:80 friendlyhello # Run "friendlyname" mapping port 4000 to 80
docker run -d -p 4000:80 friendlyhello # Same thing, but in detached mode
docker container ls # List all running containers
docker container ls -a # List all containers, even those not running
docker container stop <hash> # Gracefully stop the specified container
docker container kill <hash> # Force shutdown of the specified container
docker container rm <hash> # Remove specified container from this machine
docker container rm $(docker container ls -a -q) # Remove all containers
docker image ls -a # List all images on this machine
docker image rm <image id> # Remove specified image from this machine
docker image rm $(docker image ls -a -q) # Remove all images from this machine
docker login # Log in this CLI session using your Docker credentials
docker tag <image> username/repository:tag # Tag <image> for upload to registry
docker push username/repository:tag # Upload tagged image to registry
docker run username/repository:tag # Run image from a registry
docker search python
docker history python:latest #Show the history of an image
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 命令实例
目录挂载,如下例:将宿主机目录./data 挂载到容器目录.../some_folder/.
docker run -v ./data:/container_name/some_folder/ image_name
指定工作目录:使用-w 参数,指定容器的工作目录为 /data
docker -w /data
# 3. 创建镜像
在 Docker 中创建镜像,最常用的方式就是使用 Dockerfile。Dockerfile 是一个 Docker 镜像的描述文件,其中包含了一条条指令,每一条指令构建一层,描述该层应当如何构建
看一个 Dockerfile 的例子
# 基于centos镜像
FROM centos
# 维护人的信息
MAINTAINER the centos project <hello@qq.com>
# 安装httpd软件包
RUN yum -y update
RUN yum -y install httpd
# 开启80端口
EXPOSE 80
# 复制网站首页文件至镜像中web站点下
ADD index.html /var/www/html/index.html
# 复制该节本至镜像中,并修改其权限
ADD run.sh /run.sh
RUN chmod 775 /run.sh
# 当启动容器时执行脚本
CMD ["/run.sh"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
从示例可以看出 Dockerfile 结构大致可以分为四部分:
- 基础镜像信息
- 维护者信息
- 镜像操作执行
- 容器启动时执行指令 Dockerfile 每行支持一条指令,每条指令可带多个参数,支持以#开头的注释
# 在当前路径构建docker
docker build -f mydockerfile -t mycentos:0.1 .
2
Dockerfile 语法
| 关键字 | 示例 | 说明 |
|---|---|---|
| FROM | FROM centos:6 | 基于 centos 镜像,并指定版本信息 |
| MAINTAINER | MAINTAINER the centos project hello@qq.com | 说明维护者信息 |
| LABEL | LABEL maintainer="hello@qq.com" | 说明维护者信息(推荐使用语法) |
| RUN | RUN chmod 775 /run.sh RUN ["chmod", "775", "/run.sh"] | 用于执行命令 |
| COPY | COPY ./start.sh /start/sh | 拷贝文件或目录到镜像中 |
| ADD | ADD run.sh /run.sh ADD html.tar.gz /var/www/html ADD https://xxx.com/html.tar.gz /var/www/html | 拷贝文件或目录到镜像中,如果是 URL 或压缩包会自动下载或解压 |
| WORKDIR | WORKDIR /data | 为 RUN、CMD、ENTRYPOIN 以及 COPY 和 AND 设置工作目录,相当于 cd |
| VOLUME | VOLUME ["/var/lib/mysql"] | 指定容器挂载到宿主机的目录或其它容器 |
| EXPOSE | EXPOSE 80 443 | 打开指定端口,端口暴露给其他容器,不会暴露给主机 |
| ENV | ENV MYSQL_ROOT_PASSWORD 123456 | 设置环境变量 |
| CMD | CMD ["sh","/run.sh"] CMD sh /run.sh | 指定容器启动后要执行的命令这里执行sh /run.sh |
| ENTRYPOINT | ENTRYPOINT /bin/bash -C '/start.sh' | 启动容器时执行,与 CMD 类似。只是由 ENTRYPOINT 启动的程序不会被 docker run 命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给 ENTRYPOINT 指定指定的程序 |
| USER | USER user1 | 指定运行 shell 脚本的用户 |
| HEALTHCHECK | HEALTHCHECK --interval=5m \ --timeout=3s --retries=3 \ CMD curl -f http::/localhost/ || exit 1 | 告诉 Docker 如何测试容器以检查它是否正常 --interval 设置运行时间间隔 --timeout 服务响应超时时长 --start-period 服务启动多久后开始探测 --retries 认为检测失败几次为宕机 0: 容器健康,随时可以使用; 1:不健康的容器无法使用; 2:保留不使用此容器,退出代码。 |
| ARG | FROM centos:6 ARG user USER $user docker build --build-arg user=tony Dockerfile | 在构建镜像时指定一些参数 |
# 4. docker-compose
Compose 是用于定义和运行多 Docker 容器应用程序的工具。通过 Compose 可以使用 YAML 文件来配置应用程序的服务。然后,使用一个命令,就可以从配置中创建并启动所有服务。Compose 可在所有环境中工作:生产,登台,开发,测试以及 CI 工作流。文档 https://docs.docker.com/compose/
使用 Compose 基本上可分为三个步骤:
- 通过 Dockerfile 定义应用环境,以便于重复应用
- 编写 docker-compose.yml 定义应用程序的服务,以便在隔离环境中一起运行
- 运行命令 docker-compose up,启动 Compose
下面是一个 docker-compose.yml 配置文件
version: '2.0'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- Links: 将制定容器连接到当前连接,可以设置别名,避免 ip 方式导致的同期重启动态改变的情况无法连接
- volumes:挂载制定目录到磁盘目录,语法是这样的:docker_dir:local_dir
其他命令可使用 docker-compose help 查看。启动 Compose 时可以使用
# 5. YML(YAML)文件语法格式
基本语法:使用空格索引控制层级关系,只要左侧对其,则都是统一级别,大小写敏感。 值的写法: 字面量值:数字、字符串、布尔值,字符串不用加引号,但 true 会认为是布尔值,而不是字符串 对象:建:值。例
person:
name: boot
age: 18
# 或使用行内写法,注释使用 # 开头
person:{name: boot, age:18}
2
3
4
5
数组:
animal:
-cat
-dog
-pig
# 或
animal:[cat, dog, pig]
2
3
4
5
6