我们下载的镜像都是官方默认的镜像,这些镜像有时无法满足我们个性化的要求,这时我们就可以自己来制作镜像。制作镜像有三种方法:
制作镜像
1、使用docker commit
方法
优点: 方便,一个指令(把一个现有的容器制作成一个镜像)
缺点:没有记录制作的过程
2、使用Dockerfile + docker build
指令
3、本地文件系统导入模板
docker commit
我们可以直接使用docker commit
指令将一个容器制作成一个镜像:
1 | docker commit 容器名称 镜像名称:标签 |
dockerfile
使用Dockerfile 文件制作镜像的过程:
1、编写Dockerfile文件
2、执行docker build
指令生成镜像1
docker build -t 镜像名称:标签 Dockerfile文件所在目录
示例:1
2docker build -t test:1.0 .
#.表示当前目录
Dockerfile 详解
我们一般可以把一个Dockerfile 文件内容分为四部分
| 四部分 | 指令 |
| ——————– | —————————– |
| 基础镜像信息 | FROM (第一条指令必须是这个) |
| 维护者信息 | MAINTAINER |
| 镜像操作指令 | RUN、COPY、ADD、EXPOSE、ENV等 |
| 容器启动时执行的指令 | CMD、ENTRYPOINT |
指令说明
FROM:指定基础镜像
镜像是一层一层的,最底层是操作系统,我们要制作镜像必须要先试用 FROM 来指定一个镜像,然后我们是在这个基础镜像的基础上制作新镜像的:1
2FROM 镜像:标签
#FROM alpine:3.8MAINTAINER:指定作者名称(选填)
1
2FROM alpine:3.8
MAINTAINER jiaobantang@126.comRUN:运行 shell 命令
在制作镜像的过程中可以使用 RUN 来执行 shell 命令。
如:
1、在镜像中创建/php目录
2、为镜像安装vim 编辑器
3、设置 apk 的国内镜像源(多个指令用 && 连接,如果指令太长可以使用 \ 写到下一行中)
4、更新 apk 的软件1
2
3
4
5
6
7FROM alpine:3.8
MAINTAINER jiaobantang@126.com
RUN mkdir /php
RUN apk add vim
RUN echo http://mirrors.ustc.edu.cn/alpine/v3.8/main > /etc/apk/repositories && \
echo http://mirrors.ustc.edu.cn/alpine/v3.8/community >> /etc/apk/repositories
RUN apk update && apk upgradeCOPY、ADD 复制本地文件到镜像中
1 | ADD/COPY 源目录 目标目录 |
ADD:该命令将复制指定的源目录到容器中的目标目录。 其中源目录可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
COPY :当使用本地目录为源目录时,推荐使用 COPY。
示例、在制作镜像时复制当前目录中的 php 目录到镜像中的 /php 目录中:1
2
3
4
5
6
7
8
9FROM alpine:3.8
MAINTAINER jiaobantang@126.com
RUN mkdir /php
RUN apk add vim
RUN echo http://mirrors.ustc.edu.cn/alpine/v3.8/main > /etc/apk/repositories && \
echo http://mirrors.ustc.edu.cn/alpine/v3.8/community >> /etc/apk/repositories
RUN apk update && apk upgrade
COPY php /php
ENV :设置环境变量。
可以使用 ENV 来设置镜像中的环境变量。1
ENV <key> <value>
EXPOSE:暴露端口
1
EXPOSE <port> [<port>...]
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。1
EXPORT 80 800 880
- ENTRYPOINT
容器在启动时执行的命令,一个 Dockerfile 中只能有一个 ENTRYPOINT 指令,如果写了多个,那么只有最后一个会执行。
语法有两种:
1 | ENTRYPOINT ["命令", "参数1", "参数2" ...] |
示例:在启动容器时,输出 ‘hello’
1 | ENTRYPOINT ["echo", "hello"] |
- CMD
容器在启动时执行的命令,一个 Dockerfile 中只能有一个 CMD 指令,如果写了多个,那么只有最后一个会执行。
CMD 与 ENTRYPOINT 的不同:
1、CMD 设置的命令可以被 docker run
时指令的要执行的命令覆盖,而 ENTRYPOINT 的命令不会被覆盖。
2、CMD 和 ENTRYPOINT 同时存在时,CMD 中的内容会变成 ENTRYPOINT 中指令命令的默认参数,该参数可以被 docker run
时设置的命令覆盖。
WORKDIR
指定当前的工作目录。
比如下面指令先切换到了 /php 目录中,之后执行的指令都是在这个目录下的操作(相对于cd /php
)1
2WORKDIR /php
mkdir abc # 创建 /php/abc 目录VOLUME
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
格式:1
VOLUME ["目录"]
指定了挂载目录之后,就可以在创建容器时使用 -v
或者 --volumes-from
来指令共享挂载这些目录。
制作带扩展的 PHP 镜像
创建 Dockerfile1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21FROM php:7.2-fpm-alpine
MAINTAINER "jiaobantang@126.com"
#使用国内 apk 源
RUN echo http://mirrors.ustc.edu.cn/alpine/v3.8/main > /etc/apk/repositories && \
echo http://mirrors.ustc.edu.cn/alpine/v3.8/community >> /etc/apk/repositories && \
apk update && apk upgrade
# 安装依赖
RUN apk add libpng-dev autoconf gcc g++ make openssl-dev
##### 安装 PHP 扩展
# 安装 gd、pdo_mysql 库
RUN docker-php-ext-install gd pdo_mysql sockets pcntl zip mysqli opcache
# 更新 pecl
RUN pecl channel-update pecl.php.net
# 安装 redis 扩展
RUN echo -e "\n\n" | pecl install redis && docker-php-ext-enable redis
# 安装 yaf 扩展
RUN pecl install yaf && docker-php-ext-enable yaf
# 安装 swoole 扩展
RUN echo -e "yes\nyes\n\n\n\n\n" | pecl install swoole && docker-php-ext-enable swoole
# 安装 git composer
RUN apk add git composer
创建镜像:
1 | docker build -t 镜像名:标签 . |
上传镜像
镜像制作好之后,我们可以吧镜像上传到docker的仓库中
docker 的官方网站为注册用户提供了一个 docker 仓库,我们可以把我们自己的镜像放到 docker 官方的仓库上。
注册账号
因为需要谷歌人机验证,请自行搬梯子
登陆
有了自己的仓库之后,我们就可以把本地的镜像上传到仓库中给所有人使用。
1、首先需要先在本地登录
执行以下指令进行登录(需要输入账号、密码):
1 | docker login |
2、打标签
登录成功之后,还需要为要上传的镜像打一个标签,注意这个标签必须要以 账号/
开头:
1 | docker tag 本地镜像:标签 账号/镜像名称:标签 |
比如,我的账号是 jiaobantang ,现在我要将本地的 php:1.0 上传到仓库中,那么首先我们对这个镜像打标签:1
docker tag php:1.0 fortheday001/php:1.0
3、上传
打完标签之后,我们就可以上传了:
1 | docker push 账号/镜像:标签 |
如:
1 | docker push jiaobantang/php:1.0 |
这个指令会将镜像上传到 jiaobantang 这个仓库中。
构建私有镜像仓库
官网只可以设置一个私有仓库,多个需要RMB
可以自己搭建一个私有镜像仓库
拉了镜像
1
docker pull registry
创建容器
1 | docker run --name dockerhub -d -p 绑定端口号:5000 registry |
- 上传到私有仓库
1 | docker tag 镜像:标签 仓库IP:绑定端口号/镜像:标签 |
如:
1 | docker tag alpine:3.8 localhost:5000/alpine:3.8 |
编排
为什么要使用编排
当容器多时,一个一个的管理 太麻烦,所以我们可以使用编排,通过一个简单指令来管理多个容器。
使用流程:
1、创建 docker-compose.yml 配置文件(yaml语法)
2、使用 docker-compose
来指令管理这个集群
创建配置文件
配置文件默认使用 docker-compose.yml
做为文件名,其中使用 yaml 语法编写。
yaml 语法说明:
a. 缩近代表子选项目,如下面的 mysql 和 php 就是 services 的子选项。
b. - 代表有多个值(相当于数组),如下面的 ports 下就绑定了两个端口号(注意 - 后面要加空格 )
例子:创建一个 mysql 和一个 PHP 容器,PHP依赖于mysql:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17version: '3'
services:
mysql:
image: mysql:5.7.24
ports:
- "43306:3306"
- "55555:3306"
environment:
- MYSQL_ROOT_PASSWORD=123123
volumes:
- /data:/var/mysql/data
php:
image: fortheday001/php
depends_on:
- mysql
links:
- mysql:mysql
- version:指定使用的版本,这个要和使用的 docker 的版本对应
- services :配置要启动的容器
- mysql、php:启动的容器的名字,可以自定义
- image:启动容器需要使用的镜像
- ports:需要映射的端口号
- environment:启动容器时需要设置的环境变量
- volumes:需要挂载的硬盘
- depends_on:依赖的容器,这一项决定了容器在启动时的顺序
- links:启动容器时的连接
编排指令
创建好配置文件之后,就可以使用 docker-compose
指令来管理配置文件中配置的容器了。
注意:执行指令时必须要在配置文件的同级目录中执行。
常用的指令如下:
1 | docker-compose up -d # 创建所有容器并在后台运行 |
目录共享
我们在启动容器时,可以添加 --volumes-from
这个参数,和另一个容器共享目录。
流程:
1、先在一个容器启动时使用 -v 参数设置挂载的目录(挂载之后才允许其它容器来共享)
1 | docker run --name abc -d -v /var/www/html fortheday001/php |
-v 这里并没有指定绑定到的位置,那么它会随机绑定到一个位置上(这种不能和主机共享目录)
注意:如果绑定时不指定 绑定的位置 ,那么不能和主机共享目录,只能用来容器之间共享目录。
2、其它的容器在启动时可以使用 --volumes-from
来共享
1 | docker run --name bcd -d --volumes-from abc fortheday001/php |
扩展:可以通过 docker inspect
指令查看一个容器已经挂载的目录:
docker inspect abc 查看abc容器:
1 | "Mounts": [ |
比如:我们现在有两个容器 a 、b 现在我们希望b能够共享a中的/data目录 :
那么我们应该在启动 b 容器时添加这个参数:
1 | docker run --name b -d --volues-from a 镜像的名字.. |
这个指令就是创建 b 容器并且和 a 容器共享目录 。
思考:那么到底共享了 a 中的哪个目录 。
答:只能共享 a 容器中挂载了的目录(启动a 时使用 -v
挂载的路径 )
主机容器之间共享
如果希望容器和主机也共享目录,那么在使用 -v
参数挂载目录时要指定要挂载的主机的目录 。
这个只能在容器之间共享
1 | docker run --name abc -d -v /var/www/html fortheday001/php |
如果希望这个目录和主机也共享,那么必须要挂载到主机的目录上:
1 | docker run --name abc -d -v C:/code/html:/var/www/html fortheday001/php |
进入容器/镜像的方法
进入容器
当我们要进入一个正在运行的容器时可以使用以下这个指令:
1 | docker exec -it 容器的名称 /bin/sh |
-it :以交互的方式运行 /bin/sh 指令
进入镜像
有时我们希望进入一个还没有创建容器的镜像,这时我们可以使用下面这个指令:
1 | docker run -it --rm 镜像的名字 /bin/sh |
原理:创建一个临时的容器然后进入,退出时删除容器(–rm)
-it :以交互的方式运行 /bin/sh 指令
–rm :退出指令时删除容器
[mark] (参考自我的上课讲义)完!