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