坑有点多,都是配置的坑,不是平台的坑,这是踩坑后的一次性成功的步骤
1、安装必要的构建工具和依赖项
yum update -y
yum install libffi-devel -y
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make
yum install libffi-devel -y 这一步必不可少,否则ansible --version 会报ERROR: No module named '_ctypes'
2、配置腾讯云内网源
python3 -m pip install --upgrade pip (这一句有点慢耐心等待)
pip3 config set global.index-url http://mirrors.tencentyun.com/pypi/simple
pip3 config set global.trusted-host mirrors.tencentyun.com
3、
pip3 install pywinrm
提示python3.6太低,至少需要python3.8
4、执行openssl version查看版本是2017年的1.0.2k,太老
执行find /usr -type d -name "openssl" 2>/dev/null 无异常发现
执行find /usr -type f -name "libssl.so*" 2>/dev/null 发现3个libssl.so,其中有个版本跟openssl version的版本能对应是1.0.2k,但有个版本明显较新,是1.1.1k
/usr/lib64/libssl.so.1.0.2k
/usr/lib64/libssl.so.1.1.1k
/usr/lib64/libssl.so.0.9.8e
于是,萌发升级openssl 1.0.2k到 1.1.1的思路
查资料发现1.1.1最新版是2023年的1.1.1w,但是源码编译安装的时候报错了:
checking OpenSSL header version... 1010117f (OpenSSL 1.1.1w 11 Sep 2023)
checking OpenSSL library version... 101010bf (OpenSSL 1.1.1k FIPS 25 Mar 2021)
configure: error: Your OpenSSL headers do not match your library
这里报错后,后面源码编译安装的python就没有意义,因为import ssl时报错ModuleNotFoundError: No module named '_ssl'
于是转变思路,不升级openssl 1.0.2k到 1.1.1w了,而是升级到 1.1.1k,这样就不会有上面[OpenSSL header version] do not match [OpenSSL library version]的问题了
5、参考https://zhuanlan.zhihu.com/p/688858890 编译安装openssl-1.1.1k 和openssh-9.7p1
wget http://windows-1251783334.cos.ap-shanghai.myqcloud.com/openssl-1.1.1k.tar.gz -O openssl-1.1.1k.tar.gz
wget http://mirrors.aliyun.com/pub/OpenBSD/OpenSSH/portable/openssh-9.7p1.tar.gz -O openssh-9.7p1.tar.gz
这个文档整体上复制粘贴即可,但有几处比较坑,就是下面圈出的连字符和英文双引号(当然你得注意下这个文档是按1.1.1w去升级的,我则是1.1.1k),其他的我都是复制粘贴的
另外就是编辑ssh配置文件/etc/ssh/sshd_config 那里,文档少一句话,否则root用户没法账号密码方式ssh远程
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
6、openssl version升级成功后显示的结果是OpenSSL 1.1.1k 25 Mar 2021,接着就可以编译安装python3.8.19了
wget http://windows-1251783334.cos.ap-shanghai.myqcloud.com/Python-3.8.19.tgz -O Python-3.8.19.tgz
tar zxvf Python-3.8.19.tgz
cd Python-3.8.19
我后来试了下,编译python3.12.4也可以
wget http://windows-1251783334.cos.ap-shanghai.myqcloud.com/Python-3.12.4.tgz -O Python-3.12.4.tgz
tar zxvf Python-3.12.4.tgz
cd Python-3.12.4
(yum install libffi-devel -y ,这一步必不可少,否则ansible --version 会报ERROR: No module named '_ctypes',如果在编译python3.8之前漏了这步,得重新编译python3.8,重新编译之前需要在 Python-3.8.19 解压后的源码目录执行make distclean)
./configure --with-openssl=/opt/openssl -with-openssl-rpath=auto
make -j && make altinstall
这里需要特别注意,如果是2c2g的或更低配的机器编译python,有可能内存会不够用而出现out of memory报错
这里需要特别注意,如果是2c2g的或更低配的机器编译python,有可能内存会不够用而出现out of memory报错
这里需要特别注意,如果是2c2g的或更低配的机器编译python,有可能内存会不够用而出现out of memory报错
连续试了2次编译python3.12都出现out of memory,知道是2G内存不够用了,于是果断增加swap,一开始增加了512MB swap,还是out of memory,后来干脆增加到2GB swap,这回没有再出现out of memory。因此,如果搞swap,建议至少来2GB。具体参考我这篇文档
fallocate -l 2048M /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile none swap sw 0 0" >> /etc/fstab
mount -a
free -m
安装成功后配置软链接并更新pip
rm -rf /usr/bin/python3
rm -rf /usr/bin/pip3
ln -s /usr/local/bin/python3.8 /usr/bin/python3
ln -s /usr/local/bin/pip3.8 /usr/bin/pip3
python3 -m pip install --upgrade pip
如果是python3.12,则是
rm -rf /usr/bin/python3
rm -rf /usr/bin/pip3
ln -s /usr/local/bin/python3.12 /usr/bin/python3
ln -s /usr/local/bin/pip3.12 /usr/bin/pip3
python3 -m pip install --upgrade pip
7、用pip3安装pywinrm、ansible
如果用pip3 uninstall ansible卸载ansible,卸载时敲完Y回车后,耐心等,有些慢,需要等几分钟
pip3 install --root-user-action=ignore --ignore-installed pywinrm[credssp]
pip3 install --root-user-action=ignore --ignore-installed ansible
上面2句可以合并成一句:
pip3 install --root-user-action=ignore --ignore-installed pywinrm[credssp] ansible
8、查看pywinrm和ansible版本
pip3 list |grep ansible
pip3 list |grep pywinrm
pip3 list |grep credssp
python3.8.19时,pywinrm和ansible版本:
ansible 6.7.0
ansible-core 2.13.13
pywinrm 0.4.3
requests-credssp 2.0.0
python3.12.4时,pywinrm和ansible版本:
ansible 10.1.0
ansible-core 2.17.1
pywinrm 0.4.3
requests-credssp 2.0.0
9、上述操作过程中,会看到环境变量告警
WARNING: The script normalizer is installed in '/usr/local/bin' which is not on PATH
执行ansible --version不认ansible,就是因为环境变量中没有/usr/local/bin,毕竟该目录下可执行文件不少,单独搞软链接还是太麻烦了
比如ln -s /usr/local/bin/ansible /usr/bin/ansible
所以,需要把/usr/local/bin加入环境变量
10、创建正确的/etc/ansible/hosts是重中之重
低版本的ansible是一套名称,高版本的是另一套名称
比如低版本示例:注意里面有ssh
[windows]
119.45.62.115
[windows:vars]
ansible_ssh_user="Administrator"
ansible_ssh_pass="密码"
ansible_connection="winrm"
ansible_ssh_port=5985
高版本示例,各个项是什么名称、填什么值,参考ansible官方文档https://docs.ansible.com/ansible/latest/os_guide/windows_winrm.html
例如:注意里面没有ssh
[windows]
119.45.62.115
[windows:vars]
ansible_user="Administrator"
ansible_password="密码"
ansible_connection="winrm"
ansible_port=5985
ansible_ssh_user 应该变成ansible_user,否则报错"msg": "basic: auth method basic requires a username"
ansible_ssh_pass应该变成ansible_password,否则可能会报错"msg": "basic: auth method basic requires a password"
ansible_ssh_port应该变成ansible_port,否则会报错"msg": "basic: HTTPSConnectionPool(host='IP', port=5986): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f96c15c9970>: Failed to establish a new connection: [Errno 111] Connection refused'))",明明指定的5985,报错信息里却是5986,很显然,指定的项名称不对
上述3种情况对应3个项名称,区别就是项名称
ansible 119.45.62.115 -m win_ping -e 'ansible_python_interpreter=/usr/bin/python3'
详细的报错信息如下
119.45.62.115 | UNREACHABLE! => {
"changed": false,
"msg": "basic: auth method basic requires a username",
"unreachable": true
}
119.45.62.115 | UNREACHABLE! => {
"changed": false,
"msg": "basic: auth method basic requires a password",
"unreachable": true
}
119.45.62.115 | UNREACHABLE! => {
"changed": false,
"msg": "basic: HTTPSConnectionPool(host='119.45.62.115', port=5986): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f96c15c9970>: Failed to establish a new connection: [Errno 111] Connection refused'))",
"unreachable": true
}
grep -v -E '(^#|^$)' /etc/ansible/hosts
/etc/ansible/hosts内容如下即可(不指定5985端口的话,不能注释最后2句)
[windows]
119.45.62.115
[windows:vars]
ansible_user="Administrator"
ansible_password="密码"
ansible_connection="winrm"
#ansible_port=5985
ansible_winrm_transport=basic
ansible_winrm_server_cert_validation=ignore
如果注释最后2句的话,则必须指定5985端口
[windows]
119.45.62.115
[windows:vars]
ansible_user="Administrator"
ansible_password="密码"
ansible_connection="winrm"
ansible_port=5985
#ansible_winrm_transport=basic
#ansible_winrm_server_cert_validation=ignore
除过用ansible $Windows机器IP -m win_ping验证外,还可以用openssl s_client -connect host:port测试
比如
openssl s_client -connect 119.45.62.115:5985
openssl s_client -connect 119.45.62.115:5986
windows端的winrm配置参考https://developer.hashicorp.com/packer/docs/communicators/winrm#examples
net user Administrator "密码"
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore
# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"
# Remove HTTP listener
#Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse
# Create a self-signed certificate to let ssl work
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force
# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"
# Configure WinRM to allow unencrypted communication, and provide the
# self-signed cert to the WinRM listener.
cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"
# Make sure appropriate firewall port openings exist
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"
cmd.exe /c netsh firewall add portopening TCP 5985 "Port 5985"
# Restart WinRM, and set it so that it auto-launches on startup.
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm
#执行完这段Powershell后要重启机器
#执行完这段Powershell后要重启机器
#执行完这段Powershell后要重启机器
执行完这段Powershell后要重启机器
执行完这段Powershell后要重启机器
执行完这段Powershell后要重启机器
以上都配好后,就可以在Linux端调整/etc/ansible/hosts后用ansible $Windows机器IP -m win_ping来验证了,如果要指定python路径,例如ansible $Windows机器IP -m win_ping -e 'ansible_python_interpreter=/usr/bin/python3'
三、https://github.com/tencentyun/ansible-tencentcloud/tree/master/inventory
python3 tencent_cloud.py --list 能拉到帐号下所有cvm实例信息,如上图,我帐号有2台机器:
linux 机器:ins-1fkmda7h(129.211.6.204)
windows 机器:ins_oloasdye(119.45.62.115)
ansible -i tencent_cloud.py all 指定所有机器(all)
ansible -i tencent_cloud.py 119.45.62.115 是按外网IP指定了机器
ansible -i tencent_cloud.py ins_oloasdye 是按cvm instanceid指定了机器
即便-m win_ping -k -u Administrator(而不是-m ping -k -u root),无济于事
-i指定了.py脚本主机信息,就无法指定/etc/ansible/hosts
ansible -i /etc/ansible/hosts windows -m win_ping 这种是可以的
ansible -i tencent_cloud.py ins_oloasdye -m win_ping -k -u Administrator 这种不行,因为在-i xxx.py ...参数的作用下,不走/etc/ansible/hosts中的配置而是走22端口ssh协议,因此访问不了windows机器
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。