📖 학습주제
개발환경 구축을 위한 Docker와 K8S 실습 (5)
Docker 정리
Docker 관련 용어들
- Docker Image
- Dockerfile
- Docker Container
- Docker Hub (hub.docker.com)
- Docker Compose
- 다수의 Docker Container들을 관리
- docker-compose.yml
◦ Services
◦ Networks
◦ Volumes: host/anonymous/named volumes
Docker를 실제 Production 환경에서 사용할 때 유념할 점
- Docker volumes
- Host volume은 보통 개발시 소스코드를 바로 container안으로 마운트하기 위함
- Production에서는 named volumes를 써야함
- Docker container는 read-only로 사용
- 내용을 바꿔야한다면 실행 중인 컨테이너를 수정하지 말 것
- 항상 이미지를 새로 빌드하고 다시 컨테이너들을 새로 론치
- 자동화가 중요해짐: CI/CD 프로세스
- 다수의 Docker Container들을 다수의 호스트들에서 실행 필요
- 용량 문제와 Fail-over (혹은 fail-tolerant)
Docker를 개인 생산성을 향상을 위해서 사용
- 개발시 필요한 모듈을 Docker 이미지로 받아와서 Container로 실행
- 여러 소프트웨어를 연동해서 개발시 이 것들을 docker-compose로 설정
장점
- 일관된 방식으로 소프트웨어 설치 (문서화하고 매뉴얼하게 설치 불필요)
- 분리된 충돌없는 환경에서 소프트웨어 설치/실행
서버 관리의 어려움
복잡한 다수의 서버로 구성된 시스템을 효율적으로 관리한다는 것은 어려운 일임
관리해야하는 서버의 수가 늘어나면 생기는 문제
- 어느 서버가 문제가 있는지
- 어느 서비스가 문제를 갖고 있는지
- 이런 문제들을 얼마나 빨리 알고 해결할 수 있을지
- 새로 들어온 사람이나 주니어를 잘 온보딩하려면 어떻게 할지
- 또한 문제들은 밤낮없이 연휴에도 발생함
해결방안
문서화
- 지금 서비스 상황과 셋업 방법 문서화
- 다양한 문제 발생시 해결 방법 문서화
- 문서를 현재 상황에 맞게 업데이트하는 것은 엄청난 노력이 듦 (상황에 따라 의미가 없는 경우도 많음)
- 몇백대의 서버를 일일히 관리하고 명령을 실행한다는 것은 거의 불가능
코드로 대신함(Infrastructure As Code)
- Infrastructure As Code: DevOps 엔지니어가 꼭 알아야하는 기술
- 문서보다는 코드로 관리
- 대화형 명령보다는 자동화된 스크립트로 해결
- 다수의 서버들에 명령을 대신 실행해줌
- 다양한 툴들이 쏟아져 나옴
- Chef, Puppet, Ansible, Terraform, …
- 단점
- 배우기 어려움(Learning curve가 높음)
- 설치시 소프트웨어 충돌 문제에는 크게 도움이 안 됨
Virtual Machine의 도입
- 소프트웨어 충돌 해결을 위해 VM을 사용
- 한 Physical Server에 다수의 VM을 올리고 서비스별로 VM을 하나씩 할당
- 단점
- VM이 전반적으로 리소스 소비가 크고 느림
- 결정적으로 특정 VM 벤더 혹은 클라우드에게 종속되어 버림 (Lock-in)
Docker의 도입
- 모든 소프트웨어를 Docker Image로 만들면 어디서건 동작
- 기본적으로 리눅스 환경에 최적
- VM에 비해 리소스 낭비도 적고 실행 시간도 빠름
- 오픈소스라 클라우드나 특정업체 Lock-in 이슈도 없음
- 거의 단점이 없음 (하지만 Docker Container의 수가 늘어나면서 관리가 힘들다는 점이 부각됨)
Docker Container의 장점
- Container 생성이 쉽고 빠름 (VM 비교)
- Image를 통해 버전 관리를 하고 배포하고 문제시 롤백이 용이
- 사용 언어등의 환경에 따른 관리방법에 차이가 없음
- 개발, 빌드, 등록, 실행 절차가 일관되게 만들어짐 (Dev, Test, Production)
- 개인컴퓨터이건 프로덕션 환경이나 동일
- 오픈소스이기에 특정 클라우드 벤더나 업체와 독립적
Docker를 기본으로 서비스를 배포하는 과정

But 컨테이너의 수가 기하급수적으로 늘어남
-> Docker Container를 효율적으로 관리할 수 있는 도구가 필요함
- 다수의 컨테이너를 동시에 관리
- 놀고 있는 서버나 너무 바쁜 서버를 어떻게 알아낼지?
- 마이크로서비스의 등장으로 인한 서비스 수 증가로 어떤 서비스들이 있는지 쉽게 찾을 수 있는 방법이 필요
- 모니터링을 어떻게 할 것인가?
- 특정 서비스의 컨테이너 수를 탄력적으로 어떻게 운영할 것인가?
마이크로서비스

- 웹 서비스를 다수의 작은 서비스(microservice)들로 구현하는 방식
- 각 서비스들은 팀 단위로 원하는 언어/기술로 개발하는 자율성을 가짐
- 각 서비스들은 계약관계로 지켜야하는 책임이 있고 서비스 정보를 등록해야함
Container Orchestration
Container Orchestration
다수의 Container들을 효율적으로 관리하기 위한 도구
Container Orchestration 기능

- 한 클러스터 안에 다양한 서비스들이 공존 (DB, Web Service, Backend, …)
- 자원 요청을 받아 마스터가 자원을 할당
- 다양한 기능 제공: 배포, 스케일링, 네트워크, 인사이트 등등
소프트웨어 배포

- 서비스 이미지를 Container로 배포
- 이상이 감지되면 이전 안정 버전으로 롤백
- v1에서 v2로 배포가 되는 경우 문제가 생기면 v1으로 롤백
- Container의 수가 많을수록 큰 이슈가 됨
- DevOps 팀 관점에서 보면 가장 중요한 기능
스케일링


- 특정 서비스의 Container 수를 쉽게 늘리고 줄이는 것
- 이때 서버의 utilization(균등하게 분배)도 고려
네트워크

- 서비스가 다수의 컨테이너로 나눠지면서 이들을 대표하는 Load Balancer를 만들어주어야 함
- 서비스들간에 서로를 쉽게 찾을 수 있어야함
- 서비스 디스커버리
인사이트

- 노드/컨테이너 문제시 해결
- 서버 2의 F가 다운되면 이를 서버 3에 재실행
- F 로드밸런서 정보도 맞게 수정
- Logging/Analytics 등등의 기능 제공
- 외부 서비스 plug and play
- 전체 서비스 분석
- 시각화
- 문제 분석
K8s
Kubernetes (K8s)
- 컨테이너 기반 서비스 배포/스케일/관리 자동화를 해주는 오픈소스 프레임워크
- 클라우드나 on-prem 모두에서 잘 동작
- 어느 컨테이너이면 가능하지만 주로 Docker Container들이 대상이 됨
- 물리서버나 가상서버 위에서 모두 동작
- 가장 많이 사용되는 컨테이너 관리 (Orchestration) 시스템
- 사용회사와 커뮤니티 활동이 굉장히 많고 활발
- 모든 글로벌 클라우드 업체들이 지원
- 확장성이 좋아서 다양한 환경에서 사용됨
- 머신러닝: Kubeflow
- CI/CD: Tekton
- Service Mesh: Istio
- Serverless: Kubeless
- 다수의 서버에 컨테이너 기반 프로그램을 실행하고 관리
- 컨테이너 기반 프로그램 == Docker Container
- 보통 Docker와 K8S는 같이 사용됨
- Pod: 같은 디스크와 네트웍을 공유하는 1+ 컨테이너들의 집합
기본 구조
마스터-노드

- 노드는 물리서버이거나 가상서버
- 클러스터는 1+ 노드의 집합
- 마스터는 클러스터는 관리해주는 역할 수행
K8S 프로세스
- API Server (Container로 동작): kube-apiserver
- Entrypoint of K8S cluster
- Web UI, CLI (kubectl), API
- Scheduler
- Pods 생성과 할당 (노드들의 상황 고려 - utilization)
- Controller Manager
- 전체 상황을 모니터링하고 fault tolerance 보장
- Master는 High Availability가 중요함
- etcd
- K8S 환경 설정 정보가 저장되는 key/value 스토어로 백업됨
Controller runtime : 대부분 Docker가 사용됨
Kubectl : 커맨드라인 툴
kubectl run hello-minikube
kubectl cluster-info
kubectl get node
Pod
- K8S 사용자가 사용하는 가장 작은 빌딩 블록
- 1 Pod = 보통은 하나의 container로 구성
- 하나보다 많은 경우에는 보통 helper container가 같이 사용됨
- 같은 Pod 안에서는 디스크와 네트워크가 공유됨
- Fail-over를 위해 replicas를 지정하는 것이 일반적
- Pod는 네트웍 주소를 갖는 self-contained server