카테고리 없음

[2023-05-26 금] 도커 최종, 도커 컴포즈, 도커 모니터링, 도커스웜

16비트 2023. 5. 26. 18:05

 

1. gcp에서 워드프레스 dbserver 만들기

어제 실수했던 도커허브 리포지토리에 있는 이미지 지우기

GCP 인스턴스 웹콘솔에서 SSH 접속

 

컨테이너 안에 있는 스토리지를 이미지로 만들고싶었다(근데 안됨)

원래는 스토리지를 빼놓고 이미지로 만들어야함

 

$ sudo su -

# timedatectl set-timezeon Asia/Seoul      # 인스턴스 타임존 맞추기

 mkdir dbserver && $_

 

 

도커 이미지 과정 추상화

gcp-dbserver 도커 컨테이너 만들기

# 상태저장이 되도록 함

# docker run -itd -p 3306:3306 --name mysql --network gcp-network ubuntu:18.04    # 우분투를 base image로 gcp-network에 mysql 컨테이너 생성+실행. -itd를 넣어서 컨테이너가 up된 상태로 계속 실행되도록 명령

// # docker rmi -f $(docker images -q)   # 이미지를 전부 지우는 명령

 

# docker ps    # mysql 컨테이너 프로세스가 띄워졌다

COMMAND가 떠있다. 떠있어야 컨테이너가 UP이 된다. 우분투 이미지 자체 안에 커맨드가 안들어가있다. -it 명령을 통해 컨테이너 안쪽에 들어갈 수도 있고 커맨드/bin/bash 기능을 수행시켜주는 역할을 할 수 있다

 

 

# docker exec -it mysql bash    # mysql 컨테이너 안으로 들어감

# cat /etc/os-release   # debian이나 우분투 os의 상세 정보를 볼 수 있다. 

# sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list   # s/ 찾을 사이트 /ftp 변경 사이트. 경로에 있는 파일명을 바꿀 것이다. 빠르게 설치하기 위함

# apt-get update   # 저장소가 바뀐걸 업데이트

# apt-get install -y mariadb-server

# sed -i "s/bind-address/#bind-address/g" /etc/mysql/mariadb.conf.d/50-server.cnf    # bind-adress는 로컬에서만 접속하도록 하는 것. 접근제어 하는 것을 사용하지 않도록 #을 붙여주는 치환 명령. 뒤에 경로는bind-address가 위치한 파일

# service mysql start   # mysql 데몬을 실행시키는 명령. service는 systemctl 이전 버전

# mysql_secure_installation     # enter(현재 패스워드없음) > Y(root 패스워드 설정) > y > y > y > y

# service mysql restart

# mysql -u root -p   # 방금 만든 루트 패스워드로 mysql 접속

# CREATE USER 'wpuser'@'%' IDENTIFIED BY 'wppass';

CREATE DATABASE IF NOT EXISTS wordpress;

GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'%';

quit

 

2. 워드프레스 도커 dbserver 갈아끼우기

# docker run -d -p 80:80 --name my-wp --network gcp-network apeachcloud/my-wp:v1.0   # 도커허브에 있는 이미지를 가지고 컨테이너 생성+실행

# docker ps    

# docker rename mysql dbserver    # 컨테이너 이름 변경

# curl ipconfig.io     # 인스턴스 ip를 Route53에 레코드 등록

 

어제의 오류의 발생 원인 : 커밋할 때 컨테이너를 stop(중지)하고 커밋+push를 진행해야했다

 

blog.changhoon.shop으로 접속하면 my-wp 컨테이너에 있는 워드프레스가 뜬다

댓글남기기

# docker stop dbserver my-wp     # commit과 push하기 위해 반드시 컨테이너를 중지해야한다

# docker commit -a "peach" -m "wordpress" my-wp apeachcloud/gcp-wordpress:tiger

# docker push apeachcloud/gcp-wordpress:tiger

# docker commit dbserver mysql-base:v1.0     # 임시 커밋으로 mysql-base:v1.0으로 이미지를 만든다. -a 명령과 -p는 필수가 아니다.

# docker iamges      # mysql-base:v1.0 이미지가 만들어졌다. 도커 컨테이너로 되려면 도커 커맨드를 사용하게 하려면 엔트리포인트나 CMD를 넣어줘야한다

# vi Dockerfile    # 내가 만든 이미지에 커맨드를 하나 추가해서 다시 이미지를 만든다. 이렇게 상태저장을 할 수 있다. 정식 방법이 아닌 편법. 정식 방법은 데이터를 빼냈다가 다시 붙이는 방식으로 가야하는데 지금은 상태저장상태로 push하기 위해서 mysqld를 넣어줌. 이 작업을 안하면 docker run이 되지 않는다

FROM mysql-base:v1.0

ENTRYPOINT ["mysqld"]     # 데몬 실행 명령어 mysqld

# docker build -t apeachcloud/gcp-dbserver:eagle .          # 현재 경로의 Dockerfile을 기반으로 이미지 생성 

# docker push apeachcloud/gcp-dbserver:eagle

 

# docker ps -a  

# docker rm -f ce0fdf5259a1 a852188d9bfe  # 현재 생성되어있는 컨테이너(본뜬 컨테이너) 지우기

 

# docker run -d -p 3306:3306 --name dbserver --network gcp-network apeachcloud/gcp-dbserver:eagle

# docker run -d -p 80:80 --name wordpress --network gcp-network apeachcloud/gcp-wordpress:tiger

 

접속테스트

댓글이 잘 있는 것을 확인하였고 댓글을 하나 남긴다

# docker stop dbserver

# docker commit -a "peach" -m "gcp-wp-2" dbserver apeachcloud/gcp-dbserver:falcon

# docker rm -f dbserver     # dbserver를 지우면 접속이 끊긴다

# docker run -d -p 3306:3306 --name dbserver --network gcp-network apeachcloud/gcp-dbserver:falcon

# docker ps

다시 접속하면 페이지가 정상적으로 뜨고 댓글이 남겨져있는 것으로 상태저장이 된 것을 확인할 수 있다

 

# docker images

 

3. 개발자 도커 활용

onbuild 명령어 활용

--- 운영자 역할       운영자가 이미지를 처음으로 이미지를 빌드한다. 그 뒤 개발자가 이미지를 빌드할 떄 ADD 명령이 수행된다. 개발자는 운영자에게 받은 도커파일과 tar파일을 같은 경로로 놓아두고 빌드하고 도커허브로 commit+push하면 되는 것.
# mkdir onbuild && cd $_
# vi Dockerfile.base
FROM ubuntu:18.04
RUN sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list
RUN apt-get -y update
RUN apt-get -y install nginx
EXPOSE 80
ONBUILD ADD website*.tar /var/www/html/     # ADD는 tar파일을 풀 수 있는 기능이 있다. 운영자가 빌드하면 남게되는 명령
CMD ["nginx", "-g", "daemon off;"]     # 도커파일을 이미지로 실행을 시키면 nginx가 올라가서 웹 이미지를 갖춘다

 

 

docker서버가 운영자 tester 서버가 개발자 역할을 할 것. 개발자를 위한 web-base:v1.0을 도커허브에 올리고 Dockerfile을 만들어서 개발자에게 보내준다

 

# ls

# cd onbuild    # Dockerfile은 개발자한테 줄 것. Dockerfile.base는 운영자가 처음 빌드할 도커파일

 

운영자는 개발자에게 onbuild파일을 만들고 소스코드를 tar로 만들어주세요

 

$ mkdir onbuild && cd $_

 

aws.tar파일이 개발자가 만든 것이라 가정

$ sudo cp ~/aws.tar .

 

$ mv aws.tar website.tar   # 개발자에게 tar 이름을 website로 시작해달라고한다. ADD 명령을 설계할 때 운영자가 지정하기 때문

# scp Dockerfile peach@192.168.1.202:/home/peach/onbuild      # 운영자는 개발자에게 초기 빌드를 마친 Dockerfile을 보낸다

 

$ docker build -t apeachcloud/web-site:aws . # Dockerfile은 같은 경로에 있는 website.tar파일을 물귀신처럼 같이 빌드된다.

$ docker images    # 이미지가 생성되었다

$ docker run -d -p 80:80 --name=web-site apeachcloud/web-site:aws # 생성한 이미지를 가지고 컨테이너를 만들어주세요

접속테스트

# docker login

# docker push apeachcloud/web-site:aws    # 빌드하고 접속테스트에 성공한 이미지를 push

 

웹사이트가 리뉴얼되었다. 새로운 tar파일을 개발자 환경에서 업로드한다

 

$ mv website.tar aws.tar

$ cp ~/food.tar .

$ mv food.tar website.tar

$ docker build -t apeachcloud/web-site:food .     # 새롭게 리뉴얼된 tar파일을 도커 이미지를 빌드한다.

$ docker run -d -p 8080:80 --name web-site2 apeachcloud/web-site:food      # 생성한 이미지로 컨테이너를 생성+실행

접속테스트

# docker push apeachcloud/web-site:food    # 도커 허브에 새롭게 리뉴얼된 사이트의 이미지를 push. '리포지토리/이미지 이름:태그' 순서

도커허브에서 방금 작업했던 이미지를 확인할 수 있다

 

 

 

--- 도커 사설 레지스트리(GCP)

도커 허브는 퍼블릭하게 도커 이미지를 올리고 공유할 수 있는 공간이다.

사설 레지스트리(GCP)는 프라이빗하게 공유할 수 있는 공간. 도커허브가 마비될 수도 있기 때문에 개발자는 여기에도 push해줘야한다

 

GCP 세션

# docker run -d -p 5000:5000 --restart=always --name private-docker-registry registry    # 5000번 포트로 껐다켜져도 서버가 켜지면 컨테이너도 자동으로 실행되도록 private-docker-registry이름. registry라는 도커 이미지가 있다. ':버전'을 적지 않으면 가장 최신의 이미지를 가져온다

 

사설 리포지토리가 등록하는게 아니라 클라이언트가 세팅해야함

# vi /etc/docker/daemon.json                  # 클라이언트가 세팅해야하는 값
{ "insecure-registries":["blog.changhoon.shop:5000"] }    # 이 도메인을 적어야만 저장소를 이용할 수 있다


# systemctl restart docker     # restart하면 컨테이너가 다 내려가지만 registry는 always명령을 통해 자동으로 실행된다

 

# docker update --restart always dbserver      # 컨테이너가 실행중이어도 always 명령을 줄 수 있다

# docker update --restart always wordpress 

# systemctl restart docker   

# docker ps     # always 명령이 적용되어서 restart되어도 컨테이너가 UP되었다

 

4. 사설 레지스트리(GCP)에서 이미지 공유

GCP 방화벽 열기

현재 gcp 인스턴스에 5000번 포트가 열려있지 않다. 방화벽을 열어줘야한다

정책 이름 'default-5000'

트래픽 방향 '수신'

일치 시 작업 '허용'

대상 '네트워크의 모든 인스턴스'

소스 IPv4 범위 '106.253.56.124/32'     #  강의실 내 IP

지정된 프로토콜 및 포트 'TCP' - 포트 '5000'

 

우분투(개발자) 세션

$ vi /etc/docker/daemon.json # 클라이언트가 설정해야한다.
{ "insecure-registries":["blog.changhoon.shop:5000"] }

$ systemctl restart docker

$ docker images    # 생성했던 food와 aws 이미지를 사설 레지스트리에 push해야한다

태깅 : 이미지를 별칭(별명)을 달아주는 것.  이미지의 ID는 동일하지만 태깅이 다를 수 있다

$ docker tag apeachcloud/web-site:aws blog.changhoon.shop:5000/web-site:aws  

$ docker tag apeachcloud/web-site:food blog.changhoon.shop:5000/web-site:food

$ docker images    # 이미지 ID는 같지만 리포지토리가 다른 이미지가 생성되었다

$ docker push blog.changhoon.shop:5000/web-site:aws    # 사설 레포지토리로 이미지를 push

$ docker push blog.changhoon.shop:5000/web-site:food

도커 운영자 세션   # 도커 운영자도 인증해야한다

# vi /etc/docker/daemon.json # 클라이언트
{ "insecure-registries":["blog.changhoon.shop:5000"] }


# systemctl restart docker

# docker run -d -P --name aws blog.changhoon.shop:5000/web-site:aws     # gcp 사설 리포지토리에 올려놓은 aws 이미지를 이용해서 운영자 서버에서 컨테이너를 띄움

# docker run -d -P --name food blog.changhoon.shop:5000/web-site:food    # food 이미지를 이용해서 컨테이너를 띄움

 

접속테스트

# docker ps

 

컨테이너 정리하기

# docker container prune     # 중지되어있는 컨테이너 모두 지우기

# docker rm -f 0abad8184638 cfb62a752597   # 실행되어있는 컨테이너 지우기

# docker rmi -f $(docker images -q)      # 이미지 아이디를 찾아서 모두 지움

5. 도커 컴포즈 명령어

# curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose  # 도커 컴포즈 실행파일을 내려받는다

# chmod +x /usr/local/bin/docker-compose   # 두 개 이상의 컨테이너를 생성해서 연동을 하는 명령어

# mkdir my_wordpress && cd $_

# vi docker-compose.yml                                       # 스크립트에 따라서 두 개 이상의 컨테이너가 생성되고 연동이 된다

version: "3.3"                                                          # 버전에 따라 매개변수가 다르다

services:

  dbserver:                                                              # 생성할 컨테이너 이름

    image: mysql:5.7                                                # 컨테이너 이미지

    volumes:                                                             # 컨테이너 마운트 경로. persistent 볼륨을 통해 백업해야한다. 원래 이렇게 해야한다. 앞에선 편법을 써서 통째로 이미지로 구워버렸음

      - db_data:/var/lib/mysql                                    # db_data는 볼륨 이름이다. 도커 컴포즈가 볼륨을 생성할 수 있다 Mountpoint 경로가 너무 길기 때문에 볼륨 이름으로 관리한다.  /var/lib/mysql은 db컨테이너 데이터가 들어있는 곳.

    restart: always                                                    # 껐다 켜져도 컨테이너가 UP하는 기능

    environment: # -e                                               # key:value형식으로 환경을 꾸밈

      MYSQL_ROOT_PASSWORD: password

      MYSQL_DATABASE: wordpress

      MYSQL_USER: wpuser

      MYSQL_PASSWORD: wppass

  wordpress:                                                             # 생성할 컨테이너 이름

    depends_on:      # 우선순위가 앞서야할 것을 적어준다. wordpress 컨테이너 실행에 앞서서 dbserver 컨테이너를 실행

      - dbserver 

    image: wordpress:latest                                       # wordpress 컨테이너 이미지

    volumes:                                                               # 도커 Host에 저장할 데이터. 컨테이너가 지워져도 복원이 쉽다

      - wordpress_data:/var/www/html

    ports: # -p 80:80                       # 포트번호를 지정하지 않으면 기본 포트로 지정된다. 

      - "8888:80"                              # Host의 포트번호를 8888로 지정한다

    restart: always                           # 껐다 켜져도 컨테이너가 실행되도록 설정

    environment:                              # 환경 변수 key:value로 정의. 앞서 dbserver컨테이너의 값들을 넣어준다 

      WORDPRESS_DB_HOST: dbserver:3306

      WORDPRESS_DB_USER: wpuser

      WORDPRESS_DB_PASSWORD: wppass

      WORDPRESS_DB_NAME: wordpress

volumes:             # 도커 컴포즈가 볼륨을 생성한다. Mountpoint를 만듦

  db_data: {}

  wordpress_data: {}

version: "3.3"    
services:
  dbserver:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment: # -e
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: wppass
  wordpress:
    depends_on:
      - dbserver
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports: # -p 80:80
      - "8888:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: dbserver:3306
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wppass
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}

 

# docker-compose up -d                      # 경로에 있는 docker-compose.yml 스크립트를 실행한다. -d 명령은 백그라운드 실행. 도커 컴포즈가 세팅되고 실행된다. 네트워크 세팅이 안되면 컨테이너 이름이 도메인처럼 안된다. 컨테이너 간에 도메인 이름을 사용하게 하기 위해 네트워크를 세팅한다. 폴더의 이름이 접두어로 달려서 이름이 생성된다


# docker-compose ps

 

접속테스트    # db와 web이 연동 작업이 끝났을 때 나오는 화면

최신 버전의 워드프레스가 잘 설치되었다

 

 


# docker-compose pause                # 2개의 컨테이너를 한 꺼번에 일시 중지(잠시 멈춤, 재개속도 빠름). stop은 전원을 끄는 것.
# docker-compose unpause

 

6. 도커 컨테이너 모니터링

# docker-compose port wordpress 80     # 컨테이너의 80포트와 연결된 포트포워드 정보가 나옴


# docker-compose config      # docker-compse 스크립트가 나온다

# docker network ls     # 생성시 네트워크 설정을 안해도 자동으로 설정되었다

# docker inspect network 09eb4354f9cf

 

 


# docker-compose stop wordpress
# docker-compose rm wordpress


# docker-compose down              # stop + rm 명령. 컨테이너를 전부 삭제. 자동으로 생성해줬던 네트워크도 삭제된다



# docker-compose down --rmi all     # 이미지까지 지우는 명령

# docker-compose down -v    # 볼륨을 지우는 명령

 

 

 

도커 컨테이너 모니터링

# 도커 컨테이너를 모니터링하는 컨테이너 생성+실행

VERSION=v0.44.0              # use the latest release version from https://github.com/google/cadvisor/releases
docker run \ 
  --volume=/:/rootfs:ro \                        # 마운트할 항목. Host : 컨테이너. 'ro'는 read only
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \             # 8080포트로 들어오면 8080포트로 포트포워딩
  --detach=true \                         # 백그라운드 실행
  --name=cadvisor \
  --privileged \                            # 권한 관련된 보안
  --device=/dev/kmsg \              # 커널의 로그 데이터를 얻기 위해서 리눅스의 스트림 다바이스 장치
  gcr.io/cadvisor/cadvisor:$VERSION          # 이미지 경로. gcr은 google cloud registry

 

VERSION=v0.44.0    # use the latest release version from https://github.com/google/cadvisor/releases
docker 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 \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  --privileged \
  --device=/dev/kmsg \
  gcr.io/cadvisor/cadvisor:$VERSION

# docker-compose up -d                 # 앞에서 다 지워버려서 다시 모니터링할 이미지, 볼륨, 컨테이너를 생성

 

 

모니터링 접속

Virtual Box 가상머신의 리소스 정보가 나온다

 

 

7. 도커스웜 실행

새로고침 연타

새로고침을 마구 하면 CPU 변화량이 요동친다

# docker-compose down    # 컨테이너가 stop+rm

# docker system df    # 컨테이너 disk크기와 마운트 정보를 가져온다

# docker system prune -a -f  # 컨테이너 네트워크을 다 정리해줌.

# free -h   # 마스터는 최소 CPU 2core에 메모리 4G여야 한다

 

도커 스웜(Cluster) 세팅

Docker Host가 마비될 수 있기 때문에 두 대 이상의 클러스터로 구성한다

 

센토스 도커 설치

# curl -fsSL https://get.docker.com/ | sh 
# yum -y install bash-completion wget unzip mysql
# curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
# systemctl enable --now docker

# poweroff

manager1이 디스크를 많이 차지하고 연결된 복제는 디스크 공간을 많이 차지하지 않는 worker1 생성. manager1이 잘못되면 마비될 수 있다. 지금은 용량을 공유해서 디스크 사용량을 작게함. 실무에선 완전한 복제 사용

똑같이 한 번 더해서 worker2를 만든다

그룹으로 묶고 가상머신 실행

 

manager1 세션

# hostnamectl set-hostname manager1

# firewall-cmd --permanent --zone=public --add-port=2377/tcp    # 서로가 통신하기 위한 2377포트를 열어준다. 매니저만 열어줌
# firewall-cmd --reload
# hostnamectl set-hostname manager1

# hostnamectl set-hostname worker1

# hostnamectl set-hostname worker2

 

MultiExec 기능
# cat <<EOF > /etc/hosts
192.168.1.166 manager1                      # 도커 main Host
192.168.1.232 worker1                         # 일꾼들로서 컨테이너들을 담고있다
192.168.1.235 worker2
EOF

# ping manager1    # manager1에서 worker1,2 서버 이름으로 핑이 나간다. host에 추가했기 때문

 

8. 도커 스웜 복제

-manager1 세션

# docker swarm init --advertise-addr 192.168.1.166  # 토큰 정보가 나온다.  

worker1,2 세션에 토큰 정보를 넣어서 연결한다
# docker swarm join --token SWMTKN-1-0cvvrx2jhzd25z6wdrsvr8nvb25iarwdwrplsbgxqtbs6xyhca-3tbwev2eszxsnb0x5ov7kk0tg 192.168.1.166:2377

-manager1 세션
# docker node ls     # 클러스터 연결이 되었다


# docker service create --name my_web --replicas 3 --publish published=8080,target=80 apeachcloud/web-site:food
# 도커허브에 저장되어있는 food.tar 이미지로 my_web 컨테이너 총 3개 만든다. published는 docker Host의 포트

최소 단위가 컨테이너가 아니고 task라고 캡슐처럼 컨테이너를 집어넣는다.

task안에 컨테이너가 여러 개 들어갈 수 있다

또 하나의 노드 안에 여러개의 task로 존재할 수 있다. 쿠버네티스에서는 task를 pod라고 부른다

Swarm manager는 task 단위로 관리한다

# docker service ls

접속테스트     # manager1, worker1, worker2 각각의 IP로 접속이 가능하다. 도커스웜 클러스터에 구축된 웹서버는 로드밸런싱이 된다. 라운드로빈 방식이 아니다. least connect 방식

 

# docker service ps my_web     # my_web 서비스 이름으로 상세내역 확인. 컨테이너 이름이 my_web.1, my_web.2, my_web.3으로 각각의 노드에 컨테이너가 생성되었고 실행 중이다

# docker service logs my_web   # 현재 쌓인 로그가 없다
# docker service inspect --pretty my_web    # pretty는 조금 더 간소화해서 보여주는 명령. Endpoint Mode:  vip 옵션이 로드밸런서 방식이다


# docker service scale my_web=6    # 수동으로 컨테이너 크기를 늘리는 명령. 생성되는 컨테이너를 task에 공평하게 분배한다 


# docker service ps my_web


# docker service rm my_web    # manager에서 제거 명령 실행