도커에 대하여 - 8.17

양승현·2022년 8월 17일
0

docker

목록 보기
1/12
post-thumbnail

클라우드와 도커의 시작

  • 클라우드 = 남아도는자원을 외부에 제공(그리드 컴퓨팅) + 과금시스템(유틸리티 컴퓨팅, 전기세)
  • 클라우드는 사설 클라우드와 퍼블릭(공인) 클라우드로 나뉜다.
공인 클라우드 (aws,azure,gcp,ncp...)
사설 클라우드 (openstack, cloudstack, vmware)

클라우드 컴퓨팅 특징

  • on-demand - 주문 즉시 사용가능
  • 인터넷 접속이 가능하다면 위치에 상관없이 24시간 온라인을 유지할 수 있다.(서비스 이용가능)
  • 탄력성(필요할 때 마다 늘리고 줄이고 가능)/확장성 : "auto scale"을 통해 탄력적으로 서비스의 확장과 축소가 가능하다.
예) 인스턴스의 대수를 2대에서 4대로 늘리는 것, 디스크의 용량을 10GB에서 20GB로 늘리는 것. 
-> 수평적으로 늘리는 것/수직적으로 늘리는 것. 일반적으로 클라우드에서 탄력적/확장성을 얘기할 때에는 scale out을 지칭한다. 
특정 상황이 되면 자동으로 스케일을 확장하도록 설정할 수 있다. -> "**오토스케일링"**
  • 자원 관리를 풀에 담아서 일괄적으로 처리 할 수 있다. -> 자원의 클러스터화가 가능해야한다.
  • 자원 사용의 모니터링이 가능해야한다. 이는 과금 서비스와 연계하여 사용될 수 있다.
  • 24시간 온라인을 유지할 수 있는 애플리케이션(예전에는 downtime이 많았다.) : 가상머신등의 지역간 이동을 통해 구현 가능하게 됨

서버 가상화

  • kvm과 같은 하이퍼바이저를 이요와여 가상 서버 형태로 서버를 제공하는 방법

스토리지 가상화

  • 적은 양의 스토리지를 묶어 하나의 큰 자원풀로 활용하는 것

네트워크 가상화

  • vlan, vxlan, vpc(virtual private cloud), vrf(virtual routing forwarding - 각 고객사별로 별도의 라우팅 테이블을 제공하는 것)

프로비저닝(provisioning)

  • 시스템을 즉시 사용할 수 있는 준비 상태로 대기하는 것(network, server)
  • 만약 가상서버 10대, 네트워크 준비, 볼륨 준비 등을 일일이 처리한다면 이는 오랜시간이 걸릴 것이다. 이를 이괄적으로 처리할 수 있는 프로비저닝 도구가 있다.(대표적으로 ansible,chef,puppet,vagrant 등)
-> 일일이 명령을 통해 구현했다면 프로비저닝 도구를 일반적으로 코드로 구현하여 배포한다.

배포(Deployment)

  • 애플리케이션을 즉시 사용할 수 있는 준비 상태로 대기하는 것(mysql, mariaDB)

오케스트레이션

  • 시스템 또는 애플리케이션의 묶음을 일괄적으로 배포/프로비전 할 수 있으며 이를 회수하는 것.
  • 일반적으로는 애플리케이션/컨테이너의 관리에 주로 사용하는 용어이며 특히 컨테이너와 관련하여 대표적인 오케스트레이션 도구로는 "쿠버네티스"가 있다.

클라우드 구분

  • laas - 서버/네트워크/방화벽과 같이 서비스 제공을 위한 인프라 환경을 제공하는 것 -> openstack, ec2, kvm을 인스턴스 형태로 제공한다.
  • paas - 개발환경(데이터베이스, 개발 언어, IDLE 등을 동일한 버전등으로 제공할 수 있다.)
  • Saas - 소프트웨어를 제공한다.

온프레미스

  • 크라우드와 달리 자체 데이터 센터를 운영하는 것
  • 자체 솔루션등을 적용할 수 있어 보안상, 효율성 면에서는 우수하다고 할 수 있다.
  • 단, 현재는 온프레미스 환경에서 이를 클라우드로 전환하는 케이스가 늘고 있다.
-> 사설 클라우드로 변환

사설 클라우드

  • 대기업/금융권등의 서버를 자체 데이터 센터에서 클라우드를 구축하고 이를 활용하는 방법

하이브리드 클라우드

  • 퍼블릭과 프리빗의 결합
  • 예를들어 웹서버는 aws에서 제공하고 데이터 보관 서비스는 사설 클라우드를 활용하는 방법

Bare Metal vs 가상머신 vs 컨테이너

베어메탈

  • 애플리케이션이 OS 위에 직접 배포된다.

가상머신

  • 파이퍼바이저를 이용하여 가상서버를 구축하고 해당 서버위에 애플리케이션이 배치되는 형태로 가상머신은 각자의 커널을 갖는다.
  • 실제로 애플리케이션이 동작하기 위해서는 guest os -> 커널 -> 하이퍼바이저 -> 커널 -> 물리자원을 거쳐야 하므로 성능 저하가 발생한다.

컨테이너

  • (도커 엔진 -> 도커에서 이미지와 컨테이너를 관리하는 도구이며 도커의 핵심)
  • 컨테이너는 자신이 속한 Os의 커널을 직접 사용하므로 성능 저하가 거의 없다.
  • 사용자(이용자) 입장에서는 자신이 이용하는 애플리케이션이 가상머신에서 또는 컨테이너에서 동작하는것은 관심 대상이 아니다. 이용자는 빠른 처리 속도만을 요구한다.
  • 최근에는 대부분의 애플리케이션이 잦은 I/o를 요구하므로 컨테이너를 이용하는 경향이 아주 많다.
  • 따라서 성능저하가 없으면서도 배포가 용이하고 스케일등의 적용이 쉬운 컨테이너를 이용하는 것이 이용자를 위해서 유리하다.
  • 컨테이너는 가상머신처러 물리적 자원을 격리시키는 것이 아니라 프로세스를 격리시킬수 있다.
ps -ef | grep httpd
httpd가 설치된 상태에서 추가적으로 httpd를 설치하여 웅영할 수 있는가? -> 없다

도커

  • 도커는 리눅스에서 사용하던 기술인 namespace(프로세스 자원관리), cgroup(자원 사용 제한)를 이용하여 개발되었다.

도커의 namespace

  • 아래와 같은 리눅스의 네임스페이스를 차용하여 만들었다.
  1. user namespace - 사용자 또는 그룹별로 격리
  2. UTS(unix time-sharing) namespace - 응용프로그램 입장에서 호스트명과 도메인에 대한 분리된 가시성을 제공
  3. 마운트 namespace - 프로세스에서 마운트된 파일시스템에 대한 가시성을 제공하기 위해 자신만의 마운트 네임스페이스 사용할 수 있다.
    (각각의 컨테이너에서 별도의 호스트 디렉토리를 마운트 할 수 있다.)
  4. PID namespace - Process ID는 호스트상의 다른 응용프로그램으로부터 격리 될 수 있다. 이를 통해 동일한 애플리케이션이 동시에 2개 이상 동작하는 것도 가능하다.
  5. 네트워크 namespace - 네트워크 인터페이스, 라우팅 테이블등에 대한 격리 가능하다.

CI/CD

  • 지속적인 통합과 지속적인 배포
  • 기존에는 코드의 변경 사항을 일괄적으로 모아 한꺼번에 서버에 올리는 형식이였다면 이제는 각 개발자가 자신이 담당하는 코드를 github/gitlab에 push하면 이를 감지한 CD(gitlab,jenkins)가 컨테이너에 이를 실시간(비정기적,정기적[cron])으로 이를 컨테이너에 반영한다.
gitlab은 설치형 오픈소스로도 제공된다.
  • 쿠버네티스는 컨테이너를 생성하는 runtime(containerd, cri-o, rkt, podman)이 아니다.(쿠버네티스가 사실상 표준으로 취급된다.) -> ECS, EKS, GKS

  • 쿠버네티스와 달리 runtime으로 도커만을 사용하는 오케스트레이션 툴도 있다 -> swarm

  • 컨테이너 생성을 위해서는 이를 위한 이미지가 필요하다. 이미지는 정적인 파일이며 수정이 된다면 수정된 이미지를 이용한 모든 컨테이너는 변경된 내용이 반영된 상태에서 배포된다.

  • 컨테이너는 이미지로 부터 받은 내용을 토대로 생성되고 추가된 내용은 영구적으로 보관되지 않는다. 영구적인 보관이 필요하다면 별groups도의 volume을 이용하여 데이터를 보관할 수 있다.

이미지가 보관되는 장소 Registry

local registry

  • 도커가 설치되어 있는 내 컴퓨터
rapa@rapa:~$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
nginx        latest    b692a91e4e15   2 weeks ago   142MB
httpd        latest    f2a976f932ec   2 weeks ago   145MB

private registry

1) 지정된 사용자/그룹의 접근만을 허용하는 저장소. aws,azure,gcp 와 같은 퍼블릭 클라우드 환경에서 특정 사용자/계정/프로젝트만을 위한 저장소
2)dockerhub에서 저장소를 생성할 때 private으로 생성하게 되면 지정된 사용자들만 접속할 수 있다.
3) registry 컨테이너를 이용하여 회사내에 자체적으로 사설 저장소를 구현할 수 있다.

public registry

  • 모든 사용자들이 접근하고 이미지를 다운 받을 수 있는 곳 dockerhub

이미지로부터 컨테이너를 생성하는 과정

  • 1) docker container run --name httpd01 .... httpd (명령어 입력)
  • 2) 로컬에 httpd 이미지가 있는지 여부를 확인하고 없다면 public registry 로 접속하여 httpd 최신 버전을 로컬 레지스트리로 다운로드 한다.
  • 3) 로컬 레지스트리에 저장된 이미지를 이용하여 컨테이너 생성
  • 4) 생성된 컨테이너를 실행

컨테이너의 종류

    1. os 컨테이너
    1. 애플리케이션 컨테이너

도커 이미지

step0.

  • 이미지는 동일 IP 주소에서는 하루에 100개 정도 받을 수 있다.
    계정 별로 100개 받고 싶다면 인증정보를 통해 접근해야 한다.
    또한 로컬에 우리가 만들어 둔 이미지를 public registry에 push하기 위해서도 인증정보가 필요하다.
    https://hub.docker.com

로그인 방법

  • 1) username/password
rapa@rapa:~$ sudo cat /home/rapa/.docker/config.json 
- id,passwd가 저장되어 있다.
rapa@rapa:~$ rm -rf /home/rapa/.docker/config.json
- 보안을 위해 삭제
  • 2) username/token
echo "토큰" | docker login --username gnon5367 --password-stdin

step1.

  • 퍼블릭에 있는 이미지를 로컬 레지스트리로 pull 해야 한다.
docker pull centos:7
docker pull nginx 

step2.

  • centos7 컨테이너 배포하기
rapa@rapa:~$ docker container run -it --name centos01 --hostname centos1 centos:7 /bin/bash

step3.

    1. exit -> 동작중인 컨테이너를 종료하고 빠져나온다
rapa@rapa:~$ docker container ls  <-- 동작중인 컨테이너 확인
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
rapa@rapa:~$ 
docker start centos01  <--- 중지중인 컨테이너 시작하기
docker attach centos01 <--- 컨테이너 내부로 진입하기
    1. ctrl + p, ctrl + q -> 컨테이너를 종료하지 않고 빠져 나온다.

step4.

  • nginx 이미지 다운로드 하기
rapa@rapa:~$ docker pull nginx
-> docker hub 에 있는 nginx 최신 이미지를 로컬 저장소에 pull 한다 

rapa@rapa:~$ docker image ls

step5.

  • nginx 배포하기
rapa@rapa:~$ docker container run -d --name nginx01 -p 8001:80 nginx

8001:80 -> ubuntu host의 8001 포트와 컨테이너의 80번 포트를 매핑하겠다.

rapa@rapa:~$ docker container ls

  • IP 확인
  • nginx 접속

step6.

  • httpd 실행하기
rapa@rapa:~$ docker container run -d --name httpd01 -p 8002:80 httpd

    1. 로컬저장소에 이미지가 있는지 여부를 확인한다. 없다!!!
    1. 도커 허브에 접속하여 httpd:lastest 를 찾고 이를 pull 한다.
    1. 로컬에 pull 된 이미지를 이용하여 이름 httpd01 인 컨테이너를 생성한다. 이때 ubuntu 호스트의 8002번 포트와 컨테이너의 80 번 포트를 자동으로 매핑해 준다.
rapa@rapa:~$ docker container start httpd01

rapa@rapa:~$ docker container exec httpd01 env

-> 외부 연결용 인터페이스가 없는 경우에는 외부 클라이언트에서 컨테이너에게 명령을 전달하고 결과를 외부에서 받을 수 있다
  • 결국 exec 를 사용하면 컨테이너 내부로 직접들어가지 않아도 컨테이너의 명령을 외부에서 전달하여 결과를 확인할 수 있다.

Quiz. httpd를 이용하여 추가 웹서버를 실행해 보세요.

rapa@rapa:~$ docker container run -d --name httpd02 -p 8003:80 httpd
rapa@rapa:~$ docker container start httpd02

index 파일 수정

rapa@rapa:~$ touch index.html
rapa@rapa:~$ vim index.html 
rapa@rapa:~$ curl https://www.naver.com > index.html
rapa@rapa:~$ docker container run -d --name httpd80 -p 8080:80 -v /home/rapa:/usr/local/apache2/htdocs httpd

rapa@rapa:~$ docker container run -d --name httpd88 -p 8888:80 -v /home/rapa:/usr/local/apache2/htdocs httpd

rapa@rapa:~$ echo "hello" > index.html

저장소

  • 이미지가 보관되는 곳(registry,repository)
  • 불특정 다수가 접근하여 이미지를 사용할 수 있는 pubilc registry
rapa@rapa:~$ docker search python

이라고 하면 도커 허브에 연결하여 퍼블릭 저장소에 보관된 공개된 모든 이미지를 검색/pull 할 수 있다. 
첫번째 검색 결과는 항상 공식 이미지이다.
공식 이미지는 별도의 계정 정보가 보이지 않는다.
python 하지만 public registry에 공개된 이미지는 id/python과 같이 출력된다.
예) yangseunghyun/python
  • 특정 사용자/그룹만 접근하여 이미지를 사용할 수 있는 private registry
1. 도커 허브에 repository를 만들때 private으로 만들고 접속 허용하고자 하는 id를 지정한다.
2. aws,gcp,azure와 같이 vpc환경에서 작업하는 경우에도 사설 저장소를 운영할 수 있다.
3. 우리 회사 내부나 우리 강의장 별도의 서버를 하나 준비하고 헤당 서버에 registry라는 이미지를 이용하여 사설 저장소를 운영할 수 있는 컨테이너를 생성한다.
  • 나 혼자만 접속할 수 있는 local registry
내 컴퓨터 자체에 이미지를 보관할 수 있는 공간이 있는데 여기를 로컬 저장소라고 하며 컨테이너 생성시에는 1차적으로 이 로컬 저장소에서 이미지를 검색하게 된다.
(만약 없다면 도커 허브로 연결한다.)

컨테이너 명령

컨테이너 생성

- docker container run (생성/시작)
- docker container create (생성)

컨테이너 삭제

- docker container stop + docker container rm
- docker container rm -f
- docker container rm -f $(docker container ls --all -q)
-> 모든 컨테이너 삭제

생성된 컨테이너에 연결하기

- docker container attach

생성된 컨테이너에 명령 전달하기

- docker container exec [컨테이너 이름] 필요한 명령어

이미지 pull

- docker pull httpd
-> 도컨에 제공되는 공식 이미지 중 최신 이미지를 pull
- docker pull centos:7
-> 도커 허브 공식 centos 이미지 중 7버전 -> 로컬

컨테이너 리스트

- docker container ls --all

이미지 리스트

- docker container ls
- docker container ls --all -q
-> id 만 뽑아서 보여준다

이미지 상세 정보 확인

rapa@rapa:~$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        latest    b692a91e4e15   2 weeks ago     142MB
rapa@rapa:~$ docker image inspect b692a91e4e15 

nginx 데몬을 시작시켜라
해당 이미지를 이용하여 컨테이너로 배포하면 처음 시작되는 명령어

entrypoint - cmd와 비슷하게 처음 컨테이너가 시작되면 동작시키는 명령어

Layer - 도커의 이미지를 처음 만든 이미지를 기준으로 추가되는 내용을 레이어 형태로 얹게 된다.
최초 이미지를 base로 하여 추가되는 내용만 저장된다.

도커 이미지 만드는 방법

    1. 동작중인 컨테이너를 commit하여 이미지로 만든다
    1. Dockerfile 을 이용하여 베이스이미지 지정, 추가 패키지 선택, 컨테이너로 동작시 실행할 명령어등을 지정한 뒤 이를 build 하면 로컬 저장소에 이미지가 생성된다.(**)

도커 이미지 허브에 올리기

rapa@rapa:~$ docker image tag nginx:latest gnon5367/mynginx:blue
rapa@rapa:~$ docker image tag nginx:latest gnon5367/mynginx:green
rapa@rapa:~$ docker image ls

rapa@rapa:~$ docker push gnon5367/mynginx:green
rapa@rapa:~$ docker push gnon5367/mynginx:blue

  • 업로드 확인

docker container run 옵션들

  • -i 대화식 모드 열기
  • -t 단말 디바이스 제공(마치 ssh로 연결하는 것) 일반적으로 it 옵션은 함께 사용하는 경우가 많다.
docker container run -it
  • -d 생성된 컨테이너를 백그라운드에서 동작시킨다. 데이터베이스나 웹서버와 같이 생성된 컨테이너로 관리자가 즉시 진입할 필요가 없는 경우에 많이 사용한다.
docker container run -d --name httpd80 -p 8080:80 -v /home/rapa:/usr/local/apache2/htdocs httpd
  • --name 생성된 컨테이너는 기본적으로 id를 부여받고 이중 12자리를 이용하여 관리할 수 있다. 하지만 간단히 이름을 이용하여 관리하고자 하는 경우에는 --name을 이용하여 컨테이너의 이름을 부여할 수 있다. 단, rename을 이용하여 나중에 변경할 수도 있다.
    단. 동시에 다수의 컨테이너(동일한 기능을 수행하는)를 생성하는 경우에는 이름을 지정하는것이 불필요한 작업이다. 만약 이름을 부여하지 않으면 자동으로 임의의 이름을 부여하게 된다.
  • --hostname 컨테이너 내에서 사용하는 컨테이너의 호스트 이름
docker container run -it --name centos01 --hostname centos1 centos:7 /bin/bash
  • --rm 삭제
  • --env 컨테이너 내에서 사용할 시스템 환경 변수를 지정할 수 있다.
  • -v 볼륨 마운트
docker container run -d --name httpd80 -p 8080:80 -v /home/rapa:/usr/local/apache2/htdocs httpd
host      : 컨테이너
-> 두가지 방식으로 사용할 수 있다.
1. 호스트의 특정 디렉토리와 컨테이너의 특정 디렉토리를 마운트 할 때
2. 별도의 볼륨을 만들어서 연결하는 방식으로도 사용된다.

일반적으로 둘을 구분할때 아래와 같이 작성한다.
1. /home/rapa:/home/root
2. myvolume:/root

위의 볼륨은 클라우드에서 매우 중요하다. PV, PVC@kubernetes

  • -p 호스트의 특정 포트와 컨테이너의 특정 포트를 매핑할때 사용한다. -p 컨테이너에서 노출한 특정 포트를 호스트의 임의의 포트와 자동 매핑시켜 준다.
  • --link 두개 이상의 컨테이너를 연결하는 방법으로 이름을 이용한 링킹이 가능하다. 주로 외부에 노출되지 않은 데이터베이스와 같은 경우 웹컨테이너와 연결할 때 사용한다.

데이터베이스를 사용하는 방법

  1. 서버를 준비한다. -> OS를 설치한다 -> mysql을 설치한다(bare metal)
  2. aws에 가서 RDS 서비스를 신청한다 (OS는 Amazonlinux로 제공된다. 단, OS로 접근은 되지 않는다.)
  • 애플리케이션의 설치 과정 없이 신청 즉시 해당 애플리케이션으로 접속할 수 있는 서비스 -> 완전 관리형
  1. 도커를 이용하여 신청한다. 즉시 제공된다. 만약 모든 개발자들이 동일 버전의 개발 환경이 필요하다면 컨테이너를 이용한 개발이 유용하다. (버전이 똑같기 때문에)

mysql 배포하기

rapa@rapa:~$ docker pull mysql:5.7
rapa@rapa:~$ sudo apt -y install mysql-common
rapa@rapa:~$ sudo apt -y install mysql-client-core-8.0 

Quiz1.

  • root 패스워드 = test123
  • 기본 DB = testdb
  • 외부에 공개할 포트 = 기본적으로 컨테이너는 3306/tcp를 이용하여 외부에 노출된다. 우리는 호스트의 33061번 포트를 통해 해당 DB로 접근할 수 있어야 한다. 컨테이너의 이름은 mydb로 한다.
    우분투에서는 sudo apt -y install mysql-client-core-8.0으로 설치한뒤, 접속해 본다.
rapa@rapa:~$ docker container run -d --name mydb -e MYSQL_ROOT_PASSWORD=test123 -e MYSQL_DATABASE=testdb -p 33061:3306 mysql:5.7
rapa@rapa:~$ docker container run -it -d --name mydb -e MYSQL_ROOT_PASSWORD=test123 -e MYSQL_DATABASE=testdb -p 33061:3306 -v /home/rapa/mydb:/var/lib/mysql --restart=always mysql:5.7
rapa@rapa:~$ mysql testdb -u root -P 33061 -h 127.0.0.1 -p
  • --restart=always 를 사용하면 도커 데몬이 재시작될때 자동으로 해당 컨테이너를 실행시킨다. 만약 옵션이 없다면 컨테이너는 종료된 상태가 된다.

[워드프레스 구성하기]

rapa@rapa:~$ docker container run -d --name wpdb -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress --restart=always mysql:5.7
rapa@rapa:~$ docker container rm -f wordpress
rapa@rapa:~$ docker container run -d -e WORDPRESS_DB_PASSWORD=password -e WORDPRESS_DB_NAME=wordpress -e WORDPRESS_DB_USER=root --name wordpress --link wpdb:mysql -p 80:80 wordpress

0개의 댓글