Docker
Docker의 durtk
- 2013년 봄, 닷클라우드(현재 Docker)사의 엔지니어 솔로몬하익스가 공개.
- 이대부터 그 편리함 덕분에 Docker는 점차 퍼져가고 있으며, 컨테이너 관련 기술의 표준이 되었다.
Docker의 기본 개념
- Docker는 컨테이너형 가상화 기술(운영 체제 수준 가상화)을 사용한다.
- 컨테이너형 가상화 자체는 이전에 LXC(Linux Containers)가 있었으며, Docker초기에는 컨테이너형 가상화를 구현하는데 LXC를 런타임으로 사용했다.
가상화 기술과 컨테이너 기술 비교
- 가상 머신(VM)은 하드웨어 기반의 여러 게스트 운영 체제로, 하이퍼바이저를 통해 에뮬레이션 된다.
- 컨테이너는 애플리케이션 수준 구성이며, 커널 하나를 공유하는 여러 가상환경을 에뮬레이션 한다.
가상머신(VM)
- 하이퍼바이저를 통해 에뮬레이션 된다.
- 가상머신 OVA, ISO 자체가 Gb단위이며, 크다.
- OS를 설치하고 그 위에 이진, 라이브러리, 애플리케이션들을 올린다.
컨테이너
- 컨테이너는 이미지를 통해 에뮬레이션되며,
- Mb단위로 상대적으로 매우 가볍다.
- 컨테이너 오케스트레이션 엔진 위에서 OS를 설치할수도 안할 수도 있고, 애플리케이션만 컨테이너에 올린다.
- 운영체제를 중앙에서 공유하는 방법으로 더 가벼운 컨테이너를 사용할 수 있었다.
- 운영체제를 없애기위해 운영체제수준의 가상화를 구현하는것이 컨테이너 기술이다.
- 컨테이너 형 기술이다.
Docker 이미지
- Docker 컨테이너를 정의.
- Docker 컨테이너를 구성하는 파일 시스템과 실행할 애플리케이션 설정을 하나로 합친것
- 컨테이너를 생성하는 템플릿 역할을 한다.
Docker 컨테이너
- Docker이미지를 기반으로 생상된다.
- Docker이미지를 스냅샷의 형태로 가져와서, 실행되는 것.
- 파일 시스템과 애플리케이션이 구체화되어 실행되는 상태이다.
- OS가 없을 수 있고, OS수준 가상화된 엔진을 통해 OS자원을 공유해서 사용한다.
Docker 실습
VM 생성
스펙
- OS: Centos7
- RAM: 4Gb
- CPU: 2C
- 가상머신을 새로 만들어주거나, 가져오기를 통해 만들어준다.
가져오기를 할 때, IP가 중복된다면
- 오른쪽 버튼을 눌러 MAC주소를 새로 바꿔준다.
- IP주소를 확인해서 MobaXterm으로 들어가쟈.
CentOS Docker설치
- Docker CE : Community Edition 무료 오픈 소스
- EE: Enterprise Edition 유료, 보안관련 부분이 추가되었다.
curl -fsSL https://get.docker.com/ | sh
: get.docker.com에서 자동으로 OS를 측정해서 최신 도커를 설치할 수 있게 해준다.
- 설치하며 selinux도 disable시켜준다.
yum -y install bash-completion wget unzip net-tools mysql telnet rdate
같이 사용할 여러 도구를 설치해준다.
- bash-completion 명령어 자동완성도구
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
- 도커 bash_completion을 설치, 설정해준다.
systemctl enable --now docker
: 도커를 데몬, 백그라운드로 실행해준다.
docker --version
: 설치 확인 및 버전출력
Docker Engine, Host
- 이제 위 CentOS를 Docker Engine또는 Docker Host로 부른다.
Docker Hub
- 도커 허브 홈페이지, 로그인 후 화면이다.
- 여기서 Run을 하지는 않는다. 배포하는 곳, repository? 이기 때문이다.
- 여기서 Build, Ship, Delivary하게 된다.
- CLI에서도 찾아볼 수 있다.
docker search nginx
: docker hub에서 이미지를 검색한다.
- 제일 위에 STARS를 가장 많이 받은 OFFICIAL nginx가 보인다.
- 그 아래는 다른 사람들이 이를 이용해 만든 또다른 이미지들이다.
도커 기본 명령어 (Ad-hoc)
nginx 가져오기
docker image pull nginx
- VM 과 달리 nginx를 사용하기위해 OS를 내려받은것이 아니라, nginx라는 기능, 어플리케이션 이미지만 내려받아서 컨테이너로 사용한다.
- nginx:latest에서
:
뒤에있는 latest는 버전이 명시되어 있다.
docker image ls
: 현재 호스트에 존재하는 image들의 리스트를 출력한다.
nginx 살펴보기
- docker image inspect의 내용을 전부 보면 이렇게 정보들이 yaml 또는 json으로 작성되어있다.
- 이렇게 키값을 검색하여 값을 출력받을 수 있다.
docker image inspect --format="{{ .Os}}" nginx
- nginx의 OS부분만 필터링해서 보기
docker image inspect --format="{{ .Metadata.LastTagTime}}" nginx
- Metadata의 하위 정보에 접근해서 출력받는 방법이다.
- 이렇게 정보에 접근하는 방법이 쿠버네티스 시험에 나오기 때문에 알아놓는것도 좋다.
- grep명령어로 이렇게 찾을 수도 있다.
컨테이너 생성
docker container create -p 80:80 --name webserver nginx
- 도커 컨테이너를 생성한다. webserver라는 이름으로 생성할 것이고, nginx를 이미지로 사용한다.
- 여기서 nginx이미지 이름은 create뒤에만 있다면 위치는 중요하지 않다.
- 그러나 제일 마지막에 넣는것을 룰이라 생각하자.
- 또, 80:80으로 포트 포워딩을 여기서 진행해줄 수 있다.
- 80번포트로 들어오는 트래픽을 80으로 보내준다.
- 이 뒤에 80번포트를 8080등 다른 포트번호로 보낼 수 있다.
- 출력으로 나온 문자열은 container의 ID이다.
- 그러나 컨테이너가 생성되지 않았다.
docker container list -a
: -a(all) 옵션을 주어서 모두 보기를 해야 보인다.
- 현재 Created상태라 아직 list에 보이지 않는것이다.
- 즉 아직 실행이 되지 않은 상태이다.
- 실행중이라는 것은 Process에 올라갔다는 말이다.
docker container start webserver
: 명령어로 webserver컨테이너를 실행시켜준다.
docker container ls
로 리스트를 출력하면 이제서야 나온다.
웹페이지 접근
- 또, 웹 페이지에 접근할 수 있다.
- 그러나 웹 페이지에 접근하려면 IP주소를 Docker Host의 IP로 접근해야 한다.
- 그래서 접근가능한 IP가 하나밖에 없으니 포트포워딩을 통해 다른 서비스를 이용할 수 있도록 해주는 것이다.
컨테이너 조작
docker container start webserver
: 도커 컨테이너를 시작한다.
docker container stop webserver
: 도커 컨테이너를 정지한다.
- 실행중인 container 리스트에 보이지 않고, Exited상태로 출력된다.
docker container start webserver
: 다시 webserver 컨테이너를 시작한다.
docker container rm -f webserver
: webserver컨테이너를 삭제한다. 이때 -f옵션을 줘서 실행중 상태, 대기중 상태 등에서 제거해준다.
Docker Deamon
docker container run -p 80:80 --name webserver nginx
- run명령어로 Create -> start를 한번에 처리해줬다.
- 웹페이지에도 접근할 수 있다.
- 접근한 로그도 볼 수 있다.
- 그러나 이 상태에서 다음 명령어를 할 수 없다.
- 이 상태를 Foreground(전면부) 실행이라고 한다.
- Ctrl+C 로 종료해준다. 종료해주면서 프로세스가 죽고, container도 대기상태가 된다.
- 여기서 container가 실행중이 아니니, -f 옵션이 없어도 컨테이너가 잘 삭제된다.
-docker container run -d -p 80:80 --name webserver nginx
- 이번에는 -d옵션을줘서 Deamon(Background)에서 실행한다.
- d옵션은 detach라는 뜻이다.
Docker Deamon Multy container
- 이름이 충돌하면 또다시 에러가 출력된다.
- 들어오는 소스포트를 같게해도 포트 Confilct(충돌)에러가 난다.
- 그러나 주의할점은 에러가나도 Container가 Create(생성)은 된다.
- 이렇게된다면 소스포트를 수정해도 이름 충돌에러가 나올 수 있다.
- 이때는 컨테이너를 삭제하고 다시 생성해주면 된다.
- 삭제하고 충돌을 피해주면 81번 포트로 잘 접속이 된다.
Docker run
docker container run --name test_cal centos /bin/cal
- test_cal이라는 이름의 컨테이너로
- centos 이미지를 사용한다.
- /bin/cal 명령어를 실행하고 종료하게 된다.
- 마지막에 명령어를 넣어주면 명령어를 실행하고 종료하는 일회요? 컨테이너가 된다.
- local에 centos이미지가 존재하지 않으니 PULL 해서 centos 이미지를 가져오고 있다.
- PULL이 완료되고, /bin/cal 명령어가 실행되어 달력이 출력되었다.
- 그리고 아래 list를 보면 대기중인 Exited상태가 나온다.
Docker 컨테이너 접속하기
docker container run -it --name test_bash centos /bin/bash
- bash명령어를 사용할 수 있도록 컨테이너에 접속할 수 있다.
- 여기서 -it옵션이 있어야 bash명령어로 들어갈 수 있다.
- 또, exit로 나갈 수 있다.
Docker 컨테이너
생성
- Docker이미지에서 스냅샷의 형태로 컨테이너가 만들어진다.
구동
- 컨테이너가 구동중일 때, 스냅샷 위에 프로세스가 진행된다.
- 여기서 stop <-> start로 정지, 시작 할 수 있다.
중지
- 프로세스에 올라와있지 않을 대, ls명령어에 나오지 않고 -a옵션으로 볼 수 있다.
- 이때 Exited상태로 남아있는다.
Docker Hub에서 이미지 검색
- 기본 구문:
docker search [옵션] 이미지 키워드
- 주요 옵션
- --no-trunc: 결과를 모두 표시
- --limit: 최대 검색 결과 수
- --filter=start=n: 별표가 n개 이상인 것만 표시
- 사용 예시
- docker search nginx
- docker search ubuntu
컨테이너 백그라운드 실행 (docker container tun)
- 기본 구문: docker container run [실행옵션] 이미지[:태그][인수]
- 사용 예시
- docker container run -d --name test_ping centos/bin/ping localhost : 핑 명령어를 사용하는 컨테이너
- docker container logs -t test_ping : test_ping컨테이너의 출력을 보여준다.
컨테이너 접속 포트 설정 (docker container run)
- 기본구문
docker container run -d -p 8080:80 --name test_port nginx
docker container stats test_port
: stats는 현재 컨테이너의 자원 사용량을 보여준다.
- 페이지가 간단해서 그런지 자원이 잘 안올라간다.
컨테이너 리소스 지정 (docker container run)
- docker container run [자원옵션] 이미지 [:태그][인수]
- 사용 예시
- docker container run -d -p 8181:80 --cpus 1 --memory=256m --name test_resource nginx
컨테이너 디렉토리 공유 (docker container run)
docker container run -d -p 8282:80 --cpus 1 --memory=256m -v /tmp:/usr/share/nginx/html--name volume-container nginx
- 여기서 -v 옵션이 vind mount를 뜻한다.
- /tmp(호스트의 경로):/usr/share/nginx/html디렉토리(index.html폴더)에 volume-container라는 디렉토리를 공유할 것이다.
- 컨테이너 실행 후, 호스트 PC에서 HELLO를 넣은 index.html을 만들어준다.
- 8282포트로 접속하니 HELLO가 출력된다.
- 디렉토리가 잘 공유되고 있다.
컨테이너 리스트 표시(docker container ls)
- 기본 구문
- 사용 예시
docker container ls
: 프로세싱중인 컨테이너 리스트 출력
docker container ls -a
: 모든 컨테이너 출력
docker container ls -a -f name=test_webserver
: 이름에 webserver가 들어가는 컨테이너 출력
docker container ls -a -f exited=0
: exited가 0인 컨테이너 출력
docker container ls -a --format "table {{.Names}}\t{{.Status}}"
: 도커 컨테이너들을 name과 status 정보를 table로 표시하라
동작중인 컨테이너 연결 (docker container attach)
- 사용예시
- docker container attach test_bash
- ctrl+p, ctrl+q를 입력
- docker contain ls
- 동작중인 컨테이너에 SSH연결로 접속한것 처럼 연결할 수 있다.
exit
명령어로 연결 해제되면, 컨테이너가 죽어있다.
- 그러나 다시 시작한 후, 연결해서 ctrl+q로 연결 해제되면, 컨테이너가 계속 동작중이다.
동작중인 컨테이너에서 프로세스 실행 (docker container exec)
- 기본 구문
docker container exec [옵션] <컨테이너> <실행명령> [인수]
- 사용예시
docker container exec -it test_bash /bin/echo "Hello world"
docker container exec -it test_bash /bin/bash
- 똑같은 컨테이너에 똑같이 접속하는데, 다만 들어가지 않고 명령어를 실행하게 할 수 있다.
- 또, exit로 나가도 컨테이너가 정지되지 않았다.
- webserver2의 index.html도 수정해본다.
- vi가 없다.... minimal하게 컨테이너를 꾸미기위해 기본설치에서도 용량을 줄인 것이다.
동작중인 컨테이너 프로세스 확인 (docker container top)
- 사용예시
docker container top test_port
- 현재 동작하는 프로세스들의 PID, PPID를 얻을 수 있다.
동작중인 컨테이너의 포트 전송 확인(docker container port)
- 현재 포트 포워드에 대한 정보를 출력한다.
- 포트에대한 정보는 ls -a 명령어로 이렇게도 볼 수 있다.
컨테이너의 이름 변경 (docker container rename)
- 사용예시
docker container rename test_port webserver
- test_port -> weebserver -> webserver로 이름을 바꿨다.
- 이렇게 오타로 이름을 잘못줬다고 컨테이너를 삭제하고 다시만들기는 힘들 것이다.
컨테이너 안의 파일을 복사 (docker container cp)
- 사용예시
- docker container cp webserver:/usr/share/nginx/html/index.html /root/index.html : index.html파일을 host root디렉토리에 옮겨준다.
- docker container cp ./index.html webserver:/usr/share/nginx/html/index.html : 다시 호스트 -> webserver로 보내준다
- docker container cp ./html webserver:/usr/hare/nginx
- 아예 디렉토리 자체를 옮겨줄 수도 있다.
- html폴더를 찾아 MobaXterm으로 호스트에 넣어준 후, 이 html폴더를 복사해주었다.
컨테이너와 원본 이미지의 차이점 확인(docker container diff)
- 사용예시
docker container diff webserver
- A: Add, 새로 추가된 사항을 말한다.
- C: Change, 기존에 존재했으나, 바뀐 사항을 말한다.
컨테이너를 이미지로 만들기 (docker container commot)
- 기본 구문
- `docker container commit [옵션] 컨테이너 이미지[:태그]
- 옵션
- --auther, -a : 작성자명 기입
- --message, -m : 간단한 메세지 기입
- 사용 예시
docker container commit -a "cocudeny(~~@gmail.com)" -m "I made it" webserver2 test_commit:v1.0
: 여기서 -a와 -m은 제작자와 커멘트 부분이라 없어도 된다. 컨테이너로 이미지를 생성하는 부분이다.
docker image ls
- TAG부분에 버전이 잘 들어간 것을 볼 수 있다.
- 결국 REPOSITORY와 TAG가 합쳐져서 이미지의 이름이 되는 것이다.
Ubuntu 도커 설치
sudo apt update -y
: 업데이트를 먼저 진행한다.
sudo apt install apt-transport-https ca-certificates curl software-properties-common
: apt-transport-https와 ca-certificates를 설치해주고, curl, software-properties-common를 설치해준다.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
docker를 다운로드 받아준다.
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
: ubuntu bionic버전의 stable버전으로 설치를 진행한다.
sudo apt update
- sudo apt-cache policy docker-ce : 도커 Comunity Edition으로 정책을 설정해준다.
sudo apt install docker-ce
최종적으로 도커 CE버전을 설치해준다.
- docker --version으로 설치를 확인해준다.
Ubuntu에서 웹서버 컨테이너 올리기
- 먼저 CentOS7에서 이미지를 tar파일로 만들어준다.
docker image save -o test_commit.tar test_commit:v1.0
- 이미지를 test_commit파일로 저장한다.
- -o 옵션은 Out을 뜻한다. (내보내기)
- scp명령어를 통해 Ubuntu VM으로 보내준다.
- docker hub를 통해 업로드 다운로드 할 수 있지만, 현재 docker 계정이 없다고 가정한 상태이다.
- 또, SSH 설정을 아직 안했기때문에 쉽게 진행할 수 있다.
docker image load -i test_commit.tar
- .tar파일을 docker image로 로드한다.
- -i 옵션은 input을 뜻한다.
- 아래 docker image ls로 확인하면 이미지로 잘 올라온것을 확인할 수 있다.
- docker container run -d -p 80:80 -it --name webserver test_commit:v1.0
- run을 진행한다.
- -d 옵션으로 데몬, 백그라운드에서 작동되게 한다.
- -p 옵션으로 80-80포트로 포트포워딩한다.
- -it로 /bin/bash로 들어갈 수 있게 한다.
- --name으로 이름을 webserver로 준다.
- 이미지이름은 v1.0까지 포함하여 이미지 이름이다.
- run까지 작업하여 Deployment(배포)까지 하는 것이 배포의 과정이다.
- 위 작업을 자동으로 하게 된다면 그것이 바로 CI/CD이다.