使用 Docker 构建开发、测试环境

docker 为开发人员和系统管理员提供了一个可供开发,分发(ship)和运行应用的平台。将Docker化的应用及其依赖环境不需要经过任何修改就可以分发到任何地方–提供给QA,团队成员或者分发到云平台中。这是使用Docker的一个很重要的目的。

什么是 Docker

Docker的英文本意是码头工人,也就是搬运工,这种搬运工搬运的是集装箱(Container),集装箱里面装的可不是商品货物,而是任意类型的App,Docker把App(叫Payload)装在Container内,通过Linux Container技术的包装将App变成一种标准化的、可移植的、自管理的组件,这种组件可以在你的笔记本上开发、调试、运行,最终非常方便和一致地运行在生产环境下的各种云机房和服务器上。

Docker 与传输虚拟机的对比

Docker的核心底层技术是LXC(Linux Container),Docker在其上面加了薄薄的一层,添加了许多有用的功能。 这篇stackoverflow上的问题和答案很好地诠释了Docker和LXC的区别,能够让你更好的了解什么是Docker, 简单翻译下就是以下几点:

Docker 有什么用呢?以运维的角度来说,你的应用程序一般都需要特定版本的操作系统、应用服务器、 JDK 、数据库服务器,还可能需要调整配置文件和其他一些依赖关系。应用程序可能需要绑定到指定的端口和一定量的内存。这些运行应用程序所需要的组件和配置就是所说的应用程序操作系统。你当然可以写一个包含下载和安装这些组件的安装脚本。 Docker 简化了这个流程,通过创建一个包含应用程序和基础设施的镜像(image),当作一个组件进行管理。这些镜像可以创建 Docker 容器(container),容器运行在 Docker 提供的容器虚拟化平台上。

Docker 的构成

Docker 有两个主要组件:

Docker 采用 Linux 容器 来提供隔离、沙箱、复制、资源限制、快照和其他的一些优势。详细信息的可以看 excellent piece at InfoQ on Docker Containers 了解。

镜像是 Docker 的“构建组件”,也是应用操作系统的只读模版。容器是从镜像创建出来的运行状态,是 Docker 的“运行组件”。容器是可以运行、启动、停止、移动和删除的。镜像保存的仓库是 Docker 的“分发组件”。

Docker的镜像与容器

Docker 按启动顺序包含两个组件:

客户端可以和服务端运行在一台主机上,也可以在不同的主机上。服务端需要用 pull 命令从仓库中拉一个镜像下来。服务端可以从 Docker Hub 或者其他配置的仓库中下载镜像。服务端主机可以从仓库中下载和安装多个镜像。然后客户端就可以用 run命令 来启动容器。客户端与服务端通过socket或者REST API 进行通信。

Docker 的安装

在 CentOS 中安装 Docker:

sudo yum -y install docker-io    #安装 docker
sudo service docker start           #启动 docker 服务
sudo chkconfig docker on        #如果需要 docker 服务为自启动

在Ubuntu/Debian中安装 Docker:

sudo apt-get udpate
sudo apt-get install docker.io
sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io #命令自动补全

其它操作系统的安装可以查看官方文档

Docker的运行与退出

在了解了Image和Container的概念后,我们可以开始下载一个Image,Docker的好处就是提供了一个类似github的Image仓库管理,你可以非常方便pull别人的Image下来运行,例如,我们可以下载一个CentOS Image:

sudo docker pull centos:centos6

这里 centos6是一个 tag,类似于 Git 的 tag,能过它来确定下载的 CentOS 的版本。下载完成后,执行docker images命令来列出你已经下载的 images:
下载截图
下载之后,我们通过命令行来运行一个容器,命令很简单,例如我们想执行一个 shell 终端:

sudo docker run -i -t centos:centos6 /bin/bash

默认情况下,docker 容器是不提供交互shell 的,也不提供标准输入。可以指定-i选项来提供交互,提供-t 选项来分配一个伪终端。
在 Shell 中你可以做你想做的任意操作,安装软件,编写程序,运行命令等。当你操作后想将结果保存,这时可以用 docker commit 命令将 Container 提交成 Image。哦,假如你这里还处在交互 shell 中,记得先使用 Ctrl+d 或者 exit 命令退出。

sudo docker ps -a

首先执行 ps 命令查看容器ID
容器 ID 截图
然后使用 commit 命令将容器进行保存

sudo docker commit 851d custom/centos-aliyun

容器提交后,执行sudo docker images就能看到刚才提交的容器。

docker端口映射

经常要在 Docker 中开启某些网络服务,需要将 docker 虚拟机的网络端口与宿主机端口连接起来。比如将 docker 中的8080端口映射到宿主机的80端口上:

sudo docker run -p 80:8080 custom/tomcat

宿主机硬盘挂载

这也是常用功能之一,尤其是服务需要记录日志、保存文件等时候。

sudo docker run -i -t -v /host/dir:/container/path ubuntu /bin/bash

以上是把宿主机器的/host/dir 挂载到/container/path 路径上。

容器间共享存储

主要借助于-volumes-from参数实现

COUCH1=$(sudo docker run -d -v /var/lib/couchdb shykes/couchdb:2013-05-03)
COUCH2=$(sudo docker run -d -volumes-from $COUCH1 shykes/couchdb:2013-05-03)

这个特性,让人有许多想像空间,比如,一个容器实例用于 Web 存储,另外两个实例用于 Web 请求,实现读写分离。

镜像的导入/导出

方法1: 使用 save/load 命令来实现镜像的导入导出

sudo docker save IMAGENAME | bzip2 -9 -c>img.tar.bz2
#或者你喜欢 tar.gz
sudo docker save IMAGENAME > imageName.tar.gz

镜像导入功能使用 load 命令解压导入即可

sudo docker load < imageName.tar.gz

# 喜欢压缩的同学
bzip2 -d -c <img.tar.bz2 | sudo docker load

方法2: push/pull 将 image 文件推送到Docker Hub上去。这种方法类似于 git。你可以在 Docker Hub 上建立自己的公有或者私有库,适用于远程分享。缺点是,有时 image 文件特别大,需要考虑网络带宽问题。
方法3: 搭建自己的私服repository,将 image 提交到私服,适用于企业网络。

Dockerfile

在 Shell 脚本环境中一步步安装,低效且劳累。Docker 可以通过自定义 Dockerfile 实现自动化构建 docker 镜像的脚本,既方便分享也便于修改与模板化。

# VERSION 1.0.0

# 默认Centos,可以改成你需要的任意镜像
FROM centos

# 签名
MAINTAINER wupher "wupher@foxmail.com"

RUN echo 'We are running some # of cool things'
RUN yum update 
RUN yum install -y openssh-server
RUN mkdir -p /var/run/sshd

# 设置root ssh远程登录密码
RUN echo "root:123456" | chpasswd

RUN yum install -y mysql-server
RUN yum install -y java-1.7.0-openjdk

# 安装tomcat 等……

# 挂载硬盘,用于保存 log
VOLUME ["/var/log/", "/var/volume2"]

# 容器开放22端口
EXPOSE 22

# 容器开放 8080端口
EXPOSE 8080

# 设置Tomcat初始化运行,SSH终端服务器作为后台运行,这样 docker run image的时候,这些服务就自动启动了
ENTRYPOINT service tomcat start && /usr/sbin/sshd -D

完整的 DockerFiler,可以参考官方文档

应用场景

Docker目前有以下应用场景:

现有缺陷

Docker 现在才1.0版本,这些问题相信未来都将会解决。

(完)
comments powered by Disqus
Powered by GitHub  &&  Jekyll | CC BY-NC-SA