Docker

Docker新手入门实战教程

Jager · 9月12日 · 2017年 · · 741次已读

一、实践背景

为了学习 Docker,我们先结合实际需求,设计这样一个场景 case:假设有一个个人网站,想使用 Nginx 反向代理方案,能够在国内外快速搭建多个类似于 CDN 的节点,提供集群式的 WEB 访问服务。

我想到的方案如下:

  • 常规部署方案:    购买云主机->环境初始化->部署 Nginx->配置反向代理->DNS 解析
  • Docker 部署方案:购买云主机->yum 安装 docker->拉取自定义镜像并执行->DNS 解析
  • 腾讯云容器方案: 腾讯云容器服务->创建服务->DNS 解析

很明显,使用 Docker 部署方案,整个过程会变得简单快捷,也更易自动化。当然,若不是对 IDC 有特殊要求的话,腾讯云的容器服务当选为最佳方案。

下面简单记录下我从 Docker 镜像的创建、上传到部署的实践过程。

实验环境:

  • 腾讯云:CentOS Linux release 7.2.1511 (Core)
  • 阿里云:CentOS Linux release 7.2.1511 (Core)
  • Docker version 1.12.6, build 88a4867/1.12.6
  • Docker 镜像版本:Centos 官方最新版
  • Nginx 版本:Tengine 2.2.0
  • 其他略..

二、制作镜像

1、安装配置 Docker

# 安装 docker
yum install -y docker

# 配置腾讯云镜像加速(官方的龟速)
vim /etc/sysconfig/docker
#新增如下参数:
OPTIONS='--registry-mirror=https://mirror.ccs.tencentyun.com'

#重启 docker 服务:
systemctl restart docker

2、制作基础镜像

拉取 centos 官方基础镜像
docker pull centos
查看当前镜像
docker images
[root@MyServer docker]# docker images
REPOSITORY                                              TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos                                        latest              328edcd84f1b        4 weeks ago         192.5 MB

运行并进入镜像:

docker run -ti docker.io/centos:latest /bin/bash

此时,终端已经进入了镜像里面,现在我们可以根据自己的需求安装额外的组件,比如我这次需要用到 crontab 任务计划服务、进程守护 supervisor 等,那么直接在这个终端开始操作:

[root@0d7f7b8769d9 /]# yum install -y epel-release crontabs
[root@0d7f7b8769d9 /]# yum install -y python-pip
[root@0d7f7b8769d9 /]# pip install --upgrade pip
[root@0d7f7b8769d9 /]# pip install supervisor

Ps:上面的 PS 提示符中的 0d7f7b8769d9 就是本次启动的 CONTAINER ID ,在下面的 commit 即将用到。

完成必要组件安装之后,按下 Ctrl +D 退出系统,接着使用 docker commit 命令创建新镜像,比如命名为 nginx-proxy-base,版本 latest:

docker commit 0d7f7b8769d9 centos/nginx-proxy-base:latest

执行完成后,可以使用 docker images 查看刚创建的镜像:

[root@MyServer ~]# docker images
REPOSITORY                                              TAG                 IMAGE ID            CREATED             SIZE
centos/nginx-proxy-base                                 latest              676fcfff6d3c        About an hour ago   366 MB

到此,我们就创建了一个自定义的 Docker 基础镜像(Ps:基础镜像类似一个 VM 虚拟机的快照,方便后续步骤都可以从这个基础上重新制作。)

3、制作服务镜像

有了前面的基础镜像之后,我们可以在此基础之上添加应用程序或自定义配置,打包为服务镜像。以本文背景需求为例,为了方便后续维护,Nginx 我采用纯静态编译方式,制作成绿色便携版本。

因此,我们先在宿主机上静态编译一个符合需求的 Nginx(仅展示关键步骤,依赖组件自行搞定):

# 把所有依赖都静态编译进去
./configure  --prefix=/usr/local/nginx \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_realip_module \
--with-pcre=../pcre-8.39  \
--with-zlib=../zlib-1.2.11 \
--with-http_sub_module \
--with-openssl=../openssl-1.0.2j \
--add-module=../ngx_cache_purge-2.3 \
--add-module=../ngx_http_substitutions_filter_module
# 安装
make && make install

安装后得到 /usr/local/nginx 目录,接着我们按照实验需求修改 Nginx 各项配置,比如反向代理:

server {
    listen 80;
    server_name demo.domain.com;
    access_log /data/wwwlogs/demo.domain.com.log;
    index index.html index.htm index.php;

    location  / {
        proxy_pass http://xxx.xxx.xxx.xxx;
        proxy_set_header  X-Forwarded-For $remote_addr;
        proxy_redirect off;
        proxy_set_header Host demo.domain.com;
    }
}

全部配置 OK 后,运行 nginx,确保可以正常工作。

4、编写 Dockerfile

①、创建一个目录,比如:

mkdir -p /data/docker-nginx-proxy
cd /data/docker-nginx-proxy

②、创建 supervisor 配置文件,注意必须非 daemon 模式,所以此处 crond 会带上-n 参数:

[supervisord]
nodaemon=true

[program:crond]
command=crond -n 

[program:nginx]
command=/usr/local/nginx/sbin/nginx

③、继续创建其他所需文件,比如 crontab.list:

0 3 * * * /usr/local/nginx/sbin/nginx -s reload > /dev/null 2>&1

④、将前面的 nginx 目录拷贝过来:

cp -rf /usr/local/nginx .

⑤、编写 Dockerfile 文件:

vim Dockerfile

FROM  centos/nginx-proxy-base:latest
MAINTAINER <im@zhang.ge>
# 将所需文件复制到镜像指定路径
ADD nginx /usr/local/nginx
ADD supervisord.conf /etc/supervisord.conf

# 定义一些命令(因为 Docker 是分层的,这里建议将多个命令通过&&连接,写到一个 RUN 里面来减少 Docker 层数)
# 指定时区,解决 Dcoker 时间和宿主机时间差异问题
RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo Asia/Shanghai > /etc/timezone && \
    ln -sf /usr/local/nginx/sbin/nginx /bin/ && \
    echo 'daemon off;' >> /usr/local/nginx/conf/nginx.conf && \
    crontab /etc/crontab.list
			 
# 运行 supervisor,这里注意 CMD 只能用一次
CMD ["/usr/bin/supervisord"]

附:dockerfile 常用指令,可以按实际需求自行添加:

FROM:指定基础 image
MAINTAINER:用来指定镜像创建者信息
ADD:从 src 复制文件到 container 的 dest 路径
RUN:在容器里面执行命令
CMD:设置 container 启动时执行的操作,只