与在本地主机上通过SSH端口转发的服务器同步失败[解决]
总结
想做的事情
-
- ローカルの ~/ansible/work/ にチェックアウトした myapp のソースコードを、サーバの /var/ma2saka/myapp に転送したい
-
- サーバは vagrant でローカルに立ててる Cent OS 6.5
- もともとスクリプトは AWS サーバ用に書いていて動作しているもの
先解决方案
即使端口号不同,但如果主机名部分相同,会导致错误操作。
在库存文件中,可以使用类似于“host1 ansible_ssh_host=127.0.0.1”的方式来指定主机,而无需直接写IP地址,这样可以确保主机名称部分不会重复。
以前失败的模式
写下的定义
- name: sync source code
synchronize:>
dest=/var/ma2saka/myapp
src=/Users/ma2saka/ansible/work/myapp/
recursive=yes
links=yes
rsync_opts="--exclude='.git'"
以下是中国的本地化释义,只提供一种选项:
【仅供参考】
在库存中
[dev]
127.0.0.1
[dev:vars]
ansible_ssh_user=vagrant
ansible_ssh_port=2222
在本地,通过Vagrant搭建的服务器正在使用端口号2222进行监听。
事先注册了公钥。
ssh-add -D
ssh-add ~/.ssh/id_rsa
ssh-copy-id -p 2222 vagrant@127.0.0.1
发生错误
TASK: [deploy | sync source code] *********************************************
failed: [127.0.0.1 -> 127.0.0.1] => {"cmd": "rsync --delay-updates -FF --compress --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no -o Port=2222' --exclude='.git' --out-format='<<CHANGED>>%i %n%L' \"/Users/ma2saka/ansible/work/myapp/\" \"/var/ma2saka/myapp\"", "failed": true, "rc": 23}
msg: rsync: change_dir "/Users/ma2saka/ansible/work/myapp/" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1039) [sender=3.0.6]
FATAL: all hosts have already failed -- aborting
哎呀,就算收到消息说:”rsync:切换目录“/Users/ma2saka/ansible/work/myapp/”失败:没有这个文件或目录(2)。” 也不管它。那个目录是存在的呢。无论怎么看都是。
由于使用的是 brew 安装的 1.8.2 版本,因此怀疑是这个原因,尝试使用 pip 重新安装却不起作用。
1.9.1 没有特别的变化。
在亚马逊或其他服务器上工作得很好。
[dev]
myapp1.amazon.example.com
myapp2.amazon.example.com
myapp3.amazon.example.com
[dev:vars]
ansible_ssh_user=ec2-user
ansible_ssh_port=22
一切问题,按照预期正常运行。
将 127.0.0.1 别名设置在 /etc/hosts 文件中后,成功运行了。
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
127.0.0.1 this.is.it
[dev]
this.is.it
[dev:vars]
ansible_ssh_user=vagrant
ansible_ssh_port=2222
当使用此进行执行。
.. 略 ..
TASK: [deploy | sync source code] *********************************************
changed: [this.is.it -> 127.0.0.1]
.. 略 ..
这东西虽然按照期待的那样动了,所以还是可以接受,但心里总觉得有点不爽。
如果将主机名设为localhost,根本就无法连接。
如果你不允许指定IP,那么考虑使用localhost会怎么样呢?
TASK: [deploy | sync source code] *********************************************
failed: [localhost -> 127.0.0.1] => {"cmd": "rsync --delay-updates -FF --compress --archive --rsh 'ssh -S none -o StrictHostKeyChecking=no -o Port=2222' --exclude='.git' --out-format='<<CHANGED>>%i %n%L' \"/Users/ma2saka/ansible/work/myapp/\" \"/var/ma2saka/myapp\"", "failed": true, "rc": 12}
msg: ssh: connect to host localhost port 2222: Connection refused
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]
唔……
换言之,我迟迟才意识到,真正的问题在于主持人的“名字”吗?
在ansible_ssh_host配置中解决
我遇到的正是这个现象。
- Ansible multiple hosts with port forwarding – Stack Over Flow
如果您想要通过ansible连接到正在进行端口转发的本地主机,那么在清单文件中提供一个合适的别名是一个好的方法。
[dev]
# lvh.me とか this.is.it とか書かなくていい
host1 ansible_ssh_host=127.0.0.1
[dev:vars]
ansible_ssh_user=vagrant
ansible_ssh_port=2222
大致上,由于我检查了同步模块的代码以及在运行时传输的脚本,所以我理解了它的行为,但是这是个陷阱。总的来说,错误信息太不友好了。我抱怨了一下,但问题解决了,心情不错。
自我审视
-当仔细观察下,你会发现能知道”这个脚本在哪里执行”。当我写入了127.0.0.1而失败时,实际上脚本是在远程服务器上执行的。然而,由于指定了源码的本地路径,所以无法找到目录。
如果我们注意到这一点,应该立即意识到不是特定模块的 bug,而是 ansible 的主机名解析逻辑,但我却追踪错误的地方错误地花了时间。这确实很困难。