일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- IAM
- FTP
- NAT
- EC2 인스턴스
- SAA-C03
- aws cloud school 8
- vmware
- tftp
- Ebs
- aws cloud school
- NLB
- GNS3
- Firewall
- Troubleshooting
- aws cloud
- DNS
- aws cloud shcool 8
- Kubernetes
- eks
- ALB
- linux
- AWS
- 네트워크
- aws SAA-c03
- AWS 자격증
- 3 TIER
- docker
- EC2
- aws saa
- vyos
- Today
- Total
나의 공부기록
[Docker]01. 컨테이너 가상화 본문
컨테이너 가상화 - Docker
- 컨테이너 가상화를 하면 Host의 H/W와 kernel을 공유받기 때문에
➡️ Hypervisor 가상화와 달리 Guest VM과 Guest OS를 필요로 하지 않음 - 프로세스 수준의 격리는 논리적으로 격리가 되는 것으로, A Container에서 B Container로 넘어갈 수 있기 때문에
➡️ 보안에 취약함 - 자원의 오버헤드적인 측면에서 Hypervisor 가상화보다 Container 가상화가 더 빠름(유리함)
- VM을 프로비저닝 하는 과정 없이 애플리케이션만 띄우면 되기 때문에, 속도가 훨씬 빠름
VM 생성 과정이 애플리케이션을 생성하는 것과 비슷 - Docker의 이미지를 만드는 것을 잘해야 함🌟
Hypervisor 가상화 | Container 가상화 | |
격리 수준 | 하드웨어 수준 | 프로세스 수준 |
자원 | 오버헤드가 높음 | 오버헤드가 낮음 |
보안 | 컨테이너 가상화에 비해 높음 | 하이퍼바이저에 비해 낮음 |
프로비저닝 속도 | 상대적으로 느림 guest VM부터 구성 |
상대적으로 빠름 호스트 H/W와 커널까지 공유 ➡️Guest VM과 kernel 구성할 필요❌ |
호환성 | 원하는 OS 설치 가능 | 호스트에 종속 ➡️ 리눅스 기반의 컨테이너만 가능 |
✅ 컨테이너 가상화를 위한 리눅스 기반 기술
1️⃣ chroot(Change Root)
- chroot를 통해 컨테이너의 최상위 디렉토리를 변경하여, 컨테이너 내부에서 접근 가능한 디렉토리(공간)를 제한
2️⃣ Cgroup(Control Group)
- 컨테이너 호스트의 자원을 제한
- 하이퍼바이저의 경우 자원을 할당(2core, 2GB, 20GB)하는 개념
↔️ 컨테이너의 경우는 제한(RAM 2GB까지 사용 가능)을 하는 개념 - 호스트의 모든 자원을 하나의 컨테이너가 끌어다 쓰는 것을 제한
컨테이너 가상화의 종류
Docker
- 컨테이너를 관리하는데 최적화
- 앞으로 K8s를 할 때도 계속 사용할 예정
Containerd
- K8s를 구성하는 런타임(=Engine)으로 사용할 예정
CRIO
LXC(Linux Container)
Container 가상화 실습
1. Ubuntu-tem을 Clone ➡️ RAM 용량 증가
- Spec
- IP : 211.183.3.100/24
- RAM : 4GB

- IP 수정
root@ubuntu-tem:~# vi /etc/netplan/00-installer-config.yaml

2. Docker 설치
# Docker 다운로드
root@ubuntu-tem:~# curl -fsSL https://get.docker.com -o get-docker.sh
root@ubuntu-tem:~# ls
get-docker.sh snap
# Docker 실행 권한 부여
# +x와 777 차이점
# +x는 기존 권한에 실행 권한 추가
# 777는 모든 권한을 모든 사용자에게 추가
root@ubuntu-tem:~# chmod +x get-docker.sh
# Docker 실행
root@ubuntu-tem:~# ./get-docker.sh
# Executing docker install script, commit: 4c94a56999e10efcf48c5b8e3f6afea464f9108e
+ sh -c apt-get -qq update >/dev/null
- docker 설치 확인
root@ubuntu-tem:~# docker -v
Docker version 28.0.1, build 068a01e
⚠️유의사항

- docker를 설치해서 생성된 인터페이스 = docker0
- docker0라는 NIC를 통해 어떤 네트워크가 구성됐는지 파악 가능
➡️ IP가 부여되어 있어야 함❗(=정상)
➡️ IP 부여❌ (=비정상) - 비정상인 상태이면, 컨테이너는 실행되는데, 컨테이너끼리나 외부로 통신이 ❌
- 비정상인 상태면, systemctl restart docker하면 IP 부여됨

- 리눅스 측면에서 바라본 컨테이너 네트워크(172.17.0.0/16)
3. Container 실행
- nginx라는 Base Image 다운로드 ➡️ 이미지 생성
# = docker <container 생량> run nginx
# nginx : 이미지의 이름
root@ubuntu-tem:~# docker run nginx
Unable to find image 'nginx:latest' locally # 이미지가 존재하지❌ 다운로드
# 다운로드(Pulling) 목록 ↔️ Push
# 여러 개의 Layer = 하나의 이미지
# 변경사항 발생 ➡️ 변경된 Layer만 수정하면 됨
latest: Pulling from library/nginx
7cf63256a31a: Pull complete
bf9acace214a: Pull complete
513c3649bb14: Pull complete
d014f92d532d: Pull complete
9dd21ad5a4a6: Pull complete
943ea0f0c2e4: Pull complete
103f50cb3e9f: Pull complete
Digest: sha256:9d6b58feebd2dbd3c56ab5853333d627cc6e281011cfd6050fa4bcf2072c9496
Status: Downloaded newer image for nginx:latest
- docker 실행 ➡️ foreground 상태
- 컨테이너가 잘 동작하려면 반드시 foreground 상태인 프로세스가 존재해야 함
- 예시) 자바 컨테이너 : 자바가 잘 동작하기 위한 명령을 실행해줘야 함
➡️ java -jar app.jar
- 예시) 자바 컨테이너 : 자바가 잘 동작하기 위한 명령을 실행해줘야 함
- [Ctrl + c ] : 프로세스 종료하며 컨테이너 빠져나옴
- 컨테이너가 잘 동작하려면 반드시 foreground 상태인 프로세스가 존재해야 함

- docker ps : 정상동작 중인 컨테이너 상태
- 컨테이너 이름 또는 컨테이너 ID로 특정하면 됨
- 이름을 정하지 않으면 랜덤하게 지정됨

- docker ps -a : 모든 컨테이너 상태 확인

💡컨테이너 내부에서 포어그라운드로 동작하던 프로세스가 종료되자 컨테이너가 중지됨
👉 이 차이를 이해하고 해결하는게 컨테이너 가상화에서 필수이자 가장 기본이 되는 능력임
4. Container 삭제 - 컨테이너 이름
# docker <container 생략> rm -f <container ID 또는 NAMES>
# -f(force) : 강제삭제, 실행 중이어도 삭제
root@ubuntu-tem:~# docker rm -f strange_hamilton
5. Container 생성 - 이름부여
# 이름이 test이고, baseImage가 centos7인 컨테이너
root@ubuntu-tem:~# docker run --name test centos:7
Unable to find image 'centos:7' locally
7: Pulling from library/centos
2d473b07cdd5: Pull complete
Digest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
Status: Downloaded newer image for centos:7
- centos:7 이미지는 처음에 설계 당시, '이 컨테이너를 실행하면 "/bin/bash"라는 명령을 수행하라'라고 만들어짐
➡️ docker run명령으로 컨테이너를 실행시키면서 "/bin/bash"라는 명령이 수행되었을 것임
👉 컨테이너가 "정상동작"하려면 반드시 컨테이너 내부에서 포어그라운드로 프로세스가 실행되어야 하기 때문에, 그 조건을 충족시키지 못해서 결국 컨테이너는 stop된 상태로 존재
root@ubuntu-tem:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# COMMAND : /bin/bash ➡️ 컨테이너가 실행될 때, 수행되는 명령어
# 단, 해당 컨테이너를 동작시키지는 않음(= 특정한 프로세스 실행❌)
root@ubuntu-tem:~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e273f375fbbe centos:7 "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago test
6. Container 실행 시, 수행할 명령어 - COMMAND
- COMMAND : 컨테이너를 foreground로 유지시키기 위해서 사용됨
- 명령어를 작성하면 /bin/bash를 실행하지 않고 작성된 명령어를 실행
# 명령 옵션 ⬅️ <이미지> ➡️ COMMAND : 구분 가능
root@ubuntu-tem:~# docker run --name test centos:7 sleep 60
# 컨테이너가 실행될 때, sleep 60라는 명령어가 실행됨
root@ubuntu-tem:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ffc78d357807 centos:7 "sleep 60" 5 seconds ago Up 5 seconds test
# 60초 이후에 컨테이너가 종료됨
# 컨테이너 내부에서 foreground를 유지시켜주던 sleep 60가 종료되면
root@ubuntu-tem:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- exec : 실행 ps -p 1 : pid가 1인 애 보여줘
- pid 1 : 컨테이너의 동작(Status = UP)을 "담보"하는 프로세스
- 컨테이너 동작이 하나라도 되어있어야 컨테이너가 살아있을 수 있음
root@ubuntu-tem:~# docker exec test ps -p 1

docker start : 실행
docker restart : 재실행
docker stop : 중지
7. Container 삭제 - PID
# container 실행
root@ubuntu-tem:~# docker run --name ntest nginx:latest
# PID로 Container 삭제
root@ubuntu-tem:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6c0a5343495 nginx:latest "/docker-entrypoint.…" 12 seconds ago Up 11 seconds 80/tcp ntest
root@ubuntu-tem:~# docker rm -f c6c0a5343495
c6c0a5343495
➕질문 : 컨테이너의 경우엔 꼭 운영체제가 아닌, nginx나 python, java 같은 앱도 컨테이너로 만들 수 있음
➡️ 호스트의 커널을 공유 중이기 때문에 가능
[이미지 추가]
- kvm의 이미지와 컨테이너 이미지가 어떤 차이가 있는지 이해하면 좋음
- 컨테이너 이미지로 컨테이너를 띄우더라도 원래 이미지는 그대로 존
8. 컨테이너 백그라운드 실행(리눅스 상)
# -d(detach) : 리눅스 상의 background에서 컨테이너가 실행되고 있음
# 컨테이너의 내부에서는 foreground로 실행됨(nginx 설계 상)
root@ubuntu-tem:~# docker run -d --name ntest nginx:latest
7a63340a2d25edf2d04d99b64f21239c0a5cb8c7cf4a369d0d850a689ee34b9c
# 컨테이너가 정상적으로 실행되고 있음을 확인 가능
root@ubuntu-tem:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7a63340a2d25 nginx:latest "/docker-entrypoint.…" 57 seconds ago Up 57 seconds 80/tcp ntest
9. 컨테이너 세부정보 확인 - Inspect

# 컨테이너의 세부정보
root@ubuntu-tem:~# docker inspect ntest
# ntest 컨테이너의 IP 정보
root@ubuntu-tem:~# docker inspect ntest | grep -i ipa
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
- container와 통신 가능 확인

10. 컨테이너 로그 확인 - logs
- 일반적으로 컨테이너를 실행시켰을 때, 내부의 프로세스가 적절하게 동작하지 않아 컨테이너가 중지되는 경우가 있는데, 왜 중지됐는지 여부를 어느 정도 확인 가능
➡️ DB 연동❌, COMMAND에 문제가 있는 경우, 내부에서 프로세스 동작 ❌
# 컨테이너의 로그 확인
# 주로, 컨테이너가 잘 동작하지 않을 때 확인
root@ubuntu-tem:~# docker logs ntest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
11. docker network 정보 확인
#
root@ubuntu-tem:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
19a76ba62a7a bridge bridge local # Workstation의 NAT 대역과 동일 / 외부와 통신 가능
9754215ebb6d host host local # 호스트 내에서만 통신
acc770ab6373 none null local # 네트워크❌
root@ubuntu-tem:~# docker network inspect bridge
12. docker image 정보 확인
- 우리가 pull해온 두 개의 이미지(nginx:latest, centos:7은 도커허브에서 가져온 Official한 이미지)
root@ubuntu-tem:~# docker image ls
# REGISTRY : 도서관 ( docker hub, AWS ECR, 사설 등...)
# REPOSITORY : 책장
# TAG : 책
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest b52e0b094bc0 5 weeks ago 192MB
centos 7 eeb6ee3f44bd 3 years ago 204MB
13. 컨테이너 내부 명령 수행 - 리눅스
root@ubuntu-tem:~# docker <container> exec <명령을 수행할 컨테이너> <명령>
# ntest라는 컨테이너에 ls라는 명령어 실행
root@ubuntu-tem:~# docker exec ntest ls
bin
boot
dev
docker-entrypoint.d
docker-entrypoint.sh
etc
home
lib
lib64
14. 컨테이너 내부 접속 - 컨테이너
# -i(interactive) : 상호작용, -t(terminal)
# 해당 컨테이너와 터미널로 작용하겠음 = 터미널로 접속하겠다.
root@ubuntu-tem:~# docker run -it --name cent centos:7 bash
# a1ee8de1c265 : 컨테이너 ID
# cent라는 컨테이너를 실행함과 동시에, 내부로 들어옴
[root@a1ee8de1c265 /]#
💡컨테이너 빠져나오는 방법
1️⃣ Ctrl + pq : 몰래 빠져나오기
👉 내가 열었던 터미널이 유지되어, container 동작 유지

2️⃣ Ctrl + d : 내부 프로세스를 유지하지 않고 나옴
👉foreground로 동작하는 프로세스가 없기 때문에, 컨테이너는 중지 상태

실습 - 01
문제
myhttpd라는 이름을 갖는 컨테이너를 띄워보세요. 이 컨테이너를 백그라운드로 실행시키고, 컨테이너 이미지는 httpd:latest 이걸로 하세요.
-d 옵션 사용, 베이스 이미지 : httpd:latest
풀이
# 컨테이너 생성
root@ubuntu-tem:~# docker run -d --name myhttpd httpd:latest
Unable to find image 'httpd:latest' locally
latest: Pulling from library/httpd
7cf63256a31a: Already exists
d2f10b557009: Pull complete
4f4fb700ef54: Pull complete
38fd0d422c41: Pull complete
470035b3d48f: Pull complete
fdebd6c6e1b2: Pull complete
Digest: sha256:10381816bb7e60ae3a9db3784f2966a8910b6ff07c4da54bd2d62d2671c8ab6e
Status: Downloaded newer image for httpd:latest
e11dc0a7f7dc319da1db3df06540386e44824807331350f95d8cd795831c41d9
# 백그라운드에서 실행 확인
root@ubuntu-tem:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e11dc0a7f7dc httpd:latest "httpd-foreground" 10 seconds ago Up 9 seconds 80/tcp myhttpd
실습 - 02
문제
실습 - 01의 컨테이너 ip를 조회해서 curl을 해보세요.
풀이
# myhttpd의 IP 정보 확인
root@ubuntu-tem:~# docker inspect myhttpd | grep -i IP
"IpcMode": "private",
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
# myhttpd 주소 접속
root@ubuntu-tem:~# curl 172.17.0.2
<html><body><h1>It works!</h1></body></html>
✅ test라는 컨테이너는 실행(run)되면서 bash라는 명령이 수행됨
➡️ 해당 명령만으로는 내부의 httpd 프로세스가 정상적으로 동작하지 않음
➡️ httpd-foreground : httpd:latest라는 컨테이너를 foreground로 유지시키기 위한 명령어로, 외부에서 httpd에 접속 가능
15. 동작 중인 컨테이너 접속 - exec
- 내부로 진입해서 명령을 치겠음 = 콘솔 접속하는 느낌
# 이미 동작중인 컨테이너에 접속
root@ubuntu-tem:~# docker exec -it test bash
root@7d8596b029ec:/usr/local/apache2# ls
bin build cgi-bin conf error htdocs icons include logs modules
root@7d8596b029ec:/usr/local/apache2# cd htdocs
root@7d8596b029ec:/usr/local/apache2/htdocs# ls
index.html
root@7d8596b029ec:/usr/local/apache2/htdocs# pwd
/usr/local/apache2/htdocs
# httpd라는 컨테이너 이미지의 웹 루트 디렉토리 : /usr/local/apache2/htdoc
root@7d8596b029ec:/usr/local/apache2/htdocs# cat index.html
<html><body><h1>It works!</h1></body></html>
실습 - 03
문제
httpd:latest 이미지로 이름이 index_http 라는 컨테이너를 만들고 이 컨테이너의 주소로 curl 했을 때, hello라는 기본 페이지가 보이도록 해보세요.
풀이
방법 - 1️⃣
root@ubuntu-tem:~# docker run -d --name index_http1 httpd:latest
496446f5a1b6d33cdae7009d436473c62b44f30106d35c0d0c840ee6afed9485
root@ubuntu-tem:~# docker inspect index_http1 | grep -i ipa
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAMConfig": null,
"IPAddress": "172.17.0.3",
root@ubuntu-tem:~# curl 172.17.0.3
<html><body><h1>It works!</h1></body></html>
root@ubuntu-tem:~# docker exec -it index_http1 bash
root@496446f5a1b6:/usr/local/apache2# cd htdocs
root@496446f5a1b6:/usr/local/apache2/htdocs# echo hello > index.html
root@ubuntu-tem:~# curl 172.17.0.3
hello

방법 - 2️⃣
- 특문이 없었으면 명령을 그래로 수행해도 되는데, 특문이 있었기 때문에 sh -c를 통해 내가 수행할 명령어를 묶어줌
root@ubuntu-tem:~# docker exec index_http1 sh -c 'echo hello2 > /usr/local/apache2/htdocs/index.html'
root@ubuntu-tem:~# curl 172.17.0.3
hello2

실습 - 04
문제
nginx:latest 이미지로 이름이 index_nginx 라는 컨테이너를 만들고 이 컨테이너의 주소로 curl 했을 때 hello_nginx라는 기본페이지가 보이도록 해보세요. 웹루트디렉터리는 검색해 보세요!
풀이
방법 1️⃣
# 컨테이너 생성
root@ubuntu-tem:~# docker run -d --name index_nginx nginx:latest
1391b1e058ad30415ee321b70c6fd9d4330484ade6f66f8df110888b80e27170
# 컨테이너 콘솔 접속
root@ubuntu-tem:~# docker exec -it index_nginx bash
root@1391b1e058ad:/# ls
bin dev docker-entrypoint.sh home lib64 mnt proc run srv tmp var
boot docker-entrypoint.d etc lib media opt root sbin sys usr
# nginx 웹 루트 디렉토리 이동
root@1391b1e058ad:/# cd /usr/share/nginx/html
root@1391b1e058ad:/usr/share/nginx/html# ls
50x.html index.html
# index.html 수정
root@1391b1e058ad:/usr/share/nginx/html# echo hello_nginx > index.html
root@1391b1e058ad:/usr/share/nginx/html# curl localhost
hello_nginx
결과 확인

방법 2️⃣
root@ubuntu-tem:~# docker exec index_nginx sh -c 'echo hello_nginx2 > /usr/share/nginx/html/index.html'
root@ubuntu-tem:~# curl 172.17.0.2
hello_nginx2
16. 모든 컨테이너의 ID 확인
root@ubuntu-tem:~# docker ps -a -q
1391b1e058ad
17. 모든 컨테이너 삭제
root@ubuntu-tem:~# docker rm -f $(docker ps -qa)
1391b1e058ad
Docker 옵션 - Volume(-v)🌟
- 컨테이너와 호스트를 마운트 하는 개념
- 컨테이너의 경우, 컨테이너가 삭제되면 내부에 데이터나 로그 같은 것들도 같이 삭제
➡️ 데이터베이스 컨테이너가 날아가면, 데이터도 다 날아가게 됨
👉 영구적으로 저장시키고 싶은 데이터가 있다면, -v(volume)을 통해 host에 영구 저장시킬 수 있음
1. 원본 경로 생성
root@ubuntu-tem:~# mkdir /host-txt
2. 컨테이너 생성
root@ubuntu-tem:~# docker run -d --name vol_nginx -v /host-txt:/txt nginx:latest
f38bb78a0d51b9b93bc97ed7ceeb37b08a87cc59dd01498437c103fc7db253e3
3. test.txt 파일 생성
root@ubuntu-tem:~# echo vol-test > /host-txt/test.txt
root@ubuntu-tem:~# cat /host-txt/test.txt
vol-test
4. 컨테이너 내부의 /txt 경로에 test.txt 파일이 있는 것을 확인 가능

5. 내부에서 삭제 ➡️ 외부에서도 삭제

💡호스트 및 컨테이너 내부에 디렉토리가 없으면 자동으로 생성됨
root@ubuntu-tem:~# docker run -d --name vol_nginx -v /host-txt1:/txt nginx:latest
fc36ae23d0f6b922f4373e0648348417e271942327032456ad6f94c3391a4094
root@ubuntu-tem:~# ls /
bin dev home host-txt1 lib32 libx32 media opt root sbin srv sys usr
boot etc host-txt lib lib64 lost+found mnt proc run snap swap.img tmp var
root@ubuntu-tem:~#
실습 - 05
문제
-it 옵션이나 exec를 사용하지 않고, nginx:latest 이미지로 컨테이너를 생성했을 때, vol_test라는 문구가 뜨도록 해보세요.
풀이
1. 기존 경로에 index.html 생성
root@ubuntu-tem:~# cd /host-txt
root@ubuntu-tem:/host-txt# ls
root@ubuntu-tem:/host-txt# echo vol_test > index.html
2. 컨테이너 생성
root@ubuntu-tem:/host-txt# docker run -d --name my_nginx -v /host-txt:/usr/share/nginx/html nginx:latest
8691381e60260151fe499b995f17f8266c9c34ab59c77025b027a1a675ea65d4
root@ubuntu-tem:/host-txt# docker inspect my_nginx | grep -i ipa
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
3. 결과 확인

❗새로운 컨테이너를 띄워서 내부로 진입하여, /usr/share/nginx/html로 가보니, 이미 index.html이 존재
➡️ 기존에 파일이 존재하면, 호스트의 파일이 우선순위가 높음
# 1️⃣ 새로운 컨테이너 생성
root@ubuntu-tem:/host-txt# docker run -it --name test nginx:latest bash
# 2️⃣ 웹 디렉토리 index.html 확인
root@cdbca1427ef6:/# cd /usr/share/nginx/html
root@cdbca1427ef6:/usr/share/nginx/html# ls
50x.html index.html
👉 /usr/share/nignx/html이 바라보고 있는 경로가 달라짐 ➡️ /host-txt 마운트가 우선순위가 높음
Docker 옵션 - Publish(-p)🌟
- 컨테이너를 외부에 노출/배포(publish)시키는 옵션
- Destination NAT와 비슷한 개념
1. 컨테이너 생성 : Publish 옵션 설정
- pub이라는 80포트이기 때문에, 컨테이너가 특정이 됨
# -p : publish
# 8080:80 ➡️ 호스트의 포트:컨테이너의 포트
root@ubuntu-tem:/host-txt# docker run -d --name pub -p 8080:80 nginx:latest
2. publish 확인
- 0.0.0.0 호스트의 전체 대역에서 8080으로 들어오면 80으로 연결해줘라
- 80/tcp ➡️ 컨테이너 내부 동작하는 프로세스가 서비스를 제공하는 포트
- 일반적으로 웹서버는 80, python 장고는 8000, nodejs 기반은 3000번 등...
➡️ 중요한건 컨테이너 내부에서 실제로 어떤포트로 서비스가 제공되는지가 제일 중요하고,
👉 그 포트를 찾아서 publish를 해줘야한다.

- 호스트에서 컨테이너가 8080포트를 점유하고 있는 것을 확인 가능
➡️ 8080로 서비스를 제공함을 확인 가능



❗실습, 테스트할 때는 되도록이면 호스트의 well-known 포트는 사용하지 않는 것이 좋음
➡️ 최종적으로 웹서버를 배포하는 거면 80 포트 같은 well-known 포트를 사용
실습 - 06
문제
호스트의 /host_vol 이라는 경로에는 간단한 강아지 템플릿이 존재한다. 이 무료템플릿을 호스트의 7979번 포트로 publish 해보세요.
풀이
1. 마운트 경로 생성
# host_vol 마운트 경로 생성
root@ubuntu-tem:/# mkdir /host_vol
root@ubuntu-tem:/# cd host_vol
2. 무료 템플릿 설정
# dog 템플릿 다운로드
root@ubuntu-tem:/host_vol# wget https://www.free-css.com/assets/files/free-css-templates/download/page21/dogs-palace.zip
# unzip 패키지 다운로드
root@ubuntu-tem:/host_vol# apt install -y unzip
# dog 템플릿 압축 해제
root@ubuntu-tem:/host_vol# unzip dogs-palace.zip
# zip 파일 삭제
root@ubuntu-tem:/host_vol# rm -rf dogs-palace.zip
# 폴더명 변경
root@ubuntu-tem:/host_vol# mv dogs-palace dog
3. 컨테이너 생성
# 컨테이너 생성
root@ubuntu-tem:/host_vol# docker run -d --name pub_dog -v /host_vol/dog:/usr/share/nginx/html -p 7979:80 nginx:latest
3c1e55d6f27003c9075430147772fcc3ac40d738a432c7d7b80abe4ddae2ff88
4. 서비스 제공 확인
# 서비스 제공 확인
root@ubuntu-tem:/host_vol# ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=823,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=895,fd=3))
LISTEN 0 128 127.0.0.1:6010 0.0.0.0:* users:(("sshd",pid=17356,fd=10))
LISTEN 0 128 127.0.0.1:6011 0.0.0.0:* users:(("sshd",pid=6201,fd=10))
LISTEN 0 4096 0.0.0.0:7979 0.0.0.0:* users:(("docker-proxy",pid=21287,fd=7))
LISTEN 0 4096 0.0.0.0:8080 0.0.0.0:* users:(("docker-proxy",pid=19819,fd=7))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=895,fd=4))
LISTEN 0 128 [::1]:6010 [::]:* users:(("sshd",pid=17356,fd=9))
LISTEN 0 128 [::1]:6011 [::]:* users:(("sshd",pid=6201,fd=9))
LISTEN 0 4096 [::]:7979 [::]:* users:(("docker-proxy",pid=21293,fd=7))
LISTEN 0 4096 [::]:8080 [::]:* users:(("docker-proxy",pid=19824,fd=7))

Docker 옵션 - CP
1. host ➡️ 컨테이너(pub_dog)로 파일 복사
root@ubuntu-tem:/host_vol# echo cptest > cptest.txt
root@ubuntu-tem:/host_vol# ls
cptest.txt dog
# pub_dog(컨테이너)의 최상위 경로에 cptest.txt 파일 복사
root@ubuntu-tem:/host_vol# docker cp ./cptest.txt pub_dog:/
Successfully copied 2.05kB to pub_dog:/
- cptest.txt 복사 확인

2. 컨테이너(pub_dog) ➡️ host로 파일 복사
root@ubuntu-tem:~# docker cp pub_dog:/cptest.txt ./
Successfully copied 2.05kB to /root/./
root@ubuntu-tem:~# ls
cptest.txt get-docker.sh snap
Docker 옵션 - 환경변수 지정(-e)
- 주로 데이터베이스 컨테이너 생성 시, 자주 사용됨
➡️데이터베이스 컨테이너의 경우엔 적어도 root 패스워드를 설정해야 컨테이너가 잘 동작함
1. 컨테이너 생성
root@ubuntu-tem:~# docker run -d --name envcon -e ENVTEST=test nginx:latest
42c3ee37af352286e8288e4f83d6faa7e23d7b844ea3cf61cebec527b1d9e15c
- 컨테이너 생성시, -it로 만들면 나중에 나올때, 컨테이너가 잘 동작할지 장담하지 못함
➡️되도록이면 -d(detach)로 접속 권장
2. 컨테이너 접속
root@ubuntu-tem:~# docker exec -it envcon bash
root@42c3ee37af35:/#
3. 환경변수 확인
root@42c3ee37af35:/# echo $ENVTEST
test
Docker 옵션 - 작업 디렉토리 지정(-w)
- 나중에 중요함
1. 컨테이너 생성
root@ubuntu-tem:~# docker run -d --name workdir nginx:latest
367cc62182939fa2d8f8f8434be782ccc86f70eb4be12157750f345c2c1a6556
2. workdir 컨테이너 접속
- 컨테이너 접속 경로 = 현재 작업 디렉토리
root@ubuntu-tem:~# docker exec -it workdir bash
root@367cc6218293:/#
3. 작업 디렉토리 지정하여 생성한 컨테이너
root@ubuntu-tem:~# docker run -d --name workdir1 -w /usr nginx:latest
bcc4f75231f0a80deed0d0cbb20922b8a03a5a9006bbaa52dbc5af8196200a7a
4. workdir1 컨테이너 접속
root@ubuntu-tem:~# docker exec -it workdir1 bash
root@bcc4f75231f0:/usr#
Docker 옵션 - 재시작(--restart)
1. docker engine 재시작 시, 동작 중이던 컨테이너 전부 stop

2. 컨테이너 생성 : 재시작 옵션
root@ubuntu-tem:~# docker run -d --name retest --restart=always nginx:latest
de4c52d08b023b37f5a671716d2f1aa3c18b0c49cbd189cd10a46721c3cc56a0
3. docker engine 재시작해도 컨테이너 재시작됨

'CS > Docker' 카테고리의 다른 글
[Docker] 06. Docker Compose (0) | 2025.03.24 |
---|---|
[Docker] 05. Multi-Stage Build(멀티 스테이지 빌드) (0) | 2025.03.24 |
[Docker] 04. App 배포 - Java & NodeJS & Python (0) | 2025.03.20 |
[Docker]03. Container Registry (0) | 2025.03.20 |
[Docker]02. Docker Image - Dockerfile 명령어 (1) | 2025.03.18 |