我们下载的镜像都是官方默认的镜像,这些镜像有时无法满足我们个性化的要求,这时我们就可以自己来制作镜像。制作镜像有三种方法:

制作镜像

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
2
docker build -t test:1.0 .
#.表示当前目录

Dockerfile 详解
我们一般可以把一个Dockerfile 文件内容分为四部分
| 四部分 | 指令 |
| ——————– | —————————– |
| 基础镜像信息 | FROM (第一条指令必须是这个) |
| 维护者信息 | MAINTAINER |
| 镜像操作指令 | RUN、COPY、ADD、EXPOSE、ENV等 |
| 容器启动时执行的指令 | CMD、ENTRYPOINT |

指令说明

  • FROM:指定基础镜像
    镜像是一层一层的,最底层是操作系统,我们要制作镜像必须要先试用 FROM 来指定一个镜像,然后我们是在这个基础镜像的基础上制作新镜像的:

    1
    2
    FROM 镜像:标签
    #FROM alpine:3.8
  • MAINTAINER:指定作者名称(选填)

    1
    2
    FROM alpine:3.8
    MAINTAINER jiaobantang@126.com
  • RUN:运行 shell 命令
    在制作镜像的过程中可以使用 RUN 来执行 shell 命令。
    如:
    1、在镜像中创建/php目录
    2、为镜像安装vim 编辑器
    3、设置 apk 的国内镜像源(多个指令用 && 连接,如果指令太长可以使用 \ 写到下一行中)
    4、更新 apk 的软件

    1
    2
    3
    4
    5
    6
    7
    FROM 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、ADD 复制本地文件到镜像中

1
ADD/COPY 源目录 目标目录

ADD:该命令将复制指定的源目录到容器中的目标目录。 其中源目录可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
COPY :当使用本地目录为源目录时,推荐使用 COPY。
示例、在制作镜像时复制当前目录中的 php 目录到镜像中的 /php 目录中:

1
2
3
4
5
6
7
8
9
FROM 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
2
ENTRYPOINT ["命令", "参数1", "参数2" ...]
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
    2
    WORKDIR /php
    mkdir abc # 创建 /php/abc 目录
  • VOLUME
    创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
    格式:

    1
    VOLUME ["目录"]

指定了挂载目录之后,就可以在创建容器时使用 -v 或者 --volumes-from 来指令共享挂载这些目录。

制作带扩展的 PHP 镜像

创建 Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FROM 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
2
docker tag 镜像:标签  仓库IP:绑定端口号/镜像:标签
docker push 仓库IP:绑定端口号/镜像:标签

如:

1
2
docker tag alpine:3.8  localhost:5000/alpine:3.8
docker push 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
17
version: '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
2
3
4
docker-compose up -d   			# 创建所有容器并在后台运行
docker-compose stop # 停止所有容器
docker-compose down --volumes # 删除所有容器以及挂载的目录
docker-compose ps # 查看当前这个集群中的容器的状态

目录共享

我们在启动容器时,可以添加 --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
2
3
4
5
6
7
8
9
10
11
12
"Mounts": [
{
"Type": "volume",
"Name": "92e89eeb09791da95e9a67cc0945d531407dc5b605e818fdf2300e27d73cf5f0",
"Source": "/var/lib/docker/volumes/92e89eeb09791da95e9a67cc0945d531407dc5b605e818fdf2300e27d73cf5f0/_data",
"Destination": "/var/www/html",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],

比如:我们现在有两个容器 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] (参考自我的上课讲义)完!

 评论



本站使用 Material X 作为主题 , 总访问量为 次 。
隐藏