(번역) Docker에서 GCP 인증하기 - Application Default Credentials (ADC)
번역 원문: Authentication on GCP with Docker: Application Default Credentials
Google Cloud Platform을 이용해서 작업하다 보면, 다음과 같은 사항을 익히게 됩니다.
- 로컬 개발환경에서: Google Cloud SDK를 설치 후,
gcloud auth application default-login
만 실행하면 마치 마법처럼 모든 일이 해결된다. - Google Cloud 환경에서: 인스턴스를 올릴 때 사용하는 서비스 계정을 사용하여 자체 인증된다. (심지어는 이미지에 cloud sdk가 설치되지 않았더라도!)
- Google Cloud 환경에서
GOOGLE_APPLICATION_CREDIES
환경변수를 설정하면 수동으로 사용자를 인증하고, 자체 서비스 계정 인증 내용을 덮어쓴다. 이때 환경변수는 로컬 파일 시스템에서의 JSON 자격 증명 파일을 가리켜야 한다.
이 모든 것이 마법처럼 작동하고, 거의 모든 애플리케이션에 적용됩니다! 도대체 어떻게 이루어지는 걸까요? 만약 사용자 자격 증명(user credentials)을 사용해서 도커로 빌드한 응용 프로그램을 실행하려면 어떻게 해야 하는거죠? gcloud auth application-default login
을 실행할 때, 대체 어떤 일이 벌어지는 걸까요?
이 글은 마법의 배후에 있는 공학을 밝혀냅니다. 또한 사용자 자격 증명을 사용해 도커로 빌드한 응용 프로그램을 실행하는 방법에 대해서도 설명합니다.
이 이야기를 쓰기 위해, 저는 파이썬 및 자바용 구글 인증 라이브러리를 잠깐 살펴보았습니다. 더 자세한 정보를 원하시면, 직접 코드를 한번 살펴보세요!
ADC: Application Default Credentials
위에서 설명한 “자동” 인증은 ADC(Application Default Credentials)라는 원리로 작동합니다.
ADC 흐름은 GCP 리소스와 상호작용하려는 응용 프로그램이 임시 IAM 액세스(bearer) 토큰을 얻기 위해 따라야 하는 일련의 단계입니다. ADC 흐름은 모든 Google Cloud의 클라이언트 라이브러리 및 인증 라이브러리에서 구현(이용)됩니다. 거의 모든 애플리케이션이 이러한 라이브러리를 사용하여 인증을 처리하기 때문에, GCP를 사용한 인증과 관련해 애플리케이션이 일관되게 동작하는 것이죠.
ADC 흐름
ADC 흐름은 다음과 같은 단계를 따릅니다:
-
GOOGLE_APPLICATION_CREDIES
환경변수가 설정되고 자격 증명 파일을 가리키면, 이 파일의 내용을 액세스 토큰을 가져오는 데 사용한다. 파일은 사용자 자격 증명(user credentials) 파일이거나 서비스 계정 자격 증명(service account credentials) 두 가지 경우 모두 가능하다. -
만약 환경변수가 설정되어 있지 않으면, Cloud SDK 구성 폴더에서
application_default_credentials.json
이라는 파일을 찾는다.gcloud auth application-default login
을 통해 애플리케이션 인증을 받는 게 바로 이 경우다. -
둘 중 어느 것도 아니면, 인증되지 않은 HTTP 요청을 GCE 메타데이터 서비스로 보낸다. 만약 애플리케이션이 클라우드 환경에서 실행된다면, 이 요청의 결과로 액세스 토큰을 받을 수 있다.
참고로:
-
“Cloud SDK 인증” 방식을 사용하기 위해 반드시 Google Cloud SDK를 설치할 필요는 없습니다. 파일 시스템의 올바른 위치에 유효한 자격 증명 파일을 저장하기만 하면 됩니다! SDK는 UNIX 시스템의 기본 위치인 ~/.config/gcloud에서 Cloud SDK를 찾습니다.
-
App Engine을 위한 레거시 메커니즘도 존재합니다. 이는 메타데이터 서비스 전에 확인되기도 하니, 만약 앱 엔진을 사용하고 있는데 예상대로 작동하지 않는 경우 이 부분을 확인해 보세요.
-
위에서 설명한 단계가 실제로 어떻게 작동하는지, 즉 자격 증명이나 메타데이터 서비스를 사용하여 액세스 토큰을 얻는 방법을 자세히 살펴보는 또 다른 글을 썼습니다. 확인해 보세요! https://medium.com/datamindedbe/three-methods-for-obtaining-gcp-access-tokens-7a516a79129a
ADC 이름
컴퓨터 과학에는 두 가지 어려운 문제가 있습니다: 캐시 무효화, 이름 짓기, 그리고 배열을 1부터 세기.
ADC라는 이름은 다소 혼란스럽습니다. 그냥 자격 증명(credentials)이라고 부르면 안 되는 걸까요? 저의 의견은 다음과 같습니다:
-
ADC는 “자격 증명 파일”이나 “비밀번호”를 포함하지 않을 수 있다는 관점에서 자격 증명이 아닙니다. 예를 들면, ADC는 단순히 메타데이터 서비스에 대한 호출일 뿐일 수도 있습니다. ADC는 일련의 단계 또는 인증 라이브러리에 대한 조금 이상한 이름일 뿐이죠.
-
액세스 토큰을 검색하기 위해 ADC를 “적용”할 수 있으며 GCP 리소스와 상호 작용할 수 있는 권한을 사용자에게 부여한다는 관점에서는 자격 증명이기도 합니다. 프로그래밍적으로 말하자면, ADC는 자격 증명의 인터페이스를 구현합니다.
저는 ADC 적용과 관련된 일련의 단계를 지칭하기 위해 **“ADC 흐름”**이라는 용어를 사용하는 것을 선호합니다.
Docker에서 ADC 사용하기
위의 내용을 알고 있으면, Docker에서 ADC 흐름을 작동시키는 것은 매우 쉽습니다! ADC는 애플리케이션 기본 자격 증명 파일을 컨테이너 내부에 볼륨으로 마운트하고, 환경변수 GOOGLE_APPLICATION_CRENTIES
가 해당 파일을 가리킬 때 작동합니다. 따라서 기본 Unix 시스템의 Google Cloud SDK 구성 폴더가 표준 위치에 있다고 가정하면 명령은 다음과 같습니다:
docker run -v "$HOME/.config/gcloud/application_default_credentials.json":/gcp/creds.json:ro \
--env GOOGLE_APPLICATION_CREDENTIALS=/gcp/creds.json \
...
-
사용자 자격 증명(user credentials)을 사용하여 애플리케이션을 실행하는 것은 개발에는 문제가 없지만, 프로덕션에서 수행해야 하는 작업은 아닙니다. 이것이 구글이
application_default_credentials.json
파일을 숨기는 것을 좋아하는 이유 중 하나일 것입니다. -
물론 서비스 계정 파일도 사용할 수 있습니다.
Google Cloud SDK
그럼, 이게 다일까요? 그럴 수도 있고, 아닐 수도 있습니다. 기술적으로 위의 솔루션은 실행 중인 컨테이너에서 ADC를 사용할 수 있게 해주지만, ADC 흐름을 따르지 않는 중요한 애플리케이션 세트도 있습니다… 바로 Google Cloud SDK 자기 자신이죠! 여기에는 gcloud뿐만 아니라 bq나 gsutil과 같은 gcloud와 함께 쓰이는 도구도 포함됩니다. 도커 컨테이너 내에서 이러한 도구를 사용하려는 경우 위의 솔루션은 작동하지 않습니다.
어떻게 google cloud SDK 자기 자신을 인증할까?
Cloud SDK는 사용자 자격 증명, 서비스 계정 자격 증명 또는 메타데이터 서비스를 사용하여 다른 애플리케이션과 동일한 방식으로 자체 인증합니다. 그러나, 그들은 일반적인 위치(ADC 흐름에서 쓰이는 위치)에서 인증 파일들을 찾지 않습니다. 대신 SDK 도구는 로그인한 사용자 및 서비스 계정의 자격 증명을 로컬 데이터베이스에 저장하는데요. 사용자 프로필 사이를 쉽게 전환하기 위해 gcloud 명령을 사용할 수 있긴 하지만, 약간 유감스럽네요.
참고로:
-
ADC에서 사용되는 Google ID가 SDK 도구와 상호 작용하는 데 사용되는 것과 동일한 ID일 필요는 없습니다. 즉,
gcloud auth login
(또는gcloud auth activate-service-account
)과gcloud auth application-default login
을 서로 다른 계정으로 로그인할 수도 있습니다. -
Cloud SDK 구성이 저장된 위치, 자격 증명 데이터베이스에 액세스하는 방법, 환경 변수를 통해 구성을 조작하는 방법에 대해 자세히 알고 싶다면 제가 작성한 다른 글을 확인해 보세요. https://medium.com/datamindedbe/mastering-the-google-cloud-platform-sdk-tools-ddcb16b62886
ADC와 Cloud SDK가 Docker에서 함께 작동하도록 셋팅하기
Cloud SDK와 ADC를 모두 작동시키려면 컨테이너 내부에 전체 Cloud SDK 구성 디렉토리를 볼륨 마운트하는 것이 좋습니다. 다소 부담스럽지만, 강력한 솔루션이에요. 그런 다음 Cloud SDK에 마운트된 볼륨을 구성 디렉터리로 사용하도록 지시할 수 있습니다:
docker run -v "$HOME/.config/gcloud:/gcp/config:ro" \
-v /gcp/config/logs \
--env CLOUDSDK_CONFIG=/gcp/config \
--env GOOGLE_APPLICATION_CREDENTIALS=/gcp/config/application_default_credentials.json \
...
이 코드 조각은 다음과 같이 작동합니다:
- 일반적으로 컨테이너 내에서 구성을 수정하지 않기 때문에 구성을 읽기 전용으로 마운트합니다. 원한다면
:ro
를 제거해도 괜찮아요. CLOUDSDK_CONFIG
변수를 사용하면 gcloud 구성을 비표준 위치(UNIX 시스템의 경우 기본 위치는 ~/.config/gcloud)에 저장할 수 있습니다.- 로그 디렉토리를 볼륨 마운트했습니다 (
-v /gcp/config/logs
). 이렇게 하면 로그 디렉토리를 다시 쓸 수 있게 되고, 도커 계층에 쓸 때보다 성능이 향상됩니다. - ADC의 부분 구현을 사용하는 일부 애플리케이션은
CLOUDSDK_CONFIG
변수값을 인식하지 못할 수 있으므로, 적절한 사용을 위해GOOGLE_APPLICATION_CREDIES
를 명시적으로 설정해줍니다. CLOUDSDK_AUTH_CRENTIAL_FILE_OVERRIDE
라는 변수를 사용하면 전체 설정값을 마운트할 수 있습니다. 하지만 이는 현재gcloud
에서만 작동하고,bq
나gsutil
등 다른 프로그램에서는 작동하지 않습니다.- 홈 디렉토리의 위치가 실행할 모든 도커 컨테이너에 대해 동일하지 않기 때문에 도커 사용자의 홈 디렉토리 내에 마운트하는 대신,
CLOUDSDK_CONFIG
변수를 사용해 폴더 위치를 구성해주는 게 좋습니다. - 위의 코드 조각을
docker_run_gcp
라는 alias로 정의하고, ~/.bash_aliases 파일에 추가해 두면 좋습니다. 인증된 상태에서 애플리케이션을 실행하려면, 셸에docker_run_gcp
라고 치기만 하면 됩니다. - Google Cloud SDK가 설치되지 않은 시스템에서도 이 아이디어를 이용할 수 있지만, Docker를 통해서만 실행할 수 있습니다.
이게 다에요! ADC, Cloud SDK의 자체 인증 방법, Docker를 사용하여 인증 문제를 제거하고 원활한 개발 환경을 구축하는 방법에 대해 알아야 할 모든 사항을 확인해 봤습니다!
저는 벨기에 루벤에 본사를 둔 독립적인 데이터 엔지니어링 및 데이터 분석 컨설팅 회사인 Data Minded에서 근무하고 있습니다. 만약 GCP가 당신을 슬프게 한다면, 언제든지 연락해 주세요! (참고로, 저희는 AWS, Azure, Terraform, Spark 등에도 관심이 있습니다.)
댓글