
→ docker vm위에 올린 app과 docker2 vm위에 올린 mydb를 연결하는 것이다.
→ docker vm의 app은 도커 파일로 이미지 빌드할 수 있다.
→ 이미지 빌드하면서 mydb를 바라보도록 설정해주면 mydb와 연동할 수 있다.
포트 포워딩!
첫번째 vm에 80포트로 들어오면 myapp의 5000포트로 들어갈 수 있도록 포트포워딩!
(포트포워딩 테이블 존재)
sudo docker run -d -p 80:5000 \
--name myapp \
--add-host db-svc:DB의IP \
ekchoi3912/myapp:v1
# 여기에서 DB의 IP 주소는 docker2에서 ip a 명령어를 통해 알수 있다.
# DB는 같은 리전의 인스턴스 위에서 동작하고 있으므로 내부 ip 주소로 통신 가능하다!
# DB 컨테이너를 포함하고 있는 docker2 vm 인스턴스 내부 ip 주소를 (DB의IP)에 입력해준다.
포트 포워딩!
도커 host 안에 있는 컨테이너는 외부에서 접근 불가능함
따라서 외부에서 접근하기 위해서는 포트포워딩을 통해 외부에 노출시켜줘야 함
chohyeon1208@docker2:~$ docker run -d --name mydb -p 3306:3306 ekchoi3912/mydb:v1
베이스 이미지는..!
# 베이스 이미지 설정
FROM python:3.8
docker run -d -p 80:5000 --name myapp --add-host db-svc:10.128.15.213 app
파이썬을 image pull해오면 밑 os로 데비안이 자동으로 따라옴
1) docker vm 내부 컨테이너 중 myapp 컨테이너 app.py 안에 mysql db 관련한 설정이 변수인 db-svc로 들어 이있음.
2) myapp 컨테이너를 docker run 즉 프로세스로 실행시켜줄 때 —add-host db-svc=db ip 라는 옵션을 추가해주면 변수에 value를 넣어주는 것과 같다!
3) ip주소는 가변성이 크기 때문에 코드는 되도록이면 변수로 작성해주는 것이 좋다!
4) myapp 컨테이너는 도커 파일을 토대로 빌드했고, 빌드한 내용 중 app.py가 있기 때문에 이 파일 안의 내용으로 빌드되었다.
→ docker vm에 build 해놓은 app 이미지를 도커 허브 - 나의 레파지토리에 push 해놓아야 두번째 실습의 환경 구축이 쉽다.

→ docker vm에 실행되고 있던 프로세스와 빌드되어 있던 이미지를 모두 삭제한다.
(첫번째 실습에서 프로세스화 했던 myapp이 포트포워딩으로 80:5000에서 실행되고 있기 때문이다.)
→ 반드시 haproxy를 프로세스화 하기 전에 myapp이 db와 연동될 수 있게 만들어줘야 한다.
(myapp은 flask로 만들어졌으므로 5000번 포트에서 동작한다.)
→ 이 haproxy 또한 도커 파일로 image build 해준다.
💡 ⚡ 주의할 점 - IP 주소⚡
**IP주소는 가변적이기 때문에 IP주소 대신 변수로 코드를 작성한 다음,
**이미지 빌드하거나 프로세스화(docker run) 시켜줄 때 변수에 value 값을 넣어주자!
포트포워딩의 기능 살펴보기!
포트포워딩은 어느 상황에서 사용해야 하는지!
여기에서 우리가 이 실습을 진행하는 이유는 vm 인스턴스 외부 네트워크의 host가 vm 인스턴스 내부 네트워크의 vm의 컨테이너!!에 진입할 수 있는지 보기 위함이다.
즉, 외부에서 vm 인스턴스 위에 올라가 있는 컨테이너에 접근하는 방법을 보기 위함이다
→ 포트포워딩 사용
(동일 vm 내에 app 컨테이너와 db 컨테이너를 모두 프로세스화 시켜주면, 내부 네트워크로 통신 가능하다!! → 포트포워딩 필요 없음)
**docker rm -f $(docker ps -a -q)** # 컨테이너 모두 삭제
**docker rmi -f $(docker images -q)** # 로컬 이미지 모두 삭제

→ 컨테이너와 이미지 아무 것도 남아 있지 않은 것을 볼 수 있다.
docker ps -a # 모든 컨테이너 확인
docker images # 로컬에 저장되어 있는 이미지 확인
이때, db와 연동시켜 프로세스화 시킨다.
(myapp1, myapp2)
docker run -d --name myapp1 --add-host db-svc:10.128.15.213 chohyeon1208/test:app
docker run -d --name myapp2 --add-host db-svc:10.128.15.213 chohyeon1208/test:app

Dockerfile
## Dockerfile
# 베이스 이미지로 HAProxy 공식 이미지를 사용
FROM haproxy:latest
# HAProxy 설정 파일을 컨테이너로 복사
COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
# HAProxy 포트 (기본: 80, 443)을 노출
EXPOSE 80 443
# HAProxy를 포어그라운드 모드로 실행
CMD ["haproxy", "-f", "/usr/local/etc/haproxy/haproxy.cfg"]
haproxy.cfg → 맨 마지막 줄은 무조건 빈 행으로 두기!
(cfg 파일은 개행으로 명령이 끝남을 정함,,이라고 하는데 확실하지 않음)
## haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
daemon
maxconn 256
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
default_backend servers
backend servers
balance roundrobin
server server1 web1:5000 check
server server2 web2:5000 check
💡 Dockerfile로 이미지 빌드는 반드시 Dockerfile이 존재하는 디렉토리에서 실행!!

→ Dockerfile image build는 반드시 Dockerfile이 존재하는 디렉토리에서 실행해야하기 때문에
해당 경로로 가서 Dockerfile이 있는지 확인하고 이미지 빌드하자!
docker build -t haproxy .
## 주의 해야하는 것!! 마지막 점!!
## 이미지 빌드 경로 주의하기!!

→ haproxy image build가 완료된 것을 볼 수 있다.
docker inspect bridge

docker run -d -p 80:80 --name proxy --add-host web1:172.17.0.2 --add-host web2:172.17.0.3 haproxy

docker vm의 외부 IP 주소를 url 창에 입력한다.
http의 기본 포트는 80이므로 따로 포트를 입력할 필요는 없다.

→ haproxy 컨테이너를 통해
→ myapp1으로 연결되는 것을 볼 수 있다.

→ haproxy 컨테이너를 통해
→ myapp2로 연결되는 것을 볼 수 있다.
컨테이너를 외부에 노출시키기
= 외부에서 vm 인스턴스 내부에 있는 컨테이너에 접근 가능하게 만들어준다.
💡 도커 host 안에 있는 컨테이너는 외부에서 접근 불가능하다.
→ 따라서 외부에서 접근하기 위해서는 포트포워딩을 통해 외부에 노출시켜줘야 한다.
포트는 문을 열어둔 채로 기다리고 있다고 생각하면 된다.
예를 들어 myapp이라는 컨테이너가 5000번 포트에서 동작한다는 뜻은, 5000번 포트를 열고 기다리고 있다는 뜻이다.
Dockerfile build = image build
다른 사람이 내가 만든 dockerfile로 image build해도 올바른 경로에 이미지가 build 되도록 하기 위해서 작업 디렉토리를 설정
→ 도커 네트워크 ????????
제공한다.
웹 애플리케이션의 부하 분산과 TCP/HTTP 기반의 로드 밸런싱 기능을 제공한다.
haproxy.cfg 파일의 backend server 부분을 보면 알 수 있다.
내가 진행한 실습에서는 round robin으로 부하 분산 기능을 만들어줬다.
→ docker commit은 원래 있던 이미지로만 새로운 이미지를 build할 수 있고,
→ Dockerfile을 이용한 image build는 완전히 새로운 이미지도 build할 수 있다.
💡 단, 여기에서 주의할 점은
docker commit으로 이미지를 build할 경우, 기존의 컨테이너가 실행 중이어야 한다.
실행 중인 컨테이너의 상태가 캡쳐되어 새로운 이미지가 만들어지기 때문이다.
haproxy.cfg 파일의 마지막 줄은 비어있는 줄로 둬야 한다.
haproxy.cfg 파일의 옵션(?)은 개행을 기준으로 실행되기 때문이다.
→ 따라서 haproxy.cfg 파일의 마지막 문단을 실행하기 위해서는 맨 마지막 줄을 비워둬야 한다.
--add-host 옵션 사용 이유프로세스화(docker run) 해주는 컨테이너 내에서 호스트 명과 IP 주소의 매핑을 위해 사용한다.
IP주소는 가변적이기 때문에 IP주소 대신 변수로 코드를 작성한 다음,
**이미지 빌드하거나 프로세스화(docker run) 시켜줄 때 변수에 value 값을 넣어준다.**