Cloud IAP는 VPN 없이 공개 IP 주소 없이 컴퓨팅 인스턴스에 연결할 수 있게 해주는 Google Cloud Platform용 프록시입니다. 인스턴스를 설정한 후 gcloud
다음과 같이 이 유틸리티를 사용하여 이름으로 인스턴스에 연결할 수 있습니다 gcloud compute ssh my-server-01
. 이는 프록시를 통해 귀하를 인증하고 귀하의 Google 계정을 사용하여 대상 서버에 로그인합니다(운영 체제 로그인이라는 기능 사용).
gcloud
도구가 수행하는 작업을 수행하려면 사용자 정의 연결 플러그인이 필요하다고 생각합니다 .
답변1
토론 후https://www.reddit.com/r/ansible/comments/e9ve5q/ansible_slow_as_a_hell_with_gcp_iap_any_way_to/소켓을 통한 SSH 연결 공유를 사용하도록 솔루션을 변경했습니다.
@mat 솔루션보다 두 배 빠릅니다. 우리 제품에 넣었어요.이는 호스트 이름 패턴에 의존하지 않는 구현입니다!
올바른 해결책은 Bastion/Jump 호스트를 사용하는 것입니다. gcloud
명령이 여전히 생성된 Python 인터프리터를 생성하기 때문입니다 ssh
. 여전히 비효율적입니다!
ansible.cfg
:
[ssh_connection]
pipelining = True
ssh_executable = misc/gssh.sh
ssh_args =
transfer_method = piped
[privilege_escalation]
become = True
become_method = sudo
[defaults]
interpreter_python = /usr/bin/python
gathering = False
# Somehow important to enable parallel execution...
strategy = free
gssh.sh
:
#!/bin/bash
# ansible/ansible/lib/ansible/plugins/connection/ssh.py
# exec_command(self, cmd, in_data=None, sudoable=True) calls _build_command(self, binary, *other_args) as:
# args = (ssh_executable, self.host, cmd)
# cmd = self._build_command(*args)
# So "host" is next to the last, cmd is the last argument of ssh command.
host="${@: -2: 1}"
cmd="${@: -1: 1}"
# ControlMaster=auto & ControlPath=... speedup Ansible execution 2 times.
socket="/tmp/ansible-ssh-${host}-22-iap"
gcloud_args="
--tunnel-through-iap
--zone=europe-west1-b
--quiet
--no-user-output-enabled
--
-C
-o ControlMaster=auto
-o ControlPersist=20
-o PreferredAuthentications=publickey
-o KbdInteractiveAuthentication=no
-o PasswordAuthentication=no
-o ConnectTimeout=20"
exec gcloud compute ssh "$host" $gcloud_args -o ControlPath="$socket" "$cmd"
고쳐 쓰다gcloud
Google 엔지니어가 호출해서는 안되는 응답을 했습니다.평행하게! 바라보다'gcloudcomputessh'는 병렬로 사용할 수 없습니다.
실험에 따르면 Ansible을 사용하면 fork=5
거의 항상 오류가 발생합니다. 나는 fork=2
그런 것을 경험한 적이 없습니다.
업데이트 2시간이 지남에 따라 2020년 말까지 잠금 오류 없이 병렬로 실행할 수 있었습니다 gcloud compute ssh
(WSL에서는 수행했습니다 ).fork = 10
답변2
플러그인을 연결하지 않고도 이 작업을 수행할 수 있는 방법을 찾았습니다. 기본적으로 도구를 래핑 gcloud
하고 ansible_ssh_executable
매니페스트 수준에서 정의하는 해당 스크립트에 대한 매개변수를 가리키는 스크립트를 작성합니다. gcp_compute
예상대로 인벤토리 플러그인이 호스트를 이름으로 인식하는지 확인해야 합니다 gcloud compute ssh
.
스크립트는 다음과 같습니다.
#!/bin/sh
set -o errexit
# Wraps the gcloud utility to enable connecting to instances which are behind
# GCP Cloud IAP. Used by setting the `ansible_ssh_executable` setting for a play
# or inventory. Parses out the relevant information from Ansible's call to the
# script and injects into the right places of the gcloud utility.
arg_string="$@"
grep_hostname_regex='[a-z]*[0-9]\{2\}\(live\|test\)'
sed_hostname_regex='[a-z]*[0-9]{2}(live|test)'
target_host=$(
echo "$arg_string\c" | grep -o "$grep_hostname_regex"
)
ssh_args=$(
echo "$arg_string\c" | sed -E "s# ${sed_hostname_regex}.*##"
)
cmd=$(
echo "$arg_string\c" | sed -E "s#.*${sed_hostname_regex} ##"
)
gcloud compute ssh "$target_host" \
--command="$cmd" \
--tunnel-through-iap \
-- $ssh_args
노트:
- 이는 macOS에서 테스트되었습니다.
sed
예를 들어 Linux에서는 옵션이 다를 수 있습니다. - "호스트" 정규식은 명명 규칙과 일치해야 합니다. 나처럼 일관된 명명 규칙이 없다면 정보를 구문 분석하는 다른 방법을 찾아야 합니다.
답변3
@gavenkoa 및 @matt를 게시해 주셔서 감사합니다. 한 가지 제안은 영역을 하드코딩할 필요가 없도록 다음을 추가하는 것입니다.
단편:
ZONE=$(gcloud compute instances list --filter="name:${host}" --format='value(zone)')
gcloud_args="
--tunnel-through-iap \
--zone=${ZONE}