CoreOS-精要-全-

CoreOS 精要(全)

原文:annas-archive.org/md5/67b7f0648c51eef801b6977d634ac230

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

CoreOS 是一种新型的 Linux 操作系统,经过优化可运行 Linux 容器,如 Docker 和 rkt。它具有完全自动化的更新系统、没有包管理器,并且拥有完全集群化的架构。

无论你是 Linux 专家还是刚入门并对 Linux 有一些了解的初学者,本书将为你提供逐步的安装和配置 CoreOS 服务器的说明,同时构建开发和生产环境。你将接触到新的 CoreOS rkt 应用容器运行时引擎和谷歌的 Kubernetes 系统,它能让你将一个 Linux 容器集群作为一个单独的系统进行管理。

本书内容概述

第一章, CoreOS – 概述与安装, 包含了关于 CoreOS 的简要概述,讲解了 CoreOS 的相关内容。

第二章, 使用 etcd 入门, 解释了什么是 etcd 以及它的用途。

第三章, 使用 systemd 和 fleet 入门, 介绍了 systemd 的概述。本章告诉你什么是 fleet 以及如何使用它来部署 Docker 容器。

第四章, 管理集群, 是关于设置和管理集群的指南。

第五章, 构建开发环境, 向你展示如何设置 CoreOS 开发环境来测试你的应用容器。

第六章, 构建部署设置, 帮助你设置代码部署、Docker 镜像构建器和私有 Docker 注册表。

第七章, 构建生产集群, 讲解了如何在云端设置 CoreOS 生产集群。

第八章, 介绍 CoreUpdate 和容器/企业注册表, 概述了免费和付费的 CoreOS 服务。

第九章, CoreOS rkt 入门, 告诉你什么是 rkt 以及如何使用它。

第十章, Kubernetes 入门, 教你如何设置和使用 Kubernetes。

本书所需条件

对于本书,你需要一个 Linux 系统或一台 Apple Mac 电脑,以及一个 Google Cloud 账户来运行示例。同时,你还需要最新版本的 VirtualBox 和 Vagrant 来运行脚本。

本书适用对象

本书适用于任何 Linux/Unix 系统管理员。即使是对 Linux/Unix 有基本了解的人,在使用本书时也会有一定的优势。

本书同样适用于已经熟悉网络虚拟化的系统工程师和系统管理员,他们希望了解如何利用 CoreOS 开发计算网络,以便部署应用程序和服务器。他们必须具备扎实的 Linux 操作系统和应用容器知识,最好曾经使用 Linux 发行版进行开发或管理工作。

约定

本书中,你将会看到多种不同风格的文本,区分不同类型的信息。以下是这些风格的一些示例,并对其含义进行解释。

文本中的代码词汇如下所示:“我们可以通过使用include指令包含其他上下文。”

代码块如下所示:

  etcd2:
    name: core-01
    initial-advertise-peer-urls: http://$private_ipv4:2380
    listen-peer-urls: http://$private_ipv4:2380,http://$private_ipv4:7001
    initial-cluster-token: core-01_etcd
    initial-cluster: core-01=http://$private_ipv4:2380
    initial-cluster-state: new
    advertise-client-urls: http://$public_ipv4:2379,http://$public_ipv4:4001
    listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
  fleet:

任何命令行输入或输出都如下所示:

$ git clone https://github.com/coreos/coreos-vagrant/

新术语重要词汇以粗体显示。例如,你在屏幕上、菜单或对话框中看到的词汇,文本中会像这样出现:“我们应该在终端窗口中看到这个输出。”

注意

警告或重要提示以框的形式出现,如下所示。

提示

小贴士和技巧以如下方式出现。

读者反馈

我们始终欢迎读者的反馈。告诉我们你对本书的看法——你喜欢或不喜欢什么。读者的反馈对我们非常重要,因为它帮助我们开发出更符合你需求的书籍。

若要向我们发送一般反馈,只需发送电子邮件至 <feedback@packtpub.com>,并在邮件主题中提及书名。

如果你在某个领域有专长,并且对写作或参与书籍的编写感兴趣,可以查看我们的作者指南:www.packtpub.com/authors

客户支持

现在你已经成为一本 Packt 图书的自豪拥有者,我们提供了一些工具帮助你从购买中获得最大收益。

下载示例代码

你可以从你的账户中下载示例代码文件,访问 www.packtpub.com 获取你所购买的所有 Packt 出版的书籍的示例代码。如果你是在其他地方购买的本书,你可以访问 www.packtpub.com/support,并注册以便直接将文件通过电子邮件发送给你。

勘误

尽管我们已尽一切努力确保内容的准确性,但错误仍然可能发生。如果您在我们的书籍中发现错误——可能是文本或代码中的错误——我们将非常感激您能向我们报告。这样,您不仅能帮助其他读者避免困扰,还能帮助我们改进后续版本的书籍。如果您发现任何勘误,请通过访问 www.packtpub.com/submit-errata,选择您的书籍,点击勘误提交表单链接,并输入您的勘误详细信息。待勘误确认后,您的提交将被接受,勘误将上传至我们的网站,或添加到该书标题的现有勘误列表中。

要查看之前提交的勘误,访问 www.packtpub.com/books/content/support 并在搜索框中输入书名。所需信息将在勘误部分显示。

盗版

互联网上的版权素材盗版问题在所有媒体中都是一个持续存在的问题。在 Packt,我们非常重视版权和许可的保护。如果您在互联网上发现我们的作品的任何非法复制,请立即向我们提供其位置地址或网站名称,以便我们采取措施。

我们感谢您帮助保护我们的作者,并支持我们为您提供有价值的内容。

问题

如果您在书中的任何方面遇到问题,可以通过 <questions@packtpub.com> 联系我们,我们将尽力解决您的问题。

第一章:CoreOS – 概述与安装

CoreOS 通常被描述为大规模服务器部署的 Linux,但它也可以轻松地作为单一主机运行在裸金属、云服务器上,甚至可以作为虚拟机在你的计算机上运行。它旨在运行 dockerrkt 应用容器,稍后你将在本书中了解它的主要功能。

本书是一本实用的、以示例为驱动的指南,帮助你学习 CoreOS Linux 操作系统的基础知识。我们假设你有 VirtualBox、Vagrant、Git、Bash 脚本和命令行(UNIX 类计算机的终端)的经验,并且已经在 Mac OS X 或 Linux 计算机上安装了 VirtualBox、Vagrant 和 git,这些将是前几章所需的工具。至于云安装,我们将使用 Google Cloud 的 Compute Engine 实例。

到本书结束时,你应该已经熟悉如何在你的笔记本或台式机以及云端上设置 CoreOS。你将学习如何设置本地计算机开发机器以及本地和云中的集群。此外,我们还将涵盖 etcdsystemdfleet、集群管理、部署设置和生产集群等内容。

另外,最后一章将介绍 Google Kubernetes。这是一个开源的容器编排系统,用于管理 dockerrkt 容器,并允许在计算集群中将它们作为一个整体进行管理。

本章中,你将学习 CoreOS 的工作原理,并通过 VirtualBox 和 Vagrant 的帮助,在你的笔记本或台式机上进行基本的 CoreOS 安装。

本章我们将基本讨论两个主题:

  • CoreOS 概述

  • 安装 CoreOS 虚拟机

CoreOS 概述

CoreOS 是一个最小化的 Linux 操作系统,旨在运行 dockerrkt 容器(应用容器)。默认情况下,它被设计用于构建强大且易于管理的服务器集群。它为所有机器提供自动、非常可靠且稳定的更新,从而减轻了 sysadmins 的维护负担。而且,通过将一切都运行在应用容器中,这种设置使得你可以非常轻松地扩展服务器和应用,替换故障的服务器仅需几分之一秒,等等。

CoreOS 如何工作

CoreOS 没有包管理器,因此一切都需要通过 docker 容器进行安装和使用。此外,CoreOS 在 RAM 使用效率上比普通 Linux 安装高出 40%,如下图所示:

CoreOS 如何工作

CoreOS 使用主动/被动双分区方案进行更新,将其作为一个整体进行更新,而不是采用逐个包的方法。其根分区是只读的,只有在应用更新时才会发生更改。如果更新在重启时失败,它将回滚到之前的启动分区。下图展示了操作系统更新被应用到 B 分区(被动)并在重启后变为启动用的活动分区。

CoreOS 如何工作

dockerrkt 容器作为应用程序在 CoreOS 上运行。容器为应用程序打包提供了非常好的灵活性,且能够非常快速地启动——仅需几毫秒。下图展示了 CoreOS 的简洁性。底层是 Linux 操作系统,第二层是带有 docker 守护进程的 etcd/fleet,顶层是服务器上运行的容器。

CoreOS 如何工作

默认情况下,CoreOS 被设计为以集群形式工作,但它也能很好地作为单个主机工作。通过 fleet 可以非常容易地跨集群机器控制和运行应用容器,并使用 etcd 服务发现将它们连接在一起,正如下图所示。

CoreOS 如何工作

CoreOS 可以轻松部署在所有主要的云服务提供商上,例如 Google Cloud、Amazon Web Services、Digital Ocean 等等。它在裸金属服务器上也运行得非常好。此外,它还可以通过 Vagrant,使用 VirtualBox 或 VMware 虚拟机支持,轻松安装在运行 Linux、Mac OS X 或 Windows 的笔记本或台式机上。

这段简短的概述应该能帮助你理解 CoreOS 的基本概念及其功能。接下来,让我们进入实际操作,安装 CoreOS 到我们的笔记本或台式机上。

安装 CoreOS 虚拟机

要使用 CoreOS 虚拟机,你需要在计算机上安装 VirtualBox、Vagrant 和 git。

在接下来的示例中,我们将在本地计算机上安装 CoreOS,这将作为 VirtualBox 上的虚拟机。

好的,让我们开始吧!

克隆 coreos-vagrant GitHub 项目

让我们克隆这个项目并启动它。

在终端中(从现在开始,我们将只使用终端短语,并用 $ 来标记终端提示符),输入以下命令:

$ git clone https://github.com/coreos/coreos-vagrant/

这将从 GitHub 仓库克隆到你计算机上的 coreos-vagrant 文件夹。

使用 cloud-config

要启动单个主机,我们需要通过用户数据文件以 cloud-config 格式提供一些 config 参数。

在你的终端中,输入以下命令:

$ cd coreos-vagrant
$ mv user-data.sample user-data

用户数据应该包含类似这样的内容(coreos-vagrant GitHub 仓库不断更新,所以当你克隆仓库时,可能会看到稍有不同的内容):

#cloud-config
coreos:
  etcd2:
    #generate a new token for each unique cluster from https://discovery.etcd.io/new
    #discovery: https://discovery.etcd.io/<token>
    # multi-region and multi-cloud deployments need to use $public_ipv4
    advertise-client-urls: http://$public_ipv4:2379
    initial-advertise-peer-urls: http://$private_ipv4:2380
    # listen on both the official ports and the legacy ports
    # legacy ports can be omitted if your application doesn't depend on them
    listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
    listen-peer-urls: http://$private_ipv4:2380,http://$private_ipv4:7001
  fleet:
    public-ip: $public_ipv4
  flannel:
    interface: $public_ipv4
  units:
    - name: etcd2.service
      command: start
    - name: fleet.service
      command: start
    - name: docker-tcp.socket
      command: start
      enable: true
      content: |
        [Unit]
        Description=Docker Socket for the API

        [Socket]
        ListenStream=2375
        Service=docker.service
        BindIPv6Only=both
        [Install]
        WantedBy=sockets.target 

etcd2:fleet: 行之间的文本替换成如下内容:

  etcd2:
    name: core-01
    initial-advertise-peer-urls: http://$private_ipv4:2380
    listen-peer-urls: http://$private_ipv4:2380,http://$private_ipv4:7001
    initial-cluster-token: core-01_etcd
    initial-cluster: core-01=http://$private_ipv4:2380
    initial-cluster-state: new
    advertise-client-urls: http://$public_ipv4:2379,http://$public_ipv4:4001
    listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
  fleet:

注意

你也可以从 github.com/rimusz/coreos-essentials-book/blob/master/Chapter1/user-data 下载最新的 user-data 文件。

这应该足以启动一个带有 etcdfleetdocker 运行的单主机 CoreOS 虚拟机。

我们将在后续章节中更详细地讨论 cloud-configetcdfleet

启动和 SSH

现在是启动我们的 CoreOS 虚拟机并使用 ssh 登录其控制台的时候了。

让我们启动我们的第一个 CoreOS 虚拟机主机。为此,使用终端输入以下命令:

$ vagrant up

这将触发 vagrant 下载最新的 CoreOS alpha 版本(这是config.rb文件中设置的默认频道,可以很容易地更改为 beta 或稳定版本)镜像和lunch虚拟机实例。

你应该在终端中看到类似以下的输出:

启动和 SSH

CoreOS 虚拟机已启动,现在让我们使用以下命令打开与新虚拟机的ssh连接:

$ vagrant ssh

它应该显示类似以下内容:

CoreOS alpha (some version)
core@core-01 ~ $

提示

下载示例代码

你可以从你在www.packtpub.com上的账户下载所有购买的 Packt Publishing 书籍的示例代码文件。如果你在其他地方购买了本书,可以访问www.packtpub.com/support并注册,文件将直接通过电子邮件发送给你。

完美!让我们验证一下etcdfleetdocker是否正常运行。以下是所需命令及相应的输出截图:

$ systemctl status etcd2

启动和 SSH

要检查fleet的状态,请键入以下命令:

$ systemctl status fleet

启动和 SSH

要检查docker的状态,请键入以下命令:

$ docker version

启动和 SSH

很棒!一切看起来都正常。因此,我们成功地在 VirtualBox 中启动了第一个 CoreOS 虚拟机。

总结

在本章中,我们了解了 CoreOS 是什么以及如何安装。我们使用 Vagrant 和 VirtualBox 帮助完成了在本地计算机上的 CoreOS 安装,并检查了etcdfleetdocker是否正常运行。

在接下来的章节中,你将继续更详细地探索和学习所有 CoreOS 服务。

第二章:开始使用 etcd

在本章中,我们将介绍 etcd,CoreOS 的服务中央枢纽,它提供了一种可靠的方式来跨集群机器存储共享数据并进行监控。

为了进行测试,我们将使用上一章中已经安装的 CoreOS 虚拟机。在本章中,我们将覆盖以下主题:

  • 介绍 etcd

  • 从主机机器读取和写入到 etcd

  • 从应用容器读取和写入

  • 观察 etcd 中的变化

  • TTL(生存时间)示例

  • etcd 的使用案例

介绍 etcd

etcd 功能是一个开源的分布式键值存储系统,运行在计算机网络上,其中信息存储在多个节点上,并通过 Raft 共识算法进行数据复制。etcd 功能用于存储 CoreOS 集群的服务发现和共享配置。

配置信息存储在预写日志中,包括集群成员 ID、集群 ID 和集群配置,并且可以被所有集群成员访问。

etcd 功能在每个集群的中央服务角色机器上运行,并在网络分区或当前主节点丢失时优雅地处理主节点选举。

从主机机器读取和写入到 etcd

你将学习如何从主机机器读取和写入 etcd。我们将在这里使用 etcdctlcurl 示例。

登录到主机

要登录到 CoreOS 虚拟机,请按以下步骤操作:

  1. 启动第一章中安装的 CoreOS 虚拟机。在你的终端中输入以下命令:

    $ cdcoreos-vagrant
    $ vagrant up
    
    
  2. 我们需要通过 ssh 登录到主机:

    $ vagrant ssh
    
    

读取和写入到 etcd

让我们使用 etcdctl 读取和写入 etcd。所以,请执行以下步骤:

  1. 使用 etcdctl 设置一个名为 message1 的键,其值为 Book1

    $ etcdctl set /message1 Book1
    Book1 (we got respond for our successful write to etcd)
    
    
  2. 现在,让我们读取键值,确认一切是否正常:

    $ etcdctl get /message1
    Book1
    Perfect!
    
    
  3. 接下来,让我们通过基于 HTTP 的 API 使用 curl 尝试做同样的操作。curl 功能非常方便,可以从任何可以访问 etcd 集群的地方访问 etcd,但你不想/不需要使用 etcdctl 客户端:

    $ curl -L -X PUT http://127.0.0.1:2379/v2/keys/message2 -d value="Book2"
    {"action":"set","key":"/message2","prevValue":"Book1","value":"Book2","index":13371}
    
    

    让我们来读取它:

    $ curl -L http://127.0.0.1:2379/v2/keys/message2
    {"action":"get","node":{"key":"/message2","value":"Book2","modifiedIndex":13371,"createdIndex":13371}}
    
    

    使用基于 HTTP 的 etcd API,意味着客户端应用程序可以直接读取和写入 etcd,无需与命令行交互。

  4. 现在,如果我们想删除键值对,我们输入以下命令:

    $ etcdctl rm /message1
    $ curl -L -X DELETE http://127.0.0.1:2379/v2/keys/message2
    
    
  5. 此外,我们可以向目录中添加键值对,因为当将键放入目录中时,目录会自动创建。我们只需要一个命令就能将键放入目录:

    $ etcdctl set /foo-directory/foo-key somekey
    
    
  6. 现在让我们检查目录的内容:

    $ etcdctl ls /foo-directory –recursive
    /foo-directory/foo-key
    
    
  7. 最后,我们可以通过输入以下命令从目录中获取键值:

    $ etcdctl get /foo-directory/foo-key
    somekey
    
    

从应用容器读取和写入

通常,应用容器(这是 dockerrkt 和其他类型容器的通用术语)默认情况下没有安装 etcdctl,甚至没有安装 curl。安装 curl 比安装 etcdctl 要容易得多。

对于我们的示例,我们将使用 Alpine Linux 的 docker 镜像,它非常小,不会花费太多时间从docker注册表中拉取:

  1. 首先,我们需要检查docker0接口的 IP 地址,稍后我们将使用该地址与curl配合使用:

    $ echo"$(ifconfig docker0 | awk'/\<inet\>/ { print $2}'):2379"
    10.1.42.1:2379
    
    
  2. 让我们使用bash shell 运行docker容器:

    $ docker run -it alpine ash
    
    

    在命令提示符中我们应该看到类似于/ #的内容:

  3. 由于 Alpine Linux 默认没有安装curl,我们需要安装它:

    $ apk update&&apk add curl
    $ curl -L http://10.1.42.1:2379/v2/keys/
    {"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"modifiedIndex":3,"createdIndex":3}]}}
    
    
  4. 重复上一个小节中的第 3 步和第 4 步,这样你就能明白无论你从哪里连接到etcdcurl的工作方式始终是一样的。

  5. Ctrl +D退出docker容器。

监视etcd中的变化

这次,让我们监视etcd中键值的变化。监视键值变化在以下情况下非常有用:例如,有一个fleet单元,它将nginx的端口写入etcd,而另一个反向代理应用程序则监视变化并更新其配置:

  1. 我们需要先在etcd中创建一个目录:

    $ etcdctlmkdir /foo-data
    
    
  2. 接下来,我们监视此目录中的变化:

    $ etcdctl watch /foo-data--recursive
    
    
  3. 现在,在新的终端窗口中打开另一个 CoreOS shell:

    $ cdcoreos-vagrant
    $ vagrantssh
    
    
  4. 我们在/foo-data目录下添加一个新键:

    $ etcdctl set /foo-data/Book is_cool
    
    
  5. 在第一个终端中,我们应该看到一条通知,提示键值已被更改:

    is_cool
    
    

TTL(生存时间)示例

有时,为键设置生存时间TTL)以便在一定时间后过期是非常方便的。例如,当监视一个 TTL 为 60 秒的键时,反向代理就会用到 TTL。因此,如果nginx fleet服务没有更新该键,它将在 60 秒内过期并从etcd中删除。然后,反向代理检查时未找到该键,因此会将nginx服务从config中移除。

让我们在这个示例中设置 TTL 为 30 秒:

  1. 在终端中输入以下内容:

    $ etcdctl set /foo "I'm Expiring in 30 sec" --ttl 30
    I'm Expiring in 30 sec
    
    
  2. 验证该键是否仍然存在:

    $ etcdctl get /foo
    I'm Expiring in 30 sec
    
    
  3. 30 秒后再次检查:

    $ etcdctl get /foo
    
    
  4. 如果您请求的键已经过期,您将收到错误100

    Error: 100: Key not found (/foo) [17053]
    
    

这次,etcd删除了该键,因为我们为它设置了 30 秒的 TTL。

注意

TTL 在使用etcd作为检查点进行不同服务之间的通信时非常方便。

etcd的使用案例

运行在工作节点上的应用程序容器,可以在代理模式下读取和写入etcd集群。

etcd的常见使用案例如下:存储数据库连接设置、缓存设置和共享设置。例如,Vulcand 代理服务器(vulcanproxy.com/)使用etcd存储 Web 主机连接详细信息,这些信息对所有集群连接的工作节点机器可用。另一个例子是存储 MySQL 的数据库密码,并在运行应用程序容器时检索它。

在接下来的章节中,我们将详细讨论集群设置、中央服务和工作节点角色机器。

总结

在这一简短的章节中,我们介绍了etcd的基础知识,以及如何读取和写入etcd,监视etcd中的变化,并使用 TTL 设置etcd键的生存时间。

在下一章中,你将学习如何使用systemdfleet单元。

第三章:开始使用 systemd 和 fleet

在本章中,我们将介绍systemdfleet的基础知识,包括系统单元文件。我们将演示如何使用fleet来启动 Docker 容器。

本章将涵盖以下主题:

  • 开始使用systemd

  • 开始使用fleet

开始使用 systemd

你将学习什么是systemd以及如何使用systemctl来控制systemd单元。

systemd 概述

systemd是 CoreOS 使用的初始化系统,用于启动、停止和管理进程。

基本上,它是 CoreOS 的系统和服务管理器。在 CoreOS 上,systemd几乎完全用于管理 Docker 容器的生命周期。systemd记录每个进程在单元文件中的初始化指令,单元文件有许多种类,但我们主要讨论"服务"单元文件,因为涵盖所有单元文件超出了本书的范围。

systemd 单元文件

systemd记录每个进程在我们希望运行的"服务"单元文件中的初始化指令/属性。在 CoreOS 上,用户手动安装或通过 cloud-init 安装的单元文件放置在/etc/systemd/system,这是一个可读写的文件系统,因为 CoreOS 的大部分内容只有只读访问权限。由 CoreOS 团队策划的单元文件放在/usr/lib64/system/system,而临时单元文件仅在一次启动的运行时存在,存放在/run/system/system。这一点对于调试fleet服务非常有帮助。

好的,让我们创建一个单元文件来测试systemd

  1. 启动你在第一章中安装的 CoreOS 虚拟机,并通过ssh登录主机。

  2. 让我们创建一个简单的单元文件hello.service

    $ sudo vi /etc/systemd/system/hello.service
    
    

    I键并复制粘贴以下文本(或者使用提供的示例文件hello.service):

    [Unit]
    Description=HelloWorld
    # this unit will only start after docker.service
    After=docker.service
    Requires=docker.service
    
    [Service]
    TimeoutStartSec=0
    # busybox image will be pulled from docker public registry
    ExecStartPre=/usr/bin/docker pull busybox
    # we use rm just in case the container with the name "busybox1" is left 
    ExecStartPre=-/usr/bin/docker rm busybox1
    # we start docker container
    ExecStart=/usr/bin/docker run --rm --name busybox1 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
    # we stop docker container when systemctl stop is used
    ExecStop=/usr/bin/docker stop busybox1
    
    [Install]
    WantedBy=multi-user.target
    
  3. Esc键,然后输入:wq保存文件。

  4. 要启动新的单元,运行以下命令:

    $ sudo systemctl enable /etc/systemd/system/hello.service
    
    

    /etc/systemd/system/multi-user.target.wants/hello.service创建了一个指向/etc/systemd/system/hello.service的符号链接。

    $ sudo systemctl start hello.service
    
    
  5. 让我们验证hello.service单元是否已启动:

    $ journalctl -f -u hello.service
    
    

    # 你应该看到类似以下的单元输出:

    The systemd unit files

另外,你可以查看通过docker ps运行的容器列表。

在之前的步骤中,我们创建了hello.service系统单元,启用了它并启动了它,然后用journalctl检查了该单元的日志文件。

注意

要了解更多关于systemd单元文件的高级用法,请访问coreos.com/docs/launching-containers/launching/getting-started-with-systemd

systemctl 概述

systemctl用于控制并提供systemd系统及其单元的状态检查。

它就像是你与系统的接口(类似于其他 Linux 发行版中的 supervisord / supervisordctl),因为所有在单台机器上的进程都是由 systemd 启动和管理的,包括 docker 容器。

我们已经在前面的示例中使用它来启用并启动 hello.service 单元。

以下是一些有用的 systemctl 命令及其用途:

  1. 检查单元的状态:

    $ sudo systemctl status hello.service
    
    

    你应该看到类似的输出,如下所示:

    systemctl 概览

  2. 停止服务:

    $ sudo systemctl stop hello.service
    
    
  3. 你可能需要强制停止服务,但这并不会停止 docker 容器:

    $ sudo systemctl kill hello.service
    $ docker ps
    
    

    你应该看到类似的输出,如下所示:

    systemctl 概览

  4. 如你所见,docker 容器仍在运行。因此,我们需要使用以下命令停止它:

    $ docker stop busybox1
    
    
  5. 重启服务:

    $ sudo systemctl restart hello.service
    
    
  6. 如果你修改了 hello.service,那么在重启之前,你需要重新加载所有服务文件:

    $ sudo systemctl daemon-reload
    
    
  7. 禁用服务:

    $ sudo systemctl disable hello.service
    
    

systemd 服务单元只能在单台机器上运行和控制,它们最好用于一些简单的任务,例如在重启时下载一些文件等。

你将在下一个主题和后续章节中继续学习 systemd

开始使用 fleet

我们使用 fleet 来充分利用 systemd 的高级功能。fleet 是一个集群管理器,在集群级别控制 systemd。你甚至可以在单台机器上使用它,并同样获得 fleet 的所有优势。

它鼓励用户将应用程序写成小而短暂的单元,这些单元可以轻松地在一个自我更新的 CoreOS 机器集群中迁移。

fleet 单元文件

fleet 单元文件是常规的 systemd 单元,并结合了特定的 fleet 属性。

fleet 单元文件

它们是与 fleet 进行交互的主要方式。与 systemd 单元一样,fleet 单元定义了你想要做什么以及 fleet 如何做。fleet 将会根据 [X-Fleet] 部分的 fleet 特殊属性,将有效的单元文件调度到单台机器或集群中的某台机器,这部分属性替代了 systemd 单元中的 [Install] 部分。其余的 systemd 部分在 fleet 单元中是相同的。

让我们概览一下 [X-Fleet] 部分的 fleet 特定选项:

  • MachineID:该单元将在由指定字符串识别的机器上调度。

  • MachineOf:此选项将机器限定为托管特定单元的机器。

  • MachineMetadata:这将使机器仅限于那些具有特定元数据的主机。

  • Conflicts:此选项可防止单元与其他单元一起部署,使用通配符匹配其他单元的名称。

  • Global:将此单元调度到集群中的所有机器。如果除了 MachineMetadata 以外提供了其他选项,则该单元被视为无效。

一个带有 [X-Fleet] 部分的 fleet 单元文件的编写示例如下:

[Unit]
Description=Ping google

[Service]
ExecStart=/usr/bin/ping google.com

[X-Fleet]
MachineMetadata=role=check
Conflicts=ping.*

那么,让我们看看 Conflicts=ping* 是如何工作的。例如,我们有两个相同的 ping.1.serviceping.2.service 文件,并且我们在集群中运行以下代码:

fleetctl start ping.* 

这将会在两台独立的集群机器上调度两个 fleet 单元。所以,让我们将之前使用的 systemd 单元 hello.service 转换为 fleet 单元。

  1. 像往常一样,您需要通过 vagrant ssh 登录到主机。

  2. 现在,让我们创建一个简单的单元文件,新的名称为 hello1.service

    $ sudo vi hello1.service
    
    

    按下 I 并复制粘贴如下文本:

    [Unit]
    Description=HelloWorld
    # this unit will only start after docker.service
    After=docker.service
    Requires=docker.service
    
    [Service]
    TimeoutStartSec=0
    # busybox image will be pulled from docker public registry
    ExecStartPre=/usr/bin/docker pull busybox
    # we use rm just in case the container with the name "busybox2" is left 
    ExecStartPre=-/usr/bin/docker rm busybox2
    # we start docker container
    ExecStart=/usr/bin/docker run --rm --name busybox2 busybox /bin/sh -c "while true; do echo Hello World; sleep 1; done"
    # we stop docker container when systemctl stop is used
    ExecStop=/usr/bin/docker stop busybox1
    
    [X-Fleet]
    
  3. 按下 Esc 然后输入 :wq 来保存文件。

    如您所见,当前我们的 [X-Fleet] 部分为空,因为我们暂时没有需要在那里使用的内容。我们将在接下来的章节中详细讲解这一部分。

  4. 首先,我们需要提交我们的 fleet 单元:

    $ fleetctl submit hello1.service
    
    
  5. 让我们验证我们的 fleet 单元文件:

    $ fleetctl list-unit-files
    
    

    舰队单元文件

  6. 要启动新的单元,运行以下命令:

    $ fleetctl start hello1.service
    
    

    舰队单元文件

    前面的命令已经提交并启动了 hello1.service

    让我们验证我们的新 fleet 单元是否正在运行:

    $ fleetctl list-units
    
    

    舰队单元文件

好的,现在是时候概览一下 fleetctl 命令了。

fleetctl 概览

fleetctl 命令与 systemctl 命令非常相似——您可以像下面这样看到这一点——而且我们不需要在 fleetctl 命令前使用 sudo。以下是您可以执行的一些任务,并列出了所需的命令:

  1. 检查单元的状态:

    $ fleetctl status hello1.service
    
    
  2. 停止服务:

    $ fleetctl stop hello1.service
    
    
  3. 查看服务文件:

    $ fleetctl cat hello1.service
    
    
  4. 如果您只想上传单元文件:

    $ fleetctl submit hello1.service
    
    
  5. 列出所有正在运行的舰队单元:

    $ fleetctl list-units
    
    
  6. 列出舰队集群机器:

    $ fleetctl list-machines
    
    

    fleetctl 概览

我们看到只有一台机器,就像我们这种情况一样,因为我们只有一台机器在运行。

当然,如果我们想查看 hello1.service 的日志输出,依然可以使用相同的 systemd journalctl 命令,如下所示:

$ journalctl -f -u hello1.service

您应该看到类似于以下的单元输出:

fleetctl 概览

参考资料

您可以通过以下给定的网址阅读更多相关主题:

总结

在本章中,您学习了 CoreOS 的 systemd 初始化系统。您还学习了如何使用 systemctlfleetctl 创建和控制系统和 fleet 服务单元。

在下一章中,您将学习如何设置和管理 CoreOS 集群。

第四章:集群管理

在本章中,我们将介绍如何在个人计算机上设置和管理本地 CoreOS 集群。你将学习如何引导一个三节点集群,通过cloud-config文件自定义它,并在集群中调度一个 fleet 单元。

在本章中,我们将涵盖以下主题:

  • 引导一个本地集群

  • 通过cloud-config文件自定义集群

  • 在集群中调度一个fleet单元

你将学习如何在个人计算机上设置一个简单的三节点集群。

确定最佳的 etcd 集群大小

最有效的集群大小是在三到九个节点之间。对于更大的集群,etcd将选择一部分实例参与,以保持集群的高效性。

集群越大,写入集群的速度越慢,因为所有数据都需要在集群的节点之间进行复制。为了优化集群,它需要基于奇数个节点构建。集群必须至少有三个节点的法定人数,并在发生网络分区时防止出现脑裂。

在我们的案例中,我们将设置一个三节点的etcd集群。为了在云上(如 GCE、AWS、Azure 等)构建一个高可用的集群,你应该使用多个可用区,以减少单个域故障的影响。

在一般的集群中,不建议将节点用于除运行etcd集群外的任何其他用途。但为了测试我们的集群设置,将一些fleet单元部署在那里是可以的。

在后续章节中,你将学习如何正确设置集群,以便用于生产环境。

引导一个本地集群

如前所述,我们将在计算机上安装一个三节点的etcd集群。

克隆 coreos-vagrant 项目

让我们克隆项目并让它运行。请按照以下步骤操作:

  1. 在终端或命令提示符中,输入以下内容:

    $ mkdir cluster 
    $ cd cluster
    $ git clone https://github.com/coreos/coreos-vagrant.git
    $ cd coreos-vagrant
    $ cpconfig.rb.sampleconfig.rb
    $ cp user-data.sample user-data
    
    
  2. 现在我们需要调整一些设置。编辑config.rb并将文件的顶部部分更改为以下示例:

    # Size of the CoreOS cluster created by Vagrant
    $num_instances=3
    
    # Used to fetch a new discovery token for a cluster of size $num_instances
    $new_discovery_url="https://discovery.etcd.io/new?size=#{$num_instances}"
    
    # To automatically replace the discovery token on 'vagrant up', uncomment
    # the lines below:
    #
    if File.exists?('user-data') &&ARGV[0].eql?('up')
      require 'open-uri'
      require 'yaml'
    
      token = open($new_discovery_url).read
    
      data = YAML.load(IO.readlines('user-data')[1..-1].join)
      if data['coreos'].key? 'etcd'
        data['coreos']['etcd']['discovery'] = token
      end
      if data['coreos'].key? 'etcd2'
        data['coreos']['etcd2']['discovery'] = token
      end
    
    yaml = YAML.dump(data)
    File.open('user-data', 'w') { |file| file.write("#cloud-config\n\n#{yaml}") }
    end
    #
    

    注意

    或者,你也可以使用本章中的示例代码,这些代码会随着 coreos-vagrant GitHub 仓库中的更改而保持更新。

    我们在这里做的操作如下:

    • 我们将集群设置为三实例

    • 每次执行vagrant up命令时,发现令牌会自动替换。

  3. 接下来,我们需要编辑用户数据文件:

    "#discovery: https://discovery.etcd.io/<token>"这一行改为如下:

    "discovery: https://discovery.etcd.io/<token>"
    

    所以,当我们下次启动基于 Vagrant 的集群时,我们将会有三个 CoreOS etcd节点在同一个集群中运行,并通过"https://discovery.etcd.io/<token>"提供的发现令牌连接。

  4. 现在使用以下命令启动我们的新集群:

    $ vagrant up
    
    

    我们应该在终端中看到如下内容:

    克隆 coreos-vagrant 项目

    等一下!还有更多输出!

    克隆 coreos-vagrant 项目

    现在集群应该已经启动并运行了。

  5. 要检查集群的状态,输入以下命令:

    $ vagrant status
    
    

    你应该能看到如下截图所示的内容:

    克隆 coreos-vagrant 项目

现在是时候测试我们的新 CoreOS 集群了。我们需要通过ssh连接到其中一台节点,并检查fleet机器。可以通过以下命令来完成:

$ vagrant ssh core-01 -- -A
$ fleetctl list-machines

我们应该能看到如下截图所示的内容:

克隆 coreos-vagrant 项目

太棒了!我们已经设置好了第一个 CoreOS 集群,看到三台机器都已启动并运行。现在,让我们尝试在etcd中设置一个键,以便稍后在另一台机器上检查。输入以下命令:

$ etcdctl set etcd-cluster-key "Hello CoreOS"

你将看到如下输出:

Hello CoreOS

按下 Ctrl+D 退出,并输入以下命令进入虚拟机主机的控制台:

$ vagrant ssh core-02 -- -A

让我们验证一下,我们是否也能看到新的etcd键:

$ etcdctl get etcd-cluster-key
Hello CoreOS

太棒了!我们的etcd集群运作得很好。

按下 Ctrl+Dcore-02机器退出。

通过 cloud-config 文件定制集群

让我们对cloud-config文件进行一些更改,并将其推送到集群机器中:

  1. 在用户数据文件(针对基于 Vagrant 的 CoreOS 的cloud-config文件)中,在fleet文本块下进行更改:

    public-ip: $public_ipv4
    

    添加一行:

    metadata: cluster=vagrant
    

    所以,它看起来像这样:

    fleet:
          public-ip: $public_ipv4
          metadata: cluster=vagrant
    
  2. 让我们也通过cloud-config将一个test.txt文件添加到/home/core文件夹。在用户数据文件的末尾,添加以下代码:

    write_files:
      - path: /home/core/test.txt
        permissions: 0644
        owner: core
        content: |
    Hello Cluster
    

    这将在每台集群机器的/home/core文件夹中添加一个新文件。

  3. 为了实施我们之前所做的更改,请运行以下命令:

    $ vagrant provision
    
    

    你将看到以下结果:

    通过 cloud-config 文件定制集群

    然后,运行以下命令:

    $ vagrant reload
    
    

    第一条命令临时更新了所有三台虚拟机上的用户数据文件,第二条命令重新加载了这些文件。

  4. 要通过ssh连接到其中一台虚拟机,输入以下代码:

    $ vagrant ssh core-03 -- -A
    $ ls
    test.txt
    
    
  5. 要查看test.txt文件的内容,请使用以下命令:

    $ cat test.txt
    
    

    你应该会看到如下输出:

    Hello Cluster
    
    

如你所见,我们通过cloud-config文件在所有集群机器上添加了一些文件。

让我们使用以下命令检查一下我们在该文件中做的另一个更改:

$ fleetctl list-machines

你将看到类似这样的内容:

通过 cloud-config 文件定制集群

因此,你可以看到我们通过cloud-init文件为集群机器分配了一些元数据。

在集群中调度一个 fleet 单元

现在,进入有趣的部分,我们将调度一个fleet单元到集群中。

  1. 让我们登录到core-03机器:

    $ vagrant ssh core-03 -- -A
    
    
  2. 通过复制并粘贴这一行,创建一个新的fleet单元hello-cluster.service

    $ vi hello-cluster.service
    [Unit]
    [Service]
    ExecStart=/usr/bin/bash -c "while true; do echo 'Hello Cluster'; sleep 1; done"
    
    
  3. 让我们为集群调度hello-cluster.service任务:

    $ fleetctl start hello-cluster.service
    
    

    你应该会看到如下输出:

    Unit hello-cluster.service launched on bb53c039.../172.17.8.103
    
    

    我们可以看到,hello-cluster.service被调度到172.17.8.103机器上运行,因为该机器是第一个响应fleetctl命令的。

    在后续章节中,你将学习如何将任务具体调度到某一台机器。现在让我们查看hello-cluster.service的实时日志:

    $ journalctl -u hello-cluster.service–f
    
    

    你会看到类似这样的内容:

    在集群中调度一个 fleet 单位

  4. 退出虚拟机并重新加载集群,请输入以下命令:

    $ vagrant reload
    
    
  5. 现在,再次ssh回任何一台机器:

    $ vagrant ssh core-02 -- -A
    
    
  6. 然后运行此命令:

    $ fleetctl list-units
    
    

    将看到以下输出:

    在集群中调度一个 fleet 单位

  7. 如您所见,hello-cluster.service 已在另一台机器上调度;在我们的案例中,它是 core-01。假设我们ssh到它:

    $ vagrant ssh core-01 -- -A
    
    
  8. 然后,在那里运行以下命令。结果,我们将再次看到实时日志:

    $ journalctl -u hello-cluster.service–f
    
    

    在集群中调度一个 fleet 单位

参考文献

您可以在coreos.com/docs/cluster-management/setup/cloudinit-cloud-config/了解有关如何使用 cloud-config 的更多信息。您可以在docs.vagrantup.com找到更多关于 Vagrant 的信息。如果您对 Vagrant 有任何问题或疑问,可以订阅 Vagrant Google 小组groups.google.com/forum/#!forum/vagrant-up

摘要

在本章中,您学习了如何设置 CoreOS 集群,通过 cloud-config 进行自定义配置,将fleet服务单位调度到集群,并检查集群状态和日志中的fleet单位。在下一章中,您将学习如何进行本地和云开发设置。

第五章. 构建开发环境

在本章中,我们将介绍如何在个人电脑上为 CoreOS 设置本地开发环境,以及在 Google Cloud 的 Compute Engine VM 实例上设置测试和暂存环境集群。以下是我们将要涵盖的主题:

  • 设置本地开发环境

  • 在 Google Cloud 的远程测试/暂存集群上引导

设置本地开发环境

我们将学习如何在个人电脑上设置开发环境,借助 VirtualBox 和 Vagrant 的帮助,就像我们在早期章节中所做的那样。构建和测试docker镜像以及在本地编码使您更加高效,节省时间,当您的 docker 镜像准备就绪时,可以将其推送到 docker 注册表(私有或公共)。对于代码也是一样;您只需在本地工作和测试。准备就绪后,可以将其与团队/客户测试分支合并。

设置开发虚拟机

在之前的章节中,您学习了如何通过 Vagrant 在您的个人电脑上安装 CoreOS。在这里,我们已经准备了 Linux 和 OS X 的安装脚本,以便快速进行设置。您可以从 GitHub 仓库下载最新的CoreOS Essentials书籍示例文件:

$ git clone https://github.com/rimusz/coreos-essentials-book/

要安装基于 Vagrant 的本地开发虚拟机,请键入以下命令:

$ cd coreos-essentials-book/chapter5/Local_Development_VM
$ ./install_local_dev.sh

您应该看到类似于这样的输出:

设置开发虚拟机

等等!还有更多内容!

设置开发虚拟机

这将执行类似于我们在第一章中所做的安装,CoreOS – 概述和安装,但这次是更自动化的方式。

VM 安装期间发生了什么?

让我们检查一下 VM 安装期间发生了什么。总结一下:

  • 安装了一个新的 CoreOS 虚拟机(基于 VirtualBox/Vagrant)

  • 在您的Home文件夹中创建了一个名为coreos-dev-env的新文件夹

运行以下命令:

$ cd ~/coreos-dev-env
$ ls
bin 
fleet 
share 
vm 
vm_halt.sh 
vm_ssh.sh 
vm_up.sh

因此,这就是我们看到的结果:

  • 包括以下列表的四个文件夹:

    • bindockeretcdctlfleetctl文件

    • fleetnginx.service fleet单元存储在这里

    • share:这是主机和 VM 之间共享的文件夹

    • vm:Vagrantfile、config.rbuser-data文件

  • 我们还有三个文件:

    • vm_halt.sh: 用于关闭 CoreOS 虚拟机

    • vm_ssh.sh:用于ssh到 CoreOS 虚拟机

    • vm_up.sh: 用于启动 CoreOS 虚拟机,操作系统的 shell 预设如下:

      # Set the environment variable for the docker daemon
      export DOCKER_HOST=tcp://127.0.0.1:2375
      # path to the bin folder where we store our binary files
      export PATH=${HOME}/coreos-dev-env/bin:$PATH
      # set etcd endpoint
      export ETCDCTL_PEERS=http://172.19.20.99:2379
      # set fleetctl endpoint
      export FLEETCTL_ENDPOINT=http://172.19.20.99:2379
      export FLEETCTL_DRIVER=etcd
      export FLEETCTL_STRICT_HOST_KEY_CHECKING=false
      

现在我们已经安装了 CoreOS 虚拟机,让我们运行vm_up.sh。我们应该在终端窗口看到以下输出:

$ cd ~/coreos-dev-env
$ ./vm_up.sh

您应该看到类似于这样的输出:

VM 安装期间发生了什么?

正如我们在前面的截图中看到的,我们没有任何错误。只有fleetctl list-machines显示我们的 CoreOS 虚拟机机器,并且那里没有docker容器和运行的fleet单元。

部署舰队单元

让我们部署一些 fleet 单元,验证我们的开发环境是否正常工作。运行以下命令:

$ cd fleet
$ fleetctl start nginx.service

注意

Docker 下载nginx镜像可能需要一些时间。

你可以查看nginx.service单元的状态:

$ fleetctl status nginx.service

你应该会看到类似于以下内容的输出:

部署 fleet 单元

一旦nginx fleet单元部署完成,打开浏览器并访问http://172.19.20.99。你应该会看到以下信息:

部署 fleet 单元

让我们查看一下发生了什么。我们用fleetctl调度了这个nginx.service单元:

$ cat ~/coreos-dev-env/fleet/nginx.service

[Unit]
Description=nginx

[Service]
User=core
TimeoutStartSec=0
EnvironmentFile=/etc/environment
ExecStartPre=-/usr/bin/docker rm nginx
ExecStart=/usr/bin/docker run --rm --name nginx -p 80:80 \
 -v /home/core/share/nginx/html:/usr/share/nginx/html \
 nginx:latest
#
ExecStop=/usr/bin/docker stop nginx
ExecStopPost=-/usr/bin/docker rm nginx

Restart=always
RestartSec=10s

[X-Fleet]

然后,我们从 docker 注册表使用了官方的nginx镜像,并将本地的~/coreos-dev-env/share文件夹与/home/core/share共享,之后该文件夹被挂载为 docker 卷/home/core/share/nginx/html:/usr/share/nginx/html

所以,任何我们放入本地~/coreos-dev-env/share/nginx/html文件夹的html文件都会被nginx自动获取。

让我们回顾一下这种环境给我们带来的优势:

  • 我们可以在本地构建和测试 docker 容器,然后将它们推送到 docker 注册表(无论是私有还是公共)。

  • 在完成本地代码测试后,将代码推送到 git 仓库。

  • 通过拥有本地开发环境,生产力显著提高,因为所有工作都能更快速地完成。我们不再需要在每次代码更改后构建新的 docker 容器、将其推送到远程 docker 注册表、在远程测试服务器上拉取它们,等等。

  • 清理该环境并从一个干净的起点重新启动非常简单,能够重新使用配置好的fleet单元启动所有需要的 docker 容器。

很好!现在,我们已经拥有了一个完全可用的本地开发环境!

注意

该环境设置符合 CoreOS 文档中coreos.com/docs/cluster-management/setup/cluster-architectures/的要求,在笔记本上的 Docker 开发环境部分。

查看coreos-dev-install.sh bash 脚本,该脚本设置了你的本地开发虚拟机。这是一个简单的脚本,并且注释清晰,因此理解其逻辑不应太难。

如果你是 Mac 用户,你可以从github.com/rimusz/coreos-osx-gui下载并使用我的 Mac 应用CoreOS-Vagrant GUI for Mac OS X,它有一个漂亮的 UI 来管理 CoreOS 虚拟机。它将自动设置 CoreOS 虚拟机环境。

部署 fleet 单元

在 GCE 上引导一个远程的测试/预发布集群

所以,我们成功建立了本地开发环境。接下来,让我们迈向下一个阶段,也就是在云端构建我们的测试/预发布环境。

我们将使用 Google Cloud 的 Compute Engine,所以你需要一个 Google Cloud 账号。如果没有,可以通过cloud.google.com/compute/注册一个试用账户。试用账户有效期为 60 天,且提供$300 的信用额度,足够运行本书中的所有示例。当账户创建完成后,需要从cloud.google.com/sdk/安装 Google Cloud SDK。

在本主题中,我们将参考coreos.com/docs/cluster-management/setup/cluster-architectures/中的Easy Development/Testing Cluster,并遵循其设置 CoreOS 集群的建议。

测试/暂存集群设置

好的,让我们安装云集群,你已经下载了本书中的代码示例。请按照以下顺序执行这些步骤:

  1. 执行以下命令:

    $ cd coreos-essentials-book/chapter5/Test_Staging_Cluster
    $ ls
    cloud-config
    create_cluster_control.sh
    create_cluster_workers.sh
    files
    fleet
    install_fleetctl_and_scripts.sh
    settings
    
    Let's check "settings" file first:
    $ cat settings
    ### CoreOS Test/Staging Cluster on GCE settings
    
    ## change Google Cloud settings as per your requirements
    # GC settings
    
    # CoreOS RELEASE CHANNEL
    channel=beta
    
    # SET YOUR PROJECT AND ZONE !!!
    project=my-cloud-project
    zone=europe-west1-d
    
    # ETCD CONTROL AND NODES MACHINES TYPE
    #
    control_machine_type=g1-small
    #
    worker_machine_type=n1-standard-1
    ##
    
    ###
    
  2. 更新settings,填入你的 Google Cloud 项目 ID 和你希望 CoreOS 实例部署的区域:

    # SET YOUR PROJECT AND ZONE !!!
    project=my-cloud-project
    zone=europe-west1-d
    
  3. 接下来,让我们安装我们的控制服务器,即etcd集群节点:

    $ ./create_cluster_control.sh
    
    

    测试/暂存集群设置

我们刚刚创建了新的集群etcd控制节点。

  1. 我们来看一下这个脚本中包含的内容:

    #!/bin/bash
    # Create TS cluster control
    
    # Update required settings in "settings" file before running this script
    
    function pause(){
    read -p "$*"
    }
    
    ## Fetch GC settings
    # project and zone
    project=$(cat settings | grep project= | head -1 | cut -f2 -d"=")
    zone=$(cat settings | grep zone= | head -1 | cut -f2 -d"=")
    # CoreOS release channel
    channel=$(cat settings | grep channel= | head -1 | cut -f2 -d"=")
    # control instance type
    control_machine_type=$(cat settings | grep control_machine_type= | head -1 | cut -f2 -d"=")
    # get the latest full image name
    image=$(gcloud compute images list --project=$project | grep -v grep | grep coreos-$channel | awk {'print $1'})
    ##
    
    # create an instance
    gcloud compute instances create tsc-control1 --project=$project --image=$image --image-project=coreos-cloud \
     --boot-disk-size=10 --zone=$zone --machine-type=$control_machine_type \
     --metadata-from-file user-data=cloud-config/control1.yaml --can-ip-forward --tags tsc-control1 tsc
    
    # create a static IP for the new instance
    gcloud compute routes create ip-10-200-1-1-tsc-control1 --project=$project \
     --next-hop-instance tsc-control1 \
     --next-hop-instance-zone $zone \
     --destination-range 10.200.1.1/32
    
    echo " "
    echo "Setup has finished !!!"
    pause 'Press [Enter] key to continue...'
    # end of bash script
    
    

它从settings文件中获取所需的 Google Cloud 设置。借助 Google Cloud SDK 中的gcloud工具,它设置了tsld-control1实例并为其分配了静态内部 IP10.200.1.1。这个 IP 将被工作节点用来连接运行在tsc-control1上的etcd集群。

cloud-config文件夹中,我们有创建 CoreOS 实例所需的cloud-config文件,适用于 GCE。

打开control1.yaml并检查其中的内容:

$ cat control1.yaml
#cloud-config

coreos:

etcd2:
 name: control1
 initial-advertise-peer-urls: http://10.200.1.1:2380
 initial-cluster-token: control_etcd
 initial-cluster: control1=http://10.200.1.1:2380
 initial-cluster-state: new
 listen-peer-urls: http://10.200.1.1:2380,http://10.200.1.1:7001
 listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
 advertise-client-urls: http://10.200.1.1:2379,http://10.200.1.1:4001
 fleet:
 metadata: "role=services,cpeer=tsc-control1"
 units:
 - name: 00-ens4v1.network
 runtime: true
 content: |
 [Match]
 Name=ens4v1

 [Network]
 Address=10.200.1.1/24
 - name: etcd2.service
 command: start
 - name: fleet.service
 command: start
 - name: docker.service
 command: start
 drop-ins:
 - name: 50-insecure-registry.conf
 content: |
 [Unit]
 [Service]
 Environment=DOCKER_OPTS='--insecure-registry="0.0.0.0/0"'
write_files:
 - path: /etc/resolv.conf
 permissions: 0644
 owner: root
 content: |
 nameserver 169.254.169.254
 nameserver 10.240.0.1
#end of cloud-config

如你所见,我们有一个cloud-config文件用于控制机,它完成以下任务:

  1. 它创建了一个静态 IP 为10.200.1.1etcd集群节点,用于连接etcd集群。

  2. 它将fleet元数据设置为role=services,cpeer=tsc-control1

  3. Unit 00-ens4v1.network10.200.1.1分配了一个静态 IP。

  4. docker.service的 drop-in 文件50-insecure-registry.conf设置了--insecure-registry="0.0.0.0/0",这允许你连接到任何私有托管的 docker registry。

  5. write_files部分,我们更新了/etc/resolv.conf,添加了 Google Cloud 的 DNS 服务器,因为如果给实例分配了静态 IP,DNS 服务器有时不会自动添加。

创建我们的集群工作节点

为了创建集群工作节点,使用的命令如下:

$ ./create_cluster_workers.sh

创建我们的集群工作节点

记下工作节点的外部 IP,如前面截图所示;我们稍后会用到它们。

当然,你也可以随时在 Google 开发者控制台中查看它们。

创建我们的集群工作节点

让我们来查看 cloud-config 文件夹中的 test1.yamlstaging1.yaml 文件。运行以下命令:

$ cat test1.yaml
#cloud-config

coreos:
 etcd2:
 listen-client-urls: http://0.0.0.0:2379,http://0.0.0.0:4001
 initial-cluster: control1=http://10.200.1.1:2380
 proxy: on
 fleet:
 public-ip: $public_ipv4
 metadata: "role=worker,cpeer=tsc-test1"
 units:
 - name: etcd2.service
 command: start
 - name: fleet.service
 command: start
 - name: docker.service
 command: start
 drop-ins:
 - name: 50-insecure-registry.conf
 content: |
 [Unit]
 [Service]
 Environment=DOCKER_OPTS='--insecure-registry="0.0.0.0/0"'
# end of cloud-config

如我们所见,我们有 cloud-config 文件用于 test1 机器:

  • 它连接到 etcd 集群机器 control1 并启用 etcd2 的代理模式,这使得在主机上运行的任何内容都能通过 127.0.0.1 地址访问 etcd 集群

  • 它设置了 fleet 元数据 role=services,cpeer=tsc-test1

  • docker.service 的 drop-in 50-insecure-registry.conf 设置了 --insecure-registry="0.0.0.0/0",这将允许你连接到任何私有托管的 docker 注册表

就这样!

如果你查看 tsc-staging1.yaml 云配置文件,你会发现它与 test1.yaml 几乎相同,唯一的区别是 fleet 元数据中有 cpeer=tsc-staging1。但我们还没完成!

现在让我们安装 OS X/Linux 客户端,这将使我们能够从本地计算机管理云开发集群。

让我们运行这个安装脚本:

$ ./install_fleetctl_and_scripts.sh

你应该会看到以下输出:

创建我们的集群工作节点

那么,最后一个脚本做了什么呢?

在你的主文件夹中,它创建了一个名为 ~/coreos-tsc-gce 的新文件夹,其中包含两个子文件夹:

  • bin

    • etcdctl:这是用于访问远程集群 control1 节点上 etcdctl 客户端的 shell 脚本

    • fleetctl:本地 fleetctl 客户端用于控制远程集群

    • staging1.sh:建立与远程 staging1 工作者的 ssh 连接

    • test1.sh:建立与远程 test1 工作节点的 ssh 连接

    • set_cluster_access.sh:这设置了远程集群的 shell 访问

  • fleet

    • test1_webserver.service:我们 test1 服务器的 fleet 单元

    • staging1_webserver.service:我们 staging1 服务器的 fleet 单元

现在,让我们看一下 set_cluster_access.sh

$ cd ~/coreos-tsc-gce/bin
$ cat set_cluster_access.sh
#!/bin/bash

# Setup Client SSH Tunnels
ssh-add ~/.ssh/google_compute_engine &>/dev/null

# SET
# path to the cluster folder where we store our binary files
export PATH=${HOME}/coreos-tsc-gce/bin:$PATH
# fleet tunnel
export FLEETCTL_TUNNEL=104.155.61.42 # our control1 external IP
export FLEETCTL_STRICT_HOST_KEY_CHECKING=false

echo "etcd cluster:"
etcdctl --no-sync ls /

echo "list fleet units:"
fleetctl list-units

/bin/bash

该脚本由 ./install_fleetctl_and_scripts.sh 预设,使用远程 control1 外部 IP 地址,并允许我们发出远程 fleet 控制命令:

$ ./set_cluster_access.sh

创建我们的集群工作节点

很好!我们的集群已启动并运行,工作节点已连接到 etcd 集群。

现在我们可以在本地计算机上运行 fleetctl 命令来控制远程集群。

在远程集群上运行 fleetctl 命令

现在让我们安装在 ~/coreos-tsc-gce/fleet 文件夹中的 nginx fleet 单元。运行以下命令:

$ cd ~/coreos-tsc-gce/fleet

让我们首先将 fleet 单元提交到集群:

$ fleetctl submit *.service

现在,让我们启动它们:

$ fleetctl start *.service

你应该会看到类似于以下截图的内容:

在远程集群上运行 fleetctl 命令

给 docker 一些时间从 docker 注册表下载 nginx 镜像。然后我们可以使用以下命令检查我们新部署的 fleet 单元的状态:

$ fleetctl status *.service

在远程集群上运行 fleetctl 命令

然后,运行这个命令:

$ fleetctl list-units

在远程集群上运行 fleetctl 命令

完美!

现在,在你的网页浏览器中,打开工作节点的外部 IP,你应该能看到以下内容:

在远程集群上运行 fleetctl 命令

nginx服务器现在已正常工作。它们显示此错误信息的原因是我们尚未提供任何index.html文件。我们将在下一章进行此操作。

但在我们结束本章之前,让我们检查一下我们的test/staging nginx 舰队单元:

$ cd ~/coreos-tsc-gce/fleet
$ cat test1_webserver.service

你应该能看到如下代码:

[Unit]
Description=nginx

[Service]
User=core
TimeoutStartSec=0

EnvironmentFile=/etc/environment
ExecStartPre=-/usr/bin/docker rm nginx
ExecStart=/usr/bin/docker run --rm --name test1-webserver -p 80:80 \
-v /home/core/share/nginx/html:/usr/share/nginx/html \
nginx:latest
#
ExecStop=/usr/bin/docker stop nginx
ExecStopPost=-/usr/bin/docker rm nginx

Restart=always
RestartSec=10s
[X-Fleet]
MachineMetadata=cpeer=tsc-test1 # this where our fleet unit gets scheduled

这里有几点需要注意:

  • Staging1有一个几乎相同的单元;它将test1替换为staging1。因此,我们重复使用了与本地开发机器相同的舰队单元,只进行了少许更改。

  • ExecStart中,我们使用了test1-webserverstaging1-webserver,因此通过使用fleetctl list-units,我们可以看到哪个是哪个。

    我们添加了这一部分:

    [X-Fleet]
    MachineMetadata=cpeer=tsc-test1
    
    

这将把该单元调度到特定的集群工作节点。

如果你是 Mac 用户,可以从github.com/rimusz/coreos-osx-gui-cluster下载并使用我的 Mac 应用CoreOS-Vagrant Cluster GUI for Mac OS X,它提供了一个便捷的 UI 来管理你计算机上的 CoreOS 虚拟机。

在远程集群上运行 fleetctl 命令

这个应用程序将设置一个小型的control+双节点本地集群,这使得在将集群任务推送到云端之前,更容易在本地计算机上进行集群相关的测试。

参考资料

你可以阅读更多关于我们在本地和云端测试/预发布环境中使用的 CoreOS 集群架构的信息,访问coreos.com/docs/cluster-management/setup/cluster-architectures/

总结

在本章中,你学习了如何在 CoreOS 上设置本地开发环境,并在 GCE 上设置远程测试/预发布集群。我们根据不同的元数据标签调度了舰队单元。

在下一章中,我们将学习如何将代码部署到我们的云服务器。

第六章:构建部署设置

在上一章中,你学习了如何在个人计算机上为开发设置本地 CoreOS 环境,并在 Google Cloud 的 Compute Engine 虚拟机实例上设置测试和预发布环境集群。

在本章中,我们将介绍如何将代码从 GitHub 仓库部署到我们的测试和预发布服务器,以及如何设置 Docker 构建器和 Docker 私有注册表工作节点以进行 Docker 镜像构建和分发。

在本章中,我们将涵盖以下主题:

  • 在测试和预发布服务器上部署代码

  • 设置 Docker 构建器和私有 Docker 注册表机器

在测试和预发布服务器上部署代码

在上一章中,你学习了如何在 Google Cloud 上设置你的测试和预发布环境并在其中部署 Web 服务器。在这一节中,我们将展示如何将代码部署到测试和预发布环境中的 Web 服务器。

在服务器上部署代码

要将代码部署到我们的Test1Staging1服务器上,我们运行以下命令:

$ cd coreos-essentials-book/chapter6/Test_Staging_Cluster/webserver
$ ./deploy_2_test1.sh

你将得到以下输出:

在服务器上部署代码

然后,运行以下命令:

$ ./deploy_2_staging1.sh

你应该看到以下结果:

在服务器上部署代码

现在,打开tsc-test1tsc-staging1虚拟机实例的外部 IP 地址,将它们复制到浏览器中(你可以在 GC 控制台、Compute Engine、虚拟机实例中查看 IP)。

你看到的输出取决于服务器。

对于测试服务器,你应该看到类似这样的内容:

在服务器上部署代码

这是你在预发布服务器上看到的内容:

在服务器上部署代码

让我们看看发生了什么:

$ cat deploy_2_test1.sh
#!/bin/bash

function pause(){
read -p "$*"
}

## Fetch GC settings
# project and zone
project=$(cat ~/coreos-tsc-gce/settings | grep project= | head -1 | cut -f2 -d"=")
zone=$(cat ~/coreos-tsc-gce/settings | grep zone= | head -1 | cut -f2 -d"=")

# change folder permissions
gcloud compute --project=$project ssh  --zone=$zone "core@tsc-test1" --command "sudo chmod -R 755 /home/core/share/"

echo "Deploying code to tsc-test1 server !!!"
gcloud compute copy-files test1/index.html tsc-test1:/home/core/share/nginx/html --zone $zone --project $project

echo " "
echo "Finished !!!"
pause 'Press [Enter] key to continue...'

如你所见,我们使用了gcloud compute来更改home/core/share/nginx/html文件夹的权限,因为我们需要能够在那里复制文件。我们将一个index.html文件复制到了那里。

在实际场景中,应该在这里使用git pull从测试和预发布分支拉取代码。

为了自动化发布到Test1/Staging1服务器上,例如,可以使用 Strider-CD,但这超出了本书的范围。你可以在github.com/Strider-CD/strider上阅读关于 Strider-CD 的内容,并实践如何实现它。

设置 Docker 构建器和私有 Docker 注册表工作节点

我们已经成功地通过gcloud compute在云上的测试/预发布环境中部署了代码(在我们的例子中是index.html),通过在一个简单的 Shell 脚本中运行它。

让我们在云上的测试/预发布环境中设置一台新服务器。它将为我们构建 Docker 镜像,并将它们存储在我们的私有 Docker 注册表中,以便它们可以在我们的生产集群中使用(你将在下一章学习如何设置)。

服务器设置

由于 Docker 构建器和私有 Docker 注册表单元将运行在同一台服务器上,我们将在测试/预发布环境中再部署一台服务器。

要安装新服务器,运行以下命令:

$ cd coreos-essentials-book/chapter6/Test_Staging_Cluster
$ ls
cloud-config
create_registry-cbuilder1.sh 
dockerfiles
files
fleet
webserver

接下来,让我们安装我们的新服务器:

$ ./create_ registry-cbuilder1.sh

你应该看到类似以下的输出:

服务器设置

让我们看看脚本安装过程中发生了什么:

  • 创建了一个新的 server tsc-registry-cbuilder1

  • 静态 IP 的 10.200.4.1 路由已经为 tsc-registry-cbuilder1 实例创建。

  • 新服务器的外部端口 5000 已被打开。

  • files 文件夹中的文件 reg-dbuilder1.sh 被复制到了 ~/coreos-tsc-gce/bin

  • fleet 文件夹中的 dbuilder.serviceregistry.service fleet 单元被复制到了 ~/coreos-tsc-gce/fleet

如果我们查看 GCE 控制台中的虚拟机实例,我们应该能看到我们的新实例:

服务器设置

我们现在需要验证我们的新服务器是否正常工作,所以我们执行 ssh 连接到它:

$ cd ~/coreos-tsc-gce/bin
$ ./reg-dbuider1.sh

服务器设置

非常好!我们的新服务器已经启动并运行。按 Ctrl + D 退出。

现在我们需要验证我们的服务器是否连接到集群。所以,运行以下命令:

$ ./set_cluster_access.sh

脚本的输出应该像这样:

服务器设置

完美!我们可以看到我们的新服务器已成功连接到集群:

服务器设置

好的,现在让我们安装这两个新的 fleet 单元:

$ cd ~/coreos-tsc-gce/fleet
$ fleetctl start dbuilder.service registry.service

服务器设置

接下来,让我们列出 fleet 单元:

$ fleetctl list-units

服务器设置

如果你看到 activating start-pre,请给 fleet 单元几分钟时间来拉取远程 Docker 镜像。

你可以使用以下命令检查 fleet 单元的状态:

$ fleetctl status dbuilder.service

服务器设置

假设我们等几分钟再试一次:

$ fleetctl list-units

服务器设置

然后我们可以看到我们成功地在新的 tsc-registry-cbuilder1 服务器上创建了两个新的 fleet 单元。

你可能还记得在上一章中,set_cluster_access.sh 脚本做了以下操作:

  • 它将 PATH 设置为 ~/coreos-tsc-gce/bin 文件夹,以便我们可以从任何文件夹访问存储在其中的可执行文件和脚本。

  • 它将 FLEETCTL_TUNNEL 设置为我们 control/etcd 机器的外部 IP。

  • 它通过 fleetctl list-machines 打印集群中的机器。

  • 它通过 fleetctl list-units 打印集群中的单元。

  • 它允许我们通过本地的 fleetctl 客户端与远程的 etcd 集群进行交互。

总结

在本章中,你学会了如何在 GCE 上部署代码到远程的测试/预发布集群,并设置 Docker 构建器和私有 Docker 注册机。

在接下来的章节中,我们将讨论以下内容:使用我们的预发布和 Docker 构建器及私有注册机服务器将代码从预发布部署到生产环境,构建 Docker 镜像,并在生产服务器上部署它们。

第七章:构建生产集群

在上一章中,我们看到如何在远程测试/暂存集群上部署代码,并设置 Docker 构建器和私有 Docker 注册服务器。在本章中,我们将讲解如何在 Google Cloud Compute Engine 上设置生产集群,以及如何通过 Docker 构建器和 Docker 私有注册表从暂存服务器部署代码。

本章我们将涉及以下主题:

  • 将远程生产集群引导到 GCE

  • 在生产集群服务器上部署代码

  • Dev/Test/Staging/Production 设置概览

  • 基于fleet的 PaaS

  • 另一个运行 CoreOS 集群的云端替代方案

在 GCE 上引导远程生产集群

我们已经看到如何在 Google Cloud 上设置测试/暂存环境。在这里,我们将采用非常相似的方法来设置生产集群,其中通常经过测试的代码将在稳定的环境中运行,且使用更强大和高可用性的服务器。

设置生产集群

在安装集群之前,让我们看看那里有哪些文件夹/文件;在终端中输入以下命令:

$ cd coreos-essentials-book/chapter7/Production_Cluster
$ ls
cloud-config 
create_cluster_workers.sh 
fleet 
files 
create_cluster_control.sh 
install_fleetctl_and_scripts.sh
settings

如你所见,我们有与设置测试/暂存集群非常相似的文件夹/文件。

注意

我们不会打印出所有要使用的脚本和文件,因为那样会占据整整一章的篇幅。请查看这些脚本和其他文件,它们有很好的注释,应该不难理解。

当你完成本章内容后,你可以采用提供的脚本来引导你的集群。如前所述,请更新settings文件,填写你的 Google Cloud 项目 ID 和你希望 CoreOS 实例部署的区域:

  1. 接下来,让我们安装我们的控制服务器,即生产集群的 etcd 节点:

    $ ./create_cluster_control.sh
    
    

    设置生产集群

    我们刚刚创建了新的生产集群控制节点。

    为了学习目的,我们只使用了一个etcd服务器。对于真实的生产集群,建议至少使用三个etcd服务器,并且每个服务器应该位于不同的云可用区。

    由于生产集群设置脚本与测试/暂存集群脚本非常相似,我们在这里不再分析它们。

  2. 下一步是创建我们的生产集群工作节点:

    $ ./create_cluster_workers.sh
    
    

    你应该看到如下输出:

    设置生产集群

    对于其他集群工作节点,你应该看到类似以下内容:

    设置生产集群

    注意

    记下工作节点的外部 IP;稍后我们将需要这些 IP。当然,你也可以随时在 Google Cloud 开发者控制台查看它们。

    所以,我们已经在 GCE 上设置好了生产服务器。如果你检查 Google Cloud 开发者控制台中的计算引擎实例,你应该看到一份服务器列表,类似这样:

    设置生产集群

  3. 现在让我们安装所有必要的脚本,以便访问我们的集群:

    $ ./install_fleetctl_and_scripts.sh
    
    

    这个脚本将创建一个名为 ~/coreos-prod-gce 的新文件夹,其中包含与我们的测试/暂存集群相同的文件夹:

    • bin 文件夹将包含用于访问集群机器的脚本和 set_cluster_access.sh 脚本

    • fleet - website1.service fleet 单元文件

  4. 让我们运行 set_cluster_access.sh

    $ cd ~/coreos-prod-gce/bin
    $ ./set_cluster_access.sh
    
    

    设置生产集群

完美!我们的生产集群已正常运行!

如你所见,我们这里有三台服务器,一台用于 etcd 服务,另外两台是用于运行我们网站的工作节点。

我们已经准备好了 website1 fleet 单元。现在让我们安装它:

$ cd ~/coreos-prod-gce/fleet
$ fleetctl start website1.service

以下截图演示了输出内容:

设置生产集群

现在我们准备好在生产服务器上部署代码了。

在生产集群服务器上部署代码

在前面的章节中,我们看到了如何在 Google Cloud 上设置测试/暂存环境并部署我们的代码,同时我们也设置了 Docker 构建器和 Docker 私有注册表服务器。

在下一节中,我们将学习如何使用 Docker 构建器和 Docker 私有注册表将代码部署到我们的生产集群的 Web 服务器上。

设置 Docker 构建器服务器

在将代码从暂存环境部署到生产环境之前,我们需要将 Dockerfile 文件和 build.shpush.sh 文件复制到我们的 Docker 构建器。

为此,请运行以下命令:

$ cd coreos-essentials-book/chapter7/Test_Staging_Cluster/
$ ./install_website1_2_dbuilder.sh

你应该看到类似于以下截图的内容:

设置 Docker 构建器服务器

那么让我们来看一下发生了什么——也就是那个脚本做了什么。它已经将三个文件复制到 Docker 构建器服务器:

  1. 这将用于构建我们的生产 Docker 镜像:

    $ cat Dockerfile:
    FROM nginx:latest
    ## add website code
    ADD website1 /usr/share/nginx/html
    EXPOSE 80
    
    
  2. 以下是 Docker 镜像构建脚本:

    $ cat build.sh
    docker build --rm -t 10.200.4.1:5000/website1 .
    
    
  3. 以下是将 Docker 镜像推送到我们的私有 Docker 注册表的脚本:

    $ cat push.sh
    docker push 10.200.4.1:5000/website1
    
    

好的,我们已经准备好了 Docker 构建器服务器。现在让我们开始在生产服务器上进行代码部署。

在生产服务器上部署代码

要在生产 Web 服务器上部署代码,请运行以下命令:

$ cd ~/coreos-prod-gce

当我们构建生产集群时,安装脚本已经安装了 deploy_2_production_website1.sh 脚本。让我们运行它,你应该会看到类似于以下两张截图的输出:

$ ./deploy_2_production_website1.sh

在生产服务器上部署代码

你还应该看到类似下面的内容:

在生产服务器上部署代码

现在,在浏览器中打开 prod-web1prod-web2,使用它们的外部 IP,你应该能看到如下截图所示的内容:

在生产服务器上部署代码

我们看到的网页与暂存服务器上的完全相同。

太棒了!我们已经成功将代码部署到生产服务器上!

让我们看看那里发生了什么。

运行以下命令:

$ cat deploy_2_production_website1.sh
#!/bin/bash
# Build docker container for website1
# and release it

function pause(){
read -p "$*"
}

# Test/Staging cluster
## Fetch GC settings
# project and zone
project=$(cat ~/coreos-tsc-gce/settings | grep project= | head -1 | cut -f2 -d"=")
zone=$(cat ~/coreos-tsc-gce/settings | grep zone= | head -1 | cut -f2 -d"=")
cbuilder1=$(gcloud compute instances list --project=$project | grep -v grep | grep tsc-registry-cbuilder1 | awk {'print $5'})

# create a folder on docker builder
echo "Entering dbuilder docker container"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no  core@$cbuilder1 "/usr/bin/docker exec docker-builder /bin/bash -c 'sudo mkdir -p /data/website1 && sudo chmod -R 777 /data/website1'"

# sync files from staging to docker builder
echo "Deploying code to docker builder server !!!"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no core@$cbuilder1 '/usr/bin/docker exec docker-builder rsync -e "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" -avzW --delete core@10.200.3.1:/home/core/share/nginx/html/ /data/website1'
# change folder permisions to 755
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no  core@$cbuilder1 "/usr/bin/docker exec docker-builder /bin/bash -c 'sudo chmod -R 755 /data/website1'"

echo "Build new docker image and push to registry!!!"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no core@$cbuilder1 "/usr/bin/docker exec docker-builder /bin/bash -c 'cd /data && ./build.sh && ./push.sh'"
##

# Production cluster
## Fetch GC settings
# project and zone
project2=$(cat ~/coreos-prod-gce/settings | grep project= | head -1 | cut -f2 -d"=")

# Get servers IPs
control1=$(gcloud compute instances list --project=$project2 | grep -v grep | grep prod-control1 | awk {'print $5'})
web1=$(gcloud compute instances list --project=$project2 | grep -v grep | grep prod-web1 | awk {'print $5'})
web2=$(gcloud compute instances list --project=$project2 | grep -v grep | grep prod-web2 | awk {'print $5'})

echo "Pull new docker image on web1"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no core@$web1 docker pull 10.200.4.1:5000/website1
echo "Pull new docker image on web2"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no core@$web2 docker pull 10.200.4.1:5000/website1

echo "Restart fleet unit"
# restart fleet unit
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no core@$control1 fleetctl stop website1.service
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no core@$control1 fleetctl start website1.service
#
sleep 5
echo " "
echo "List Production cluster fleet units"
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no core@$control1 fleetctl list-units

echo " "
echo "Finished !!!"
pause 'Press [Enter] key to continue...'

部署到生产环境的步骤如下:

  1. 在 Docker 构建器服务器上创建名为 /data/website1 的文件夹。

  2. 通过 docker-builder 容器使用 rsync 将文件从 Staging1 同步到 Docker 构建服务器。

  3. 通过 docker-builder 容器运行 build.sh 脚本。

  4. 将新的 Docker 镜像推送到私有 Docker 注册表。

  5. 将新的 Docker 镜像拉取到 Prod-web1prod-web2 服务器上。

  6. 通过生产集群的 etcd 服务器重启 website1.service fleet 单元。

  7. 就这样!我们已完成将新网站发布到生产集群。

注意

需要注意的一点

我们使用 docker-builder 容器来同步和构建我们的 Docker 容器。

这可以直接在 Docker 构建服务器上完成,但使用容器可以让我们将任何所需工具添加到容器中,这带来了优势。如果我们需要复制 Docker 构建服务器或用新服务器替换它,我们只需要安装 docker-builder 容器,就能让一切恢复正常。

Dev/Test/Staging/Production 环境概述

让我们概述一下以我们所采用的方式进行 Dev/Test/Staging/Production 环境设置的优点:

  • 通过 CoreOS 虚拟机进行本地代码开发可以减少测试时间,因为所有更改都会推送到 VirtualBox 虚拟机上的本地服务器。

  • 基于云的测试/预发布环境适用于使用 GitHub 或 Bitbucket 的团队共享项目。就我们而言,它还运行 nginx 容器作为我们的 Web 服务器,代码通过附加的 host 文件夹来使用。这大大加快了从测试和预发布 git 分支进行代码部署的速度,因为每次从 git 仓库拉取代码时,Docker 容器无需重新构建。

  • 对于生产环境,使用的是一个独立的集群。分离开发和生产集群是一个良好的实践。

  • 对于生产环境,我们使用与测试/预发布服务器相同的 Docker 基础镜像,但我们会构建一个新的 Docker 镜像,并将代码嵌入其中。因此,我们可以通过在所有服务器上重用相同的 Docker 镜像,自动扩展网站到任意数量的服务器,所有服务器将运行完全相同的代码。

  • 对于 Docker 镜像构建和我们的私有 Docker 注册表,我们使用相同的服务器,该服务器仅通过内部 GCE IP 可访问。如果您想将 Docker 注册表暴露给外部访问,例如,应该在 Docker 注册表前放置带有认证的 nginx 容器以确保安全。

  • 这只是设置 Dev/Test/Staging/Production 环境的一种方式。每种设置场景都不同,但这种设置应为你提供正确的方向。

基于 fleet 的 PaaS

在本章及之前的章节中,我们解释了如何使用 fleet 在集群上部署不同的服务。Fleet 是一个功能强大且易于使用的低级集群管理器,可以在集群层面控制 systemd。然而,它缺乏 Web UI、易用的编排工具等,因此 PAZ 这个优秀的 PaaS 在此时为我们提供了帮助。

使用 PAZ 部署服务

www.paz.sh 网站具有一个非常漂亮且用户友好的 Web UI,使得设置 CoreOS 集群变得更加容易。PAZ 还提供了一个 API,如果你想通过脚本自动化操作,可以使用它。

通过其仪表板,您可以添加和编辑服务,检查集群的状态(按主机或单元查看),并查看集群的监控信息和日志。

使用 PAZ 部署服务

它充分利用fleet来协调集群中各台机器上的服务。它是用Node.js构建的,所有服务都作为 Docker 容器运行。

以下几点解释了 PAZ 的工作原理:

  • 用户可以在 UI 中声明服务

  • 服务存储在服务目录中

  • 调度器是部署服务的服务

  • 您可以手动指示调度器进行部署,或在 CI 过程结束时触发它

  • Paz 支持推送后 Docker Hub 的 Web 钩子

  • 通过使用etcd和服务发现,您的容器将被连接在一起

当然,它会不断发展并获得新特性,但在撰写本书时,只有前面列表中的服务可用。

本书的范围不包括对 PAZ 的完整概述,但你可以在paz.readme.io/v1.0/docs/paz-architecture 阅读更多关于 Paz 架构的信息。

另一种运行 CoreOS 集群的云解决方案

为了引导我们的测试/预生产和生产集群,我们使用了 Google Cloud Compute Engine 的虚拟实例,但有时您可能希望在不在自己场所存储的真实服务器(裸金属服务器)上运行您的服务器。

市面上有许多不同的裸金属服务器提供商,但其中一个吸引我注意的是www.packet.net

最近我在调查 CoreOS 和容器的托管解决方案时发现了这些。它们有趣的地方在于,既然没有走传统的云/虚拟化路线,它们创建了一个真正按需、裸金属的云解决方案。我能够在不到 5 分钟的时间内从零开始启动一个 CoreOS 服务器,而且它们有一个相当全面的 API 和相应的文档。

这是一个 Packet 项目仪表板的示例:

另一种运行 CoreOS 集群的云解决方案

总结

在本章中,我们了解了如何设置生产集群并使用 Docker 构建器和私有 Docker 仓库机器部署我们的代码预发布。最后,我们概述了一个基于fleet的 PaaS——Paz.sh

在下一章中,我们将概述 CoreOS 更新策略和我们的服务器的 CoreUpdate。我们还将使用托管的公有/私有 Docker 仓库 quay.io 和自托管的 CoreOS 企业注册表。

第八章:介绍 CoreUpdate 和容器/企业注册中心

在上一章中,我们了解了如何设置生产集群并部署代码,如何使用 Docker 构建器设置暂存环境,以及如何将私有 Docker 注册中心机器部署到生产服务器。

在本章中,我们将概述 CoreOS 更新策略、付费的 CoreUpdate 服务以及在容器注册中心和企业注册中心托管的 Docker 镜像。

本章将涵盖以下主题:

  • 更新策略

  • CoreUpdate

  • 容器注册中心

  • 企业注册中心

更新策略

在我们了解 CoreOS 的付费 CoreUpdate 服务之前,先概述一下开箱即用的自动更新策略。

自动更新

CoreOS 默认启用自动更新。

正如我们之前提到的,当 CoreOS 团队发布更新时,主机将其暂存到临时位置并安装到被动的 usr 分区。重启后,活动分区和被动分区将交换。

在写这本书时,共有四种更新策略,如下所示:

自动更新

应该使用哪种更新策略在 cloud-configupdate 部分中定义:

  #cloud-config
  coreos:
    update:
      group: stable
      reboot-strategy: best-effort

让我们来看一下这些更新策略:

  • best-effort:这是默认策略,其工作方式是检查机器是否为集群的一部分。如果是,它会使用 etcd-lock;否则,它会使用 reboot 策略。

  • etcd-lock:这使我们能够通过在每台机器上放置一个 reboot 锁来一次只启动一台机器,并逐一重启它们。

  • reboot:一旦更新安装到被动分区,它将立即重启机器。

  • off:在成功更新安装到被动分区后,机器不会被重启。

更新策略的使用

以下是一些 update 策略的应用示例:

  • best-effort:建议在生产集群中使用此策略

  • reboot:这可以用于只能在一天中的特定时间重启的机器,例如用于在维护窗口中进行自动更新。

  • off:适用于本地开发环境,其中重启控制权由用户掌握

如果你想了解更多更新策略,请访问 CoreOS 官网:coreos.com/docs/cluster-management/setup/update-strategies/

CoreUpdate

CoreUpdate 是受管 Linux 计划的一部分(coreos.com/products/)。

这是 CoreOS 商业版中的一个工具。它为用户提供了自己的支持 Omaha 服务器,类似于 Red Hat Satellite Server 和 Canonical Landscape 等工具:

  • 标准计划由 CoreOS 管理和托管

  • 高级计划可以在防火墙后运行,可以是本地部署或云端部署

CoreUpdate 使用与前面提到的update策略完全相同的策略,除了在cloud-config文件中的update部分有一些区别:

#cloud-config 
  coreos:
    update:
      group: production
      server: https://customer.update.core-os.net/v1/update

这里:

  • group是你在 CoreUpdate 仪表板上设置的内容

  • server是你在为托管 Linux 计划注册后生成的链接。

在我们当前的示例中,根据cloud-config,服务器属于https://customer.update.core-os.net/v1/update,而groupproduction

我们通过 CoreUpdate UI 进行更改,如下图所示:

CoreUpdate

以下功能是可用的:

  • 发布通道;在我们的案例中,它是稳定的。

  • 启用/禁用自动更新

  • 机器更新之间的时间窗口;在我们的案例中,它是 90 分钟。

CoreUpdate 的 UI 允许你非常轻松地控制集群更新组,无需通过终端对每台服务器执行ssh并单独修改每台服务器的更新设置。

注意

你可以在以下页面阅读更多关于 CoreUpdate 的信息:

coreos.com/docs/coreupdate/coreos/coreupdate-configure-machines

coreos.com/docs/coreupdate/coreos/coreupdate-getting-started

容器注册表

容器注册表是 CoreOS 为应用容器提供的托管服务,网址是quay.io。在那里,如果你不想自己运行私有 Docker 注册表,可以托管你的 Docker 镜像:

  • 它为公共容器仓库提供免费、无限的存储和仓库。

  • 如果你需要私有仓库,它提供了多种计划供你选择。

Quay.io 概览

让我们看一下它们提供的概览:一个友好且易于使用的 UI。

Quay.io 概览

在下面的截图中,我们更详细地查看了 postgres 容器镜像:

Quay.io 概览

从前面的截图中可以看出,UI 非常易于使用,功能也很容易理解。

让我们看看创建仓库功能是怎样的:

Quay.io 概览

当你创建一个新仓库时,你可以进行以下操作:

  • 将仓库设置为公开或私有。

  • 如果你想自己构建容器并将它们推送到注册表中,可以将其清空。

  • 提供(上传)一个Docker文件。

  • 链接到 GitHub 仓库。这是首选选项,因为它允许你在向 GitHub 仓库推送更改时自动构建容器。

企业注册表

企业注册表与容器注册表基本相同,但托管在你的本地或云服务器上,位于你的防火墙后面。

它有不同的计划选项,可以在coreos.com/products/enterprise-registry/找到。

它允许你管理容器构建、团队和用户的权限等。

如果贵公司的需求是一个非常安全且完全由您控制的设置,那么使用容器注册表和企业注册表是最佳选择。

总结

在本章中,我们概述了 CoreOS 更新策略、CoreUpdate 服务、托管的免费/付费容器注册表quay.io以及自托管的企业注册表服务。

在下一章中,您将了解 CoreOS 的 rkt——可以替代 Docker 容器使用的应用容器运行时。

第九章:CoreOS rkt 简介。

在前一章中,我们概述了 CoreUpdate、免费的和付费的容器仓库,以及 CoreOS 提供的托管和企业级注册中心。

在本章中,你将学习 CoreOS 的 rkt,一个面向应用的容器运行时。我们将涵盖本章中的以下主题:

  • rkt 简介。

  • 使用 rkt 运行精简版 Docker 镜像。

  • 将 Docker 镜像转换为 ACI。

rkt 简介。

rkt(发音为 "rock it")是由 CoreOS 制作的应用容器运行时,设计时注重可组合性、速度和安全性。它是 Docker 的替代方案,专为在安全性和生产环境要求最严格的服务器上运行而设计。

rkt 是一个独立的工具,相较于 Docker 的客户端和中央守护进程版本,它使得 rkt 成为 Docker 的一个更好的替代方案,因为它有更少的约束和依赖。例如,如果 docker 中央守护进程崩溃,所有正在运行的 docker 容器将被停止;而在 rkt 的情况下,这只会影响到特定的 rkt 进程,该进程负责在其 pod 中运行 rkt 容器。由于每个 rkt 进程都会有自己的进程标识号PID),因此如果一个 rkt 进程崩溃,它不会影响到其他任何 rkt 进程。

rkt 的功能。

我们将概述 rkt 的主要功能,内容如下:

  • 它可以与 init 系统集成,如 systemdupstart

  • 它可以与集群编排工具集成,如 fleetKubernetes(我们将在下一章介绍)。

  • 它与其他容器解决方案如 Docker 兼容。

  • 它具有可扩展和模块化的架构。

应用容器基础。

rkt应用容器appc: github.com/appc/spec/)的一个实现,它是开源的,定义了应用容器的镜像格式、运行时环境和发现机制:

  • rkt 使用的是应用容器镜像ACI)格式的镜像,这一格式由应用容器(appc)规范定义(github.com/appc/spec)。ACI 只是一个简单的 tarball 包,包含不同的 rootfs 文件和镜像清单。

  • 一个 pod(rkt 中的基本执行单元)是一个或多个应用镜像(ACI)的集合,并且可以在 pod 级别应用一些可选的附加元数据——例如,应用一些资源限制,如 CPU 使用率。

使用 rkt。

由于 rkt 已预装在 CoreOS 中,使用 rkt 运行 ACI 镜像非常简单,而且与 docker 命令非常相似。(我很想写更多内容,但由于 rkt 还在不断变化和创新,目前提供的选项并不多,这在写这本书时也是如此。)

由于 rkt 没有运行 OS X 客户端,你需要直接登录到 CoreOS VM 主机上才能运行以下示例命令:

  1. 首先,我们需要信任远程站点,才能从那里下载任何 ACI 文件,因为 rkt 默认会验证签名:

    $ sudo rkt trust –prefix example.com/nginx
    
    
  2. 然后我们可以从那里获取(下载)一个镜像:

    $ sudo rkt fetch example.com/nginx:latest
    
    
  3. 然后使用 rkt 运行容器非常简单:

    $ sudo rkt run example.com/nginx:v1.8.0
    
    

如你所见,rkt 使用了 ETag——在我们的案例中将会运行 v1.8.0。

rkt 网络

默认情况下,rkt 运行使用主机模式进行端口分配。例如,如果你的 Dockerfile 中有 EXPOSE 80,运行此命令:

$ sudo rkt run example.com/nginx:v1.8.0

rkt pod 将与主机共享网络栈和接口。

如果你想分配一个不同的端口/私有 IP 地址,则使用带有这些参数的 run

sudo rkt run --private-net --port=http:8000 example.com/nginx:v1.8.0

rkt 环境变量

可以使用 --inherit-env 标志从主机继承环境变量。使用 flag --set-env,我们可以设置单独的环境变量。

好的,接下来我们准备一些环境变量,通过以下两个命令来继承:

$ export ENV_ONE=hi_from_host
$ export ENV_TWO=CoreOS

现在让我们在命令中将它们与 --set-env 一起使用,如下所示:

$ sudo rkt run --inherit-env --set-env ENV_THREE=hi_nginx example.com/nginx:v1.8.0

rkt 卷

对于主机卷,需使用 -volume 标志。卷需要在创建新的 ACI 镜像和转换 Docker 镜像时在 ACI 清单中定义。你将得到如下输出:

rkt 卷

以下命令将在 rkt Pod 上挂载 host 目录:

$ sudo rkt run –volume volume-/var/cache/nginx,kind=host,source=/some_folder/nginx_cache example.com/nginx:v1.8.0

请注意,在编写本书时,rkt 卷标准尚未完成,因此当 rkt 达到最终版本时,前面的示例可能无法工作。

接下来,让我们看看 rkt 如何与 Docker 镜像良好配合。

使用 rkt 运行简化版 Docker 镜像

由于在公共的 Docker hub 上有成千上万的 Docker 镜像,rkt 使得你可以非常轻松地使用它们。或者,你可能已经有了一些 Docker 镜像,并希望使用 rkt 来运行它们,而无需构建新的 rkt ACI 镜像,来查看它们如何与 rkt 一起工作。

运行 Docker 镜像与之前的示例非常相似:

  1. 由于 Docker 镜像尚不支持签名验证,因此我们只需跳过验证步骤,并使用 --insecure-skip-verify 标志来获取一个镜像:

    $ sudo rkt --insecure-skip-verify fetch docker://nginx
    
    

    使用 rkt 运行简化版 Docker 镜像

  2. 前面截图中的最后一行表示转换后的 ACI 的 rkt 镜像 ID,这可以用来与 rkt 一起 run

    $ sudo rkt --insecure-skip-verify run sha512-13a9c5295d8c13b9ad94e37b25b2feb2
    
    
  3. 我们也可以用这种方式运行,镜像将会被下载然后运行:

    $ sudo rkt --insecure-skip-verify run docker://nginx
    
    
  4. 如果我们想要与 Docker 镜像一起使用卷,可以运行这行命令:

    $ sudo rkt --insecure-skip-verify run \
    --volume /home/core/share/nginx/html:/usr/share/nginx/html \
    docker://nginx
    
    

    这与 docker 命令非常相似,对吧?

  5. 好的,让我们更新本地开发的 nginx.service,以便使用 rkt

    [Unit]
    Description=nginx
    [Service]
    User=root
    TimeoutStartSec=0
    EnvironmentFile=/etc/environment
    ExecStart=/usr/bin/ rkt --insecure-skip-verify run \
     -volume /home/core/share/nginx/html:/usr/share/nginx/html \
    docker://nginx
    #
    Restart=always
    RestartSec=10s
    [X-Fleet]
    
    

如你所见,那里没有 ExecStop=/usr/bin/docker stop nginx。这不需要,因为 systemd 会在使用 systemctl / fleetctl 停止时,通过发送 SIGTERM 信号来停止运行中的 nginx 进程。

比 Docker 简单多了,对吧?

在下一节中,我们将看到如何将 Docker 镜像转换为 ACI 镜像。

将 Docker 镜像转换为 ACI

随着 CoreOS 的推出,出现了与 rkt 相关的另一个文件——docker2aci。它将 Docker 镜像转换为 ACI 镜像(rkt 使用的应用容器镜像)。

让我们来转换我们的nginx镜像。运行以下命令:

$ docker2aci docker://nginx

将 Docker 镜像转换为 ACI

我们还可以将 Docker 镜像保存在文件中并进行转换。运行以下命令:

$ docker save -o nginx.docker nginx
$ docker2aci nginx.docker

将 Docker 镜像转换为 ACI

最后,您可以尝试通过更新之前的 nginx.service fleet 单元来使用生成的 ACI 文件:

[Unit]
Description=nginx
[Service]
User=root
TimeoutStartSec=0
EnvironmentFile=/etc/environment
ExecStart=/usr/bin/ rkt --insecure-skip-verify run \
 --volume volume-/usr/share/nginx/html,kind=host,source=/usr/share/nginx/html \
 full_path_to/nginx-latest.aci
#
Restart=always
RestartSec=10s

[X-Fleet]

概述

在本章中,我们概述了 CoreOS rkt 的主要特点、rkt 应用容器及其镜像格式。您还学会了如何使用 rkt 将基于 acidocker 的镜像作为容器运行。

在下一章中,您将了解 Google Kubernetes,这是一个用于应用容器的开源调度系统。

第十章:Kubernetes 介绍

在本章中,我们将简要介绍 Google Kubernetes,它在多个主机上管理容器化应用程序。由于 Kubernetes 是一个非常庞大的项目,本章将仅概述其主要概念和一些用例,包括以下内容:

  • 什么是 Kubernetes?

  • Kubernetes 的主要组件

  • Kubernetes 集群设置

  • Tectonic——CoreOS 和 Kubernetes 结合的商业实现

什么是 Kubernetes?

Google 已经在容器中运行一切超过十年了。在内部,他们使用一个名为 Borg 的系统(research.google.com/pubs/pub43438.html),这是 Kubernetes 的前身,用于在服务器之间扩展和编排容器。

从 Borg 中汲取的经验教训被用来构建 Kubernetes,一个开源容器编排系统。它在 2014 年 6 月发布后迅速流行。

Borg 的所有最佳思想都融入到了 Kubernetes 中。许多 Borg 的开发者现在在 Kubernetes 项目中工作。

Kubernetes 在其 GitHub 项目上获得了成千上万的星标(github.com/GoogleCloudPlatform/kubernetes),并得到了开源社区以及 CoreOS、Red Hat、Microsoft、VMware 等公司的大力支持。

Kubernetes 的主要组件

Kubernetes 可以在任何现代的 Linux 操作系统上运行。

以下是 Kubernetes 的主要组件:

  • Master(主节点):这是 Kubernetes 的主要控制服务集,通常运行在一台服务器上,etcd集群除外。但它也可以分布在几台服务器上。Kubernetes 的服务如下:

    • etcd集群

    • API 服务器

    • 控制器管理器

    • 调度器

  • 节点:这是集群中的工作节点。它可以是虚拟机(VM)或裸机服务器。节点由主节点服务管理,并专门用于运行 Pod。每个节点必须运行以下两个 Kubernetes 服务:

    • Kubelet

    • 网络代理

    Docker 和 rkt 用于运行应用容器。未来我们将看到更多支持的应用容器系统。

  • Pod:这是一个共享上下文运行的应用容器组。即使是单个应用容器,也必须在 Pod 中运行。

  • 复制控制器:这些确保指定数量的 Pod 在运行。如果 Pod 太多,它们会被杀死。如果太少,所需的 Pod 数量将被启动。即使只有一个 Pod,也不建议在没有复制控制器的情况下运行 Pod。

  • 服务:同一个 Pod 只能运行一次。如果它崩溃,复制控制器会用一个新的 Pod 替代它。每个 Pod 都有自己的专用 IP,这样就可以在同一个节点上运行多个容器在不同端口上。但每次从模板启动 Pod 时,复制控制器都会分配不同的 IP,这时服务就发挥了作用。每个服务会分配一个虚拟 IP,并且该 IP 会一直与服务绑定,直到服务结束。

  • 标签:这些是每个 Kubernetes 组件使用的任意键值对;例如,复制控制器使用它们进行服务发现。

  • :卷是一个可以从容器访问的目录,用于存储容器的有状态数据。

  • Kubectl:这个工具用于控制 Kubernetes 集群管理器。例如,你可以添加/删除节点、Pod 或复制控制器;查看它们的状态;等等。Kubernetes 使用manifest文件来设置 Pods、复制控制器、服务、标签等。

Kubernetes 有一个不错的用户界面,它是由kismatic.io/开发并贡献的。它运行在一个 API 服务器上:

Kubernetes 的主要组件

这使我们能够检查 Kubernetes 集群的状态,并添加/删除 Pods、复制控制器等。它还允许我们通过用户界面以与kubectl相同的方式管理 Kubernetes 集群。

kismatic.io/也将在不久的将来提供 Kubernetes 的企业/商业版本。

Kubernetes 集群设置

在前一部分中,我们概述了 Kubernetes 的主要功能,现在让我们做一些有趣的事情——在 Google Cloud 上安装一个小型 Kubernetes 集群。

请注意,如果你使用的是免费的/试用的 Google Cloud 账户,该账户有 8 个 CPU 的限制(允许 8 个虚拟机),你需要删除其中的一些。让我们用 Kubernetes 集群替换我们的生产集群。根据以下屏幕截图选择虚拟机。然后点击右上角的删除按钮。

Kubernetes 集群设置

现在我们准备安装 Kubernetes 集群:

  1. 在你的终端中输入以下命令:

    $ cd coreos-essentials-book/Chapter10/Kubernetes_Cluster
    
    

    请注意,由于我们有一些文件夹/文件与我们用于设置测试/暂存/生产集群时非常相似,因此这次我们不再复习这些脚本。你可以随时查看这些设置文件,了解其中的差异:

  2. 更新那里settings文件中的 Google Cloud 项目 ID 和区域。

  3. 现在我们来运行第一个脚本,名为1-bootstrap_cluster.sh

    $ ./ 1-bootstrap_cluster.sh
    
    

    你应该看到类似这样的输出:

    Kubernetes 集群设置

如果你查看 Google Cloud 控制台,你应该会看到三个新的虚拟机,分别是k8s-masterk8s-node1k8s-node2

Kubernetes 集群设置

1-bootstrap_cluster.sh脚本已经安装了一个小型的 CoreOS 集群,它的设置方式与我们之前的测试/暂存/生产集群相同——一个etcd服务器和两个连接到它的工作节点。还会在用户的主文件夹中创建一个新的文件夹k8s-cluster,该文件夹将复制settings文件,并且后续的其他二进制文件也会复制到该文件夹。

  1. 接下来,我们需要在计算机上安装fleetctletcdctlkubectl本地客户端,以便能够与 CoreOS 集群的etcdfleet服务,以及 Kubernetes 主服务进行通信。

    在终端中输入以下命令:

    $ ./2-get_k8s_fleet_etcd.sh
    
    

    你应该看到类似于此的输出:

    Kubernetes 集群设置

  2. 现在,让我们在我们的新 CoreOS 集群上安装 Kubernetes 集群。

    在终端中输入以下命令:

    $ ./3-install_k8s_fleet_units.sh
    
    

    你应该看到类似于这里展示的输出:

    Kubernetes 集群设置

  3. 让我们尝试通过 "" 访问我们的 Kubernetes 集群,该文件已通过 1-bootstrap_cluster.sh 脚本复制到 ~/k8s-cluster/bin

    在终端中输入以下命令:

    $ cd ~/k8s-cluster/bin
    $ ./set_k8s_access.sh
    
    

    你应该看到类似于以下的输出:

    Kubernetes 集群设置

如你所见,我们的 Kubernetes 集群已启动并正在运行。

set_k8s_access.sh 的作用是通过将 localhost 端口 2379(fleet)和 8080(Kubernetes 主节点)转发到远程 k8s-master 服务器,为 fleetctlkubectl 提供访问权限。

  1. 让我们通过在终端中输入以下命令来检查 Kubernetes 集群:

    $ kubectl cluster-info
    
    

    你应该看到类似于此的输出:

    Kubernetes 集群设置

    完美!现在我们可以从本地计算机访问远程 Kubernetes 集群了。

  2. 既然我们的 Kubernetes 集群已经启动并运行,让我们部署与生产集群部署中使用的相同的 website1 Docker 镜像。

    在终端中输入以下命令:

    $  kubectl run website1 --image=10.200.4.1:5000/website1 --replicas=2 --port=80
    
    

    你应该看到以下输出:

    Kubernetes 集群设置

    上一个命令创建了两个监听 port 80website1 pods。它还创建了一个名为 website1 的复制控制器,该控制器确保始终有两个 pods 在运行。

    我们可以通过在终端中输入以下命令列出已创建的 pods

    $ kubectl get pods
    
    

    你应该看到类似于以下的输出:

    Kubernetes 集群设置

    要列出已创建的复制控制器,请在终端中输入以下命令:

    $ kubectl get rc
    
    

    你应该看到以下输出:

    Kubernetes 集群设置

  3. 现在,让我们将我们的 Pods 暴露到互联网。Kubectl 命令可以与 Google Compute Engine 集成,为 pods 添加一个公共 IP 地址。要做到这一点,在终端中输入以下命令:

    $ kubectl expose rc website1 --port=80 --type=LoadBalancer
    
    

    你应该看到类似于此的输出:

    Kubernetes 集群设置

    上一个命令创建了一个名为 website1 的服务,并为该服务映射了一个外部 IP 地址。要找到该 IP 地址,请在终端中输入以下命令:

    $ kubectl get services
    
    

    你应该看到类似于以下的输出:

    Kubernetes 集群设置

最后一行的 IP 地址是我们的 IP,它是负载均衡器的地址。它被分配给 k8s-node-1k8snode-2 服务器,并由 website1 服务使用。

让我们在浏览器中输入这个 IP 地址。我们应该看到类似于此的输出:

Kubernetes 集群设置

如你之前所见,它展示的网页与我们生产环境中的网页完全相同。同时,它的代码也和我们在预发布环境中的代码一模一样。我们从中构建了 Docker 镜像,并将该镜像用于生产集群和 Kubernetes 集群的部署。

如果你愿意,可以通过以下简单命令轻松地运行更多副本的 Pods:

$ kubectl scale --replicas=4 rc website1

让我们通过在终端中输入以下命令来检查我们的复制控制器:

$ kubectl get rc

你应该会看到类似以下的输出:

Kubernetes 集群设置

上述命令用于扩展 Pods,复制控制器确保我们始终运行四个副本。

注意

你可以在github.com/GoogleCloudPlatform/kubernetes/tree/master/examples找到大量的使用示例来进行实验。

本书篇幅太短,无法涵盖使用 Kubernetes 的所有好处,但我们很快应该会看到更多关于 Kubernetes 的书籍出版。

注意

这里提供了一些其他的 URL 供参考:

如果你是 Mac 用户,可以安装一个应用程序来在 Mac 上设置 Kubernetes 集群:1 个主节点 x 2 个节点,网址是 github.com/rimusz/coreos-osx-gui-kubernetes-cluster,以及独立的主节点/节点设置,网址是 github.com/rimusz/coreos-osx-gui-kubernetes-solo

其他关于 CoreOS 上 Kubernetes 的指南可以在 github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/getting-started-guides/coreos.md 查看。

Tectonic – CoreOS 和 Kubernetes 结合实现商业化

Tectonic (tectonic.com)是一个商业化的 CoreOS 发行版,结合了 CoreOS 和 Kubernetes 堆栈。任何规模的企业都可以使用它。

Tectonic 已预装了所有 CoreOS 和 Kubernetes 的开源组件,并添加了一些商业功能:

  • 工作流和仪表盘的管理控制台/UI

  • 企业级单点登录(SSO)集成

  • Quay 集成的容器注册表用于构建和共享 Linux 容器

  • 用于容器部署自动化的工具

  • 定制化的滚动更新

它可以在公有云或本地环境中运行。

它的管理控制台简单易用:

Tectonic – CoreOS 和 Kubernetes 结合实现商业化

在上面的截图中,我们可以看到复制控制器RC)的可视化。在左侧,你可以看到每个 RC 以及它为 Pods 分配的标签。在 RC 名称下方,你会看到所有运行中的 Pods 列表,这些 Pods 匹配相同的标签查询。

Tectonic – CoreOS 和 Kubernetes 结合实现商业化

前面的截图展示了elasticsearch复制控制器的状态、使用的标签以及 Pod 卷。

Tectonic 旨在提供一种简便的容器部署解决方案,公司可以快速看到在企业中使用容器的好处。

摘要

在本章中,我们概述了 Google Kubernetes,介绍了它的基本概念、主要组件以及其 CoreOS 商业实现。

我们希望这本书能够为您提供所需的所有信息,帮助您充分利用 CoreOS 及相关容器的强大功能,并助力您开发高效的计算网络。感谢您的阅读!

posted @ 2025-07-05 19:49  绝不原创的飞龙  阅读(5)  评论(0)    收藏  举报