가상화 기술과 컨테이너 기술
- 컨테이너는 VM과 달리 애플리케이션 수준으로 구성되며, VM의 ISO보다 Minimal한 이미지를 사용한다. OS커널 하나를 공유하여 여러 가상 환경을 에뮬레이션 한다.
Docker 이미지
- Docker 컨테이너를 구성하는 파일 시스템과 실행할 애플리케이션을 하나로 합쳐놓은것.
- 음식으로 치자면 데우기만하면 바로 먹을 수 있는 레토르트식품과 같다.
- 컨테이너를 생성하는 템플릿 역할을 한다.
Docker 컨테이너
- Docker 이미지를 기반으로 파일 시스템과 애플리케이션이 구체화되어 실행되는 상태이다.(프로세스에 점유한 상태 == 활성상태)
- Create -> start의 순서를 Run명령어로 한번에 진행할 수 있다.
Docker Hub에서 이미지 검색 (docker search)
- 기본 구문
- docker search [옵션] 이미지 키워드
- 주요 옵션
- --no-trunc : 결과를 모두 표시
- --limit : 최대 검색 결과 수
- --filter=start-n : 별표가 n개 이상인 것만 표시
- 사용 예시
- docker search nginx
- docker search ubuntu
Docker 이미지 저장소(https://hub.docker.com)
- Docker 이미지 저장소(docker hub)에는 앞서 docker image pull명령을 통해 다운로드한 CentOS베이스 이미지와 nginx와 같은 웹 서버 애플리케이션을 다운받아 이용할 수 있습니다.
레지스트리에서 이미지 가져오기(docker image pull)
- 기본 구문
- docker image pull [옵션] 이미지명 [:태그명]
- 주요 옵션
- -all-tags, -a : 저장소에서 태그가 지정된 이미지를 모두 다운로드
- --disable-content-trust : 이미지 확인 건너뛰기
이미지 목록 보기 (docker image ls)
- 기본 구문
- docker image ls [옵션][리포지토리명]
- 주요 옵션
- --no-trunc : 결과를 모두 표시
- --quite, -q : 이미지 ID만 표시
- -q옵션은 나중에 컨테이너 ls 옵션에서도 쓰인다.
하나 이상의 이미지에 대한 자세한 정보 표시(docker image inspect)
- 기본 구문
- docker image inspect [옵션] 이미지 [이미지...]
- 주요 옵션
- --format, -f : 원하는 정보만 출력
- 사용 예시
- docker image inspect --format="{{.Os}}" nginx
컨테이너 생성 및 시작 (docker container run)
- 기본구문 : docker container run [옵션] 이미지 [:태그][인수]
- 옵션
- --detach, -d : 백그라운드에서 실행한다.
- --interactive, -i : 표준 입력을 연다.
- --tty, -t : 터미널을 사용한다.
- 사용예시
- docker container run --name test_cal centos /bin/cal
- docker container run -it --name test_bash centos /bin/bash
컨테이너 리소스 지정 (docker container run)
- 기본구문
- docker container run [자원 옵션] 이미지 [:태그][인수]
- 사용 예시\
- docker container run -d -p 8181:80 --cpus 1 --memory=256m --name test_resource nginx
컨테이너 리스트 표시 (docker container ls)
- 기본 구문
- docker container ls [옵션]
- 사용 예시
- docker container ls
- docker container ls -a
- docker container ls -a -f name=test_webserver
- docker container ls -a -f exited=0
- docker container ls -a --format
docker container ls
명령어는 현재 실행중인 컨테이너의 리스트를 반환하는데, docker ps
명령어로 더 짧은명령어로 똑같은 출력을 볼 수 있다.docker image rm 이미지이름:버전
으로 이미지를 삭제할 수 있다.docker rmi 이미지이름:버전
- docker container를 run 한다.
- --name 옵션으로 이름을 test_cal으로 준다.
- centos:7
- centos 이미지를 가져온다.
- 오른쪽에 버전을 정의하여 7버젼을 가져온다. 기본값은 latest 최신버전을 가져온다.
- /bin/cal 명령어를 실행할 것이다.
- 현재 centos 이미지가 local에 존재하지 않아 docker hub에서 자동으로 pull 해오는 것을 볼 수 있다.
- 이미지 pull이 성공했고, /bin/cal명령어가 실행되어 달력이 잘 출력된 것을 볼 수 있다.
- 또, -d옵션이 없고 일회용으로 사용되어 명령어가 수행되자마자 프로세스에서 내려갔다.
docker exec 명령어로 접속하기
docker run -it --name test_bash centos:7 /bin/bash
- exec 명령어로 컨테이너에 접속하려면, run명령어를 사용할 떄, 옵션으로 -it를 넣어줘야 한다.
- i : 표준입력(input), t : 터미널
- 만약 -it에서 i를 빼면, 표준 입력이 빠져, 컨테이너에 접속해도 입력을 할 수 없어 나갈 수 없게된다.
- 연결을 끊고 다시해야한다...
docker 백그라운드 실행
- -d 옵션으로 백그라운드에서 실행하게 한다.
docker container run -d --name test_ping centos /bin/ping localhost
- test_ping이라는 이름을 ㅣlocalhost로 ping을 날리는 컨테이너를 하나 시작한다.
docker container logs -t test_ping
으로 test_ping에서 출력되는 출력을 표시해본다.컨테이너 접속 포트 설정 (docker container run)
- docker container run -d -p 8080:80 --name test_port nginx
- test_port이름으로 nginx어플리케이션을 백그라운드로 실행한다.
- 이때, -p 옵션으로 포트포워딩을 한다. 8080으로 들어오는 트래픽을 80포트로 받아준다.
- nginx 에 필요한 이미지 5개가 설치되었다.
- 현재 백그라운드에서 test_port(nginx)가 실행중이다.
- 호스트의 IP와 포트로 접속하면 웹페이지도 잘 보인다.
- docker container stats test_port
- 현재 컨테이너의 자원 사용 현황을 볼 수 있다.
컨테이너 리소스 지정
- 기본구문
- docker container run [자원옵션] 이미지 [:태그][인수]
- 사용예시
- docker container run -d -p 8181:80 --cpus 1 --memory=256m --name test_resource nginx
- 컨테이너에 cpu1개와 메모리 256mb를 지정하여, 최소 이정도의 자원은 필요하다고 정의한다.
- docker stats test_resource 로 확인해보면 CPU는 확인하지 못하지만, memory limit을 볼 수 있다.
컨테이너 디렉토리 공유
docker container run -d -p 8282:80 --cpus 2 --memory=512m -v /tmp:/usr/share/nginx/html --name volume-container nginx
- -d 데몬모드로, -p 8282:80 포트포워딩을 한다.
- CPU는 2개 메모리는 512m로 하고,
- -v로 디렉토리 /tmp(host) -> /usr/share/nginx/html(container) 로 디렉토리를 공유한다.
- 리소스 지정 잘됨
- hostPC에서 index.html을 생성한다.
- volume-container에서 서비스되는 웹페이지에서 수정되었다.
컨테이너 리스트 표시
- 기본 구문
- docker container ls [옵션]
- 사용예시
- docker container ls : 프로세싱 중인 컨테이너 리스트 출력
- docker container ls -a: 모든 컨테이너 리스트 출력
- docker container ls -a -f name=test
- test가 들어가는 컨테이너 검색
- -f 는 filter의 의미이다.
- docker container ls -a -f exited=0
- 상태가 exited인 컨테이너를 출력한다.
- docker container ls -a --format "table {{.Names}}\t{{.Status}}"
- format을 테이블의 형태로 출력해준다.
동작중인 컨테이너 연결
- 예시
- docker container attach test_bash
- 여기서 그냥 exit명령어를 입력하면 test_bash 컨테이너가 종료된다.
- 컨테이너가 종료되지 않으려면, ctrl+p 또는 ctrl+q로 나가야한다.
- 컨테이너를 재시작해주고, ctrl+q로 나가보았다.
동작중인 컨테이너 프로세스 실행
- 기본 구문
- docker container exec [옵션] <컨테이너> <실행명령> [인수]
- 사용예시
- docker container exec -it test_bash /bin/echo "Hello World"
- docker container exec -it test_bash /bin/bash
컨테이너 이름 변경 (docker container rename)
- 사용예시 : docker container rename test_port webserver
컨테이너 안의 파일을 복사
- 사용예시
- docker container cp webserver:/usr/share/nginx/html/index.html /root/index.html
- 컨테이너에서 host로 파일 복사
- docker container cp ./index.html webserver:/usr/share/nginx/html/index.htm
- host에서 컨테이너로 파일 복사
- docker container cp .html webserver:/usr/share/nginx
- 위 이미지처럼 html 폴더를 다운받아 복사해주는 방식으로 전달해주었다.
컨테이너와 원본 이미지의 차이점 확인
- 사용예시
- docker container diff webserver
- A 는 Add, C : Changed 를 뜻한다.
컨테이너를 이미지로 만들기
- 기본 구문
- docker container commit [옵션] 컨테이너 이미지 [:태그]
- 옵션
- --author, -a : 작성자명 기입 (cocudeny@~~~.com)
- --message, -m : 간단한 메세지 기입
- 사용예시
- docker container commit -a "cocudenycocudeny@google.com" -m "Hello~" webserver test_commit:v1.0
이미지 저장
- 기본구문
- docker image save [옵션] <저장 파일명> [이미지]
- 사용예시
- docker image save -o test_commit.tar test_commit:v1.0
tar 이미지 불러오기
- 기본구문
- docker iamge load [옵션] <저장 파일명>
- 사용예시
- docker image load -i test_commit.tar
- docker image ls
- docker container run -d -p 80:80 --name webserver test_commit:v1.0
Docker 네트워크 구조
- External Network에서 VM의 랜카드 (enp0s3)을 통해 docker0의 NAT GW로 통하고, docker의 NAT GW에서 가상 LAN카드(veth1)를 통해 컨테이너의 랜카드와 통신한다.
- veth6fb8512@if8
- veth6b7041c@if10
- vethc148a60@if16
검증
docker container exec -it test_bash /bin/bash
: test_bash 컨테이너에 접속한다.yum install -y iproute
: 컨테이너는 매우 minimal하기 때문에ip a
,ifconfig
조차 없다. 그래서 ifconfig을 위해iproute
를 설치해준다.
- vethc148a60@if16 (test_bash)에서
ip a
명령어를 입력한 모습이다.- 16: eth0@if17
- 컨테이너의 랜카드(eth0@if17)은 16에 연결되어있다.
- 16 == if 16
- 즉 도커엔진(호스트)에 16번포트에 vethc148a60으로 연결되어있고, 이 16번포트에 eth0으로 연결되어있는 것이다.
Docker 네트워크 리스트 표시
- 기본구문
- docker network ls [옵션]
- 옵션
- -f, --fileter=[] : 필터링하여 출력한다.
- --no-trunc : 모든 정보를 출력한다.
- -q, --quiet : 네트워크 ID만 출력한다.
- 사용예시
- docker network ls
- docker network ls -q --fileter driver=bridge
Docker 네트워크 생성 및 삭제
- 기본 구문
- docker network create [옵션] 네트워크
- 옵션
- --driver, -d : 네트워크 브리지 또는 오버레이
- --ip-range : 컨테이너에 할당하는 IP주소의 범위 지정
- -=subnet : 서브넷을 CIDR형식으로 지정
- 사용예시
- 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
- 기본 도커 네트워크
- bridge 네트워크가 docker 0 랜카드이다.
- 네트워크를 생성한다.
- 192.168.123.0/24를 가진 subnet에서 IPrange를 192.168.123.0/25로 준다.
Docker 네트워크 연결
- 기본구문
- docker network connect [옵션] 네트워크 컨테이너
- 사용예시
- docker network connect test_bridge webserver
- docker container inspect webserver
- docker entwork disconnect test_bridge webserver
- docker container run -d --name webserver1 --network test_bridge -p 8080:80 nginx
- docker entwork inspect test_bridge
- webserver가 우리가 만든 test_bridge에 잘 연결되었다.
docker network connect test_bridge test_bash
- 기본 bridge 네트워크에 있었던, test_bash를 test_bridge에도 연결시켰다.
같은 네트워크에 있다는 의미
- test_bash에 exec명령어로 접속한다.
- 여기서 같은 test_bridge에 속해있는 webserver2에 ping을 보내고 싶을 때, webserver2의 IP주소를 얻어야 한다.
- 그러나 같은 네트워크안에 있을 때, 컨테이너의 이름을 도메인주소처럼 서로 사용할 수 있다.
- 서로 IP가 바뀌더라도, DNS처럼 서로 이어져있을 것이다.
db server
- https://hub.docker.com/_/mariadb - Docker hub Myria db page
- docker container로 maria db를 생성할 때, 정의해줄 변수들이 따로 정리되어있다.
- docker run -d -p 3306:3306 --name dbserver \ #3306번 포트포워딩을 하고, dbserver라는 이름으로 컨테이너를 실행한다.
-e MYSQL_DATABASE=wordpress \ # database 생성
-e MYSQL_USER=wpuser \ # user생성
-e MYSQL_PASSWORD=wppass \ # user password생성
-e MYSQL_ROOT_PASSWORD=password mariadb # root password 생성
- 도커 이미지를 활용하여, 환경변수 몇개를 설정한 것 말고는 매우 쉽게 mariadb를 설치했다.
webserver
- docker run -it -d -p 8888:80 --name apache --network test_bridge centos:7 : -id -d 옵션을 -itd로 붙힐 수 있다. 주로 안쓰더라도 혹시몰라 옵션을 넣는 사람들도 있다.
docker inspect test_bridge
에서 apache가 잘 생성되어잇다.docker exec -it apache bash
yum install -y httpd php php-mysql php-gd php-mbstring wget unzip
wget httpd://ko.wordpress.org/wordpress-4.8.2-ko_KR./zip
cd /var/www/html
unzip /wordpress-4.8.2-ko_KR.zip
chown -R apache:apache wordpress/*
: wordpress파일의 수정 권한을 apache:apache로 준다.httpd &
httpd를 시작한다.
- 서버 호스트네임을 호스트IP:3306으로 넣었다.
- 워드프레스생성을 완료하였다.
- docker hub 홈페이지는 스스로 로그아웃을 안한다...
- 다른 컴퓨터에서 docker hub에 로그인할 일이 있다면 마지막에 꼭 로그아웃을 해주도록 하자.
Docker image tag
docker tag test_commit:v1.0 jo1132/test_commit:v1.0
- 도커 이미지에 태그를 달아 다른 두개처럼 생성했다.
- docker images로 보면 다른 두개처럼 따로 나오지만 ID를 확인하면 똑같은 이미지임을 알 수 있다.
- 이는 Docker Hub Push를 위해 이름을 다르게 태그(별칭)을 달아준 것이다.
- docker push ~~ 하지만, requested access to the resource is denied에러가 출력된다.
docker login
docker login
: 도커 로그인해준다.
- 로그인이 성공적으로 끝났고, 비밀번호가 암호화되지 않은 상태로 저장됬다는 에러가 출력된다.
- 다시
docker push jo1132/test_commit:v/1.0
으로 push를 진행한다.
- push가 성공적으로 끝났다.
- docker hub에도 잘 올라왔다.
Ubuntu에서 실행시켜보기
우분투 도커 설치
- 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 bionic stable"
- sudo apt update
- sudo apt-cache policy docker-ce
- sudo apt install docker-ce
도커에서 컨테이너 실행하기
docker run -d -it -p 80:80 --name webserver jo1132/test_commit:v1.0
- 문제없이 이미지를 가져와서 웹페이지를 띄웠다.
- 앞서 다룬 Docker 이미지를 위한 자동화 작업이다.
- Docker 이미지 생성 방법은 베이스 이미지를 바탕으로 일일이 컨테이너를 생성하고, 파라미터를 설정하여, 미들웨어 설치를 통해 만들어진 컨테이너를 다시 이미지로 생성하였다.
- 그러나 Docker 파ㅣㅇㄹ은 컨테이너를 생성하는 여러 구성 정보를 하나의 파일로 정리하고 일괄실행하여 docker build명령을 통해 Docker 이미지를 작성하는 스크립트이다.
vi Dockerfile
- dockerfile의 파일명은
D
ockerfile로 해야한다.FROM ubuntu:18.04 # Base 이미지 가지고온다. MAINTAINER cocudeny@example.com LABEL "name"="webserver" ENV aloha=data ENV path=/var/www/html RUN sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/source.list # 업데이트 할 떄의 소스를 daum kakao로 수정하여 저장한다. RUN apt-get update -y RUN apt-get install apache2 -y COPY nihao /var/www/html COPY hello.html $path ADD aws.tar /var/www/html WORKDIR /var/www/html RUN echo ohayo >> ohayo.html VOLUME /var/www/html EXPOSE 80 ENTRYPOINT ["apachectl"] CMD ["-D", "FOREGROUD"]