Return to site

Docker 实战之入门以及 Dockerfile (二)

本文内容,由【 Docker 实训课程】第一讲视频翻译整理而成

作者介绍:

张春源,目前任职 cSphere。国内最早期的 Docker 实践者,在生产环境拥有一年多的 Docker 容器管理经历。深刻理解 Docker 对于开发、测试以及运维的价值。擅长利用Docker 构建整个 DevOps 自动化平台。热爱专研 Dockerfile 这门艺术,并对 CoreOS 有深入研究。

如何构建 Docker 中间件镜像

Docker 实战准备

主要包括如下四步:

  1. 首先登陆 OSChina Git ;
  2. 将 docker-training 项目 Fork 到自己的仓库;
  3. 使用自己熟悉的 SSH 工具连接到服务器;
  4. 执行 git clone https://git.oschina.net/*YOURNAME*/docker-training.git,将你的远程仓库 clone 到服务器。
构建 csphere/php-fpm:5.4 镜像
# cd docker-training/php-fpm/ # ls Dockerfile nginx_nginx.conf supervisor_nginx.conf nginx_default.conf php_www.conf supervisor_php-fpm.conf

各文件解释:

  • nginx_nginx.conf 替换默认的nginx.conf文件;

  • nginx_default.conf 替换默认的default.conf文件;

  • php_www.conf 修改 apache 用户为 nginx;

  • supervisor_nginx.conf 添加启动 nginx 的 supervisor 文件;

  • supervisor_php-fpm.conf 添加启动php-fpm的supervisor文件。

查看 Dockerfile 内容:

#
# MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com>
# DOCKER-VERSION 1.6.2
#
# Dockerizing php-fpm: Dockerfile for building php-fpm images
#
FROM csphere/centos:7.1
MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com>

# Set environment variable
ENV APP_DIR /app

RUN yum -y install nginx php-cli php-mysql php-pear php-ldap php-mbstring php-soap php-dom php-gd php-xmlrpc php-fpm php-mcrypt && \
yum clean all

ADD nginx_nginx.conf /etc/nginx/nginx.conf
ADD nginx_default.conf /etc/nginx/conf.d/default.conf

ADD php_www.conf /etc/php-fpm.d/www.conf
RUN sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php.ini

RUN mkdir -p /app && echo "<?php phpinfo(); ?>" > ${APP_DIR}/info.php

EXPOSE 80 443

ADD supervisor_nginx.conf /etc/supervisor.conf.d/nginx.conf
ADD supervisor_php-fpm.conf /etc/supervisor.conf.d/php-fpm.conf

ONBUILD ADD . /app
ONBUILD RUN chown -R nginx:nginx /app

Dockerfile 命令解析:

ONBUILD ADD . /app

ONBUILD 在生成当前 docker 镜像的时候不生效,在子镜像生效;ONBUILD 在产品发布时起着非常重要的作用!举例

A 镜像中有ONBUILD指令,在构建 A 镜像时ONBUILD指令不执行; B 镜像FROM A,在构建 B 镜像时ONBUILD指令开始执行。

如何给 docker 镜像命名:
  • registry-url: registry 服务器的域名或者 ip ;
  • namespace: 自定义;
  • image-name: docker 镜像的名字;
  • tag: docker 镜像的版本号,推荐使用应用服务的版本号来命名,如 php-fpm:5.4 。

生成 php-fpm 镜像

docker build -t csphere/php-fpm:5.4 . `

Step 12 : ONBUILD add . /app
---> Running in 9e21ede67350
---> 7541483a5a76
Removing intermediate container 9e21ede67350
Step 13 : ONBUILD run chown -R nginx:nginx /app
---> Running in ab55fc7a46a1
---> c61699e8c237
Removing intermediate container ab55fc7a46a1
Successfully built c61699e8c237
 

生成 website 容器:

docker run -d -p 8080:80 --name website csphere/php-fpm:5.4
da30b15d3518320f4150b20ef329e59432a65610968977277879578b5fd8f4f7

参数解释:

  • -d 后台运行
  • -p 8080:80 将宿主机的8080 端口映射到容器的 80 端口;
  • —name website 给容器命名为 website ;
  • csphere/php-fpm:5.4 使用这个镜像镜像创建 docker 容器。

使用浏览器访问:http://your_ip:8080/info.php

如何进入一个正在运行的 docker 容器?

docker exec -it website /bin/bash

# supervisorctl 查看当前容器中使用supervisor启动了哪些服务
nginx RUNNING pid 9, uptime 0:23:15
php-fpm RUNNING pid 10, uptime 0:23:15

构建 csphere/mysql:5.5 镜像

cat Dockerfile
#
# MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com>
# DOCKER-VERSION 1.6.2
#
# Dockerizing Mariadb: Dockerfile for building Mariadb images
#
FROM csphere/centos:7.1
MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com>

ENV DATA_DIR /var/lib/mysql

# Install Mariadb
RUN yum install -y mariadb mariadb-server && \
yum clean all

ADD mysqld_charset.cnf /etc/my.cnf.d/

COPY scripts /scripts
RUN chmod +x /scripts/start

EXPOSE 3306

VOLUME ["/var/lib/mysql"]

ENTRYPOINT ["/scripts/start"]

Dockerfile 命令解析:

VOLUME [“/var/lib/mysql”]

VOLUME指令,宿主机文件目录和 docker 容器文件目录做映射

ENTRYPOINT [“/scripts/start”]

ENTRYPOINT在每次启动 docker 容器时都会被执行,此例,是运行了一个 shell 脚本”/scripts/start”

每次启动都会运行/scripts/start脚本,脚本内容如下:

# cat start
#!/bin/bash

set -e

#
# When Startup Container script
#

if [[ -e /scripts/firstrun ]]; then
# config mariadb
/scripts/firstrun_maria
rm /scripts/firstrun
else
# Cleanup previous mariadb sockets
if [[ -e ${DATA_DIR}/mysql.sock ]]; then
rm -f ${DATA_DIR}/mysql.sock
fi
fi

exec /usr/bin/mysqld_safe

脚本解析:

  • set -e 脚本中只要有一行有错误,就会中断脚本执行

  • 如果 firstrun 文件存在,执行 firstrun_maria 脚本,如果不存在,删除 mysql.sock 文件,并启动 Mariadb

firstrun_maira 脚本是初始化 Mariadb,以及设置数据库用户和密码,详情内容请自行阅读脚本文件

构建 mysql:5.5 镜像

docker build -t csphere/mysql:5.5 .

Docker volume 保证删除容器后,数据不删除

  • 保存容器中的数据
  • 数据共享

使用方法:

  1. 在 Dockerfile 中定义 VOLUME[“/data”]
  2. 通过docker run -d -v <host_dir>:<container_dir>
案例:
  • 创建 mysql 容器,不挂载 docker volume ,删除后,数据是否存在
  • 创建 mysql 容器,挂载 docker volume ,删除后,数据是否存在

运行不挂载 docker volume 的 mysql 容器

# docker run -d -p 3306:3306 --name dbserver csphere/mysql:5.5 0a3092395c1e6a84f0ecd5383799f210519c5aefc82cbb7ee2ed1a471fc463f5

删除 docker 容器,容器里面的数据都会随着容器被删除而删除

# docker rm dbserver
Error response from daemon: Cannot destroy container dbserver: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f
Error: failed to remove containers: [dbserver]

参数解释:

  • docker rm 删除状态为 “Exited” 的 docker 容器
  • docker rm -f 强制删除 docker 容器

运行挂载 docker volume 的 mysql 容器

docker run -d -p 3306:3306 -v /var/lib/docker/vfs/dir/mydata:/var/lib/mysql csphere/mysql:5.5

f49165d5e081b8bd8af9cb9c0bbbeb6545d45f857c1a852646c105 docker exec -it f49 /bin/bash

登陆数据库创建 mydb 数据库

# mysql
# show databases;
# create database mydb;
Query OK, 1 row affected (0.00 sec)
# show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
# exit
exit

查看主机文件目录下,是否已生成 mydb 数据库目录文件

# ls /var/lib/docker/vfs/dir/mydata/
aria_log.00000001 ibdata1 ib_logfile1 mysql performance_schema
aria_log_control ib_logfile0 mydb mysql.sock test

```

```
停止docker容器
# docker stop f49165d5e081
f49165d5e081
删除docker容器,查看`mydb`目录是否被删除
# docker rm f49165d5e081
f49165d5e081
# ls /var/lib/docker/vfs/dir/mydata/ 验证,挂载docker volume后,容器被删除掉,数据还在
aria_log.00000001 ibdata1 ib_logfile1 mysql performance_schema
aria_log_control ib_logfile0 mydb mysql.sock test

新创建一个容器,挂载到刚才的数据目录下,是否可以把之前的数据库加载回来

docker run -d -p 3306:3306 --name newdb -v /var/lib/docker/vfs/dir/mydata:/var/lib/mysql csphere/mysql:5.5
29418b93d4d4a00a86169c568b6f952e71d25b155d7f6b8012d953022691b2b8

docker exec -it newdb /bin/bash

# mysql
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)

验证结果: 只要保证数据不被删除,创建新容器并挂载之前的数据目录,业务即可恢复(容器可随意删除、创建)

All Posts
×

Almost done…

We just sent you an email. Please click the link in the email to confirm your subscription!

OKSubscriptions powered by Strikingly