Programming-[Infra]/Docker

도커 교과서(엘튼 스톤맨, 심효섭) - 14. 도커 원격 접속, 보안과 context

컴퓨터 탐험가 찰리 2023. 5. 6. 14:00
728x90
반응형

 

1. 도커 API 접속 엔드포인트

 

도커 엔진에 접근하여 여러 작업들을 할려면 도커 API에 요청을 해야된다. 그리고 기본적으로 도커 API는 로컬 채널에만 열려있다. 다시 말해 본인의 컴퓨터로만 본인 컴퓨터의 도커 엔진에 접근할 수 있다.

 

비보안 HTTP로 도커 엔진 접근해보기

 

비보안 HTTP 접근 설정은 위험하다. 아무나 내 컴퓨터의 도커 엔진에 인증없이 접근하여 비트코인 채굴 등의 서비스를 컨테이너로 띄워버릴 수도 있다! 그냥 실습만해보고 설정을 원래대로 돌려놔야한다.

 

원격으로 내 컴퓨터의 도커 엔진에 접속하는 연습을 위해 HTTP 접근을 허용해본다. 도커 데스크탑의 설정 > General 부분에서 Expose daemon on tcp://localhost:2375 without TLS라는 체크박스에 체크하면 GUI 방식으로 설정할 수 있다고 교재에 나와있으나, 내가 사용하는 v4.9.1 버전에는 이런 메뉴가 없다. 따라서 설정 파일에 직접 접근하여 수정해본다.

 

이전 글 도커 교과서(엘튼 스톤맨, 심효섭) - 8. 모니터링- prometheus, grafana 에서 확인했던 아래 위치의 도커 설정 파일을 수정한다.

/Users/사용자명/.docker/daemon.json

 

"hosts": [
"tcp://0.0.0.0:2375", # 2375번 포트로 원격 접속 허용
"npipe://", # 윈도의 파이프에서 로컬 채널 접속 허용
"fd://" # 리눅스 소켓으로 로컬 채널 접속 허용
],
"insecure-registries": [
"registry.local:5000"
],
	"builder": { "gc": { "defaultKeepStorage": "20GB", "enabled": true } },
	"experimental": false,
	"features": { "buildkit": true },
    "metrics-addr": "0.0.0.0:9323"
}

 

그런데 도커에서 이런 설정을 막는건지 에러가 뜨면서 도커 실행이 되질 않는다. 그냥 이런것이 있다는 것만 알고 넘어가야할 것 같다. 만약 저런식으로 변경했다면 damone.json을 nano daemon.json 명령어로 열어서 builder 아래 부분만 남도록 편집해주고 도커를 재시작하면 된다.

 

 

 

 

2. 보안 원격 접근 설정 및 접근 해보기

 

로컬 채널 외 다른 보안 채널을 이용하여 도커 API에 요청을 전송할 수 있다. TLS(Transport Layer Security, 전송 계층 보안), SSH(Secure Shell, 보안 셸) 프로토콜 이다. 아래에서 차례대로 실습을 진행해볼 것이다.

 

다만 본인 컴퓨터의 도커 엔진은 도커 데스크탑을 통해서 가상머신에서 동작하고 있고 가상 머신의 도커 API 채널은 수정할 수 없다고 한다. 그래서 외부 서버에서 도커 엔진을 띄워서 거기에 접근해보는 실습을 한다. 무슨 뜻인지 아직 정확한 이해는 어렵지만 아무튼 앞서 배웠던 Play with Docker를 이용할 것이다.

 

TLS로 접근

 

node를 생성하고 아래 명령어들을 입력한다.

 

mkdir -p /diamol-certs # 인증서를 위치시킬 디렉터리 생성
docker container run -v /diamol-certs:/certs -v /etc/docker:/docker diamol/pwd-tls:server # 인증서 및 설정값을 적용할 컨테이너 실행
# 새로운 설정으로 도커 재시작
pkill dockerd
dockerd &>/docker.log &

 

dockerd는 백그라운드에서 실행되고 있는 도커의 메인 프로세스이다. pkill로 프로세스를 종료하고, dockerd 명령어로 재실행했다.

&> 명령어는 stdout과 error를 파일에 기입하라는 Bash 명령어이다.

&는 백그라운드에서 실행하라는 명령어이다.

 

다음으로 Open Port 버튼을 클릭해서 2376번 포트로 지정한다.

 

새로운 브라우저 창이 열리며 URL을 확인할 수 있다. 브라우저창의 주소를 그대로 복사하면 http:// 프로토콜이 붙는다. tcp:// 프로토콜을 사용할 것이기 때문에 이 부분은 삭제해야한다. 그리고 맨 뒤에 /도 제거한다.

ip172-19-0-45-chb0n901k7jg00dq1oa0-2376.direct.labs.play-with-docker.com

 

위와 같은 URL을 이용하여 이제 로컬 컴퓨터에서 Play with Docker에서 생성한 노드에 있는 도커 엔진에 접근한다. 다만 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"
}

 

 

이제 로컬 컴퓨터에서 Play with Docker상의 노드에 접근한다. 터미널에 아래처럼 입력한다.

pwdDomain="{상기 생성한 play with docker의 URL}" # 리눅스
curl "http://$pwdDomain/containers/json" # 도커 API로 접근
docker --host "tcp://$pwdDomain" container ls # 명령행 도구로 접근

# 클라이언트 인증서를 로컬 컴퓨터로 추출
mkdir -p /tmp/pwd-certs
cd ./ch15/exercises
tar -xvf pwd-client-certs -C /tmp/pwd-certs

# 클라이언트 인증서를 사용하여 도커 엔진에 접근
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

# 도커 명령행 도구로 명령 내려보기
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

 

클라이언트 인증서를 받기 전에는 Error response가 떨어졌으나, 이후에는 아래처럼 Play with Docker에서의 Response가 잘 전달되는 것을 확인할 수 있었다.

명령어 실행 전 후로 container가 생성된 것을 확인할 수 있다.

 

 

SSH로 접근

 

ssh는 도커 CLI가 표준 ssh 클라이언트를 사용하기 때문에 도커 엔진 쪽에서 설정을 변경할 필요가 없다. 그리고 사용자 인증을 서버가 대신 처리해줘서 인증서도 필요없다. 도커 엔진을 실행하고 있는 node1에서 원격 접속에 사용할 계정만 추가하면 된다.

 

#node2에서 실행
node1ip="{사용 중인 node1의 ip주소}"
ssh rrot@$node1ip
exit

docker container ls

#node1에서 실행
docker -H ssh://root@$node1ip container ls

 

ssh root@node1ip 명령어를 입력하면 아래처럼 연결을 유지할 것인지 물어본다. 이후 node1에 접속된다.

 

 

3. 도커 컨텍스트

 

보안 정보를 context로 지정하여 활용할 수도 있다. 상세 정보들을 로컬 컴퓨터에 저장하는 방식이다.

# tls
docker context create pwd-tls --docker "host=tcp://$pwdDomain,ca=/tmp/pwd-certs/ca.pem,cert=/tmp/pwd-certs/client-cert.pem,key=/tmp/pwd-certs/client-key.pem"

# ssh
docker context create local-tls --docker "host=ssh://user@server"
# user@server 정보는 play with docker에서 확인할 수 있다.

docker context ls

 

 

컨텍스트 전환

$env:DOCKER_CONTEXT='pwd-tls' # 윈도우
export DOCKER_CONTEXT='pwd-tls' # 리눅스

# 변경된 context내 container 리스트를 확인해보자.
docker container ls

# 모든 세션을 열고 있는 터미널의 컨텍스트를 기본으로 복귀시킴
docker context use default

 

환경 변수를 설정하면 위에서 설정한 pwd-tls 이름의 컨텍스트로 전환된다.

 

docker context use

위 use 명령으로 context를 전환할 수 있다고 한다. 그러나 이 명령어를 통해 컨텍스트를 바꾸지 않고 기본 컨텍스트는 로컬 도커 엔진을 가리키도록 놔두고 환경 변수만 사용해서 컨텍스트를 전환하는 것이 좋다. 이 환경 변수의 값은 docker context use 명령에 오버라이드 되에 우선하지만 현재 터미널에만 영향을 미치기 때문이다.

 

아래 사진 상 위쪽 터미널에서 docker context use 'pwd-tls'를 사용하고 context를 확인하면 현재 컨테이너는 변경사항이 적용되지 않아서 default를 사용하고 있으나, 새로운 터미널을 열고 컨텍스트를 확인해보면 pwd-tls를 사용 중인 것을 볼 수 있다. docker context use 명령어는 모든 세션의 터미널에 영향을 미친다. 따라서 DOCKER_CONTEXT 환경 변수를 바꾸는 식으로 작업하는 것이 좋다.

 

컨텍스트를 잘못 바꿨다가 로컬이 아닌 운영 컨텍스트에 접근해 실수를 해버리면 큰 문제가 된다.

 

 

 

4. 지속적 배포

 

보안이 적용된 원격 도커 엔진에 접속할 수 있다. 원격으로 접속할 수 있다는 것은 지속적 배포를 할 수 있다는 뜻이 된다.

 

cd ch15/exercises/infrastructure
docker-compose -f ./docker-compose.yml -f ./docker-compose-linux.yml up -d

 

그런데 이전 글에서 살펴본 것처럼 gogs에서 그대로 에러가 나고 있다... 어떻게 고쳐야할지 모르겠어서 여기서도 이 정도로 마무리해야할 것 같다..

 

728x90
반응형