4

Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。

对开发而言,使用 docker 就可以非常方便的集成开发环境,不需要繁琐的安装,只需要用 docker 拉取一个镜像启动即可;环境问题这种大坑,使用 Docker 直接跳过,如把 Mysql、Redis、Mongo… 等开发需要用的数据库做成一个镜像,或者 JAVA、Nodejs、Python… 等做成镜像,可以保持环境一致,节约开发成本。

安装 Docker

在 Linux 上,安装(以 Ubuntu 为例):

# 安装 Docker 需要 curl
> which curl
# root 不需要 sudo
# > apt-get update && sudo apt-get install curl
# > sudo apt-get install curl
> curl -fsSL https://get.docker.com/ | sh

Mac/Windows 上,宿主平台不支持 Docker 直接运行,因而 Docker 在这两个系统上运行在 VirtualBox 中(Docker 官方提供一键安装教程 MacWindows ,提供 Docker Toolbox 一键安装/运行)。

各个平台的安装其实都不太一样,官方给了每个平台的安装方法如:

Ubuntu

Red Hat

CentOS

使用 Docker 之前,请先修改源,参考章节 修改 Docker 源

基本原理

与 VM 技术不同,Docker 运行在宿主平台(Linux系列)上:

docker

Docker 使用 Linux Containers 技术,即基于容器的操作系统层级虚拟化技术,但是又有区别:

docker-vs-lxc

详细区别可以参考这里

Docker 使用如下结构来提供服务:

docker arch

Docker 服务启动后, Docker 客户端可以使用 docker 命令 拉取/构建/推送/运行 Images 。每个 Image 运行的时候都跑在一个 Container 中。

  • Images:镜像,是一系列只读模板(layers)的集合,内核是最底层(第 0 层),不能被修改或保持状态。一个 Docker 镜像基于另一个 Docker 镜像,类似于继承

第 1 层的镜像(Base Image)为基本的系统如 Ubuntu、CentOS,其他层的镜像(除了最顶层)称为父层镜像(Parent Image)。创建对象的时候,基本都是以其他镜像为基础:

# 基础镜像
FROM centos:6 # or FROM ubuntu:latest
# 应用镜像
FROM mysql:latest
  • Containers:容器,在所有的镜像层之上增加一个可写层。这个可写层有运行在 CPU 上的进程,而且有两个不同的状态:运行态(Running)和退出态(Exited)。

所以同一个镜像可以运行在多个 Container 之中,互不影响。

修改 Docker 源

注册 Docker Hub ,即可打开新世界的大门。

然而 Docker Hub 拉取镜像灰常慢,所以加一个镜像源来加速。到 daocloud/阿里云 之类的服务上去注册一个镜像服务,然后修改 Docker 的配置:

  1. Linux

    修改 `/etc/sysconfig/docker` ,添加 `other_args="--registry-mirror=${yours}"`
    
  2. Mac / Windows

    `docker-machine create` / `boot2docker init` 创建 docker 虚拟机的时候,有一个参数是`--engine-registry-mirror [--engine-registry-mirror option --engine-registry-mirror option] Specify registry mirrors to use` 。创建时带上这个参数就好了。
    

如果是官方一键安装,可以修改/Applications/Docker/Docker\Quickstart\Terminal.app/Contents/Resources/Scripts/start.shcreate 添加参数。

Windows 木有研究,但是应该也是类似的修改方法。

基本使用

启动 Docker之后,即可使用 docker 命令:

Usage: docker [OPTIONS] COMMAND [arg...]
       docker [ --help | -v | --version ]

A self-sufficient runtime for containers.

Options:

  --config=~/.docker              Location of client config files
  -D, --debug                     Enable debug mode
  -H, --host=[]                   Daemon socket(s) to connect to
  -h, --help                      Print usage
  -l, --log-level=info            Set the logging level
  --tls                           Use TLS; implied by --tlsverify
  --tlscacert=~/.docker/ca.pem    Trust certs signed only by this CA
  --tlscert=~/.docker/cert.pem    Path to TLS certificate file
  --tlskey=~/.docker/key.pem      Path to TLS key file
  --tlsverify                     Use TLS and verify the remote
  -v, --version                   Print version information and quit

Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders between a container and the local filesystem
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in a running container
    export    Export a container's filesystem as a tar archive
    history   Show the history of an image
    images    List images
    import    Import the contents from a tarball to create a filesystem image
    info      Display system-wide information
    inspect   Return low-level information on a container or image
    kill      Kill a running container
    load      Load an image from a tar archive or STDIN
    login     Register or log in to a Docker registry
    logout    Log out from a Docker registry
    logs      Fetch the logs of a container
    network   Manage Docker networks
    pause     Pause all processes within a container
    port      List port mappings or a specific mapping for the CONTAINER
    ps        List containers
    pull      Pull an image or a repository from a registry
    push      Push an image or a repository to a registry
    rename    Rename a container
    restart   Restart a container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save an image(s) to a tar archive
    search    Search the Docker Hub for images
    start     Start one or more stopped containers
    stats     Display a live stream of container(s) resource usage statistics
    stop      Stop a running container
    tag       Tag an image into a repository
    top       Display the running processes of a container
    unpause   Unpause all processes within a container
    update    Update resources of one or more containers
    version   Show the Docker version information
    volume    Manage Docker volumes
    wait      Block until a container stops, then print its exit code

Run 'docker COMMAND --help' for more information on a command.

每个命令解释的很清楚,还可以使用 docker COMMAND --help 查看命令详细介绍。

举个栗子

centos:6 为例,先从 docker hub 拉取镜像:

> docker pull centos:6

因为这是一个基础镜像,所以启动也就是开启一个 bash ,这样就进入到 container 内部了:

> docker run -it centos:6 /bin/bash
[root@4a2e60863aa8 /]#

构建镜像

Docker 镜像依靠 Dockerfile 构建,下面给个示例,我们构建一个包含 Redis、Mysql、MongoDB 的镜像。

Docker 命令和 Linux 命令非常相似,如果对 Linux 命令模式不熟悉,建议先去熟悉这块。

1. Dockerfile
# 以 centos 为基础
FROM centos:6
# 维护者
MAINTAINER Zhang Xun <xtkml.g@gmail.com> # ${NAME} <${EMAIL}>
# epel 源,提供很多包
RUN yum -y install epel-release \
    && yum -y update \
    && yum -y install sudo wget unzip tar git systemd glib-devel # 一些基础 lib
# gcc,centos 6 的 gcc 太老了,装 4.8
RUN wget http://people.centos.org/tru/devtools-2/devtools-2.repo -O /etc/yum.repos.d/devtools-2.repo \
    && yum -y install devtoolset-2-gcc devtoolset-2-binutils devtoolset-2-gcc-c++ \
    && ln -s /opt/rh/devtoolset-2/root/usr/bin/* /usr/local/bin/ \ # link symbol
    && hash -r # refresh path

# mysql 5.6 from official repo
RUN wget http://repo.mysql.com/mysql-community-release-el6-7.noarch.rpm \
    && rpm -ivh mysql-community-release-el6-7.noarch.rpm \
    && rm -rf mysql-community-release-el6-7.noarch.rpm \
    && yum -y install mysql-server

# reids
RUN yum -y install redis

# mongodb from official repo
RUN { \
        echo '[mongodb-org-3.2]'; \
        echo 'name=MongoDB Repository'; \
        echo 'baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/'; \
        echo 'gpgcheck=1'; \
        echo 'enabled=1'; \
        echo 'gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc'; \
    } > /etc/yum.repos.d/mongodb-org-3.2.repo \
    && yum -y install mongodb-org \ # 安装
    && sed -i 's/bindIp/#bindIp/g' /etc/mongod.conf # 开启远程连接

# 暴露端口
# 如果不需要在 docker 外面连接数据库,则不需要开启端口,也不需要打开 mongo 和 mysql 的远程权限
EXPOSE 3306 # mysql port
EXPOSE 6379 # redis port
EXPOSE 27017 # mongo port

# clean
RUN yum -y clean all

# 数据库启动脚本
ADD start.sh /start.sh
RUN chmod +x /start.sh

# 如果想让镜像不以 root 用户运行,可以添加一个用户
# RUN useradd -d /home/base -m -s /bin/bash -p 123456 base
# RUN echo -e "base\tALL=(ALL)\tNOPASSWD: ALL\n" >> /etc/sudoers
# USER base

# /etc/sudoers,允许 shell 脚本使用 sudo 命令,非 root 用户需要修改这项
# RUN sed -i 's/Defaults\s*requiretty/#Defaults requiretty/g' /etc/sudoers

# 运行镜像的时候,入口脚本
CMD sh -c "bash /start.sh run"
2. start.sh
#!/usr/bin/env bash

# start db,如果是非 root 用户,需要使用 sudo 命令
service mysqld start
service mongod start
redis-server > ~/.redis.log &

# 开启 mysql root 远程连接权限
mysql -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;" -uroot

echo 'start'

# 开启一个 bash 进程保持镜像一直运行
/bin/bash
build & push

构建镜像:

docker build -t zzxun/develop-env-basic .
# 巴拉巴拉一大堆 log

等待构建成功。

之后使用 images 命令查看镜像列表:

> docker images
REPOSITORY               TAG             IMAGE ID            CREATED              SIZE
zzxun/develop-env-basic  latest          b1af590d971c        8 minutes ago        1.311 GB
centos                   6               fc73b108c5ae        2 weeks ago          228.9 MB

可以把镜像推送到 Docker Hub:

docker push zzxun/develop-env-basic
run

运行镜像,使用 run -d 让镜像在后台运行:

# 命名 container 为 env
docker run -it -d --name env -p 3306:3306 -p 27017:27017 -p 6379:6379 zzxun/develop-env-basic
# 还可以使用 -v 命令挂载宿主机文件
docker run -it -d --name env -v ~/git-space:/data/git-space -p 3306:3306 -p 27017:27017 -p 6379:6379 zzxun/develop-env-basic
# 如果只在 docker 中运行,则更本不需要开启端口,即关闭 Dockerfile 中的 EXPOSE(需要重新构建)
docker run -it -d --name env -v ~/git-space:/data/git-space zzxun/develop-env-basic

# 更多参数使用 docker run --help 查看

之后使用 ps 查看正在运行的容器:

> docker ps
CONTAINER ID        IMAGE                     COMMAND                   CREATED             STATUS              PORTS                                                                      NAMES
5a846421b812        zzxun/develop-env-basic   "/bin/sh -c 'sh -c \"b"   2 minutes ago         Up 5 hours          0.0.0.0:3306->3306/tcp, 0.0.0.0:6379->6379/tcp, 0.0.0.0:27017->27017/tcp   env
进入 container

使用 exec 可以进入 container 内部,上一步给 container 取了别名,所以可以直接使用别名,也可以使用 container id(输入前几个字母就好了,docker 会自动查找匹配)。

> docker exec -it env bash # 或者 docker exec -it 5a bash
[root@5a846421b812 /]#
How To Connect

如果是 Linux 系统,则可以直接连接 127.0.0.1:3306/6379/27017

Mac 和 Windows 系统下,因为 Docker 运行在虚拟机中,所以使用:

> docker-machine ip
192.168.99.100

则可连接 192.168.99.100:3306/6379/27017 使用数据库。


猫与麦子
413 声望12 粉丝

膝盖中箭