도커 이미지와 컨테이너
도커 이미지
- 컨테이너를 생성할 때 필요한 요소
 - 여러 개의 계층으로 된 바이너리 파일로 존재
 - 컨테이너를 생성하고 실행할 때, 읽기 전용으로 사용
 [저장소 이름]/[이미지 이름]:태그로 구성
도커 컨테이너
- 도커 이미지를 기반으로 컨테이너를 생성할 수 있음
 - 해당 이미지의 목적이 맞는 파일이 들어있는 파일 시스템과 격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립적 공간이 생성
 - 이미지에서 변경된 사항만 컨테이너 계층에 저장
 - 컨테이너에서 하는 작업은 원래 이미지의 영향을 받지 않음
 - 생성된 컨테이너는 독립된 파일 시스템을 제공받으며 호스트와 분리되어 있음
 - 특정 컨테이너에서 어플리케이션을 설치하거나 삭제해도 다른 컨테이너와 호스트는 변화없음
 
도커 컨테이너 다루기
도커 컨테이너 생성
- docker : docker 클라이언트 언급
 - run : 컨테이너 생성 및 실행
 - <이미지> : 해당 컨테이너를 위한 이미지 이미지>
 
-it란?
-it를 붙여줘야 명령어를 실행한 후 계속 명령어를 적을 수 있음-i- interactive 상호 입출력
 
-t- terminal
 - tty(유닉스 계열 운영체제 명령어)를 활성화해서 배시 셸을 사용하도록 설정
 
-it가 없다면, 그냥 redis-cli를 키고 밖으로 다시 나와버림- exit 또는 command+C로 종료할 수 있으나, 이는 도커 컨테이너를 종료시키고 빠져나옴
    
- Command + P,Q 를 입력하면 컨테이너의 쉘에서만 빠져나옴
 
 
이미지 내부 파일 시스템 구조 보기
$ docker run <이미지> __명령어___
- 명령어 : 이미지가 가지고 있는 시작 명령어를 무시하고 여기에 있는 커맨드를 실행하게 함
 - 특정 이미지 안에 
ex) ls라는 명령어를 실행가능하게 하는, 해당 이미지의 파일 스냅샷 안에 ls를 실행할 수 있게 하는 파일이 있어야 실행가능함 
컨테이너 나열하기
$ docker ps: process status- CONTAINER ID : 컨테이너 고유한 아이디 해쉬값 (일부분)
 - IMAGE : 컨테이너 생성시 사용한 도커이미지
 - COMMAND : 컨테이너 시작시 실행될 명령어, 대부분 이미지에 내장되어 있으므로 별도의 설정이 필요없음
 - CREATED : 컨테이너가 생성된 시간
 - STATUS : 컨테이너의 상태
        
- 실행중은 Up, 종료는 Exited, 일시정지 Pause
 
 - PORTS : 컨테이너가 개방한 포트와 호스트에 연결한 포트
 - NAMES : 컨테이너 고유한 이름
        
- 컨테이너 생성시 –name 옵션으로 이름을 설정하지 않으면 도커 엔진이 임의로 형용사와 명사를 조합해 설정함
 - id와 마찬가지로 중복이 안되고, docker rename 명령어로 변경할 수 있음
 
 
$ docker run <이미지> ping localhost으로 컨테이너가 살아있는지 확인할 수 있음-a옵션으로 정지된 컨테이너를 포함한 모든 컨테이너의 목록을 볼 수 있음
Docker Lifecycle
- 생성(create) -> 시작(start) -> 실행(running)
    
$ docker run <이미지 이름>$ docker create <이미지 이름>+$ docker start <시작할 컨테이너 아이디/이름>$ docker create <이미지 이름>
- 이미지에 있는 파일 스냅샷을 컨테이너의 하드디스크에 올려줌
 - 해당 작업을 한 컨테이너의 id값을 리턴함
      - 
$ docker start -a <시작할 컨테이너 아이디/이름> - ‘-a’ : attach
        
- 도커 컨테이너가 실행될 때, 해당 컨테이너에서 나오는 output을 모두 화면에 표출해줌
 
 - 컨테이너에 프로세스를 시작해줌
 - 포그라운드 식으로 이미지를 동작시켰기 때문에, 백그라운드로 실행할 수 없음
 
 - 중지
    
- 아래 명령어 둘 다 컨테이너를 중지시킴
 $ docker stop <중지할 컨테이너 아이디/이름>- gracefully 하게 중지시킴
 - 자비롭게 그동안 하던 작업들을 완료후 컨테이너들을 중지시킴
 - SIGTERM을 날려 grace period(정리하는 시간)을 두고, SIGKILL을 날려 정지시킴
 
$ docker kill <중지할 컨테이너 아이디/이름>- 바로 컨테이너를 중지시킴
 - 바로 SIGKILL을 날림
 
$ docker stop $(docker ps -a -q)- 모든 컨테이너의 아이디를 중지하는 명령어
 
 - 삭제
    
$ docker rm <삭제할 컨테이너 아이디/이름>- 실행중인 컨테이너는 중지한 후 가능함
 
- 모든 컨테이너를 삭제 : 
$ docker rmdocker 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컨테이너>
 
 
컨테이너를 외부에 노출
컨테이너 실행 명령어 바꾸기
- docker run 이미지 이름
 $ docker run -p 49160:8080 이미지 이름- 로컬 파일(package.json, index.js)을 컨테이너에 복사해줌
 - 네트워크도 마찬가지로 로컬 네트워크에 있던 것을 컨테이너 내부에 있는 네트워크에 연결시켜주어야함
 

- 컨테이너 내부의 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
 
컨테이너 어플리케이션 구축
- 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 컨테이너를 실행하면, 오류가 출력됨
 - 컨테이너의 연결뿐만 아니라 컨테이너 실행 순서의 의존성도 정의해줌
 
 
도커 볼륨
- 이미지는 읽기전용으로 사용하고, 컨테이너의 변경사항은 컨테이너 레이어에 저장됨
 - 컨테이너를 삭제하면, 컨테이너 계층에 저장되어 있던 데이터가 같이 삭제됨
 - 데이터를 영속적인 데이터로 활용하기 위해 볼륨을 이용함
 
- 호스트 볼륨 공유
    
--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으로 싹 다 지울 수 있음