使用 Ansible 管理 CoreOS
来自: http://python.jobbole.com/84255/
这篇文章是关于使用 Ansible 管理 CoreOS 的基础技术。如果你熟悉 Ansible 和一些基本的 CoreOS知识有助于更好的理解下文 。
什么是Ansible?
Ansible 是一个IT自动化工具。它可以配置系统,布署程序和管理很多高级IT任务,像持续集成和零当机更新。
Ansible 是一个底层工具,可以(通常通过 SSH)远程(Inventory)运行一组命令,这些命令可以是一行简单的 shell 语句,也可以使用 Ansible 内置模块执行一些常用任务,如文件复制,包管理,系统信息等等。Ansible 已经包含了很多有用的模板,你也可以很容易地创建你自己的模块。
为什么使用 Ansible for CoreOS?
Ansible 不需要在在目标机器上安装远程代理,只需通过基本的 SSH 连接就可以运行全部功能。
对运行容器来说 CoreOS 是一个 Linux 极小发行版。它没有象桌面发行版那样附带包管理器和一些通用的系统功能。
因为 Ansible 不需要一个远程代理,并且 CoreOS 的设计目标就是通过系统软件直接运行在容器中,两者相互支撑。
起步
继续之前,请确认你已经在你本地安装了 Ansible 。如果你已经正确安装,你可以在 shell 里运行下面这条命令:
$ ansible --version ansible 1.8
$ ansible --version ansible 1.8
为了在本地 CoreOS 上演示 Ansible 我们使用 Vagrant 文件准备了一个简单的仓库。这也是一个好的方式,用来检查你的 playbooks (Ansible commands 命令集)是否像你期望的那样运行。你需要安装 vagrant 才能使用这些示例.
如果你已经在运行 Ansible,并且熟悉在云平台上启动 CoreOS,你可以无视这些步骤,直接跳到下一节。
在你本地机器运行下面命令:
$ git clone https://github.com/defunctzombie/coreos-ansible-example.git $ cd coreos-ansible-example $ vagrant up -- wait for vagrant to finish booting the machine(s) -- $ ./bin/generate_ssh_config
$ git clone https://github.com/defunctzombie/coreos-ansible-example.git $ cd coreos-ansible-example $ vagrant up -- wait for vagrant to finish booting the machine(s) -- $ ./bin/generate_ssh_config
这会启动一个 CoreOS 服务器并且配置一些基本网络连接,服务器启动后,我们运行一个本地脚本 generate_ssh_config 创建一个 Ansible 配置文件,这样就知道怎样通过 SSH 连接我们的服务器。
Inventory 设置
Inventory文件是用来定义主机和群组。在我们的 vagrant 示例中有一个 inventory 文件:ininventory/vagrantwhich,在使用 ansible 配置我们的 CoreOS 示例时我们会用到它。
## inventory file for vagrant machines core-01 ansible_ssh_host=172.12.8.101 [web] core-01
## inventory file for vagrant machines core-01 ansible_ssh_host=172.12.8.101 [web] core-01
我们只有一个命名为 core-01 的主机,我们已经创建了一个命名为 web 的群,并且列出该群下的所有主机。你可以拥有任意数量的主机和群。Ansible 甚至支持动态 Inventory 文件,适合应用在大型生产环境
通过我们的 vagrant inventory 运行一下 ping 测试,通过 shell(在项目文件夹下)执行下面的命令:
$ ansible -i inventory/vagrant all -m setup
$ ansible -i inventory/vagrant all -m setup
如果一切正常,你将看到下面的输出:
core-01 | FAILED >> { "failed": true, "msg": "/bin/sh: /usr/bin/python: No such file or directory\r\n", "parsed": false }
core-01 | FAILED >> { "failed": true, "msg": "/bin/sh: /usr/bin/python: No such file or directory\r\n", "parsed": false }
这个命令失败了。为了弄清楚失败原因和解决办法,让我们近距离观察一下Ansible是如何在远程机器上运行的。
运行 Ansible
当你运行 Ansible 命令或者 playbook 时,Ansible 会通过 SSH 访问远程机器,复制模块代码(使用 Python 编写)并且使用 playbook 中指定的参数运行模块代码。
目标机器必须安装一个 Python 编译器,Ansible 才能执行这些模块代码进而配置你的机器。
CoreOS 是设计运行在容器里,并没有内置 Python 编译器,也不能通过包管理器安装 Python。这就是产生了一个鸡和蛋的问题。
幸运的是 Ansible 有一个原生可执行模块,可以执行 python 模块直接在远程系统运行 shell 命令。我们通过这个功能在我们的 CoreOS 主机上启动一个轻量级的 Python 解释器。一旦主机可以通过 Python 引导,playbooks 可以使用 myriad 提供 Ansible 模块来执行系统任务,如启动服务,安装 python 库,管理 Docker 容器。
编辑inventory/vagrant文件在最后一行添加如下内容:
[coreos] core-01 [coreos:vars] ansible_ssh_user=core ansible_python_interpreter="PATH=/home/core/bin:$PATH python"
[coreos] core-01 [coreos:vars] ansible_ssh_user=core ansible_python_interpreter="PATH=/home/core/bin:$PATH python"
在所有croeos群会配置Ansible在/home/core/bin下查找python和pip,否则Ansible会尝试查找/usr/bin/python,这个路径在我们的CoreOS主机是不存在的。
我们使用 coreos-bootstrap 规则启动我们的CoreOS主机。
使用下面的命令安装规则:
$ ansible-galaxy install defunctzombie.coreos-bootstrap -p ./roles
$ ansible-galaxy install defunctzombie.coreos-bootstrap -p ./roles
现在我们可以使用ansible运行提供的bootstrap.yml文件。
$ ansible-playbook -i inventory/vagrant bootstrap.yml
$ ansible-playbook -i inventory/vagrant bootstrap.yml
命令运行完成后,我们可以运行我们最初的ansible设置命令,并且会看到facts列表。
$ ansible -i inventory/vagrant all -m setup core-01 | success >> { "ansible_facts": { "ansible_all_ipv4_addresses": [ "172.17.42.1", "10.0.2.15", "172.12.8.101" ], ...
$ ansible -i inventory/vagrant all -m setup core-01 | success >> { "ansible_facts": { "ansible_all_ipv4_addresses": [ "172.17.42.1", "10.0.2.15", "172.12.8.101" ], ...
花点时间看一下atbootstrap.yml和site.ml文件,bootstrap.yml是第一个包含的。你自己的Ansible脚本同样需要bootstrap.ml,否则在运行其他playbooks之前配置CoreOS主机。
Playbook 例子
一旦 Ansible 在你的 CoreOS 主机上可以成功运行,我们就可以做一些事情象启动系统服务,启动Docker容器等。
website.yml 文件显示了一个例子。它启动 etcd 服务,接着使用 pip 安装 docker-py,最后在 web 主机群上使用 Ansible docker 模块启动一个容器。
- name: example nginx website hosts: web sudo: true tasks: - name: Start etcd service: name=etcd.service state=started - name: Install docker-py pip: name=docker-py - name: pull container raw: docker pull nginx:1.7.1 - name: launch nginx container docker: image="nginx:1.7.1" name="example-nginx" ports="8080:80" state=running
- name: example nginx website hosts: web sudo: true tasks: - name: Start etcd service: name=etcd.service state=started - name: Install docker-py pip: name=docker-py - name: pull container raw: docker pull nginx:1.7.1 - name: launch nginx container docker: image="nginx:1.7.1" name="example-nginx" ports="8080:80" state=running
使用下面命令运行这个playbook。
$ ansible-playbook -i inventory/vagrant website.yml
$ ansible-playbook -i inventory/vagrant website.yml
现在你打开 http://172.12.8.101:8080 ,可以看到nginx的默认首页 。
你现在已经可以创建更多的plays,用来配置你的CoreOS主机,Plays可以用来运行很多任务,像app自动布署,集群管理,等等。
小提示
本地 Docker 注册
从远程注册机下载镜像需要消耗时间和带宽。要管理一个集群时,运行一个本地注册机,其他机器从注册机拉取可以加速开发效率。使用 roles 和 playbooks 可以轻松自动搞定。
在通用 playbook 安装 pip 模块
如果你要安装 docker 模块,可以考虑在设置好 bootstrap.yml 之后,在 playbook 上通过 pip module 为所有主机安装 docker-py。
使用容器而不是本地二进制
避免使用大量的本地已安装的优化工具过度配置 CoreOS 主机。在很多种情况下,容器化服务可以很好的运行,且不需要更多的底层主机访问权限。
你甚至可以通过挂载的方式绑定另外一个容器的相关路径而映射主机的进程。
</div>