备注
本文所有涉及安装都是用Ubuntu20.04演示,如果需要切换到Redhat/CentOS请自行将所有安装命令更换为yum/dnf install
ansible进行免密操作
安装ansible并初始化
安装
root@harbor:~# apt update && apt -y install ansible root@harbor:~# ansible --version ansible 2.9.6 config file = /etc/ansible/ansible.cfg configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3/dist-packages/ansible executable location = /usr/bin/ansible python version = 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0]
修改配置文件
修改资产清单,默认资产清单在/etc/ansible/hosts
root@harbor:~# cat /etc/ansible/hosts [k8s_node] #主机组名 master1 #这里如果写主机名需要在/etc/hosts里面做解析 master2 master3 node1 node2 node3 [k8s_node:vars] #这里定义变量的时候需要和组名保持一致 ansible_ssh_user=root ansible_ssh_pass="***" #你的密码,如果不统一的话可以单独在资产名后面定义
接下来检查一下
root@harbor:~# ansible k8s_node -m ping -o master1 | FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"} master2 | FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"} node1 | FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"} master3 | FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"} node2 | FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"} node3 | FAILED! => {"msg": "to use the 'ssh' connection type with passwords, you must install the sshpass program"}
出现报错了,不过给了提示信息,我们安装上sshpass再试试
root@harbor:~# apt -y install sshpass root@harbor:~# ansible k8s_node -m ping -o master1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"} node1 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"} master2 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"} node2 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"} master3 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"} node3 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"},"changed": false,"ping": "pong"}
正常第一次使用模块可能会有如下提示
root@harbor:~# ansible lb -m ping -o The authenticity of host 'lb.org ' can't be established. ECDSA key fingerprint is SHA256:Vg7I4oCxTSrst9ztoQworwFW4/lj/gF+wMqnGKmw5bM. Are you sure you want to continue connecting (yes/no/[fingerprint])?
需要跳过的话可以编辑/etc/ansible/ansible.cfg
host_key_checking = False #找到这行,去掉原本的注释
ansible批量免密资产
这里我是用ansible自己来免密别人
生成密钥
root@harbor:~# ssh-keygen -t rsa -b 2048 -P '' -q -f .ssh/id_rsa root@harbor:~# ls .ssh/ id_rsa id_rsa.pub
生产密钥之后只需要想办法将公钥送到被免密主机的.ssh/authorized_keys中
初次免密
正常如果没有被免密的主机其实很简单,只需要执行下面的playbook即可
--- - hosts: lb name: first Trust tasks: - name: mkdir .ssh file: path: /root/.ssh state: directory - name: copy key copy: src: /root/.ssh/id_rsa.pub dest: /root/.ssh/authorized_keys
执行一下
root@harbor:~# ansible-playbook first.yml PLAY [first Trust] ****************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************** ok: [lb.org] TASK [mkdir .ssh] ******************************************************************************************************************************* changed: [lb.org] TASK [copy key] ********************************************************************************************************************************* changed: [lb.org] PLAY RECAP ************************************************************************************************************************************** lb.org : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 root@harbor:~# ssh lb.org *** System restart required *** Last login: Tue Nov 1 15:07:22 2022 from 10.10.21.174 root@lb:~#
免密成功
第N次免密(N > 1)
这里指的是如果对方已经被别人做过免密的情况,那我们就不能直接用copy模块了,而是需要想办法将自己的公钥拼接到原来已有的authorized_keys中,剧本如下:
--- - hosts: k8s_node name: last Trust gather_facts: no tasks: - name: copy key copy: src: /root/.ssh/id_rsa.pub dest: /tmp/authorized_keys.tmp - name: trust shell: cat /tmp/authorized_keys.tmp >> /root/.ssh/authorized_keys - name: delete /tmp/authorized_keys.tmp file: path: /tmp/authorized_keys.tmp state: absent
执行并验证
root@harbor:~# ansible-playbook last.yml PLAY [last Trust] ******************************************************************************************************************************* TASK [copy key] ********************************************************************************************************************************* changed: [node1] changed: [master3] changed: [master1] changed: [master2] changed: [node2] changed: [node3] TASK [trust] ************************************************************************************************************************************ changed: [node2] changed: [node1] changed: [master1] changed: [master2] changed: [master3] changed: [node3] TASK [delete /tmp/authorized_keys.tmp] ********************************************************************************************************** changed: [node1] changed: [node2] changed: [master1] changed: [master2] changed: [master3] changed: [node3] PLAY RECAP ************************************************************************************************************************************** master1 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 master2 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 master3 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node1 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node2 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 node3 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 root@harbor:~# ssh master1 *** System restart required *** Last login: Tue Nov 1 15:21:31 2022 from 10.10.21.174
ansible批量协助其他机器进行免密
这里我的lb来免密其他的机器
--- - hosts: all name: last Trust tasks: - name: touch id_rsa shell: ssh-keygen -t rsa -b 2048 -P '' -q -f .ssh/id_rsa when: inventory_hostname in groups.lb #如果lb已经生成过密钥,记得注释上面的task - name: copy key fetch: src: /root/.ssh/id_rsa.pub dest: /tmp/ when: inventory_hostname in groups.lb - name: copy key to other hosts copy: src: /tmp/lb.org/root/.ssh/id_rsa.pub #这个路径是/tmp拼接lb的公钥路径 dest: /tmp/authorized_keys.tmp when: inventory_hostname in groups.k8s_node - name: trust shell: cat /tmp/authorized_keys.tmp >> /root/.ssh/authorized_keys when: inventory_hostname in groups.k8s_node - name: delete /tmp/authorized_keys.tmp file: path: /tmp/authorized_keys.tmp state: absent when: inventory_hostname in groups.k8s_node
ansible-playbook执行一下即可完成免密
shell脚本进行免密操作
利用expect和spawn进行免密
下面这个脚本可以直接对/etc/hosts中记录了的host进行免密
root@harbor:~# apt -y install expect root@harbor:~# cat ssh-ssh.sh #!/bin/bash ssh-keygen -t rsa -b 2048 -P "" -f /root/.ssh/id_rsa -q for host in `awk '{print $1}' /etc/hosts`;do expect -c " spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@${host} expect { *yes/no* {send -- "yes\r"; exp_continue} *assword* {send xxxx\r; exp_continue} #xxxx对应自己的密码 }" done #xxxx对应自己的密码 root@harbor:~# sh ssh-ssh.sh
利用sshpass进行免密
root@harbor:~# apt -y install sshpass root@harbor:~# cat ssh-ssh.sh #!/bin/bash ssh-keygen -t rsa -b 2048 -P "" -f /root/.ssh/id_rsa -q # export SSHPASS=xxxx #xxxx对应自己的密码,必须要提前声明,否则会报错 for host in `awk '{print $1}' /etc/hosts`;do # sshpass -e ssh-copy-id -o StrictHostKeyChecking=no $host sshpass -p 123456 ssh-copy-id -o StrictHostKeyChecking=no $host done root@harbor:~# sh ssh-ssh.sh