Container & Docker

yooooooona·2024년 12월 1일

MLOPS

목록 보기
2/12
post-thumbnail

1. 용어

Docker:
컨테이너를 사용하여 각각의 프로그램을 분리된 환경에서 실행 및 관리 할 수 있는 툴이다.

사용하는 이유: 독립성과 재현성, 나의 로컬 컴퓨터를 오염시키지 않아도 된다.

컨테이너:
하나의 컴퓨터 환경 내에서 환경이 독립된 여러개의 미니 컴퓨터 환경을 만들게 되는데 그 각각의 미니 컴퓨터 환경을 컨테이너라고 한다.
비유1) 마치 윈도우 환경에서 하나에 컴퓨터에 여러 사용자가 사용할 수 있도록 계정이 나뉜 경우, 각각의 사용자 계정은 완전 별도의 환경으로 꾸려지게 된다.
비유2) 과거 버추얼머신과 비교하자면 넓은 건물 내부에 진짜 벽을 세워서 방을 나눠 세를 주는 경우의 복잡/어렵/시간비효율과 비교하여, 세입자가 자기만의 작은 컨테이너를 가지고 들어와서 살게되면 벽을 세워야하는 어려움이 사라져서 용이함.

호스트 컴퓨터:
여러 컨테이너가 가동되고 있는 마치 내 노트북같은 컴퓨터를 호스트 컴퓨터라고 한다.

컨테이너의 독립성:
1) 디스크(저장공간)을 각각 가지고 있다. 즉 a컨테이너에서 b컨테이너의 저장파일에 닿을 수 없다
2) 네트워크도 독립적이라 컨테이너별로 고유한 ip와 포트정보를 가지고 있다.

이미지
비유) 닌텐도의 게임별 게임 칩
Node.js라는 프로젝트를 이미지로 만들었을 경우, 다른 누군가 이를 docker를 통해 실행시키면 Node.js가 컨테이너 환경에서 복잡한 설치과정없이 손쉽게 실행된다.

즉 Node.js에 필요한 다른 곁다리 친구들의 다운로드,설치, 버전맞춤에 필요한 모든 액션들이 이미지에 다 저장되어 있어서, 이 이미지를 실행하면 한큐에 뚝딱! 바로 Node.js를 사용할 수 있게끔 미니 컴퓨터 안에서 셋팅+실행해준다.

dockerhub:
github처럼 이미지를 저장해 놓고, 공유하고, 이를 다운받을 수 있는 곳
우리는 이미지를 가져올 때 dockerhub에서 올라가 있는 이미지를 다운받게 되는 것이다.

참고) 이미지는 버전을 tag라고 부른다.

도커허브에서는 버전=태그들의 정보와 이미지별 how to use가 적혀있는데
특히 고유한 옵션을 필수로 입력해야만 사용할 수 있는 이미지들이 있어
이 부분을 반드시 확인하는게 좋다!
예: mysql이 password 옵션

docker desktop:
현재 내 컴퓨터의 컨테이너/이미지 상태들을 보여주는 아주 편리한 프로그램!! 보면서 작업하면 좋다.

참고) docker desktop도 docker hub도 각각 한번씩 로그인해줘야한다!

2. 명령어들

(1) 이미지 관련

docker pull [이미지명]
이미지 다운로드 받기

docker pull [이미지명]: [버전=태그명]
해당 버전의 이미지를 다운받아오기, 각자 다른 버전의 이미지는 서로 다른 파일처럼 별개로 저장되어 다운로드되어진다. 태그를 입력하지 않으면 기본으로 latest 즉 가장 최신의 이미지가 자동으로 다운되느 것.

docker image ls
다운 받아져 있는 이미지들 확인하기
첫행: 이미지 이름
TAG: 버전명
IMAGE ID: 이미지 별로 아이디가 존재한다 (COMMIT ID 처럼)
CREATED: 제작자가 이 이미지를 만든 날짜 (내가 다운받은 날짜가 아님!)

docker image rm [IMAGE ID 앞자리 3-4글자/또는 이미지 이름]
해당 이미지 삭제하기. 단, 지금 이 이미지를 사용 중인 '중단된' 컨테이너가 있다면 삭제 불가.

docker image rm -f [IMAGE ID 앞자리 3-4글자]
지금 중단된 컨테이너가 사용 중인 이미지 강제로 삭제. 단, 지금 계속 켜져있는 컨테이너의 이미지는 삭제할 수 없다. 이 경우 컨테이너를 중단시키고 이 명령어 사용하기

docker image rm $(docker images -q)
지금 사용중이지 않은 모든 이미지 삭제하기

docker image rm -f $(docker images -q)
지금 중지된 컨테이너에서 사용중인 이미지 삭제하기

(2) 컨테이너 관련

docker create [이미지 이름]
해당 이미지를 가지고 도커 생성하기
만약 다운받지 않은 이미지일지라도 create 명령어를 주면 다운로드가 되면서 동시에 컨테이너를 생성한다

docker start [컨테이너 ID의 일부]
create는 컨테이너를 만들기만 하고 실행하진 않는다. start를 해줘야 컴퓨터의 전원버튼을 켜는 것. 컴퓨터를 켜면 ps -a 명령어에서 상태가 UP으로 바뀐다.ㅣ

docker run [이미지 이름]
도커 create와 start를 합친 기능.
사실 pull+creat+start!! 이걸 가장 많이 사용한다!


docker ps -a
내 컴퓨터에 떠있는 모든 컨테이너 리스트 (실행, 중단 모두)
CONTAINER ID : 컨테이너를 식별하는 아이디
IMAGE: 어떤 이미지가 해당 컨테이너에 열려있는지
STATUS: 각 컨테이너의 상태 : CREATED / UP / EXTISTED

docker ps
현재 실행중인 컨테이너들만 리스트


docker stop [컨테이너 ID의 일부]
해당 컨테이너의 중지 = 컴퓨터를 얌전히 윈도우>시스템 종료 버튼 눌러서 끄는 정상적인/안전하게 방법

참고) 여러개를 한번에 중지하는 방법: 띄어쓰기 넣어서 아이디 여러개 넣기

docker kill [컨테이너 ID의 일부]
해당 컨테이너의 중지 but 컴퓨터의 전원버튼 오래눌러서 끄는것처럼 비정상적으로 끄는 방법/stop과 다르게 무식하게 끄느라 파일들이 손상될 수 있다. 하지만 컴퓨터가 먹통되었을때는 어쩔 수 없이 써야하는 명령어


docker rm [컨테이너 ID의 일부]
중지되어있는 컨테이너 삭제하기! 실행중인 컨테이너를 삭제하려하면 오류창이 뜬다.

docker rm $(docker ps -qa)
중지된 모든 컨테이너 한번에 삭제하기

*docker rm -f [컨테이너 ID의 일부]
실행되고 있는 컨테이너 중시키고 삭제하기 >> 즉 stop+rm로 편리함!


위의 상태는 foreground; 내가 실행시킨 프로그램의 내용이 화면에 실행되고 출력되는 상태
/ 반대말은 background; 내가 실행시킨 프로그램이 컴퓨터 내부적으로 실행되는 상태

foreground에서 나가는 방법: ctrl+c

docker run -d [이미지 이름]
백그라운드에서 컨테이너를 만들면서 이미지를 여는 방법
docker run -it [이미지 이름]
포어그라운드에서 인터렉티브한 환경으로 컨테이너를 만들면서 이미지를 여는 방법


docker run --name [원하는 컨테이너 이름][이미지 이름]
컨테이너를 만들때 원하는 이름 붙여서 만들기
docker ps를 하면 제일 마지막 행에 이름이 붙여진 걸 알 수 있다.


환경변수
이미지마다 고유한 환경을 구성하는데 입력해줘야하는 변수들이 있을 수 있다. 이러한 것들을 지정해주는 옵션은 -e

docker run -e [환경변수 이름]=[환경변수값][이미지명]
(예: mysql의 비밀번호 )
docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql

입력한 환경변수 확인하는 법
1) 해당 컨테이너로 들어가기
2) **echo $[환경변수이름]


포트맵핑하는 법

컨테이너에서 backgound로 만든 내용을 브라우저를 통해 로컬호스트로 불러오기를 할는 방법 :
ps로 포트 확인하기 > 크롬(가능하면 시크릿 모드(ctrl+shift+n)로) > localhost:[포트번호]

하지만!!! 불러와지지 않는다 왜??
포트맵핑을 하지 않아서!!

컨테이너는 독립된 컴퓨터로서 자기만의 port를 가지고있다.
이 컨테이너만의 port를 내 호스트 컴퓨터의 port와 연결시켜주는 것을 "portmapping"이라고 한다.

포트맵핑을 하면서 컨테이너 만드는 법
docker run -d -p [호스트포트]:[컨테이너포트][이미지 이름]
(예: docker run -d -p 4000:80 nginx)
(더 편리한 예: docker run -d -p 80:80 nginx)

참고) 만약 포트맵핑을 하려했는데 해당 포트가 already in use라고 뜬다면?
상황의 예: 컨테이너로 mysql을 포트매핑하려했는데, 내 호스트 컴퓨터에서 이미 mysql을 열심히 사용중이라 같은 이름의 포트로 연결이 안됨
해결방법: 호스트 컴퓨터의 mysql 강제 종료하기


docker logs [컨테이너 Id 일부]
도커의 모든 작동기록인 로그들을 보는 방법

docker logs --tail [원하는 숫자][컨테이너 Id 일부]
숫자만큼의 가장 최근 로그들만 보기

docker logs -f [컨테이너 Id 일부]
실시간 로그 결과 보기
단 예전 로그들도 다뜨고 난 뒤에 추가된다

(응용) docker logs --tail 0 -f [컨테이너 Id 일부]
예전로그들은 안보여주고 지금부터 추가되는 것들만 쌓임

로그를 언제쓰는가? 디버깅할떄!
상황 예)run을 했는데 create는 되었지만 start는 안된 컨테이너의 이유를 찾기! = password option is not specified라고 답을 알수있음


실행중인 컨테이너 내부에 접속하기!

docker exec -it [컨테이너 id][실행형식]
예) docker exec -it 500 bash

완전 별개의 객체인 호스트와 컨테이너
우리가 쓰는 터미널은 호스트 컴퓨터의 터미널이다
그 터미널로 컨테이너로 들어가서 컨테이너를 작동시킬 수 있는 코드!

위의 커멘드를 입력하면 커멘드 행 앞에 다른 이름이 뜨는 것을 볼 수 있다.
bash로 들어가면 리눅스 커멘드 ls, cd, cat 등을 자유롭게 쓸 수 있다.

해당 컨테이너에서 나오는 방법: exit


도커 볼륨

도커의 한계:
만약 아래와 같이 할 경우
1) 컨테이너를 만들어서 a이미지를 실행시키고 열심히 작업해서 파일 1을 컨테이너에 생성함
2) 해당 컨테이너를 닫고 삭제함
3) 다음날 같은 a이미지로 컨테이너를 새로 만들어 실행함
결과: 파일 1은 사라져있다!!

왜냐하면 도커로 만드는 컨테이너는 이러한 휘발성=재현성을 목표로 만들어졌으니까

하지만 만약 다시 a이미지를 열었을때 이전 파일들을 다시 가져오고 싶다면?
호스트 저장공간과 컨테이너의 저장공간을 연결지어놓는 '볼륨'이라는 명령어를 써놔야함!!

docker run -v [호스트의 디렉토리 절대경로]:[컨테이너의 디렉토리 절대경로][이미지 이름]

즉 이경우, 앞의 경우과 다르게
컨테이너의 작업 디렉토리에서 작업한 결과가 호스트 컴퓨터의 작업디렉토리에 연동되어 저장되고, 이 컨테이너를 삭제해도 호스트 컴퓨터에 작업 결과들이 남아있게 된다.

컨테이너의 디렉토리 절대경로는 이미지마다 다른데
도커허브에서 해당 이미지에 대한 세부설명 중 "where to store data" 파트에 있음

-p로 포트맵핑만 한 경우

컨테이너가 돌아가는 동안에는 호스트 컴퓨터의 데이터플랫폼에서 해당 mysql을 열어보면 잘 연결이되지만, 컨테이너를 종료하고 나면 호스트 컴퓨터의 데이터플랫폼에서 해당 mysql이 인식되지 않는다.

-p로 포트맵핑도 하고 볼륨도 한 경우

이 경우 컨테이너를 지웠다가 새로만들면서 이미지를 열면
이전 컨테이너에서 작업한 파일들이 호스트의 저장공간에 저장되어있었어서 다시활용할 수 있다.

주의사항: 호스트컴퓨터의 저장공간과 관련된 각종 환경변수는 처음 컨테이너를 연결했던 때로 유지된다. 만약 컨테이너를 다시 만들어서 들어올때 환경변수를 다르게 해놨다면, 해당 디렉토리를 사용할 수 없거나, 아예 그 프로그램이 안돌아가게 된다.
이런 경우 기존의 호스트 저장공간 내 디렉토리를 삭제해주거나,
이미지를 실행시켜서 거기 안에서 환경변수를 바꿔줘야한다.


기타

docker run --rm [이미지이름]
이 도커를 stop할때 동시에 삭제되도록 하는 것


요약

용어: 이미지, 컨테이터, 도커, 도커 허브, 도커 데스크탑

기본 명령어:
이미지 가져오기
컨테이너 만들기
컨테이너 시작하기
이미지 가져오기+컨테이너 만들기+컨테이너 시작하기
컨테이너 끄기
컨테이너 리스트 확인하기 (실행중인 것만)
컨테이너 리스트 전체보기
이미지 리스트 보기
컨테이너 삭제하기
이미지 삭제하기
컨테이너 로그 확인하기
컨테이너 최근 n개 로그만 확인하기

run 명령어 옵션:
포트맵핑
볼륨
이름 지정
foreground에서 run
background에서 run
종료하면 자동삭제 조건으로 run

background로 실행중인 컨테이너에 들어가기
컨테이너에서 나오기

profile
배우고 있습니다.

0개의 댓글