CoreOS和Docker入门
转载自: 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容器。对我而言,存在两个最大的不同:
Docker更加模块化:鉴于在一个独立的VM上,你部署的各个应用经济上不吸引人而且笨重,使用Docker的轻量容器,这成为可能。
与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入门的更多相关文章
- redis哨兵集群、docker入门
redis-sentinel主从复制高可用 Redis-Sentinel Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果m ...
- 【Docker入门】
目录 Linux容器 Docker的优势 Docker三大概念 安装使用Docker 补充知识 [Docker入门] 发布文章 "qq_41964425" @ *** 所谓Dock ...
- docker入门 基础命令 docker安装
docker入门 在学一门新知识的时候,超哥喜欢提问,why?what?how? wiki资料 什么是docker Docker 最初是 dotCloud 公司创始人 Solomon Hykes ...
- Docker入门与进阶(上)
Docker入门与进阶(上) 作者 刘畅 时间 2020-10-17 目录 1 Docker核心概述与安装 1 1.1 为什么要用容器 1 1.2 docker是什么 1 1.3 docker设计目标 ...
- 第三章 Docker 入门
第三章 docker 入门 3.1 确保docker已经就绪 首先查看docker程序是否存在,功能是否正常 [#3#cloudsoar@cloudsoar-virtual-machine ~]$su ...
- Docker入门教程(九)10个镜像相关的API
Docker入门教程(九)10个镜像相关的API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第九篇,重点介绍了镜像相关的Docker Remote ...
- Docker入门教程(八)Docker Remote API
Docker入门教程(八)Docker Remote API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第八篇,重点介绍了Docker Remote ...
- Docker入门教程(七)Docker API
Docker入门教程(七)Docker API [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第七篇,重点介绍了Docker Registry API和 ...
- Docker入门教程(六)另外的15个Docker命令
Docker入门教程(六)另外的15个Docker命令 [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第六篇,继续介绍Docker命令.之前的第二篇文章 ...
随机推荐
- scikit-learn一般实例之六:构建评估器之前进行缺失值填充
本例将会展示对确实值进行填充能比简单的对样例中缺失值进行简单的丢弃能获得更好的结果.填充不一定能提升预测精度,所以请通过交叉验证进行检验.有时删除有缺失值的记录或使用标记符号会更有效. 缺失值可以被替 ...
- c# socket
好久没有写CS端代码,今天有空复习一下SOCKET. 功能说明: 1.服务端向客户端发送信息 2.客户端向服务端发送信息 效果如下图: 服务端代码: Socket serverSocket = new ...
- asp.net MVC 应用程序的生命周期
下面这篇文章总结了 asp.net MVC 框架程序的生命周期.觉得写得不错,故转载一下. 转载自:http://www.cnblogs.com/yplong/p/5582576.html ...
- ef
现阶段使用回溯 entityframework作为.net平台自己的一个orm的框架,之前在项目中也有使用,主要采用了table和model first的方式,此两种感觉使用上也是大同小异.在项目中经 ...
- 【微信开发】公众号后台设置错误导致的微信redirect_uri参数错误【图】
在微信开发中,如微信网页授权登录,分享到朋友圈自定义内容,微信h5支付时 可能会遇到微信redirect_uri参数错误的情况. 此时除了检查自己代码正确性外,还要检查一下是否正确地设置了公众号后台的 ...
- PowerDesigner从Sqlserver中反转为带注释的字典及快捷键操作
PowerDesigner的操作经常忘记,所以把常用的功能记录下来备忘. 1.修改反转过来的字段 PowerDesigner从数据库反转的时候,默认不带注释,需要先进行修改. 输入如下脚本: {OWN ...
- BroadcastReceiver几种常见监听
1.BroadcastReceiver监听拨号 <intent-filter android:priority="1000" > <action android: ...
- 解决mysql too many connections的问题
由于公司服务器上的创建的项目太多,随之创建的数据库不断地增加,在用navicat链接某一个项目的数据库时会出现too many connections ,从而导致项目连接数据库异常,致使启动失败. 为 ...
- spring mvc返回json字符串的方式
spring mvc返回json字符串的方式 方案一:使用@ResponseBody 注解返回响应体 直接将返回值序列化json 优点:不需要自己再处理 步骤一:在spring- ...
- js 隐式转换
1.数字number与字符串string相加的就,最后会得到一个字符串string:'1'+3='13' 2.数字number与字符串string相减,最后会得到一个数字number:'1'-0=1, ...