IT STUDY LOG

[Docker] 03. Docker Image 다루기 본문

devops bootcamp 4/클라우드 서비스 운영

[Docker] 03. Docker Image 다루기

roheerumi 2023. 4. 12. 16:00

# 학습 목표

  • 컨테이너 기술이 무엇인지, Docker가 왜 필요한지 알 수 있다.
  • 컨테이너와 이미지, 레지스트리가 무엇인지 이해할 수 있다.
  • 대표적인 레지스트리인 Docker Hub에서 이미지를 검색하고, 사용할 수 있다.
  • 한 개의 이미지를 이용해서 컨테이너를 구축할 수 있다.
  • 두 개 이상의 이미지를 이용해서 컨테이너를 구축하고 서로가 어떻게 연결되는지 알 수 있다.
  • Docker CLI에서 명령어를 사용해서 이미지를 생성/수정/배포하고, 컨테이너를 생성/삭제할 수 있다.
  • Dockerfile을 이용해 이미지를 생성할 수 있다.
  • 애플리케이션을 컨테이너화할 수 있다.

 


# 학습 내용

1.  한 개의 Docker Image를 다루는 방식 연습

실습 자료

- 도커 이미지 레파지토리 : sebcontents/part1 이미지 repository

 

Docker

 

hub.docker.com

- 웹 서버 소스 코드 파일 :  https://github.com/codestates/SpaceInvaders 

 

GitHub - codestates/SpaceInvaders

Contribute to codestates/SpaceInvaders development by creating an account on GitHub.

github.com

$ git clone git@github.com:codestates/SpaceInvaders.git
'SpaceInvaders'에 복제합니다...
remote: Enumerating objects: 83, done.
remote: Total 83 (delta 0), reused 0 (delta 0), pack-reused 83
오브젝트를 받는 중: 100% (83/83), 1.05 MiB | 1.06 MiB/s, 완료.
델타를 알아내는 중: 100% (25/25), 완료.

 

Step 0 : 아파치 웹 서버 이미지(httpd)를 기반으로 한 도커 이미지 다운로드 후 컨테이너 생성, 소스코드를 복사

# 컨테이너 이미지 다운로드 후 컨테이너를 3000포트에서 백그라운드로 실행
$ docker run --name devops_game -d -p 3000:80 sebcontents/part1;
Unable to find image 'sebcontents/part1:latest' locally
latest: Pulling from sebcontents/part1
69692152171a: Pull complete 
7284b4e0cc7b: Pull complete 
3678b2d55ccd: Pull complete 
aeb67982a725: Pull complete 
06954f8169fd: Pull complete 
5a69a0fbc9a4: Pull complete 
Digest: sha256:f4e361540471040738958dcd1a21c0a338b16acfe0159aee0b55341c7042b50b
Status: Downloaded newer image for sebcontents/part1:latest
202a3eec56ad55f1267711d47ad244786eee21a0dcbc7c0c24b95a5266733396

# 도커 프로세스 확인
$ docker ps
CONTAINER ID   IMAGE                      COMMAND              CREATED          STATUS          PORTS                                   NAMES
1e4b28c41ec3   sebcontents/part1:latest   "httpd-foreground"   15 minutes ago   Up 15 minutes   0.0.0.0:3000->80/tcp, :::3000->80/tcp   devops_game
# 소스코드 파일 위치가 있는 곳에서 컨테이너에 소스코드 복사
$ docker container cp ./ devops_game:/usr/local/apache2/htdocs
Preparing to copy...
Copying to container - 32.77kB
Copying to container - 65.54kB
# ... 중략 ... #
Copying to container - 2.458MB
Copying to container - 2.49MB
Copying to container - 2.498MB
Successfully copied 2.498MB to devops_game:/usr/local/apache2/htdocs

$ docker container ls
CONTAINER ID   IMAGE                      COMMAND              CREATED         STATUS         PORTS                                   NAMES
1e4b28c41ec3   sebcontents/part1:latest   "httpd-foreground"   3 minutes ago   Up 3 minutes   0.0.0.0:3000->80/tcp, :::3000->80/tcp   devops_game

 

Step 1 : 컨테이너 복사 후 웹 브라우저에서 정상 기동 확인

 

Step 2 : 컨테이너 속 txt 파일 안에 있는 단어 확인

docker exec -it 컨테이너_이름 bash

- 컨테이너 내부에서 bash shell을 실행

  >  -i, --interactive 옵션 : 도커 컨테이너와 상호작용할 때 표준 출력을 계속 열어줌
  > -t, --tty 옵션 : 가상 터미널을 할당 

# 생성한 컨테이너 내에서 배시쉘 실행
$ sudo docker exec -it devops_game bash

# root@이후 오는 번호는 랜덤
root@1e4b28c41ec3:/usr/local/apache2# 

# 경로 이동
root@1e4b28c41ec3:/usr/local/apache2# cd /
root@1e4b28c41ec3:/# cd data/
root@1e4b28c41ec3:/data# ls
quiz2.txt

# apt 업데이트 후 필요한 모듈 다운
root@1e4b28c41ec3:/data# apt update
root@1e4b28c41ec3:/data# apt install vim

# 내용 확인
root@1e4b28c41ec3:/data# cat quiz2.txt
kimcoding

# exit 명령어로 종료
root@1e4b28c41ec3:/data# exit

 

2. 두 개의 Docker Image를 다루는 방식 연습

실습 자료

출처 : 코드스테이츠 데브옵스 부트캠프 과정

- localhost:8080으로 접속할 경우 sebcontents/client 이미지를 이용해 배포한 client 컨테이너의 80 번 포트로 연결

 > nginx 이미지를 기반으로 한 sebcontents/client 이미지를 이용하여 client 컨테이너를 생성

 

Docker

 

hub.docker.com

 > node 이미지를 기반으로 한 sebcontents/server 이미지를 이용하여 server 컨테이너를 생성

 

Docker

 

hub.docker.com

# 레파지토리로부터 이미지 다운로드
$ docker pull sebcontents/server
$ docker pull sebcontents/client

# 정상적으로 다운로드되었는지 확인
$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
sebcontents/server   latest    6d83150df9dd   15 months ago   178MB
sebcontents/client   latest    52bfef33cd3d   15 months ago   142MB

 

Step 0 : docker-compose CLI 사용

도커 컴포즈

- 도커를 사용하여 멀티 컨테이너(Docker Container) 기반 애플리케이션을 정의, 구성, 실행하는 도구

- YAML 파일 형식으로 작성된 설정 파일을 사용하여 여러 개의 도커 컨테이너를 하나의 애플리케이션 스택으로 정의하고, 동시에 실행 및 관리 가능

- 애플리케이션의 다양한 서비스(Component)들을 정의하고, 각 서비스의 설정, 환경 변수, 볼륨 마운트 등 지정이 가능하며 컨테이너들 간의 네트워크 연결, 종속성 관리, 스케일링 등을 제어할 수 있어 복잡한 멀티 컨테이너 애플리케이션의 배포와 관리를 용이하게 함

- 도커 컴포즈를 사용하면 개발 환경에서의 애플리케이션 구성 및 테스트, 스테이징 환경에서의 애플리케이션 배포, 프로덕션 환경에서의 애플리케이션 운영 등에서 일관된 도커 컨테이너 구성과 실행을 할 수 있어 개발과 운영의 일관성 유지 가능

# docker-compose.yaml에 정의된 이미지를 컨테이너로 실행
docker-compose up # -d 옵션을 함께 사용하면, 컨테이너를 백그라운드로 실행 가능

# docker-compose.yaml에 정의된 이미지를 이용해 실행된 컨테이너를 종료
docker-compose down

# 특정 이미지만 컨테이너로 실행
docker-compose up {특정 이미지}

 

Step 1 : docker-compose.yaml (yml) 파일 생성

- 하나의 docker-compose에서 관리되는 컨테이너끼리는 동일한 docker network에서 구동 (docker run 명령과 다르게 docker-compose 파일 안에서 기본 network가 사용됨)

# docker-compose.yaml(docker-compose.yml) 파일 생성, 위치는 무관 
version: '3.8'

services:
  nginx:
    image: sebcontents/client
    restart: 'always'
    ports:
      - "8080:80"
    container_name: client

  node:
    image: sebcontents/server
    restart: 'always'
    ports:
      - "4999:80"
    container_name: server

 

Step 2 : yaml 파일이 있는 위치에서 yaml 파일 실행

# docker compose v2의 경우 v1 명령어인 docker-compose 명령어가 적용되지 않음 
$ docker-compose up -d
ERROR: Version in "./docker-compose.yaml" is unsupported. You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/

# docker compose 명령어 사용
$ docker compose up -d
[+] Running 3/3
 ✔ Network docker_compose_study_default  Created                                                                                   0.2s 
 ✔ Container server                      Started                                                                                   2.3s 
 ✔ Container client                      Started
 
 # 도커 컨테이너 동작 확인
 $ docker container ls
CONTAINER ID   IMAGE                COMMAND                   CREATED         STATUS         PORTS                                   NAMES
6dc5aaf5b4b6   sebcontents/client   "/docker-entrypoint.…"   6 minutes ago   Up 6 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   client
5cfe69f19c0a   sebcontents/server   "docker-entrypoint.s…"   6 minutes ago   Up 6 minutes   0.0.0.0:4999->80/tcp, :::4999->80/tcp   server

 # 네트워크 소켓에 정상기동 되었는지 확인
 $ sudo netstat -antp | grep "docker"
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      24015/docker-proxy  
tcp        0      0 0.0.0.0:4999            0.0.0.0:*               LISTEN      23995/docker-proxy  
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      18575/docker-proxy  
tcp6       0      0 :::8080                 :::*                    LISTEN      24022/docker-proxy  
tcp6       0      0 :::4999                 :::*                    LISTEN      24002/docker-proxy  
tcp6       0      0 :::3000                 :::*                    LISTEN      18582/docker-proxy

 

Step 3 : 브라우저 확인

 

3. Volume 과 환경변수 설정하기

데이터 볼륨, 도커 컨테이너와 데이터 볼륨

 

볼륨 (컴퓨팅) - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 운영 체제 환경에서, 볼륨(volume) 또는 논리 드라이브(logical drive)는 하나의 파일 시스템을 갖춘 하나의 접근 가능한 스토리지 영역으로, 일반적으로(꼭

ko.wikipedia.org

 

도커 컨테이너 데이터 볼륨 관리

도커는 하나의 이미지로 부터 여러 컨테이너를 만들기 위해서 Union File system을 사용한다. 유니온 파일 시스템은 원본 이미지에 변경된 내용(diff)를 추가하는 방식이므로, 다른 컨테이너에서 사용

www.joinc.co.kr

- 도커 볼륨은 도커 컨테이너 내부와 호스트(도커 호스트 머신) 간에 데이터를 공유하고 저장하기 위한 기능으로 컨테이너가 종료되더라도 데이터를 영속적으로 보존 가능

- 도커 컨테이너는 독립적인 환경을 가지며, 컨테이너가 종료되면 내부의 데이터도 함께 소멸하기 때문에 컨테이너가 종료되더라도 데이터를 영속적으로 보존하고자 할 때 도커 볼륨을 사용

- 도커 볼륨은 호스트 머신의 파일 시스템에 저장되며, 컨테이너는 이 볼륨을 마운트하여 데이터에 접근 가능

- 도커 볼륨은 컨테이너를 생성할 때 `-v` 또는 `--volume` 옵션을 사용하여 설정

 

Step 1 : docker-compose.yaml (yml) 파일 생성

- 노트북 칩에 따라 mysql 이미지가 다르기 때문에 환경에 맞는 yaml파일 작성

- 웹서버 yaml 파일에 volumes 지시어를 입력해 "로컬 호스트에서 공유할 볼륨 파일 시스템"과 "컨테이너 내부에서 사용할 파일 시스템"을 지정 (ex. 로컬호스트_파일시스템:컨테이너_파일시스템)

# CPU 칩 확인, M1을 제외한 경우의 docker-compose.yaml(docker-compose.yml) 파일 내용
version: '3.8'

services:
  nginx:
    image: sebcontents/client
    restart: 'always'
    ports:
      - "8080:80"
    container_name: client

  node:
    image: sebcontents/server
    restart: 'always'
    ports:
      - "4999:80"
    container_name: server
    volumes:
      - "./volumefolder:/data"

  mysql:
    image: mysql:latest
    restart: 'always'
    container_name: database
    environment:
      MYSQL_ROOT_PASSWORD: supersecret # root 계정 비밀번호
      MYSQL_DATABASE: test # 초기 생성 데이터베이스
      MYSQL_USER: username # 생성할 사용자 이름 
      MYSQL_PASSWORD: supersecret # 생성할 사용자 비밀번호
      
 # Mac의 M1칩의 경우 docker-compose.yaml(docker-compose.yml) 파일 내용
 version: '3.8'

services:
  nginx:
    image: sebcontents/client
    restart: 'always'
    ports:
      - "8080:80"
    container_name: client

  node:
    image: sebcontents/server
    restart: 'always'
    ports:
      - "4999:80"
    container_name: server
    volumes:
      - "./volumefolder:/data"

  mysql:
    image: amd64/mysql
    restart: 'always'
    container_name: database
    environment:
      MYSQL_ROOT_PASSWORD: supersecret # root 계정 비밀번호
      MYSQL_DATABASE: test # 초기 생성 데이터베이스
      MYSQL_USER: username # 생성할 사용자 이름 
      MYSQL_PASSWORD: supersecret # 생성할 사용자 비밀번호

 - Docker Hub의 mysql 이미지의 description을 확인해 환경 변수 설정과 사용 방법을 확인

 

Step 2 : yaml 파일이 있는 위치에서 yaml 파일 실행

$ docker compose up -d
[+] Running 12/12
 ✔ mysql 11 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                           36.7s 
   ✔ 328ba678bf27 Pull complete                                                                                                    7.9s 
   ✔ f3f5ff008d73 Pull complete                                                                                                    8.1s 
   ✔ dd7054d6d0c7 Pull complete                                                                                                    8.3s 
   ✔ 70b5d4e8750e Pull complete                                                                                                    9.0s 
   ✔ cdc4a7b43bdd Pull complete                                                                                                    9.2s 
   ✔ 3e9c0b61a8f3 Pull complete                                                                                                    9.4s 
   ✔ 806a08b6c085 Pull complete                                                                                                   14.7s 
   ✔ 021b2cebd832 Pull complete                                                                                                   16.1s 
   ✔ ad31ba45b26b Pull complete                                                                                                   30.1s 
   ✔ 0d4c2bd59d1c Pull complete                                                                                                   33.1s 
   ✔ 148dcef42e3b Pull complete                                                                                                   33.3s 
[+] Running 1/1
 ✔ Network docker_volume_study_default  Created                                                                                    0.2s 
 ⠋ Container database                   Creating                                                                                   0.0s 
 ⠋ Container client                     Creating                                                                                   0.0s 
 ⠋ Container server                     Creating
 [+] Running 3/3
 ✔ Container server    Started                                                                                                     2.5s 
 ✔ Container client    Started                                                                                                     2.6s 
 ✔ Container database  Started
 
 # 서비스 소켓 기동 확인
 $ sudo netstat -antp | grep "docker"
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      26083/docker-proxy  
tcp        0      0 0.0.0.0:4999            0.0.0.0:*               LISTEN      26061/docker-proxy  
tcp6       0      0 :::8080                 :::*                    LISTEN      26090/docker-proxy  
tcp6       0      0 :::4999                 :::*                    LISTEN      26068/docker-proxy  

# docker container 상태 확인
$ docker container ls
\CONTAINER ID   IMAGE                COMMAND                   CREATED              STATUS              PORTS                                   NAMES
3e800af770da   sebcontents/server   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:4999->80/tcp, :::4999->80/tcp   server
bacea1b39dc7   mysql:latest         "docker-entrypoint.s…"   About a minute ago   Up About a minute   3306/tcp, 33060/tcp                     database
f6b764719e5c   sebcontents/client   "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp, :::8080->80/tcp   client

 

Step 3 : yaml 파일이 있는 위치에서 volume 파일 시스템 확인 후 파일 생성

$ ll
합계 16
drwxrwxr-x 3 roheerumi roheerumi 4096  4월 11 16:05 ./
drwxrwxr-x 7 roheerumi roheerumi 4096  4월 11 15:51 ../
-rw-rw-r-- 1 roheerumi roheerumi  647  4월 11 16:00 docker-compose.yaml
drwxr-xr-x 2 root      root      4096  4월 11 16:05 volumefolder/

$ cd volumefolder/
$ sudo vim test_file.txt
$ ll
합계 12
drwxr-xr-x 2 root      root      4096  4월 11 16:09 ./
drwxrwxr-x 3 roheerumi roheerumi 4096  4월 11 16:05 ../
-rw-r--r-- 1 root      root         5  4월 11 16:09 test_file.txt

 

Step 4 : 서버 컨테이너의 /data에 정상적으로 저장되었는지 확인

# 서버 컨테이너에서 쉘 실행
$ docker exec -it server sh

# /data 디렉토리로 이동
/usr/src/app # cd /
/ # cd data/

# 파일 저장 확인
/data # ls
test_file.txt

 

Step 5 : 컨테이너 중지 후 재기동 시 파일이 그대로 존재하는지 확인

# 컨테이너 중지
$ docker container stop server database client 
server
database
client

# 컨테이너 재기동
$ docker container restart server client database 
server
client
database

# 서버 컨테이너에 sh 실행하여 파일 확인
$ docker exec -it server sh
/usr/src/app # cd /data
/data # ls
test_file.txt
/data #

# References

챗 GPT

Docker Networking overview

 

Networking overview

 

docs.docker.com

 

Overview of docker compose CLI

 

Overview of docker compose CLI

 

docs.docker.com

Docker compose-file Docs

 

Overview

 

docs.docker.com

Try Docker Compose

 

Try Docker Compose

 

docs.docker.com

docker compose VS docker-compose

 

docker compose VS docker-compose

docker compose v2를 간략하게 정리합니다. 소개 Docker Compose는 여러개의 container을 실행시키기 위한 tool로 Compose file format를 따른다. Docker Desktop 을 다운 받으면 사용 할 수 있다. V1과 다른점 가장 큰 차

shinjam.tistory.com

docker hub - mysql

 

mysql - Official Image | Docker Hub

Quick reference Supported tags and respective Dockerfile links 8.0.32, 8.0, 8, latest, 8.0.32-oracle, 8.0-oracle, 8-oracle, oracle 8.0.32-debian, 8.0-debian, 8-debian, debian 5.7.41, 5.7, 5, 5.7.41-oracle, 5.7-oracle, 5-oracle 5.7.41-debian, 5.7-debian, 5-

hub.docker.com

 

Comments