MSA

03 클라우드네이티브의 이해(CI/CD, Docker, Container)

1. 클라우드 네이티브(Cloud Native)란?

클라우드 환경에서 Application, Architecture, Infrastructure 등의 환경을 뜻합니다.
클라우드 네이티브 애플리케이션은 환경 변화에 민첩하고 능동적으로 대응하기 위해서 네이티브 환경에서 Saas(Software as a service)나 Faas(Function as a Service)형태로 서비스 되는 애플리케이션을 뜻합니다.

마이크로서비스는 2주안에 독립적으로 개발해서 배포할 수 있는 정도의 크기를 권고하여 개발 및 배포가 요청에 따라 적절히 확장되는 구조를 가질 수 있습니다.

SaaS(Software as a service)

특정 기간 혹은 특정기간만 필요한 만큼 구매하여 사용하는 주문형 소포트웨어 서비스

12팩터

SaaS가 가져야할 특성과 지켜야할 패턴들에 대한 경험을 정리하는것을 뜻하며 클라우드 애플리케이션 플랫폼인 헤로쿠(Heroku)에 등록하여 사용한 애플리케이션의 활용을 12가지로 정리한 문서입니다.

12팩터 종류

  1. 코드베이스
    원본소스를 뜻하며 소스코드 저장소 내의 원천소스를 하나 가집니다.

  2. 종속성
    프로그램에 사용하는 라이브러리들은 암묵적인 종속성을 가지면 안됩니다.

  3. 환경설정
    코드에서 사용하는 환경설정 정보는 코드가 완전히 분리되어 관리되어야합니다.
    data connection info, hostname, back-end 등

  4. 백엔드 서비스
    백엔드 서비스는 모두 리소스로 취급하며 Database나 메시지큐가 대표적입니다. 즉, 리소스 식별자 URI(User Resource Identifier)로 접근

  5. 빌드,릴리즈 및 실행
    소스코드는 빌드 릴리즈,실행단계로 격리되어 운영됩니다.

  6. 프로세스
    프로세스(process)는 무상태(Stateless)로 실행되며 상태정보를 공유하지 않아야합니다.

  7. 포트바인딩
    하나의 독립된 서비스로 동작할 수 있고 외부에서 접속할 수 있어야합니다.

  8. 동시성(concurrency)

특정 시스템에 부하가 발생시 하드웨어 스케일업을 진행하며 수용 용량보다는 프로세스의 Workload를 수평으로 확장하여 수평적 확장(scale-out)이 가능한 프로세스 모델 형태를 가져야합니다.

  1. 폐기가능(disposability)
    graceful shutdown이 보장되어야 하며 비정상적인 프로세스의 종료에도 실행 중이던 작업은 안전하게 종료되어야 합니다.

  2. 개발,테스트,운영환경의 일관성
    개발환경은 테스트나 운영 환경과도 같아야합니다. 개발에서 운영까지 배포되는 시간, 담당자, 도구의 차이로 발생하는 문제를 최소하고 지속적인 배포가 될 수 있는 환경이 되어야합니다.

  3. 로그
    로그는 Stream Event로 취급하여 애플리케이션에서 로그처리에 관여하거나 가공 및 관리하려 해서는 안됩니다.

  4. 일회성 프로세스
    일회성 작업은 구분하여 별도의 프로세스로 구성합니다. 예를 들면, 관리자 관련 작업이나 유지 보수 관련 작업으로 생겨나는 프로세스들은 별도로 분리하여 구성합니다.

2. 클라우드 네이티브 아키텍쳐

2.1. 확장가능한 아키텍처

클라우드에 최적화된 애플리케이션을 개발하고 운영할 수 있는 아키텍처를 제공합니다. 모놀리스 시스템 아키텍처 구조에서는 하나의 인스턴스에서 애플리케이션이 실행됩니다. (화면, 비즈니스로직, 데이터 처리)

2.2. 탄력적 아키텍처

Resliense Architecture란 서비스 생성-통합-배포, 비즈니스 환경 변화에 대응 시간을 단축, 오류를 예측하고 적절히 대응할 수 있는 아키텍처 구조입니다. 분산 병렬처리, 수평적 확장, 무상태 통신방식, 오류를 예측하여 실행 상태를 유지하기 위한 자동 복원 능력이 지원되어야 합니다.

장애 격리
Fault isolation은 오류 및 장애에 대한 격리이며 특정 서비스의 오류로 인해 다른 서비스까지 영향이 도달하는 것을 없애는 것입니다.

3. 클라우드 네이티브 인프라

컨테이너 기반 패키지(Container based package)란?
컨테이너 단위의 패키지입니다. 패키지 단위가 시스템 단위일 수도 있고, 서비스 애플리케이션 단위일 수도 있습니다. 컨테이너로 패키지된 단위가 실행 단위입니다.

즉, 컨테이너 단위로 독립적인 인터페이스와 물리적으로 접속이 가능한 IP와 포트를 가집니다.

리눅스 컨테이너 기술을 응용한 도커 컨테이너는 PasS(Platform as a Service) 영역에 큰 변화와 발전을 가져왔다고 해도 과언이 아닙니다. 보통 jar,war 형태로 배포를 처리했지만, 이제는 도커이미지로 컨테이너를 실행하면 쉽게 배포가 가능합니다.

동적 관리
시스템은 서비스와 추가와 삭제를 자동으로 감지하여 새롭게 추가된 서비스로 서비스 요청을 라우팅할 수 있습니다.

4. 지속적 통합과 배포

CI(Continuous Integration)
소스코드의 지속적인 통합과 배포는 클라우드 네이티브환경 구축을 위하여 중요한 요소입니다. 지속적 통합은 개발 환경에서 개발 중인 코드를 통합하고 필요에 따라 테스트로 병행 수행하는 일련의 프로세스를 발합니다.

주로, CI(Continuous Integration) 서버, 소스 관리(SCM, Soruce Code Managemet), 빌드도구(tool), 테스트 도구가 있으며 CI 서버는 빌드 프로세스가 관리하는 서버입니다. 예를 들면, 젠킨스를 들 수 있습니다.

소스 저장소는 소스코드의 형상을 관리하는 시스템으로 Git을 들 수 있습니다.

지속적 배포

지속적 배포에는 Continuous Delivery와 Continous Deployment 두가지 유형으로 나뉘고 실행 환경으로 배포하기 직전상태인 배포형태와 실행환경까지 자동으로 배포하는 환경입니다.

카나리배포와 블루그린배포

빌드된 소스를 릴리스하는 데에는 카나리(Canary) 배포와 블루그린(Blue-Green) 배포의 두가지 대표적인 유형이 있습니다.

카나리 배포같은 경우 새 버전의 서비스를 일부 사용자들에게만 배포하여 정상 유무를 확인하는 전략이고, 블루그린 배포는 운영과 같은 환경이 하나 더 있고 한쪽 새로운 버전을 배포하여 사용자의 연결 요청을 새버전 서비스로 라우팅을 유도하여 문제가 없으면 이전 환경의 사용을 중지하는 방식입니다.

5. 데브 옵스(DevOps)

데브옵스(DevOps)는 애플리케이션과 서비스의 개발에서 배포 운영까지 바르게 제공되는 조직의 협업문화를 뜻합니다.

6. 컨테이너(Container)

컨테이너(Container)는 운엉체제상에서 독립된 공간을 할당하고 독립된 공간끼리는 서로 격리되어 독립된 자원을 할당받고 프로세스 간 간섭이 없다면 애플리케이션 입장에서는 자신만의 공간을 가지게 되고 용도에 맞게 안전하게 실행됩니다.

즉, 마이크로서비스는 컨테이너를 단위로 묶어서 즉시 필요한 시점에 배포할 수 있는 장점을 가지고 있습니다.

프로세스 격리

격리된 공간에서 수행하는 프로세스는 다른 공간에서 동작하는 프로세스의 영향을 받지 않습니다. 네트워크자원을 분할하면 별도의 IP 어드레스를 할당하여 액세스가 가능합니다.

가상화와 컨테이너

가상화는 하이퍼바이저(Hypervisor)라는 소프트웨어를 이용하여 하나의 시스템에서 여러 개의 운영체제를 사용할 수 있게 지원하는 기술입니다. 반면에 컨테이너는 하이퍼바이저 없이 컨테이너 엔진을 통해서 가상의 격리된 공간을 생성하는 기술입니다.

7. 리눅스 컨테이너

리눅스 컨테이너는 컨테이너 기술을 적용하고 잇고, 하나의 호스트 운영체제 위에 여러개의 격리된 시스템 환경을 구성할 수 있는 운영체제 수준의 가상화 기술입니다.
네임스페이스(namespace), 컨트롤그룹(cgroups)이라는 커널기능을 사용하여 격리된 공간을 관리합니다.

8. 네임스페이스

네임스페이스는 컨테이너별로 격리된 공간을 가질 수 있도록 지원하는 기술입니다.
“PID”,“NET”, “MNT”, “UID”, “UTS”, “IPC” 여섯가지의 네임스페이스를 제공합니다.

PID(Process ID): 각 프로세스에 할당된 고유한 ID
NET(NETWORK): 네트워크 디바이스(device), IP, 포트(port), IP 테이블(table) 등
MNT(Mount): 컴퓨터 시스템에 접속되어 있는 디바이스 정보를 운영체제로 인식
UID: 네임스페이스별로 userID, group ID를 할당
UTS: 네임스페이스별로 호스트명(host name)과 도메인(domain)을 독자적으로 가집니다.
IPC(Inter Process Communication): 프로세스간 통신객체(Object)를 네임스페이스별로 할당합니다.

9. 도커 컨테이너

도커 이미지(docker image)는 하나 혹은 여러개의 이미지 레이어로 구성되어있고 도커엔진에서 사용하는 기본 단위입니다. 도커 컨테이너를 생성하는 요소로 가상 머신의 이미지 파일과 비슷하다고 생각하면됩니다.

도커는 이미지와 컨테이너라는 개념을 제시하고 있으며 이미지는 베이스 이미지(base iamge)와 도커 이미지로 개념적으로 구분할 수 있습니다.

도커 컨테이너

도커 컨테이너(docker container)는 도커 이미지를 독립된 공간을 할당하여 실행한 런타임 개체(runtime object)입니다. 도커 엔진(docker engine)위에서 기동되며 가상의 IP와 포트, 이름을 가질 수 있습니다.

도커 레지스트리

도커 레지스트리(docker registry)는 도커 이미지를 관리 할 수 있게 제공된 저장공간입니다.

도커 네트워크

도커 네트워크(docker network)는 도커 컨테이너 단위로 서비스 할 수 있도록 네트워크 환경을 제공하는 가상의 네트워크 환경입니다. 이를 가능하게 하는것은 가상의 브릿지인 docker()가 담당하며 도커 데몬이(docker demon)이 가동된후 ip가 할당되고, 도커 컨테이너별로 컨테이너별 eth()에 IP가 자동으로 할당됩니다. NIC(eth0)는 도커 내부 네트워크와 브리지 역할을 하는 docker()와 연결됩니다.

docker()은 도커 내부 컨테이너들의 가상의 NIC(veth)와 연결되어 접속할 수 있습니다. 도커 내부 컨테이너들은 각자 가상의 eth()에 IP가 자동으로 할당되어서 docker()에서는 컨테이너의 IP를 확인하여 연결 할 수 있습니다.

도커 네트워크는 NAPT(Network Address Port Translation) 기능을 사용합니다.

NAPT란?

하나의 IP를 가지고 가상의 여러 IP 및 포트와 변환하는 기능입니다. NAT(Network Address Translation)과 차이를 가지고 있는데, NAT는 공용 IP와 사설 IP와의 관계, 즉 public IP : Private IP 관계가 1:1로 변환하는 방식이라면 NAPT는 포트까지 변환하여 1:N으로 변환하는 방식입니다.

서비스 요청이 컨테이너까지 전달되는 과정

사용자 http://www.kgh.com:8080 -> eth0 8080 -> docker() -> 컨테이너 1번(80 port)

도커 컨테이너가 80번 포트로 서비스 되고 있는데 NAPT 8080 -> 80 으로 변환하는 설정이 되어 있다면 외부 사용자의 요청을 8080 호출은 NAPT 설정에 의해 80 도커 컨테이너에 연결하여 결과를 반환해줄 것입니다.