본문 바로가기

KOSA 클라우드 솔루션즈 아키텍트 양성과정

[7.8] Docker(image, container)

* Docker

runC : 컨테이너 런타임

 

Type2 가상머신 vs 컨테이너

- 컨테이너: 라이브러리, 이진, 운영체제를 공유

- 컨데이너 오케스트레이션 엔진: 운영체제의 자원을 컨테이너와 공유하는 역할, 개별 컨테이너마다 운영체제가 없어도 됨

 => 개별 컨테이너 별로 운영체제가 없어서 오버헤드가 없음

 => 운영체제 수준 가상화(컨테이너에서 운영체제를 제외하기 위한 가상화)

- 컨테이너는 애플리케이션만 실행

 

* 도커 이미지:

 - 도커 컨테이너를 구성하는 파일 시스템과 실행할 애플리케이션 설정을 하나로 합친 것

 - 컨테이너를 생성하는 템플릿 역할

 

* 도커 컨테이너:

 - 도커 이미지를 기반으로 생성

 - 파일 시스템과 애플리케이션이 구체화되어 실행되는 상태


--- 센토스 도커 설치(Docker CE; Community Edition)

  -- CE와 EE(Enterprise Edition)의 주요한 차이는 보안 취약점 점검 서비스와 같은 부분

# curl -fsSL https://get.docker.com/ | sh
=> 해당 사이트에서 sh(shell script)를 가져옴(도커 설치를 쉽게 해주는 쉡 스크립트) ,
=> 쉘 스크립트가 현재 사용자가 어떤 운영체제를 사용 중인지 판단해서 해당 운영체제에 맞는 도커를 설치하게 해줌
# yum -y install bash-completion wget unzip net-tools mysql telnet rdate
=> net-tools : 라우트 정보를 확인하는 도구
# rdate -s time.bora.net && clock -w
# curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
=> 도커의 자동완성 도구 활성화
# systemctl enable --now docker
=> 도커 엔진은 데몬(백그라운드 실행)이기에, 스타트와 인에이블 시켜줘야만 이용할 수 있음

=> 설치가 완료되면, 해당 centos는 Docker Engine 혹은 Docker Host라고 함


--- 우분투 도커 설치

 

$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
$ sudo apt update
$ sudo apt-cache policy docker-ce
$ sudo apt install docker-ce

--- AWS 도커 설치

 

$ sudo amazon-linux-extras install docker -y
$ sudo systemctl start docker && systemctl enable docker
$ curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
$ sudo usermod -a -G docker ec2-user

--- 도커 이미지 가져오기(도커 허브; Registry의 역할)

ship : push와 pull을 합해서 ship이라고 함


--- 도커 기본 명령어

 

# docker search nginx
=> nginx를 사용해서 웹 컨테이너(웹 서버)를 만들고자 할 때 사용
=> nginx 이미지가 도커 허브에 있는지 확인하는 명령어
STARS: 받은 별점의 개수, OFFICIAL: 정품이라는 의미, 나머지는 다른 사람들이 만들어 놓은 응용된 버전들
# docker image pull nginx
# docker image ls
# docker image inspect --format="{{ .Os}}" nginx
=> inspect: 도커 이미지의 속성 등 정보를 확인하는 명령어
=> format: 필터링 기능으로 Os를 키로 하는 값을 보겠다는 의미, .Os 앞의 .은 최상위키위치해 있다는 의미
=> 하위에 다른 키가 또 있다면 .Metadata.LastTagTime과 같은 식으로 사용
  => docker image inspect nginx | grep LastTagTime과 같음
# docker container create -p 80:80 --name webserver nginx
=> -p: 포트 포워드를 의미
=> -p 80:80에서 :(콜론) 기준으로 왼쪽이 도커 호스트 포트, 오른쪽이 도커 호스트 내부의 컨테이너 포트
=> 외부 사용자가 호스트 포트로 접근해 오면 도커 엔진 내부의 컨테이너 포트로 트래픽 전송
=> --name webserver nginx: 여러 개의 컨테이너로부터 구분하기 위해 웹 컨테이너에게 테그를 달아주는 작업
포트포워드

# docker container ls -a
컨테이너가 Created 되긴 했지만, 실행(프로세스에 올라가는 것과 동일)은 되지 않은 상태기에 -a옵션을 통해 확인 가능

# docker container start webserver
STATUS가 Up으로 변경됨: 프로세스에 올라간 상태
# docker container stop webserver
stop: 프로세스에서 내려가기 때문에 ls에 나오지 않음
# docker container start webserver
# docker container rm -f webserver
=> -f : force를 의미, 강제로 제거하겠다는 의미
 => -f 옵션을 주지 않으면 실행 중인 컨테이너는 지워지지 않음
# docker container run -p 80:80 --name webserver nginx
=> 앞서 나왔던 docker container create -p 80:80 --name webserver nginx에서 create를 run으로 변경
run : create와 start를 합친 명령어, 도커 호스트의 IP로 접속할 때마다 로그도 출력됨

- 현재 foregroud 실행 상태이기 때문에 프롬프트에서 다른 작업을 진행할 수 없음, ctrl+c나  프로세스 킬
=> 프로세스가 킬 되었으므로 docker container ls 하면 출력되지 않음
=> 따라서, 처음부터 docker container run -d -p 80:80 --name webserver nginx 로 백그라운드로 실행하는 것이 좋음
=> 백그라운드니까 -d가 데몬이라고 착각할 수 있지만, detach의 약어, -p도 port가 아닌 publish의 약어
=> foreground의 프로세스를 킬하고 바로 run이 불가능하므로 docker container rm -f webserver부터 실행

호스트포트와 컨테이너 이름 세트가 다른 포트 포워드와 같으면 충돌일어남

=> 컨테이너 이름의 충돌이 발생하면 아무 일도 없지만, 포트 번호의 충돌이 발생하면 컨테이너가 create 됨

# docker container run --name test_cal centos /bin/cal
=> run: search, create, start, pull 등 작업을 다 묶어 놓은 것, 이미지를 가져오고, 컨테이너를 만들고 실행까지 함
=> centos 이미지 안에 있는 특정 명령어(여기서는 달력)를 실행하는 방법
=> --name: name 옵션을 주지 않으면, 랜덤하게 이름 붙여짐
잠시 사용하는 임시 컨테이너 역할로 ls -a를 통해서만 확인 가능

# docker container run -it --name test_bash centos /bin/bash
=> -it: interactive terminal의 약어, centos로 test_bash라는 컨테이너를 만들고, 컨테이너 내부로 접근
# docker container run -d --name test_ping centos /bin/ping localhost
=> 컨테이너 안에서 백그라운드 실행으로 ping 통신을 하고 있지만, 보이지는 않음
# docker container logs -t test_ping
=> 백그라운드에서 ping 통신이 잘 되고 있는지 확인
# docker container run -d -p 8080:80 --name test_port nginx
# docker container stats test_port
# docker container run -d -p 8181:80 --cpus 1 --memory=256m --name test_resource nginx
=> memory=256m(memory 256m)와 같은 식으로 쓸 수 있음
test_resource 컨테이너의 모습, 할당한 자원만큼 들어가 있음

# docker container run -d -p 8282:80 --cpus 1 --memory=256m -v /tmp:/usr/share/nginx/html --name volume-container nginx 
=> 바인드 마운트: /tmp 경로에 콘텐츠를 넣으면 ':'을 통해 웹 서버 안 쪽의 html 파일이 있는 경로와 연결 됨
/tmp에 넣은 내용

디렉토리 공유를 통해 8282포트로 접속했을 때 /tmp에 저장한 내용 표시

# docker container ls
# docker container ls -a
# docker container ls -a -f name=test_webserver
=> 컨테이너가 너무 많을 때 원하는 컨테이너를 찾을 수 있음
=> f는 format의 줄임말
# docker container ls -a -f exited=0
=> exited=0 : stop되어 있는 컨테이너 보여줌
# docker container ls -a --format "table {{.Names}}\t{{.Status}}"
Names와 Status만 추려서 테이블을 만드는 명령어

# docker container attach test_bash
[root@1689b6318c35 /]# ctrl + p, ctrl +q 를 입력
=> 프롬프트가 바뀌면서 컨테이너 안 쪽으로 들어가게 됨
=> 프롬프트에서 나올 때 exit을 하면 컨테이너가 stop됨, 따라서 ctrl + p ctrl + q 해야 컨테이너가 실행된 상태로 나옴
=> 이러한 과정이 번거로우니까 attach는 잘 쓰지 않고, exec라는 명령어를 사용하게 됨
# docker container ls
# docker container exec -it test_bash /bin/echo "Hello world"
=> -it : test_bash 터미널로 들어가
=> /bin에서 Hello world를 출력
=> 프롬프트에서 exit 입력하고 나와도 컨테이너가 stop 되지 않음
=> exec는 /bin/bash만 실행 가능
# docker container exec -it test_bash /bin/bash
exec 명령어로 컨테이너에 들어가서 인덱스 파일을 바로 수정할 수 있음
# docker container top test_port
# docker container port test_port
# docker container rename test_port webserver
=> test_port 컨테이너의 이름을 webserver로 변경
# docker container cp webserver:/usr/share/nginx/html/index.html /root/index.html
=> webserver 컨테이너의 html폴더 하위의 index.html 파일을 도커 호스트 root 하위의 index.html파일로 가져옴
# docker container cp ./index.html webserver:/usr/share/nginx/html/index.html
# docker container diff webserver
=> diff : 처음의 상태와 지금의 상태를 비교하는 명령어, 일종의 log를 확인하는 보안적인 측면에서 사용
 => A : 추가된 것 Add
 => C: 변경된 것 Change
# docker container commit -a "johnlee<test@example.com>" -m "NICE TO MEET YOU" webserver test_commit:v1.0
=> a : author의 줄임말
=> -a "johnlee<test@example.com>"는 필수 아님, 단지 해당 이미지를 내가 만들었다는 것을 증명하는 것
=> -m: 내가 작업한 내용이 무엇인지 간단하게 코멘트를 달아주는 것
=> test_commit:v1.0 에서 v1.0은 버전 관리를 위해 임의로 붙인 것으로 테그가 됨
# docker image ls
test_commit:v1.0 이미지가 생성됨
# docker image inspect test_commit:v1.0
# docker image save -o test_commit.tar test_commit:v1.0
=> save -o : 저장해서 output(내보냄)
=> 타르 형식의 파일로 test_commit:v1.0 이미지 파일을 내보내겠다는 의미
우분투를 사용하는 도커 호스트로 tar파일 전송

=> root : 파일을 보내고자 하는 서버의 유저 네임 
# docker image load -i test_commit.tar
=> 우분투에서 타르 파일을 추출하면서 도커의 이미지로 만들어주는 로드 작업
# docker image ls
# docker container run -d -p 80:80 --name webserver test_commit:v1.0
=> run이 배포(deployment)와 같은 의미로, 웹 서버 컨테이너를 만들어서 실행시키는 것
# docker network ls
# docker network ls -q --filter driver=bridge
# docker network create -d bridge --subnet 192.168.123.0/24 --ip-range 192.168.123.0/24 test_bridge
# docker network rm test_bridge
# docker network connect test_bridge webserver
# docker container inspect webserver
# docker network disconnect test_bridge webserver
# docker container run -d --name webserver1 --network test_bridge -p 8080:80 nginx
# docker network inspect test_bridge