8. 해결책
1. 네이버 메인화면 같이 미리 만들어준다.
2. 부하 분산을 한다!
a. DNS를 사용하여!
b. 웹 서버 뒤에 여러 WAS가 숨어있다!(proxy)
c. 장비가 해준다! 장비는 위대하다! 로드밸런서 짱짱……..!
하지만 가격도 위대합ㄴ……...
9. 고민 2
서버가 늘어나니 사용자는 많이 받을 수 있는데,
- 돈도 많이 들고…
- 요청 처리한도가 도달하는데 생각보다 장비의 유휴가 많네…?
- 관리도 어려워지고…(개발 및 배포에 대한 관리)
- 다음 릴리즈 일정을 짜자!
- 코드 프리즈!
- 배포!
- 으앙...롤백!
10. 해결책 - 1
장비의 Utilization을 높여봅시다!
1. Virtual Server
a. Xen, OpenStack, Hyper-V
b. 그걸 다해주는 클라우드! - AWS, Azure, IBM, Oracle 등
2. Container 구축
a. LXC, Docker
그런데 왜 관리는 더 어려워지니…?
=> 배포해야 하는 대수가 늘어나니 복구도 오래걸리구...
11. 해결책 - 2(?)
관리 이슈를 줄여봅시다!
git도 사용해서 코드관리도 해주고, 모듈들 버전으로 관리하고, 업무도 버전단위로
끊어서하면 커뮤니케이션 하기 좋잖아? 1.1.2는 언제 배포 나가요?
- 올드합니다. 유연하지도 않습니다.
- 서비스의 복잡도는 사업의 발전도에 따라 매우 높아집니다.
하나에서 다 관리하려니 손 발이 꼬이지 않기 위한 방법입니다.
12. 해결책 - 2
시스템을 쪼갭니다! -> MSA의 시작
효과
- 각 기능별 코드만 관리하므로 코드가 줄어듬
- 하나의 배포가 다른 곳에 영향을 최소로 준다
- 배포 시간이 줄어든다
- 장애 범위가 줄어든다
- 배포가 어려워졌다…!
- 시스템이 복잡해졌다…!
- 장애 파악이 어려워졌다…!
14. MSA에서 필요한 인프라는 무엇인가
떡밥은 대충 다 던졌으니 (이제서야)시작해봅시다.
- 코드 관리(git)
- 개발환경
- 서버
- 네트워크
- 배포
- 로깅
- 모니터링
큰 덩어리는 이렇습니다. 쪼개서 이야기 해봅시다.
15. 코드 관리
브랜치 관리가 매우 중요합니다.
- development, stage, production 같은 환경별 브랜치는 목표치가 있어야 합니
다.
- development : runnable 한 코드 상태로 유지되어야 함
- stage : 실환경에 내보내도 될 정도로 testing되어진 상태
- production : 실제 운영에 필요한 코드가 모입니다.
- 대부분의 개발은 이외에 브랜치에 별도로 유지/관리합니다.
- ex. feature/manager-add
- 정책적인 룰이 필요합니다.
- 배포시간에 따른 태깅이 필요합니다.
- 롤백 시점을 잡기 위해 시스템 변환 지점을 알게 됩니다.
- CI를 통한 배포시에 도움이 됩니다.
16. 개발환경
브랜치가 나뉘었으니 인프라 환경도 나뉘어야겠죠?
최소한 stage, production은 같은 환경을 유지
develop은 때로는 인프라 변경을 위해 희생당할 수도 있습니다...또륵..
인프라의 비용을 줄이기 위해서 하나의 물리 서버에 다양한 데이터베이스를 두는
경우도 있습니다.
실서버는 성능을 위해 별도 구성해야 합니다.
그만큼 서버 비용도 서비스 개수만큼 x 3쯤 됩니다.
17. 서버 - 1
앞선 서론으로 돌아가서 서버는 늘어갑니다.
그런데 모든 리소스를 쓰지 못하게 됩니다.
그래서 하나에 서버에 서비스를 여러개 실행시킵니다.
- 자고로 계란은 한 바구니에 담지 말라고..
- 운영체제에 문제가 있다면?
- 서비스 하나가 시스템에 영향을 준다면?(설정이나 리소스 등)
- 포트의 점유 문제 등은 어떻게 해결 할 것인가?
18. 서버 - 2
그래서 환경을 독립시켜봅니다.
가상화를 끼얹는다면 !? 가 ! 상 ! 화 !
Xen, OpenStack, Hyper-V와 같은 가상화 솔
루션을 이야기합니다.
리소스도 적당히 분배하고, 운영체제 제약도
해당 인스턴스에 한정짓습니다.
19. 서버 - 3
가상화 좋아요. 매우 좋습니다.
인력이 많으면 좋지만… 관리는 누가해
요…?
관리가 거기서 왜 나와…?
그래서 우리는 클라우드를 씁니다. 엣
헴
20. 서버 - 4
MSA환경은 서비스 인스턴스가 매.우. 많이 늘어나게 됩니다.
VM의 개수보다 더 많은 서비스 운영환경이 필요하게 되는 시점이 옵니다.
그리고 VM은 생각보다 Provisioning이 느립니다.
(운영체제부터 cloning해야 별도의 운영체제로 동작하기 때문에)
배포 환경을 쉽게 조정하기도 어렵습니다.
21. 서버 - 5
그래서 container환경이 각광받습니다.
Docker, LXC와 같은 녀석들이죠.
(Windows도 Hyper-V에 Docker를 얹어 지원합니
다.)
Hypervisor Type 1, 2를 비교해서 보면 좋습니다.
aws에서 container환경을 운영한다면 Type1입
니다.
22. 서버 - 6
Docker는 Base Image위에 변경 사항을 위
로 쌓아 올라가는 구조를 가지고 있습니다.
즉, 변경이 되는 경우 변경된 부분만 배포
하면 배포가 완료됩니다.
태깅도 지원하기 때문에 특정 버전으로 롤
백도 매우 쉽습니다.
어려운건 항상 인프라 관리에요..ㅠㅠ
23. 서버 - 7
다 좋은데… 좋은거 같은데...
각 서버별로 docker를 각자 관리했어야 했습니다…!!
하지만 docker swarm이 나오면서 orchestration이라는 개념이 도입되었죠.
서버를 여러개 묶어 적당히 분산해서 띄워주고, 로그도 모아주고 등
24. 서버 - 8
이후에 kubernetes, mesos, ecs 등등의 솔루션이 나타납니다.
이제 저런 솔루션들과 배포시스템을 연동하여 시스템을 배포하게 되면,
소스만 관리하는 것을 넘어 환경까지 관리하여 배포가 가능해집니다.
하지만 시스템구축은… 참 쉽죠? 하고 싶네요 ㅠㅠ
25. 네트워크 - 1
네트워크 문제는 서버가 점점 많아지면서 발생합니다.
IP가 얼마든 많으면 모두 public ip주고 하면 참 편하겠죠?
하지만 IP도 유한하기 때문에, 사설 대역이 존재합니다.
(192.xx, 10.xx, 172.xx 같은)
사설대역도 충분하면 좋겠지만, 그렇지 않습니다. 시작 숫자가 제약된 것부터 IP의
개수가 매우 제한됨을 알 수 있습니다.
26. 네트워크 - 2
가상 환경의 IP는 외부 환경과 독립적으로 자유롭게 할당하기 위해 CIDR대역
(10.10.0.0/16 같은)을 일부 자체할당 하도록 되어 있습니다.
이 제한된 리소스들은 보통 각 가상서버마다 혹은 한 호스트 안에서 할당된 컨테이
너들에겐 중복되지 않는 것을 보장합니다.
27. 네트워크 - 3
여기서 문제는 상호 접속성에 있습니다.
같은 호스트에 있는 환경인 경우 대부분 연결이 보장되게 되어 있습니다.
(설정에 따라 다르지만)
이를 위해 사용되는 기술이 vxlan입니다.
각 vm(혹은 container)가 사용하는 가상의 NIC를 관리하는 가상화용 NIC끼리 상호
접속 가능하게 tunneling을 하는 방식을 통해 상호접속성을 보장합니다.(L2 Switch
방식)
28. 네트워크 - 4
docker swarm에서는 이러한 네트워크 환경을 지원하기 위해 overlay 네트워크를
지원합니다.
29. 네트워크 - 5
하지만 docker의 overlay network는 docker cluster내부에서만 지원을 합니다.
하.지.만.
- 같은 overlay네트워크 설정을 사용한 container끼리만 통신됩니다.
- 내부에서만 통신이되고, 외부에서 내부로는 연결이 불가능합니다.
외부와 내부의 상호 서비스를 위해서는 사용이 불가능합니다.
30. 네트워크 - 6
이런 문제들을 해결하기 위한 솔루션은 결국은 SDN(Software Defined Networking)
로 향하게 되어 있습니다.
docker진영에서 가장 많이 사용하는 솔루션은 kubernetes + etcd + flannel입니다.
flannel이 일종의 dhcp역할을 하고, 각 컨테이너 노드에 대한 정보는 distributed
k/v storage인 etcd가 node이름과 ip를 관리하는 형태입니다.
하지만 IP의 한계가 존재하므로, 적절히 서비스에 따라 클러스터를 구성하는게 매
우 중요합니다.
31. 앞에 얘기가 너무 길어요 ㅠㅠ 벗뜨
네, 앞에 이야기들은 길고 험난하지만 나머지 하나의 축이 빠졌습니다.
서비스를 잘게 나누고, 서비스들이 탑재될 환경을 잘 구축하고, 서로 통신이 되게
했지만!
이제부턴 실제 개발의 영역에서의 어려움으로 들어서게 됩니다.
32. 저렇게 서버가 많아진다면..!
모든 코드에 IP를 넣는 것은 불가능합니다.
해결책
1. 배포를 겁나 열심히 한다
2. DNS를 사용한다
3. HAProxy를 사용한다
4. Web Server를 앞에 붙인다
5. Service Discovery를 사용한다
33. Service Discovery
service discovery에는 두 종류가 존재합니다.
1. 출석 부르는 녀석 : Server Side Discovery
- 서버가 client를 직접 체크
2. 자기가 손드는 녀석 : Client Side Discovery
- 서비스 스스로가 자신의 위치를 등록
34. Service Discovery
정보의 보관에 따른 분류
1. 중앙집중형
- 서버가 중앙에서 모든 정보를 관리
2. 분산 클러스터형
- 분산된 여러 클러스터에서 각자의 정보를 보관
36. Service Discovery
Service Discovery는 Netflix Eureka, Consul, Zookeeper, Etcd 등이 존재
그 중 가장 많이 사용되었던 녀석은 Netflix Eureka인데, 관련 생태계를 이끌면서
선두주자가 되었다.(Spring Cloud같은)
Eureka는 중앙 집중형, Client Discovery 방식
Consul은 분산형, Client Discovery 방식
37. Service Discovery
Service Discovery의 역할은
- 서비스들의 IP와 포트를 상관없이 요청을 할 수 있도록 도움
- 서버들의 health check를 통해 항상 온전한 서버들의 목록을 유지
- (방식에 따라 다르지만) 최대한의 인프라 이슈를 최소화
38. Local Load Balancer
대표적인 솔루션은 Netflix Ribbon
- 중앙형 Load Balancer가 장애가 나면 서비스 전면 장애가 나므로 자체관리하
기 위한 목적
- Service Discovery로부터 서버의 목록을 받아와 다음에 요청할 서버를 지정
- 자체 알고리즘을 통해 특정 서버로 요청이 몰리는 것을 방지
(개발자들은 귀찮기 때문에 항상 서버목록[0]에 요청할 것을 알고 있다)
39. Retryer
서비스에 요청을 보냈는데 실패했다면…?
실패한 서버 외에 다른 서버는 동작을 할 수 있을테니 실패시에 ‘재요청’ 해주어야
함
이걸 손으로 짠다면….? 큼칙..
잘 작성된 library를 사용하도록 합니다.
(feign, spring retryer 등)
40. Sidecar
그렇게 개발을 하다보니… 대부분의 솔루션은 Java였던 문제가..!
외국어를 써도 알아들을 수 있는 information을 구축해봅시다.
대표적인 것은 Netflix Prana.
Proxy의 형태로 다른 언어를 쓰는 서버가 Service Discovery를 사용하거나 다른 서
비스로 요청을 할 때 그 모든 것들을 delegate해주는 역할
retry를 대신 해주지는 않아요...
41. Circuit Breaker
대표적인 솔루션은 Netflix Hystrix로, 여러 thread에서 발생한 요청들을 collpase하
고 적당한 부하 분산, 실패시 정책 등을 담당합니다.
주로 실패시에는 캐싱된 데이터를 돌려주거나 다른 요청들도 빠르게 실패처리하
여 재시도를 용이하게 하는 역할을 합니다.
42. MSA 2.0
최근에 MSA는 2.0이라고 불릴만큼 보다 다양한 솔루션과의 결합이 이루어지고 있
습니다.
MSA를 흔히 말하는 방식은 Death Star Architecture라고 얘기합니다.
하지만 최근에는 Service Mesh라고 말할 정도로 촘촘하고 여러 서비스가 유기적
으로 얽힌 형태를 보이기 시작했습니다.
다음의 그림을 몇가지 비교해보면 좋을 듯 합니다.
45. 이렇게 복잡해진다면..
모든 것들을 하나 하나 관리하기는 매우 어려워집니다.그 중 초기 세팅이 제일 어
렵습니다.
그래서 이런 것들을 한번에 해주겠다! 라고 하는 솔루션들이 등장합니다.
(Istio, Linkerd 등)
Sidecar의 형태를 띄면서 모든걸 대리해줍니다. 심지어 어느정도 연구가 진행된
정책들에 대한 반영도 기본적으로 되어 있습니다.
이러한 솔루션들이 서비스들을 대신해서 커뮤니케이션을 모두 담당하게 되고, 이
런 구조가 촘촘히 얽혀있는 MESH구조를 띈다고 표현합니다.
46. 배포
배포는 빠른 배포, 빠른 롤백을 지원하는 것들이 목표입니다.
인프라에 따라 영향을 제일 많이 받는 분야이기도 합니다.
VM시스템이면 VM에 맞는 배포방식이 존재하고, 컨테이너면 컨테이너에 맞는 방
식이 존재합니다.
하지만 input은 대부분 비슷합니다. 어느 소스에서 어떤 브랜치를 사용해서 어떤
서버(혹은 클러스터)에 배포할 것이다.
자동화 되기 전까진 몸으로 때우는 방법밖에 없습니다. Jenkins와 같은 솔루션을
씁시다!
47. 로깅/모니터링
로깅과 모니터링은 왕도가 없습니다.
얼마나 잘 수집하고, 조회하기 쉬운가.
흔히 얘기하는 ELK스택도 있고, 그레이 로그를 사용하는 방식, S3에 수집하고 검색
하는 방법, AWS CloudWatch 등을 사용하는 방식 등이 있습니다. 서버 리소스 모니
터링 도구도 다양합니다.
하지만 제일 중요한 부분은, 있어도 안보면 의미 없습니다.
서비스 회사에서 시스템 안정성을 높이는 방법은 자주 확인하고 문제를 빠르게 발
견하는 방법 뿐입니다. 고객을 통해 오면 이미 늦었어요.
48. 이렇게 복잡한걸 다 하고 알아야 하느냐..?
이런것들을 하려면 많은 고려사항이 필요합니다.
- 조직이 그만한 시스템을 감당할 수 있느냐
(사람, 개발, 관리, 인프라 전 영역)
- 현재 시스템으로 충분한가
- 예상되는 미래의 시스템은 현재의 기술부채 안에서 변경 가능한가
사실 조직의 역량은 해봐야 늘어납니다.
그리고 돈이 있으면 자연스 좋아집니다.
하지만 발전하는 조직에서 현 시스템의 문제/현재의 시스템/미래의 시스템을 얼
마나 잘 그릴 수 있고, 고민하느냐가 중요합니다. => 조직의 성장동력