ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Docker 한방 요약 정리
    Engineering WIKI/Docker 2020. 1. 17. 14:33

    1. Docker란?

    • Docker는 리눅스 컨테이너 기술을 기반으로 하는 오픈 소스 가상화 플랫폼

    2. Container(컨테이너) vs Virtual Machine(가상머신)

      • Virtual Machine :
          • 하드웨어 가상화 소프트웨어로 구현된 하드웨어
          • 소프트웨어로 구현된 하드웨어 그 위에 OS를 설치하고, 그 위에 소프트웨어를 설치함으로써 무겁고 느린 단점
          • 위 단점으로 반가상화 기술방식의 Xen이 등장하였지만, 성능문제는 해결되지 못함
          • 예 : VMWare, VirtualBox 등
      • Container:
          • 리눅스에서 하드웨어 가상화와 OS설치를 하지 않고 단순히 프로세스를 단독으로 격리시키는 기술 컨테이너라는 기술이 등장
          • 하드웨어 및 OS 계층을 두지 않고 프로세스만 격리하므로 실제 그냥 앱을 실행하는 경우와 거의 차이가 보이지 않을 정도로 Virtual Machine 에 비해 성능문제가 해결됨
          • 리눅스 OS에서 지원하는 기술로 LXC(Linux Container)라는 시스템 레벨의 컨테이너 기술을 제공
          • 초기 Docker는 LXC 기술을 채용했으나, 0.9버전 이후에는 libcontainer라는 자체 컨테이너 사용

    3. Docker 실행환경별 차이점

    • Linux : 리눅스 컨테이너 기술을 기반으로 하기 때문에 Native 하게 지원됨
    • Mac & Windows : 내부에 경량의 Linux 가상머신을 띄운 후에 실행됨,(Mac에서는 xhyve, Windows에서는 Hyper-V가 내부에서 실행됨)
    • Windows : 리눅스 컨테이너와 Win32 네이티브 컨테이너를 함께 가지고 있으며 선택할 수 있음.
     
     

    1. Play With Docker

    • Docker 웹 상에서 실행해볼 수 있는 사이트, 웹상에서 리눅스 쉘화면이 노출되며, Docker가 미리 설치되어 있는 가상머신을 제공해준다.

    02-01

    2. Docker for Mac/Windows 설치

    ~ docker version
    
    Client:
     Version:      18.03.1-ce
     API version:  1.37
     Go version:   go1.9.5
     Git commit:   9ee9f40
     Built:        Thu Apr 26 07:13:02 2018
     OS/Arch:      darwin/amd64
     Experimental: false
     Orchestrator: swarm
    
    Server:
     Engine:
      Version:      18.03.1-ce
      API version:  1.37 (minimum version 1.12)
      Go version:   go1.9.5
      Git commit:   9ee9f40
      Built:        Thu Apr 26 07:22:38 2018
      OS/Arch:      linux/amd64
      Experimental: true

    3. Linux Docker 설치

    3.1 CentOS 7 이상 설치

    • 이전 버전 제거
    $ sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-selinux \
                      docker-engine-selinux \
                      docker-engine
    • 최신 저장소 설정
    $ sudo yum install -y yum-utils \
      device-mapper-persistent-data \
      lvm2
    
    $ sudo yum-config-manager \
          --add-repo \
          https://download.docker.com/linux/centos/docker-ce.repo
    • Docker 설치 (최신버전 설치)
    $  yum install docker-ce 
    • Docker 설치 (특정 버전)
    $ yum list docker-ce --showduplicates | sort -r
    docker-ce.x86_64            18.03.1.ce-1.el7.centos            docker-ce-stable 
    docker-ce.x86_64            18.03.1.ce-1.el7.centos            @docker-ce-stable
    docker-ce.x86_64            18.03.0.ce-1.el7.centos            docker-ce-stable 
    ...
    
    $ yum install docker-ce-<버전번호>
    $ yum install docker-ce-<버전번호> 
    • Docker 서비스 등록 및 시작
    $ sudo systemctl enable docker
    $ sudo systemctl start docker
    • (선택사항)docker 유저 그룹 생성 및 특정 유저를 docker 그룹에 귀속
    $ sudo groupadd docker
    $ sudo usermod -aG docker $USER
    • docker run 확인
    $ docker run hello-world
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/engine/userguide/

    3.2 Ubuntu 설치

    • 이전 버전 제거
    $ sudo apt-get remove docker docker-engine docker.io 
    • apt 패키지 색인 업데이트
    $ sudo apt-get update 
    • HTTPS를 통해 저장소 사용할 수 있도록 설정
    $ sudo apt-get install \
          apt-transport-https \
          ca-certificates \
          curl \
          software-properties-common
    • Docker 공식 GPG 키 추가
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 
    • 가장 안정적인 저장소 추가
    $ sudo add-apt-repository \
         "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
         $(lsb_release -cs) \
         stable"
    • Docker 저장소 업데이트
    $ sudo apt-get update 
    • Docker 설치
    $ sudo apt-get install docker-ce

     

     

    1. Docker 이미지 검색하기

    $ docker search ubunutu
    
    NAME                                    DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
    arvindr226/ubunutu14.04-ssh             The Docker image for ssh in Ubuntu 14.04        1                                       [OK]
    jpdc/ubunutu-apache-php-pgsql           Apache2, php5 and pgsql 9.3                     1                                       
    jrlehtinen/ub14pfed                     Launches PingFed 9.0.2 in standalone mode on…   1                                       
    csmanioto/pdi                           PDI With XRPD on Ubunutu 14                     0                                       
    dawu415/ubunutu_java_buildpack_tools                                                    0                                       
    gissehel/ubuntu-base                    Base for all my images created from an ubunu…   0                                       [OK]
    waxzce/rust-1.7                         ubunutu based rust 1.7                          0                                       
    v0rts/docker-ubuntu1604-ansible         Ubunutu 16.04 image used for application ans…   0                                       [OK]
    ...

    2. 이미지 받아 오기

    • ubuntu 최신버전 받아오기
    $ docker pull ubuntu:latest 

    3. 이미지 목록 확인하기

    • 다운로드 받은 이미지 목록 출력하기
    $ docker images
    
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    ubuntu              latest              113a43faa138        5 days ago          81.2MB
    hello-world         latest              e38bc07ac18e        2 months ago        1.85kB

    4. docker 이미지로 컨테이너 실행하기

    • docker 이미지를 컨테이너로 생성한 뒤 Bash를 실행합니다.
    • -it : 옵션을 통해 docker 이미지 컨테이너의 bash 쉘을 실행 시킵니다.
      • -i : interactive
      • ‘-t’ : 가상 tty(터미널같은입력창) 할당
    • bash를 사용할 수있도록 실행합니다.
    • docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    $ docker run -it ubuntu /bin/bash
    root@fefe911e20e7:/#
    • 내부에서 ls 명령어를 입력해봅니다. 격리된 공간에서 ubuntu가 실행되었고 내부에서 실행이 가능해집니다.

    5. docker 컨테이너 실행 확인

    • 커맨드 라인 창을 하나 더 실행하여 아래의 명령어를 입력합니다.
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
    fefe911e20e7        ubuntu              "/bin/bash"         About a minute ago   Up About a minute                       sharp_varahamihira

    6. 실행 중인 docker 정지 시키기

    • 실행 중인 docker 창은 두고 다른 창에서 아래의 명령 실행하기
    • sharp_varahamihira 는 docker ps에 나온 NAMES 항목이다.
    • docker가 컨테이너 실행 시 이름을 명시적으로 지정하지 않으면 임의의 이름을 생성한다.
    • docker stop <컨테이너 이름 또는 ID>
    $ docker stop sharp_varahamihira 
    • 실행 중 이던 화면은 아래와 같이 나온다.
    • docker 가 실행화면에서 exit 명령어를 입력하면 똑같은 효과가 생긴다.
    root@fefe911e20e7:/# exit $ 

    7. 정지된 컨테이너 다시 실행하기

    • docker start <컨테이너 이름 또는 ID>
    $ docker start sharp_varahamihira 
    • 실행 확인
    $ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    fefe911e20e7        ubuntu              "/bin/bash"         12 minutes ago      Up 18 seconds                           sharp_varahamihira

    8. 실행 중 컨테이너에 접속하기

    • docker attach <컨테이너 이름 또는 ID>
    $ docker attach sharp_varahamihira
      root@fefe911e20e7:/#

    9. 외부에서 컨테이너 안의 명령어 실행하기

    • docker exec <컨테이너 이름 또는 ID> 명령어
    $ docker exec sharp_varahamihira echo "Hello Docker"
    Hello Docker

    10. 컨테이너 삭제 하기

    • docker rm <컨테이너 이름 또는 ID
    • 기본적으로 아래의 명령어는 실행이 정지된 상태에서만 유효하다.
    $ docker rm sharp_varahamihira 
    • 실행 중인 컨테이너의 경우 강제로 지우겠다는 옵션 -f 를 추가 해야한다.
    $ docker rm -f sharp_varahamihira 

    11. 이미지 삭제 하기

    • docker rmi <이미지 이름>:<태그>
    $ docker rmi ubuntu:latest 
    • 삭제 확인
    $ docker images 

    12. MySQL 서비스 올리기

    • -d 는 데몬으로 실행 옵션
    • -p 는 포트 연결 옵션 서버포트:컨테이너포트
    • -e 는 환경 변수
    • 외부에서 3307 포트로 접속이 가능하다.
    $ docker run -d -p 3307:3306 --name mysql -e MYSQL_DATABASE=homestead -e MYSQL_USER=homestead -e MYSQL_PASSWORD=homestead -e MYSQL_ROOT_PASSWORD=qwer1234 mysql:5.7

     

     

    Docker Image 만들기 1

     

    1. Dockerfile 이란?

    • 컨테이너 내부 환경을 정의함
    • Docker 이미지 외부 리소스와의 맵핑 정보를 정의함
    • 빌드가 성공적으로 이루어진 이미지의 경우 Docker가 설치된 어디에서나 똑같이 실행될 것을 기대할 수 있음.

     

    2. Dockerfile 간단 작성

    • 특정 경로에 디렉토리를 생성 한후 .dockerignore 파일을 생성한다.
      • .dockerignore : docker 이미지 빌드 시 무시 될 파일들을 기재한다. .gitignore와 비슷하다.
     node_modules
     npm-debug.log
     Dockerfile*
     docker-compose*
     .dockerignore
     .git
     .gitignore
     README.md
     LICENSE
     .vscode
    1. Dockerfile 작성
      • python관련 이미지를 기반으로,
       # 파이썬 이미지를 기반으로 함
       FROM python:2.7-slim
          
       # Docker 이미지 내부에서 RUN, CMD, ENTRYPOINT의 명령이 실행될 디렉터리를 설정
       WORKDIR /app
          
       # 현재 디렉터리에 있는 파일들을 이미지 내부 /app 디렉터리에 추가함
       ADD . /app
          
       # requirements.txt 파일을 기반으로 파이썬 패키지들을 실행함
       RUN pip install --trusted-host pypi.python.org -r requirements.txt
          
       # 80포트를 외부로 노출함
       EXPOSE 80
          
       # 환경변수를 설정함
       ENV NAME World
          
       # 쉘을 사용하지 않고 컨테이너가 시작되었을 때 아래 명령을 실행함 'python app.py' 가 실행됨
       CMD ["python", "app.py"]
    2. requirements.txt 작성
    3. Flask Redis 
    4. app.py 파일 작성
      • 파이썬 웹프레임워크인 flask를 이용한 코드 작성
       from flask import Flask
       from redis import Redis, RedisError
       import os
       import socket
          
       # Connect to Redis
       redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
          
       app = Flask(__name__)
          
       @app.route("/")
       def hello():
           try:
               visits = redis.incr("counter")
           except RedisError:
               visits = "<i>cannot connect to Redis, counter disabled</i>"
          
           html = "<h3>Hello {name}!</h3>" \
                  "<b>Hostname:</b> {hostname}<br/>" \
                  "<b>Visits:</b> {visits}"
           return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
          
       if __name__ == "__main__":
           app.run(host='0.0.0.0', port=80)
    5. Dockerfile을 기반으로 이미지 빌드하기
      • friendlyhello 라는 이름으로 현재 디렉토리를 빌드함.
      • 마지막에 . 주의 요망 현재디렉토리라는 것을 명시 해야함.
      • docker build -t <이미지이름>:<태그> <경로>
      • 태그를 생략할 경우 자동으로 latest 가 붙는다.
      • -t 옵션 : 이미지 명칭과 태그를 지정하는 옵션
       $ docker build -t friendlyhello:first . 
    6. 이미지 확인
      1. $ docker images
            
         REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
         friendlyhello       first               af346c6c2f35        About a minute ago   132MB
         python              2.7-slim            d0d1b97dd328        6 days ago           120MB
    7. 이미지 실행 ($ docker run -p 4000:80 friendlyhello:first)
    8. 로컬에서 웹서버 구동 확인 

     

    1. .dockerignore

    • docker 이미지 빌드시 무시할 파일들을 입력합니다.
    • .gitignore 와 유사합니다.

     

    2. FROM

    • 어떤 이미지를 기반으로 생성할지 기록합니다. 부모이미지가 됩니다.
    • 이미지 이름만 입력할 수도, 태그와 함께 입력할 수도 있습니다.
    • FROM은 항상 설정해야하고, 맨 첫 줄에 설정해야합니다.
    • FROM에 설정한 이미지가 로컬에 있으면 로컬을 우선 적용하고, 없으면 Docker Hub에서 받아 옵니다.
    • FROM은 여러개 설정할 수 있습니다.
    FROM ubuntu
    FROM ubuntu:14.07

     

    3. MAINTAINER

    • MAINTAINER는 Dockerfile 작성자를 입력합니다. 생략 가능
    MAINTAINER Suwoni <suwoni@suwoni.com>

    4. WORKDIR

    • WORKDIR은 RUN과 CMD등의 Dockerfile에 사용되는 이미지 내부에서 실행할 명령어의 실행 디렉터리를 설정합니다.
    WORKDIR /app/src 

    5. ADD

    • ADD는 파일을 이미지에 추가
    • 압축파일인 경우 해제 후 추가(tar.gz의 경우 gz만 해제하고 추가합니다.)
    • 인터넷 경로를 입력할 수 있습니다.
    ADD test.sh /entrypoint.sh
    ADD . /src-dir
    ADD test.zip /test
    ADD http://blog.news.com/a.txt /b.txt

    6. COPY

    • ADD 와 비슷하게 파일을 이미지에 추가
    • 압축파일을 해제 하지 않음
    • URL 사용할 수 없음

    7. RUN

    • FROM에서 설정한 이미지 위에서 스크립트 혹은 명령을 실행
    • 쉘로 실행하기(이미지에 /bin/sh 실행파일이 있는 경우)
    RUN apt-get install -y  nginx
    RUN git clone https://github.com/docker/docker.git
    • 쉘없이 바로 실행하기(이미지에 /bin/sh 실행파일이 없는 경우)
    RUN ["apt-get", "install", "-y", "nginx"]
    RUN ["git", "clone", "https://github.com/docker/docker.git"]

    8. CMD

    • 이미지가 컨테이너로 실행이 시작될 때 실행(docker run 또는 docker start 시)
    • Dockerfile에서 한번만 사용할 수 있음
    • 쉘로 실행하기(이미지에 /bin/sh 실행파일이 있는 경우)
    CMD git clone https://github.com/docker/docker.git 
    • 쉘없이 바로 실행하기(이미지에 /bin/sh 실행파일이 없는 경우)
    CMD ["git", "clone", "https://github.com/docker/docker.git"] 

    9. ENTRYPOINT

    • CMD 와 마찬가지로 이미지가 컨테이너로 실행이 시작될 때 실행(docker run 또는 docker start 시)
    • Dockerfile에서 한번만 사용할 수 있음
    • 실행 형식은 CMD와 동일

    10. ENTRYPOINT와 CMD가 동시에 사용되는 경우

    • CMD는 ENTRYPOINT에 매개 변수만 전달하는 역할을 합니다.
    ENTRYPOINT ["echo"]
    CMD ["hello docker"]

    11. CMD와 ENTRYPOINT 차이

    • CMD는 docker run 실행 시 바로 명령어를 입력하는 경우 Dockerfile에 CMD는 무시됩니다.
    FROM ubuntu
    CMD ["echo", "Hello, Docker"]
    $ docker run ubuntuimage echo world
    world
    • ENTRYPOINT의 경우 실행시 --entrypoint 옵션을 줄 경우 무시됩니다.
    $ docker run --entrypoint="cat" 이미지명 

    12. EXPOSE

    • 노출시킬 port를 설정 docker run 명령어의 --expose옵션과 동일
    • 한꺼번에 작성 또는 여러줄 작성 가능
    EXPOSE 80 443 21 
    EXPOSE 80
    EXPOSE 443
    EXPOSE 21

    13. ENV

    • 환경변수 설정
    • 환경변수는 RUN, CMD, ENTRYPOINT에서도 적용가능
    ENV ENV_VARIABLE aaaa
    CMD echo $ENV_VARIABLE
    • ENV 에서 설정한 값을 docker run 시에 변경할 수 있습니다.
    $ docker run -e ENV_VARIABLE=bbbb 이미지명
    bbbb
    1. VOLUME
    • 디렉터리 내용을 컨테이너에 저장하지 않고 호스트에 저장하도록 설정
    VOLUME /data
    VOLUME ["data", "/var/log/hello"]
    • 위 처럼 설정할 경우 호스트(이미지를 실행한 os환경)에서 /var/lib/docker/volumes 아래의 임의의 난수로 저장된 디렉토리 안에 데이터가 들어가므로 좋은 방법이 아니다.
    • docker run -v <호스트디렉토리>:<컨테이너디렉토리> 형식으로 이미지 내부디렉토리를 호스트 디렉토리로 연결할 수 있다.
    1. ONBUILD
    • 생성한 이미지를 기반으로 다른 이미지가 생성될 때 명령을 실행

     

Designed by Tistory.