권한을 찾아서: GitHub Team을 이용하여 Kubernetes 계정 인증하기 (1)

유희철
Banksalad Tech
Published in
7 min readJun 1, 2018
“Numerous padlocks on a bridge railing” by Benjamin Bortels on Unsplash

안녕하세요, Rainist의 DevOps 엔지니어 유희철입니다.

요즘 컨테이너 기술의 사용이 확대되면서 Kubernetes(이하 k8s), Docker Swarm, Mesos 와 같은 컨테이너 오케스트레이션orchestration 툴의 사용도 필수적으로 자리 잡고 있는 것으로 보입니다.

2015년 즈음에 서버 앱 배포 및 운영에 대해 본격적으로 관심을 가지기 시작하면서, 처음으로 Docker와 k8s를 접하게 되었습니다.

Docker의 매력에 먼저 빠져들어 이런저런 서버 앱을 모두 도커화 (Dockerize) 하였는데 막상 실제 프로덕션에서 운영하기에는 고민되는 지점이 한둘이 아니었습니다. 오히려 도커화되지 않은 네이티브 앱을 다루는 것 보다 훨씬 더 골치가 아팠습니다. 특히나 Rainist같은 스타트업에서는 제품이 언제 빠르게 성장할지 모르기 때문에, 늘 서버의 클러스터링, 동적 스케일 아웃scale-out, 클러스터 내의 서비스 디스커버리 등이 요구되는데 그러한 것들을 모두 처리하기에는 어려움이 너무 컸습니다.

이 모든 복잡한 과정을 수동으로 직접 관리한다는 건 조금만 장기적인 관점으로 봐도 그 한계가 분명히 보였기에, 이런 과정을 자동으로 관리할 수 있는 도구를 찾아야겠다는 생각을 했습니다. 그 당시 사실상 Ops 분야의 뉴비였던 저에게 적합한 툴을 찾는 리서치가 버거웠지만 적합한 후보가 나올 때마다 실제로 적용해보면서 옥석을 가려갈 수 있었습니다. 그러한 과정에서 Deis, Flynn, Dokku와 같은 툴을 살펴보거나 세팅을 시도했고, 대부분 원하는 바를 달성하기에는 적합하지 않아 절망했던 기억이 있습니다. 절망의 가운데 k8s를 발견하고 당시 알파 또는 베타였던 GKE(지금의 Kubernetes Engine)를 이용해본 뒤, k8s의 철학에 크게 공감하여 언젠가 꼭 유용하게 사용하리라 다짐했습니다. (그때는 제가 전문적인 백엔드 또는 Ops 엔지니어가 아니었기에 실제로 k8s를 활용하기에는 기회가 한정적이었습니다.)

그런 아쉬움을 가지고 있던 와중에, 2017년에 Rainist에 DevOps 엔지니어로 합류하게 되었습니다. 회사에서도 DevOps 전담 엔지니어는 처음이었고 DevOps의 대한 니즈가 마침 필요하였기에 전폭적인 지원을 받으며 드디어 k8s 를 십분 활용하기 시작했고, 서서히 뱅크샐러드의 마이크로서비스들이 하나둘씩 k8s 위에서 운영되기 시작했습니다. 다행히 그동안 k8s도 기능과 이용자 규모의 측면에서도 폭발적으로 성장하여 점점 더 프로덕션에서 활용하기에 충분한 도구로 발전하고 있었습니다.

제가 Rainist 엔지니어링 블로그에 처음으로 글을 작성하다 보니 서두가 약간(?) 길었네요. 이제 이 글의 진짜 목적에 대해서 집중해보도록 하겠습니다.

k8s는 한 번 세팅만 잘 되어 있다면 사용하는 입장에서는 아주 편한 툴이지만 사실 클러스터를 처음에 구성할 때는 부분에서는 마냥 쉽다고 말하기 힘듭니다.

가장 쉽고 편하게 클러스터를 구성하고 운영하는 방법은 GCP의 Kubernetes Engine을 사용하는 것이지만 여러 가지 이유로 AWS를 사용해야 할 경우가 있습니다.

Rainist도 현재는 AWS에서 k8s 클러스터를 구성하는 게 유리하다는 판단으로 EC2를 활용하여 클러스터를 운영하고 있습니다. k8s 클러스터를 처음부터 일일이 구성하는 것이 불가능하지 않지만, 기술적인 어려움, 많은 시간 소요, 올바르게 설정되지 않을 수 있는 리스크등이 있기 때문에 세팅을 도와주는 도구가 많이 존재합니다. 저는 개인적으로 CoreOS에서 만든 Tectonic을 사용 해본 적이 있었고, 당시에 Rainist에서는 kops를 사용하고 있습니다. kops를 사용하면 비교적 쉽게 클러스터를 구성하고 바로 사용할 수 있지만 모든 것이 다 원하는 대로 준비가 되어있는 것은 아닙니다.

kops 의 기본적인 구성을 사용하면서 아쉬운 부분을 몇 가지 나열해보면

  • Networking — 기본 kubenet의 경우 노드를 50개 까지만 지원
  • Ingress — AWS Console에 접속하여 Security Group의 설정을 따로 변경해줘야 함
  • Authn/Authz (이하 Auth) — 관리자, 개발자별 아이디 발급 및 권한 설정하는 부분이 굉장히 까다롭거나 손이 많이감

등이 있는데요, 그중에서 Auth는 모든 팀에게 상당히 중요합니다. 왜냐하면, k8s 활용을 극대화하기 위해서는 다양한 개발자들이 목적에 필요한 권한을 필요로 하는 즉시 바로 얻을 수 있어야 하기 때문입니다. 권한이 없어서 서버 앱을 배포하지 못하는 것만큼 시간 낭비가 없겠죠? 또 나중에 시간이 지나서 팀원이 퇴사한 경우에는 서버의 보안을 위해서 그 즉시 해당 팀원이 가지고 있는 권한을 삭제할 수 있어야 합니다.

이런 기능은 팀에서 GitHub 을 사용해 보셨다면 아주 간단하게 Member를 추가하고 권한을 부여하고 또 손쉽게 삭제하는 경험을 해보셨을 겁니다.

하지만 k8s 클러스터에는 이런 기능을 손쉽게 사용할 수 있는 UI는 커녕 CLI 명령어조차 없다시피 합니다. 결국, 시스템 설정을 건드리는 등의 작업을 해야 하는데 문서를 보고 바로 적용할 수 있는 수준과는 거리가 있고 막상 작업하더라도 손이 많이 가죠. Kubernetes Engine이나 Tectonic 또는 앞으로 출시될 AWS EKS 를 사용한다면 이런 기능은 지원이 되겠지만 저희는 현재 저희가 직접 설치한 클러스터를 사용하고 있으니까요.

결국, 이런 어려움으로 인해, 일반적으로 권장되지 않는 practice인 /.kube/config 파일 등을 공유하여 사용하게 되는 일들이 종종 있을 수 있겠죠. 그렇게 되면 누가 어떤 액션을 취했는지 (프로덕션 서버에서는 아주 중요한 정보이죠) Auditing이 불가능해질 뿐더러 퇴사자가 생길 때마다 인증 정보를 변경해야 하며 모든 사람이 같은 권한 (cluster-admin) 을 가지고 있는 불편하고 또 불안한 상황을 마주할 수 밖에 없게 되겠죠?

이러한 상황을 k8s 공식/비공식 개발팀에서도 인지하고 있으며, 관련하여 여러 가지 방안을 내놓고 있습니다. 그중의 하나가 k8s 의 인증방식 중 하나인 OIDC 를 이용한 dex 를 이용하는 방식입니다. (참고 — 데일리 호텔의 사례)

하지만 OIDC 를 쉽게 사용할 수 있도록 도와주는 dex 조차도 설치해서 운영하는데 만만치 않은 기술적인 도전과 복잡도가 있었기 때문에 썩 내키지는 않았습니다.

그러다 얼마 전에 Webhook Token Authentication 방식을 이용하는 AppsCode의 Guard라는 오픈소스 툴을 발견하고서 희망을 품어보았습니다.

그래서 바로 시도해본 결과, 결론부터 말씀드리면 아주 만족스럽게 k8s cluster 의 Auth 이슈를 해결할 수 있었습니다!

실제로 어떤 과정을 거쳐서 적용했는지는 이어지는 다음 포스트에서 확인해보세요!

--

--