23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
안녕하세요, DEVOCEAN YOUNG 2기로 활동 중인 강다빈입니다.
DEVOCEAN에서 감사하게도 YOUNG들에게 스터디도 할 수 있도록 지원해주고 계셔서
현재 Docker, Kubernetes를 주제로 Dokubernetes라는 이름의 스터디그룹을 운영하고 있습니다.
현재 '시작하세요! 도커/쿠버네티스' 라는 책을 활용해서 스터디를 진행 중인데, 스터디를 직접 만들고 운영해보는 건 이번이 처음이어서,
일단 5월 한 달간 책의 'Docker' 관련 부분을 읽고 각자의 방식으로 공부한 뒤, 마지막 주 금요일에 오프라인으로 만나서 각자 맡은 부분을 리뷰하는 방식으로 진행했습니다.
승연 : 도커 이미지와 컨테이너, 도커 컨테이너 다루기
다빈 : 도커 이미지, Dockerfile
상우 : 도커 데몬, 쿠버네티스 기본 개념
현빈 : 도커 스웜
서현 : 도커 컴포즈
간단히 스터디 내용을 정리해보겠습니다.
Docker는 리눅스 컨테이너에 여러 기능을 추가함으로써 애플리케이션을 컨테이너로 좀 더 쉽게 사용할 수 있게 만들어진 오픈소스 프로젝트입니다.
가상 머신은 완벽한 운영체제를 생성할 수는 있지만 일반 호스트에 비해 성능 손실이 있으며, 수 기가바이트에 달하는 이미지를 애플리케이션으로 배포하기 부담스럽다는 단점이 존재합니다.
그러나 컨테이너를 사용하면 이미지를 생성 및 배포하는 시간이 vm보다 빠르며, 가상화된 공간을 사용할 때의 성능 손실도 거의 없습니다.
docker의 기본적인 명령어를 알아보겠습니다.
docker run -it ubuntu:14.04
ubuntu 14.04 버전의 bash 쉘을 활성화하는 명령어입니다.
' i ' 는 상호입출력, ' t' 옵션은 tty를 활성화하여 bash 쉘을 사용하는 것을 의미합니다.
컨테이너는 exit를 입력하거나 ctrl+D로 종료할 수 있습니다.
컨테이너를 종료하지 않고 빠져나오려면 ctrl + P,Q를 입력해야합니다.
docker ps
docker ps -a
ps는 정지되지 않은 컨테이너를 모두 출력합니다. -a 옵션을 추가해주면 정지된 컨테이너를 포함하여 모든 컨테이너의 리스트를 출력합니다.
이 명령어를 통해 컨테이너 ID, IMAGE, COMMAND, 생성 시간, 컨테이너 상태, 연결 포트, 컨테이너 고유 이름 등을 알 수 있습니다.
docker stop mycentos
docker rm mycentos
컨테이너를 먼저 정지시킨 이후에 삭제해야 에러 없이 삭제할 수 있습니다. -f 옵션을 활용하여 실행중인 컨테이너를 강제 삭제할 수도 있습니다.
도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되며 컨테이너의 변경 사항만 별도 저장해서 각 컨테이너의 정보를 보존합니다.
이미 생성된 이미지는 어떤 경우로도 변경되지 않으며, 컨테이너 계층에 원래 이미지에서 변경된 파일시스템 등을 저장합니다.
이미지에 mysql을 실행하는 데 필요한 애플리케이션 파일이 들어 있다면, 컨테이너 계층에는 DB를 운용하면서 쌓이는 데이터가 저장됩니다.
문제는, 이 컨테이너를 삭제하면 컨테이너 계층에 저장되어있던 DB 정보도 모두 삭제된다는 것입니다.
이를 방지하기 위해 컨테이너의 데이터를 영속적으로 저장하기 위한 방법이 있는데 이 중 가장 쉬운 방식이 볼륨 활용 입니다.
호스트와 볼륨 공유
-v 옵션을 활용, [호스트의 공유 디렉터리]:[컨테이너의 공유 디렉터리]
-v /home/wordpress_db:/var/lib/mysqL : 호스트의 /home/wordpress_db 디렉터리와 컨테이너의 /var/lib/mysql을 공유합니다.
볼륨 컨테이너 활용
-v 옵션으로 볼륨을 사용하는 컨테이너를 다른 컨테이너와 공유합니다.
이는 직접 볼륨을 공유하는 것이 아니라 -v 옵션을 적용한 컨테이너 를 통해 공유합니다.
도커가 관리하는 볼륨 생성
도커 자체 제공 볼륨으로 데이터를 보존합니다.
docker volume create --name myvolume
모든 컨테이너는 이미지를 기반으로 실행됩니다. 이미지에 실행 코드, 환경 설정 등이 담겨있고 이를 실제로 동작하도록 하는 것이 컨테이너라고 볼 수 있습니다.
간단히 말하면 1. 컨테이너 생성, 2. docker commit으로 이미지생성하기 이 두 가지가 기본적인 이미지 생성 방식이라고 볼 수 있습니다.
commit_test라는 이름의 컨테이너를 ubuntu:18.04 이미지 기반으로 만듭니다.
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
ubuntu:18.04 이미지에 변경사항을 만들었다면 컨테이너를 빠져나와 docker commit 명령어로 컨테이너를 이미지로 만듭니다.
-a 옵션은 이미지 작성자, -m은 커밋 메시지, 이미지에 대한 부가설명입니다.
docker images 를 입력하면 방금 커밋한 이미지인 commit_test:first를 확인할 수 있습니다.
이와 동일한 방식으로 commit_test:first 이미지 기반의 컨테이너를 만들고 commit_test:second 이미지도 만들어 줍니다.
docker inspect ubuntu:18.04
docker inspect commit_test:first
docker inspect commit_test:second
docker inspect 명령어를 사용하면 컨테이너 뿐만 아니라 네트워크, 볼륨, 이미지 등 모든 도커 단위의 정보를 확인할 수 있습니다.
이미지를 커밋할 때 컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 그 레이어를 포함해 새로운 이미지를 생성하기 때문에
전체 이미지의 실제 크기는 62.3MB + first 파일의 크기 + second 파일의 크기가 됩니다.
docker rmi commit_test:first
위와 같이 입력하면 이미지를 사용 중인 컨테이너가 존재하기 때문에 삭제 오류가 발생합니다.
이를 막기 위해서는 컨테이너를 정지 후 삭제해야합니다.
rmi -f 를 통해서도 삭제할 수 있지만 이 경우 이미지 레이어 파일이 아닌 이미지의 이름만 삭제하기 때문에 무의미합니다.
이런 파일들은 이름이 으로 바뀌어 출력되는데, 이러한 이미지들을 Dangling Image라고 부릅니다.
댕글링 이미지는 docker image prune을 통해 삭제할 수 있습니다.
1. 도커 이미지 허브
docker push, docker pull만 하면 되므로 매우 간단하지만, 무료의 경우 private 저장소의 수에 제한이 있다는 단점이 존재하긴 하지만
public 저장소는 무료로 사용할 수 있어 내가 만든 이미지가 다른 사용자에게 공개돼도 상관 없다면 좋은 선택이 될 수 있습니다.
2. 도커 사설 레지스트리
사용자가 직접 이미지 저장소를 만들 수 있습니다.
그러나 사용자가 직접 이미지 저장소 및 사용되는 서버, 저장 공간등을 관리해야 해서 사용법이 까다롭다는 단점이 존재합니다.
실습할 때도 오류가 심각하게 많이 발생해서 실패를 한..
완성된 이미지를 생성하기 위해 컨테이너에 설치해야하는 패키지, 소스코드, 실행 명령어, 셸 스크립트 등을
하나의 파일에 기록 → 도커가 이 이름을 읽어 컨테이너에서 작업 수행 뒤 이미지로 만들어낸다.
이때 기록한 파일을 Dockerfile 이라고 합니다.
직접 컨테이너를 생성하고 이미지로 커밋 x
애플리케이션 빌드 및 배포 자동화 → Git 등 이용
도커 허브에 이미지를 배포할 때에도 이미지 자체 대신 도커파일을 배포할 수 있습니다.
배포되는 이미지를 신뢰할 수 없거나 직접 이미지를 생성해서 사용하고 싶을 때에도 Dockerfile을 활용하는 것이 좋습니다.
저는 WSL2로 우분투를 윈도우에 설치한 뒤, 설치한 우분투에 도커를 설치하여 실습을 진행했습니다.
처음엔 Docker desktop을 설치한 이후에 윈도우 CMD 창을 띄워서 실습을 했더니 vi 에디터를 사용하지 못한다는 단점이..
FROM : 생성할 이미지의 베이스 이미지. 도커 파일 작성 시 반드시 한 번이상 입력해야 합니다.
이미지 이름의 포맷은 docker run 명령어에서 이미지 이름을 사용했을 때와 같습니다.
사용하려는 이미지가 도커에 없다면 자동으로 pull합니다.
MAINTAINER : 이미지를 생성한 개발자의 정보. 버전 1.13.0 버전 이후로 사용하지 않아 현재는
LABEL maintainer "kchabin <kchabin@swu.ac.kr>"위와 같은 LABEL로 교체해 표현합니다.
LABEL : 이미지에 메타데이터를 추가합니다. ‘키:값’의 형태로 저장됩니다. 추가된 메타데이터는 docker inspect 명령어로 확인할 수 있습니다.
RUN : 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행합니다. 위 도커 파일에서는 apt-get update, apt-get install apache2 -y 명령어를 실행해서 아파치 웹 서버가 설치된 이미지가 생성됩니다.
dockerfile을 이미지로 빌드하는 과정에서는 별도의 입력이 불가능해서 -y 옵션을 넣어줘야 합니다. 별도의 입력을 받아야 하는 RUN이 있다면 build 명령어는 이를 오류로 간주하고 종료한다.
ADD : 파일을 이미지에 추가한다. 예제에서는 dockerfile이 위치한 디렉터리에서 test.html 파일을 이미지의 /var/www/html 디렉터리에 추가한다.
JSON 배열의 형태로 [”추가할 파일 이름”, …. , “컨테이너에 추가될 위치”] 와 같이 사용할 수 있다. 파일 이름은 여러 개 가능하며 배열의 마지막 원소가 추가될 위치를 의미한다.
- EXPOSE : Dockerfile의 빌드로 생성된 이미지에서 노출할 포트를 설정한다.
반드시 호스트의 포트와 바인딩이 되는 것은 아니고 컨테이너의 80번 포트를 사용할 것임을 나타낸다.
run 명령어에서 -p 플래그(모든 노출된 컨테이너의 포트를 호스트에 publish)와 함께 사용된다.
CMD : 컨테이너가 시작될 때마다 실행할 명령어를 설정합니다.
Dockerfile에서 한 번만 사용할 수 있습니다. apachectl -DFOREGROUND라는 커맨드가 적용되어 컨테이너가 시작될 때마다 자동으로 아파치 웹 서버를 실행합니다.
아파치 웹 서버는 하나의 터미널을 차지하는 포그라운드 모드로 실행 → -d 옵션으로 detached 모드 컨테이너 생성합니다.
docker run [Image] [Command] → Command와 동일한 역할.
docker run 명령어에서 커맨드를 입력하면 CMD는 run의 커맨드로 덮어 쓰입니다.
JSON 배열 형태로도 사용 가능합니다. → [”실행가능파일”, “명령줄 인자 1”, “명령줄 인자2”, . .]
실제 도커의 구조는 크게 도커 클라이언트, 도커 데몬 두 가지로 나뉩니다.
도커 서버가 컨테이너를 실제로 생성하고 실행하며 이미지를 관리하는 주체이며, 이는 dockerd 프로세스로서 동작합니다.
도커 엔진은 외부에서 API 입력을 받아 도커 엔진의 기능을 수행하는데, 도커 프로세스가 실행되어 서버로서 입력을 받을 준비가 된 상태를 도커 데몬이라고 합니다.
Docker 데몬(dockerd)은 API 요청을 수신하여 도커 엔진의 기능을 수행하고 이미지, 컨테이너, 네트워크 및 볼륨과 같은 Docker 객체를 관리합니다.
which 명령어로 docker 명령어의 위치를 확인할 수 있고, /usr/bin/docker에 위치한 파일을 통해 사용되고 있다는 것을 알 수 있습니다.
ps aux | grep docker 명령어를 통해서는 실행 중인 도커 프로세스를 확인할 수 있습니다.
Docker 클라이언트는 많은 Docker 사용자가 Docker와 상호 작용하는 기본 방법입니다.
도커 데몬이 API를 사용할 수 있도록 CLI(Command Line Interface)를 제공하는 것이 Docker Client 입니다.
도커에 명령어를 입력할 때 docker run등의 명령어를 사용하죠? 이것이 도커 클라이언트를 사용하는 것입니다.
docker run과 같은 명령을 사용하면 클라이언트가 이러한 명령을 API로서 dockerd로 보내 실행하고,
이때 Docker 클라이언트는 /var/run/docker.sock에 있는 유닉스 소켓을 통해 도커 데몬의 API를 호출합니다.
도커 클라이언트가 사용하는 유닉스 소켓은 같은 호스트 내에 있는 도커 데몬에게 명령을 전달할 때 사용됩니다.
저의 실습환경인 우분투에서는 도커가 설치되면 자동으로 서비스로 등록되므로 호스트가 재시작되더라도 자동으로 실행됩니다.
일반적으로는 아래의 명령어로 docker 서비스를 활성화합니다.
# service docker start
# service docker stopdockerd 명령어 또한 /usr/bin/dockerd로서 존재하기 때문에 docker 명령어와 같이 바로 사용할 수 있습니다.
-H 옵션은 도커 데몬의 API를 사용할 수 있는 방법을 추가합니다.
# dockerd
# dockerd -H unix:///var/run/docker.sock위 두 명령어는 동일합니다. -> 아무런 옵션을 주지 않고 단순히 dockerd만 입력해도 유닉스 소켓을 실행합니다.
# dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375-H에 unix:///var/run/docker.sock를 지정하지 않는다면 유닉스 소켓은 비활성화 되므로 도커 클라이언트를 사용할 수 없게 되며, docker로 시작하는 명령어를 사용할 수 없습니다.
docker ps, create, run 등의 명령어는 하나의 도커 엔진에 존재하는 컨테이너의 목록 출력, 생성을 합니다.
그러나 실제로 도커를 운영 환경에 적용할 때에는 자원이 부족할 때 서버 클러스터링을 활용합니다.
필요한 만큼 많은 서버를 병렬로 확장해 나가면 적당한 성능의 서버 여러 대를 하나의 자원 pool로 만들어 활용할 수 있고, 비싼 서버를 사지 않아도 됩니다.
도커 스웜 모드는 실제 운영 환경에서 많이 쓰이지는 않지만, 초보자가 서버 클러스터에서 컨테이너를 어떻게 다루는지에 대한 기초적인 지식을 쌓기에 적합합니다.
docker info | grep Swarm 명령을 입력하면 스웜 모드 클러스터 정보를 확인할 수 있습니다. 지금까지는 단일 도커 서버를 통해 실습을 해왔기에 Swarm은 inactive 상태입니다.
스웜 모드는 매니저 노드와 워커 노드로 구성되어 있습니다.
워커 노드 : 실제 컨테이너가 생성되고 관리되는 도커 서버
매니저 노드 : 워커 노드를 관리하기 위한 도커 서버.
매니저 노드는 기본적으로 워커 노드의 역할을 포함합니다.
운영 환경에서 스웜 모드로 도커 클러스터를 구성하려면 매니저 노드를 다중화해야 합니다.
매니저의 부하를 분산하고, 특정 매니저 노드가 다운됐을 때 정상적으로 스웜 클러스터를 유지할 수 있기 때문입니다.
그러나, 매니저 노드의 수가 늘어난다고 스웜 클러스터의 성능이 증가하는 것은 아닙니다.
스웜 모드는 매니저 노드의 절반 이상에 장애가 생길 경우 해당 노드들이 정상적으로 복구가 될 때까지 운영을 중단합니다.
이 경우 매니저 노드의 수가 짝수 개인 경우 장애 발생 시 클러스터의 운영이 중단될 수도 있습니다.
홀수 개로 구성했을 경우에는 과반수 이상이 유지되는 쿼럼(quorum) 매니저에서 운영을 계속할 수 있어 스웜 매니저를 홀수 개로 구성하는 것이 권장됩니다.
docker swarm init : 매니저 역할 서버에서 스웜 클러스터 시작
docker swarm join : 새로운 워커 노드를 스웜 클러스터에 추가
docker node ls : 특정 도커 서버가 정상적으로 스웜 클러스터에 추가됐는지 확인
docker swarm leave : 추가된 워커 노드를 삭제 -> 해당 워커 노드에서 입력합니다.
leave 명령어는 매니저가 해당 워커의 상태를 down으로 인식하게 할 뿐, 자동으로 워커를 삭제하지 않기 때문에 매니저 노드에서 docker node rm 명령어를 사용해 삭제해야 합니다.
docker swarm leave --force : 매니저 노드 삭제
docker node promote : 워커 노드를 매니저 노드로 변경
docker node demote : 매니저 노드를 워커 노드로 변경
단, 매니저 노드가 한 개일 때는 매니저 노드에 대해 demote 명령어를 사용할 수 없습니다.
도커 클라이언트에서 사용하는 명령어가 제어하는 것은 컨테이너이지만, 스웜 모드에서는 서비스(service) 를 제어합니다.
서비스는 같은 이미지에서 생성된 컨테이너의 집합이며 서비스를 제어하면 해당 서비스 내 모든 컨테이너에 같은 명령이 수행됩니다.
서비스 내의 컨테이너를 Task라고 부르고, 이 task들은 각 워커 노드와 매니저 노드에 할당됩니다.
여러 개의 컨테이너가 하나의 애플리케이션으로 동작할 때 구축에는 run 명령어를 여러 번 사용할 수 있지만 제대로 동작하는지 테스트하는 단계에서는 매우 번거롭습니다.
매번 CLI로 컨테이너를 생성하는 것보다 여러 개의 컨테이너를 하나의 서비스로 정의해 컨테이너 묶음으로 관리할 수 있다면 좀 더 편리할 것입니다.
Docker Compose는 컨테이너를 이용한 서비스의 개발과 CI(Continuous Integration)를 위해 여러 개의 컨테이너를 하나의 프로젝트로서 다룰 수 있는 환경을 제공합니다.
아래 명령어로 설치된 도커 컴포즈의 버전을 확인할 수 있습니다.
docker-compose -v도커 컴포즈는 컨테이너의 설정이 정의된 YAML 파일을 읽어 도커 엔진을 통해 컨테이너를 생성합니다.
아래와 같이 docker-composer.yml 파일을 작성합니다.
version: '3.0'
services:
web:
image: alicek106/composetest:web
ports:
- "80:80"
links:
- mysql:db
command: apachectl -DFOREGROUND
mysql:
image: alicek106/composetest:mysql
command: mysqldYAML 파일에서 들여쓰기할 때 Tab은 도커 컴포즈가 인식하지 못하므로 2개의 공백을 사용해 하위 항목을 구분해야 합니다.
version: YAML 파일 포맷 버전
: 도커 컴포즈 1.8은 버전 2를, 버전 1.9는 버전 2.1을, 버전 1.10은 버전 3.0 사용
: 도커 컴포즈 버전은 도커 엔진 버전에 의존성이 있으므로 가능하다면 최신 버전 사용
services: 생성될 컨테이너들을 묶어놓은 단위
web, mysql: 생성될 서비스의 이름
작성한 docker-compose.yml 파일을 저장한 후 저장한 디렉터리에서 docker-compose up -d 명령어로 컨테이너를 생성할 수 있습니다.
Kubernetes는 그리스어로 '조타수'를 의미합니다.
사실상 표준의 컨테이너 오케스트레이션 도구인데, 도커 스웜 모드와 같이 여러 대의 도커 호스트를 하나의 클러스터로 만들어주는 등 여러 기능을 제공합니다.
'K'와 's' 사이의 문자 수를 나타내는 8을 사용하여 'K8s'로 줄여 쓰기도 합니다.
컨테이너 오케스트레이션이란, 컨테이너의 배포, 확장, 관리, 네트워킹을 자동화하는 것을 말합니다.
수 백에서 수천 개에 이르는 컨테이너를 다루는 환경에서는 오케스트레이션 툴을 통해 효율적으로 컨테이너들을 관리할 수 있습니다.
컨테이너 오케스트레이션 툴이 제공하는 핵심 기능은 다음과 같고, 이외에도 더 많은 기능을 제공합니다.
컨테이너 배포 관리 및 확장
로드밸런싱
장애 복구
네트워킹
서비스 디스커버리
대표적인 컨테이너 오케스트레이션 도구에는 Kubernetes, Docker Swarm, Nomad 등이 존재하는데, 이 중Kubernetes 가 개발 조직에서 가장 많이 활용되고 있습니다.
서버 자원 클러스터링, 마이크로서비스 구조의 컨테이너 배포, 서비스 장애 복구 등 다양한 기능을 지원합니다.
또한 구글, 레드햇을 비롯한 다양한 오픈소스 진영에서 쿠버네티스의 소스코드에 기여하고 있어 안정성, 성능 등을 신뢰할 수 있습니다.
다만 다른 오케스트레이션 툴 보다 많은 지식을 필요로 하기에, 영세한 업체에서 쿠버네티스를 관리하는 것은 오히려 오버 엔지니어링이 될 수도 있다는 단점이 존재합니다.
첫 시작이니까, 먼저 도커에 대해서 간단히 알아본다는 느낌으로 했는데, 생각보다 책의 내용이 어렵고 그 양이 매우 방대해서
스터디 진행 방식을 한 달에 두 번 오프라인 스터디를 진행하고 같은 내용을 함께 리뷰하면서 스터디를 진행해나가기로 했습니다.
정말 감사하게도, SKT타워 지하2층에 있는 회의실을 대여할 수 있게 해주셔서 정말 좋은 환경에서 즐겁게 오프라인 스터디를 진행할 수 있었습니다.
회의실을 대여해주시는 것도 감사한데, 맛있는 음식까지..! 정말 너무너무 즐겁게 스터디 했던 것 같습니다.
그럼 두 번째 오프라인 스터디 글로 다시 돌아오겠습니다!
긴 글 읽어주셔서 감사합니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.