Software Engineering/Ops

[Docker] basic -> Advanced, container Orchestration

Hyunseokim 2022. 11. 17. 10:38

모르면 어렵고 알면 쉬운 도커 그리고 모르면 쉽고 알면 어려운 k8s에 대한 주니어의 ops글이다

 

 

Docker is a set of platform as a service products that use OS-level virtualization to deliver software in packages called containers.

 

도커를 한마디로 말하면 OS-level virtualization 포장 → 전달 → 실행

 

여기서 "OS-level"에 집중할 필요가 있다.

도커 없이 어떤 서버에 소프트웨어를 직접 설치 -> 아무리 간단한 소프트웨어라도 수많은 라이브러리에 의존성을 갖고 있음 -> 원하는 소프트웨어를 실행하기 위해 필요한 의존성 패키지들이 함께 설치됨 -> 문제는 여기서 시작됨, 두 소프트 웨어가 같은 라이브러리에 의존하는데 필요로하는 버전이 다르거나, OS가 업데이트 되었는데 의존성 패키지 중 하나가 업데이트 된 OS와 호환이 안된다거나, 소프트웨어를 추가/삭제/변경 할 때, 어떤 결과로 이어질 지 모름. 소프트웨어 삭제 후 의존성 패키지만 남는 상황이 반복되어 하드웨어에 쓰레기가 쌓임 등 머리아픈 문제가 발생할 수 있고 이걸 Dependency hell이라고 한다.

그래서,

도커로 소프트웨어를 배포할 때는 가상화된 OS 내에 소프트웨어를 설치하는 방법으로 이루어진다. 즉 하드웨어에 기본적으로 올라가 있는 OS와 별개로 그 안에 작은 가상 OS를 띄우고 그 안에 소프트웨어를 설치하는 것. 이렇게 배포할 소프트웨어를 위해 격리된 영역, 가상화된 OS의 영역을 컨테이너라고 한다. 

 

단, 하드웨어 레벨에서 호환이 안 되는 경우는 다른 얘기다. OS-level의 가상화이므로 그보다 Low-level에는 의존적이다.

- 예를들어 x86 위해 빌드된 도커 이미지는 arm64머신에서 동작하지 않는다.

- 어디서 빌드된건지는 중요하지 않다. 무엇을 위해 빌드되었는지가 중요하다. 

- 하드웨어가 다른건 중요하지 않고 하드웨어에서 사용하는 프로세서가(명령어셋)이 다르면 절대 안돌아간다. 로제타라든지 부가적인 무언가가 필요하다.

 

 

Docker Basic: what is docker  Dockerfile 작성법, docker 실습, docker command

Docker Advanced: Dockerfile 최적화, 볼륨, 멀티컨테이너

Container Orchestration: docker-compose, 기타(k8s, ecs, etc.)

 

Docker Basic

 

What is a container image?

When running a container, it uses an isolated filesystem. This custom filesystem is provided by a container image. Since the image contains the container's filesystem, it must contain everything needed to run an application - all dependencies, configuration, scripts, binaries, etc. The image also contains other configuration for the container, such as environment variables, a default command to run, and other metadata.

 

What is a container? 

Now that you've run a container, what is a container? Simply put, a container is simply another process on your machine that has been isolated from all other processes on the host machine. That isolation leverages kernel namespaces and cgroups, features that have been in Linux for a long time. Docker has worked to make these capabilities approachable and easy to use.

 

즉)

어떤 이미지를 돌린다(실행한다) ⇒ 그 이미지를 가지고 어떤 컨테이너를 만들어서 그걸 실행한다는 말

컨테이너   실제로 실행되는, 격리된 가상 OS의 영역

같은 이미지에서 출발한 컨테이너라도 상태가 달라질 수 있다. 이미지가 같아도 컨테이너는 다를 수 있다.

 

1. Build(포장)

- 재료: context(소스코드. 소프트웨어에 직접적으로 필요한 파일과 디렉토리), Dockerfile(해당 소프트웨어를 컨테이너로 띄우기 위해 필요한 과정을 명세한 파일)

FROM python:3.8-slim  # base image 지정 -> 이 이미지를 활용해서 새 이미지 만드는 것

COPY . /app # 현재 디렉토리를 이미지의 /app/ 디렉토리로 복사
WORKDIR /app

RUN apt-get update # 명령어 차례로 실시, 예시에선 pip을 업데이트하고 의존성 패키지들을 설치함
RUN apt-get install unzip
RUN pip install --upgrade pip
RUN pip install -r /app/requirements.txt
EXPOSE 5000

CMD ["python", "-m", "flask", "run", "--host=0.0.0.0"]
# 이 이미지가 컨테이너로 실행될 때 수행할 명령어

Dockerize

❯ docker build . -t claireline
# -t는 tag로 이름 붙혀주는 명령어

=> 결과물: 도커 이미지 (빌드된 이미지를 run하면 컨테이너가 생성, 실행된다. 후에 서술)

 

🚨 mac m1 환경 deploy error

💡 docker build image의 default architecture 때문에 이후에 ECS, EKS 등 환경에서 exec format error가 생길 수 있습니다.

💡 특히 M1 맥북을 이용하는 경우, arm64로 이미지가 빌드되어 이를 push해서 ECS에서 이용하려 할 경우 (ECS는 기본적으로 x86이기 때문에) 해당 에러가 발생할 수 있습니다.

M1 맥북 사용자의 EKS 배포 오류에 대하여

# docker default build 환경 
docker inspect <image_name>

# docker build linux/amd64
docker buildx build --platform=linux/amd64 -t <tag> .

https://docs.docker.com/engine/reference/builder/

 

Dockerfile reference

 

docs.docker.com

https://blog.d0ngd0nge.xyz/docker-dockerfile-write/

 

Docker - Dockerfile 작성 / Build (이미지 제작)

[Docker - Dockerfile Write] 인프라 구성을 관리 및 효율적으로 운영하기 위해 "Dockerfile"를 이용할 수 있으며, Dockerfile를 작성하여 사용자가 원하는 설계 방향이나 설정된 내용으로 도커 이미지를 제작

blog.d0ngd0nge.xyz

Dockerfile 작성 reference


 

 

2. Share(전달)

- 이렇게 빌드된 이미지가 있으면 어디서든 서비스를 배포할 수 있다. 이미지를 전달하기 위해 push, pull이 사용된다.

- Push: 도커 이미지를 어딘가에 올린다

- pull: 도커 이미지를 어딘가에서 가져온다(어딘가: dockerhub, ECR...)

 

3. Run(실행)

- 이미지를 run하면 컨테이너가 생성, 실행된다.

docker run claireline

✓ 도커 이미지 관련 명령어

출처. 도커. 컨테이너 빌드업

 

✓ 도커 컨테이너 관련 명령어

출처: 도커, 컨테이너 빌드업

✓ 실습

도커 설치 -> 도커 데스크탑 설치 -> docker run -d -p 80:80 docker/getting-started -> http://localhost:80에 접속

 

 

 

 


Docker Advanced

 

1. Dockerfile 최적화

- 어플리케이션을 잘 설계하여 소스도 경량화 되고, 확장성을 확보했다고 생각할 수 있지만, 어플리케이션을 감싸고 있는 컨테이너 이미지가 최적화되어 있지 않을 경우 어플리케이션의 경량화는 의미가 퇴색될 수 있다.

 

Docker - image가 저장되는 방식

 

Docker - image가 저장되는 방식

Container 는 뜻 그대로 화물 수송용 박스를 생각하면 됩니다. container에 다양한 화물을 넣고 다양한 운송수단에 적재되어 쉽게 옮길 수 있는데 서버에서도 마찬가지입니다. 서버 실행에 필요한 모

woochan-autobiography.tistory.com

이미지가 저장되는 방식을 알아야, 어떤 부분에서 캐시가 되고 새로 쓰이는지 알 수 있고 그래야 경량화가 가능하다.

- 도커 이미지를 pull 받게 되면 마치 여러개로 분리된 조각을 내려받는 것처럼 보이는데 이것이 레이어(Layer)다. 이 레이어는 도커 이미지가 빌드될 때 Dockerfile에 정의된 명령문을 순서대로 실행하면서 만들어진다. 이 레이어들은 각각 독립적으로 저장되며 읽기 전용이기 떄문에 임의로 수정할 수 없다.머신 내 어딘가 해시값으로 레이어 내용이 저장이 된다(stack)

- 도커 컨테이너가 실행되면 모든 읽기 전용 레이어들을 순서대로 쌓은 다음 마지막에 쓰기 가능한 신규 레이어를 추가하게 된다. 그 다음 컨테이너 안에서 발생하는 결과물들이 쓰기 가능 레이어에 기록되는 것.

- 그래서, 아무리 많은 도커 컨테이너를 실행하더라도 기존 읽기 전용 레이어는 변하지 않고, 컨테이너 마다 생성된 쓰기 가능 레이어에 데이터가 쌓이기 때문에 서로 겹치지 않으며 컨테이너가 종료되면 모두 사라지게 된다.

- 이게 왜 중요하냐면, 이미지를 빌드할 때마다 이미 생성된 레이어가 캐시 되어 재사용 되기 때문에 빌드 시간을 단축할 수 있기 떄문!

- 하지만 Dockerfile에 정의된 모든 명령문이 레이어가 되는 것은 아니고 RUN, ADD, COPY 이 3가지 단계만이 레이어로 저장되고, CMD, LAVEL, ENV, EXPOSE 등과 같이 메타 정보를 다루는 부분은 임시 레이어로 생성되 저장되지 않아 도커 이미지 사이즈에 영향을 주지 않는다.

 

도커 파일(Dockerfile) 작성 Best Practices

 

도커 파일(Dockerfile) 작성 Best Practices

출처 이 글은 도커 엔지니어의 포스팅을 원저자의 허락을 받고 번역한 것입니다. 적절한 번역이 떠오르지 않는 부분에는 옆에 원문을 적었습니다. 원문은 다음 링크에서 살펴보실 수 있습니다.

yeomko.tistory.com

중요하니 꼭 읽어볼 것

 

2. 볼륨

 

3.  멀티 컨테이너

- 어플리케이션은 여러개의 도커 컨테이너가 협력하면서 동작한다. docker-compose.yml은 그런 다중 컨테이너를 한꺼번에 모아서 관리해준다.

- 단점) 각 서버마다 직접 들어가서 docker run (or docker-compose up) 을 해줘야 하는 문제가 있어 서버가 수십개 이상이 되면 관리가 번거로워진다, 트래픽에 따라 컨테이너 스케일링이 불가능, 장애 발생 시 컨테이너의 로그를 직접 확인하고 재실행해야 한다.

 

- docker-compose.yml 관련 CLI

https://docs.docker.com/compose/reference/

 

Overview of docker compose CLI

 

docs.docker.com

 


Container Orchestration

 

- 오케스트레이션: 다양한 머신을 하나의 클러스터로 결합하여 오케스트라의 연주자처럼 서로 다른 각자의 역할을 쉽게 조정하고 관리 할 수 있도록 설계된 소프트웨어. 오케스트라의 지휘자처럼 컨테이너를 관리하는 것!이라 생각하면 편하다. 

- 도커 스웜, 아파치 메소스, AWS의 ECS(Elastic Container Service), google의 K8s

 

- Why? 서비스가 끊기지 않게 자동 관리해준다. 이유를 나열하자면,

- 온프레미스 환경에서 수행하는 서버 업그레이드, 패치, 백업 등의 작업을 자동화(오토 스케일링, 서비스 디스커버리, 로드 밸런싱 등)하여 인프라 관리보다는 서비스 관리에 집중할 수 있다.

- 서비스 사용자는 애플리케이션이 24/7/365 지속되기를 원한다. 컨테이너에 장애 발생 시 자가회복 기능을 통해 곧바로 복제 컨테이너를 생성하여 서비스를 지속할 수 있다.

- 컨테이너화를 통해 소프트웨어를 패키지화하면 점진적 업데이트를 통해 다운타임없이 쉽고 빠르게 릴리스 및 업데이트 할 수 있다. 

- 이러한 기능 외에도 스토리지 오케스트레이션, 자동화된 빈 패킹 등 분산 시스템을 탄련적으로 운영하기위한 프레임워크를 제공한다. 

 

 

1. docker-compose

- 정의: tool for defining and running multi-container Docker applications

즉 한번에 여러개의 컨테이너를 정의하고 실행시킬 수 있는 yml 형식의 설정 파일임

 

Docker swarm: Docker swarm is a container orchestration tool, meaning that it allows the user to manage multiple containers deployed across multiple host machines.

Kubernetes: Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications.

AWS ECS: Amazon ECS is a fully managed container orchestration service that makes it easy for you to deploy, manage, and scale containerized applications.

 

- k8s/ ECS 는 사실 비교할 수가 없다! 엔진과 서비스기 때문! 간단하다.

Kuvernetes/ ECS Architecture

 

- ECS(Elastic Container Service)는 직접 실무에 참여하며 사용해볼 때 따로 포스팅 해야겠다.

 

 

2. ECR

- AWS에서 제공하는 서비스로 프라이빗 이미지 레포지토리를 만들 수 있다.

- ECR에 푸시하기 위해 AWS credential과 awscli가 필요.

- 레지스트리에 로그인 합니다. 이때 awscli를 통해 로그인에 필요한 패스워드를 얻을 수 있고, 이를 이용해 로그인하면 됩니다. 레포지토리가 아니라 레지스트리에 대한 로그인이라는 점을 주의.

- 배포 시 ssh 접속과 패키지 설치, 소스코드 설치, 빌드 등 기존에 필요했던 수많은 과정은 필요 없어지고, 대신 도커와 이미지 URI만이 필요하다. CI 파이프라인을 구축하기에도 굉장히 용이. 그냥 새 도커 이미지를 ECR에 푸시해주면 그만이기 때문. 

 

 

 

 

 

Reference)

+ 도커 초보

https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html

 

초보를 위한 도커 안내서 - 도커란 무엇인가?

도커를 처음 접하는 시스템 관리자나 서버 개발자를 대상으로 도커 전반에 대해 얕고 넓은 지식을 담고 있습니다. 도커가 등장한 배경과 도커의 역사, 그리고 도커의 핵심 개념인 컨테이너와 이

subicura.com

+ 도커 이미지의 원리

https://www.44bits.io/ko/post/how-docker-image-work

 

만들면서 이해하는 도커(Docker) 이미지: 도커 이미지 빌드 원리와 OverlayFS

도커 이미지는 유니온 마운트 기술을 활용해 계층화된 레이어들로 구성되며, 도커 레지스트리를 사용해 쉽고 효율적인 공유를 가능하게 해줍니다. 이 글에서는 도커 이미지가 저장되는 방식과

www.44bits.io

+ 멘붕 도커

https://woochan-autobiography.tistory.com/488

 

Docker - 처음 Docker 접할때 오는 멘붕 몇가지

Docker는 Virtual machine이 아니다! 처음 docker를 실행할 때 다음과 같은 명령을 실행하면 우분투 서버가 실행된다고 생각했다. 즉, Virtual machine과 같이 컨테이너 내에 우분투 서버가 실행되는 줄 알았

woochan-autobiography.tistory.com

+ 2022/02/21 Corca tech seminar : Docker and ECR