공개 키 인프라(PKI)로 스웜 보안 관리하기
공개 키 인프라(PKI)로 스웜 보안 관리하기
Docker Swarm 모드에 내장된 PKI 시스템을 활용하면 컨테이너 오케스트레이션 환경을 아주 간단하게, 그리고 안전하게 꾸밀 수 있어요. 스웜에 참여한 노드들은 서로 상호 TLS(mTLS)로 인증하고, 권한을 확인하고, 통신 내용을 암호화한답니다. 이 글에서는 스웜이 어떻게 인증서를 발급하고 관리하는지, 그리고 CA 인증서를 회전하는 방법까지 자세히 설명드릴게요.
출처: 공식문서
본문
스웜 PKI의 기본 구조
docker swarm init 명령으로 스웜을 생성하면 Docker 자신이 매니저 노드가 돼요. 기본적으로 매니저 노드는 새로운 루트 CA(인증 기관)와 키 쌍을 생성해서, 이후 스웜에 합류하는 다른 노드들과의 통신을 안전하게 보호해요. 만약 외부에서 생성한 루트 CA를 사용하고 싶다면, docker swarm init 명령의 --external-ca 플래그를 지정하면 돼요.
매니저 노드는 추가 노드를 스웜에 합류시킬 때 사용할 토큰 두 개를 생성해요. 하나는 워커용 토큰, 다른 하나는 매니저용 토큰이에요. 각 토큰에는 루트 CA 인증서의 다이제스트(digest)와 무작위로 생성된 시크릿이 포함되어 있어요. 노드가 스웜에 합류할 때, 합류하는 노드는 이 다이제스트를 사용해서 원격 매니저의 루트 CA 인증서를 검증하고, 원격 매니저는 시크릿을 사용해서 합류하는 노드가 승인된 노드인지 확인한답니다.
새 노드가 스웜에 합류할 때마다 매니저는 그 노드에 인증서를 발급해요. 이 인증서에는 무작위로 생성된 노드 ID가 포함되어 있고, 이 ID는 인증서의 CN(Common Name)으로, 노드의 역할은 OU(Organizational Unit)로 표시돼요. 노드 ID는 현재 스웜에서 노드가 존재하는 동안 암호학적으로 안전한 노드 식별자 역할을 해요.
아래 다이어그램은 매니저 노드와 워커 노드가 최소 TLS 1.2를 사용해서 통신을 암호화하는 모습을 보여줘요. (원문에는 다이어그램이 포함되어 있지만, 여기서는 텍스트로 설명할게요.)
다음은 워커 노드에서 발급받은 인증서 정보의 예시예요.
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
3b:1c:06:91:73:fb:16:ff:69:c3:f7:a2:fe:96:c1:73:e2:80:97:3b
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN=swarm-ca
Validity
Not Before: Aug 30 02:39:00 2016 GMT
Not After : Nov 28 03:39:00 2016 GMT
Subject: O=ec2adilxf4ngv7ev8fwsi61i7, OU=swarm-worker, CN=dw02poa4vqvzxi5c10gm4pq2g
...snip...
기본적으로 스웜의 각 노드는 3개월마다 인증서를 갱신해요. 이 주기는 docker swarm update --cert-expiry <TIME PERIOD> 명령으로 변경할 수 있고, 최소 회전 주기는 1시간이에요. 자세한 내용은 docker swarm update CLI 문서를 참고하세요.
CA 인증서 회전하기
Note
Mirantis Kubernetes Engine(MKE, 이전 Docker UCP)은 스웜을 위한 외부 인증서 관리자 서비스를 제공해요. MKE에서 스웜을 운영 중이라면 CA 인증서를 수동으로 회전하면 안 되고, 인증서 회전이 필요하면 Mirantis 지원팀에 문의하세요.
클러스터 CA 키나 매니저 노드가 손상된 경우, 스웜 루트 CA를 회전해서 더 이상 아무 노드도 이전 루트 CA가 서명한 인증서를 신뢰하지 않도록 만들 수 있어요.
docker swarm ca --rotate 명령을 실행하면 새로운 CA 인증서와 키가 생성돼요. 원한다면 --ca-cert와 --external-ca 플래그를 사용해서 루트 인증서를 지정하고 스웜 외부의 루트 CA를 사용할 수도 있어요. 또는 --ca-cert와 --ca-key 플래그로 스웜이 사용할 정확한 인증서와 키를 지정할 수도 있답니다.
docker swarm ca --rotate 명령을 실행하면 다음 순서로 작업이 진행돼요.
-
Docker가 교차 서명된(cross-signed) 인증서를 생성해요. 즉, 새 루트 CA 인증서의 버전이 이전 루트 CA 인증서로 서명되는 거예요. 이 교차 서명된 인증서는 모든 새 노드 인증서의 중간 인증서(intermediate certificate)로 사용돼요. 덕분에 아직 이전 루트 CA를 신뢰하는 노드들도 새 CA가 서명한 인증서를 계속 검증할 수 있어요.
-
Docker는 모든 노드에게 TLS 인증서를 즉시 갱신하라고 지시해요. 이 과정은 스웜에 있는 노드 수에 따라 몇 분 정도 걸릴 수 있어요.
-
스웜의 모든 노드가 새 CA가 서명한 새 TLS 인증서를 받은 후에는, Docker가 이전 CA 인증서와 키 자료를 잊어버리고 모든 노드에게 새 CA 인증서만 신뢰하라고 알려줘요.
이로 인해 스웜의 조인 토큰도 변경돼요. 이전 조인 토큰은 더 이상 유효하지 않아요.
이 시점부터 발급되는 모든 새 노드 인증서는 새 루트 CA로 서명되고, 중간 인증서를 포함하지 않아요.