这样理解Ansible更容易

滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。—— 《临江仙》 电脑店 从前,有一家电脑店。原来你即是老板,又是店员时,拿到清单,你就必须亲自动手采购,然后一个个零件组装。每天都做着即重复又辛苦的活。 虽说你的组装技术已经很娴熟了,但是偶尔还发生装错的情况(大概是那天和老板娘吵架了),把一个客人要求的 CPU i5 装成了 CPU i7。结果是你亏本或者赚得少了。 后来,你采购了一个自动组装电脑的机器人。你只要告诉它电脑的配置,并把零件放到指定的箱子中。接着启动这台机器,它就自动帮你组装好电脑了。它每天都干重复的活也不会叫辛苦。 最重要的是准确,它不会因为心情不好,而装错。因为它根本不会闹情绪。 这样,老板就可以从重复的工作解放出来。然后将多出来的时间花在与人的沟通上,为有不同需求的人设计更合适的电脑配置清单。毕竟游戏发烧友和办公小白领的需求是不一样的。 在运维领域,不少运维人都干着即是老板又是店员的工作。如果在运维领域也能有这样的“机器人”该多好。事实上,Ansible、Puppet、Check 就是这样的机器人。 为什么要从零设计一个运维机器人 本文并不想生硬地罗列 Ansible 的各个知识点。因为那样,大家不如直接看 Ansible 官方文档就好。 笔者采用从零设计一个运维机器人的方式来告诉你,为什么 Ansible 会是现在这个样子。当然,现实中的 Ansible 不会像本文所写的那样一步步设计。 为什么要这样呢?因为笔者觉得只有知道一个工具背后的设计原理,真正用这个工具才会得心应手。 运维机器人的最终模样 首先,需要确定一下实现这个运维机器人的目的是什么。我们并不是希望所有的运维工作都交给运维机器人,而是希望运维工作中重复的那部分尽可能的交给机器人,把创造性的工作全部交给人。如下图所示。 以终为始是一种非常有效的实现目标的思考模型。根据此思考模型,我们首先必须探讨运维机器人的最终模样。然后,再讨论可能的解决方案。 那么,什么样的运维机器人能帮助我们实现上述的自动化运维目标呢?想像一下。是不是只要我们对着运维机器人说一句:“我要部署一个 Nginx 到 192.168.12.11”。它就可以帮我们完成了? 但是它怎么知道如何连接到 192.168.12.11 呢?是使用用户名密码的方式,还是使用私钥?它又怎么知道 Nginx 需要什么样的配置呢?一问下来,其实,语音运维只适用于启动一些预定义的动作。就像汽车的一键启动。你不可能使用语音来对 Nginx 进行大量的配置。 而纯文本才是进行大量配置的最好媒介。 所以,运维机器人的最终模样是:我们将部署的主机 IP、登录方式、Nginx 的配置放在一个文本文件中,然后运维机器人读取这个文本文件,然后根据配置进行部署。如果部署的是业务系统,我们还需要准备该业务系统的二进制包。如下图所示。 那么,我们在文本文件中使用何种语言描述我们的配置需求呢?可以分成两种。一种是利于人类学习的自然语言(如英语)。另一种是利于机器读取的结构化数据(如YAML、JSON)。 按当前的技术实现的可能性,不论是运维机器人,还是交给其它程序,都需要将自然语言转到结构化的数据。就像程序员,需要将业务知识翻译成编程语言;像编译器将编程语言翻译成机器真正能识别的二进制代码。 运维机器人的真正核心不是将自然语言转成结构化的数据。所以,文本文件中,我们直接写结构化数据。同时,我们决定使用 YAML 格式作为结构化数据的载体。因为它是非常流行的配置文件格式。降低人们写结构化数据的难度。 当然,好的设计不应该与具体配置文件格式耦合。 实现运维机器人要解决哪些问题 以上只是确定了运维机器人的最终模样及使用方式,解决的是用户的问题。但是因为我们是运维机器人的设计者,我们必须考虑如何实现它。 回想一下,平时我们的运维人员是如何实现自动化的?是不是写好了 bash 脚本后,然后将脚本上传到目标机器,最后在目标机器上执行该脚本。 这个 bash 脚本其实也可以算是一种结构化的数据格式,而且是一种不需要再做编译,目标机器能直接运行的格式。 在平时的自动化方式基础上进行抽象。我们觉得要实现运维机器人要解决的关键问题有: 需要将 YAML 转成目标机器可执行的程序(或脚本)。 需要将可执行的程序上传到目标机器,并执行。 为什么一定要将 YAML 转成目标机器可执行的程序呢?直接写 bash 不就可以了? ...

2019-09-19 · 7 min · 1362 words · 翟志军 Jack Zhai

如何设计 Ansible 的入门工作坊

本月在公司内部做了一次 Ansible 的入门工作坊。本文即对这次工作坊的设计过程进行一次总结。其他技术类的工作坊也可以参考。 设计过程大概过程如下文所述。 首先,我们需要确定参加本次工作坊的受众。他们是否具有最基本的前提。本次工作坊的受众有开发、测试、运维,还有毕业生。但是他们都会使用 shell。这已经满足最基本的前提。同时,了解受众后了,也就可以因材施教。 第二,分析工作坊的内容。Ansible 是一款上手非常容易的自动化运维工具。它的特点就是实操性非常强,不需要理解 Ansible 背后的概念就可以使用的工具。 笔者根据受众和教学内容的特点,得出本次工作坊的目标(教学目标): 知道 Ansible 是什么,并知道它的作用。 了解如何查文档。 能部署一个 Spring Boot 应用。 是不是很简单?其实不然。整个工作坊没有一个人能完成所有的任务。同时发现有运维和开发基础的同学会做得更快。 那接下来怎么实现这个目标呢?笔者使用的是任务驱动的方法。也就是受众通过做一个个任务,在任务中完成学习。同时,教师可以任务过程穿插讲相关的知识点。 以下为任务列表: 执行 ansible-playbook -i hosts playbook.yml 成功 创建用户 apps 及用户组 apps: user 模块: https://docs.ansible.com/ansible/latest/modules/user_module.html group 模块: https://docs.ansible.com/ansible/latest/modules/group_module.html 创建以下文件夹,并设置文件夹的用户和组为 apps: /apps,/apps/hello,/apps/hello/bin,/apps/hello/logs file 模块: https://docs.ansible.com/ansible/latest/modules/file_module.html 将 helloworld-0.0.2.jar copy 到 /apps/hello/bin 目录下,设置该 jar 文件的用户和用户组为 apps copy 模块: https://docs.ansible.com/ansible/latest/modules/copy_module.html 使用 template 模块将 app.service copy 到目标服务器的 /etc/systemd/system 中,并重命名 hello.service : template 模块: https://docs.ansible.com/ansible/latest/modules/template_module.html 启动 hello 服务 service 模块: https://docs.ansible.com/ansible/latest/modules/service_module.html 监听 hello 服务是否启动成功 wait_for 模块: https://docs.ansible.com/ansible/latest/modules/wait_for_module.html 为目标机器安装 JDK 1.8: 在本地仓库中创建 roles 目录 clone 代码:https://github.com/geerlingguy/ansible-role-java 到 roles 目录中 在 playbook.yml 文件中加入 ansible-role-java 的role 创建自定义 role: hello role 进入 roles 目录:cd roles 使用命令生成 role 模板:ansible-galaxy init hello 将 hello 的部署逻辑(在 playbook.yml 中)写入到 hello role 中 将 hello 部署到多台机器 需要修改 hosts 文件 多环境部署 任务的设计并不是随意的,而是有意的。比如: ...

2019-07-19 · 1 min · 146 words · 翟志军 Jack Zhai

使用 Jenkins + Ansible 实现 Springboot 自动化部署101

本文要点: 设计一条 Springboot 最基本的流水线:包括构建、制品上传、部署。 使用 Docker 容器运行构建逻辑。 自动化整个实验环境:包括 Jenkins 的配置,Jenkins slave 的配置等。 1. 代码仓库安排 本次实验涉及以下多个代码仓库: % tree -L 1 ├── 1-cd-platform # 实验环境相关代码 ├── 1-env-conf # 环境配置代码-实现配置独立 └── 1-springboot # Springboot 应用的代码及其部署代码 1-springboot 的目录结构如下: % cd 1-springboot % tree -L 1 ├── Jenkinsfile # 流水线代码 ├── README.md ├── deploy # 部署代码 ├── pom.xml └── src # 业务代码 所有代码,均放在 GitHub: https://github.com/cd-in-practice 2. 实验环境准备 笔者使用 Docker Compose + Vagrant 进行实验。环境包括以下几个系统: Jenkins * 1 Jenkins master,全自动安装插件、默认用户名密码:admin/admin。 Jenkins agent * 2 Jenkins agent 运行在 Docker 容器中,共启动两个。 Artifactory * 1 一个商业版的制品库。笔者申请了一个 30 天的商业版。 使用 Vagrant 是为了启动虚拟机,用于部署 Springboot 应用。如果你的开发机器无法使用 Vagrant,使用 VirtualBox 也可以达到同样的效果。但是有一点需要注意,那就是网络。如果在虚拟机中要访问 Docker 容器内提供的服务,需要在 DNS 上或者 hosts 上做相应的调整。所有的虚拟机的镜像使用 Centos7。 ...

2019-05-15 · 2 min · 408 words · 翟志军 Jack Zhai

使用 Jenkins + Ansible 实现自动化部署 Nginx

本文介绍如何使用 Jenkins + Ansible 实现对 Nginx 的自动化部署。最终达到的效果有如下几点: 只要你将 Nginx 的配置推送到 GitHub 中,Jenkins 就会自动执行部署,然后目标服务器的 Nginx 配置自动生效。这个过程是幂等(idempotent)的,只要代码不变,执行多少遍,最终效果不变。 如果目标机器没有安装 Nginx,则会自动安装 Nginx。 自动设置服务器防火墙规则。 1. 实验环境介绍 本次实验使用 Docker Compose 搭建 Jenkins 及 Jenkins agent。使用 Vagrant 启动一台虚拟机,用于部署 Nginx。使用 Vagrant 是可选的,读者可以使用 VirtualBox 启动一个虚拟机。使用 Vagrant 完全是为了自动化搭建实验环境。 以下是整个实验环境的架构图: 注意,图中的 5123 <-> 80 代表将宿主机的 5123 端口请求转发到虚拟机中的 80 端口。 Vagrant:虚拟机管理工具,通过它,我们可以使用文本来定义、管理虚拟机。 Ansible:自动化运维工具 Docker Compose:它是一个用于定义和运行多容器 Docker 应用程序的工具。可以使用YAML文件来配置应用程序的服务。 2. 启动实验环境 克隆代码并进入文件夹 git clone https://github.com/zacker330/jenkins-ansible-nginx.git cd jenkins-ansible-nginx 构建 Jenkins agent 的镜像 需要自定义 Jenkins agent 镜像有两个原因: ...

2019-04-22 · 3 min · 432 words · 翟志军 Jack Zhai

ChatOps实战

ChatOps概念在国内已经有一些文章谈过,但是都处于理论范畴。而本文则是一篇ChatOps实践的文章。 有必要说明我对ChatOps的理解,ChatOps表面上就是在一个聊天窗口中,发送一个命令给运维机器人bot,然后bot根据我们预定义的操作进行执行,并返回执行结果。至于更深层次的作用,就是将重复性的手工的运维工作自动化了,开发人员、运维人员可以按需执行一些运维操作。 另外,我做到了自动化搭建这一套东西(感谢Github上那么多开源项目,让我少写很多Ansible脚本)。为什么要自动化搭建呢?因为我懒,我不想每次通过一条条shell手工搭建。 本文主题 在RocketChat的聊天窗口中命令Hubot执行一次Jenkins构建任务。 工具介绍 有必要简单说明一下我们此次实现ChatOps的这几个工具。 RocketChat 可以把RocketChat想像成一个具有更多功能的IRC或者微信。它依赖于MongoDB,所以,我们还将自动化安装MongoDB。 如果你了解过Slack的话,它可以作为Slack的开源替代表。 Hubot Hubot是Github出品的一个运维机器人。本质上就是一个接收命令消息,执行预定义操作的一个程序。而接收命令消息的这个组件在Hubot中被称为Adapter。比如我们希望Hubot接收来自RocketChat聊天窗口里的消息,我们就必须为Hubot安装一个RocketChat的Adapter。市面上,已经有很多Adapter了,我们很少需要自己实现自定义Adapter。 那么,Hubot接收到命令消息后,怎么知道执行哪些操作呢?这部分是需要我们实现了。本质上就是通过正则表达式匹配命令消息,然后操作。实际上通过写Coffescript脚本实现。比如: robot.respond /open the (.*) doors/i, (res) -> doorType = res.match[1] if doorType is "pod bay" res.reply "I'm afraid I can't let you do that." else res.reply "Opening #{doorType} doors" Jenkins 就这个就不用多介绍了。值得一提是Github已经有不少自动化搭建Jenkins的Ansible脚本了(完全不需要人工干预),本文使用的是geerlingguy的。 Ansible 能让开发人员快速上手的自动化运维工具。我们使用Ansible实现自动化。想简单了解Anbible,可以看看简单易懂Ansible系列 —— 解决了什么。 准备环境 需要准备几台机器: IP OS 安装 192.168.61.11 CentOS7 Jenkins,Openresty(for Jenkins) 192.168.61.14 CentOS7 Openresty(for RocketChat) 192.168.61.15 CentOS7 RocketChat Server, MongoDB,Hubot 因为我是在本地做实验的,所以需要在本机虚拟化3台机器。我使用Vagrant + VirtualBox的方式来实现。具体Vagrant如何使用,不在本文讨论范围。你也可以手工在VirtualBox或Vmware上创建相应的虚拟机。Vagrant只不过是自动化了这个过程。Vagrant会基于一个称为Vagrantfile的文件来创建机器。 ...

2017-10-08 · 1 min · 205 words · 翟志军 Jack Zhai

简单易懂Ansible系列 —— 实现ssh key主机之间复制

我们在搭建Hadoop完全分布式环境时,Hadoop的name node节点(理解为master节点)需要无密码登录到所有的data node节点。 当然,我们使用手工的方式很容易就实现了: 在name node节点上生成ssh key:ssh-keygen 将public key copy到所有的data node节点上:ssh-copy-id slave1 同时,你还必须设置~/.ssh/config,以防止登录时不停的问yes or no: ```yml Host * StrictHostKeyChecking no ``` 完了,还要设置这个文件的权限为400。 以上步骤当然可以手工一步步执行。但是,总有那么一些人:希望所有的操作都可以版本化,所有的操作都应该自动化。我属于这些人。 再说了,我发现在搭建Jenkins环境时,也遇到了同样的问题:需要将Jenkins master的public key加入到Jenkins agent机器中。 可以预见到将来我还会遇到类似的问题。于是,我找到一个方法来自动化以上操作。 在name node机器上执行task如下 创建用户的时候生成ssh_key: - name: create hadoop user user: name: "{{hadoop_user}}" group: "{{hadoop_group}}" createhome: yes generate_ssh_key: yes ssh_key_bits: 2048 ssh_key_file: .ssh/id_rsa tags: - hadoop 将id_rsa.pub拉取到ansible执行机器上 - name: fetch public key fetch: src: "/home/{{hadoop_user}}/.ssh/id_rsa.pub" dest: /tmp/ flat: yes tags: - hadoop 设置StrictHostKeyChecking no 因为我们只想修改这个用户的ssh行为,所以我们的ssh的配置只是针对当前这个用户的: ...

2017-08-19 · 1 min · 157 words · 翟志军 Jack Zhai

简单易懂Ansible系列 —— 解决了什么

不知什么时候,Ansible的slogan从“IT Automation Software for System Administrators”变成了“AUTOMATION FOR EVERYONE”。 从一个给系统管理员使用的工具变成了给所有人使用的工具。 但是,现实中,发现了解Ansible的人,还是太少了。同时,自己断断续续学习Ansible也有一段时间,希望拿出来和大家交流。所以就决定不定期写写一个关于Ansible的系列。如果你觉得我写得还可以,到文末扫码请我喝杯茶。 此文为“简单易懂Ansible”系列文章的开篇 —— Ansible解决了什么 Ansible解决了什么 首先,它是一个运维工具。当然要解决运维过程中遇到的问题了。运维过程遇到了什么问题? 想像一下,你要在一台新的机器上安装Tomcat,你会怎么样呢,条件反射的: ssh [email protected] wget -c http://apache.fayea.com/tomcat/tomcat-8.5.15.tar.gz tar -zxf apache-tomcat-8.5.15.tar.gz .....省略 好,10分钟后你愉快地完成了老板给你的任务。但是现在你需要给100台机器安装Tomcat呢?手工的重复100次? 而Ansible能让我们只定义一次,理论上可以在无限台机器上执行。换句话:减少运维工作中的重复工作。 同时,如果是人工执行100次,那么失误是难免的!自动化运维工具会严格根据我们所给指令来执行,而不会因为失恋而手抖执行了:sudo rm -rf /。 不少人反对自动化,认为那样太危险,因为一不小心就在上百台机器删错文件。显然,他们没有注意到:自动化实现的是准确地执行指令,解决人类执行任务时存在的指令理解不正确、执行不严格的问题。而机器不会出现这些问题的概念几乎为零。 没有达到预期效果,往往是我们人类下达的指令不正确。 所以,Ansible还解决了人执行指令不准确的问题。 如果使用Ansible来实现上述的运维需求,怎么做呢?你需要做三件事情: 定义目标机器的列表:一种被称为inventory的类ini文件 定义这些机器的配置:使用YAML格式的文件来描述你机器的配置 执行 ansible-playbook -i inventory playbook.yml 以下是inventory文件: [tomcat-servers] 111.111.111.111 112.112.112.112 .... 而这些ip的配置写在一种被称为playbook的YAML文件中: --- - hosts: tomcat-servers tasks: - name: download tomcat get_url: url: http://apache.fayea.com/tomcat/tomcat-8.5.15.tar.gz dest: /tmp - name: unarchive tomcat to /usr/local unarchive: src: /tmp/apache-tomcat-8.5.15.tar.gz dest: /usr/local/ remote_src: true .....省略 如果你想再添加100台机器,你需要做的,也只是在inventory文件里添加100个ip,再执行一遍ansible-playbook命令。 ...

2017-06-12 · 1 min · 123 words · 翟志军 Jack Zhai

如何在半小时搭建一个简单的日志分析平台?

人们常常说数据如金,可是,能被利用起的数据,才是“金”。而互联网的数据,常常以日志的媒介的形式存在,并需要从中提取其中的"数据"。 从这些数据中,我们可以做用户画像(每个用户都点了什么广告,对哪些开源技术感兴趣),安全审计,安全防护(如果1小时内登录请求数到达一定值就报警),业务数据统计(如开源中国每天的博客数是多少,可视化编辑格式和markdown格式各占比例是多少)等等。 之所以能做这些,是因为用户的所有的行为,都将被记录在nginx日志中或其它web服务器的日志中。日志分析要做的就是将这些日志进行结构化,方便我们的业务人员快速查询。日志分析平台要做的就是这些。 说完这些,你是不是觉得日志分析平台很难做,需要十人的团队加班几个月才能完成? 自从有了Elasticsearch、Logstash、Kibana,俗称ELK,小公司也可以很轻松地做日志分析了。说白了,1天几G的日志,ELK完全可以吃得消。就像标题说的,只需要1个人半小时就可以搭建好了。前提是你已经熟悉了Ansible。下文也假设你已经熟悉Anbile,如果不熟悉可以看看我的另一篇文章:Puppet,Chef,Ansible的共性 本文目的就是教你如何在搭建一个日志分析平台的雏形。有了这个雏形,你可以慢慢迭代出更强大,更适合你业务的日志分析平台。同时,提供可执行的源代码:OSC-AdCenter 简单日志分析架构图 我做了简化,架构图中的每个组件都可以分别放到不同的机器。这里简单介绍下这些你组件: your app:你的应用,我们的源码中,把这个给省略了 Openresty:基于Nginx的Web开发平台,你可以想像它基于Nginx做了很多扩展,类似淘宝的Tengine。为什么我们不直接使用Nginx呢?因为在Openresty上,我们可以做更多事情。 Logstash:日志收集,结构化数据后,push到Elasticsearch中,基于JRuby。可使用其它日志收集工具替代,比如Beats Elasticsearch:分布式搜索引擎,基于Lucene Kibana:用于可视化数据,基于NodeJs 日志分析平台开发所需要工具 Ansible 2.0+:简单的自动化配置工具,运维工具。关于自动化配置还有什么好说的呢? Vagrant:操作系统虚拟化工具,开发时使用。如果没有听过,Docker总听过吧。这家伙就和Docker完全类似的功能,也早于Docker出现。 一个简单的支持yml格式高亮的文本编辑器,比如Atom 自行下载JDK8:jdk-8u66-linux-x64.tar.gz放到项目路径:provision/roles/jdk8/files/jdk-8u66-linux-x64.tar.gz P.S. 抱歉这个的确需要你自己下。 什么?不用写代码吗?的确不用需要写。如果你要扩展这个雏形就会需要写一些脚本。 启动一台服务器 因为我们需要在本地开发好以后,再部署到生产环境,所以,我们需要一台服务器用来做实验。用Vagrant可以在你的开发机上虚拟化一台。clone 下 OSC-AdCenter后,进入项目目录执行:Vagrant up 文件Vagrantfile有描述这台机器的配置: Vagrant.configure(2) do |config| ANSIBLE_RAW_SSH_ARGS = [] machine_box = "trusty-server-cloudimg-amd64-vagrant-disk1" machine_box_url = "https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box" config.vm.define "oscadcenter" do |machine| machine.vm.box = machine_box machine.vm.box_url = machine_box_url machine.vm.hostname = "oscadcenter" machine.vm.network "private_network", ip: "192.168.4.10" ##指定这台机器的IP,只能宿主机能访问 machine.vm.provider "virtualbox" do |node| node.name = "oscadcenter" node.memory = 4048 node.cpus = 2 end end end 更多关于Vagrantfile:https://www.vagrantup.com/docs/vagrantfile/ Vagrant机器的默认账号密码都是: vagrant,所以你可以使用ssh [email protected]登录这台机器。也可以使用vagrant命令登录,在Vagrantfile所在目录下执行:vagrant ssh oscadcenter。 部署日志分析平台 在你的开发机上,安装好ansible: 服务器准备好了,我们只需要一条命令就可以部署OSC-AdCenter了: ansible-playbook ./provision/playbook.yml -i ./provision/inventory -u vagrant -k 然后输入ssh登录密码:vagrant。 简单说明: ansible-playbook是ansible的一个命令 ./provision/playbook.yml是描述你的服务器配置的文本,你可以想像成所有的部署脚本都写在这个文件中 ./provision/inventory是服务器在playbook在的host与ip的映射表,比如playbook中这么写: ...

2016-09-10 · 1 min · 179 words · 翟志军 Jack Zhai

Puppet,Chef,Ansible的共性

本文试图找到类似Puppet、Chef、Ansible这样自动化配置管理工具的共性,以不至于迷失在杂乱的尘世中。总会有各种人为各种目的造概念,来让世界更复杂。 本文同样适用于没有运维经验的人。因为我就是一个没有运维经验的人。欢迎斧正。 与这仨之间的历史 本人接触自动化运维的时间比较晚,也就一年前才知道Puppet及自动化运维(只限于知道),而Chef、Ansible就更晚了。然而在学习它们之前,我对运维要做哪些事情并没有概念。这就对我学习Puppet,Chef和Ansible造成的障碍。因为不知道这三个工具在运维领域的位置,解决运维过程中的哪些问题。我对这三个工具的最初印象就是有了它们,不用我手工的SSH上服务器,然后一条条命令去执行安装软件,不用SCP war包上服务器等,对服务器的操作都可以自动化了。 这个最初印象也就是我跟它们的历史。为什么要说这些呢?就是因为这个最初印象,让我觉得它们是有共性。所谓共性就是存在一些共通的概念或原理之类的东西,掌握这些“东西”,我就可以站在一个更高的高度去思考。Puppet, Chef, Ansible都是工具,对于工具来说,共性指的是它们共同要解决的问题。 但是当我翻了不少文章后依然没有结果。所以,我决定自己去找它们的共性,并记录下来。 自制一个自动化运维工具 但是要从多个相似的东西中找到共性,似乎需要同时很熟悉它们。但是我没有那么多时间。所以,我选择了另一种方法:在大脑中预想自己去实现一套自动化运维工具。但问题是,我都不知道“自动化运维工具要实现哪些功能。 那我就先把目标降低一些,把问题简化一下:将我最初的“印象”实现自动化了。我能想到的就是写一个bash脚本: ssh .... apt-get install -y java apt-get -y nginx scp .. 好,现在将问题难度加大:对多台服务器进行同样的操作。我能到想就是将所有的服务器的IP放在一个数组里,然后用for循环执行。问题来了,如果我对服务器已经执行了一次命令时可能会失败,我再想执行第二次怎么办呢?这时,我们可以在bash脚本里加上if语句,如果安装了java就不安装第二次了。 显然现实中还会有很多问题,如: 反向配置问题,这时,我们应该另写一个bash脚本来解决这个反向的问题?如果采用这种方案,我们bash脚本数量上升到一定程度,如何管理这些脚本及它们之间的关系,这个方案带来的新的复杂性将会成为我们的新问题; 服务器上操作系统的兼容性问题:不同的操作系统,我们的bash命令会不同; 软件的版本升级或降级问题等等。 面对这些问题,我们是可以每次都用bash解决,但是这样始终不是个办法。因为,bash对于建立一个自动化运维工具过于底层。说到这句话,你应该很容易就想到设计一种DSL。到这个点,我觉得我们的方向已经明朗。Puppet, Chef和Ansible都分别采用不同的DSL。而这种DSL是需要编译成服务器可执行的东西的。什么东西是可执行的?目前,我们假设这个东西是bash脚本。 但是这个DSL是放在哪里编译呢?放在受控机器端,还是主控机器上?所以,我认为所有的自动化运维工具都会遇到这个问题。什么是受控机器与主控机器?你就理解成一台机器只发命令,另一台机器只执行命令。 我们刚刚谈的是设计DSL。但是,要设计一个完整的自动化运维工具,我们最先应该考虑是主控机器如何与受控机器通信。这个问题让我很长时间感到很无力,因为无从下手。后来醒悟,原来你不能单独考虑这个问题,通信方式还与你设计的DSL及编译DSL的方式有关。同时,受控机器的执行结果这个问题,也影响着我们设计DSL。 上面我们似乎忘记了一个事实:自动化运维工具应对的往往不是一台机器,而是很多台机器。当面对多台机器时,就会产生一个新的问题:如何组织它们?因为不同的机器的职责不同,所对应的配置也就不同。 我想我们已经知道自动化运维工具都要解决的问题了: 如何与受控机器通信 如何组织成百上千台机器 DSL的设计与编译 如何得到执行结果 我不确定我们的思路与Puppet,Chef和Ansible的作者一样。也不一定完全正确。但是至少,我们大概知道自动化运维工具要解决哪些问题了。而它们是不是自动化运维工具的共性?我不确定。 但是没有关系,我们假设它们就是所有配置管理工具都要解决的问题,它们的共性,接下来我们来看看它们分别是怎么解决这些问题的。 这仨的背景 在进入学习之前,我们先看看它们的背景,然后详细了解它们是如何解决问题的。 Puppet 如何与受控机器通信 Puppet的主控机器(Server)称为Puppet master,受控机器(client)称为Puppet agent。它们使用HTTPS进行通信。在安装puppet之前,需要分别在主控机器和受控上设置的hostname。 因为是C/S架构的,意味着你需要在主控机器上安装Puppet master,(安装的过程或翻阅其它教程的时候,请注意教程所使用的Puppet的版本,Puppet版本之间是有差异的)我们以Ubuntu为例: sudo apt-get install -y puppetmaster 在受控机器上安装Puppet agent: sudo apt-get install -y puppet 安装完成后,受控机器需要设置在/etc/puppet/puppet.conf文件的[main]节点下加入server=<master’s hostname>,同时运行sudo puppet agent —test向主控机器申请认证。主控机器执行sudo puppet cert sign <agent’s hostname>认证。 ...

2016-01-02 · 3 min · 614 words · 翟志军 Jack Zhai