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
- 매니저 노드로 사용할 노드에서 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 네트워크를 생성한다
[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
[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
- 구성 환경
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']
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분