内容简介:容器管理工具为了提高官方镜像拉取速度,我们使用阿里云提供的镜像加速器。
容器管理工具 docker
的出现使开发及运行环境的配置变得更加便利,服务器运维更高效,也成为了后端工程师必须要掌握的效率工具,我们在这里总结一下它的具体使用,关于 Linux
下安装 docker
相关请看前面一篇: CentOS7安装 Docker 配置服务端和容器自启动 ,这里我们将详细介绍 docker
的使用, dockerfile
的编写规则和实例, docker-compose
工具的使用和实例,基本上想学会 docker
,看这一篇就够了。
Docker基本操作
镜像操作
配置阿里云镜像加速器
为了提高官方镜像拉取速度,我们使用阿里云提供的镜像加速器。
进入 容器镜像服务
=> 镜像加速器
,获取自己的 加速器地址 ,替换到下面,运行下面的命令即可。
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://*****.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
拉取镜像
比如我们要拉取 php
官方镜像,先到 hub.docker.com上找到我们想要的
php 镜像版本(tags),可以看到,这里有非常多的满足不同需求的版本镜像,我们选
7.1-fpm`,我们的拉取命令就是:
docker pull php:7.1-fpm
不指定 tag
从 hub
拉取镜像可能会报错,比如:
[root@localhost docker]# docker pull opensips/opensips Using default tag: latest Error response from daemon: manifest for opensips/opensips:latest not found
这里是因为 pull
默认使用 latest
作为镜像 tag
,但这个镜像下没有这个未指定这个 tag
,所以我们需要手动指定一个存在的 tag
拉取。
[root@localhost docker]# docker pull opensips/opensips:2.4
拉取的镜像并不总能直接满足需求,大部分时候我们需要创建自定义镜像,看下面的 Dockerfile的使用
部分。
提交镜像
第一步:在 https://hub.docker.com/
注册账户并创建仓库;
第二步: 为镜像设置 tag
;
比如我要把本地的 php 71镜像提交到仓库 hsu1943/php71:latest
:
docker tag php:7.1 hsu1943/php71:latest
第三步:推送镜像:
docker push hsu1943/php71:latest
容器操作
查看所有容器(包括已停止的)
[root@localhost /]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03861a98f878 php:7.1 "docker-php-entrypoi…" 11 days ago Up 33 minutes 0.0.0.0:9000->9000/tcp php71 d3e84fdcd630 nginx:1.14 "nginx -g 'daemon of…" 12 days ago Up 33 minutes 0.0.0.0:80->80/tcp, 0.0.0.0:443->433/tcp nginx114 0d47cf1170a8 redis:4.0 "docker-entrypoint.s…" 12 days ago Up 33 minutes 0.0.0.0:6379->6379/tcp redis4 076c3f7b2d07 mysql:5.7 "docker-entrypoint.s…" 12 days ago Up 33 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql57 24ecc15d6bda opensips/opensips:2.4 "/run.sh" 3 weeks ago Exited (137) 3 weeks ago opensips
重新启动容器,以下的 ID
指的是上面的 CONTAINER ID
或者是 NAMES
docker restart ID
关闭容器
docker stop ID
强制关闭容器
docker kill ID
删除容器
docker rm ID
查看容器日志
docker logs ID
进入容器并打开终端
docker exec -it ID /bin/bash
查询容器ip地址
docker inspect --format '{{ .NetworkSettings.IPAddress }}' ID
容器中 vi
, ipconfig
, ping
命令报错:
command not found
,由于一般镜像未安装这些工具,需要我们安装,当然也可以在自己的镜像 Dockfile
中加入。
apt-get update #vim apt-get install vim #ipconfig apt install net-tools #ping apt install iputils-ping
设置容器网络:
使用docker network进行网络相关配置
# 新建网络 [root@localhost /]# docker network create --subnet=172.18.0.0/16 mynetwork c387a6bdaf315fb156bfddea2edbe772bfa2981e55ee5f23bdbf5aa38a669903 # 查看已有网络 [root@localhost /]# docker network ls NETWORK ID NAME DRIVER SCOPE 11a662a47a82 bridge bridge local 1cde9f1dc93e host host local c387a6bdaf31 mynetwork bridge local 0d42b5bfe5e1 none null local # 查看网络连接情况 [root@localhost /]# docker network inspect mynetwork # 让容器连接到指定网络指定ip [root@localhost /]# docker network connect --ip 172.18.0.8 --alias mysql_test mynetwork containerID # 断开容器网络连接 [root@localhost /]# docker network disconnet mynetwork containerID # 移除网络,需要该网络中的容器全部断开连接才可以 [root@localhost /]# docker network rm mynetwork
运行容器:
使用 docker run
直接来运行一个基于官方镜像 mysql:5.7
的容器,根据参数说明,我们就知道如何启动一个容器了。
docker run -d -p 3306:3306 --privileged=true \ -v /home/docker/mysql/conf/my.cnf:/etc/mysql/my.cnf \ -v /home/docker/mysql/data:/var/lib/mysql \ -v /home/docker/mysql/log:/var/log/mysql \ --restart=always \ --network mynetwork --network-alias mysql \ -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7 参数说明: -d 后台运行 -p 开放端口 格式|主机端口:容器端口 --privileged 提供权限 -v 文件挂载 --restart=always 保持在线 --network mynetwork 使用自定义网络mynetwork --network-alias mysql 网络别名mysql -e MYSQL_ROOT_PASSWORD=123456 配置环境变量 --name mysql mysql:5.7 容器名称
备份 mysql
容器数据库:
docker exec mysql sh -c 'exec mysqldump --all-databases -uroot -p"123456"' > /some/path/on/your/host/all-databases.sql
从临时容器中获取配置文件
在容器构建过程中需要配置文件挂载,手上没有现成的配置文件?先跑一个临时容器,把默认的配置文件拷贝出来,然后根据自己的情况编辑好配置文件,挂载到使用的容器中去,就可以大道快速部署的目的了。
$ docker run --name tmp-nginx-container -d nginx $ docker cp tmp-nginx-container:/etc/nginx/nginx.conf /host/path/nginx.conf $ docker rm -f tmp-nginx-container # 这里使用了cp命令,在主机和容器之间拷贝文件
Dockerfile的使用
镜像库里的镜像并不能满足所有人的需求,需要根据不同的项目需要来制作自己的镜像, Dockerfile
就很方便的是我们可以以某个镜像为基础(基础镜像),制作一个完全满足自己需求的自定义镜像了供项目需要。具体 Dockerfile
的使用技巧,可以参考这里: Dockerfile reference ,这里大概总结一下常用操作和基本格式。
在这之前,先了解一下创建镜像。
docker build命令
# build命令默认上下文是当前目录 docker build # 指定生成镜像的名称以及tag,可以多次指定以生成多个 docker build -t shykes/myapp:1.0.2
docker build
的工作原理(上下文)解析, Docker
在运行时分为 Docker daemon
(服务端守护进程)和客户端工具。 Docker daemon
提供了一组 REST API
,被称为 DockerRemote API
,而如 docker
命令这样的客户端工具,则是通过这组 API
与 Docker daemon
交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker
功能,但实际上,一切都是使用的远程调用形式在服务端( Docker daemon
)完成。也因为这种 C/S
设计,让我们操作远程服务器的 Docker daemon
变得轻而易举。
当我们进行镜像构建的时候,并非所有定制都会通过 RUN
指令完成,经常会需要将一些本地文件复制进镜像,比如通过 COPY
指令、 ADD
指令等。 而 docker build
命令构建镜像,其实并非在本地构建,而是在服务端, 也就是 Docker daemon
中构建的。那么在这种客户端/服务端的架构中,如何才能让服务端获得本地文件呢?
这就引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径, docker build
命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker daemon
。这样 Docker daemon
收到这个上下文包后,展开就会获得构建镜像所需的一切文件。
# 会将上下文(context)发送给Docker daemon docker build . Sending build context to Docker daemon 6.51 MB ...
docker build
命令的上下文还可以是 git
仓库,压缩文件甚至是文本文件。更多的关于 docker build
命令相关看这里: docker build 。
千万不要在根目录之类的目录作为上下文,一般使用一个空目录,把 Dockerfile
和需要的文件放在该目录下进行创建。
在 Dockerfile
中使用一些操作(比如 COPY
)将上下文目录中的文件添加到镜像中,可以使用 .dockerignore
文件指定要忽略的目录或者文件,不知道如何编写一个 .dockerignore
文件? 传送门 。
默认会使用上下文目录下的 Dockerfile
,也可以在命令中指定它:
$ docker build -f /path/to/a/Dockerfile .
在执行 Dockerfile
前, Docker daemon
会一条条去校验其中的指令,如果有错误将会提示错误并停止执行。
Docker daemon
会一条一条的执行指令,每一条产生一个新的 层
,每一层是独立存在,所以在上一个指令中的 cd /tmp
对后面的指令没有影响,为了提高执行效率,应该尽量将同一类的指令放到一起执行,减少 层
,在执行过程中,默认会使用缓存,也就是如果之前有执行过,生成的 层镜像
和现在需要的是一样的,那就直接用缓存了。
Dockerfile格式
以 #
开头后面视为注释(除解析器指令); Dockerfile
指令不区分大小写,不过一般约定指令使用大写,与参数区分;
FROM:必须使用 FROM
指令开头,来指定基础镜像;
- 镜像可以是任意有效的镜像 – 这个很容易从公共仓库拉取一个镜像。
- FROM必须是Dockerfile中的首个非注释指令。
- FROM可以在单个Dockerfile中出现多次,这样可以创建多个镜像。只需记下在每个新的FROM命令之前由提交输出的最后一个图像ID。
- tag或digest值是可选的。如果都不指定,那么默认是latest。如果找不到tag的值将返回错误。
FROM <image> FROM <image>:<tag> FROM <image>@<digest>
MAINTAINER:设置生成这个镜像的作者。
MAINTAINER hsu1943 "88888888@qq.com"
ENV:声明环境变量,可以在其他指令中使用;
- 在
Dockerfile
引用环境变量可以使用$variable_name
或${variable_name}
。它们是等同的,其中大括号的变量是用在没有空格的变量名中的,如${foo}_bar
。 -
${variable_name}
变量也支持一些标准的bash
修饰符,如:-
${variable:-word}
表示如果variable
设置了,那么结果就是设置的值。否则设置值为word
。 -
${variable:+word}
表示如果variable
设置了,那么结果是word
值,否则为空值
-
-
word
可以是任意的字符,包括额外的环境变量。 - 转义符可以添加在变量前面:
\$foo
或者\${foo}
,例如,会分别转换为$foor
和${foo}
。
FROM busybox ENV foo /bar ENV PHP_INI_DIR /usr/local/etc/php WORKDIR ${foo} # WORKDIR /bar ADD . $foo # ADD . /bar COPY \$foo /quux # COPY $foo /quux
COPY:将上下文目录中的文件复制到docker镜像中
这个命令很直观,也很可靠,在这里大家可能会想到 ADD
命令,这个命令除了复制文件以外还会做更多(复制远程文件,可以自动解压缩),但我们还是建议直接用 COPY
就够了,降低复杂度,提高成功率。
对于目录而言, COPY
只复制目录中的内容而不包含目录自身 ,所以当你需要复制包含目录的话,应该指定目标路径目录。
COPY docker-php-source /usr/local/bin/
ENTRYPOINT和CMD:设置容器启动时要执行的命令
这两个命令功能上是很相似的,所以也很容易混淆,基本原则:
- Dockerfile中至少有一个(
ENTRYPOINT
或者CMD
),不然回会报错; - 多个
ENTRYPOINT
或多个CMD
只会执行最后一条; - 如果
ENTRYPOINT
使用了shell
模式,CMD
指令会被忽略; - 如果
ENTRYPOINT
使用了exec
模式,CMD
指定的内容被追加为ENTRYPOINT
指定命令的参数; - 如果
ENTRYPOINT
使用了exec
模式,CMD
也应该使用exec
模式。
对于 CMD
和 ENTRYPOINT
的设计而言,多数情况下它们应该是单独使用的。当然,有一个例外是 CMD
为 ENTRYPOINT
提供默认的可选参数。
如果还是不清楚,看看官方给出的这个图,大概就能理解了:
LABEL:添加关于镜像的一些信息
LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines." LABEL maintainer="SvenDowideit@home.org.au" # 代替MAINTAINER的使用,推荐
因为每一个LABEL都会生成一个新的镜像层,所以建议将LABEL放到一起,可以使用 \
换行达到目的,使用 docker inspect
可以查看镜像的 LABEL
s,对于同名(key)的情况,后面的LABEL会覆盖前面的,包括FROM指定的基础镜像中的,多个LABEL合并一起:
LABEL version="1.2.0" \ description="about lnmp" \ maintainer="SvenDowideit@home.org.au" \ other="other value"
EXPOSE:声明容器运行时应该打开的端口
这个指令告诉要运行 docker run
这个镜像的运维人员本镜像哪些端口需要映射,在 run
的之后可以通过 -p
来指定端口映射,或者用 -P
随机映射端口,随机映射会将 EXPOSE
声明过的端口映射出来。
对于在同一个 docker network
中的容器,无需打开端口他们之间就可以通过任何端口来访问彼此。
EXPOSE 9000
USER:指定执行后面RUN,CMD,ENTRYPOINT的用户(组)
使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当不需要管理员权限时,可以通过该命令指定运行用户。一般会在之前创建所需要的用户。
运行容器 docker run
时,可以通过 -u
参数来覆盖所指定的用户。
WORKDIR:指定工作目录
可以为后面的 RUN
, CMD
, ENTRYPOINT
, COPY
以及 ADD
指令指定工作目录,目录中可以解析之前使用 ENV
指定的环境变量。
ENV DIRPATH /var WORKDIR $DIRPATH/www/html echo pwd # 会输出 /var/www/html
ARG:构建参数,指定在build时可以传递过来的变量
使用 ARG
指定的变量可以在 docker build
中通过 --build-arg <varname>=<value>
的形式进行传递,这区别于 ENV
指定的环境变量,环境变量无法在 build
时传递进来。
ARG user1=someuser # 没有传递进来就使用默认值 ARG buildno=1
可以将 ARG
和 ENV
结合一起使用:
ARG var ENV var=${var}
ONBUILD:构建子镜像时在FROM之后立即执行在的任务
本镜像并不执行这个指令,而是在子镜像(下一层)中去执行。
# 父容器中Dockerfile内容 FROM busybox ONBUILD RUN echo "第二次构建(子构建)才执行" # 构建父镜像 docker build -t father . # 构建过程中不会打印"第二次构建(子构建)才执行" 创建子容器 # 子容器中Dockerfile内容 FORM father # 构建子镜像 docker build -t child . # 构架过程中打印了"第二次构建(子构建)才执行"
VOLUME:指定容器数据挂载点
指定容器中需要挂载到宿主机的挂载点,在宿主机会生成对应的目录(目录名随机)存放数据,需要注意这里跟 docker run
中可以指定宿主机目录不同, Dockerfile
中的挂载无法指定宿主机目录,这是为了保证可移植性,规定的目录并不一定在每个宿主机都存在。
VOLUME /var/log/mysql VOLUME ["/var/log/mysql", "/data2"]
更多关于 VOLUME
(共享 --volumes-from
)的知识可以参考官方文档。
Dockerfile小技巧:apt使用国内源
# Dockfile开头加一行,使用国内debian源 COPY ./sources.list /etc/apt/sources.list # 在Dockerfile同目录新建sources.list,内容: deb http://mirrors.ustc.edu.cn/debian/ stretch main non-free contrib deb http://mirrors.ustc.edu.cn/debian/ stretch-updates main non-free contrib deb http://mirrors.ustc.edu.cn/debian/ stretch-backports main non-free contrib deb-src http://mirrors.ustc.edu.cn/debian/ stretch main non-free contrib deb-src http://mirrors.ustc.edu.cn/debian/ stretch-updates main non-free contrib deb-src http://mirrors.ustc.edu.cn/debian/ stretch-backports main non-free contrib deb http://mirrors.ustc.edu.cn/debian-security/ stretch/updates main non-free contrib deb-src http://mirrors.ustc.edu.cn/debian-security/ stretch/updates main non-free contrib # 不同版本的debian修改stretch即可
Dockerfile实例:
FROM php:7.1-fpm # 使用国内源 ADD sources.list /etc/apt/ # install any custom system requirements RUN apt-get update && apt-get install -y --no-install-recommends \ libfreetype6-dev \ libjpeg-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libpng-dev \ libpq-dev \ libicu-dev \ libz-dev \ libbz2-dev \ libmemcached-dev \ libxml2-dev \ git \ && rm -rf /var/lib/apt/lists/* # Install various PHP extensions RUN docker-php-ext-configure bcmath --enable-bcmath \ && docker-php-ext-configure pcntl --enable-pcntl \ && docker-php-ext-configure pdo_mysql --with-pdo-mysql \ && docker-php-ext-configure pdo_pgsql --with-pdo-pgsql \ && docker-php-ext-configure mbstring --enable-mbstring \ && docker-php-ext-configure soap --enable-soap \ && docker-php-ext-install \ bcmath \ intl \ mbstring \ mcrypt \ mysqli \ pcntl \ pdo_mysql \ pdo_pgsql \ soap \ sockets \ zip \ iconv \ && docker-php-ext-configure gd \ --enable-gd-native-ttf \ --with-jpeg-dir=/usr/lib \ --with-freetype-dir=/usr/include/freetype2 \ && docker-php-ext-install gd \ && docker-php-ext-install opcache \ && docker-php-ext-enable opcache \ && pecl install xdebug redis \ && docker-php-ext-enable xdebug redis \ && rm -rf /tmp/pear # AST RUN git clone https://github.com/nikic/php-ast /usr/src/php/ext/ast/ \ && docker-php-ext-configure ast \ && docker-php-ext-install ast # ICU - intl requirements for Symfony 由于下载巨慢,改成直接COPY压缩包 # Debian is out of date, and Symfony expects the latest - so build from source, unless a better alternative exists(?) # RUN curl -o /tmp/icu.tar.gz -L http://download.icu-project.org/files/icu4c/63.1/icu4c-63_1-src.tgz \ COPY ./icu4c-58_2-src.tgz /tmp/icu.tar.gz RUN tar -zxf /tmp/icu.tar.gz -C /tmp \ && ( \ cd /tmp/icu/source \ && ./configure --prefix=/usr/local \ && make \ && make install \ ) \ && rm -rf /tmp/icu \ && rm /tmp/icu.tar.gz \ && docker-php-ext-configure intl --with-icu-dir=/usr/local \ && docker-php-ext-install intl # Install the php memcached extension RUN curl -L -o /tmp/memcached.tar.gz "https://github.com/php-memcached-dev/php-memcached/archive/php7.tar.gz" \ && mkdir -p memcached \ && tar -C memcached -zxvf /tmp/memcached.tar.gz --strip 1 \ && ( \ cd memcached \ && phpize \ && ./configure \ && make -j$(nproc) \ && make install \ ) \ && rm -r memcached \ && rm /tmp/memcached.tar.gz \ && docker-php-ext-enable memcached # set timezone RUN rm /etc/localtime \ && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #composer RUN curl -sS https://getcomposer.org/installer | php -- \ --install-dir=/usr/bin \ --filename=composer
这个 PHP7.1
的 Dockerfile
以官方镜像 php:7.1-fpm
为计出镜像,安装了常用的 工具 及扩展,设置时区及 composer
,开包即用,非常方便。
为了更好的理解 build
命令的上下文,看一下当前目录结构:
[root@localhost docker]# tree php7 php7 ├── Dockerfile ├── icu4c-58_2-src.tgz └── sources.list 0 directories, 3 files
docker-compose的使用
用于定义和运行多个 docker
容器的工具,为运维工作服务器的部署和自动化运维提供了极大的便利,通过一个 docker-compose.yml
命令就可以实现多个
安装docker-compose
安装
curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
添加执行权限
chmod +x /usr/local/bin/docker-compose
关于 docker-compose
的使用,以及 docker-compose.yml
文件的书写格式,见:
docker-compose.yml实例
version: '3' services: nginx: image: nginx:1.14 restart: always # 端口映射 ports: - "80:80" - "443:433" environment: - TZ=Asia/Shanghai # 依赖关系 depends_on: - "php" # 数据卷 volumes: # 映射主机./conf.d目录wwwroot目录nginx.conf文件 - $PWD/nginx/conf.d:/etc/nginx/conf.d - $PWD/wwwroot:/usr/share/nginx/html - $PWD/nginx/nginx.conf:/etc/nginx/nginx.conf - $PWD/logs/nginx:/var/log/nginx networks: - app_net # 容器名称 container_name: "nginx114" php: build: ./php7 restart: always # image指定build 上下文./php7目录下Dockerfile生成镜像的名称 image: php:7.1 # php-fpm记录日志用 cap_add: - SYS_PTRACE ports: - "9000:9000" volumes: # 网站文件目录,配置目录 - $PWD/wwwroot:/var/www/html - $PWD/php:/usr/local/etc networks: - app_net container_name: "php71" mysql: image: mysql:5.7 restart: always ports: - "3306:3306" # 环境变量 environment: # mysql密码 - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=123456 volumes: # 挂载数据库文件,配置文件 - $PWD/mysql/data:/var/lib/mysql - $PWD/mysql/conf:/etc/mysql - $PWD/logs/mysql:/var/log/mysql networks: - app_net container_name: "mysql57" redis: image: redis:4.0 restart: always # 如果不需要外网访问,使用"127.0.0.1:6379:6379"来限制 ports: - "6379:6379" environment: - TZ=Asia/Shanghai volumes: - $PWD/redis/data:/data - $PWD/redis/redis.conf:/etc/redis/redis.conf networks: - app_net container_name: "redis4" networks: # 配置docker network app_net: driver: bridge ipam: config: # 子网络 - subnet: 178.18.0.0/16
这是一个完整的 nginx + php + mysql + redis
多容器的运行环境,结合上面 php7.1
的 Dockerfile
实例只需要按需要修改挂载目录及配置文件即可运行。
以上所述就是小编给大家介绍的《docker,Dockerfile,docker-compose操作指南及最佳实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Pureftpd操作指南
- Kafka运维操作指南
- 《算法互动编程》操作指南(二)
- 自底向上的web数据操作指南
- [最全操作指南] 在线六个项目全部迁移Linux
- 使用FRIDA为Android应用进行脱壳的操作指南
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PHP Hacks
Jack Herrington D. / O'Reilly Media / 2005-12-19 / USD 29.95
Programmers love its flexibility and speed; designers love its accessibility and convenience. When it comes to creating web sites, the PHP scripting language is truly a red-hot property. In fact, PH......一起来看看 《PHP Hacks》 这本书的介绍吧!