前言
saltstack 對比 ansible
最大的不同就是saltstack使用的是c/s架構(gòu),即要安裝minion才能訪問客戶端,而ansible則是使用ssh協(xié)議訪問.不得不說,有一部分人就是因為覺得saltstack需要安裝客戶端,感覺很麻煩而選用了ansible.那么下面來說說salt如何通過salt-ssh來安裝minion
salt-ssh
salt-ssh 并沒有包含在salt-master中,所以需要單獨安裝
yum install salt-ssh
前提條件
salt-ssh 使用的前提條件就是roster,只有配置了roster文件后才能使用salt-ssh對機器進(jìn)行操作
下面來看一個roster文件的配置
test1:
host: 192.168.1.101
user: salt
passwd: redhat
minion_opts:
- id: test1
第1行test1: 表示該機器被salt-ssh識別到的id
第2-4行host: 指定機器的IP地址,用戶,密碼,用于ssh連接
第5行minion_opts: 表示執(zhí)行命令時傳遞的參數(shù)
如果客戶端IP沒有在master的known_hosts文件中,需要先添加上去
測試連接是否成功
salt-ssh -i 'test1' test.ping
編寫安裝minion的sls
既然已經(jīng)連接上客戶端,那么只需要在客戶端上裝上minion并啟動就好了
#同步y(tǒng)um的repo
minion_yum:
file.recurse:
- name: /etc/yum.repos.d
- source: salt://minions/yum.repos.d ##提前準(zhǔn)備的yum文件路徑
- user: root
- group: root
- file_mode: 644
- dir_mode: 755
- include_empty: True
- unless: test -e /etc/yum.repos.d/epel_aliyun.repo
#安裝minion
minion_install:
pkg.installed:
- pkgs:
- salt-minion
- skip_verify: True
- require:
- file: minion_yum
- unless: rpm -qa | grep salt-minion
#同步minion的配置文件
minion_conf:
file.managed:
- name: /etc/salt/minion
- source: salt://minions/minion.conf ##minion端需要配置的minion主配置文件
- user: root
- group: root
- mode: 640
- template: jinja
- defaults:
minion_id: {{ grains['id'] }}
- require:
- pkg: minion_install
#啟動minion
minion_service:
service.running:
- name: salt-minion
- enable: True
- require:
- file: minion_conf
文件需要自行準(zhǔn)備,并放到salt root目錄下
minion的主要配置,其他可以自行修改
id: {{ minion_id }}
master: 192.168.1.100
執(zhí)行完sls后,就可以到master上通過salt-key 直接添加minion進(jìn)行管理
擴展
- 通過kickstart批量安裝centos
- 通過Python腳本批量修改服務(wù)器IP
- master批量插入主機信息到roster
- salt-ssh 安裝minion 進(jìn)行管理
kickstart批量安裝centos
批量插入主機信息到roster
為了更加方便,所以配置kickstart時,網(wǎng)絡(luò)可以選擇是dhcp模式,這樣安裝完系統(tǒng)之后就可以上網(wǎng)
master端
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
template = '''
{id}:
host: {ip}
user: root
passwd: password
minion_opts:
- id: {id}
'''
class RequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
response = self.rfile.read(int(self.headers['content-length']))
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.data_parse(response)
self.do_insert(self.data)
result = ('data: %s, send OK\n' % response).encode('ascii')
self.wfile.write(result)
def do_insert(self, data):
with open(r'/etc/salt/roster', 'a') as f:
f.write(data + '\n')
def data_parse(self, data):
print(data)
data = json.loads(data.decode('utf-8'))
print(data)
self.data = template.format(id=data['id'], ip=data['ip'])
print(self.data)
return self.data
def main():
server_address = ('', 8099)
httpd = HTTPServer(server_address, RequestHandler)
httpd.serve_forever()
if __name__ == '__main__':
main()
minion端
ip=`ifconfig | grep 'inet' |grep -v '127.0.0.1'|grep -v inet6 | sed 's/^[ \t]*//g'|cut -d" " -f2`
hostname=`hostname`
data={"id":"$hostname", "ip":$ip}
curl -X POST -d '{"id":"'$hostname'", "ip":"'$ip'"}' "http://127.0.0.1:8099"