转载自: http://www.oschina.net/translate/coreos_and_docker_first_steps?cmp

CoreOS是一个基于Linux,systemd和Docker的小型操作系统。在这篇文章里,我将描述我是怎么看待CoreOS/Docker的,以及初始使用它的一些步骤。

什么是Docker,为什么这是个好主意?

找到合适的词汇向那些没用过它的人描述是很困难的,但让我尝试一下。使用docker,你可以将软件打包进“容器”,然后可以在你自己的服务器上或者一些云服务平台(dotcloud,stackdock,digitalocean)上运行。软件例子如cgit,一个快速的git网络接口。Docker将各个容器放入独立的Linux容器(Linux container,LXC)中,大多数是为了干净和良好定义的环境,安全不是首要因素。就有关的软件而言,它的PID是1,并拥有一个动态的主机名,动态IP地址和一个干净的文件系统。

为什么这是个好主意?它自动部署,隔离机器并抽象化。当我有多个服务器时,我可以在其中任意一个上运行同样的、无修改的Docker容器,而一点也不用关心软件(我将在这之后写cgit),因为Docker提供的环境完全一样。这使得移植没有丝毫痛苦——计划向新硬件升级、当向不同的主机转换或者因为一个服务器运行中断,它都一样。

现在你也许会说我们已经有这样一个东西,Amazon's EC2和相似的云服务存在几年了。表面上看来,它看起来非常相似,唯一不同的是你发送到EC2的是一个虚拟机,而不是Docker容器。对我而言,存在两个最大的不同:

  1. Docker更加模块化:鉴于在一个独立的VM上,你部署的各个应用经济上不吸引人而且笨重,使用Docker的轻量容器,这成为可能。

  2. 与Docker工作有一个不同的脑力模型。使用一个虚拟的长期运行的服务器,你需要手动或者自动(如使用Puppet)来保持其运行,与之相比,你可以不再考虑服务器,开始关注软件/应用。

CoreOS有几个很牛的特点. 它以只读模式运行, 除了“state partition”, 这个地方,我们基本上使用它来存放系统单元文件,包括启动监视你的docker容器, 另外还有docker’的本地图片缓存和一些固定的区域。我喜欢只读文件系统,因为这意味着,他们很稳定,并且几乎不可能被破坏. 另外, CoreOS会自动更新而且它重用了ChromeOS的更新器. 另外,他还有一些很有趣的集群优势, 可以看这篇文章 etcd, a highly-available key-value store for service configuration and discovery, 以这篇文章作为基础raft consensus algorithm. 他可以做出容易的master选择,但是在写作的的时候,

这还没有应用。

当然了, 如果你喜欢, 你也可以安装你最喜欢的Linux分发版,并且安装上Docker, which should be reasonable straight-forward (请允许我用几个小时介绍这篇文章Debian’s old mount(8) version, which has a bug). 从个人角度而言,我发现这是一个有趣的尝试,运行一个和Docker hosting有非常相似的约束的环境.然后,你会发现你喜欢上Docker了!

第一步: Docker化 cgit

你既可以使用交互式命令行手动创建一个docker容器或者使用一个Dockerfile。第一种命令行的方式是非常容易出错的,因此仅为了尝鲜,我只推荐使用Dockerfiles。一个Dockerfile的开头指定了一个标准镜像,可以是一个小型环境(busybox) 或者更多的是一个linux发行版的最小封装,如在我们的例子里使用的是 tianon/debian。

定义了标准镜像以后, 你可以在RUN命令后面运行任意的命令,还可以在ADD命令之后添加文件. 容器内外的接口其实就是一个或者多个TCP端口. 当前比较常用的是HTTP使用的经典端口80. 最后一个需要指定的是入口(ENTRYPOINT), 就是当你运行容器的时候docker会首先执行的程序. 我们为cgit使用的Dockerfile就像这样:

FROM tianon/debian:sid

RUN apt-get update
RUN apt-get dist-upgrade -y
RUN apt-get install -y lighttpd ADD cgit /usr/bin/cgit
ADD cgit.css /var/www/cgit/cgit.css
ADD cgit.png /var/www/cgit/cgit.png ADD lighttpd-cgit.conf /etc/lighttpd/lighttpd-cgit.conf ADD cgitrc /etc/cgitrc EXPOSE 80
ENTRYPOINT ["/usr/sbin/lighttpd", "-f", "/etc/lighttpd/lighttpd-cgit.conf", "-D"]

在我的机器上,这个文件为 ~/Dockerfiles/cgit/Dockerfile。在 cgit 目录下的这个文件旁,我放了 cgit-0.9.2 的源代码,并且从编译目录树中将 cgit、cgit.css 和 cgit.png 拷贝出来。lighttpd-cgit.conf 相当简单:

server.modules = (
"mod_access",
"mod_alias",
"mod_redirect",
"mod_cgi",
) mimetype.assign = (
".css" => "text/css",
".png" => "image/png",
) server.document-root = "/var/www/cgit/" # Note that serving cgit under the /git location is not a requirement in
# general, but obligatory in my setup due to historical reasons.
url.redirect = (
"^/$" => "/git"
)
alias.url = ( "/git" => "/usr/bin/cgit" )
cgi.assign = ( "/usr/bin/cgit" => "" )

注意,我们手工编译 cgit 的唯一原因是因为还没有它的 Debian 包(编译过程有点特殊。。。)。为了实际编译这个容器并且正确的打标签,运行 rundocker build -t="stapelberg/cgit" . :

home $ docker build -t="stapelberg/cgit" .
Uploading context 46786560 bytes
Step 1 : FROM tianon/debian:sid
 ---> 6bd626a5462b
Step 2 : RUN apt-get update
 ---> Using cache
 ---> 3702cc3eb5c9
Step 3 : RUN apt-get dist-upgrade -y
 ---> Using cache
 ---> 1fe67f64b1a9
Step 4 : RUN apt-get install -y lighttpd
 ---> Using cache
 ---> d955c6ff4a60
Step 5 : ADD cgit /usr/bin/cgit
 ---> e577c8c27dbf
Step 6 : ADD cgit.css /var/www/cgit/cgit.css
 ---> 156dbad760f4
Step 7 : ADD cgit.png /var/www/cgit/cgit.png
 ---> 05533fd04978
Step 8 : ADD lighttpd-cgit.conf /etc/lighttpd/lighttpd-cgit.conf
 ---> b592008d759b
Step 9 : ADD cgitrc /etc/cgitrc
 ---> 03a38cfd97f4
Step 10 : EXPOSE 80
 ---> Running in 24cea04396f2
 ---> de9ecca589c8
Step 11 : ENTRYPOINT ["/usr/sbin/lighttpd", "-f", "/etc/lighttpd/lighttpd-cgit.conf", "-D"]
 ---> Running in 6796a9932dd0
 ---> d971ba82cb0a
Successfully built d971ba82cb0a

第二步:推到注册器

Docker公司默认会提供一个从注册器抽取图片的服务。由于注册容器可能包含机密的配置信息如密码和其他的证书,因此不建议把图片放入到公共的注册器中。dockify.io和quay.io提供了私人注册器的服务,但是你也可以使用你自己的。当你使用自己的注册器时需要注意你是保证它的可用性。小心别在当你需要通过龟速的DSL来传送你的docker容器到自己私人的注册器时,出现网络中断的情况。一个替换方法就是使用自己的注册器但是通过付费方式把容器那些文件存储到亚马逊S3上,

在默认配置下很容易运行自己的注册器的(只存储数据在容器下的/tmp目录下,无需认证)

d0 $ docker run -p 5000:5000 samalba/docker-registry

然后,你可以对我们在步骤1中建立的图片进行标记和推送图片到注册器中:

docker tag stapelberg/cgit d0.zekjur.net:5000/cgit
docker push d0.zekjur.net:5000/cgit

第三步: 在CoreOS上运行cgit

为了简单的运行cgit容器,我们运行一下代码:

d0 $ docker run d0.zekjur.net:5000/cgit
2013-12-07 18:46:16: (log.c.166) server started

但是这还不是他的全部作用, 80端口只是被cgit容器使用,还没有提供给外届或者是其他的cgit容器访问. 或者你也可以使用-p 80参数去自定义你的对外端口。

d0 $ docker run -p 4242:80 d0.zekjur.net:5000/cgit

当使用浏览器访问 http://d0.zekjur.net:4242/ 时,你就能看到cgit了.但是, 即使你在自己的cgitrc中建立了一个git仓库,他还是不起作用,因为在这个容器中,他还是没有git仓库.所以最有效的方法就是给他们提供一个权限。在这个例子中,在容器中只读。创建 /media/state/_CUSTOM/git 这目录,并且将你的仓库放在里面, 再重新启动容器:

d0 # mkdir -p /media/state/_CUSTOM/git
d0 # cd /media/state/_CUSTOM/git
d0 # git clone git://github.com/stapelberg/godebiancontrol
d0 $ docker run -v /media/state/_CUSTOM/git:/git:ro \
  -p 4242:80 d0.zekjur.net:5000/cgit

这样你就能在仓库中看到这个git仓库了.现在,我们就需要给cgit建立一个unit脚本,确保机器重启,容器也能自动开启了:

d0 # cat >/media/state/units/cgit.service <<'EOT'
[Unit]
Description=cgit
After=docker.service [Service]
Restart=always
ExecStart=/usr/bin/docker run \
    -v /media/state/_CUSTOM/git:/git:ro \
    -p 4242:80 \
    d0.zekjur.net:5000/cgit [Install]
WantedBy=local.target
EOT
d0 # systemctl daemon-reload

第四步: 在容器的前端运行nginx

你可能注意到了我们并没有直接在80端口上直接暴露cgit. 大多数时候,你没有那么多的公共的IP地址来给每个服务分配一个。所以我们部署一个nginx来作为其他服务的反向代理,这样做还有一个好处是可以对其他服务进行无缝升级(在另一个端口启动新版本的cgit并测试,然后重启nginx, 把请求转向这个新版本的cgit)。

在docker里安装nginx跟安装cgit是很相似的, 仅需一些手动编辑:

home $ mkdir -p ~/Dockerfiles/nginx
home $ cd ~/Dockerfiles/nginx
home $ cat >Dockerfile <<'EOT'
FROM tianon/debian:sid RUN apt-get update
RUN apt-get dist-upgrade -y
RUN apt-get install -y nginx-extras EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
EOT
home $ docker build -t=stapelberg/nginx .
home $ docker tag stapelberg/nginx d0.zekjur.net:5000/nginx
home $ docker push d0.zekjur.net:5000/nginx

现在, 我们并不直接将 cgit 暴露出来, 而是把 cgit 的4242端口绑定到 docker0 的桥接接口上, 其他容器也可以访问这个接口:

d0 $ docker run -v /media/state/_CUSTOM/git:/git:ro \
  -p 172.17.42.1:4242:80 d0.zekjur.net:5000/cgit

我决定不把实际的虚拟主机配置包括在 Nginx 容器中,而是保持在 /media/state/_CUSTOM/nginx 中,以便可以修改它(未来可能实现自动化),可以简单地通过向 Nginx 发送 SIGHUP 信号来重新加载它:

d0 # mkdir -p /media/state/_CUSTOM/nginx
d0 # cat >/media/state/_CUSTOM/nginx/cgit <<'EOT'
server {
        root /usr/share/nginx/www;
        index index.html index.htm;         server_name d0.zekjur.net;         location / {
                proxy_pass http://172.17.42.1:4242/;
        }
}
EOT

最后一步,运行 nginx 容器,如下:

d0 $ docker run -v /media/state/_CUSTOM/nginx:/etc/nginx/sites-enabled:ro \
  -p 80:80 dock0.zekjur.net:5000/nginx

一切完成后,当你在浏览器中访问 d0.zekjur.net ,你会受到 cgit 的欢迎!

CoreOS和Docker入门的更多相关文章

  1. redis哨兵集群、docker入门

    redis-sentinel主从复制高可用 Redis-Sentinel Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果m ...

  2. 【Docker入门】

    目录 Linux容器 Docker的优势 Docker三大概念 安装使用Docker 补充知识 [Docker入门] 发布文章 "qq_41964425" @ *** 所谓Dock ...

  3. docker入门 基础命令 docker安装

    docker入门   在学一门新知识的时候,超哥喜欢提问,why?what?how? wiki资料 什么是docker Docker 最初是 dotCloud 公司创始人 Solomon Hykes ...

  4. Docker入门与进阶(上)

    Docker入门与进阶(上) 作者 刘畅 时间 2020-10-17 目录 1 Docker核心概述与安装 1 1.1 为什么要用容器 1 1.2 docker是什么 1 1.3 docker设计目标 ...

  5. 第三章 Docker 入门

    第三章 docker 入门 3.1 确保docker已经就绪 首先查看docker程序是否存在,功能是否正常 [#3#cloudsoar@cloudsoar-virtual-machine ~]$su ...

  6. Docker入门教程(九)10个镜像相关的API

    Docker入门教程(九)10个镜像相关的API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第九篇,重点介绍了镜像相关的Docker Remote ...

  7. Docker入门教程(八)Docker Remote API

    Docker入门教程(八)Docker Remote API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第八篇,重点介绍了Docker Remote ...

  8. Docker入门教程(七)Docker API

    Docker入门教程(七)Docker API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第七篇,重点介绍了Docker Registry API和 ...

  9. Docker入门教程(六)另外的15个Docker命令

    Docker入门教程(六)另外的15个Docker命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第六篇,继续介绍Docker命令.之前的第二篇文章 ...

随机推荐

  1. [Winform] DataGridView 总结(FAQ)

    Q1.  如何使单元格不可编辑? A:设置 ReadOnly 属性,可以设置的对象包括 DataGridViewRow(行).DataGridViewColumn(列).DataGridViewCel ...

  2. Ionic 简单操作

    在使用 Ionic 之前要安装 Nodejs,Cordova . Java 下载Java 网站.Java 默认安装在 C:\Program Files\Java 文件目录. Android 下载And ...

  3. Maven自定义绑定插件目标:创建项目的源码jar

    <build> <plugins> <!-- 自定义绑定,创建项目的源码jar --> <plugin> <groupId>org.apac ...

  4. spider RPC插件化体系

    为了满足灵活扩展的需要,spider支持灵活的自定义插件扩展,从功能上来说,插件和过滤器的差别在于过滤器不会阻止请求的执行同时对于主程序不会有API上的影响(比如servlet 过滤器和监听器)(最多 ...

  5. webpack+react+antd 单页面应用实例

    React框架已经火了好长一段时间了,再不学就out了! 对React还没有了解的同学可以看看我之前的一篇文章,可以快速简单的认识一下React.React入门最好的实例-TodoList 自己从开始 ...

  6. dirname 命令

    dirname 命令用途将指定路径除了最后以外的部分写到标准输出.语法dirname Path描述dirname 命令读取指定路径名保留最后一个"/"(斜杠)及其后面的字符,删除其 ...

  7. SharePoint 2013 沙盒解决方案不能激活(激活按钮不可用)

    把沙盒解决方案上传到目标站点的"解决方案"库中,发现"激活"按钮是灰掉的,不可用. 首先,我想到的是权限不足,所以 "以管理员身份"启动IE ...

  8. MAC的SVN怎么设置允许.a文件上传

    首先在mac中svn的安装会去选择Cornerstone 如果遇到这个问题肯定是已经安装并准备上传.a 文件了.首先要清楚svn是默认过滤忽略.a文件的上传的,要想可以上传.a 可以通过这个简单的方法 ...

  9. AC算法学习笔记

    1.算法流程图 (1)    void Init() 此函数是初始化函数,用来给fail数组和goto数组初始化值. (2)    void GotoFunction(string x) 这个函数的作 ...

  10. Appfuse:第一张表维护

    1. 建立表userinfo 列名 描述 UserID 主键.自增 UserName 用户名 Pwd 密码 CreateDate 创建日期 2. 在src/main/resources目录下增加文件h ...