일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- guru
- dockerfile
- docker
- 플랫폼
- BAEKJOON
- Python
- 백준
- 코어 이더리움 프로그래밍
- 러스트
- AWS
- fluent python
- Container
- RabbitMQ
- 동시성
- function
- Kubernetes
- Thread
- 블록체인
- Ethereum
- 파이썬
- Network
- rust
- 알고리즘
- 이더리움
- 전문가를 위한 파이썬
- BlockChain
- Refactoring
- IMAGE
- Algorithm
- Fast API
Archives
- Today
- Total
글쓰기 | 방명록 | 관리 |
Victoree's Blog
[1] 도커 이미지와 컨테이너 본문
728x90
1. 도커 이미지와 컨테이너
1) 도커 이미지
- 컨테이너를 생성할 때 필요한 요소
- 여러 개의 계층으로 된 바이너리 파일로 존재
- 컨테이너를 생성하고 실행할 때, 읽기 전용으로 사용
[저장소 이름]/[이미지 이름]:태그
로 구성
2) 도커 컨테이너
- 도커 이미지를 기반으로 컨테이너를 생성할 수 있음
- 해당 이미지의 목적이 맞는 파일이 들어있는 파일 시스템과 격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립적 공간이 생성
- 이미지에서 변경된 사항만 컨테이너 계층에 저장
- 컨테이너에서 하는 작업은 원래 이미지의 영향을 받지 않음
- 생성된 컨테이너는 독립된 파일 시스템을 제공받으며 호스트와 분리되어 있음
- 특정 컨테이너에서 어플리케이션을 설치하거나 삭제해도 다른 컨테이너와 호스트는 변화없음
2. 도커 컨테이너 다루기
도커 컨테이너 생성
- docker : docker 클라이언트 언급
- run : 컨테이너 생성 및 실행
- <이미지> : 해당 컨테이너를 위한 이미지
-it란?
-it
를 붙여줘야 명령어를 실행한 후 계속 명령어를 적을 수 있음-i
- interactive 상호 입출력
-t
- terminal
- tty(유닉스 계열 운영체제 명령어)를 활성화해서 배시 셸을 사용하도록 설정
-it
가 없다면, 그냥 redis-cli를 키고 밖으로 다시 나와버림- exit 또는 command+C로 종료할 수 있으나, 이는 도커 컨테이너를 종료시키고 빠져나옴
- Command + P,Q 를 입력하면 컨테이너의 쉘에서만 빠져나옴
3. 이미지 내부 파일 시스템 구조 보기
$ docker run <이미지> __명령어___
- 명령어 : 이미지가 가지고 있는 시작 명령어를 무시하고 여기에 있는 커맨드를 실행하게 함
- 특정 이미지 안에
ex) ls
라는 명령어를 실행가능하게 하는, 해당 이미지의 파일 스냅샷 안에 ls를 실행할 수 있게 하는 파일이 있어야 실행가능함
4. 컨테이너 나열하기
$ docker ps
: process status- CONTAINER ID : 컨테이너 고유한 아이디 해쉬값 (일부분)
- IMAGE : 컨테이너 생성시 사용한 도커이미지
- COMMAND : 컨테이너 시작시 실행될 명령어, 대부분 이미지에 내장되어 있으므로 별도의 설정이 필요없음
- CREATED : 컨테이너가 생성된 시간
- STATUS : 컨테이너의 상태
- 실행중은 Up, 종료는 Exited, 일시정지 Pause
- PORTS : 컨테이너가 개방한 포트와 호스트에 연결한 포트
- NAMES : 컨테이너 고유한 이름
- 컨테이너 생성시 --name 옵션으로 이름을 설정하지 않으면 도커 엔진이 임의로 형용사와 명사를 조합해 설정함
- id와 마찬가지로 중복이 안되고, docker rename 명령어로 변경할 수 있음
$ docker run <이미지> ping localhost
으로 컨테이너가 살아있는지 확인할 수 있음-a
옵션으로 정지된 컨테이너를 포함한 모든 컨테이너의 목록을 볼 수 있음
5. Docker Lifecycle
- 생성(create) -> 시작(start) -> 실행(running)
$ docker run <이미지 이름>
$ docker create <이미지 이름>
+$ docker start <시작할 컨테이너 아이디/이름>
$ docker create <이미지 이름>
- 이미지에 있는 파일 스냅샷을 컨테이너의 하드디스크에 올려줌
- 해당 작업을 한 컨테이너의 id값을 리턴함
$ docker start -a <시작할 컨테이너 아이디/이름>
- '-a' : attach
- 도커 컨테이너가 실행될 때, 해당 컨테이너에서 나오는 output을 모두 화면에 표출해줌
- 컨테이너에 프로세스를 시작해줌
- 포그라운드 식으로 이미지를 동작시켰기 때문에, 백그라운드로 실행할 수 없음
- '-a' : attach
- 중지
- 아래 명령어 둘 다 컨테이너를 중지시킴
$ docker stop <중지할 컨테이너 아이디/이름>
- gracefully 하게 중지시킴
- 자비롭게 그동안 하던 작업들을 완료후 컨테이너들을 중지시킴
- SIGTERM을 날려 grace period(정리하는 시간)을 두고, SIGKILL을 날려 정지시킴
$ docker kill <중지할 컨테이너 아이디/이름>
- 바로 컨테이너를 중지시킴
- 바로 SIGKILL을 날림
$ docker stop $(docker ps -a -q)
- 모든 컨테이너의 아이디를 중지하는 명령어
- 삭제
$ docker rm <삭제할 컨테이너 아이디/이름>
- 실행중인 컨테이너는 중지한 후 가능함
- 모든 컨테이너를 삭제 :
$ docker rm
docker ps -a -q`` - 이미지 삭제 :
$ docker rmi <이미지 id>
- 한번에 컨테이너, 이미지, 네트워크 모두 삭제 :
$ docker system prune
- 도커를 쓰지 않을때, 모두 정리하고 싶을 때 사용하면 좋음
- 이것은 실행중인 컨테이너에는 영향을 주지 않음
$ docker volume prune
과 같이 원하는 오브젝트를 전부 지우는 것도 가능함
$ docker rmi $(docker images -f "dangling=true" -q)
- 이름없는 이미지 none || : 이미지 제거
$ docker rm $(docker ps -a -q)
- 모든 컨테이너의 아이디를 삭제하는 명령어
> 실행중인 컨테이너에 명령어 전달
$ docker exec <컨테이너 아이디>
- docker run 명령어 v.s. docker exec
- run : 새로 컨테이너를 만들어 해당 명령어를 실행시킴
- exec : 이미 실행중인 컨테이너에 명령어를 실행시킴
> 실행중인 컨테이너에서 터미널 생활 즐기기
$ docker exec -it <컨테이너 아이디> <sh/zsh/bash>
- 컨테이너를 쉘 환경으로 접근하기가 가능함
> 레디스를 이용한 컨테이너 이해
- 레디스 서버가 먼저 작동하고 있어야 함 -> 레디스 클라이언트(redis-cli) 실행 후 명령어를 레디스 서버에 전달
- docker run redis
- redis-cli
- 레디스 클라이언트가 레디스 서버가 있는 컨테이너 밖에서 실행을 하려 하니 레디스 서버에 접근을 할 수 없어 에러가 발생
- 레디스 클라이언트도 컨테이너 안에서 실행을 시켜야 함
- docker run redis
- docker ps
- docker exec -it <컨테이너 아이디> redis-cli
6. 컨테이너를 외부에 노출
1) 컨테이너 실행 명령어 바꾸기
- docker run 이미지 이름
$ docker run -p 49160:8080 이미지 이름
- 로컬 파일(package.json, index.js)을 컨테이너에 복사해줌
- 네트워크도 마찬가지로 로컬 네트워크에 있던 것을 컨테이너 내부에 있는 네트워크에 연결시켜주어야함
- ![Image]({{ site.baseurl }}/images/docker_network.png)
- 컨테이너 내부의 8080이라는 포트에 바로 접근하려면 매핑을 해주어야 함
- 49160은 로컬 브라우저의 포트로 가면, 컨테이너의 8080으로 매핑됨
- 호스트의 특정 IP를 사용하려면 192.168.0.100:8000:8080 과 같이 바인딩할 IP와 포트를 명시
- 또한 여러개의 포트를 외부에 개방하려면 -p 옵션을 여러번 써서 설정할 수 있음
$ docker run -it -p 5000:8080 -p 192.168.0.100:8000:8080 ubuntu:14.04
2) 컨테이너 어플리케이션 구축
- mysql 이미지를 이용해 데이터베이스 컨테이너 생성
docker run -d \ > --name wordpressdb \ > -e MYSQL_ROOT_PASSWORD=password \ > -e MYSQL_DATABASE=wordpress \ > mysql:5.7
- 워드프레스 이미지를 이용해 워드프레스 웹 서버 컨테이너 생성
docker run -d -e WORDPRESS_DB_PASSWORD=password --name=wordpress --link wordpressdb:mysql -p 80 wordpress
$ docker ps
로 연결된 포트 확인 후 접속해보기
- d : detach 의 줄임말
- 컨테이너 실행 후 바로 터미널에서 빠져나오기
- 백그라운드 전용으로 이미지를 실행시켰기 때문에 -a(포그라운드)로 접근이 불가능함
- 대신 exec 옵션을 통해 해당 컨테이너에 접속할 수 있음
- e
- 컨테이너 내부의 환경변수 설정
- link
- 컨테이너 A가 B 컨테이너로 접근하는 간단한 방법은 NAT으로 부터 할당받은 내부 IP를 사용하는 것
- 도커 엔진은 내부 IP를 순차적으로 할당하기 때문에 alias로 접근하도록 설정 가능
- 단, wordpressdb가 종료된 상태에서 wordpress 컨테이너를 실행하면, 오류가 출력됨
- 컨테이너의 연결뿐만 아니라 컨테이너 실행 순서의 의존성도 정의해줌
7. 도커 볼륨
- 이미지는 읽기전용으로 사용하고, 컨테이너의 변경사항은 컨테이너 레이어에 저장됨
- 컨테이너를 삭제하면, 컨테이너 계층에 저장되어 있던 데이터가 같이 삭제됨
- 데이터를 영속적인 데이터로 활용하기 위해 볼륨을 이용함
- 호스트 볼륨 공유
--v /home/data:/var/lib/mysql
- 호스트에 특정 주소와 컨테이너 내부 주소를 매핑시켜서 볼륨을 공유하는 방식
- 동기화가 아니라 완전히 같은 디렉토리
- 이미 해당 디렉토리에 특정 파일이 있다면, 덮어씌워짐
- 볼륨 컨테이너
- 1번의 방식으로 호스트와 볼륨을 공유한 컨테이너로 부터 볼륨을 공유받는 방식
--volumes-from 먼저_공유한_컨테이너명
- 1번에 공유한 /home/data라는 디렉토리를 공유받음
- 도커 볼륨
$ docker volume create --name myvolume
라는 명령어로 볼륨을 생성$ docker volume ls
를 통해 볼륨 확인 가능- 로컬 호스트에 저장되며 도커 엔진에 의해 생성됨
--v [볼륨의 이름]:{컨테이너의 공유 디렉토리}
으로 설정 가능함- 해당 볼륨이 실제로 호스트의 어느 주소에 있는지는 알 필요 없음
- 하지만 확인이 하고 싶다면
$ docker inspect
라는 명령어를 통해 확인할 수 있음 MountPoint
라는 데이터를 통해 확인할 수 있음
- 하지만 확인이 하고 싶다면
- 그냥
-v /root
라고 옵션을 주게되면, auto_volume이 생성됨 docker volume prune
으로 싹 다 지울 수 있음
728x90
'Infra > Docker' 카테고리의 다른 글
[5] Dockerfile (0) | 2021.05.28 |
---|---|
[4] Docker 이미지 (0) | 2021.04.26 |
[3] Docker Logging 및 자원 할당 (0) | 2021.04.26 |
[2] Docker Network (0) | 2021.04.26 |
[0] Docker에 대해 알아봅시다! (0) | 2021.04.26 |
Comments