Search

컨테이너 간 SSH 키 공유

일회성을 가지는 컨테이너인 만큼 직접적으로 ssh key를 컨테이너에 집어넣는것은 좋지 않을것이다. 컨테이너를 생성할 떄 마다 새로운 키를 할당해 known host를 할당하거나 비밀번호 없이 접속하도록 key 공유 자동화 시스템을 만드는것도 상당히 시간 낭비일 것 같다.
컨테이너를 실행시키는 호스트 컴퓨터에서 키를 생성하고 컨테이너에 마운트 시키는것이 간단한 해결방법일것이다.
지금부터의 과정은 systemctl이 불가능한 5개의 노드로 구성된 CentOS7 컨테이너 클러스터에서 진행한다.
먼저 테스트용 컨테이너를 띄운 뒤, 키를 초기화한다. dockerhub에서 가져온 날것의 CentOS7에 openssh-server, openssh-client, openssh-askpass를 설치해 수행하였다.
이 키들은 ssh 서비스를 초기 실행하기 위해 필요하다.
ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N "" && \ ssh-keygen -f /etc/ssh/ssh_host_ecdsa_key -t ecdsa -N "" && \ ssh-keygen -f /etc/ssh/ssh_host_ed25519_key -t ed25519 -N ""
Bash
복사
컨테이너 간 ssh 접속을 위한 RSA키를 생성한다.
ssh-keygen -q -t rsa -N "" -f ~/.ssh/id_rsa <<<y
Python
복사
생성된 공개키를 authorized_keys에 등록함으로써 ssh 접속 시 비밀번호를 묻지 않는다.
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Python
복사
/etc/ssh 디렉토리와 ~/.ssh 디렉토리에 생성된 파일들을 가져와 호스트 컴퓨터의 적당한 장소에 보관한다.
docker cp temporary_container:/etc/ssh /home/user/ssh-keys/etc-ssh docker cp temporary_container:~/.ssh /home/user/ssh-keys/root-ssh
Python
복사
docker-compose로 5개의 컨테이너를 띄운다. 임의로 주어지는 컨테이너의 IP 대신 고정값을 받기 위해 network를 추가해주었다.
privileged: ssh 자원에 접근할 수 있도록 Privileged 권한을 준다.
volumes: 앞서 저장한 호스트의 키를 컨테이너에 마운트 한다.
hostname, extra_hosts: 호스트 이름을 통해 접속에 용이하게 한다.
version: "3.7" services: master01: image: centos7/hadoop:nn privileged: True container_name: master01 hostname: master01 volumes: - type: bind source: /home/user/ssh-keys/root-ssh target: ~/.ssh - type: bind source: /home/user/ssh-keys/etc-ssh target: /etc/ssh networks: cluster-net: ipv4_address: 172.16.238.2 extra_hosts: - "master02:172.16.238.3" - "slave01:172.16.238.4" - "slave02:172.16.238.5" - "slave03:172.16.238.6" stdin_open: true tty: true master02: image: centos7/hadoop:nn privileged: True container_name: master02 hostname: master02 volumes: - type: bind source: /home/user/ssh-keys/root-ssh target: ~/.ssh - type: bind source: /home/user/ssh-keys/etc-ssh target: /etc/ssh networks: cluster-net: ipv4_address: 172.16.238.3 extra_hosts: - "master01:172.16.238.2" - "slave01:172.16.238.4" - "slave02:172.16.238.5" - "slave03:172.16.238.6" stdin_open: true tty: true slave01: image: centos7/hadoop:nn privileged: True container_name: slave01 hostname: slave01 volumes: - type: bind source: /home/user/ssh-keys/root-ssh target: ~/.ssh - type: bind source: /home/user/ssh-keys/etc-ssh target: /etc/ssh networks: cluster-net: ipv4_address: 172.16.238.4 extra_hosts: - "master01:172.16.238.2" - "master02:172.16.238.3" - "slave02:172.16.238.5" - "slave03:172.16.238.6" stdin_open: true tty: true slave02: image: centos7/hadoop:nn privileged: True container_name: slave02 hostname: slave02 volumes: - type: bind source: /home/user/ssh-keys/root-ssh target: ~/.ssh - type: bind source: /home/user/ssh-keys/etc-ssh target: /etc/ssh networks: cluster-net: ipv4_address: 172.16.238.5 extra_hosts: - "master01:172.16.238.2" - "master02:172.16.238.3" - "slave01:172.16.238.4" - "slave03:172.16.238.6" stdin_open: true tty: true slave03: image: centos7/hadoop:nn privileged: True container_name: slave03 hostname: slave03 volumes: - type: bind source: /home/user/ssh-keys/root-ssh target: ~/.ssh - type: bind source: /home/user/ssh-keys/etc-ssh target: /etc/ssh networks: cluster-net: ipv4_address: 172.16.238.6 extra_hosts: - "master01:172.16.238.2" - "master02:172.16.238.3" - "slave01:172.16.238.4" - "slave02:172.16.238.5" stdin_open: true tty: true networks: cluster-net: ipam: driver: default config: - subnet: "172.16.238.0/24"
YAML
복사
docker-compose up 수행 후, 올라간 모든 컨테이너에서 ssh 서비스를 실행한다. 필자는 매번 서비스를 시작하기 귀찮아서 entrypoint인 bash의 시작과 동시에 서비스가 실행되도록 ~/.bashrc에 서비스 시작을 작성하였다.
참고로 컨테이너의 lifetime은 컨테이너 접속 시 수행하는 커맨드의 lifetime과 같아서 종료되지 않는 커맨드가 제일 마지막으로 실행되어야 한다.
#Dockerfile ... RUN echo \ $' \n /usr/sbin/sshd' >> /root/.bashrc ... ENTRYPOINT ['/bin/bash']
Docker
복사
이제 master01 컨테이너에서 master02로 ssh 접속을 시도하면 yes/no를 묻는 질문과 함께 접속이 진행된다. 마운트 한 볼륨의 known_hosts는 모든 컨테이너가 공유하니 master01~slave03 컨테이너에 한번씩만 접속하여 업데이트 해주면 된다.