이번에는 도커위에 Python을 사용하여 Rest Api를 수신하는 서버를 만들어 볼 예정이다.

※ Rest Api에 대해서는 하기 글을 참조
2021.07.29 - [IT/아키텍처] - Rest

대략적인 아키텍쳐는 아래와 같다.

(1) 유저가 HTTP 메소드를 사용해서, 도커에 떠있는 Nginx의 api location 호출하면 ( 80 Port )
(2) Nginx Reverse Proxy를 사용하여, Python으로 Request를 포워딩 해준다 ( 82 Port )
(3) Rest Api를 구현한 Python에서 해당값을 리턴해주고
(4) Nginx는 json 타입으로 유저에게 Response 해줄 계획이다.

 


1) Python Rest Api Server 구성

 

[참조] - https://justkode.kr/python/flask-restapi-1 // Flask로 Rest API 구현하기

 

- Docker 위에 Pyhton 및 라이브러리 설치 

  ※ 이미지 생성 및 프록시 세팅부분은 생략하고 작성

 

ㅁ Python 설치

apt-get update
apt install python3

[설치확인] python3 --version

 

ㅁ Pyhton 라이브러리 설치를 위한 pip 설치

 

apt-get update
apt-get install python3-pip

=> 설치중에 커넥션 에러 발생. security.ubuntu는 접근하나, archive.ubuntu 에는 접근 못하는 것으로 추정

Get:116 http://security.ubuntu.com/ubuntu bionic-updates/main amd64 python3-xdg all 0.25-4ubuntu1.1
[31.3 kB] Fetched 105 MB in 1min 6s (1586 kB/s)
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/i/isl/libisl19_0.19-1_amd64.deb Could not connect to XXXXX

=> ubuntu repository를 변경하자. ( mirror.kakao.com )

 

vi /etc/apt/sources.list
=> 편집창에서 :%s/archive.ubuntu.com/mirror.kakao.com

apt-get update
apt-get install python3-pip

- Flask 다운로드

 

Flask : Micro web framework로 직역하면 가볍게 사용할수 있는 웹 프레임워크다.

         간단한 rest api 서버 혹은 Web 서버 구성시에 사용한다.

 

pip3 install Flask

이제는 익숙한 프록시, SSL 오류.

 

1) 구글링하니, trusted host 옵션을 주라고 한다.

   => 동일 에러

pip3 install --trusted-host pypi.python.org flask

 

2) 블로그에 프록시 컨피그 적용 후, 수행 가이드

pip3 install --proxy your_proxy_path Flask

=> SSL 문제로 URL 접속 불가 이슈

==>VM 환경이 아닌, 로컬 환경에서는 인터넷 접속 이상없음

 

1,2 옵션을 동시에 주면된다. 

- 프록시를 통해 패키지 Install

- SSL 없이, python host에 대해서는 신뢰

 

-> Flask 및 dependency 패키지 다운로드 성공

 

같은 방법으로 Flask-restx 도 설치해준다.

 

 

- Rest Server Code 작성

 

from flask import Flask  
from flask_restx import Api, Resource 

app = Flask(__name__)  
api = Api(app)  


@api.route('/api/users')  # /api/user 에 클래스 매핑
class HelloWorld(Resource):
    def get(self):  
        return {"id": 123,
        "name": "kim"}

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=80)

 

- 컨테이너 이미지로 커밋하고, 포트 매핑해서 다시 띄워보자

 

sudo docker commit $Container_ID sk007001/rest_api:python

sudo docker run -p 80:80 sk007001/rest_api:python python3 /python/rest_api.py
[ -p ] : 호스트의 80 포트로 오는 요청을 해당 컨테이너 80포트로 연결
[ python3 /python/rest_api.py ] : 위에 만들어둔 rest api 코드 실행

 

- RestClient 를 사용하여, 리퀘스트를 던져보자

 

 

※ 보완할 점

 

- 컨테이너 수행시 명령어가 너무길다.

  이미지에 수행될 명령어를 미리 지정하여, 컨테이너만 수행해도 rest_api 서비스가 올라가도록 변경해볼 것

 

- DB 연결후, /api/users 뒤에 파라미터값에 따라 다른 값을 리턴하는 로직 구현

 

- Nginx 리버스 프록시 기능을 활용하여 위의 그림처럼 연결할 것

MSA를 공부하다보면, 서비스간에 REST Api로 통신한다고 나와있다.

여기서 말하는 REST의 정의는 무엇인지 찾아보고, 구현해보려한다

 


REST

자원자원에대한 주소를 지정하는 방법에 대한 아키텍쳐이다.

REST 아키텍쳐를 따르는 시스템을 Restful, API 통신을 Rest Api 라고도 한다.

 

 


특징 6가지

1) Uniform (유니폼 인터페이스)
2) Stateless (무상태성)
3) Cacheable (캐시 가능)
4) Self-descriptiveness (자체 표현 구조)
5) Client - Server 구조
6) 계층형 구조

 

1) 유니폼 인터페이스

 

URI로 지정된 리소스에 대해, 통일된 인터페이스로 수행되는 것을 의미한다.

 

나같은 경우는 통일된 (Uniform) 인터페이스라는 표현의 이해가 어려웠는데,

클라이언트의 환경 ( 플랫폼 / 프로그래밍 언어 )에 종속되지 않는 느슨한 결합 ( Loosly Coupling ) 아키텍쳐가 더 이해하기 쉬웠다.

 

 

2) 무 상태성

 

서버단에서 상태 정보(컨텍스트)를 저장하지 않음을 의미한다.

 

세션이나 쿠키같은 정보를 저장하지않고, Request에 대해 들어온 요청대로 수행하기만한다.

요청에 대해 History 고려 및 정보 저장이 필요없으므로, 구현이 간단해진다는 장점이 있다.

 

 

3) 캐시 가능

 

HTTP 메소드를 사용하기에, 기존 캐시 기능을 그대로 사용할 수 있다.

 

Last-Modified 혹은 E-tag를 사용하여 데이터 갱신유무를 파악하고, 변화가 없으면 클라이언트의 자체 캐시값을 활용한다

 

※ HTTP Cash 프로세스
- 리퀘스트 헤더에 Last Modified를 포함하거나, E-tag를 사용하여 보낸다 ( E-tag가 우선됨 )

1) Last Modified 값을 If-modified-Since 헤더에 포함시켜, 서버측의 시간과 비교한다.
2) E-tag 값을 If-None-Match 에 포함시켜, 서버측의 값과 비교한다
=> 값이 같다면 304 Not Modified 리턴코드를 응답하고, 클라이언트는 가지고있는 캐시값을 사용한다.

 

4) 자체 표현 구조

 

리퀘스트만 보고도 무슨 내용인지 직관적으로 파악이 가능해야한다.

 

예를들어, GET http://localhost/customer/123 라는 리퀘스트가 있다고 하자.

단번에 회원중에 키값(회원ID)가 123인 사람을 조회하는 GET 메소드 라는것을 알 수 있다.

 

 

5) 클라이언트 - 서버구조

 

API를 통해 요청하고, 인증이나 컨텍스트 정보를 직접 관리하는 Client 와

접근가능하도록 API를 제공하는 Server 역할로 나누어 독립적인 개발이 가능하도록 한다.

 

 

6. 계층형 구조

 

클라이언트 입장에서는 Api를 통해 서버로 요청하지만,

서버 내부적으로 다양한 계층을 지닐수 있다.

 

스위치 , WEB 서버등을 통해 사용자 인증, SSL, 로드밸런싱 등을 구현할 수 있으며

Apache Reverse Proxy나 HA Proxy 등을 통해 Host 분리없이 구현할 수 있다.

 


구현 가이드

 

1. 자원에 대한 행위는 CRUD를 사용한다.

 

Create - [HTTP Post] 해당 리소스를 생성한다.
Read   - [HTTP Get] 해당 리소스를 조회한다.
Update - [HTTP Put] 해당 리소스를 수정한다.
Delete  - [HTTP DELETE] 해당 리소스를 삭제한다.

 

2. URI는 정보를 표현해야한다. ( 명사형 )

 

1번과도 연관된 내용이다.

동사는 CRUD로 제한하고, 나머지 자원에 대한 정보는 모두 명사로 표시한다.

 

 

3. /로 리소스 계층을 식별한다

 

ex ) GET http://localhost/customer/123

      마지막에 /는 혼동을 줄수있기에 넣지 않는다.

 

 

4. 모든 경로에는 소문자를 사용한다.

 

대소문자에 따라 리소스를 다르게 인식하기 때문에, 대문자는 사용하지 않는다.

 

 

5. 하이픈 ( - )을 통한 가독성 

 

언더바 ( _ )는 환경에 따라 보기 힘들수도 있기때문에,

URI 내의 가독성을 높이고 싶으면 하이픈을 사용한다.

 

ex) GET http://localhost/vip-customer/123 ( O )
    GET http://localhost/vip_customer/123  ( X )


※ HTTP Response Code

 

Rest Api를 통해 리퀘스트에 단순 응답만 하는것이 아닌

다양한 Response Code 들을 통해, 처리결과를 좀더 정확하게 회신주어야한다.

 

대표적인 값은 

2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다
 - 200 : 클라이언트 요청을 정상적으로 수행함
 - 201 : 서버가 요청한 리소스 생성작업을 성공함

3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
 - 301 : 사용자가 요청한 페이지에 대해 URI가 변경되었다.

4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다
 - 400 : 사용자가 요청이 어떤것인지 인식하지 못했을 때
 - 401 : 사용자의 권한이 부족하거나 인증이 완료되지 않음
 - 403 : 금지된 리소스에 사용자가 접근할 때
 - 404 : 존재하지 않는 리소스를 요청했을 때
 - 405 : 잘못된 메소드로 서버에 요청했을 때

5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다
 - 500 : 내부 서버오류로 인해 요청 수행 불가

 

https://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C

 

HTTP 상태 코드 - 위키백과, 우리 모두의 백과사전

아래는 HTTP(하이퍼텍스트 전송 프로토콜) 응답 상태 코드의 목록이다. IANA가 현재 공식 HTTP 상태 코드 레지스트리를 관리하고 있다. 모든 HTTP 응답 코드는 5개의 클래스(분류)로 구분된다. 상태 코

ko.wikipedia.org

 

 

[참조]

https://meetup.toast.com/posts/92

'IT > 아키텍처' 카테고리의 다른 글

MSA ( MicroService Architecture )  (0) 2021.07.13
Monolithic  (0) 2021.07.03

이번에는 Hello Wolrd를 출력하는 웹페이지를 만들어보려고 한다.

다양한 방법으로 만들어볼껀데, 아래 3가지 방식으로 구현 할 것이다.

1) front 페이지만 만들고, nginx 이미지를 받아 페이지만 적용
2) 제로 베이스에서, 우분투위에 Nginx를 올려 커스텀 이미지를 만드는 방식
3) Docker File을 통한 구현

 

1) Nginx 이미지에 home 화면만 바꾸어서 적용

 

- 홈 화면인 index.jsp 페이지 작성

 

- Nignx 이미지 다운로드 및 사용법 확인

 

나처럼 페이지 컨텐츠만 바꿔서 띄우려는 사람들이 많았는지, 설명 가장 위에 적혀있었다.

$ docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx

※ 옵션

--name : 컨테이너의 이름을 지정

-v : {PATH1}:{PATH2} Host의 디렉토리를 Conatiner에 마운트

 

 

여기에 Host:Conatiner 포트매핑만 해서 가동시켜보겠다.

sudo docker run --name hello-nginx -v /docker:/usr/share/nginx/html:ro -p 80:80 -d nginx

 

 

이상하게 페이지 접근시, 화면이 나오지 않고 파일 다운로드가 된다.

 

jsp 확장자를 인식못하는것 같아, html로 변경해보고 다시 접근해보려한다

 

sudo docker exec -it $Container_ID /bin/bash  
=> 해당 컨테이너에 접속

 

접속해서 해당 컨텐츠 확장자 변경하려했으나, 컨테이너 내부에서는 Mount 된 디렉토리 內 변경 불가

 

Host 에서 직접 변경 및 컨테이너 내부에서 변경된 것 확인

 

 

변경후에 잘 되는것 확인


2) 커스텀 이미지 만들기

 

우분투 기반의 Hello World2를 출력하는 커스텀 이미지를 생성하려한다.

 

 

- 베이스이미지 ( 우분투 ) pull

 

docker run -it --rm --name hello_nginx_v2 ubuntu:18.04

 

- 컨테이너 내에 nginx 설치

 

apt-get install nginx

 

nginx 패키지를 못찾았다... 패키지 인스톨시에는 저장소 업데이트를 항상 먼저해주자

 

??? 

저장소에 접근을 못하고있다. 프록시 문제로 예상된다

2021.06.30 - [IT/도커도커] - (1) Ubuntu에 도커 설치하기 - 프록시 설정 참조

 

기존 VM Host에는 프록시 설정을 해주었으나

Conatiner는 새로운 Ubuntu OS를 띄운셈이므로, 다시 적용해주어야한다.

 

그런데 우분투 컨테이너에는 기본 편집기가 없다 ( nano, vim 등등 )

그래서 귀찮지만 conf.d 파일을 Host 에서 Container로 옮겨줘야한다.

sudo docker cp /etc/apt/apt.conf.d/90curtin-aptproxy hello_nginx_v2:/etc/apt/apt.conf.d/

 

 

프록시 설정 완료후, 저장소 업데이트 및 nginx Install

 

Index.html 파일 변경

 

sudo docker cp /docker/index.html hello_nginx_v2:/usr/share/nginx/html

 

 

컨테이너 Commit 하여 이미지 생성

 

sudo docker commit hello_nginx_v2 sk007001/hello-world:v0.2

 

 

컨테이너 수행

 

sudo docker run -p 80:80 -d sk007001/hello-world:v0.2

 

 

이미지 Hub에 Push

 

정상 동작하는것을 확인했으니, Hub에 올리자

 


3) Dockerfile를 통한 구현

 

FROM ubuntu:18.04

RUN apt-get update
RUN apt-get install -y nginx

ADD /docker/index.html /usr/share/nginx/html

EXPOSE 80

WORKDIR /etc/nginx

CMD ["nginx", "-g", "daemon off;"]

 

FROM : ubuntu를 베이스로 지정

 

RUN apt-get update : ubuntu 패키지 리스트를 업데이트

RUN apt-get install -y nginx: nignx 패키지를 인스톨 ( 모든것에 동의함. -y )

 

ADD : Host에 만들어둔 index 파일을 컨테이너로 복사

 

EXPOSE : 컨테이너의 80포트로 접속할 수 있게 오픈

 

WORKDIR : 커맨드 실행할 Path 지정

 

CMD : nginx를 백그라운드로 실행

 

 

- Docker Build

 

 

패키지 업데이트 실패하였다...

프록시 설정안해줘서 일텐데, 매번 설정해주기 귀찮다. 디폴트 지정하는법이 있는지 찾아봐야겠다.

 

일단 수동으로 옮겨주자.

- 프록시 컨피그 파일을 컨테이너로 수정

 

ADD /etc/apt/apt.conf.d/90curtin-aptproxy /etc/apt/apt.conf.d/

 

 

해당 파일을 못찾는다고 나온다.

/Docker 에서 빌드했는데 하위 디렉토리에서 파일을 못찾은듯 하다.

 1) /에서 빌드하고 image Path 수동지정

 2) 해당 파일들 /Docker 하위로 이동

 

2번 방법을 사용해서 진행하자

 

 

이번에는 호스트의 81포트를 열어서, 컨테이너 80포트로 연결해주자

 

sudo docker run -p 81:80 -d sk007001/hello-world:v0.3

 

 

정상적으로 컨테이너가 올라갔으나, 404 not found 발생

 

1) index.html 파일 부재

 

- sudo docker exec -it bfe /bin/bash 접속
- /usr/share/nginx/html 밑의 커스텀 index 파일 확인
- 존재하는 것 확인

2) root 디렉토리 확인

- 컨테이너의 nginx conf 확인 ( /etc/nginx/nginx.conf -> /etc/nginx/sites-enabled/default )
- root : /var/www/html로 되어있는데 혹시 이거때문에...?

- root 디렉토리 위치를 /usr/share/nginx/html로 바꾼후 nginx reload 수행

 

- 81포트/index.html 접속

 

먼저 Hello Wolrd 출력부터 해보려고 한다

 

마찬가지로 아래 2가지 방식으로 구현할 것이다.

1) 이미 만들어져있는 이미지 사용
2) Docker File을 통한 커스텀 이미지 생성

 

1) 기존 이미지 사용

 

https://hub.docker.com/ 에 가면 다양한 도커 이미지들을 볼 수 있다.

그중에서 도커 공식이미지인 Hello-world 이미지를 살펴보자

 

hello-world 이미지

아무런 태그를 달지않으면 latest 태그가 받아질 것이고,

어떤 태그들이 있는지도 확인할 수 있다.

 

Hello-world Tag

기본 이미지, 사용방법 등의 설명페이지가 있지만,

간단한 Hello-world 이미지이기때문에 바로 수행해볼 것이다.

 

sudo docker run hello-world

위의 간단한 명령어로, 사용 가능하다.

어떤 동작원리인지 모르는 블랙박스 형태여도, 사용할수 있다는게 장점이기도 하다.

 

run 명령어 수행시, Host PC에 이미지가 없어서 hub.docker 에서 이미지를 가져오는 모습이다.

Tag는 따로 지정해주지 않아, Default 인 latest 태그 이미지를 가져온다.

 

 

2) Docker File을 통한 커스텀 이미지 생성

 

먼저, Docker File 기본 구성에 대해 알아보자.

 

- From : base 이미지 지정
- ADD : 로컬,URL에서 파일이나 디렉토리를 컨테이너로 복사할때 사용
- COPY : ADD와 같은 기능이나 URL에서 가져올 수 없고, 압축파일도 해제없이 그대로 복사된다.
- LABEL : key=value의 기타 정보를 이미지에 심을 떄 사용
            메타정보라고 넘어갈 수 있지만, 후에 쿠버네티스 사용 시 필요한 항목이니 유의
- ENV : 컨테이너에 적용할 환경변수 사전 정의
- ARG : 컨테이너 빌드시 사용할 아큐먼트 정의
- EXPOSE : 호스트와 연결할 포트 번호를 설정
- VOLUME : 호스트 디렉토리 마운트. 
- RUN : 이미지 생성 시, 실행할 Command 지정
- CMD : 이미지 생성 이후, 처음으로 실행될 명령어. 여러개의 CMD 작성시, 마지막 CMD만 적용
- ENTRYPOINT : 이미지 생성 이후 실행될 명령어.
 
 ※ Command 문법

RUN/CMD/ENTRYPOINT ["command","parameter1","parameter2"]

※ CMD와 ENTRYPOINT 차이

 

ENTRYPOINT는 DockerFile에 지정된 그대로 명령을 수행하지만,

CMD는 인자값을 주게되면 해당 인자값으로 명령을 수행한다.

 

 

Hello World DOCKER FILE

 

- Dockerfile 생성

 

FROM alpine:3.14  # 우분투 말고, 도커 베이스이미지로 많이쓰이는 알파인을 사용하였다. ( 5MB 정도 )

CMD ["echo","Hello-World"] # 이미지 생성후 Hello World 출력

 

- 이미지 빌드

sudo docker build -t sk007001/hello-world:v0.1 /docker

-t <이미지명:tag명> <Dockerfile 위치> 명령어로, Dockerfile 기반의 이미지를 태깅하여 빌드하였다.

앞의 sk007001은 개인 hub 저장소 위치를 명시해주었다.

 

 

- 이미지 확인 및 컨테이너 생성

 

sudo docker images

 

sudo docker run sk007001/hello-world:v0.1

 

- 해당 Image 저장소에 Push

 

잘 동작하는것을 확인했으니, 저장소에 Push 하려한다.

sudo docker push sk007001/hello-world:v0.1

 

'IT > 도커도커' 카테고리의 다른 글

(6-1) 도커 內 Rest Api 서버 구성하기 ( Python )  (0) 2021.08.11
(5) 도커 Hello World - 웹페이지  (0) 2021.07.22
(3) 도커 명령어  (0) 2021.07.19
(2) 컨테이너 및 도커  (0) 2021.07.14
(1) Ubuntu에 도커 설치하기  (0) 2021.06.30

도커 아키텍처


Docker run

 

클라이언트 환경에서 Docker run 수행시, Host의 Docker daemon과 통신한다.

UNIX 소켓 또는, 네트워크로 연결되며 REST API를 사용해 리퀘스트를 보낸다.

 

Run 프로세스

 

- docker run <option> $Image:tag <command>

1) Docker_Host 내에서 해당 이미지:태그를 찾는다
2) 없으면 레지스트리에서 이미지:태그를 다운받아온다
3) 이미지를 사용하여 컨테이너 실행
4) 컨테이너에서 명령 수행

 

Run 옵션

 

주로 사용하는 옵션들을 정리해보았다.

 

-d : 컨테이너를 백그라운드로 수행

-e : 컨테이너 내의 환경변수 지정

    --env-file : 환경변수 파일을 지정하여 컨테이너 수행

-i : 표준입력(stdin)을 컨테이너와 연결하여, 명령어를 작성할 수 있게한다.

    주로 -t 옵션과 같이써서, bash 명령어 수행가능하게 한다.

--name: 컨테이너에 이름을 지정하여, 관리가 쉽게한다.

-p : 호스트로 접근하는 특정 포트를, 컨테이너 포트와 매핑시켜준다 ( 프록시, 포워딩 )

     ex) -p 80:8080 / 80포트로 호스트에 접근하는 리퀘스트를, 컨테이너의 8080포트로 연결해준다.

--rm : 컨테이너 수행이 완료되면, 자동으로 삭제한다.

-v : 호스트의 파일시스템을 컨테이너에 마운트한다.

 


Docker ps

 

현재 수행중인 컨테이너 목록. -a 옵션을 통해 종료된 컨테이너까지 확인할 수 있다.

 

Docker Images

 

현재 Host PC에 저장된 이미지 목록 확인

 

Docker Stop/Start $Contianer_ID

 

컨테이너 종료 및 종료된 컨테이너 수행

 

 

Docker rm $Container_ID

 

Host PC 내에서 컨테이너 삭제

 

Docker rmi $Container_ID

 

Host PC 내에서 이미지 삭제

 

 

Docker search $Image_name

 

Docker Hub내에서 해당 이미지 검색

 

 

Docker pull $Image:$tag

 

해당 이미지 다운로드. Run 명령어에는 pull 및 수행 명령단계가 포함되어있다.

 


※ docker pull 이슈 발생




Pull 리퀘스트 횟수 제한에 걸림

- 도커의 경우, 구독 유저가 아니면 리퀘스트 제한이 있는데 ( 익명 100회 / 로그인 200회 . 6시간 기준 )
  프록시 IP를 쓰다보니, 다른 사용자들로 인해 리퀘스트 제한에 걸렸다.

- login 하여, 계정을 통한 리퀘스트로 문제 해결

 

 

'IT > 도커도커' 카테고리의 다른 글

(5) 도커 Hello World - 웹페이지  (0) 2021.07.22
(4) 도커 Hello World  (1) 2021.07.20
(2) 컨테이너 및 도커  (0) 2021.07.14
(1) Ubuntu에 도커 설치하기  (0) 2021.06.30
(0) Oracle VM 을 통한 Ubuntu 서버 설치  (1) 2021.06.29

도커에 대해 설명하기전에 컨테이너 개념에 대해서 먼저 알아야한다.

컨테이너 : 리눅스 커널을 공유하여, 프로세스를 격리된 공간에서 띄우는 기술

 

비슷한 용어로 가상화가 있지만, 둘의 의미는 다르다.

 

먼저 가상화 같은경우

컴퓨터 리소스의 추상화라는, 좀더 넓은 의미를 가지고있다.

 

하지만 주로 Hypervisior를 구동하여 가상머신 ( Virtual Machine ) 을 생성하는 논리적 플랫폼 기술을 의미한다.


VM은 리소스의 추상화와 격리가 되어있지만, 크나큰 단점이 하나 있다.

 

바로 Geust OS의 중복이다.

VM 아키텍처

VM을 하나 생성해, 격리할때마다 Gesut OS 위에 Application을 올리므로

Guest OS 만큼의 리소스가 중복으로 낭비되고 있다.

 

이러한 특징은 MSA ( MicroService Architecture )가 떠오르면서, 큰 단점이 되었다.

2021.07.13 - [분류 전체보기] - MSA ( MicroService Architecture )

 


MSA에서 수백 수천개로 나뉘는 서비스를 위해, 효율적인 리소스 활용은 필수가 되었고

운영체제 수준의 가상화리눅스 커널을 공유하는 컨테이너 기술이 떠오르게 되었다.

 

컨테이너는 모든 컴포넌트마다 OS를 가상화하는것이 아니라

리눅스 커널을 공유하고, APP 단위로 가상화하여 구분하는 개념이다.

 

각 컨테이너는 Cgroup, namespace 개념을 적용해, 격리 및 관리가 진행된다.

 

Cgroup


프로세스들의 격리 및 자원관리 역할을 하는 리눅스 커널 기능
cpu, 디스크, 메모리 등을 다룬다.


Namespace

각 컨테이너는 namespace 단위로 리소스가 관리된다.

(1)  Mnt(파일 시스템 마운트) : 파일시스템 포인트 관리
(2)  Pid(프로세스) : 독립적인 프로세스 공간을 할당
(3)  Net(네트워크) : 네트워크 인터페이스. namespace 간에 network 충돌을 방지 (중복 포트 등)
(4)  Ipc(System IPC) : 독립적으로 프로세스 간의 통신 관리 ( Sahred memory, semaphore 등 )
(5)  Uts(hostname) : 독립적인 hostname 할당
(6)  User(UID) : 독립적인 사용자 할당

 

그중, 대표적인 오픈소스 프로젝트가 Docker 이다.

 

도커 아키텍처


도커 이미지

 

 

이미지란 컨테이너 실행에 필요한 파일과 설정 값등을 포함하고 있는 읽기전용 템플릿이다.

( ex: Ubuntu 이미지에는, Ubuntu 구성을 위한 파일과 환경변수값들이 저장되어있다 )

 

 

특징으로는,

 

1) 변하지 않는다.
2) 하나의 이미지로 여러개의 컨테이너를 구동할 수 있다.
3) Dockerfile을 bulid하면 Image가 생성되고, Image 를 run 하면 컨테이너가 생성된다.
4) Git 처럼 Docker Hub를 통해 쉽게 관리할 수 있다 ( Pull & Push )
5) 레이어 개념을 적용해, 이미지 다운로드시 불필요한 작업을 줄인다

 

※ 도커에서 이미지를 만드는 방식 ( 레이어 )

 

- 여러개의 레이어를 겹쳐서 하나의 F/S처럼 동작하는 이미지를 만든다.

 

예를들어, Hello World를 출력하는 웹페이지를 서비스하는 Image를 만든다고 가정하자.
Base Image를 기반으로, ubuntu OS 레이어와, Nginx 레이어를 올려 하나의 이미지를 만들 것이다.

이 이미지를 누군가 다운받아, Hello Wolrd2라는 image를 만들었을때
index.jsp 내용만 바뀌었을뿐인데 전체 레이어를 다시 받을필요가 없다.

변경된 index.jsp 에 해당하는 레이어만 다시 받음으로써,
Hello World2 이미지를 사용할 수 있다.

 

 

도커의 장점

 

어느곳에서든 동일한 환경을 유지할 수 있다.

  - 개발서버가 존재하여, 운영과 동일환경에서 개발하는 경우는 드물다고 생각된다.

    보통 로컬PC 에서 개발하고, 해당 소스를 시스템에 반영할텐데 몇 가지 문제가 예상된다.

     

   1) 가장 먼저, 로컬PC (윈도우) 에서 만든 서비스는, 시스템 (리눅스)에서 호환되지 않을 가능성이 높을 것이다.

   2) 로컬PC의 환경변수 세팅과 시스템의 환경변수가 다르기 때문에, 동일 아키텍처라도 디플로이가 안될수도 있다.

 

컨테이너 단위로 관리

  - 하나의 OS에 다양한 컨테이너를 띄울수 있으며, 각 컨테이너는 독립된 환경이기 때문에

    다양한 서버들을 운영할 수 있다. ( 자바, 파이썬, 오라클 등등 )

 

유연한 자원관리

  - 고정된 자원을 할당받는것이 아니기 때문에, 자유롭게 Scale up/out 이 가능하다.

 

'IT > 도커도커' 카테고리의 다른 글

(5) 도커 Hello World - 웹페이지  (0) 2021.07.22
(4) 도커 Hello World  (1) 2021.07.20
(3) 도커 명령어  (0) 2021.07.19
(1) Ubuntu에 도커 설치하기  (0) 2021.06.30
(0) Oracle VM 을 통한 Ubuntu 서버 설치  (1) 2021.06.29

MSA란?

 

MSA에 대한 공식적인 정의는 찾을 수 없었다.

그래서 나름대로 MSA의 특징이라고 생각되는 것을 적어보았다.

- 서비스가 작게 나뉘어져있어야하고, 개별 서비스는 독립적인 배포가 가능해야한다.
- API를 통해 각 서비스간 통신한다.
- 각 서비스간 영향도가 최소화 되어야한다.
  ※ DB조차도 중앙관리 될 필요가 없으며, 개별 서비스가 DB를 소유한채 API를 통해서만 데이터를 가져온다.

장점

앞서 작성했던 Monolithic의 단점이, MSA의 장점이 될 수 있다.

( 2021.07.03 - [IT/아키텍처] - Monolithic )

 

다른 서비스들에 영향을 끼치지 않음

  - 독립적인 서비스 구성으로, 배포 실패나 장애 발생시에 시스템 전체에 영향을 끼치지 않는다.

 

요구사항의 빠른 반영이 가능하다

 - 다른팀의 개발을 기다릴 필요없이, 빠르게 개발 및 테스트를 진행할 수 있고, CI/CD가 가능하다.

  ※ CI ( Continuous Integration ) : 지속적 통합으로, 코드의 변경사항이 형상관리 시스템에 계속 반영되어 품질을 유지
                                             개발 / 테스트 / 병합 단계를 의미


     CD ( Continuous Deploy 혹은 Delivery ) : 지속적 서비스 제공 또는 배포. 테스트 및 운영서버로 자동 배포를 의미.

 

배포시간의 감소

  - 기존 Monolithic에서는 몇십, 몇백GB 짜리 소스코드를 디플로이 하느라 시간이 오래걸린다.

    해당시간동안 서비스가 불가능하다는 의미이기도 하며, Time out 으로 디플로이가 실패할 수도 있다.

    

    하지만 MSA에서 소스코드 용량은 KB,MB 단위이기때문에 배포에 오랜시간이 걸리지 않는다.

 

다양한 형태의 아키텍처

  - 각 서비스간에 프로그래밍 언어나 프레임워크에 엮여있지 않아, 다양한 아키텍처 구성이 가능하다

   

 


단점

 

시스템 복잡도 상승

  - 위의 다양한 컴포넌트들에서 보이듯,  각 서비스별 관리에 있어 어느정도 컴포넌트에 대한 지식이 필요하다.

 

성능 하락

  - 서비스간 통신을 모두 API를 통해 진행하기 때문에, latency 및 네트워크 비용 발생

 

데이터 정합성

  - 데이터가 단일 DB가 아닌, 개별 서비스에 종속되어 있기때문에
    관리가 어렵고 정합성 문제가 발생할 수 있다.

'IT > 아키텍처' 카테고리의 다른 글

Rest  (0) 2021.07.29
Monolithic  (0) 2021.07.03

Monolithic ?

 

MSA에 대해 정리하기 전에, 반대되는 개념인 Monolithic을 살펴봤다.

 

흔히 우리가 개발할때 하나의 war나 directory로 묶어서 배포하는 방식을 의미한다.

 

쇼핑몰 홈페이지를 구축한다고 가정하여, Monolithic의 단점과 왜 MSA가 떠오르게 되었는지 서술하려한다.

 

 


 

조그마한 변경도, 시스템 전체에 영향을 줄 수 있다.

프로젝트로 회원가입, 로그인, 장바구니, 구매등의 기능이 있는 홈페이지를 하나 만들었다고 가정하자.

 

고객으로부터 포인트 서비스를 개발해달라는 요청을 받아, 아래와 같이 프로세스를 진행하는 중이다.

 

요구사항 분석 - 설계 - 개발 - 빌드 - 테스트

 

오랜시간에 걸쳐 테스트까지 완료되었고, 운영서버에 배포하고 서비스를 확인하려 했으나...

 

 

다른쪽 코드는 건들지도 않았는데, 메인페이지부터 모든 서비스가 안되기 시작한다.

 


강력한 결합으로, 컴포넌트의 변경이 다른 컴포넌트에 영향을 미침

 

고객 요청사항을 위해, 로그인 방식을 바꾸려고 한다.

 

이 기능은 시스템의 자바버전으로 구현이 어려워서, 버전을 올리고 코드를 반영했다.

 

배포 후, 기능이 잘 동작하는것에 미소짓고 있었는데...?

 

회원가입이 안된다는 VOC가 마구들어오고 있었다.

 

회원가입 중 일부기능이 신규 자바버전과 호환되지 않는 탓이었다.

 


 

고객의 요구사항 반영이 늦어짐

 

크게 데인 우리는, 기준을 높여 배포를 진행하기로 하였다.

 

1) 코드 변경 시, 엄격한 영향도 조사

2) 특정 서비스를 개발도중에, 관련 서비스까지 모두 타팀에서 건들지 말 것

3) 최소한의 서비스 중단을 위해, 고객들이 이용하지 않는 저녁시간 이후에 배포할 것

 

이후에, 하나의 요구사항 반영에는

개발 및 테스트시간보다 기타 절차들에서 시간이 더 걸리게되었고, 우리는 고객들의 불만에 시달렸다...

 

 


배포시간의 증가

 

시간이 지나 우여곡절끝에,  시스템은 안정화되었고 평화로운 나날을 보내고 있었다.

 

어느날 간단한 소프트웨어 패치로, 배포를 하게되었는데

 

반영버튼을 누른뒤로, Admin 페이지는 모래시계만 돌고 서비스도 계속 작동을 하지 않았다

 

특별한 에러로그는 없이, 계속 서비스는 내려가있었고 결국 프로세스를 재시작하기로 하였다.

 

가동하면서 로그를 봤는데 웬걸. 너무나 시스템이 커져버린탓에 몇 십분씩 걸리는 거였다.

 

(1)번째 서비스가 가동되었습니다. ( 19:33 )
(2)번째 서비스가 가동되었습니다.
                     ·
                     ·
                     ·
(153)번째 서비스가 가동되었습니다. ( 19:45 )

개별 프레임워크 구성이 어려움

 

고객 요청으로 154번째 서비스를 추가하려고 한다.

 

마침 쉽고 효과적으로 적용할 수 있는 오픈소르를 찾았고, 기쁘게 관련 문서를 뒤져봤는데.....

 

호환 언어 : Python

 

'IT > 아키텍처' 카테고리의 다른 글

Rest  (0) 2021.07.29
MSA ( MicroService Architecture )  (0) 2021.07.13

- 다운로드전 필요 패키지 설치

 

sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  • apt-transport-https : 패키지 관리자가 https를 통해 데이터 및 패키지에 접근할 수 있도록 한다.
  • ca-certificates : 인증서 기반의 SSL 통신을 가능하게 해준다.
  • curl : 서버와 통신할수 있는 커맨드 툴
  • software-properties-common : 개인 소프트웨어 패키지 저장소.
                                            우분투 공식 저장소에 없는 패키지들을 받을 때 사용

- 도커 저장소 및 Key 추가

 

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

 

  • s ( slient ) : 진행로그를 표시하지 않음
  • apt-key : 패키지 인증시 사용할 키를 추가한다.

 

※ Curl 명령어 실패

 

더보기

curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
gpg: no valid OpenPGP data found.

1. https://curl.haxx.se/ca/cacert.pem 에서 인증서를 받아 적용하거나

2. -k 옵션으로 인증서 검증 스킵

 


- Repository 경로 추가하기 ( PPA )

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"

 

- apt update

 

sudo apt-get update

※ docker update 시, 인증서 에러 발생. 프록시에 사용할 인증서를 추가해주자

 

 

ㅁ 인증서를 구한다음에 openssl을 통해 crt 확장자로 바꿔준다.

openssl x509 -in ABC.pem -inform pem -out ABC.crt

 

ㅁ /usr/share/ca-certificates/extra 디렉토리 생성후, 변환된 crt 인증서 이동

 

ㅁ 인증서 패키지 reconfig후 해당 인증서 추가.

sudo dpkg-reconfigure ca-certificates 

- 도커 설치 및 확인

 

sudo apt install docker-ce
sudo systemctl status docker

 

 

 

참조 ( https://roseline124.github.io/kuberdocker/2019/07/17/docker-study02.html )

'IT > 도커도커' 카테고리의 다른 글

(5) 도커 Hello World - 웹페이지  (0) 2021.07.22
(4) 도커 Hello World  (1) 2021.07.20
(3) 도커 명령어  (0) 2021.07.19
(2) 컨테이너 및 도커  (0) 2021.07.14
(0) Oracle VM 을 통한 Ubuntu 서버 설치  (1) 2021.06.29

+ Recent posts