* 시간될때 엑셀 공부해놓기
1. 가상화의 개념
- IaaS(Infra Structure as a Service) : 환경/시설을 제공 (AWS)
- PaaS(Platform as a Service) : 개발 환경을 제공 (도커), google app engine
- SaaS(Software as a Service) : (salesforce, SAP)
가상화의 장점
1. 비용절감 -> 물리적인 서버 3대를 이용하여 운영하던 애플리케이션을 1대의 서버에서 논리적으로 3대의 서버를 생성하고 여기에 애플리케이션을 배포할 수 있게 됨으로써 비용을 절감.
2. 무중단 서비스 가능
-> Live Migration
3. 지역간 이동 가능
= 가용성 증대 (가상화가 클라우드에 도입될 경우 가용성은 99.9999%)
VMware Workstation : 개인용( type 2 )
- 하이퍼바이저가 Host OS 상에 설치됨
VMware ESXi : 기업용( type 1 )
- ESXi(OS) -> VMKernel(하이퍼바이저)
- Linux -> KVM(하이퍼바이저)
- 하이퍼바이저가 커널상에 설치됨
구조 : 하이퍼바이저를 이용하면 물리자원 - 하이퍼바이저 - [vResource - OS - App](VM)
BareMetal : 하드웨어 위에 하이퍼바이저가 바로 배치, 그 위에 Guest OS 그 위에 Application == VM
Host Based : HostOS위에 VMWare와 같은 애플리케이션 위에 VM이 올라가는 구조이다.
가장큰 단점은 너무 무겁다. VM이 가상자원에 접근하려면 host kernel에 반드시 접근해야하기 허락과 접근과정이 일어나기 때문에 무거워진다. VM에서 동작하는 애플리케이션의 성능은 물리자원들의 성능은 평균적으로 30% 정도 성능저하.
컨테이너 기반의 가상화: 컨테이너 내에 애플리케이션을 배치하고 컨테이너 형태 자체를 배포하여 각 애플리케이션에 대한 격리도를 높였다, 이러한 환경을 컨테이너(Container)라고 부르며 응용프로그램을 그 안에서 독립적으로 실행할 수 있다. 기존 가상화에 비해 보다 더 가벼운 격리도를 보일 수 있다.
LXC 컨테이너는 격리된 환경을 제공한다. 하지만 컨테이너라는 단어의 또 다른 이면인 이동성을 충족하기에는 부족하다.
이를 위해 도커가 탄생하였다. 도커는 컨테이너의 이동성과 패키징을 지원하기 위해 개발된 기술이다
1. 리눅스 컨테이너(LXC) -> 컨테이너이동 -> Docker
- 네임스페이스 격리(Namespace Isolation) = 프로세스 격리
네임스페이스 격리 또는 네임스페이스는 프로세스 상에서 사용하는 특정 자원에 대한 가시성을 제한하기 위해 리눅스 커널에 구현된 기능이다. 별도의 네임스페이스를 사용하는 프로세스 간에는 서로의 자원을 볼 수 없도록 하는 것이다.
- 컨트롤 그룹(Control-group, Cgroup) = 자원 격리
네임스페이스를 사용하는 아이디어는 시스템 자원에 대해 프로세스마다 다른 가시성을 제공 하는 것이다. 이를 통해 어느 정도의 격리는 제공하지만 그 자원들을 사용하는 것을 막지는 못한다.
Cgroup은 이러한 부분 또는 자원의 할당을 담당한다. Cgroup은 CPU, 메모리, 디스크I/O 등과 같은 자원을 제어하며 우선순위를 조정할 수 있고 자원의 사용을 제한할 수도 있다. 특정 프로세스에 대해 더 높은 수준의 CPU,메모리 할당을 할 수도 있으며 특정 프로세스가 사용하는 자원의 양을 모니터링 할 수도 있다.
이 두가지를 해서 도커에게 넘긴다.
2. 도커 컨테이너 -> 컨테이너 오케스트레이션(쿠버네티스)
컨테이너도 두가지 종류가 존재
1. App - mariadb, httpd, nginx, jenkins, node.js, python를 자신이 원하는 버전으로 설정 가능
2. OS - App 위치에 os를 집어넣는 방식 -> CentOS, Fedora 등등... -> 커널은 호스트 OS 커널을 사용함.
* 일반적으로 각 컨테이너에서 한 가지 작업을 잘 수행하는 것이 좋음.
* 기본적으로 LXC 기술을 사용하기 때문에 모든 소프트웨어는 Linux 환경위에서 돌아감
3. 쿠버네티스
쿠버네티스(구글 주도로 작성됨)는 애플리케이션 배포를 위해 runtime(도커)이 필요함. 명령을 받아 작업하게끔 만드는 것. 사실상 컨테이너 오케스트레이션의 표준이다.
2. 인프라 기술의 이해
3. 실습환경 구성
[ 도커설치(ubuntu) ]
user1에게 권한 부여
usermod -aG sudo user1
vi /etc/sudoers
sudo apt update
sudo apt install -y 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 focal stable"
apt-cache policy docker-ce
sudo apt install -y docker-ce
sudo systemctl status docker
sudo systemctl enable docker
sudo apt-get install -y ssh
sudo systemctl start docker
sudo systemctl enable docker
sudo systemctl status docker
docker -v
user1을 docker 그룹에 넣어서 사용하기
sudo usermod -aG docker user1
groups
su user1
groups user1
[ 도커설치(centos) ]
sudo yum -y install nfs-utils
sudo yum -y install yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum -y install docker-ce
4. Docker 기본 명령어의 사용
[ 도커 라이프사이클 ]
[ 도커 이미지 ]
1. 도커는 컨테이너 안에 App을 넣는다. 이 안에 들어갈 수 있는건 App과 OS이다.
이 컨테이너를 만들기 위해서는 BaseImage가 필요하다.
로컬저장소(private repo) : local PC에 이미지를 저장하는 것을 말함. public은 접근제한 없이 누구든지 다운받아 사용 -> docker hub
원격저장소(public repo) : 이걸 가져오기 위한 docker hub, 원격저장소가 따로 존재. private는 접근제한이 있다 -> docker hub, aws, gcp, azure, 로컬환경(회사내)
명령어
### login ####################################################################
docker login #필수 -> 이거해야 이미지 받아옴
sudo cat /home/user1/.docker/config.json # docker hub 인증 토큰이 있음
### search ####################################################################
docker search centos:7
# 사용자 지정 + 도커 공식의 tag가 7인 이미지들을 볼 수 있음
# tag는 버전을 의미, tag가 없다면 centos중에서 최신을 찾아서 가져옴
docker search centos
# 도커 공식 이미지를 찾을 수 있음
### pull ####################################################################
docker pull centos:7
docker pull centos
# 이미지 가져오기
### image ####################################################################
docker image ls
docker image ls -a # 전체 이미지 봄
docker image ls -qa # 전체 ID로만 봄
# 다운받은 이미지 확인
### container ####################################################################
## run ##
docker container run --it --name centos01 --hostname centos1 centos:7 /bin/bash
# 도커 컨테이너 생성
# -it : 터미널 안에서 입력가능
# --name : 컨테이너 이름 지정
# --hostname : 컨테이너 내에서의 이름 지정
# centos:7 : 사용하는 이미지 -> 없으면 docker hub에서 찾아옴
# /bin/bash : 사용하는 커널
# ctrl + p -> ctrl + q = docker 빠져나오기
# --restart=always
docker container run -d -p 80001:80 httpd
# -d : background 실행
# -p : 포트 포워딩
docker container run -it -v /home/user1/nginxhtml:/root \
-w /testdir \
-e WORKDIR=/testdir centos:7 /bin/bash
# -w : working directory, 처음 컨테이너 접속시 해당 디렉토리 사용
# -e : 환경변수 선언
## attach ##
docker container attach <컨테이너명>
## create ##
docker container create ~~
## start ##
docker container start <컨테이너명>
docker container restart <컨테이너명>
## stop ##
docker container stop <컨테이너명>
## ls ##
docker container ls # 컨테이너 확인
docker container ls -a # 전체 컨테이너 확인
docker container ls -aq #전체 컨테이너 ID만 확인
## rm ##
docker container rm -f ([컨테이너 이미지] or [컨테이너 ID])
# 도커 컨테이너 강제로 지우기
docker container rm -f $(docker container ls -aq)
# 도커 컨테이너 전체다 지우기
### volume ####################################################################
## NFS방식 마운트 ##
docker container run -d -p 8888:80 -v /home/user1/html:/usr/share/nginx/html nginx
# -v는 볼륨을 의미
# 내 /home/user1/html 폴더를
# 컨테이너 /usr/share/nginx/html에 마운트하겠다.
# nginx이미지 디렉토리 /usr/share/nginx/html/index.html
# httpd이미지 디렉토리 /usr/local/apache2/htdocs
## iSCSI 방식 마운트 ##
docker volume create --name testvol
# 볼륨 만들기
docker volume ls
# 볼륨 갯수
docker container run -it -v testvol:/root centos:7 /bin/bash
# 컨테이너 만들기
### prune ####################################################################
docker container prune # 멈춰 있는 컨테이너들 삭제
docker volume prune #멈춰 있고 사용안되는 볼륨 삭제
docker system prune # 멈춰 있는 컨테이너/연결안된 네트워크/사용안되는 이미지, 캐시 삭제
docker system prune -af # 동작중인 컨테이너를 제외하고 삭제
### image ####################################################################
docker image ls
docker image tag centos:7 tonyhan18/mycentos:1.0
# 도커 이미지를 가져다가 우리만의 이미지를 만듬
# 수정 안하고 만들면 같은 이미지가 만들어짐
### push ####################################################################
docker push tonyhan18/centos:1.0
# 주의할점은 올릴때 repository와 같은 이름의 파일만 받아주고
#이름이 다르면 public 공간을 새로 만들어서 업로드해준다.
### monioring ####################################################################
docker container stats <컨테이너이름>
docker container top <컨테이너이름>
sudo apt-get install htop # 비슷하게 그냥 centos에서 쓰는것도 있음
### others ####################################################################
docker container exec nginx01 hostname
# 컨테이너에 명령 전달
### cgroup, 물리자원할당 ####################################################################
docker run -d --memory="200m" --memory-swap=""
# --memory="1g"
# 특정 CPU만 쓰라고 지정할 수 있다.
docker container run -d --name cpuset --cpuset-cpus=2 nginx
# 직관적으로 CPU의 개수를 정해준다.
docker container run -d --name cpustest --cpus=0.5 nginx
도커 시작 실패시 재도전하는 플래그도 존재
docker container inspect <컨테이너 이름>
# 컨테이너 정보 확인
docker container inspect --format='{{.LogPath}}' <이미지ID>
docker container inspect --format='{{.NetworkSettings.Networks.bridge.IPAddress}}' 5adde526daf2
# 파일이 JSON이라서 --format으로 자세하게 볼 수 있음
실제 OS 입장에서 컨테이너는 하나의 애플리케이션이므로 각 애플리케이션(컨테이너)이 실행되면 애플리케이션 별로 1개의 PID(Process ID)가 할당됨.
우분트 OS 위에 컨테이너들을 연결하기 위한 기본네트워크가 있는데 그게 docker0(172.17.0.1). 컨테이너들이 docker0를 DG로 생각해서 연결한다. 그리고 docker0는 NAT로 동작.
docker network ls
bridge : 실제 ubuntu의 주소와 동일한 대역의 주소를 컨테이너에 할당한다.
host : 일반 가상화에서는 지원되지 않는 옵션으로 호스트(ubuntu)의 IP 주소를 컨테이너에 할당하고 동일하게 사용하고자 하는 경유에 사용(거의 사용하지 않음)
none : 컨테이너에 NIC이 없는 상태 -> 네트워크 안쓰겠다.
overlay : 클러스터 환경에서 사용되는 드라이버이고 클러스터링 되어 있는 호스트끼리 동일 사설 네트워크를 사용할 수 있음. 클러스터를 묶고 네트워크를 만들면 자동으로 overlay가 만들어진다.
실재로 이미지를 만들면 원본 이미지 + 바뀐 부분이 생기고 docker hub에서는 이 바뀐부분만을 업로드 받는다.
그외에도 엄청 많은데... 나중에 필요하면 쓰자
실습1 : wordpress + mysql
### link ############################################################
# link 옵션 : 같은 호스트 내에 컨테이너 간 연결을 할 떄 사용
# /etc/hosts에 등록해놓고 ip가 바뀌면 자동으로 변경해주어서 가능
docker container run -d --name wordpressdb \
-e MYSQL_ROOT_PASSWORD=test123 -e MYSQL_DATABASE=wordpress mysql:5.7
# mysql 이미지 컨테이너 만들기
docker container run -d --name wordpress \
--link wordpressdb:mysql -p 8881:80 wordpress
# --link <컨테이너 이름>:<별칭>
실습2 : CAdvisor
docker container run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
-p 8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest
호스트의 특정 디렉토리(도커와 관련된)를 캐드바이저의 특정 디렉토리와 마운트하고 해당 디렉토리에 있는 도커관련 정보를 GUI를 통해 웹에서 확인할 수 있도록 도와준다.
- /var/run : 우분투(진짜 서버)에서 도커를 제어하기 위한 소켓이 포함되어 있다.
- /sys : 도커 컨테이너들의 cgroup 정보가 포함되어 있음.
- /var/lib/docker : 도커 컨테이너와 이미지 등의 정보가 파일 형태로 존재한다.
cd /sys/fs/cgroup/cpu/docker
로 가보면 돌아가는 컨테이너 ID를 확인할 수 있다.
실재 폴더 안에는 cpu정보들을 확인할 수 있다.
실습3 : mysql 깔린 centos 이미지 만들기
FROM centos:7
ENV MARIADB_CERSION=10.4
RUN yum install -y epel-release && \
yum install -y mariadb-server
VOLUME /var/lib/mysql
ENV MYSQL_RANDOM_ROOT_PASSWORD=test123 \
MYSQL_DATABASE=testdb
VOLUME /var/lib/mysql
RUN yum -y install git curl wget httpd
COPY index.html /var/www/html/index.html
RUN curl https://www.nginx.com > /var/www/html/nginx.html
ADD a.tar /var/www/html
VOLUME /etc/httpd /var/log/httpd
EXPOSE 80 3306
CMD httpd -D FOREGROUND
5. Dockerfile의 작성
[ 도커 이미지 만들기(Dockerfile) ]
자신만의 이미지를 만드는 대표적인 방법 = Dockerfile
# FROM, RUN, COPY, CMD
FROM ubuntu:18.04
RUN apt-get update -y
RUN apt-get install nginx -y
COPY index.html /var/www/html/index.html
CMD nginx -g 'daemon off;' # daemon off를 하지 않겠다
# CentOS version, EXPOSE
FROM centos:7
RUN yum update -y
RUN yum install httpd -y
COPY index.html /var/www/html/index.html
EXPOSE 80 8080
CMD httpd -D FOREGROUND
# ONBUILD ADD
FROM centos:7
RUN yum -y install httpd
EXPOSE 80
ONBUILD ADD global.tar /var/www/html
CMD httpd -D FOREGROUND
- FROM(필) : 베이스 이미지 지정 -> 로컬 저장소를 먼저 확인후 없으면 remote에서 가져온다
예전에는 MAINTAINER을 이용해서 이미지 제작에 대한 설명 적음. 현재는 LABEL을 이용하여 이를 대체함
- LABEL(선택) 은 주석처럼 사용되지만 이미지 안에 들어는 감
- RUN : 이미지내에서 실행할 명령어들, RUN은 Dockerfile 내에서 여러번 사용가능. 베이스 이미지에 대해 애플리케이션/미들웨어 등을 설치하거나 환경 구축을 위한 명령을 실행.
- COPY는 로컬에 있는 특정 파일, 디렉토리를 이미지로 복사함
(ADD는 COPY와 비슷하다. COPY의 모든 기능을 포함한다. 원격지에 있는 파일을 붙여넣기도 가능)
- ADD는 패키지의 내용이 풀리면서 붙여넣기 된다.
- ONBUILD : 그 다음 빌드에서 실행할 명령을 이미지 안에 설정하기 위한 명령. ONBUILD는 팀장이 베이스이미지를 만들고 이를 배포, 개발팀은 팀장이 만든 베이스 이미지를 가져다가 새로운 이미지로 만들떄 동작하는 기능이다.
- EXPOSE : 특정 포트에서 서비스 제공하기 위해 열어놓기
- CMD 와 RUN은 둘다 대부분 명령실행이 주가 되지만 RUN은 이미지에서 실행한다.
CMD는 이미지가 아니라 컨테이너로 배포될 때 실행하는 명령어다.
CMD는 RUN과 달리 Dockerfile 내에서 1번만 사용가능 -> 여러개의 명령어를 사용하기 위해서는 쉘을 이용하면된다. -> 쉘을 복붙하고 실행시키면 된다.
[ CMD /bin/bash install.sh ]
- 데몬실행(ENTRYPOINT) :docker container run 명령을 실행했을 때 실행된다.
docker build -t mynginx:1.0 .
#현재 위치에 있는 도커파일로 만들겠다
# t(tag)는 이미지 이름
# :1.0 버전명
# . 도커 파일 위치
# -f 도커 파일 위치 지정
컨테이너의 헬스 체크(HEALTHCHECK)
컨테이너 안의 프로세스가 정상적으로 작동하고 있는지를 체크하고 싶을 때에 사용한다. 일반적인 명령의 구문은 다음과 같다
실행을 했음에도 이미지를 잘못만들었다면 그냥 죽는다.
그래서 살아있는지 확인하는 것이다.
환경변수 설정(ENV) : 많이쓴다
Dockerfile 안에서 환경변수를 설정하고 싶을 때는 ENV 명령을 사용하며 다음 두 서식 중 하나로 기술할 수 있다.
모든 이미지의 환경변수 값이 같아진다.
작업디렉토리 지정(WORKDIR)
Dockerfile에서 정의한 명령을 실행하기 위한 작업용 디렉토리를 지정하고자 할 때 사용하 며 다음과 같은 명령을 실행하기 위하여 지정이 가능하다.
WORKDIR /test
RUN touch a.txt
RUN touch b.txt
RUN touch c.txt
#이 작업들은 test 폴더 아래에서 이루어진다.
RUN cd /etc && \ # 작업 디렉토리가 이동하지는 않는다.
touch d.txt # 얘는 test에서 이루어진다.
WORKDIR /etc
# 이후의 모든 작업은 /etc 아래에서 진행됨
사용자 지정(USER)
이미지 실행이나 Dockerfile 의 다음과 같은 명령을 실행하기 위한 사용자를 지정할 때 사 용한다
USER test 아래부터는 test 계정이 작업
라벨 지정(LABEL)
이미지에 버전 정보나 작성자 정보, 코멘트 등과 같은 정보를 제공할 때에는 LABEL 명령을 사용한다.
예전 MAINTAINER이다.
포트 설정(EXPOSE)
컨테이너의 공개 포트번호 지정할 때 사용 예를 들어 8080 포트를 공개하고자 한다면 다음과 같이 작성한다.
- EXPOSE : 방화벽에서 포트를 여는 역활
Dockerfile 내에서의 변수 설정(ARG)
Dockerfile 안에서 사용할 변수를 정의할 때에는 ARG 명령을 사용한다. ARG 명령을 사용하 면 변수의 값에 따라 생성되는 이미지의 내용을 바꿀 수 있다. ENV 와 달리 이 변수는 Dockerfile 안에서만 사용할 수 있다.
ENV는 컨테이너에서 사용하는 변수를 의미한다면
ARG는 도커파일 안에서 사용할 변수를 정의한다.
기본 쉘 지정(SHELL)
쉘 형식으로 명령을 실행할 때 기본쉘을 설정하려면 SHELL을 사용한다. SHELL을 지정하지 않으면 리눅스는 [“/bin/sh", "-c"], 윈도우는 [”cmd", "/S", "/C"] 가 기본이 된다
파일 및 디렉토리 추가(ADD)
이미지에 호스트상의 파일이나 디렉토리를 추가할 때에는 ADD 명령을 사용한다. ADD 명령은 다음과 같은 형식으로 작성이 가능하다. 원격지에 있는 파일도 붙여넣을 수 있고/tar 파일 풀면서 붙여넣을 수 있고/패턴도 사용가능하다
볼륨 마운트(VOLUME)
- 컨테이너에서 볼륨이 필요한 이유
1. 컨테이너는 휘발성이다. 컨테이너 내에서 새로운 파일을 생성했는데 컨테이너가 삭제되었다면 생성된 파일은 함께 사라진다. 즉, 데이터를 영구적으로 보관할 수 없다.
-> 이를 위해 로컬(우분투)에 볼륨을 생성하고 해당 볼륨을 컨테이너에 연결해준다. 해당 볼륨에 데이터가 작성된다면 컨테이너가 삭제되더라도 데이터는 영구적으로 보관할 수 있게 된다.
이미지에 볼륨을 할당하고자 할 때 사용한다. VOLUME ["/마운트포인트“] 와 같은 형식으로 구성하면 호스트나 다른 컨테이너에서 마운트 를 수행한다. 구성하는 형식은 다음과 같다.
∎ VOLUME ["/var/log/"]
∎ VOLUME /var/log
∎ VOLUME /var/log /var/db
컨테이너는 영구 데이터를 저장하는 데는 적합하지 않다. 따라서 영구 저장이 필요한 경우 에는 외부 스토리지에 저장하는 것을 추천한다. 영구데이터는 Docker의 호스트 머신상의 볼륨에 마운트하거나 공유 스토리지를 볼륨으로 마운트 하는 것이 가능하다
볼륨 마운트하기
FROM centos:7
RUN yum -y update
RUN yum -y install git curl wget httpd
COPY index.html /var/www/html/index.html
RUN curl https://www.nginx.com > /var/www/html/nginx.html
ADD a.tar /var/www/html
VOLUME /etc/httpd /var/log/httpd
EXPOSE 80 3306
CMD httpd -D FOREGROUND
httpd를 설치하면 /etc/httpd 디렉토리를 로컬의 볼륨과 연결 가능하다.
/var/log/httpd 는 컨테이너 아래 httpd 아래의 파일(access_log, error_log)들을 내 컴퓨터의 볼륨과 연결할 수 있다.
[ 도커 레지스트리를 이용한 사설 저장소 구축 ]
지금까지 이미지를 저장한곳은 local 저장소였다. 지금까지 실습환경은 ubuntu의 docker을 이용해서 docker hub의 base 이미지들을 받아와 패키지를 설치하고 컨테이너배포시 실행할것들을 패키지로 묶으면 우리가 원하는 이미지가 만들어진다.
이건 local에만 저장되어있고 docker hub에 올리기 위해서는 docker tag를 이용해서 이름을 바꾸어야만 했다. 이렇게 만든것을 push하게 되면 docker hub에 올라가게 된다.
그런데 이게 어떻게 자동으로 되는 것일까?
- docker login하면 결국에 docker로 로그인하게 된다. 기본적으로 docker login은 docker hub에 로그인 하도록 설정되어 있다.
docker login
하면 자동으로 인증한다. 그리고 파일은 /home/user1/.docker/config.json안에 들어가 있다.
그래서 도커 이미지를 저장할 수 있는 곳
1. local registry (내 컴퓨터)
2. public registry (docker-hub)
3. private registry
- 인터넷 접속을 이용한 사설 저장소 : 설치가 필요하지 않다.
1. docker hub 사설 저장소
2. aws, gcp, azure 사설 저장소
- 폐쇄형 (인터넷 연결 없어도 사용가능)
1. private registry : 설치형
[ 사설 저장소 구축하기 ]
docker image pull registry
docker container -d -p 5000:5000 --name registry1 registry
위와같이 작성해주면 사설 저장소 컨테이너가 만들어진다. 이곳에 이미지를 넣는것이다.
이미지를 사설 저장소, 공개 저장소 등에 push 하기 위해서는 이미지 이름에 일정한 규칙을 준수해야 한다. 일반적으로
ID/IMAGENAME:TAG 로 이미지 이름을 만들어놓자
사설 저장소
레지스트리주소:포트번호/이미지이름:태그
사설 저장소 공간 확인
## 직접 레지스트리 조절
docker run -it -p 8080:8080 --name registry-web --link registry \
--restart=always \
-e REGISTRY_URL=http://registry:5000/v2 \
-e REGISTRY_NAME=localhost:5000 \
hyper/docker-registry-web
## 백그라운드
docker run -d -p 8080:8080 --name registry-web --link registry \
--restart=always \
-e REGISTRY_URL=http://registry:5000/v2 \
-e REGISTRY_NAME=localhost:5000 \
hyper/docker-registry-web
<본인IP>:8080
으로 접속하면 저장소를 확인할 수 있다.
이미지 삽입/다운
docker image tag centos:7 localhost:5000/test:1.0
docker image push localhost:5000/test:1.0
docker image pull localhost:5000/test:1.0
위의 방식으로 이미지를 넣고 다운받을 수 있다.
저장소 인증
사설저장소를 만들면 각 서버가 이미지를 땡겨온다. 이때 그냥 이미지를 땡기지 말고 인증서를 미리 서버별로 발급해주어서 이미지를 받아오게함으로 보안성을 높일 수 있다.
그래서 나중에 다른 서버에서 이미지를 받아오기 위해서 insecure-registry 설정을 해주어야 한다.
[ ubuntu ]
인증을 거치지 않고 pull, push가 되도록 하고 싶다면 다음과 같이 진행한다.
systemctl stop docker
sudo vi /etc/default/docker
systemctl restart docker
위와같이 DOCKER_OPTS를 설정해주어서 인증서 없이도 접근가능하도록 만들면 된다.
위와같이 작성해주면 211.183.3.254라는 저장소 주소로 인증없이 접속. 이렇게 하면 인증없이 떨어진 주소에 이미지를 올릴 수 있게 된다.
외부에 있는 곳에 인증을 거치어서 들어가고 싶으면 아래의 방법을 쓰자
docker login 1.1.1.1 # 사설 저장소가 1.1.1.1에 구축되어 있고 ID/PW로 들어간다.
Username: test
Password:
게 되었다는 의미는 실재 로그인 되었다는 것이 아닌 우리의 ID/PW를 저장했다는 의미이다.
정보 두개가 보이는데
1번은 우리가 등록한거다.(1.1.1.1) -> 인증서버로 가면 거기에 username/pw가 있는 경우이다.
2번의 주소는 docker hub를 등록한 것이다.
3번째 방법은 ID/PW 없이 인증서만으로 로그인하는 방법이다.
[ centos ]
[Docker] 'insecure-registry' 설정 :: 재밌다 개발 2 (tistory.com)
[Docker] 'insecure-registry' 설정
문제 상황 최근 내가 진행하고 있는 프로젝트 중 하나는, 데이터 분석 및 추후 머신러닝 적용의 가능성으로 인해 파이썬으로 작성되고 있다. 사실 파이썬은 비교적 자잘하고 귀찮은, 비교적 중
asuraiv.tistory.com
/etc/docker/daemon.json 파일을 만들어서 이미지를 쉽게 올렸다가 내릴 수 있게 만들어야 한다.
위의 정보를 manager와 worker 모두 가지고 있어야 한다.
6. Docker Compose
[ docker-compose ]
단, 한대의 서버에서 스케일 조정이 된다는 점이 단점
다만 docker-compose는 단독으로 사용되지 않는다. 한 PC 내에서만 이걸 써야하기 때문에 지금과 같이 서버가 여러대인 환경에 어울리지 않는다. 사용자는 서버 한대의 여러 포트로 접속하지 않기에 꼭 유용하다고 볼 수 있는 기술이 아니다.
=> 이것보다는 서버를 3대 만들고 한대에서 서버를 배포하고 이와 유사한 서비스를 다른 서버에도 만든다.
이 서버들을 LB를 통해 나누어서 들어가면 분산처리가 가능해진다. 이 환경들을 cluster로 묶어야 하는데 이 기술을 swarm이라고 부름. 도커 컴포즈는 디렉토리 내에서 모든 작업이 이루어 져야 한다. 디렉토리 위치가 달라지면 yml 파일을 못 읽는다.
모든 컨테이너는 동일 네트워크에서 연결되어야 한다.(overlay 네트워크) 물리적으로 불가능하지만 논리적으로 이를 연결할 수 있어야 한다. 또한 각 서버에 위치한 물리자원들(CPU, RAM)을 통합관리할 수 있어야 한다. 이를 위해서는 "cluster"와 클러스터 환경에서 컨테이너를 오케스트레이션 할 수 있어야 한다. 그래서 서버별로 ip를 나누어서 배포하는 방법이다.
curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
먼저 docker-compose를 받아와야 한다.
docker-compose.yml 의 개요
앞서 언급하였듯이 도커 컴포즈는 ‘docker-compose.yml' 파일에 시스템 내에서 가동하는 여러 컨테이너들의 구성을 모아서 정의하게 된다. 이 정의 파일은 YAML 형식으로 기술한다.
YAML
YAML 은 구조화된 데이터를 표현하기 위한 데이터 포맷이다. YAML 은 Python 과 같이 들여쓰기로 데이터의 계층 구조를 나타낸다. 들여쓰기는 탭이 아니라 스페이스를 사용하며 누가 써도 읽기 쉽기 때문에 설정 파일등에 많이 이용된다. YAML에서는 데이터의 맨 앞에 ‘-’를 붙이면 배열을 나타낼 수 있으며 ‘-’ 다음에 는 반드시 스페이스를 넣어야 한다
컴포즈 파일은
- 서비스
- 네트워크
- 볼륨을 정의한다.
- version : 버전별로 적용되는게 다 달라서 고정해야함. 안 적으로 1.0으로 시작됨
- webserver : container와 같은 역활을 한다.
- ports : 자신의 포트와 호스트의 포트를 매핑한다. (-p 8001:80)
- networks : 이름별로 별도의 네트워크를 만들어서 연결해서 사용
- expose : 외부에 공개되지 않았다. 노출만 된것이다. 컨테이너 자체에 오픈된 포트를 의미하며 이 포트가 외부에서 연결되는 것은 아니다. (EXPOSE 80 3306)
- volumes
/var/lib/mysql과 볼륨이 연결
현재 디렉토리 cache/를 /tmp/cache 에 연결
~/configs 와 /etc/configs/을 연결 (read only인데 잘 안쓴다)
- depends_on
서비스 의존관계 -> 일종의 시작 순서 결정. 시작순서를 결정한다는 것이지 앞 서비스가 실행되고 뒤가 실행되는게 아님
- compose 실행/종료
# docker-compose 가동
docker-compose up -d
# docker-compose 종료
docker-compose down # container는 없애고 볼륨은 남긴다.
# 배포된 컨테이너들만 확인 가능
docker-compose ps
# 스케일을 늘리어서 가동
docker-compose up --scale wordpress=3
# 서비스 명 wordpress에 해당하는 컨테이너만 스케일을 3으로 조정하여 확장할 수 있다.
실습1. mysql 과 wordpress를 이용한 웹 서비스 배포
- 패키지 설치
docker pull mysql:5.7
docker pull wordpress
vi docker-compose.yml
- compose 파일 정의하기
version: "3.3"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: test123
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
image: wordpress
volumes:
- wordpress_data:/var/www/html
ports:
- "8009-8012:80"
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
depends_on:
- db
# networks:
volumes:
db_data: {}
wordpress_data: {}
실습2. centos 컨테이너 + db 컨테이너(mysql; mariadb -> ROOT_PASSW)
FROM centos:7
RUN yum clean all
RUN yum -y update
RUN yum -y install httpd
RUN yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
RUN yum -y install epel-release yum-utils
RUN yum-config-manager --disable remi-php54
RUN yum-config-manager --enable remi-php74
RUN yum -y install php php-mysqlnd php-fpm php-cli php-gd php-mysql
RUN yum -y install php-mysql php-gd php-ldap php-odbc php-pear php-xml \
php-xmlrpc php-mbstring php-snmp php-soap curl curl-devel
ADD bbs.tar /var/www/html
RUN chmod 755 /var/www/html
RUN mkdir /var/www/html/bbs/files
WORKDIR /var/www/html/bbs
RUN chgrp apache files
RUN chmod 777 -R /var/www/html/bbs
EXPOSE 80
CMD httpd -D FOREGROUND
version: "3.3"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: test123
MYSQL_DATABASE: bbs
MYSQL_USER: bbs
MYSQL_PASSWORD: bbs
bbs:
image: bbs:1.0 # <--docker build -t bbs:1.0 .
volumes:
- bbs_data:/var/www/html/bbs
ports:
- "8001:80"
restart: always
depends_on:
- db
volumes:
db_data: {}
bbs_data: {}
7. Docker Swarm
[ Docker Swarm ]
다수의 호스트와 컨테이너를 효율적으로 관리할 수 있는 방법을 고려해야함.
- 이를 위한 첫 번째 대안이 바로 도커 스웜 (Docker Swarm)이다. 도커 스웜은 여러 도커 호스트를 클러스터로 묶어주는 컨테이너 오케 스트레이션 도구의 한 종류이다. 오케스트레이션 도구를 활용하면 어느 호스트에 어느 컨테이너를 배치할 것인지, 서로 다른 호스트에 위치한 컨테이너간 통신은 어떻게 조율해야 하 는지와 같은 수고를 덜 수 있으며, 호스트가 여러대로 나뉘어 있다고 하더라도 이를 신경쓰 지 않고 클러스터를 투명하게 다룰 수 있게 된다
이걸 yaml을 이용해서 관리하면 더 편할텐데 이를 docker stack이라고 부른다.
도커에서 클러스터링을 통한 컨테이너 오케스트레이션은 도커스웜/쿠버네티스 가 있는데
도커만을 사용하여 오케스트레이션 할 수 있는 도구는 두가지
- docker swarm classic
- docker swarm mode(우리가 지금 쓰는거) -> 기본 도커 설치 패키지에 포함되어 있음, 그냥 도커 스웜이라고 부름
* 스웜과 k8s(Kubernetes)의 가장큰 차이점은 runtime으로 쓰는게 다르다.
-> 스웜은 docker only
-> k8s는 docker + podman + cri-o + rocket...(일반 밴더들 포함해서 확장성이 높음)
- docker swarm classic
1. swarm classic은 위와같은 구조로 있을때 manager 옆에는 DB를 하나둔다
2. 각 worker에는 agent가 들어간다
3. agent는 manager의 (관리) 매니저와 통신을 위해 manager과 연결된다
4. 각 agent가 매니저로부터 업무지시 받으면 agent는 runtime에게 전달한다. 그럼 docker는 받은 업무를 처리
DB가 모든 노드 정보를 가지고 있어야하고 생존여부 체크도 해야함. 그래서 DB 내부에 분산코디네이터 존재
- docker swarm mode
기존 스웜 클래식이 분산코디네이터(클러스터 환경 정보 저장), 매니저(노드제어), 에이전트 (각 노드에 배치되어 런타임에게 업무 전달)가 나뉘어져 있었다면 스웜모드는 이를 모두 manager 내에 통합시켰다. 따라서, 매니저가 업무를 전달하면 이를 각 노드의 도커에게 직접 전달.
- role이 worker라고 적혀있다.
- label을 붙여서 seoul/busan 등등 붙여줄 수 있다.
지정된 곳에서만 컨테이너가 배포되도록 할 수 있다.
먼저 각 PC 별로 host들을 적어놓자
[ docker swarm 설치 ]
### manager ########################################################
docker swarm init --advertise-addr 211.183.3.100
# 토큰 생성 -> 나온 토큰을 각 서버에서 실행해서 등록
# --advertise-addr은 현재 서버의 ip이다.
docker swarm join-token manager
docker swarm join-token worker
# 토큰 확인
# 서로 토큰이 다르기 때문에 가입시키는 노드에 맞추어 처리해주어야 한다.
하면 토큰이 나온다. 이걸 가지고 worker들에게 복붙해주자
토큰이 manage과 worker 두개가 나오는데 manager은 최소한 2개를 두는 것이 좋기 때문이다.
[ 노드 관리 ]
### 매니저 ###
# node 없애기
docker node rm worker3
docker node rm -f worker1
docker node rm --force worker1
# manager에 등록된 worker들 확인하기
docker node ls
# manager의 상세 구성 정보를 확인 -> JSON 형태의 데이터
docker node inspect manager
# 다른 노드의 권한 높이기
docker node promote worker1
# 다른 노드의 권한 낮추기
docker node demote worker1
# manager의 상세 구성 정보를 확인 -> JSON 형태의 데이터
docker node inspect manager
### node ###
service docker stop
# docker swarm 에서 빠져나오기
### 공통 ###
docker swarm leave
docker swarm leave --force
# docker swarm 에서 빠져나오기
이제 문제점이 만약에 서버에 이미지들이 없다면 온라인에서 이미지를 받아오려고 하기 때문에 스로틀링이 발생할 수 있다.
또 원격에서 다운받고 있는데 한개가 속도가 굉장히 빨라서 비대칭성 문제가 발생할 수 있다.
그래서 저장소를 매니저에 두면 이를 해결할 수 있다.
[ docker swarm 서비스 시작 ]
# docker manager에서만 수행해주기(--with-registry-auth를 사용시)
docker login -u <ID> -p <PW># public cloud 사용시
# 이미지 설치
docker image pull nginx
# 이미지가 반드시 모든 노드에 있어야 함
### docker swarm service ###
# 생성된 서비스
# 서비스 복사해서 4개 만든다음 운영 -> worker들도 login해주어서 이미지 다운로드 해야함
# --replicas <숫자> 사용시 scale 사용가능
# --mode global 사용시 scale 사용불가능
docker service create --name myweb --replicas 4 -p 80:80 nginx
docker service create --name myweb2 --replicas 4 -p 80:80 tonyhan18/myweb:1.0
# 서비스를 최대 노드로 생성
docker service create --name myweb --mode global -p 80:80 nginx
# worker들은 manager의 login 정보를 타고 이미지 다운(--with-registry-auth)
docker service create --with-registry-auth --name testweb -p 8008:80 --replicas 4 nginx
# 생성된 서비스 버전 업데이트
docker service update --image tonyhan18/myweb:2.0 myweb2
# 이전 서비스 상태로 되돌리기
docker service rollback myweb2
# docker swarm 서비스 상태 확인
docker service ps myweb
# docker swarm 서비스 리스트 확인
docker service ls
# docker swarm 서비스 삭제
docker service rm myweb
# docker swarm 서비스 확대/축소
docker service scale myweb=2
# docker swarm 네트워크 확인
docker network ls
[ docker swarm 네트워크 ]
docker network ls
# overlay 네트워크 만들기
docker network create -d overlay --subnet 192.168.111.0/24 gildong
1. docker-gwbridge : ingress 네트워크에 포함된 서비스들이 외부와 통신할 때 사용하는 bridge이다.
2. ingress 네트워크 : network driver로 overlay를 사용하므로 전체 노드에 걸쳐서 통신이 가능하게 된다.(로드밸런스에 참여한다) 특정 컨테이너가 삭제되거나 동작하지 않더라도 해당 노드로의 접속이 들어오면 이를 오버레이를 통해 타 노드의 컨테이너(서비스)에서 이를 처리하게 됨.
위와같이 생성된 gildong 네트워크는 전체 호스트를 가로지르는 오버레이 네트워크이며 SCOPE가 swarm이므로 스웜 클러스터에 참여하는 서비스들이 연결될 수 있는 네트워크이다.
그렇다면 서비스를 이용하여 만든 것(컨테이너)이 아니라 docker container run을 이용하여 만든 컨테이너는 gildong 네트워크에 연결이 가능한가? --net gildong 가능? 불가능함. 오직 docker service를 위한 것이다. 하지만 꼭 원한다면 네트워크 생성시 --attachable을 꼭 사용해야 한다.
# attachable 옵션이 들어간 docker network
docker network create -d overlay --subnet 192.168.112.0/24 --attachable gildong2
# 컨테이너를 만들때 --net 옵션을 사용하자
docker container run -it --net gildong2 centos:7
# 컨테이너의 상태를 확인해서 내부의 IPA 부분을 확인하면 정보를 볼 수 있다.
docker container inspect <컨테이너 ID> | grep IPA
[ 롤링 업데이트 ]
기존 컨테이너가 포함하고 있는 내용을 동작중인 상태에서 변경하는 것이 아니다.
실제로는 기존 컨테이너가 중지되고 새로운 버전으로 생성된 컨테이너가 이 역활을 대체하는 것이다.
만약 기존 컨테이너로 돌아가고 싶다면 이를 롤백 할 수 있다. 대신 저장소가 필요함 -> 사설 저장소를 이용하기
docker service rollback myhttpd
위의 명령어로 이전 서비스로 돌아가면된다.
[Secret/Config]
둘다 컨테이너로 특정 정보를 전달하는 변수와 같은 목적으로 사용한다.(암호를 매번 바꾸는 등의)
컨테이너 내에서 사용이 되더라도 만약 컨테이너가 삭제되면 해당 secret, config는 휘발성 이므로 없어진다.
컨테이너 배포시 컨테이너에서 사용할 데이터를 따로 지정해왔다. 그런데 아예 이미지에 그런 내용을 넣으면 어떻겠냐는 것이다. 이미지는 정적인 결과물이므로 고정된 내용을 수정할 수 없다. 이미지를 만들었다면 고대로 컨테이너에 들어가지 수정되지 않는다. 이를 수정할 수 있게 하자는 것이다.
예를 들어 우리가 ssh PW를 지정했는데 이걸 매번 지정하기 귀찮아서 ssh 패스워드를 넣었다고 가정하자. 이것의 단점은 이 이미지로 배포시 모든 컨테이너의 패스워드는 동일해진다.
그래서 패스워드, 변수같은 민감한 내용을 집어넣었는데 이 값이 매번 바뀌게 하고 싶다는 것이 핵심이다.
이미지 내에 secret을 설정한다. secret test1이라는 것을 만들고 그 안에 패스워드를 매번 바꾸어 넣고 배포한다.
---
이미지내에 패스워드, 변수, key 값 등이 적용되어 있다면 이를 이용하여 생성한 모든 컨테이너는 동일한 pwd, 변수, key값을 사용할 수 밖에 없게된다. 이는 보안상 결함이라고 할 수 있다.
이 경우 이미지에 Secret/Config 를 사용하면 필요할 때마다 value를 변경하여 컨테이너를 배포하는 형식으로 각 컨테이너 별로 별개의 key, password, 변수 등을 전달할 수 있게된다.
이미지에 secret과 config를 정의하고 컨테이너 배포시 secret과 config의 값을 정의해 놓는다.
그럼 secret과 config의 차이는 암호화를 하고 안하고의 차이점이다.
secret을 사용하면 Data가 암호화된다. 대신 컨테이너 안에서는 값을 볼 수 있다.
Secret, Config는 docker container run으로는 사용할 수 없다.
오직 docker swarm에서만 사용할 수 있다. 만약 docker container 에서 패스워드를 적용하고자 한다면 -e PASS=test123과 같이 보안성이 없는 상태에서 데이터를 저장할 수 밖에 없다.
- Secret은 컨테이너 내에서는 평문, 컨테이너 삭제시 함께 사라진다.(휘발성)
- Secret -> 패스워드, ssh key, 인증서와 같이 중요한 데이터를 전송할 때 사용한다.
- Config -> 설정파일, 변수와 같이 암호화가 필요하지 않은 경우에 사용한다.
사용하는 방법
1. secret/config 를 생성한다.
2. 서비스 생성시 "1" 에서 만든 결과물을 컨테이너의 어디에서 사용할 것인지 지어해준다.
Secret 생성하기
# secret 생성방법
# 끝에 `-`가 보이는건 오타가 아니다!
echo test123 | docker secret create mypwd -
# 이 방법으로도 패스워드를 만들 수 있다.
docker secret create mypwd pwd.txt
# 만들어진 secret 들 보기
docker secret ls
# 암호의 정보를 확인
docker secret inspect mypwd
실재로 test123 이라는 정보가 보이지는 않는다.
# 실재 docker swarm 배포시 secret 사용방법
docker service create --name mysql --replicas 1 \
--secret mypwd \
-e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mypwd" \
-e MYSQL_PASSWORD_FILE="/run/secrets/mypwd" \
-e MYSQL_DATABASE="wordpress" mysql:5.7
mysql 내에서 사용할 root의 패스워드 -> 컨테이너 내에 있는 /run/secrets/mypwd 파일의 내용을 토대로 설정
--secret mypwd 를 적용하게 되면 mypwd의 내용을 컨테이너 내의 /run/secrets/mypwd에 기본적으로 붙여넣기 해준다.
이렇게하면 test123이라는 mypwd는 파일로 동작하여 /run/secrets/mypwd 에 저장된다. 이미지에서는 보이지 않고 컨테이너에서는 정상적으로 동작하게된다.
만들어진 위치로 가서 container의 상태를 확인해보자
docker container exec <NAMES> cat /run/secrets/mypwd
실재 결과를 확인할 수 있다.
---
고객이 클라우드 환경에 들어와서 원하는 패스워드를 입력하면 해당 패스워드는 Secret으로 저장하여 외부 타 사용자, 클라우드 관리자 모두 볼 수 없도록 해야한다.
단, 일반적인 설정 파일의 내용이나 간단한 변수등은 보안이 필요하지 않으므로 이는 config를 이용하여 배포한다.
# config 파일 만들기
docker config create webconfig index.html
# config 파일 내용 확인하기
docker config inspect webconfig
위와같이 Data 부분이 암호화되어 배포된다.
# 실재 config를 이용한 배포
docker service create --replicas 1 -d -p 8001:80 --name webconfig1 \
--config source=webconfig,target=/usr/share/nginx/html/index.html nginx
[ 볼륨 ]
일반적으로 도커에서 사용하는 두가지 볼륨형태를 스웜에서도 사용할 수 있다.
1. file storage -> -v (또는 --volume)
-v /root:/root -> 호스트의 /root와 컨테이너의 /root를 마운트하는 방법
디렉토리와 디렉토리를 연결하는 방법
2. block storage
-v myvolume:/root -> 호스트의 디스크 myvolume을 호스트의 /root에 마운트하는 방법
# block storage 방식
docker service create -d --name testvol1 \
--mount type=volume,source=vol1,target=/root centos:7
# file storage 방식
# 좋은 방식은 아니다.
docker service create -d --name testvol2 \
--mount type=bind,source=/root/host,target=/root/container centos:7
file storage 를 잘 쓰지 않는 이유가 있다.
서버 컨테이너중 하나가 죽었을 때 컨테이너를 다른곳으로 마이그레이션해줄 텐데
1. 이미 사용하는 같은 스토리지가 마운트 됨
2. 스토리지가 동기화 안됨
이를 위해 스웜 클러스터 외부에 별도로 스토리지를 준비하고 각 컨테이너는 이 스토리지에 연결하여 디스크 또는 디렉토리를 사용하는 방법을 적용해야 안정적으로 스토리지 제공이 가능하다. -> Persistent Storage(영구 외부 스토리지)
k8s -> PV(Persistent Volume), PVC(Persistent Volume Claim)
개발자가 자신이 원하는 크기의 디스크 사이즈, 사용용도(읽기/쓰기, 동시 여러명 접속 여부) 등을 지정하여 볼륨에게 요청하면 해당 요청에 적절한 볼륨을 개발자 서버에게 자동으로 연결해 주는 기술.
[라벨 사용하기]
지금까지의 서비스 배포는 replicas 또는 global 을 이용하여 특정 개수만큼 또는 각 호스트 별로 1개씩 서비스를 배포하는 방식이었다. 이로인해 manager 에서도 서비스가 배포되는 일이 발생하는데, 만약 서비스 배포를 특정 노드에서만 배포하고 싶다면?
docker node inspect manager | grep Role
하면 위와같이 나오는데 이걸 배포할때 특정 Role에만 배포하라고 요청할 수 있다.
# 노드에 label 붙이기/없애기
docker node update --label-add zone=seoul worker1
docker node update --label-rm zone worker1
# 특정 역활의 컨테이너에만 이미지 배포
docker service create -d --name webtest --constraint 'node.role==worker' -p 80:80 --mode global nginx
# 특정 호스트이름 컨테이너에만 이미지 배포
docker service create -d --name webtest --constraint 'node.hostname==worker1' -p 80:80 --mode global nginx
# 특정 라벨의 컨테이너에만 이미지 배포
docker service create -d --name webtest --constraint 'node.labels.zone==seoul' -p 80:80 --mode global nginx
Python
### 패키지 설치 #########
sudo apt-get install python3-pip
pip install docker
python3
### 코딩 ###########
import docker
# docker 설정 변수 받아오기
client = docker.from_env()
# 설치된 docker image 보기
client.images.list()
# 동작중인 도커 컨테이너 보기
client.containers.list()
# 죽든 살든 모든 도커 컨테이너 보기
client.containers.list(all)
Docker SDK for Python — Docker SDK for Python 5.0.3 documentation (docker-py.readthedocs.io)
Docker SDK for Python — Docker SDK for Python 5.0.3 documentation
Docker SDK for Python A Python library for the Docker Engine API. It lets you do anything the docker command does, but from within Python apps – run containers, manage containers, manage Swarms, etc. For more information about the Engine API, see its doc
docker-py.readthedocs.io
더 자세한것은 위의 링크에서 확인하기
Docker Stack
스택은 하나 이상의 서비스를 그룹으로 묶은 단위로, 애플리케이션 전체 구성을 정의한다. 서비스는 애플리케이션 이미지를 하나밖에 다루지 못하지만, 여러 서비스가 협조해 동작하는 형태로는 다양한 애플리케이션을 구성할 수 있는데 이를 스택이라고 한다.
docker stack은 docker compose와 다르다.
docker compose는 한 서버내에서 컨테이너를 정의하지만 docker stack은 서비스를 정의한다.
docker swarm + docker-compose(yaml) => yaml 파일에 필요한 환경 구성 정보 등을 작성하고 이를 이용하여 서비스를 배포하는 형식
k8s는 pod라는 개념이 존재 -> 완벽한 서비스를 제공하기 위한 최소 단위로 "Pod"라는 개념을 사용한다. Pod는 1개 이상의 컨테이너로 구성되며 만약 2개 이상의 컨테이너가 하나의 포드를 구성할 경우 두 컨테이너는 무조건 붙어다닌다.
k8s에서 지정하는 replicas는 pod == swarm에서는 서비스를 의미한다(분리 가능하다)
스택이 다루는 애플리케이션 하나하나는 컴포즈와 같다. 스택은 결국 스웜에서 동작하는 스케일 인/아웃, 제약조건 부여가 가능한 컴포즈다. 스택은 docker stack 하위 명령으로 조작 한다.
스택을 사용해 배포된 서비스 그룹은 overlay 네트워크에 속한다. 만약 스택에서 overlay 네트워크를 설정하지 않으면 스택마다 서로 다른 overlay 네트워크를 생성하고 그안에 서비스 그룹이 속하게 되어 다른 overlay 네트워크에 속한 서비스간 연결이 불가능해 진다.
위와같이 추가 옵션들이 있는데 기존 네트워크에 추가해서 사용할 수 있다.
deploy 같은 경우 스택을 새로 배포 혹은 업데이트 함이라고 적혀있다. 그래서 이런기능이 k8s에도 있다.
(kubectl apply)
도커 스웜, HAproxy, Nginx를 활용한 웹서비스와 로드밸런싱
지금 구성하는 것은 worker01 ~ worker03까지 nginx를 배포하는 것이다. 그리고 manager에 HAproxy를 배포한다. 이게 안정적인 방식은 아니다. LB가 앞에 있어야 하기 때문이니 안좋은 구조이다.
HAproxy도 컨테이너로 제공된다.
# haproxy와 컨테이너를 연결하기 위한 overlay 네트워크 생성
docker network create --driver=overlay --attachable web
haproxy와 컨테이너를 연결하기 위한 overlay 네트워크 생성한다. --driver=overlay로 하면 모든 클러스터환경에 똑같이 배치가 된다.
--attachable 이라고 하면 docker container run 명령어로 만든 컨테이너가 overlay 네트워크에 연결된다. 이 옵션이 없으면 docker container run 명령어로 --network 을 넣어도 web에 연결불가능하다. 하지만 이 방식으로 연결이 가능해진다.
2번은 아무 이름이나 지어서 yml 파일을 만들어낸 모습이다.
위와같이 있다고 하자.
version은 composer version 3과 같다.
services에는 nginx와 proxy가 있다.
배포하기 위해서는 다음 명령어를 넣어주자
```
docker stack deploy --compose-file=web.yml web
```
Quiz.
각 nginx는 cpu 0.5개 RAM은 64mb를 할당하라 단, 여유자원이 풍부할 경우에는 최대 1개, 128MB까지 제공
version: '3'
services:
nginx:
image: nginx
deploy:
replicas: 3
placement:
constraints: [node.role != manager]
restart_policy:
condition: on-failure
max_attempts: 3
resources:
limits:
cpus: '1'
memory: 128M
reservations:
cpus: '0.5'
memory: 64M
environment:
SERVICE_PORTS: 80
networks:
- web
proxy:
image: dockercloud/haproxy
depends_on:
- nginx
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 80:80
networks:
- web
deploy:
mode: global
placement:
constraints: [node.role == manager]
networks:
web:
external: true
8. Kubernetes
'Development(Web, Server, Cloud) > Cloud : 정리' 카테고리의 다른 글
[개발회고] Docker Swarm(Docker Stack) + React + Express(Node Server) + Nginx + Reverse Proxy (0) | 2022.03.31 |
---|---|
7. MySQL (0) | 2022.03.23 |
5. 클라우드 가상화(KVM, Libvirt) (0) | 2022.02.24 |
4. Cloud 네트워크 (0) | 2022.02.08 |
3. GCP와 AWS (0) | 2022.01.18 |