본문 바로가기
Development(Web, Server, Cloud)/22) LINUX - Cloud

클라우드 42일차(CAdvisor, Dockerfile Advanced, Private Docker Registry, Docker Compose)

by tonyhan18 2022. 3. 3.
728x90

docker system prune -af  : 동작중인 컨테이너를 제외하고 삭제

 

Docker 을 작동하기 위해서 OS에는 커널과 커널안의 namespace, cgroup이 존재

namespace : 작업별 구획나누기 -> 컨테이너 각각에 PID를 할당해서 상호 간섭이 일어나지 않도록 만든다.

cgroup : 리소스 부여 -> 컨테이너 별 물리 리소스를 제한, 분배해서 안정적인 서비스 유지

 

추가적인 명령어들

이중에서도

```

docker container stats

docker container top

```

를 확인해보자.

 

```

sudo apt-get install htop

```

htop이 실행된다. htop

입력시 위와같이 물리자원 사용량을 확인할 수 있다.

 

```

docker container run -d -p 8001:80 --name nginx01 nginx

docker container stats nginx01

docker container top nginx01

```

먼저 컨테이너를 만들고 상태를 확인해보자

 

컨테이너(쿠버네티스 : pod-완전한 하나의 서비스를 제공할 수 있는 컨테이너의 묶음)

- 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정보들을 확인할 수 있다.

 

```

cat cpu.shares

```

 

 

211.183.3.200:8080 으로 브라우저 접속해보자

 

```

docker container exec nginx01 hostname

```

nginx01 에게 hostname이라면 명령 전달

이걸 이용해서 컨테이너

 

Dockerfile (Dockerfile 내에 필요한 내용을 작성하여 build)

-> Dockerfile 텍스트 파일을 생성하고 내부에 base image 지정

-> 이미지에 설치해야할 패키지 지정

-> 볼륨 연결

-> 나중에 컨테이너로 배포할 때 처음 실행할 명령어 지정

 

* 시간될때 엑셀 공부해놓기

실습1. centos7 이미지에 

```

docker build -t newcentos:blue .

docker build -t newcentos:blue -f <dockerfile 위치>

docker image rm -f newcentos:blue

```

 

볼륨연결

- 컨테이너에서 볼륨이 필요한 이유

1. 컨테이너는 휘발성이다. 컨테이너 내에서 새로운 파일을 생성했는데 컨테이너가 삭제되었다면 생성된 파일은 함께 사라진다. 즉, 데이터를 영구적으로 보관할 수 없다.

-> 이를 위해 로컬(우분투)에 볼륨을 생성하고 해당 볼륨을 컨테이너에 연결해준다. 해당 볼륨에 데이터가 작성된다면 컨테이너가 삭제되더라도 데이터는 영구적으로 보관할 수 있게 된다.

 

볼륨 마운트(VOLUME)

이미지에 볼륨을 할당하고자 할 때 사용한다.

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

- VOLUME

httpd를 설치하면 /etc/httpd 디렉토리를 로컬의 볼륨과 연결 가능하다.

/var/log/httpd 는 컨테이너 아래 httpd 아래의 파일(access_log, error_log)들을 내 컴퓨터의 볼륨과 연결할 수 있다.

 

- EXPOSE : 방화벽에서 포트를 여는 역활

 

대충 index.html과 a.tar이 필요하다

만들어주자

볼륨 2개가 새로 생기었다. 이게 어디에 생긴것인지 inspect를 이용해서 알아보자

 

docker container inspect test01

하면 위와같이 Mounts 부분을 확인할 수 있다.

 

개중 httpd log 정보가 있는 위치로 가서 access_log 파일을 확인하면 위와같이 정보가 있는 것을 확인할 수 있다.

 

실습 3.

DockerFile 을 이용하여 나만의 Docker Image 만들기 - NHN Cloud (skill.or.kr)

 

DockerFile 을 이용하여 나만의 Docker Image 만들기 - NHN Cloud

Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)

doc.skill.or.kr

미리 생성한 컨테이너 test01을 삭제하고,

기존 Dockerfile을 활용하여 아래의 추가 조건을 갖춘 이미지 생성, 컨테이너 배포가 가능하도록 하세요.

 

기존 내용에 mariadb-server(버전은 10.4)를 설치하고, 처음 컨테이너가 배포될때 웹서버 DB서버 모두 실행 가능해야함.

CMD는 사용하지 말고 ENTRYPOINT만 한번 사용하기

 

http://211.183.3.200:8008 로 접속, 컨테이너의 80번 포트로 들어감

mysql testdb -u root -ptest123 -h 211.183.3.200 -P 33068 -> 컨테이너:3306으로 연결되도록하기

 

commit (생성된 컨테이너를 이미지화)

 

 

DownGit (minhaskamal.github.io)

 

DownGit

 

minhaskamal.github.io

github 일부 디렉토리만 다운받기

 

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

 

먼저 간단하게 작성했다. 이렇게 하면 웹서버 접속과 mariadb 접속이 가능해진다.

하지만 여전히 mariadb 10.4를 어떻게 깔지 못했다. 이걸 수정해야 한다.

 

---

 

ubuntu (20.04) 에서 인터페이스 설정

- yml, yaml 파일을 이용하여 변경하기

- desktop 버전은 기본적으로 Network Manager 의 관리하에 있다.

NM은 일반적으로 GUI가 있는 환경에서 일반 사

 

```

sudo systemctl stop NetworkManager

sudo systemctl disable NetworkManager

sido vi /etc/netplan/01-network-manager-all.yaml

```

 

```

sudo netplan apply

ip a

```

네트워크가 바뀌었다.

 

docker tag를 이용해서 기존 docker hub에 올라갈 이미지의 이름을 바꾸어서 push 하면 자동으로 올라간다.

별거 없이 이게 가능한 이유는 docker login시에 이미 관련 설정 파일이 있어서 그렇다.

 

위와같이 인증경로가 나오는 것을 확인할 수 있다. 이 경로에 인증을 받기 때문에 곧장 docker hub에 데이터를 넣을 수 있는 것이다.

 

기본적으로 docker login은 docker hub에 로그인 하도록 설정되어 있다.

도커 허브는 public, private 저장소를 모두 제공

 

도커 레지스트리를 이용한 사설 저장소 구축

 

지금까지 이미지를 저장한곳은 local 저장소였다. 지금까지 실습환경은 ubuntu의 docker을 이용해서 docker hub의 base 이미지들을 받아와 패키지를 설치하고 컨테이너배포시 실행할것들을 패키지로 묶으면 우리가 원하는 이미지가 만들어진다. 

이건 local에만 저장되어있고 docker hub에 올리기 위해서는 docker tag를 이용해서 이름을 바꾸어야만 했다. 이렇게 만든것을 push하게 되면 docker hub에 올라가게 된다.

 

그런데 이게 어떻게 자동으로 되는 것일까?

```

docker login

```

하면 자동으로 인증한다. 그리고 파일은 /home/user1/.docker/config.json안에 들어가 있다.

인증을 위한 경로가 나오는 것을 확인할 수 있다.

 

결국은 docker login하면 결국에 docker로 로그인하게 된다. 로그인 후에는 자동으로 PC에 연결된다.

만약 이 파일이 없으면 다시 인증을 해주어야 한다. 이때는 ID/PW를 요청하게 된다.

 

기본적으로 docker login은 docker hub에 로그인 하도록 설정되어 있음.

도커 허브는 public, private 저장소를 모두 제공한다.

 

---

 

회사내에서 자체 프로젝트를 진행하고 있는 경우에는 인터넷과의 연결이 없는 경우가 많음

로컬 저장소의 이미지는 공유 불가.

 

그래서 도커 이미지를 저장할 수 있는 곳

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

 

사설 저장소

레지스트리주소:포트번호/이미지이름:태그

centos:7 -> localhost:5000/test1.0

```

docker tag centos:7 localhost:5000/test:1.0

docker image push localhost:5000/test:1.0

 

docker image rm -f localhost:5000/test:1.0

docker image pull localhost:5000/test:1.0

```

 

사설저장소를 만들면 각 서버가 이미지를 땡겨온다. 이때 그냥 이미지를 땡기지 말고 인증서를 미리 서버별로 발급해주어서 이미지를 받아오게함으로 보안성을 높일 수 있다.

그래서 나중에 다른 서버에서 이미지를 받아오기 위해서 insecure-registry 설정을 해주어야 한다.

[Docker] 'insecure-registry' 설정 :: 재밌다 개발 2 (tistory.com)

 

[Docker] 'insecure-registry' 설정

문제 상황  최근 내가 진행하고 있는 프로젝트 중 하나는, 데이터 분석 및 추후 머신러닝 적용의 가능성으로 인해 파이썬으로 작성되고 있다. 사실 파이썬은 비교적 자잘하고 귀찮은, 비교적 중

asuraiv.tistory.com

 

docker private registry insecure

 

/etc/docker/daemon.json 파일을 만들어서 이미지를 쉽게 올렸다가 내릴 수 있게 만들어야 한다.

 

 

[docker-compose]

```

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.yml 의 개요

앞서 언급하였듯이 도커 컴포즈는 ‘docker-compose.yml' 파일에 시스템 내에서 가동하는 여 러 컨테이너들의 구성을 모아서 정의하게 된다. 이 정의 파일은 YAML 형식으로 기술한다.

 

YAML

YAML 은 구조화된 데이터를 표현하기 위한 데이터 포맷이다. YAML 은 Python 과 같이 들여쓰기로 데이터의 계층 구조를 나타낸다. 들여쓰기는 탭이 아니라 스 페이스를 사용하며 누가 써도 읽기 쉽기 때문에 설정 파일등에 많이 이용된다. YAML에서는 데이터의 맨 앞에 ‘-’를 붙이면 배열을 나타낼 수 있으며 ‘-’ 다음에 는 반드시 스페이스를 넣어야 한다

 

컴포즈 파일은

- 서비스

- 네트워크

- 볼륨을 정의한다.

 

따라서 컴포즈 파일의 좌측 벽면에는

version, services, networks, volumes를 붙여 쓴다.

 

아래의 경우는 이미 만들어져 있는 이미지를 활용하는 경우

services:

  webserver:

    image: httpd

 

아래의 경우는 Dockerfile을 이용하여 이미지 생성부터 서비스배포까지 포함한다.(비추)

services:

  webserver:

    build: .  # 현재 위치에 있는 Dockerfile을 이용하여 이미지 만들고 그 이미지로 실행

 

Git 저장소에서 가져오기(비추천)

이 방법은 추천하지 않는다.

 

version : 버전별로 적용되는게 다 달라서 고정해야함. 안 적으로 1.0으로 시작됨

webserver : container와 같은 역활을 한다.

ports : 자신의 포트와 호스트의 포트를 매핑한다. (-p 8001:80)

networks : 이름별로 별도의 네트워크를 만들어서 연결해서 사용

expose : 외부에 공개되지 않았다. 노출만 된것이다. 컨테이너 자체에 오픈된 포트를 의미하며 이 포트가 외부에서 연결되는 것은 아니다. (EXPOSE 80 3306)

 

위와같이 작성할때

/var/lib/mysql과 볼륨이 연결

현재 디렉토리 cache/를 /tmp/cache 에 연결

~/configs 와 /etc/configs/을 연결 (read only인데 잘 안쓴다)

 

volumes_from, links는 현재는 안쓴다.

 

서비스 의존관계 -> 일종의 시작 순서 결정. 시작순서를 결정한다는 것이지 앞 서비스가 실행되고 뒤가 실행되는게 아님

 

 

실습 : mysql과 wordpress를 이용한 웹 서비스 배포하기

```

docker pull mysql:5.7

docker pull wordpress

vi docker-compose.yml

```

 

만약 서버를 두개 이상 만들고 wordpress를 모두 8009에 물리면 연결이 안된다. 그래서 1:1 구성을 해주어야 한다.

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: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: {}

```

docker-compose up -d

```

 

하면 도커 컴포즈가 된다.

두개가 생기었다.

 

word press 접속이 가능하다

 

이제 갯수를 늘려보자 wordpress나 db나 무엇이든 scale-out 해보자

```

docker-compose up --scale wordpress=3

``

에러가 엄청많이뜬다.

 

에러를 보니 포트가 이미 사용중이라는 문제이다. 그냥 한꺼번에 삭제해버리자

```

docker-compose down  # container는 없애고 볼륨은 남긴다.

```

 

이렇게 해보니 잘된다.

 

그런데 문제점은 로딩이 안끝난다;; 심지어 접속하면 wordpress_2에만 접속된다.

```

docker-compose up --scale wordpress=3 --scale db=3 -d  #이것도 안된다.

```

보면 네트워크가 하나의 브릿지에 연결되고 거기 위에서 웹서버 3개가 돌아가는 구조이다.

 

docker-compose up -d

docker-compose 파일에 기반하여 컨테이너를 실행할 경우에는

docker-compose.yml 이 있는 디렉토리에서 docker-compose up -d 를 통해 서비스 배포

 

docker-compose ps는 컴포즈를 통해서 배포된 컨테이너들만 확인 가능

docker-compose up --scale wordpress=3 -> 서비스 명 wordpress에 해당하는 컨테이너만 스케일을 3으로 조정하여 확장할 수 있다.

 

만들어져 있는 모든 환경을 한번에 삭제하고 싶다면 파일이 있는 디렉토리에서 docker-compose down

 

FROM centos:7
RUN yum -y update
RUN yum -y install git curl wget httpd
COPY index.html /var/www/html/index.html
VOLUME /etc/httpd /var/log/httpd
EXPOSE 80
CMD httpd -D FOREGROUND
version: "3.3"
services:
  websrv:
    image: myhttpd:1.0
    networks:
      - websrvnet
    volumes:
      - websrv:/etc/httpd
    ports:
      - "8001-8008:80"
    restart: always

networks:
  websrvnet:

volumes:
  websrv: {}

 

 

728x90