Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

[NDC17] Kubernetes로 개발서버 간단히 찍어내기

10,972 views

Published on

데브시스터즈의 Cookie Run: OvenBreak 에 적용된 Kubernetes 기반 다중 개발 서버 환경 구축 시스템에 대한 발표입니다.
Container orchestration 기반 개발 환경 구축 시스템의 필요성과, 왜 Kubernetes를 선택했는지, Kubernetes의 개념과 유용한 기능들을 다룹니다. 아울러 구축한 시스템에 대한 데모와, 작업했던 항목들에 대해 리뷰합니다.
*NDC17 발표에서는 데모 동영상을 사용했으나, 슬라이드 캡쳐로 대신합니다.

Published in: Software

[NDC17] Kubernetes로 개발서버 간단히 찍어내기

  1. 1. seungyong@devsisters.com 오 승 용 Kubernetes로 개발서버 간단히 찍어내기 개발팀 누구나 필요할 때 서버를 띄울 수 있게
  2. 2. 내용 (Kopub M) 발표자 소개 오 승 용 • 현 DEVSISTERS 서버개발자 • Publishing Infra • Cookie Run: OvenBreak • Cookie Run for Kakao, LINE Cookie Run • NEXON – Erlang 기반의 인 게임 보이스 챗 서버 개발 • 스타트업 (WeClay) • GIST(광주과학기술원) 학사과정 1기 2
  3. 3. 데브시스터즈 서버팀 • 모두가 DevOps Engineer • 서버 구조를 설계하고, 어떤 언어, 어떤 스택을 쓸지, 프로토콜 구조를 잡고, • 게임 기획에 참여하고, 게임 로직에 맞는 서버 코드를 짜고, • 개발부터 프로덕션까지 서버 배포, 모니터링하고, 장애를 대응하고, • 뭔가 아쉬우면 새로 만들고 (libquic, LogQuery 시스템, …) 할 일이 많고 다양하다 3
  4. 4. 데브시스터즈 서버팀 • 이게 현실적으로 가능하려면.. 기술로 해결할 수 있는 일은 기술로 풀자! 4
  5. 5. Cookie Run: OvenBreak • 2016년 10월 27일 출시 • 글로벌 원빌드 11개 언어 지원 • 1천만 다운로드 5
  6. 6. 문제 제기 왜 개발 서버를 “찍어내는 것” 이 필요했는가
  7. 7. 새 서버가 유저를 만날 때까지 1. 문제 제기 DEV STAGE PROD (Live, Real, ..) QA 7 개발 서버 환경 서버와 클라의 첫 만남 검수 QA엔지니어 테스트 스테이징 운영 환경과 유사 배포 전 마지막 테스트 프로덕션 실제 유저들이 접속하는 서버 오늘 발표가 다룰 것 개발자가 로컬에서 구현을 마치면,
  8. 8. Dev 서버 하나를 모두가 같이 쓸 수 있을까? 1. 문제 제기 개발 초기에는 ‘dev’ 서버 하나를 띄움 8
  9. 9. Dev 서버 하나를 모두가 같이 쓸 수 있을까? 1. 문제 제기 로그인 연동 팀 UX 개선 팀 로그인 인증 방식 변경 Dev API 호환 X 왜 앱이 크래시나지?? 9
  10. 10. Dev 서버 하나를 모두가 같이 쓸 수 있을까? 1. 문제 제기 “밸런스 데이터를 바꿔야 하는데, 다른 분들에게 영향을 주기 싫어요” 개발 환경 서버가 하나만 있으면 매우 불편 10 “이벤트 QA 하려면 서버 시간을 미래로 바꿔야 하는데 괜찮을까요?” “번역 작업을 하고 싶은데, 테스트용 클라이언트를 매일 받기 싫어요”
  11. 11. 1. 문제 제기 개발 서버를 두 대 띄워서 돌려 쓰자! Dev Dev2 그렇다면, 11
  12. 12. 1. 문제 제기 한달 정도는 버텼으나, 환경 두 개로는 부족. Dev Dev2 그렇다면, 개발 서버를 세 대 띄워서…!? Dev3 12
  13. 13. • 시점에 따라 필요한 개발 서버 환경 수가 유동적 • 각각의 개발 서버가 어떤 “역할”을 하는지 모름 • “이 서버는 누가 어떤 용도로 쓰고 있는 서버일까?” • “내가 이 서버 써도 되나?” • “이제 안 쓰는 서버인가?” 1. 문제 제기 13
  14. 14. 구현 개발 서버를 찍어내는 서비스 만들기
  15. 15. 구현 스펙 • 원하는 시점에 원하는 버전의 서버 환경을 여러 개 띄울 수 있어야 함 • 서버 환경의 메타 정보를 쉽게 확인 가능해야 함 • 서버의 버전, 목적, 띄운 날짜, 띄운 사람 등등 2. 구현 15
  16. 16. Dev1 DB 개발 서버 구조 2. 구현 Logging Infra 16 Dev1 Dev2 DB Dev2 …
  17. 17. Game Server League Server Scheduler Server App Backoffice (운영툴) 개발 서버 구조 2. 구현 DB Logging Infra 서버 환경별 분리 필요 17 Dev1 DB Dev1
  18. 18. 2. 구현 18 Demo
  19. 19. 2. 구현 19 Demo
  20. 20. 2. 구현 20 Demo
  21. 21. 2. 구현 21 Demo
  22. 22. 2. 구현 22 Demo
  23. 23. 2. 구현 • 띄울 서버가 많고, 서버 간에 통신도 필요 • 추가 서버 환경이 필요할 때마다 새 서버 인스턴스를? • 가능은 하지만 복잡. 서버 개발자 이외는 사용하기 어려움 • 모든 서버 앱들은 Dockerized (또는 Dockerize 가능) Container Orchestration Tool 을 써 보자! 23
  24. 24. 2. 구현 Container Orchestration? • Multi-node Docker (or other containers) Cluster 24 Host Host 1 Host 2 Host N nginx nginx
  25. 25. 2. 구현 Container Orchestration? • Scheduling: 새로 띄울 도커 컨테이너를 최적의 머신에 띄우기 (ex. 가장 메모리 소비가 낮은 머신) 25 Host 1 Host 2 Host N nginx nginx
  26. 26. 2. 구현 Container Orchestration? • Scaling: 도커 컨테이너를 (여러 머신에) 여러 대 띄우기 (+ 죽으면 살리기) 26 Host 1 Host 2 Host N nginx 3 nginx nginx nginx
  27. 27. 2. 구현 Container Orchestration? • Load balancing: 특정 서비스 요청을 여러 도커 컨테이너로 분산 27Host 1 Host 2 Host N nginx nginx nginx
  28. 28. 2. 구현 Amazon ECS Docker (Swarm mode) Kubernetes Container Orchestration Tool 고르기 28 X AWS 의존성 복잡. 기능 부실 X 심플  기능 부족 O
  29. 29. 2. 구현 • Google 내부에서 사용하던 Borg의 open source 버젼 • 활발하게 개발되고 있는 프로젝트 • 시스템 구축에 적합한 각종 기능들 • 자체 DNS를 통한 내부 서비스 discovery • Namespace – 각 서버 환경별 클러스터 구분 용이 • GCP(GKE), Azure에서 managed service 제공 • 하지만 AWS 에서도 각종 방법으로 구축 가능 Kubernetes 29 Container Orchestration Tool 고르기
  30. 30. 빠르게 살펴보는 Kubernetes 30 • Pod - 최소 단위 (≈ docker container) apiVersion: v1 kind: Pod metadata: name: nginx-app label: name: nginx-app spec: containers: - name: nginx-app image: nginx:1.7.9 ports: - containerPort: 80 name: http protocol: TCP Host 1 172.x.x.1 nginx Host 2 172.x.x.2 10.x.x.100:80
  31. 31. 빠르게 살펴보는 Kubernetes 31 • Replica Set – Pod Scaler Host 1 172.x.x.1 nginx Host 2 172.x.x.2 10.x.x.100:80 apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: nginx-rs spec: replicas: 3 template: metadata: labels: app: nginx-app spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 Host 3 172.x.x.3 nginx 10.x.x.110:80 nginx 10.x.x.120:80
  32. 32. 빠르게 살펴보는 Kubernetes 32 • 2. 구현 • Service Host 1 172.x.x.1 nginx Host 2 172.x.x.2 10.x.x.100:80 Host 3 172.x.x.3 nginx 10.x.x.110:80 nginx 10.x.x.120:80 Service nginx-svc 10.x.x.130:80 apiVersion: v1 kind: Service metadata: name: nginx-svc spec: type: ClusterIP selector: app: nginx-app ports: - port: 80 name: web-port protocol: TCP
  33. 33. 빠르게 살펴보는 Kubernetes 33 • 2. 구현 • Service apiVersion: v1 kind: Service metadata: name: nginx-svc spec: type: ClusterIP selector: app: nginx-app ports: - port: 80 name: web-port protocol: TCP
  34. 34. 빠르게 살펴보는 Kubernetes 34 • 2. 구현 • Service apiVersion: v1 kind: Service metadata: name: nginx-svc spec: type: ClusterIP selector: app: nginx-app ports: - port: 80 name: web-port protocol: TCP Service nginx-svc 10.x.x.130:80 Service Discovery 클러스터 내에서 (또는 클러스터의 DNS address를 바라본다면) nginx-svc:web-port -> 10.x.x.130:80 으로 resolve ex. curl http://nginx-svc:web-port = curl http://10.x.x.130:80
  35. 35. 빠르게 살펴보는 Kubernetes 35 • 2. 구현 • Namespace • Kubernetes 내 리소스의 논리적 분리 단위 (C++ 등의 그것과 비슷) nginx-svc 서비스의 namespace가 ’ns1’, 요청을 보내는 도커의 namespace가 ns1이 아니라면 (ex. ns2) nginx-svc.ns1:web-port
  36. 36. Game Server League Server Scheduler Server App Backoffice (운영툴) 기존 개발 서버 구조 2. 구현 DB Logging Infra 36 Node ‘dev2’ Node ‘dev1’
  37. 37. Namespace ‘dev2’ 2. 구현 Kubernetes를 적용한 서버 구조 Amazon ElastiCache (Redis) Amazon RDS (MySQL) Game Server League Server Scheduler Server Backoffice (운영툴) Namespace ‘dev1’ 37 Logging Infra
  38. 38. 2. 구현 Kubernetes 적용하기 • 각 서버 어플리케이션들은 모두 Kubernetes 로 • 서버 환경 (dev1, dev2, ..)별 namespace 생성 • http://gameserver:80 으로 요청 ➞ 같은 서버 환경의 game server로 요청됨 Game Server League Server Scheduler Server Backoffice (운영툴) 38
  39. 39. 2. 구현 Kubernetes 적용하기 • Redis, MySQL ➞ AWS에서 제공하는 서비스 사용 • 각각 서버 환경별 space를 분리할 방법 존재 • MySQL – Database • Redis – DB number • Couchbase ➞ Kubernetes • 별도 인스턴스 구성 시 서버 환경별 space 분리 불편 ➞ Kubernetes 각 서버 환경 namespace에 container로 띄움 DB 39
  40. 40. 2. 구현 Kubernetes 적용하기 • Logging Infra ➞ Kubernetes • Component와 띄울 노드가 많은데, 각각은 리소스를 별로 안 씀 (Zookeeper, Kafka, ElasticSearch, Logstash, ..) • Ex. Zookeeper: 3대, Mem 500M, CPU < 5% (1 core) Logging Infra 공통 40
  41. 41. Kubernetes 클러스터 띄우기 • Managed Cluster Service • Google Cloud – GKE (Google Container Engine) • Azure – Azure Container Service • AWS는 직접 구축 또는 별도의 tool 이용 • kube-aws, kops, kargo, Tectonic, … https://kubernetes.io/docs/getting-started-guides/#table-of-solutions 2. 구현 41
  42. 42. Kubernetes 클러스터 띄우기 • kube-aws • CoreOS • Flannel • Amazon CloudFormation 2. 구현 42
  43. 43. Kubernetes 클러스터에 서비스 띄우기 • 유형 1. 웹 서비스 • Game Server, … • Non-stateful • ReplicaSet 과 Service 사용 2. 구현 ReplicaSet game-server replicas: 2 Pod game-server-x29fb Pod game-server-a1234 Service game-server 43
  44. 44. 잠깐! 클라이언트가 Kubernetes 서비스에 접속하려면 NodePort 2. 구현 apiVersion: v1 kind: Service metadata: name: nginx-svc spec: type: NodePort selector: app: nginx-app ports: - port: 80 name: http protocol: TCP Worker 1 172.20.7.95 Worker 2 172.20.7.112 nginx nginx service TCP 30035 TCP 30035 44 모든 노드의 ‘특정’ 포트로 접속하면 해당 서비스로 라우팅
  45. 45. 잠깐! 클라이언트가 Kubernetes 서비스에 접속하려면 2. 구현 • 그럼 동적으로 생성된 포트 번호를 외워야 되나요? (직접 지정이 가능하나, 대략 3만번 ~ 6만번대 포트만 사용 가능) • Kubernetes worker 하나가 죽으면 DNS record는 어떻게.. • 그럼 회사 망에서 Ingress ACL 모든 포트 오픈을 해야 하나요? • HTTPS 쓰고 싶은데 인증서는 또 어떻게.. 45
  46. 46. Ingress Controller 2. 구현 ReplicaSet game-server replicas: 2 Pod game-server-x29fb Pod game-server-a1234 Service game-server AWS Elastic Load Balancer proxy Service Backoffice backoffice.login-dev.??.com game.login-dev.??.com 46 login-dev 서버환경 NodePort
  47. 47. Kubernetes 클러스터에 서비스 띄우기 • 유형 2. Stateful Service • Zookeeper, Kafka, .. • 보통 각 개별 pod 별로 직접 접근 필요 • Pod 하나를 가지는 ReplicaSet 및 Service 구성 + NodePort • Kubernetes의 Persistent Volume + AWS EBS 이용 2. 구현 47 Host 1 kafka-1 Amazon EBS Host 2 Host 2 kafka-1 Amazon EBS ReplicaSet zookeeper-1 replicas: 1 Pod zookeeper-1-a1234 Service zookeeper-1 172.x.x.100:42181
  48. 48. 서버를 띄우는 웹 페이지 만들기 • 이제 CLI 로 서버를 띄울 수 있게 되었다! • 하지만 여전히 불편 – 어떤 서버가 있는지, 누가 띄웠는지 등등 • 서버를 띄우고, 내리고, 상태를 확인하는 웹 페이지를 만들자 2. 구현 48
  49. 49. Stove • 개발 서버를 띄우는 웹 • Python / Django • Pykube 2. 구현 49
  50. 50. Stove • 떠 있는 서버의 정보를 쉽게 파악 가능 (띄운 사람, 버젼, 띄운 날 등) • 서버별로 들어갈 웹 페이지 링크 2. 구현 50
  51. 51. Stove • 커밋&푸시 ➔ Automated Docker Build • Github API 통한 버젼별 commit log • 서버 이름과 설명을 적어 목적을 알 수 있게 • 런치 / 업데이트 / 삭제 시 Slack Webhook • 사내 방송 시스템과 연계하여 개발팀 알림 “xx 서버 업데이트 시작합니다” 2. 구현 51
  52. 52. 개발 서버가 많아지니.. 어디로 붙어야 하나?! 2. 구현 • 기존에는 서버 환경이 고정적이었으므로 하드 코딩 (ex. 디버그 클라이언트 런치 시 ‘dev’, ‘dev2’, ‘dev3’ 중 고르기) • 서버가 많아지고, 때에 따라 다른 서버에 접속해야 하는데, 손으로 일일히 주소를 쓰기 힘들다 52
  53. 53. 개발 서버가 많아지니.. 어디로 붙어야 하나?! • Preset API • 접속할 서버 주소 • 접속 시 사용할 리소스 버젼 / 게임데이터 버젼 2. 구현 53
  54. 54. 리뷰 원하던 것을 얻었는가
  55. 55. 그래서, 목표는 달성했나요? 1. 개발팀 누구나 필요할 때 서버를 띄울 수 있게 ➞ 달성 • 클라이언트 개발자나 QA 엔지니어도 필요에 따라 서버 On/Off/Update • 각 서버의 정체성이 명확해져 개발 시 API, 데이터 충돌 등 이슈 감소 • 마침 독립 테스트 서버가 필요했던 타 팀들 • 알파런 (Machine Learning), 테스트 자동화, … 3. 리뷰 55
  56. 56. 그래서, 목표는 달성했나요? 2. 개발 서버 환경 운영 비용의 감소 • AWS Reserved Instance • 따로 띄우기 애매한 각종 서비스들 (ex. 다국어 CS 번역 봇) 3. 리뷰 56
  57. 57. Kubernetes는 옳은 선택이었나? • Yes. 구현에 필요한 기능들을 비교적 편하게 쓸 수 있었음 • 아쉬웠던 점 • 복잡한 셋업 과정 (GCP를 쓰지 않는다면) • 복잡한 문서 • API version 이 자주 변경됨 (ex. extensions/v1beta1 ➔ v1) 3. 리뷰 57
  58. 58. Kubernetes on Production Environment? • 최근 Production 사용 사례 많음 (Pokemon Go, NCSOFT 등) • 쿠키런 오븐브레이크: X • 동기부여와 안정성 이슈 • IDC / On-Premise 물리 서버 환경에서 유용할 듯 3. 리뷰 58
  59. 59. We’re Hiring! http://www.devsisters.com/jobs/ 59

×