学习主要基于RUNOOB的教程进行学习记录
docker源码地址:https://github.com/docker/docker-ce
一、Docker 简介
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
1. 应用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
2. 架构
- 镜像(Image):Docker的镜像,相当于是一个root文件系统
- 容器(Container):镜像类似于面向对象程序设计中的类,容器即为实体。镜像是静态的定义,容器事镜像运行时的实体。容器可以被创建,启动,停止,删除和暂停
- 仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 **<仓库名>:<标签>** 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 **latest** 作为默认标签。标签>仓库名> |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
二、安装
1. Mac 安装
1
brew cask install docker
或者下载docker安装包
1
docker --version #查看docker当前版本
2. 镜像加速
使用网易的镜像加速
1
http://hub-mirror.c.163.com
在任务栏点击 Docker for mac 应用图标 -> Perferences… -> Daemon -> Registry mirrors。在列表中填写加速器地址即可。修改完成之后,点击 Apply & Restart 按钮,Docker 就会重启并应用配置的镜像地址了。
三、容器使用
1. hello world
1
docker run ubuntu:15.10 /bin/echo "Hello World"
-
docker: Docker的二进制执行文件
- run:与docker组合,表示运行一个容器
- ubuntu:15.10:执行要运行的镜像,docker先在本地主机上查找镜像是否存在,若不存在,docker从镜像仓库Docker Hub下载公共镜像
- /bin/echo “Hello World”:在启动的容器中执行的命令
2. 交互式容器
1
docker run -i -t ubuntu:15.10 /bin/bash
- t:在新容器中制定一个终端
- i:允许你对容器内的标准输入进行交互
运行后,我们即进入到一个ubuntu的容器系统中,使用exit / ctrl + D退出当前容器,回到主机
3. 后台方式启动容器
1
2
docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63
- d:后台方式打开容器
- 返回的长串字符是容器ID
1
2
3
docker ps # 查看当前容器状态
docker logs container id / container name #查看容器内的标准输出
docker stop container id / container name #停止容器
4. 容器基本使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker pull ubuntu # 载入ubuntu镜像
docker run -it ubuntu /bin/bash # 以命令行模式进入容器,/bin/bash实现交互式shell
docker stop/restart # 停止/重启容器
docker run -itd --name ubuntu-test ubuntu /bin/bash #后台方式打开容器
docker attach containerid #打开的容器,退出时容器停止运行
docker exec -it containerid #打开的容器,退出时容器不停止运行
docker export container id > name.tar #导出本地容器
cat docker/name.tar | docker import - test/ubuntu:v1 #从容器快照文件中再导入为镜像
docker import http://example.com/exampleimage.tgz example/imagerepo #制定url导入镜像
docker rm -f container id #删除容器
5. 运行Web应用
1
2
docker pull training/webapp #载入镜像
docker run -d -P serveraddress:portid:portid training/webapp python app. py
- -P:将容器内部使用的网络端口映射到我们使用的主机上。
通过192.168.239.130:portid,访问Web应用
1
2
3
4
5
6
7
docker port container id / container name #查看指定容器的端口映射
docker logs -f container id # 容器内的标准输出
docker top container #容器内部运行的进程
docker insepect #查看docker的底层信息,返回一个json文件记录docker的配置和状态信息
四、镜像使用
1
docker images #列出本地主机上的镜像
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签,表示版本
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
1
2
3
docker search name #搜索镜像,也可以使用Docker Hub
docker rmi imagename #删除镜像
1. 更新已有镜像
1
2
3
4
5
apt-get update #在运行的容器中执行,更新镜像
exit #退出
docker commit -m="" -a="" containerid targetImgaename #用某一个容器创建镜像,m为提交信息,a为作者
2. 构建镜像
使用docker build创建一个新的镜像。需要创建一个Dockerfile文件,包含指令来告诉Docker如何构建镜像
1
2
3
4
5
6
7
8
9
10
11
runoob@runoob:~$ cat Dockerfile
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
1
docker build -t runoob/centos:6.7 .
- -t :指定要创建的目标镜像名
- . :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
使用docker tag命令,为镜像增加一个新的标签
1
docker tag 860c279d2fec runoob/centos:dev
五、Dockerfile
Dockerfile是一个用来构建镜像的文本文件,包含了构建镜像所需的指令和说明
1. dockerfile文件介绍
1
2
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
- From:定制的镜像都是基于From的镜像,此处以nginx作为基础镜像,后续操作都是基于nginx
- Run:用于执行后面跟着的命令行命令,可以使用shell格式/exec格式
1
2
3
4
5
6
7
8
shell 格式
Run <命令行命令>
exec 格式
RUN ["可执行文件", "参数1", "参数2"]
RUN ["./test.php", "dev", "offline"]
RUN ./test.php dev offline
注意:Dockerfile的指令每执行一次都会在docker上新建一层,因此要避免过多无意义的层
1
2
3
4
FROM centos
RUN yum install wget \
&& wget -0 redis.tar.gz "https://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
2. 构建过程
在完成Dockerfile文件编写后,将当前目录移至Dockerfile所在的目录
1
docker build -t nginx:test . #nginx是镜像名,test是标签
最后一个 .代表上下文路径。由于我们在构建镜像时,有使用本机文件的需求。因此,在构建时,本机将路径下的所有文件发送给docker引擎,由docker引擎完成构建
3. 指令介绍
3.1 COPY
复制指令,从上下文目录中复制文件或者目录到容器的指定路径
1
2
COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
[–chown=:]:可选参数,用户改变复制到容器内文件的拥有者和属组。
**<源路径>**:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。例如:源路径>
1
2
COPY hom* /mydir/
COPY hom?.txt /mydir/
**<目标路径>**:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。目标路径>
3.2 CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行。
- RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
格式:
1
2
3
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。
3.3 ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
格式:
1
2
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用:
1
2
3
4
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
3.4 ARG
构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 –build-arg <参数名>=<值> 来覆盖。值>参数名>
格式:
1
ARG <参数名>[=<默认值>]
3.5 VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
- 避免重要的数据,因容器重启而丢失,这是非常致命的。
- 避免容器不断变大。
格式:
1
2
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
3.6 EXPOSE
仅仅只是声明端口。
作用:
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
- 在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
格式:
1
EXPOSE <端口1> [<端口2>...]
3.7 WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
格式:
1
WORKDIR <工作目录路径>
3.8 USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
1
USER <用户名>[:<用户组>]
3.9 HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
格式:
1
2
3
4
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令
HEALTHCHECK [选项] CMD <命令> : 这边 CMD 后面跟随的命令使用,可以参考 CMD 的用法。
3.10 ONBUILD
用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。
格式:
1
ONBUILD <其它指令>
六、Docker Compose
Compose是用于定义和运行多容器Docker应用程序的工具。通过Compose,使用YML文件配置应用程序需要的所有服务。
- 使用Dockerfile定义应用程序的环境
- 使用docker-compose.yml定义构成应用程序的服务,使其可以在隔离环境中一起运行
- 执行docker-compose up 命令来启动并运行整个应用程序
1. 安装
linux安装:https://www.runoob.com/docker/docker-compose.html
macOS/windows安装:安装桌面版Docker Toolbox已自带
2.
七、各容器使用实例
1.Mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 拉取特定版本的mysql
docker pull mysql:versionid
# 以mysqlimage为镜像,创建名为containerName的mysql容器,mysql密码为admin
docker run --name containerName -e MYSQL_ROOT_PASSWORD=admin -d -p 3306:3306 mysqlimgae
# 将需要导入的sql脚本复制进容器中
docker cp sourcePath/fileName containerName:targetPath/fileName
# 以后台运行不退出方式进入容器
docker exec -it containerName bash
# 输入密码进入mysql
mysql -u root -p
# 创建数据库
create database
# 使用创建的数据库
use database
# 导入脚本
source targetPath/fileName
2. RabbitMQ
1
2
3
4
5
# -d 以后台方式打开, --hostnanme 指定hostname, --name指定name
# RABBITMQ_DEFAULT_USER创建用户为root,RABBITMQ_DEFAULT_PASS密码为admin,-p 将mq端口号映射到本地
docker run -d --hostname my-rabbit --name myrabbit -e RABBITMQ_DEFAULT_USER=root -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 rabbitmq:management
# 浏览器访问暴露的端口
localhost:15672
3.elastic search
1
2
3
4
5
6
7
docker run -p 9200:9200 -p 9300:9300 -d --name es_643 elasticsearch:6.4.3
# 进入elastic search
docker exec -it es_643 /bin/bash
# 下载版本对应的分词器
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.3/elasticsearch-analysis-ik-6.4.3.zip
4.redis
1
2
3
4
5
docker pull redis:latest
docker run -itd --name myredis -p 6379:6379 redis
docker exec -it redis-test /bin/bash