从前有个名叫chef的大厨,功夫甚为了得,通过如下几招:
chef-client就成为chef大厨餐厅的免认证,唯一VIP会员了。
这么复杂的东西,chef大厨也自写了一套秘籍:knife,来进行管理,knife种有不同的招式,来对不同的方面进行不的处理;使用起来也相当方便
比如给客人新加一道菜(客户吃什么也都是chef控制的,东西怎么做也是chef控制的,太霸道了)
knifenoderun_listaddclient1nova在去掉一道菜:
knifenoderun_listremoveclient1nova这套秘籍还有很多的招式,预知详情,输入knife,按回车
不过呢,chef大厨认为自己厨艺比较高,怕餐厅工作都自己搞,人多了忙不过来,就定了个规矩,上菜,只上菜谱,而且不主动给送(就是这么霸道);客户要什么菜,告诉大厨,大厨给你发过去;这样大厨就比较轻松了,客户累了一点(也就是是说真正干事的人是客户自己,客户在自己的家里按照菜谱做自己要的菜);不过这样做的好处就是可以用较低的成本,完成较多的工作;而且呢,客户也可以是一些小客户,在地球上没有独立或者固定地址的客户。
既然这样,也就是说,如果是仅仅是想到不错的菜,对菜的具体加工过程没有洁癖的话,只要去研究这个菜谱怎么搞,就好了;如果有洁癖,想吃很好的菜,那就去研究这个餐厅的工作机制吧,我想要的是吃上不错的菜,那么我就去研究这个菜谱怎么写;而我是个懒人,实现我的效果即可
先看眼菜谱是什么样的
treeopensshopenssh├──attributes│└──default.rb├──files│└──default│└──mysh├──metadata.rb├──recipes│├──default.rb│└──pubkeys.rb└──templates└──default ├──ssh_config.erb └──sshd_config.erb6directories,7files1:我需要什么2:我做什么有了上面的准备工作,下面就该操刀实干了
shell是如此的强大,但是如果全部用shell来实现我们的需求,那我们刚才花的那几分钟岂不是白花了,不能让他白花;看看shell之外有有那些路可以走。
首先整理下,一般情况下,我们都需要对系统做什么操作(当然,我们需要的所有东西,基本都可以通过执行一个命令来实现,我认为,从某个角度来说,这就是对shell的另一种实现)
操作上有以下几种:
模式:
模式“模式名”do。。。#这里写你。。。#要做的操。。。#做end模式只能使用chef定义好的,模式名,可以自定义
directory"/root/script"doowner"root"group"root"mode0755action:createend创建一个/root/script的文件夹,用户属于root,用户组也属于root,权限为0755
directory"/root/script"dorecursivetrue#递归删除action:deleteend不要怀疑,刚看起来,对一个文件夹操作都要这么多行代码,真麻烦
file"/root/123.txt"doowner"root"group"root"mode00755action:createendfile"/root/123.txt"doaction:deleteendexecute"upgradescript"docommand"shutdown-h0"action:runendcommand决定了执行什么命令(里面写什么就执行什么)action怎么操作做这个命令(这是个通用选项),这里写的是执行,也是每次到这里都会执行这个命令这个操作每执行一次,你的系统就关机一次
package"dstat"doaction:installend在模块名出写上,要操作的包的名字
action决定怎么操作做个包
逻辑上有以下几种:
看看chef的实现方式:
template"/etc/nginx/nginx.conf"donotifies:run,"execute[nginx_reload]",:immediatelyendexecute"nginx_reload"docommand"nginx-sreload"action:nothingendnotifies:标记了,什么时候通知什么操作,做什么动作
官方文档是这样写的:
notifies:action,"resource_type[resource_name]",:notification_timing那么“notifies:run,“execute[nginx_reload]”,:immediately”,这句话翻译成人话,就是这样的,马上运行名字为”nginx_reload”的命令;在结合场景翻译下:在对/etc/nginx/nginx.conf配置完成后,马上运行名字为”nginx_reload”的命令。
action:这里的nothing,标记了该操作,平时的不作为,如果吧这里的nothing改为run,那么就满足了上面说到的蛋蛋都疼的需求
如果将上面2个需求翻译成英语就是
翻译成chef的语法就是:(会英语就是好啊,学技术都这么快,语法都能猜出来了)
only_if和not_if的意义虽然不一样,但是用法是一样的
这种情况下chef的操作代码就像是这样:
execute'restart_mysql'docommand'/etc/init.d/mysqldrestart'not_if'netstat-ln|grep3306'end这个翻译成人话就是执行”netstat-ln|grep3306”,如果有输出,就不执行这个命令来,否则执行
interpreter:这里指定了bash,既然需要制定,就说明这里的选择不仅仅一个,还应该有其它,还真猜对了,这里可以写bashcshperlrubypython(当然应该是bash用的多些吧,反正如果让我执行py的话我是不会这样写的)
user:指定了在什么目录下运行,当然在脚本的第一行,cd到某个目录也是一样的效果
code:指定了结尾的logo,这里,从当前行开始,一直到,EOH中间的都是要执行的脚本
not_if在这里加了个判断,只要在/usr/local/src目录下没有名字nginx的文件时,才执行这个脚本
比如要对莫个客户做调整:
\#knifenodeeditclient_name会打开一个编辑器,显示当前用户的配置文件(json格式,要注意里面的东西一定要是json的否则,如果你些了半天,有个标点符号错,然后保存了,恭喜,你刚才些的白写了),
{"name":"client_name","run_list":["recipe[os_init]","recipe[openssh]"],"normal":{"openssh":{"server":{},"client":{}},"manage":{"extra":["user1","user2"]},"tags":[]},"chef_environment":"_default"}在normal的下面有这样一段:
"manage":{"extra":["user1","user2"]},在recipe或者template中,如何使用这些信息呢?通过node[‘manage’][‘default’]这个变量就可以获取到一个内容为有2个元素(‘user1’,’user2’)