本教程将解释如何运行一套salt-environment,其中单个minion可以拥有多个master服务器,并且如果当前master服务器失败了,则在它们之间进行故障转移。
配置步骤是:
- 配置master(s),签署其auth-reply
- 设置minion(s),以验证master-public-keys
- 在minion(s)上启用对多masters的支持
- 在minion(s)上启用master-check功能
请注意,建议你事先对salt身份验证和通信过程进行了解,以理解本教程的内容。 此处描述的所有设置都在salt默认的身份验证/通信过程之上实现的。
salt-minion的默认行为是连接到一个master服务器并接受master服务器的公钥。 随着每个发布管理命令,master发送他的public-key供minion检查,如果这个public-key发生了变化,则minion会报错并退出。 实际上,这意味着在任何给定时间只能有一个master。
如果当前的master因网络或硬件故障而失联了,但minion可以拥有任意数量的masters(1:n),那么会不会更好?
注意
另外还有一个MultiMaster-Tutorial的部署方案,它具有与此不同的方法和拓扑,显然也更加简单,可能也能满足你的需求,甚至可能更适合,请参见Multi-Master Tutorial
我们还希望在一个minion从master那里收到的第一个公钥信息的过程中添加一些真实性检查。 目前,minion将接受第一个master的公钥视为理所当然的行为。
设置master设备以签署它发送给minions的公钥,并使minions能够验证此签名的真实性。
要使用签名功能,master和minion都必须启用签名和/或验证的设置。 如果master签署了公钥但是minion没有核实,那么minion就会报错并退出。 同样的情况也发生在,当master没有签名但是minion试图验证时。
让master签名其公钥的最简单方法是设置:
master_sign_pubkey: True
在重新启动salt-master服务后,master服务器将自动生成新的用于签名服务的密钥对:
master_sign.pem
master_sign.pub
可以指定一个自定义的密钥对的名称:
master_sign_key_name: <name_without_suffix>
然后,master服务器将在重新启动时生成该密钥对,并使用它来创建附加到auth-reply的公钥签名。
这种计算是针对一个minion的每个auth-request完成的。 如果有许多minions频繁做授权,建议使用下面描述的conf_master:master_pubkey_signature和conf_master:master_use_pubkey_signature设置。
如果正在使用多个masters服务器且启用了签署其auth-reply的功能,则必须将用于签名的密钥对master_sign.*文件复制到每一个master服务器上。 否则,当连接到不同的master时,minion将会因为公钥签名是使用不同的签名密钥对创建的,而无法验证master的公钥信息。
Minion需要拥有签名使用的公钥(并且只能是正确的那个!)才能验证它收到的签名。 我们需要将该公钥(默认为master_sign.pub)从master服务器复制到minions节点的pki-directory中一份。
/etc/salt/pki/minion/master_sign.pub
千万不要把 master_sign.pem文件也复制走了,这个私钥文件只能存放在master上
当准备好上面的公钥文件后,在minions的配置中启动签名检查的功能:
verify_master_pubkey_sign: True
以debug模式重启下salt minion服务,这样便于观察下上面配置的功能是否正常:
salt-minion -l debug
启动后,你应该能看到类似下面这样的debug日志信息:
[DEBUG ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG ] salt.crypt.verify_signature: Loading public key
[DEBUG ] salt.crypt.verify_signature: Verifying signature
[DEBUG ] Successfully verified signature of master public key with verification public key master_sign.pub
[INFO ] Received signed and verified master pubkey from master 172.16.0.10
[DEBUG ] Decrypting the current master AES key
或者,运气不好的话,也许看到的是类似下面这样的报错信息:
[DEBUG ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG ] salt.crypt.verify_signature: Loading public key
[DEBUG ] salt.crypt.verify_signature: Verifying signature
[DEBUG ] Failed to verify signature of public key
[CRITICAL] The Salt Master server's public key did not authenticate!
在这种情况下,应该检查,minion上的验证pubkey(master_sign.pub)与master上的验证pubkey(master_sign.pub)是否相同。
确认可以验证成功后,再把minion改为使用守护进程模式启动。
对于信息安全有近乎偏执得严格要求的人,也可以配置为对从master收到的所有数据做签名校验。
always_verify_signature: True
通过设置以下两个参数的来完成在minion上配置多个master服务器:
- 指定一个masters服务器的列表
- 定义master的类型
master:
- 172.16.0.10
- 172.16.0.11
- 172.16.0.12
master_type: failover
这告诉minion上面的所有master都可以连接。 使用此配置启动minion服务时,它将按照定义的顺序尝试连接master服务器。
如果希望minion随机连接到上面列表中的某一个master,请设置:
master_shuffle: True
于是,在minion第一次连接尝试之前会先对master列表的内容打乱原有的顺序。
接受minion的第一个master会被minion所使用。
为了使minion能够检测它是否仍然连接到其当前的master设备,可以启用它的健康检查功能:
master_alive_interval: <seconds>
如果检测到连接已经丢失了,则minion将临时从列表中删除失败的master服务器并尝试连接到其他已经定义了的一个master服务器上(如果启用了shuffle参数,则还会再次对master列表内容进行洗牌)。
至少需要准备好两个masters来测试多masters的故障转移功能。
两个salt masters都需要运行起来,然后为了便于观察测试数据,我们使用debug模式运行salt minion:
salt-minion -l debug
启动minion后,会连接至master列表中的第一个master服务器上面:
[DEBUG ] Attempting to authenticate with the Salt Master at 172.16.0.10
[DEBUG ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG ] salt.crypt.verify_signature: Loading public key
[DEBUG ] salt.crypt.verify_signature: Verifying signature
[DEBUG ] Successfully verified signature of master public key with verification public key master_sign.pub
[INFO ] Received signed and verified master pubkey from master 172.16.0.10
[DEBUG ] Decrypting the current master AES key
我们可以登录到master列表中的第一个master服务器上,执行下test.ping命令,来验证测试下这个minion访问master服务的连通性。
如果上面的测试通过了,那我们可以把minion连接上的这个master服务先关闭掉,或者通过系统防火墙屏蔽下服务端口的访问。然后观测下salt多masters架构的故障转移功能。
根据在minion配置文件中设置的master_alive_interval参数所指定的健康检查时间间隔,minion会探测到自己已经不能再正常连接到当前的salt master服务,它会把这个信息也在日志中写入一份,像下面这样。
[INFO ] Connection to master 172.16.0.10 lost
[INFO ] Trying to tune in to next master from master-list
然后,minion将从列表中删除当前的master,并尝试连接到下一个master
[INFO ] Removing possibly failed master 172.16.0.10 from list of masters
[WARNING ] Master ip address changed from 172.16.0.10 to 172.16.0.11
[DEBUG ] Attempting to authenticate with the Salt Master at 172.16.0.11
如果一切配置正确,将成功验证新的master的密钥公钥:
[DEBUG ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[DEBUG ] salt.crypt.verify_signature: Loading public key
[DEBUG ] salt.crypt.verify_signature: Verifying signature
[DEBUG ] Successfully verified signature of master public key with verification public key master_sign.pub
使用新master服务器身份验证成功:
[INFO ] Received signed and verified master pubkey from master 172.16.0.11
[DEBUG ] Decrypting the current master AES key
[DEBUG ] Loaded minion key: /etc/salt/pki/minion/minion.pem
[INFO ] Authentication with master successful!
这时,在新的master服务器上执行针对这个minion的test.ping测试,可以成功返回结果。
通过上述设置,master设备会为每个minion的auth-request请求计算签名。 在有许多minions和频繁的auth请求时,这可以消耗掉master服务器上相当多的CPU资源。
为了避免这种情况,master设备可以使用其公钥预先创建好一个签名。 将签名保存为base64编码的字符串,由master服务在启动时读取一次,并仅将该字符串附加到auth-reply中。
可以使用下面的命令创建该签名:
salt-key --gen-signature
这将在master的 pki-directory目录中创建一个默认的签名文件。
/etc/salt/pki/master/master_pubkey_signature
它是一个简单的文本文件,内容是二进制签名转换为base64格式。
如果在此之前还没有生成过签名密钥对,则可以在同一次的调用中自动创建签名密钥对和签名文件:
salt-key --gen-signature --auto-create
设置下面的参数告诉master服务使用预先创建的签名文件:
master_use_pubkey_signature: True
注意这要求'master_pubkey_signature'文件已经放在master服务器的pki目录中,且具有正确的签名信息。
可以使用下面的参数自定义签名文件的文件名:
master_pubkey_signature: <filename>
对于同时部署和使用了很多master服务器的情况,会有多个公钥(默认和签名),建议使用salt-masters的主机名作为签名的文件名。 因为签名很容易混淆,单单从这个文件的内容上看不出任何有关创建签名的密钥的信息。
在使用这些功能时,请验证你配置的服务是否一切正常,且是按照与上面相同的方式完成的。
salt-master的默认密钥对是:
/etc/salt/pki/master/master.pem
/etc/salt/pki/master/master.pub
为了能够创建对消息的签名(在这种情况下主要是指的公钥),必须将另一个密钥对添加到salt master服务的设置中。 它的默认名称是:
master_sign.pem
master_sign.pub
master.*和master_sign.*密钥对的组合使用,提供了生成(公钥)签名的可能性。 如果签名密钥对所使用的公钥对接收者(minion)是可用的,则给定消息的签名就可以确定是唯一并且可以被验证的。
使用下面的方法计算master服务器公钥master.pub的签名:
master_sign.pem
master.pub
M2Crypto.EVP.sign_update()
这会导致把二进制签名转换为base64格式并附加到aution-reply中发送给minion。
minion因为是可以使用本地存放好的签名对公钥文件的,所以可以用下面的方法对签名的真实性做验证:
master_sign.pub
master.pub
M2Crypto.EVP.verify_update()
在运行了多个master服务器时,必须在所有master服务器上都存放好用于签名的密钥对,或者必须为每个master服务器单独预先计算master_pubkey_signature(因为它们都具有不同的公钥)。