IT STUDY LOG
[Docker] 03. Docker Image 다루기 본문
# 학습 목표
- 컨테이너 기술이 무엇인지, Docker가 왜 필요한지 알 수 있다.
- 컨테이너와 이미지, 레지스트리가 무엇인지 이해할 수 있다.
- 대표적인 레지스트리인 Docker Hub에서 이미지를 검색하고, 사용할 수 있다.
- 한 개의 이미지를 이용해서 컨테이너를 구축할 수 있다.
- 두 개 이상의 이미지를 이용해서 컨테이너를 구축하고 서로가 어떻게 연결되는지 알 수 있다.
- Docker CLI에서 명령어를 사용해서 이미지를 생성/수정/배포하고, 컨테이너를 생성/삭제할 수 있다.
- Dockerfile을 이용해 이미지를 생성할 수 있다.
- 애플리케이션을 컨테이너화할 수 있다.
# 학습 내용
1. 한 개의 Docker Image를 다루는 방식 연습
실습 자료
- 도커 이미지 레파지토리 : sebcontents/part1 이미지 repository
- 웹 서버 소스 코드 파일 : https://github.com/codestates/SpaceInvaders
$ 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 컨테이너를 생성
> node 이미지를 기반으로 한 sebcontents/server 이미지를 이용하여 server 컨테이너를 생성
# 레파지토리로부터 이미지 다운로드
$ 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 과 환경변수 설정하기
- 도커 볼륨은 도커 컨테이너 내부와 호스트(도커 호스트 머신) 간에 데이터를 공유하고 저장하기 위한 기능으로 컨테이너가 종료되더라도 데이터를 영속적으로 보존 가능
- 도커 컨테이너는 독립적인 환경을 가지며, 컨테이너가 종료되면 내부의 데이터도 함께 소멸하기 때문에 컨테이너가 종료되더라도 데이터를 영속적으로 보존하고자 할 때 도커 볼륨을 사용
- 도커 볼륨은 호스트 머신의 파일 시스템에 저장되며, 컨테이너는 이 볼륨을 마운트하여 데이터에 접근 가능
- 도커 볼륨은 컨테이너를 생성할 때 `-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
Overview of docker compose CLI
docker compose VS docker-compose
'devops bootcamp 4 > 클라우드 서비스 운영' 카테고리의 다른 글
[AWS] 01. 클라우드 컴퓨팅 (0) | 2023.04.14 |
---|---|
[Docker] 04. 애플리케이션 컨테이너화 (1) | 2023.04.13 |
[Docker] 02. Docker CLI (0) | 2023.04.12 |
[Docker] 01. 왜 Docker인가? (0) | 2023.04.11 |
[Docker] 00. Before You Learn (0) | 2023.04.11 |