Docker Semi Project 8.29~9.1

양승현·2022년 8월 29일
2

docker

목록 보기
12/12

Proxy 를 이용한 Docker Swarm Mode 환경을 구성

구성 목표

Proxy 를 이용한 Docker Swarm Mode 환경을 구성
추가 사항

  • 저장소 : harvor 사용
  • private-registry 인증 추가
  • haproxy 사용 - 쉘 으로 사용자 요청이 들어왔을 때 클러스터 환경에 컨테이너 배포

script

클라우드 이미지 생성

- 기본 이미지 준비
    - ubuntu 18.04
    - ubuntu 20.04
    - centos7
    - centos8
- virt-builder

swarm 설치

- swarm 버전 선택
    - 20.10
    - 19.x

worker 개수 선택

- node 개수

flavor 선택

- cpu
- memory
- ex
    - cpu2, ram2 → m1.small
    - cpu2, ram4 → m1.large
    - cpu4, ram8 → m1.xlarge

disk 선택

- 10G
- 20G
- 40G

manager 접속하기 위한(터미널로) key 이름 입력

- testkey
    - public key
    - private key

virt-builder로 이미지 생성

- docker 설치

manager를 먼저 생성

- worker가 사용하기 위한 토큰 발행(docker swarm init) → local로 보냄(sh 파일로 만들어서)
- worker를 생성한 후 local에 있는 토큰 파일(token.sh)을 실행하도록 함(docker swarm join)
- testkey 넣어주기

사용자에게 manager 정보 보여주기

- ip(토큰에 있음)
- manager에 접속할 수 있는 private key 제공

auto scaling?

공통 설정 사항

hosts 설정

echo "211.183.3.99 lb " >> /etc/hosts
echo "211.183.3.100 manager " >> /etc/hosts
echo "211.183.3.101 worker1" >> /etc/hosts
echo "211.183.3.102 worker2" >> /etc/hosts

방화벽, selinux 종료

systemctl stop firewalld ; systemctl disable firewalld && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config && setenforce 0

도커, 도커 컴포즈 설치

  • yum-utils 설치
[root@manager ~]]# yum install -y yum-utils
  • yum-config-manager 를 통해서 docker 저장소 설정
[root@manager ~]]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  • 최신 버전 도커 엔진 설치
[root@manager ~]]# yum -y install docker-ce docker-ce-cli containerd.io
  • 도커 시작
[root@manager ~]]# systemctl start docker
  • 실행중인 도커 확인
[root@manager ~]]# systemctl status docker
  • Docker 서비스를 운영체제 부팅시 자동 시작하도록 설정
[root@manager ~]]# sudo systemctl enable docker
  • 도커 버전 확인
[root@manager ~]]# docker --version

한번에 설정하기

yum install -y yum-utils && yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo  && yum -y install docker-ce docker-ce-cli containerd.io && systemctl start docker && systemctl status docker && sudo systemctl enable docker && docker --version
  • 도커 컴포즈 설치
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

docker 명령 실행시 sudo 입력 없이 user1 으로 실행

vi /etc/sudoers
user1 ALL=(ALL) ALL  <-- 추가
user1 ALL=NOPASSWD: ALL  <-- 추가

groupadd docker
usermod -aG docker user1
service docker restart
reboot

manager

swarm 토큰 및 연결

  • 매니저 노드로 사용할 노드에서 swarm 시작
[root@manager ~]# docker swarm init --advertise-addr ens32
  • 토큰 재확인
[root@manager ~]# docker swarm join-token manager
  • 발행된 토큰으로 worker 연결
[root@manager ~]# docker swarm join-token worker | manager
  • 연결 확인
rapa@manager:~$ docker node ls

worker에서의 라벨 지정

  • worker에 대한 라벨을 지정해준다.
[root@manager ~]# docker node update --label-add name=worker worker1
worker1
[root@manager ~]# docker node update --label-add name=worker worker2
worker2
[root@manager ~]# docker node update --label-add name=manager manager
manager

토큰 연결 해제 및 라벨 해제

토큰 연결 해제

docker swarm leave
  • 라벨 해제
rapa@manager:~$ docker node update --label-rm zone worker

공통 사항

overlay 네트워크 구성

  • 내부 통신을 위한 overlay 네트워크를 생성한다
[root@manager ~]# docker network create --driver=overlay --attachable manager
5s8vszudf7csjqv72vw25sq26
[root@manager ~]# docker network create --driver=overlay --attachable worker1
v6o0ioocg1jpin9v183a9kv7z
[root@manager ~]# docker network create --driver=overlay --attachable worker2
ytia47kjgog1i6ufqh01yknpp

overlay 네트워크 삭제

docker network rm

main 컨테이너 생성 -manager

[root@manager test]# vi index.html
<h1>Yang Seung Hyun Page</h1>
<a href="http://211.183.3.99/velog">velog</a>
<a href="http://211.183.3.99/instagram">instagram</a>
[root@manager test]# cat Dockerfile 
FROM ubuntu:18.04

RUN apt update
RUN apt -y install apache2
ADD index.html /var/www/html
EXPOSE 80

CMD apache2ctl -D FOREGROUND
  • 이미지 생성
rapa@manager:~/0824/blue$ docker build -t main:1.0 .
  • 도커 허브 저장소에 저장
rapa@manager:~/0824/blue$ docker image tag main:1.0 211.183.3.99:8000/yang/main:1.0
rapa@manager:~/0824/blue$ docker push 211.183.3.99:8000/yang/main:1.0
  • main.yml
[root@manager test]# cat main.yml 
version: '3.7'

services: 
  apache: 
    image: 211.183.3.99:8000/yang/main:1.0
    deploy: 
      replicas: 2
      placement:
        constraints: [node.labels.name == worker]
      restart_policy: 
        condition: on-failure 
        max_attempts: 2 
    environment: 
      SERVICE_PORTS: 80 
    networks: 
      - manager 

  proxy:
    image: dockercloud/haproxy
    depends_on: 
      - apache
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:      # -p option, attached to ingress network
      - "8881:80"
    networks:   # backend network -> apache containers
      - manager        
    deploy:
      mode: global
      placement: 
        constraints: [node.labels.name == manager]      

networks: 
  manager: 
    external: true
  • 컨테이너 배포
[root@manager httpd]# docker stack deploy -c main.yml main

velog 컨테이너 생성 -worker1

[root@manager velog]# curl https://velog.io/@yange > index.html 
[root@manager velog]# cat Dockerfile
FROM ubuntu:18.04

RUN apt update
RUN apt -y install apache2
ADD index.html /var/www/html
EXPOSE 80

CMD apache2ctl -D FOREGROUND
  • 이미지 생성
[root@manager velog]# docker build -t velog:1.0 .
  • 도커 허브 저장소에 저장
[root@manager velog]# docker image tag velog:1.0 211.183.3.99:8000/yang/velog:1.0
[root@manager velog]# docker push 211.183.3.99:8000/yang/velog:1.0
  • main.yml
[root@manager velog]# cat velog.yml
version: '3.7'

services:
  apache:
    image: 211.183.3.99:8000/yang/velog:1.0
    deploy:
      replicas: 2
      placement:
        constraints: [node.labels.name == worker]
      restart_policy:
        condition: on-failure
        max_attempts: 2
    environment:
      SERVICE_PORTS: 80
    networks:
      - worker1

  proxy:
    image: dockercloud/haproxy
    depends_on:
      - apache
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:      # -p option, attached to ingress network
      - "8882:80"
    networks:   # backend network -> apache containers
      - worker1
    deploy:
      mode: global
      placement:
        constraints: [node.hostname == manager]

networks:
  worker1:
    external: true
  • 컨테이너 배포
[root@manager velog]# docker stack deploy -c velog.yml velog

instagram 컨테이너 생성 - worker2

[root@manager instagram]# vi index.html
curl <a href="https://www.instagram.com/y_seung_hyun/
">instagram</a>
[root@manager instagram]# cat Dockerfile 
FROM ubuntu:18.04

RUN apt update
RUN apt -y install apache2
ADD index.html /var/www/html
EXPOSE 80

CMD apache2ctl -D FOREGROUND
  • 이미지 생성
[root@manager instagram]# docker build -t instagram:1.0 .
  • 도커 허브 저장소에 저장
[root@manager instagram]# docker image tag instagram:1.0 211.183.3.99:8000/yang/instagram:1.0
[root@manager instagram]# docker push 211.183.3.99:8000/yang/instagram:1.0
  • instargram.yml
[root@manager instagram]# cat instagram.yml
version: '3.7'

services:
  apache:
    image: 211.183.3.99:8000/yang/instagram:1.0
    deploy:
      replicas: 2
      placement:
        constraints: [node.labels.name == worker]
      restart_policy:
        condition: on-failure
        max_attempts: 2
    environment:
      SERVICE_PORTS: 80
    networks:
      - worker2

  proxy:
    image: dockercloud/haproxy
    depends_on:
      - apache
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ports:      # -p option, attached to ingress network
      - "8883:80"
    networks:   # backend network -> apache containers
      - worker2
    deploy:
      mode: global
      placement:
        constraints: [node.hostname == manager]

networks:
  worker2:
    external: true
  • 컨테이너 배포
[root@manager instagram]# docker stack deploy -c instagram.yml instagram

컨테이너 삭제

docker rm -f $(docker container ls -qa)

LB - Harbor 설치

1. Docker 프라이빗 이미지 저장소 Harbor 설치

  • harbor 설치
curl -s https://api.github.com/repos/goharbor/harbor/releases/latest | grep browser_download_url | cut -d '"' -f 4 | grep '\.tgz$' | wget -i -
  • 압축 해제
tar -xzvf harbor-offline-installer-v2.6.0.tgz
  • harbor.yml 작성
vi harbor.yml
  5 hostname: registry.rapa.eng
 10   port: 8000
HTTPS # 주석 처리
  • 파일 명 변경
cp harbor.yml.tmpl harbor.yml
  • prepare 스크립트 실행 및 설치
./install.sh
  • 설정 파일 변경후 적용
docker-compose up -d

Harbor 연결

  • 받아오는 쪽에서 docker daemon 설정으로 insecure-registries를 해주기
[root@worker1 ~]# sudo vi /etc/docker/daemon.json
{ "insecure-registries": ["211.183.3.99:8000"] }
  • 도커 구성 업데이트
systemctl reload docker && systemctl restart docker
  • 도커 harbor 레지스트리 로그인
[root@worker1 ~]# docker login 211.183.3.99:8000

harbor 저장소 사용하기

  • 프로젝트 생성하기
  • 저장하기
[root@manager httpd]# docker build -t yang:1.0
[root@manager httpd]# docker tag yang:1.0  211.183.3.99:8000/yang/yang:2.0
[root@manager httpd]# docker push 211.183.3.99:8000/yang/yang:2.0

2. 도커 허브 연결

토큰을 통한 로그인
[user1@docker01 ~]$ echo "토큰" | docker login --username gnon5367 --password-stdin

LB - LB-HAproxy 구성

모니터링_Prometheus + CAdvisor + Grafana

  • 구성 환경
211.183.3.100 manager - (Prometheus, Grafana)
211.183.3.101 worker1 - (Node Exporter, CAdvisor)
211.183.3.102 worker2 - (Node Exporter, CAdvisor)

worker1,2 - Node Exporter, CAdvisor

# docker run -d -p 9100:9100 --name node-exporter prom/node-exporter:v0.14.0

# docker run --volume=/:/rootfs:ro \
 --volume=/var/run:/var/run:rw \
 --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 \
 google/cadvisor:v0.27.0

manager - prometheus

  • prometheus.yml
global:
    scrape_interval: 5s
    external_labels:
        monitor: 'my-monitor'
scrape_configs:
    - job_name: 'node-exporter'
      static_configs:
          - targets: ['211.183.3.101:9100', '211.183.3.102:9100']
  • prometheus-cadvisor.yml
global:
    scrape_interval: 5s
    external_labels:
        monitor: 'my-monitor'
scrape_configs:
    - job_name: 'node-exporter'
      static_configs:
          - targets: ['211.183.3.101:8080', '211.183.3.102:8080']

scripts

create scripts

rapa@seunghyun:~/project/network$ vi create_network.sh

echo -n " ###### Build new image 
ex)docker_username port image_name version :"
read docker_username port db_image_name version

docker build --tag ${docker_username}:${port}/${db_image_name}:${version}


#!/bin/bash
echo -n "network overlay create : "
read name
docker network create -d overlay $name

remove scripts

[root@manager scripts]# cat remove.sh
#!/bin/bash
clear
echo -e "###########삭제 프로그램##########"
echo
echo "무엇을 삭제할지 결정해주세요"
echo "1. 컨테이너 삭제"
echo "2. 네트워크 삭제"
echo "3. 이미지 삭제"
echo "4. 프로그램 종료"

echo -n "삭제할 번호를 입력하세요 : "
read number

if [ -z  $number ]
then
        clear
        echo " 선택하지 않았습니다"
        sh remove.sh
elif [ $number -eq 1 ]
then
        clear
        echo -e "컨테이너 삭제하기"
        echo -n "동작중인 컨테이너"
        echo
        docker stack list
        echo -n "컨테이너 이름을 입력하세요 : "
        read stack
        docker stack rm $stack /dev/null 2>&1
        sh remove.sh
elif [ $number -eq 2 ]
then
        clear
        echo -e "네트워크 삭제하기"
        echo
        docker network ls
        echo -n "네트워크 이름을 입력하세요 :"
        read network_name
        docker network rm $network_name /dev/null 2>&1
        sh remove.sh
elif [ $number -eq 3 ]
then
        clear
        echo "무엇을 삭제할지 결정해주세요"
        echo "1. 모든 이미지  삭제"
        echo "2. 선택한 이미지  삭제"

        echo -n "삭제할 번호를 입력하세요 : "
        read number3

        if [ -z  $number3 ]
        then
        echo " 선택하지 않았습니다."
        echo " 종료합니다."
        exit
        elif [ $number3 -eq 1 ]
        then
                echo -e "전체 이미지를 삭제합니다."
                docker rmi $(docker images -q) --force > /dev/null 2>&1
                clear
                sh remove.sh
        elif [ $number3 -eq 2 ]
        then
                echo -e "이미지 삭제하기"
                docker images -a
                echo -n "이미지 이름을 입력하세요 : "
                read image_name
                echo -n "이미지 태그를 입력하세요 : "
                read image_tag
                docker rmi -f $image_name:$image_tag > /dev/null 2>&1
                sh remove.sh
        else
                echo "번호를 잘못입력하였습니다. "
                echo "종료합니다."
                exit
        fi
elif [ $number -eq 4 ]
then
        clear
        echo -e "프로그램을 종료합니다."
        exit
else
        clear
        echo "번호를 잘못입력하였습니다. "
        echo "번호를 다시입력해주세요"
        sh remove.sh
fi

9/4 -> 개인메뉴
ppt -> pdf로 전환
demo 영상 3분 ~ 5분

0개의 댓글