ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [핵심만 콕! 쿠버네티스] 도커 기초 (도커 소개 및 명령어 총정리)
    📚 개발 도서/핵심만 콕! 쿠버네티스 2023. 7. 12. 23:53

    도커 소개

    도커는 가상실행 환경을 제공해주는 오픈소스 플랫폼이다. 이 가상실행 환경을 컨테이너라고 부른다.

    도커 플랫폼이 설치된 곳이라면 컨테이너로 묶인 애플리케이션을 어디서든 실행할 수 있는 장점을 가진다.

    클라우드 컴퓨팅으로 흐름이 넘어오면서, 서비스를 빠르게 배포할 수 있는 방법을 도커가 제공해준다.

    한번 만들어진 이미지는 온프레미스 서버든 클라우드 서버든 상관없이 언제나 동일하게 동작하기 때문에, 온프레미스와 클라우드 간 간극을 줄여줬다.

    • 표준화
    • 이식성: 도커 플랫폼 위에서 실행된다면 동일한 실행 환경으로 프로세스를 작동시킬 수 있다.
    • 가볍다: 도커는 실행되는 애플리케이션별로 커널을 공유해서, 다른 가상화 제품에 비해 가볍다.
    • 강한 보안: 컨테이너라는 고립된 환경에서 실행되므로 보안에 유리하다.

    컨테이너와 가상머신

    • 가상머신은 기존의 서버에 하이퍼바이저를 설치하고, 그 위에 가상 OS와 APP을 패키징한 VM을 만들어 실행하는 방식인 하드웨어 레벨의 가상화를 지원한다.
    • 반면, 컨테이너는 운영체제를 제외한 나머지 애플리케이션 실행에 필요한 모든 파일을 패키징한다는 점에서 OS레벨 가상화를 지원한다.이는 게스트OS와 하이퍼바이저가 없어서 이로 인한 오버헤들르 줄여 훨씬 더 가볍게 프로세스를 실행할 수 있고 컨테이너에 대한 복제와 배포가 더 용이하다.
    • 도커는 게스트os가 필요없다!!
    • 어플리케이션 레벨에서 필요한 소스코와 관련 라이브러리들을 하나로 패키징하여 별도의 실행 환경을 만드는 것이다.

    CD 플레이러를 빗댄 도커

    사용자가 도커 이미지(CD)만 가지고 있으면 도커 데몬(CD 플레이어)이 설치된 어느 컴퓨터에서든지 도커 프로세스(CD실행)를 실행할 수 있다.

    (컨테이너는 도커 이미지를 기반으로 생성되며, 도커 데몬이 해당 이미지를 사용하여 컨테이너를 실행한다.)

    • 도커 이미지: 사용자가 실행할 코드가 들어잇는 바이너리이다. CD와 마찬가지로 한번 생성하면 수정이 불가하다.
    • 도커 파일: 도커 이미지를 생성하기 위해 필요한 문서다.
    • 도커 컨테이너: 도커 이미지가 메모리 위에 상주하여 실제 코드가 수행되는 프로세스다. 컨테이너는 종료 시 모든 데이터가 휘발한다.
    • 도커 데몬: 컨테이너가 정상적으로 수행될 수 있게 실행환경을 제공한다.
    • 원격 레지스트리: 도커 이미지를 저장할 수 있는 원격 저장소이다.

     

    도커 기본 명령

    컨테이너 실행

    ~/Dev/kubernates-study > docker run docker/whalesay cowsay 'jenny hi'
    
    WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
     __________
    < jenny hi >
     ----------
        \\
         \\
          \\
                        ##        .
                  ## ## ##       ==
               ## ## ## ##      ===
           /""""""""""""""""___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
           \\______ o          __/
            \\    \\        __/
              \\____\\______/
    
    ~/Dev/kubernates-study > docker run docker/whalesay echo jenny hi
    
    WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
    jenny hi
    

     

    도커 이미지 주소의 형식

    <레지스트리 이름> / <이미지 이름> : <TAG>
    
    • 기본 레지스트리 주소: docker.io
    • 기본 사용 TAG: latest

    -d 옵션: 컨테이너를 백그라운드로 실행시켜주는 옵션

    ~/Dev/kubernates-study > docker run -d  nginx
    e52ee85015d60cf9867375d4fdc9d3694530f98eabc7e1fba09d17c8cef7ed20
    # 컨테이너 ID 반환
    

     

     

    컨테이너 조회

    docker ps
    

     

    컨테이너 상세정보 확인

    네트워크, 볼륨 등 컨테이너에 대한 모든 정보를 포함하고 있다.

    docker inspect <컨테이너 ID>
    

    컨테이너 로깅: 컨테이너에서 출력되는 로그 기록 확인

    docker logs <컨테이너 ID>
    

    -f 옵션: 백그라운드로 실행된 컨테이너 로그를 직접 확인할 수 있다.

     

     

    컨테이너에 명령어 전달

    docker exec <컨테이너 ID> <CMD>
    
    docker exec d7455a395f1a sh -c 'apt update && apt install -y wget'
    docker exec d7455a395f1a wget localhost
    
    더보기

    위처럼 exec 명령으로 nginx 컨테이너에 wget을 설치하고 localhost로 요청을 보내보자.

     

    ~/Dev/kubernates-study > docker exec e52ee85015d60cf9867375d4fdc9d3694530f98eabc7e1fba09d17c8cef7ed20 sh -c 'apt update && apt install -y wget'
    
    WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
    
    Get:1 http://deb.debian.org/debian bookworm InRelease [147 kB]
    Get:2 http://deb.debian.org/debian bookworm-updates InRelease [52.1 kB]
    Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
    Get:4 http://deb.debian.org/debian bookworm/main arm64 Packages [8802 kB]
    Get:5 http://deb.debian.org/debian-security bookworm-security/main arm64 Packages [28.3 kB]
    Fetched 9077 kB in 2s (5319 kB/s)
    Reading package lists...
    Building dependency tree...
    Reading state information...
    All packages are up to date.
    
    WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
    
    Reading package lists...
    Building dependency tree...
    Reading state information...
    The following NEW packages will be installed:
      wget
    0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
    Need to get 967 kB of archives.
    After this operation, 3683 kB of additional disk space will be used.
    Get:1 http://deb.debian.org/debian bookworm/main arm64 wget arm64 1.21.3-1+b1 [967 kB]
    debconf: delaying package configuration, since apt-utils is not installed
    Fetched 967 kB in 0s (6572 kB/s)
    Selecting previously unselected package wget.
    (Reading database ... 7598 files and directories currently installed.)
    Preparing to unpack .../wget_1.21.3-1+b1_arm64.deb ...
    Unpacking wget (1.21.3-1+b1) ...
    Setting up wget (1.21.3-1+b1) ...
    
    
    ~/Dev/kubernates-study > docker exec e52ee85015d60cf9867375d4fdc9d3694530f98eabc7e1fba09d17c8cef7ed20 wget localhost
    --2023-06-20 15:31:37--  http://localhost/
    Resolving localhost (localhost)... 127.0.0.1, ::1
    Connecting to localhost (localhost)|127.0.0.1|:80... connected.
    HTTP request sent, awaiting response... 200 OK
    Length: 615 [text/html]
    Saving to: 'index.html'
    
         0K                                                       100%  139M=0s
    
    2023-06-20 15:31:37 (139 MB/s) - 'index.html' saved [615/615]

    컨테이너 / 호스트간 파일 복사

    실행한 컨테이너와 호스트 서버간에 파일을 주고받을 수 있다.

    docker cp <HOST_PATH> <CONTAINER_ID>:<CONTAINER_PATH>
    
    # host -> container 로 이동 
    docker cp /etc/passwd d7455a395f1a:/usr/share/nginx/html/.
    # container -> host 로 이동 
    docker cp d7455a395f1a:/usr/share/nginx/html/index.html .
    

     

    컨테이너 중단/재개/삭제

    docker stop <컨테이너 ID> # 중단
    docker start <컨테이너 ID> # 재개
    docker rm <컨테이너 ID> # 삭제

     

    Interactive 컨테이너

    • -it : interactive(stdin, stdout 연결), tty(터미널 연결)의 약자다.
    • 이미지 실행 시, -it 옵션을 통해 직접 컨테이너 안으로 접속해 작업할 수 있다.
    # 이미지를 실행하면서 bash 쉘을 실행
    docker run -it ubuntu:16.04 bash
    

     

     

     

    도커 파일 작성

    나만의 도커 이미지를 만들어보자. 도커 이미지를 생성하기 위해서는 Dockerfile라는 텍스트 문서를 작성해야 한다.

    사용자는 Dockerfile에 특정 명령을 기술하여 원하는 도커 이미지를 생성한다.

    특정 명령

    • Dockerfile에 기반 이미지(base image)를 지정
    • 원하는 소프트웨어 및 라이브러리를 설치하기 위한 명령을 기술
    • 컨테이너 실행 시 수행할 명령을 기술

    Dockerfile 기초

    hello.py

    import os
    import sys
    
    my_ver = os.environ["my_ver"]
    arg = sys.argv[1]
    
    print(f"Hello {arg}, my version is {my_ver}!")
    

    Dockerfile

    # 기반 이미지를 나타낸다. 해당 이미지를 기반으로 도커 이미지가 생성된다.
    FROM ubuntu:18.04 
    
    # 사용자가 지정한 명령을 실행하는 지시자
    RUN apt-get update \\ 
        && apt-get install -y \\
        curl \\
        python3-dev
    
    # 이미지의 작업 폴더를 지정한다. 여기선 /root
    WORKDIR /root
    # 로컬 호스트에 존재하는 파일을 이미지 안으로 복사하는 지시자
    COPY hello.py .
    # 이미지의 환경변수 지정
    ENV my_ver 1.0
    
    # 이미지 실행 시, default로 실행되는 명령어 지정
    CMD ["python3", "hello.py", "jenny"]
    

    도커 빌드

    작성한 Dockerfile을 도커 이미지로 변환하기 위해 빌드 명령을 수행한다.

    docker build <PATH> -t <IMAGE_NAME>:<TAG>
    # <PATH>: Dockerfile이 위치한 디렉터리
    

    이미지에 넘겨주는 파라미터에 따라 어떻게 동작하는지 살펴보자

    # 생성한 이미지로 컨테이너 생성
    > docker run hello:1
    Hello jenny, my version is 1.0!
    
    # 파라미터로 명령어를 넘긴다 -> 도커파일 스크립트에 CMD가 되어있다면, 기존 CMD 명령은 override 된다
    > docker run hello:1 echo "hello world!"
    hello world
    
    # -e 옵션으로 컨테이너 실행시 환경변수 주입 
    > docker run -e my_ver=1.5 hello:1
    Hello jenny, my version is 1.5!
    
    > docker run hello:1 pwd
    /root
    

     

     

    Dockerfile 심화

    ARG

    Dockerfile 안에서 사용할 수 있는 매개변수를 정의한다. 파라미터로 넘겨지는 수의 값에 따라, 생성되는 이미지 내용을 바꿀 수 있다.

    FROM ubuntu:18.04 
    
    RUN apt-get update \\ 
        && apt-get install -y \\
        curl \\
        python3-dev
    
    **ARG** my_ver=1.0
    
    WORKDIR /root
    COPY hello.py .
    ENV my_ver $my_ver
    
    CMD ["python3", "hello.py", "jenny"]
    

    이미지 빌드 시, --build-arg 옵션을 이용하여 ARG 값을 덮어씌울 수 있다.

    > docker build . -t hello:2 --build-arg my_ver=2.0
    > docker run hello:2
    Hello jenny, my version is 2.0!
    

    ENTRYPOINT

    CMD와 유사하지만 실행 명령이 override 되지 않고 실행 가능한 이미지를 만든다.

    FROM ubuntu:18.04 
    
    RUN apt-get update \\ 
        && apt-get install -y \\
        curl \\
        python3-dev
    
    WORKDIR /root
    COPY hello.py .
    ENV my_ver 1.0
    
    ENTRYPOINT ["python3", "hello.py", "jenny"]`
    

    다음과 같이 hello:4 로 이미지를 만들어 실행해보자.

    ~/Dev/kubernates-study > docker run hello:4 new-guest
    Hello new-guest, my version is 1.0!
    ~/Dev/kubernates-study > docker run hello:4 pwd
    Hello pwd, my version is 1.0!
    ~/Dev/kubernates-study > docker run hello:4 echo "hello"
    Hello echo, my version is 1.0!
    

     

    도커 실행 고급

    Network

    docker run -p <HOST_PORT>:<CONTAINER_PORT> <IMAGE_NAME>
    

    포트 포워딩을 통해 외부 트래픽을 컨테이너 내부로 전달

    • 도커 컨테이너 생성(docker run) -p 옵션을 통해 포트 포워딩 가능
    • ip 확인 방법
      • 내부 IP : hostname -i 또는 ifconfig
      • 공인 IP : curl ifconfig.co
    # host의 5000번 포트로 요청하면, 컨테이너의 80번 포트로 매핑 
    docker run -p 5000:80 -d nginx
    
    curl localhost:5000
    

     

    Volume

    docker run -v <HOST_DIR>:<CONTAINER_DIR> <IMAGE_NAME>
    

    컨테이너는 휘발성 프로세스이기 때문에 내부 데이터를 영구적으로 저장할 수 없다. 지속적으로 보관하기 위해서는 볼륨이라는 것을 사용한다.

    컨테이너 실행 시, 로컬 호스트의 파일시스템을 컨테이너와 연결하여 필요한 데이터를 로컬 호스트에 저장할 수 있다.

    # 현재 디렉토리를 컨테이너의 nginx 디렉터리에 연결한다.
    docker run -p 6060:80 -v $(pwd):/usr/share/nginx/html -d nginx
    
    # 현재 디렉토리에 hello.txt 파일을 생성한다.
    echo hello! >> $(pwd)/hello.txt
    
    # nginx 내부에서 해당 파일이 보이는지 확인한다.
    curl localhost:6060/hello.txt
    

     

    Entrypoint

    --entrypoint 옵션으로 ENTRYPOINT를 강제로 override 하는 방법이 있다.

    # 이미지 생성 및 컨테이너 생성 
    docker build -t lets-echo
    docjer run lets-echo hello
    # hello
    
    # entrypoint를 cat 명령으로 override
    docker run --entrypoint=cat lets-echo /etc/passwd
    

     

    User

    기본적으로 컨테이너 유저는 root이다. 하지만 보안상의 이유로 root가 아닌 일반 유저를 사용하도록 만들 수 있다.

    # DockerFile
    FROM ubuntu:18.04
    RUN adduser --disabled-password --gecos "" ubuntu # ubuntu 유저 생성
    USER ubuntu # 컨테이너 실행 시 ubuntu로 실행
    
    # 도커파일을 통해 이미지 생성 및 컨테이너 실행 
    docker build -t my-user
    docker run -it my-user bash
    # ubuntu 유저로 로그인
    apt get
    # permission denied
    

    ubuntu는 root가 아니므로 root 권한이 필요한 apt 사용하게 되면 퍼미션 에러가 발생한다.

    컨테이너 실행 시, —user 옵션을 이용하여 명시적으로 유저를 입력할 수도 있다.

    # 강제로 root 유저 사용
    docker run --user root -it my-user bash
    

     

    Clean up

    docker rm $(docker ps -aq) -f
    docker rmi $(docker images -q) -f
    
    728x90
    반응형

    댓글

Designed by Tistory.