보안 채널을 통해 API 요청 * 전송 계층 보안(Transport Layer Securty. TLS) * HTTPS 프로토콜의 디지털 인증서와 같은 방식의 암호화를 사용한다. * 도커 API는 상호 TLS를 사용하므로 서버와 클라이언트가 각각 인증서를 갖는다. * 서버의 인증서는 자신을 증명하고 전송되는 내용을 암호화하는 데 사용되며, 클라이언트의 인증서는 자신을 증명하는 데 사용된다. * 보안 셸(Secure Shell, SSH) * 이 프로토콜은 리눅스 서버에 원격 접속하는 표준 프로토콜이지만, 윈도에서도 사용 가능하다. * SSH로 원격 서버에 접근하려면 사용자명과 패스워드 혹은 비밀키가 필요하다.
TLS vs. SSH * 어떤 보안 채널을 사용하느냐에 따라 클러스터에 접근할 권한을 부여하는 방법이 달라진다. * 상호 TLS는 더 널리 사용되는 방법이지만 인증서를 생성하고 교체하는 관리 업무에서 오버헤드가 발생한다. * 이에 비해 SSH는 사용하는 컴퓨터에 대부분 설치돼 있는 SSH 클라이언트만 있으면 되며 접근 권한 관리가 상대적으로 쉽다.
상호 TLS를 이용한 보안 원격 접근 * 우선 상호 TLS를 이용해 도커 엔진의 보안 원격 접근을 설정해 보자. * 상호 TLS를 사용하려면 먼저 인증서와 키 파일(인증서의 패스워드 역할) 쌍을 두 개 만들어야 한다. * 하나는 도커 API가 사용하고, 다른 하나는 클라리언트에서 사용한다. * Play with Docker 웹 사이트에서 사용할 수 있는 인증서를 미리 준비해 두었으니 실습에서는 이 인증서를 사용하면 된다.
실습 Play with Docker 웹 사이트에 로그인한 후 노드 하나를 생성하라. 그리고 같은 세션에서 인증서를 배포할 컨테이너를 실행한다. 그다음에는 도커 엔진이 이 인증서를 사용하도록 설정한 후 도커를 재시작하라.
001) # 인증서를 둘 디렉터리를 생성한다.
002) $ mkdir -p /diamol-certs
003)
004) # 인증서 및 설정값을 적용할 컨테이너를 실행한다.
005) $ docker container run -v /diamol-certs:/certs -v /etc/docker:/docker diamol/pwd-tls:server
006)
007) # 새로운 설정을 적용해 도커를 재시작한다.
008) $ pkill dockerd
009) $ dockerd &>/docker.log &
010) [1] 340
- 005: 이 컨테이너는 호스트에서 생성한 볼륨 마운트를 사용해 Play with Docker에서 사용 가능한 TLS 인증서를 노드로 복사하고 도커 설정 파일을 수정한다.
-
008~010: 도커 엔진을 재시작해 수정된 설정을 반영한다. 이런 식으로 도커를 재시작하는 것은 주로 Play with Docker에서 쓰인다. 보통은 도커 서비스를 재시작하는 형태다.
-
조금 전 실행한 컨테이너에는 Play with Docker 노드에서 만든 두 개의 볼륨이 마운트된다.
- 그리고 이 컨테이너가 갖고 있던 인증서와 daemon.json 파일을 노드로 복사한다.
- 도커 엔진 설정을 반영하려면 dockerd 명령으로 도커 엔진을 재시작해야 한다.
- 지금부터 도커 엔진은 TLS를 사용해 2376번 포트를 주시한다(보안 TCP 접근을 위해 관습적으로 사용되는 포트다)
포트 오픈 * 한 단계만 더 거치면 로컬 컴퓨터에서 Play with Docker 노드의 도커 엔진을 원격에서 사용할 수 있다. * Open Port 버튼을 클릭해 2376번 포트를 지정한다 * 그러면 오류 메시지가 찍힌 탭이 열리면 오류 메시지는 무시하고 URL을 클립보드로 복사한다. * 이 URL이 현재 Play with Docker 세션의 유일한 도메인이다. * 이 도메인을 사용해 로컬 컴퓨터에서 Play with Docker 웹 사이트에서 실행 중인 도커 엔진에 접속할 수 있다. * 이제 현재 사용 중인 Play with Docker 세션에 원격으로 접속할 준비가 끝났다.
인증 기관, 서버 인증서와 클라이언트 인증서 * TLS 인증서와 OpenSSH에 대한 더 자세한 설명은 생략하자먼 인증 기관, 서버 인증서와 클라이언트 인증서의 관계에 대해서는 잘 알아 두어야 한다. * TLS를 통해 도커 엔진에 접근하려면 인증 기관과 한 쌍의 인증서(클라이언트 인증서, 서버 인증서)가 필요하다. * 인증서에는 수명이 있어서 원격 도커 엔진에 대한 접근 권한을 임시로 부여하고 싶다면 단기 클라이언트 인증서를 사용하면 된다. * 이와 관련된 모든 절차를 자동화할 수는 있지만 인증서 관리에 대한 오버헤드가 여전히 존재한다. * TLS를 사용해 원격 접근이 가능하게끔 도커 엔진을 설정하려면 먼저 인증 기관 인증서, 서버 인증서 및 키의 쌍이 위치한 경로를 지정해야 한다. * 예제 15-2는 Play with Docker 세션의 도커 엔진에 적용된 TLS 원격 접근 허용 설정이다.
예제 15-2 TLS를 이용한 원격 접근 설정
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
"tls": true,
"tlscacert": "/diamol-certs/ca.pem",
"tlskey": "diamol-certs/server-key.pem",
"tlscert": "diamol-certs/server-cert.pem"
}
- 이제 도커 엔진 원격 접근에 보안이 적용됐다.
- 지금부터는 인증 기관 인증서, 클라이언트 인증서및 키 없이는 Cur로 REST API를 호출하거나 도커 명령행 도구로 이 원격 도 커 엔진에 명령을 내릴 수 없다.
- 이전에 만들어진 클라이언트 인증서도 마찬가지로 접근을 허용하지 않는다.
- 도커 엔진에 접근하려면 서버 인증서와 같은 인증 기관에서 발급 된 클라이언트 인증서가 필요하다.
- 클라이언트 TLS 없이 API 사용을 시도하면 도커 엔진이 접근을 차단한다.
- Play with Docker에서 실행한 이미지의 다른 버전을 사용하면 로컬 컴퓨터로 클라이언트 인증서를 내려받을 수 있다.
- 그다음에는 이 인증서를 사용해 원격 도커 엔진에 접근하면 된다.
실습 Play with Docker에서 실행 중인 도커 엔진에 접근할 때는 항상 2376번 포트를 사용해야 한다. 앞서 2376번 포트를 개방할 때 복사한 현재 세션의 도메인을 사용 한다. 이제 원격 도커 엔진에 접근해 보자.
001) # address 항목에서 현재 세션의 도메인을 복사한다
002) # 대략 ip172-18-0-11-cj2vgeggftqg00c9qjo0-2376.direct.labs.play-with-docker.com 과 비슷한 값이다.
003) # 도메인을 환경 변수로 설정한다(윈도)
004) ➜ $pwdDomain="<나의_현재세션_pwd_도메인>"
005)
006) # 도메인을 환경 변수로 설정한다(리눅스)
007) ➜ pwdDomain="<나의_현재세션 pwd 도메인>"
008)
009) # 도커 API에 직접 접근을 시도한다
010) ➜ curl "http://$pwdDomain/containers/ison"
011) Client sent an HTTP request to an HTTPS server.
012)
013) # 명령행 도구로도 직접 접근을 시도한다
014) ➜ docker --host "tcp://$pwdDomain" container ls
015) Error response from daemon: Client sent an HTTP request to an HTTPS server.
016)
017) # 클라이언트 인증서를 로컬 컴퓨터로 추출한다
018) ➜ mkdir -p /tmp/pwd-certs
019) ➜ cd ./ch15/exercises
020) ➜ tar -xvf pwd-client-certs -C /tmp/pwd-certs
021) x ca.pem
022) x client-cert.pem
023) x client-key.pem
024)
025) # 클라이언트를 사용해 도커 엔진에 접근을 시도한다
026) ➜ docker --host "tcp://$pwdDomain" --tlsverify --tlscacert /tmp/pwd-certs/ca.pem --tlscert /tmp/pwd-certs/client-cert.pem --tlskey /tmp/pwd-certs/client-key.pem container ls
027) CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
028)
029) # 도커 명령행 도구로 명령을 내릴 수 있다.
030) ➜ docker --host "tcp://$pwdDomain" --tlsverify --tlscacert /tmp/pwd-certs/ca.pem --tlscert /tmp/pwd-certs/client-cert.pem --tlskey /tmp/pwd-certs/client-key.pem container run -d -P diamol/apache
031) Unable to find image 'diamol/apache:latest' locally
032) latest: Pulling from diamol/apache
033) f84cab65f19f: Pull complete
034) 87259b7246e5: Pull complete
035) 3e84dc11ea39: Pull complete
036) d632c8441234: Pull complete
037) 0fcb24848396: Pull complete
038) Digest: sha256:f3fafa07dd17a03d5e5c7ad959419faf459b087fbd25a53c7db08b87d586520b
039) Status: Downloaded newer image for diamol/apache:latest
040) b62004889054867156ead579335e9eabca63f3bf3afbc3055e2f2160b06a4020
- 004: 2376번포트의 정보가 포함된 도메인을 환경 변수로 저장한다. Play with Docker에서는 포트마다 도메인이 다르게 부여된다.
- 010: 도커 엔진에 TLS 보안이 적용됐다 적합한 클라이언트 인증서를 제시하지 않으면 접근이 거절된다.
-
026: 일치하는 클라이언트 인증서를 갖고 있다면 Play with Docker 속 노드에서 동작하는 도커 엔진에 로컬 컴퓨터에서 마음대로 명령을 내릴 수 있다.
-
매번 TLS 관련 인자를 입력해야 하는 것이 조금 번거롭지만, 인잣값을 환경 변수로 정의해 두면 불편함이 조금 줄어든다.
- 클라이언트 인증서를 제대로 지정하지 않으면 오류를 일으키지만, 인증서를 정확히 지정하면 Play with Docker 웹 사이트에서 동작 중인 도커 엔진을 로컬 컴퓨터에서 마음대로 조작할 수 있다.
SSH를 이용한 보안 원격 접근 * 도커 엔진에 원격 접근할 수 있는 다른 보안 채널로 SSH가 있다. * SSH의 장점은 도커 명령행 도구가 표준 SSH 클라이언트를 사용하기 때문에 도커 엔진 쪽에서 설정을 변경할 필요가 없다는 점이다. * 사용자 인증은 서버가 대신 처리해 주기 때문에 따로 인증서를 생성할 필요도 없다. * 도커 엔진을 실행 중인 컴퓨터에서 원격 접속에 사용할 계정을 추가 하기만 하면 된다. * 이 계정을 사용해 도커 엔진에 원격으로 명령을 내릴 수 있다.
실습 Play with Docker 웹 사이트의 현재 세션으로 돌아가자. node1의 IP 주소를 옮겨 적은 뒤, 다른 노드를 하나 더 생성한다. 다음 명령을 입력해 node2에서 SSH를 통해 node1에서 실행 중인 도커 엔진에 명령을 내려 보자.
001) # node1의 IP 주소를 환경 변수로 정의한다
002) node1ip="<node1-ip-address-goes-here>"
003)
004) # 접속 테스트를 위해 SSH로 접속을 시도한다
005) ssh root@$node1ip
006) exit
007)
008) # node2에서 해당 노드에서 실행 중인 컨테이너의 목록을 확인한다
009) docker container ls
010)
011) # node1에서 원격으로 접근한 도커 엔진에서 실행 중인 컨테이너의 목록을 확인한다
012) docker -H ssh://root@$node1ip container ls
013) CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
014) b62004889054 diamol/apache "httpd-foreground" 18 minutes ago Up 18 minutes 0.0.0.0:32768->80/tcp romantic_wright
-
005: Play with Docker에서 생성한 노드는 서로의 SSH 공개 키를 자동으로 주고받으므로 패스워드 입력 없이 SSH 접속이 가능하다.
-
Play with Docker를 사용하면 이 과정이 매우 간단해진다.
- 왜냐하면 Play with Docker 웹 사이트가 도커 엔진 원격 접근에 필요한 모든 사항을 직접 관리하기 때문이다.
- 운영 환경이었다면 사용자 계정을 만들고, 게다가 패스워드 입력을 건너뛸 필요가 있는 경우에는 SSH 키를 생성해 공개 키는 서버에, 비밀키는 사용자에게 전달해야 한다.