Network

🐳도커(Docker)란?

kyunge_ev 2022. 11. 22. 23:36
도커는 컨테이너 기술을 기반으로 하는 일종의 가상화 플랫폼이다.

리눅스 컨테이너에 여러 기능을 추가함으로써 애플리케이션을 컨테이너로서 좀 더 쉽게 사용할 수 있게 만들어진 오픈 프로젝트 / 기존에 쓰이던 가상화 방법인 가상 머신(VirturalBox, VMware 등) 보다 성능의 손실이 훨 씬 덜하다.


📚 가상화 vs 컨테이너

 

가상 머신(VirturalBox, VMware 등)

  • 하나의 하드웨어에 여러 개의 가상 머신으로 분할해 효율적으로 사용할 수 있는 기술
  • 분할 된 가상 머신들은 각각 독립적인 환경으로 구동됨
  • 기존 환경( Host OS )
    분할 된 각각의 환경( Guest OS )
  • Guest OS는 하이퍼바이저에 의해 생성되고 관리됨 → 항상 하이퍼바이저를 거쳐야함
  • 속도 저하,
    가상 머신 배포 시 이미지의 크기가 매우 커짐,
    환경 구축 파일이 모두 들어가 있기 때문에 OS 크기가 매우큼

컨테이너

  • 가상의 OS를 만드는 것이 아니라 베이스 환경의 OS는 공유하면서 필요한 프로세만 격리
  • 커널을 공유하기 때문에 Host OS의 기능을 모두 사용할 수 있음
  • 애플리케이션에 필요한 파일, 특정 라이브러리 등 종속 항목만 포함 하기 때문에 이미지의 용량이 매우 작아짐,
    운영체제가 아닌 프로세스이기 때문에 하이퍼바이저를 거칠 필요가 없음 → 속도가 매우 빨라짐

📚 도커의 장점

애플리케이션의 개발과 배포가 편해짐

  • 도커 컨테이너는 서버 부팅 시 실행되는 운영체제인 Host OS 위에 실행되는 격리된 공간
    → 컨테이너 자체에 특별한 권한을 주지 않는 한, 컨테이너 내부에 소프트웨어를 설치하고 설정 파일을 수정해도 Host OS에는 영향을 끼치지 않음
  • 독립된 개발 환경을 보장 받을 수 있음
  • 작업을 마치고 이를 서버 환경에 배포할 때 해당 컨테이너를 ‘도커 이미지’라고 하는 일종의 패키지로 만들어 서버 환경에 전달하기만 하면 됨
    → 개발 시 사용했던 환경을 다른 서버에서도 컨테이너로서 똑같이 복제할 수 있음
  • 도커 이미지는 가상 머신의 이미지와 달리 커널을 포함하고 있지 않기 때문에 이미지 크기가 크지 않음
  • 이미지 내용을 레이어 단위로 구성하여 중복되는 레이어를 재사용할 수 있어 애플리케이션 배포 속도가 매우빨라짐

여러 애플리케이션의 독립성과 확장성이 높아짐

모놀리스(Monolith) 애플리케이션

  • 소프트웨어의 여러 모듈이 상호 작용하는 로직을 하나의 프로그램 내에서 구동시키는 방식
  • 소규모 서비스에서는 이 방식이 어울릴지도 모르지만, 서비스 기능이 복잡해지고 거대해 질수록 소프트웨어 자체의 확장성과 유연성이 줄어듦

마이크로 서비스(Microservice)

  • 여러 모듈을 독립된 형태로 구성하기 때문에 언어에 종속되지 않고 변화에 빠르게 대응할 수 있음
  • 각 모듈의 관리가 쉬워짐
  • 컨테이너는 수초 내로 생성, 시작이 가능할 뿐만 아니라 여러 모듈에게 독립된 환경을 동시에 제공할 수 있기 때문에 마이크로서비스 구조에서 가장많이 쓰이고있는 가상화 기술임

📚 도커 엔진(Docker Engine)

도커는 리눅스 컨테이너를 제어하는 API를 Go언어로 구현한 libcontainer를 사용하기 때문에 대부분의 리눅스 운영체제에서 사용할 수 있음 → 대표적인 리눅스 운영체제로는 CentOS, 우분투 등이 있음

 

도커 이미지

  • 컨테이너를 생성할 때 필요한 요소
  • 여러 개의 계층으로 된 바이너리 파일로 존재
  • 컨테이너를 생성하고 실행할 때 읽기 전용으로 사용됨
  • 이미지는 도커 명령어로 내려받을 수 있으므로 별도로 설치할 필요 없음
  • [저장소 이름]/[이미지 이름]:[태그]의 형태로 구성
    • 저장소(Repository) : 이미지가 저장된 장소 (생략가능)
    • 이미지 이름 : 해당 이미지의 역할을 나타냄 (생략불가)
    • 태그 : 이미지의 버전 관리, 혹은 리비전(Revision) 관리에 사용 (생략 시 latest로 인식함)

 

도커 명령어로 컨테이너 다루기

도커 버전확인

# docker -v

도커 이미지 다운만 받기

# docker pull {이미지명}:{태그}

도커파일로 이미지 생성

Dockerfile 파일이 있는 디렉토리 기준.  마지막의 ' . ' 이 상대주소

# docker build -t {이미지명} .

컨테이너 생성

run : 생성과 동시에 컨테이너 내부로 들어감
→ start, attach 실행

# docker run -i -t [이미지이름:태그]

create : 컨테이너만 생성하고 내부로 안 들어감
→ 도커 이미지를 pull 한 뒤 컨테이너만 생성 할 뿐 start, attach 실행하지 않음

# docker create -i -t {옵션 (ex)--name [생성할 이름]} [이미지이름:태그]

start , attach

// 만들어진 컨테이너 시작하기(이미지에 CMD로 지정해놓은 작업 시키기
# docker start [컨테이너이름]

// 컨테이너로 들어가기(컨테이너 내 CLI 사용하기)
# docker attach [컨테이너이름]

-i , -t 옵션

-i : 상호 입/출력
-t : tty 활성화해서 배시(bash) 셸을 사용하도록 컨테이너 설정

# bdocker run 사용 시 이 두 옵션을 사용하지 않으면 셸을 정상적으로 사용할 수 없음

동작중인 컨테이너 재시작

# docker restart {컨테이너 id 또는 이름}

컨테이너 내부에서 나오기

컨테이너 정지 시키면서 빠져나오기

exit

Ctrl + D

컨테이너 정지 안하고 빠져나오기

Ctrl + P, Q

도커 엔진에 존재하는 이미지 목록

# docker images

컨테이너 목록

정지되지 않은 컨테이너만 출력

# docker ps

정지된 컨테이너도 모두 포함하여 출력(-a 옵션)

# docker ps -a
CONTAINER ID   IMAGE                              COMMAND                  CREATED        STATUS        PORTS                                                  NAMES
8828a383f936   ubuntu:22.04                       "bash"                   25 hours ago   Up 25 hours                                                          hopeful_lovelace
  • CONTAINER ID : 컨테이너에게 자동으로 할당되는 고유한 ID ⇒docker ps 에서는 ID 일부분만 출력되는데 컨테이너 정보를 확인하기 위해선 # docker inspect [컨테이너 이름] | grep Id 사용하여 풀 ID 확인 가능
  • IMAGE : 컨테이너를 생성할 때 사용된 이미지 이름
  • COMMAND : 컨테이너가 시작될 때 실행될 명령어 ⇒ 대부분 이미지에 미리 내장돼있기 때문에 별도 설정은 필요없음
  • CREATED : 컨테이너가 생성되고 난 뒤 흐른 시간
  • STATUS : 컨테이너의 상태
    • Exited… 정지 상태
    • UP …seconds 실행중 상태
    • Pause 중지 상태
  • PORTS : 컨테이너가 개방한 포트와 호스트에 연결한 포트를 나열함
  • NAMES : 컨테이너의 고유한 이름
    ⇒ --name 옵션으로 이름을 설정하지 않으면 도커 엔진이 임의로 형용사와 명사를 무작위 조합해 이름을 설정함
    ⇒ docker rename [기존컨테이너이름] [변경할컨테이너이름] 사용하여 컨테이너 이름 변경 가능

컨테이너 삭제

# docker rm

실행중인 컨테이너는 삭제 불가하여 stop 명령어로 중지 시킨 후 삭제

# docker stop mycentos
# docker rm mycentos

실행중인 컨테이너 바로 삭제

# docker rm -f mycentos

모든 컨테이너 한번에 삭제
-> -a : 컨테이너 상태와 관계없이 모든컨테이너 / -q : 컨테이너 ID만 출력

# docker container prune
# docker ps -a -q

컨테이너의 실행 상태와 관계없이 모든 컨테이너를 정지하고 삭제

# docker stop $(docker ps -a -p)
# docker rm $(docker ps -a -q)

rmi : 이미지 삭제

# docker rmi {옵션} {이미지 id}

exec : 이미 실행된 특정 컨테이너 환경을 디버깅하는 용도

# docker exec [컨테이너ID] [COMMAND]
// 해당 컨테이너 ID 실행 후 COMMAND 명령어 실행

# docker run 은 새로 컨테이너를 생성하는 용도

logs : 도커 로그 확인

# docker logs [컨테이너ID]

 

도커 포트 설정


출처 : https://youtu.be/SJFO2w5Q2HI 생활코딩유튜브

컨테이너는 가상 머신과 마찬가지로 가상 IP 주소를 할당받음 ( 172.17.0.x 의 IP를 순차적으로 )

 컨테이너의 네트워크 인터페이스를 확인

# ifconfig

 -p : 컨테이너의 포트를 호스트의 포트와 바인딩해 연결할 수 있게 설정

# -p [호스트의 포트]:[컨테이너의 포트]
// 예) 7777:80 -> 호스트의 7777번 포트를 컨테이너 80번 포트와 연결

# -p [특정IP]:[호스트의 포트]:[컨테이너의 포트]
// 예) 192.168.0.100:7777:80

# -p [호스트의 포트]:[컨테이너의 포트] -p [특정IP]:[호스트의 포트]:[컨테이너의 포트]
// 여러 개의 포트를 외부에 개방
// 예) -p 3306:3306 -p 192.168.0.100:7777:80

# -p 80
// 컨테이너의 80번 포트를 쓸 수 있는 호스트의 포트 중 하나와 연결
// 어느포트와 연결했는지 알 수 없기 때문에 docker ps 명령어로 PORTS 항목 확인 필요

도커 볼륨

도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되며,
컨테이너의 변경 사항만 별도로 저장해서 각 컨테이너의 정보를 보존한다.
⇒ 도커가 내려가면 컨테이너가 가지고 있는 정보들이 모두 사라짐 ( 도커사용 이유가 없어짐 )

이 때, 도커 볼륨을 사용하여 Host OS와 Docker Container가 같은 디렉터리를 바라보게하여 정보를 둘 다 저장한다.
⇒ 도커가 내려가도 Host OS에 정보가 남아 보존할 수 있음

두 디렉터리를 공유하여 새로 생성한 파일을 두 곳에서 관리할 수 있음

 -v 

# -v [Host OS 공유 디렉터리(경로)]:[컨테이너 공유 디렉터리(경로)]
// 예) docker run -d -v /root:/app ubuntu:22.04

 echo [문자열] > [파일명.확장자명] : [문자열]이 내용으로 적힌 파일 생성 

 cat [파일명.확장자명] : 파일 목록에서 찾기