初探 CoreOS

shan

CoreOS 是一个新兴项目,旨在解决服务器世界中最紧迫的问题之一。 因此,我们 eNovance 发布了 eDeploy:一种执行裸机部署并轻松管理升级的工具。 部署和升级服务器是目前 IT 世界中的两大问题,因为很少有人知道如何操作。 我忍不住尝试一下 CoreOS。

一、CoreOS 是什么?

一.1. 起源

该项目基于 Google 的 ChromeOS,基本上是一个分支。 通过带来一种新的思维方式,CoreOS 依赖于以下几点

  1. 最小操作系统:内核 + systemd
  2. Docker 兼容:专为容器构建
  3. 服务发现:默认情况下使用 etcd 集群,etcd 是一个高度可用的键值存储,用于共享配置

CoreOS 为所有应用程序提供了一个统一的基础,因为它们位于由优秀的 Docker 提供支持的容器内。 这为所有应用程序提供了通用且完美的隔离。 然后,将应用程序从一台 CoreOS 服务器移动到另一台服务器变得相当容易。 此外,CoreOS 根文件系统以只读方式挂载,这很好,因为这确保了从一台服务器到另一台服务器的完美一致性。

一.2. 升级和安全性

升级 CoreOS 与通常的发行版有所不同。 更新系统基于 ChromeOS,后者执行自动升级。 CoreOS 使用两个根分区:一个处于活动状态(root A),另一个处于被动状态(root B)。 最初,系统启动到 root A 分区。 在此序列期间,CoreOS 开始与更新服务通信,以确定是否有可用的更新。 如果有,则将它们下载并安装到 root B。 在将这些更新安装到 root B 时,更新过程通过 cgroups 进行速率限制。

如果您想了解更多更新,请阅读 CoreOS 博客

一.3. 服务发现 ETCD

ETCD 是一个分布式配置服务。 最终目标是在所有 CoreOS 服务器上一次性且原子地共享和配置 Docker 容器。 虽然这方面尚未定义任何内容。

ETCD 还负责服务发现。 在 Docker 容器内运行的服务在 ETCD 中注册,以便集群稍后可以使用它们。

有关 ETCD 的更多信息,请参阅 CoreOS 博客

二、深入 CoreOS

二.1. 简单的方法:Vagrant

最近,在 Vagrant 作者的帮助下,CoreOS 团队发布了一个 vagrant box。 像往常一样,这提供了一种尝试新项目的简单方法。

1
2
3
4
5
6
7
8
9
10
☁  ~ git clone https://github.com/coreos/coreos-vagrant/
☁  ~ cd coreos-vagrant
☁  ~ vagrant up
☁  ~ vagrant ssh
Last login: Fri Aug  2 23:49:42 UTC 2013 from 10.0.2.2 on pts/0
   ______                ____  _____
  / ____/___  ________  / __ \/ ___/
 / /   / __ \/ ___/ _ \/ / / /\__ \
/ /___/ /_/ / /  /  __/ /_/ /___/ /
\____/\____/_/   \___/\____//____/

二.2. 最小操作系统

摘自 CoreOS 网站

Linux 内核 + systemd。 就这些了。 CoreOS 只有足够的组件来运行容器,但本身不提供软件包管理器。 事实上,根分区完全以只读方式挂载,以保证一致性并使更新可靠。

好的,那么我们有什么? 我简要查看了 id 并发现这个轻量级(root 为 240MB)Gentoo 3.10.4+ VM。 请参阅 Alex Polvi 的解释

我们基于 ChromeOS SDK… 使用 emerge 构建所需的二进制文件来组装发行版。 您可以将 emerge/gentoo 视为用于构建所有二进制文件的工具链。 我们还从上游 portage 拉取基本系统包,然后将它们全部编译到我们的镜像中。

更多细节

NAME=CoreOS
ID=coreos
VERSION=32.0.0
VERSION_ID=32.0.0
BUILD_ID=32.0.0
PRETTY_NAME="CoreOS 32.0.0 (Official Build) dev-channel amd64-generic test"
ANSI_COLOR="1;32"
HOME_URL="http://www.coreos.com/"

二.2.1. 正在运行的服务

下面显示了所有正在运行的服务(不包括内核守护程序)

USER       PID   STAT  COMMAND
root         1   Ss    /sbin/init
root       180   Ss    /usr/lib/systemd/systemd-journald
root       201   Ss    /usr/lib/systemd/systemd-udevd
root       256   Ss    /sbin/dhcpcd -q --nobackground
201        259   Ss    /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root       265   Ssl   /usr/sbin/update_engine -foreground -logtostderr -no_connection_manager
root       266   Ss    /bin/bash /usr/sbin/update_engine_reboot_manager
root       278   S      \_ dbus-monitor --system type=signal,interface='org.chromium.UpdateEngineInterface',member='StatusUpdate'
root       279   S      \_ /bin/bash /usr/sbin/update_engine_reboot_manager
root       270   Ss    /usr/lib/systemd/systemd-logind
root       273   Ss+   /sbin/agetty --noclear tty1 38400 linux
root       288   Ssl   /usr/bin/docker -d -D
etcd       291   Ssl   /usr/bin/etcd -v -d /var/lib/etcd

有趣的是

  • etcd 进程在端口 70014001 上运行
  • docker 在端口 4243 上运行
  • update_engine

二.2.2. 分区

Number  Start   End     Size    File system  Name             Flags
 1      32.8kB  134MB   134MB   fat16        EFI-SYSTEM       boot
 2      134MB   201MB   67.1MB               BOOT-B
 3      201MB   1275MB  1074MB  ext2         ROOT-A
 4      1275MB  2349MB  1074MB               ROOT-B
 5      2349MB  2349MB  512B                 ROOT-C
 6      2349MB  2483MB  134MB   ext4         OEM
 7      2483MB  2483MB  512B                 coreos-reserved
 8      2483MB  2483MB  512B                 coreos-reserved
 9      2483MB  5704MB  3221MB  ext4         STATE

二.2.3. 挂载点

如前所述,CoreOS 的根分区以只读方式挂载。 是的,您 不能 写入操作系统。

/dev/sda3 on / type ext4 (ro,relatime)

注意:fstab 是空的,因为 systemd 在启动时挂载分区。 您可以在 /usr/lib/systemd/system 中找到每个挂载定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
core@localhost ~ $ sudo ls -l /usr/lib/systemd/system/*.mount
-rw-r--r-- 1 root root 636 Aug  2 04:35 dev-hugepages.mount
-rw-r--r-- 1 root root 590 Aug  2 04:35 dev-mqueue.mount
-rw-r--r-- 1 root root 197 Aug  2 04:42 home.mount
-rw-r--r-- 1 root root 352 Aug  2 04:42 media-state.mount
-rw-r--r-- 1 root root 200 Aug  2 04:42 media.mount
-rw-r--r-- 1 root root 195 Aug  2 04:42 opt.mount
-rw-r--r-- 1 root root 603 Aug  2 04:35 proc-sys-fs-binfmt_misc.mount
-rw-r--r-- 1 root root 195 Aug  2 04:42 srv.mount
-rw-r--r-- 1 root root 681 Aug  2 04:35 sys-fs-fuse-connections.mount
-rw-r--r-- 1 root root 685 Aug  2 04:35 sys-kernel-config.mount
-rw-r--r-- 1 root root 628 Aug  2 04:35 sys-kernel-debug.mount
-rw-r--r-- 1 root root 591 Aug  2 04:35 tmp.mount
-rw-r--r-- 1 root root 291 Aug  2 04:42 usr-share-oem.mount
-rw-r--r-- 1 root root 541 Aug  2 04:35 var-lock.mount
-rw-r--r-- 1 root root 536 Aug  2 04:35 var-run.mount
-rw-r--r-- 1 root root 320 Aug  2 04:42 var.mount

请注意,以下挂载是从 /media/state/overlays/ 绑定的

  • /home
  • /opt
  • /srv
  • /var/lock
  • /var/run
  • /var

二.2.4. 可能有趣的东西

Vrak

  • /usr/sbin/write_gpt.sh
  • /usr/lib/coreos/
  • /usr/bin/coreos-c10n

二.3. Docker 准备就绪

二.3.1. Docker 是什么?

描述摘自 Docker 网站

Docker 是一个开源引擎,可自动将任何应用程序作为轻量级、可移植、自包含的容器部署,该容器几乎可以在任何地方运行。

Docker 容器可以封装任何有效负载,并且将在虚拟机、裸机服务器、OpenStack 集群、公共实例或上述组合上一致地运行和扩展。 开发者构建和测试的与在生产环境中运行的容器相同。

Docker 的常见用例包括

  • 自动化应用程序的打包和部署
  • 创建轻量级、私有 PAAS 环境
  • 自动化测试和持续集成/部署
  • 部署和扩展 Web 应用程序、数据库和后端服务

Docker 构建在 LXC 之上,LXC 提供命名空间功能,例如 PID、网络、IPS、mnt 和 UTS 命名空间。 它还使用控制组来管理资源会计和限制。 所有这些都由内核本身提供。

Docker 发展非常迅速,甚至即将进入 OpenStack Havana 作为新的虚拟机监控程序

二.3.2. 玩转 Docker!

我们将通过一个简单的 memcached 示例来演示 Docker 的强大功能。

默认情况下,CoreOS 不会随 Docker 附带任何镜像,因此我们需要拉取一些

1
2
3
4
5
6
7
8
9
core@localhost ~ $ docker pull ubuntu
Pulling repository base
Pulling image b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc (ubuntu-quantl) from base
Pulling b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc metadata
Pulling b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc fs layer
Downloading 10.24 kB/10.24 kB (100%)
Pulling 27cf784147099545 metadata
Pulling 27cf784147099545 fs layer
Downloading 94.86 MB/94.86 MB (100%)

请注意,从 Docker 0.6 开始,您需要 root 权限才能运行 docker 命令。 如果您真的想让普通用户使用 docker 命令,可以使用“-H”标志反转您的配置。

顺便说一下,如果您遇到

[debug] server.go:457 Updating checksums
[debug] server.go:463 Retrieving the tag list
[debug] server.go:466 Get https://cdn-registry-1.docker.io/v1/repositories/library/base/tags: x509: certificate has expired or is not yet valid

这意味着您的机器时间在 SSL 证书颁发之前或到期之后。 因此,您需要手动设置日期

1
2
core@localhost ~ $ sudo date --set="Thu Aug  28 10:05:20 UTC 2013"
Wed Aug 28 10:05:20 UTC 2013

启动容器

1
2
3
4
5
6
7
8
9
10
11
12
core@localhost ~ $ sudo docker run -i -t base /bin/bash
root@156ddbdd1dc2:/# apt-get update && apt-get install -y memcached
...
...
...
root@156ddbdd1dc2:/# ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  18064  1944 ?        S    23:50   0:00 /bin/bash
memcache   197  0.0  0.1 327440  1244 ?        Sl   23:54   0:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1
root       209  0.0  0.1  15528  1108 ?        R+   23:58   0:00 ps auxf
root@156ddbdd1dc2:/# exit
exit

容器已停止,但仍位于本地注册表中

1
2
3
4
5
6
core@localhost ~ $ docker ps -a
ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS
156ddbdd1dc2        base:latest         /bin/bash           12 minutes ago      Exit 0
5ec55e697129        base:latest         /bin/bash           12 minutes ago      Exit 0
core@localhost ~ $ docker commit 156ddbdd1dc2 leseb/memcached
abac19018985

如您所见,现在该镜像已添加到我的本地注册表中

1
2
3
4
5
6
7
core@localhost ~ $ docker images
REPOSITORY          TAG                 ID                  CREATED              SIZE
base                latest              b750fe79269d        5 months ago         24.65 kB (virtual 180.1 MB)
base                ubuntu-12.10        b750fe79269d        5 months ago         24.65 kB (virtual 180.1 MB)
base                ubuntu-quantal      b750fe79269d        5 months ago         24.65 kB (virtual 180.1 MB)
base                ubuntu-quantl       b750fe79269d        5 months ago         24.65 kB (virtual 180.1 MB)
leseb/memcached     latest              abac19018985        About a minute ago   138.6 MB (virtual 318.7 MB)

让我们运行它!

1
2
3
4
5
core@localhost ~ $ docker run -d -p 11211 leseb/memcached memcached /usr/bin/memcached -m 64 -p 11211 -u memcache -l 0.0.0.0
bfa0ba848450
core@localhost ~ $ docker ps
ID                  IMAGE                    COMMAND                CREATED             STATUS              PORTS
bfa0ba848450        leseb/memcached:latest   memcached /usr/bin/m   14 seconds ago      Up 13 seconds       49153->11211

验证容器是否正确运行以及是否绑定到本地端口 49153

1
2
3
4
5
core@localhost ~ $ ps aux|grep [l]xc
root      1205  0.0  0.1  21088  1168 pts/1    S+   00:10   0:00 lxc-start -n bfa0ba8484505752635d43549853b51465c3e83765c8b1892f07c846304cb3d7 -f /var/lib/docker/containers/bfa0ba8484505752635d43549853b51465c3e83765c8b1892f07c846304cb3d7/config.lxc -- /sbin/init -g 172.17.42.1 -e HOME=/ -e PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -e container=lxc -e HOSTNAME=bfa0ba848450 -- memcached /usr/bin/memcached -m 64 -p 11211 -u memcache -l 0.0.0.0

core@localhost ~ $ netstat -lantue|grep 49153
tcp        0      0 127.0.0.1:49153         0.0.0.0:*               LISTEN      0          13806

您可能想知道(就像我一样),如何与正在运行的容器交互。 假设容器正在运行,我想为 memcached 分配更多内存。 Docker 并非设计用于执行实时修改,而是更喜欢对所有容器进行版本控制。 假设容器在生产环境中运行,您可能希望在安全的环境中测试您即将进行的更改,基本上是一个新的容器。

二.4. 服务发现:ETCD

描述摘自 GitHub 项目。

一个高度可用的键值存储,用于共享配置和服务发现。 etcd 受 zookeeper 和 doozer 的启发,重点在于

  • 简单:可 curl 的用户界面 API(HTTP+JSON)
  • 安全:可选的 SSL 客户端证书身份验证
  • 快速:每实例基准测试 1000 次写入/秒
  • 可靠:使用 Raft 正确分发

Etcd 使用 Go 编写,并使用 raft 共识算法来管理高度可用的复制日志。

ETCD 最近进入 v0.1.0,请参阅 官方公告

我不会从 GitHub 项目文档中复制/粘贴非常好的说明。 因此,我强烈建议您查看 此处的使用说明。 还要查看 客户端工具

CoreOS 仍然是 Alpha 版本,但我发现他们已经取得了令人惊讶的进展。 社区的反应也非常好。 希望它能继续保持下去!