[Docker] 이미지 & 컨테이너 실습

신현식·2023년 2월 7일
0

구름_Docker

목록 보기
3/6
post-thumbnail

이전 도커 관련 내용

시스템과 인프라 기초

가상화 종류

  • 서버 가상화
  • 네트워크 가상화
  • 스토리지 가상화 (ex. 원 드라이브, 구글 드라이브 , N 드라이브..)
  • 컨테이너 가상화

서버 가상화

가장 일반적인 가상화, 가상 머신을 생성할 때 사용하는 기술이다. 가상 머신을 생성하려면 CPU나 메모리와 같은 시스템 자원을 나누어주는 파티셔닝 기술이 필요하다. 파티셔닝 기술은 하드웨어 파티셔닝과 소프트웨어 파티셔닝이 있지만 현재는 소프트웨어 기술이 주로 사용된다. 이는 소프트웨어를 사용하여 가상머신에게 시스템 자원을 할당하게 되는데, 이때 사용하는 소프트웨어를 하이퍼바이저라고 한다.

하이퍼바이저

호스트가 소프트웨어 파티셔닝을 할 수 있게 만들어주는 소프트웨어이다.
하이퍼바이저의 역할은 가상 머신의 리소스 관리뿐만 아니라 서로 독립적인 환경을 사용할 수 있도록 리소스간 접근 방지 기능도 가지고 있다. 하이퍼바이저는 가상 머신이 어느 정도의 가상 리소스를 할당 받을지를 정하고 실제 물리적인 자원을 사용할 수 있도록 리소스를 관리한다.
가장 널리 알려져 있는 하이퍼바이저로 상용 제품으로는 VMware와 xen, 오픈 소스로는 VitualBox, KVM이 있다

리눅스 컨테이너

리눅스 컨테이너는 컨테이너 가상화 기술을 사용한다. 리눅스 컨테이너에는 애플리케이션이나 이에 필요한 라이브러리 및 설정파일 등이 포함된다.
도커는 리눅스 컨테이너를 다루는 도구이며, 컨테이너 런타임이라고 한다.

  • 호스트 운영체제에서 그냥 앱을 돌리기 위해 필요한 리소스가 10하자. VM 기반에서 앱을 사용하기 위해서는 가상머신에는 40, GUEST OS에 50이 필요하므로 앱 하나를 위해 사실상 100이 필요

  • 앱을 돌리기 위해 필요한 리소스가 10이라 했을 때, 컨테이너 엔진은 5정도 필요하다. 따라서 앱 하나를 위해 15정도가 필요하다.
    즉, 컨테이너는 가상머신에 비해 매우 가볍다.

<소프트웨어 컨테이너>

  • 컨테이너는 외부 환경과 독립되어 있음
    ( ex. 물리적인 컨테이너의 격리)

  • 사용하고자 하는 App에 맞는 환경을 구축할 수 있다
    ( ex. 물리적인 컨테이너의 용도에 따른 종류)

  • 같은 컨테이너 엔진을 사용하고 있으면 외부요인에 상관없이 그대로 가져다 사용 가능
    -> A컨테이너 엔진에서 개발된 컨테이너는 A컨테이너 엔진을 사용하는 모든 곳에 그냥 그대로 사용 가능
    즉. 개발환경과 실제환경을 구분할 필요가 없다.

<리눅스 컨테이너에서 사용하는 기술>

cgroup

  • 프로세스 또는 쓰레드를 그룹화 하여 관리하는 기능과 시스템 리소스(CPU, 메모리, 디스크 입출력 등..)의 사용을 제한하는 기술
  • 리눅스 컨테이너는 호스트의 리소스를 공유하여 사용하는데, 이때 cgroup을 사용하여 컨테이너가 사용하는 리소스의 양을 제한할 수 있음

namespace

  • namespace에 다수의 오브젝트를 격리할 수 있음
  • 동일한 호스트에서 동일한 PID를 가질 수 없지만 서로 다른 namespace에서는 동일한 PID를 가질 수 있음
  • namespace의 종류에는 PID, Network, UID, Mount, UTS, IPC namespace

Docker란

  • Docker는 2013년 Docker사에서 Go 언어로 개발한 오픈소스 플랫폼
  • Docker를 사용하면 리눅스 컨테이너를 더 쉽게 관리하고 실행할 수 있음
  • Docker의 가장 큰 특징은 이식성인데, 이는 개발 환경, 테스트 환경, 서비스 환경을 모두 동일하게 사용할 수 있기 때문

Docker 사용 이유

  • 서버를 코드 형태로 정의
    도커는 이미지를 사용하여 컨테이너를 실행하고 컨테이너는 하나의 애플리케이션을 실행하는 서버처럼 동작한다. 도커는 이미지를 제작할 때 코드 형태로 정의하여 작성 가능한데 따라서 서버를 코드 형태로 정의할 수 있어 일관성을 유지하는 것과 버전 관리 부분에서도 편리하다.

  • 이식성
    애플리케이션 개발 단계는 크게 개발 단계, 테스트 단계, 서비스 단계로 나뉜다. 이 때 각 단계의 환경을 통일하기는 쉽지 않지만 도커를 사용하면 컨테이너에 모든 환경을 구축하기 때문에 도커만 설치하면 된다

  • 상호 운용성
    Docker는 Google, Amazon, IBM, MS, Red Hat 등 다양한 벤더에서 지원하기 때문에 다양한 벤더의 시스템 및 오픈 소스와 연계하여 사용할 수 있다.

도커의 구조

  • 이미지

    • 도커로 리눅스 컨테이너를 생성하려면 미리 제작된 이미지가 있어야 함
    • 이미지는 여러 개의 레이어로 이루어져 있으며, 각 레이어는 Read Only 상태로 사용됨
    • 만약 이미지로 컨테이너를 실행하여 파일을 생성하거나 삭제한다면 새로운 레이어를 만들어 내용을 저장하는데 이 때 사용하는 방식이 COW(Copy on Write)와 유사함
  • 저장소

    • 컨테이너를 생성하려면 이미지가 있어야 하고, 이미지는 호스트가 아닌 외부에 저장되어 공유할 수 있어야 함
    • 이를 저장소라고 하며, 범위에 따라 퍼블릭 이미지 저장소와 프라이빗 이미지 저장소로 나눌 수 있음
    • 이미지 저장소는 대표적으로 도커 허브(Docker Hub)가 있으며, 도커 허브에는 퍼블릭과 프라이빗 이미지 저장소 둘 다 사용할 수 있음
      📢 Docker 허브
    • 또한 Habor와 도커 레지스트리 같은 프라이빗 이미지 저장소를 만들어 별도로 운영할 수도 있으며, 퍼블릭 클라우드 서비스는 자체 이미지 저장소 서비스가 있음
  • 컨테이너

    • 컨테이너는 이미지의 실행 형태
    • 쉽게 말해 이미지가 메모리에 올라가면 컨테이너, 컨테이너가 디스크에 저장되어 있으면 이미지
    • 하나의 컨테이너에는 하나의 애플리케이션만 실행되는 것이 권장되며, 추가로 실행할 수 있지만 유지하는 것은 권장하지 않음

도커의 기능

도커(docker)개요 & NAPT

도커 실습

  • 가상머신 설치: centos7(호스트전용 어댑터, NAT Network, 메모리 4096)
# 연결된 네트워크의 IP 주소 확인, 
ip addr

# 윈도우 원격 접속, localhost에 위에 나온 IP주소 입력
ssh root@localhost
Password 입력 
# 만약 key문제로 접속이 안된다면 c드라이브-> 사용자 -> .ssh폴더 안에 파일을 지워준다.


# yum 관리도구 설치
yum install -y yum-utils 

# 도커 관련 레포지토리 추가
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 도커 설치
yum install docker-ce docker-ce-cli containerd.io

# 도커 시작 및 활성화
systemctl enable docker 
systemctl start docker

# 도커 설치 및 시작 확인
systemctl status docker
docker --version

ping이 보내지지 않을떄 설정
파일 -> 네트워크 매니저 -> NAT Network -> 만들기 -> 시작

이미지 검색

docker search 이미지명

이미지 다운

docker pull 이미지명:태그
docker image pull 이미지명:태그

# 이미지 관련 명령어 보기
docker image

# 둘 다 사용 가능
docker image pull centos:latest
docker pull centos:7

# latest는 default값, 안넣어줘도 괜찮음
docker pull httpd
docker image pull httpd:latest

docker_hub에 가서 다운받고 싶은 이미지를 검색하면 관련된 여러 태그정보가 나온다. 여기서 받고 싶은 태그을 찾아서 다운받을 수 있다.

  • 36fa1415f90a: Pull complete
    -> 처음 컨테이너를 생성 후 내용을 추가한 후 이미지를 생성하면 기존의 layer에 새로운 layer가 추가된다.
    -> /var/lib/docker/image/overlay2/layerdb 에 layer 저장

이미지 확인 / 삭제

# 이미지 리스트 확인
- docker image ls 
- docker images

# 이미지 ID 리스트 확인
- docker image ls -q 
- docker images -q

------------------------------------

# 이미지 삭제
- docekr image rm [-f] 이미지명:태그
=> -f 옵션은 컨테이너가 실행되었던 이미지 삭제시 
- docekr image rm image_ㅌㅌㅌid

# 컨테이너가 실행되지 않았던 이미지 삭제, 실행되고 있는 이미지는 삭제하지 못함
docker image prune --all

# 컨테이너가 실행되었던 이미지 모두 삭제
docker image rm -f $(docker images -q)



# centos:7 삭제
docker image ls
docker image rm -f centos:7

이미지 백업

# 이미지 백업
docker save -o 백업파일명 이미지명 이미지명 ....

# 이미지 백업 파일 해제
docker load -i 백업파일명



# 백업
docker save -o test.tar httpd centos:7
#백업 파일 내용 확인
tar tvf test.tar | less
# 기존 파일 삭제
docker image rm -f $(docker images -q)
# 백업 파일 해제
docker load -i test.tar

컨테이너 관련 명령

docker container

컨테이너 및 이미지 스펙 확인

docker image inspect 컨테이너명/이미지명

docker image inspect centos:7

컨테이너 생성 및 실행

create : 컨테이너 생성

  • -i (interactive): shell 명령어처럼 대화형으로 진행되는 경우 부여되는 옵션
  • -t (tty): shell 명령어는 대화형으로 하는데 있어서 해당 제어 터미널이 있어야 확인 가능
## 명령어의 container는 생략가능

# 이름 없이 컨테이너를 만들면 어무 이름이 들어감
docker container create -it --name os1 centos:7  


# 생성된 컨테이너 시작
docker container start os1

# 생성된 컨테이너에 접속
docker container attach os1

# 접속중인 컨테이너에서 나오기, 그냥 exit로 나오게 되면 container의 상태에 영향을 미침
ctrl+pq
 

💡 CMD 확인

-> 컨테이너 CMD가 shell인 경우에는 -it 옵션을 부여해야함.
cmd가 shell이기 때문에 bash 셸에서 실행되는 것을 알 수 있다.


-> 컨테이너 CMD가 httpd 서비스처럼 해당 서비스 명령어를 실행해야 되면 -it 옵션을 부여할 필요없음.
cmd가 shell이 아닌 foreground에서 실행되는 것을 알 수 있다.

실행중인 컨테이너 목록 확인

# 현재 실행 중인 컨테이너만 나옴 
docker container ps

# 실행중이지 않은 컨테이너까지 보기
docker container ps -a 


# 컨테이너 전체 아이디 보기  
docker container ps -aq

종합모드

run : create + start + attach
-> attach를 수행하고 싶지 않을 때에는 run -d (detech) 사용

docker run [option] --name 컨테이너명 이미지:태그


## cmd가 shell인 경우
# -it 옵션만 있는 경우 컨테이너기 민들어짐과 동시에 실행됨.
docker run -it --name os2 centos:7

# -itd 옵션인 경우 컨테이너기 민들어지고 실행은 안됨.
docker run -itd --name os3 centos:7
 
 
# cmd가 서비스인 경우, 실행되는 경우 강제중지밖에 없기에 -d 옵션 필요
docker run -d --name web1 httpd:latest

-> 💡 이미 존재하는 컨테이너 이름은 다시 사용할 수 없다.

컨테이너 삭제

docker container rm [-f] 컨테이너명 or 컨테이너 id
-f : 실행되고 있는 컨테이너 삭제시 붙임

# 실행중인 것은 삭제 x
docker container prune
 
 

# 모든 컨테이너 삭제
docker rm -f $(docker ps -q)

해당 컨테이너 내부에 명령어 실행

해당 컨테이너 내부에 접속 / 컨테이너 분리모드로 실행한다.

  • docker exec 컨네이너명 명령어

  • docker exec -it 컨테이너명 shell

# 해당 컨테이너 내부에 명령어 실행
docker exec os1 ls -a /root

# 명령어 대상이 shell일떄는 -it 옵션 필요
이 명령은 분리모드로 들어간 것이기 때문에 exit로 나와도 되고 해당 컨테이너에 아무런 영향도 없다.
docker exec -it os1 bash 

cmd가 서비스인 컨테이너에 shell로 접속 / 컨테이너 분리모드로 실행

inspect로 실행했을 떄, Config가 컨테이너 관련 내용이다.

# httpd 컨테이너 실행
docker run -d --name web1 httpd

# bash 셸로 접속
docker exec -it web1 bash

# htdocs디렉터리 접속, index.html파일이 존재하는 것을 확인 
cd htdocs

# 원하는 내용 입력
cat > index.html
test web server   

# bash 종료 후, 해당 컨테이너 IP 확인 	
exit 
docker inspect web1 | grep IPA

# 찾은 IP에 curl 명령
curl 컨테이너 IP

-> httpd는 컨테이너의 WorkingDir이 '/usr/local/apache2'로 지정이 되있기 때문에 실행했을 때 바로 작업할 위치로 가진다.

컨테이너 리소스 확인

한시적인 컨테이너 리소스를 확인하기 위해 --no-stream 옵션을 사용한다.

  • docker stats --no-stream

컨테이너 리소스 제한

  • 컨테이너 리소스 제한
    docker run --cpus (0.0~1.0) --memory (메모리크기) [옵션] --name 컨테이너명 이미지명:태그

  • 컨테이너 리소스 변경
    docker update --cpus or --memory (limit 제한) 컨테이너명

# os2의 메모리 1G, cpu 50%를 할당하겠다.
docker run -it --name os2 --cpus 0.5 --memory 1G centos:7

# 리소스 제한을 새롭게 바꿀 수 있다.
docker update --cpus 0.7 --memory 2G os2

  • 컨테이너 PID 확인
    docker top 컨테이너명

컨테이너에 파일 복사 및 확인

  • 컨테이너는 기본적으로 메모리에 이미지가 올라가서 실행된 상태 = 컨테이너는 메모리에 있는 것

  • 컨테이너에 일어난 변화가 이미지에 영향을 주지 않는다.

  • 컨테이너에 아무리 파일을 생성해도 컨테이너를 중지하게 되면 해당 내용은 모두 삭제

  • 컨테이너에 있는 파일을 외부로 가져오거나 외부에 있는 파일을 컨테이너에 복사해서 넣는 것이 가능

host에서 컨테이너에게 파일 복사

  • host -> container
    docker cp file or dir명 컨테이너명:path
#실제로 컨테이너 해당 경로에 파일이 생성된 것을 확인 
touch hostfile # 파일 생성
echo docker cp test > hostfile

# 컨테이너 생성
docker run -itd --name os1 centos:7 

# 파일 복사
docker cp hostfile os1:/root/ 
docker exec os1 ls /root/

------------------------------------

# host에서 컨테이너에게 디렉터리 복사
mkdir hostdir
docker cp hostdir os1:/root/
docker exec os1 ls /root/

컨테이너에서 host에게 파일 복사

  • container -> host
    docker cp 컨테이너명:path/file or dir path(복사할 경로)
# 컨테이너에서 host에게 파일 복사
docker exec -it os1 bash 
cd /root/
touch os1file
exit
# 호스트의 현재 디렉터리로 파일 복사
docker cp os1:/root/os1file ./
ls

-----------------------------------

# 컨테이너에서 host에게 디렉터리 복사
docker exec -it os1 mkdir /root/os1dir 
docker exec os1 ls /root/

# 호스트의 현재 디렉터리로 파일 복사
docker cp os1:/root/os1dir ./

컨테이너 파일 변경 현황

diff = 차이점 (기본 이미지와의 차이점)
-> 기준: 기본 이미지!!!!!

: 원래대로 변경될 경우 따로 화면이 안나온다. 추가된 파일이 사라지면 A가 사라질 뿐이다.

  • docker diff 컨테이너명

    C : change
    A : add
    D : delete

  • 처음 컨테이너 생성후 docker diff os1해보면 아무것도 안뜨는 것을 확인

  • 호스트가 컨테이너에게 파일을 복사한 후 diff로 확인하면 기본 이미지와 차이가 생긴 경로에 C와 A가 나타난 것을 확인

  • root라는 디렉터리에 변화가 생겼고 hostfile이 추가되었음을 의미

  • 컨테이너에서 파일을 삭제한 후 diff를 해보면 D로 파일의 삭제를 알림
profile
전공 소개

0개의 댓글