( 참고 : 알면 더 쉬운 도커 쿠버네티스 (곽영호, 황승준) )

2. 실무에 바로 쓰는 도커 (3)

Contents

  • 2-5. 네트워크
  • 2-6. Infra as Code
  • 2-7. 도커의 한계점


2-5. 네트워크

a) 네트워크의 종류

[ 1. 브릿지 모드 ]

  • docker network의 default 설정


[46] 브릿지 모드 확인 ( = docker 0 )

ip addr show docker0
  • 컨테이너들이 통신하는데에 필요한 가상 Linux bridge

    • bridge를 통해 서로 독립적인 네트워크를 형성해줌
    • 1) container들 간의 통신
    • 2) 외부 host 서버와의 통신
  • 여기에 나오는 3:docker이 docker가 점유하고 있는 네트워크 인터페이스

    ( docker 설치 시 기본적으로 생성됨 )


[47] 도커 bridge에 대한 상세 정보

docker network inspect bridge


IP가 어떻게 할당되는지 실습!

  • 우선, Nginx & MySQL 오피셜 image에 “iconfig 명렁어 추가”한 image 생성하기

    ( 기본 오피셜 image에는 iconfig 명령어 X )

  • 아래의 2개의 docker file 생성하기

    FROM nginx:latest
    RUN apt-get update
    RUN apt-get install -y net-tools
    RUN apt-get install -y iputils-ping
    
    FROM mysql:5.7.8
    RUN apt-get update
    RUN apt-get install -y net-tools
    RUN apt-get install -y iputils-ping
    


[48] docker file로 docker image 빌드하기

docker build -t mysql-custom .
docker build -t nginx-custom .


[49] image가 잘 생성된 것을 확인

docker images


[50] docker container (mysql-custom) 실행하기

docker run --name db -e MYSQL_ROOT_PASSWORD=1234 -p 3306:3306 -d mysql-custom


[51] db 컨테이너 안에서, ifconfig 명령어 실행

docker exec db ifconfig eth0
  • 확인 결과, IP가 172.17.02로 할당됨

  • container & host간의 통신 잘 되는 것 확인하기 위해

    ping -c 3 172.17.0.2
    

    \(\rightarrow\) (bridge network를 사용하여) db container & HOST 통신 되는 것 확인함


[52] docker container (nginx-custom) 실행하기

docker run --name nginx -p 80:80 -d nginx-custom


[51] nginx 컨테이너 안에서, ifconfig 명령어 실행

docker exec nginx  ifconfig eth0
  • 확인 결과, IP가 172.17.03로 할당됨

  • container & container 통신 잘 되는 것 확인하기 위해

    docker exec -it nginx ping -c 3 172.17.02
    

    \(\rightarrow\) (bridge network를 사용하여) nginx container & db container 통신 되는 것 확인함


의문점 : IP 자동할당 ? 고정은..??

  • 우선, 위의 172.17.02 & 172.17.03 모두 고정 IP가 아니다
  • 그렇다면.. IP 사용안하고 통신할 수는 없을까?
    • 방법 1) link 옵션 사용하기
    • 방법 2) 사용자가 직접 정의한 bridge


[52] link 사용해서 통신하기

docker run --name nginx1 --link nginx:nginx -d nginx-custom
  • nginx1라는 컨테이너를 “생성할 때”, nginx라는 컨테이너와 통신할 수 있게끔!


[53] 통신 잘 됨을 확인

docker exec nginx1 ping -c 3 nginx


[54] 컨테이너의 hosts 파일 확인하기

  • link 사용 시, 컨테이너의 hosts 파일에 해당 DNS를 추가함

  • nginx가 hosts 파일에 추가된 것 확인 가능!

docker exec nginx1 cat /etc/hosts


방법 2) 사용자가 직접 정의한 bridge

[55] 사용자가 직접 bridge 만들기

  • bridge 명 : my-bridge
docker network create my-bridge


[56] 네트워크 list 확인하기

docker network ls


[57] (기본 bridge가 아닌) 직접 만든 네트워크 사용하여, container 2개 생성 & 통신하기

  • --network 브릿지명
docker run --name nginx2 --network my-bridge -d nginx-custom
docker run --name nginx3 --network my-bridge -d nginx-custom


[58] nginx2 & nginx3이 서로 통신 잘 됨을 확인

docker exec nginx2 ping -c 3 nginx3


[ 2. host 모드 ]

네트워크를 host 모드로 실행 시,

별도의 독자적 network를 가지지 않고, host와 network 같이 사용


[59] host 모드로 container 실행하기

docker run --name nginx4 --net=host -d nginx-custom


[60] 잘 실행되었나 확인하려 했으나, EXIT 상태!

이유는..?

docker ps -a


[61] Container 로그 우선 확인해보자!

docker logs -f nginx4

이유 : 80번 포트를 이미 누가 사용 중!

( 참고 : --net=host 사용 시, -p 옵션은 사용 불가 …. docker image에 명시된 기본 포트 (80) 밖에 사용 불가 )


[62] 80번 포트 사용하고 있는 container 삭제 후, 다시 명령 실행

docker ps
docker stop nginx
docker start nginx4
docker ps


(요약)

  • bridge 모드 = 각각의 container에 각각의 IP 발급
  • host 모드 = host와 동일한 네트워크 사용 ( = IP 할당 안됨 )


[ 3. container 모드 ]

참조하는 container와 동일하게 네트워크를 구성


[63] (container 모드를 사용하여) 컨테이너 실행하기

  • 1번째 container ( db )

    docker run --name db -e MYSQL_ROOT_PASSWORD=1234 -p 3306:3306 -d mysql-custom
    
  • 2번째 container ( nginx )

    • 1번째 db container를 참조하여, 동일하게 네트워크를 구성함
    docker run --name nginx --net=container:db -d nginx-custom
    


[64] Network interface 조회하기

  • 아래 2개의 container의 IP가 서로 같음을 확인!
docker exec db ifconfig eth0
docker exec nginx ifconfig eth0


[ 4. none 모드 ]

  • 옵션 : -net=none

  • 통신에 필요한 network interface 없음


[64] (none 모드로) container 실행하기

docker run --name=nginx --net=none -d nginx-custom


[65] 외부와 연결되는 interface 없음을 확인

docker exec nginx ifconfig


2-6. Infra as Code

Infra를 코드로 관리하면 좋은점

  • 서버에 무엇이 있는지 코드로도 알 수 있다!


지금까지는, 서비스를 운영하기 위해…

  • step 1) 서버에 무언가 설치
  • step 2) 개발한 소스가 돌아갈 수 있게 끔!
  • step 3) 잘 돌아가면, 서비스 시작


누군가가 서버에 프로그램 설치 후, 시간 지나면 트래킹 hard…. ( 퇴사, 담당자 변경 … )

BUT, 개발 시 SCM 프로그램 ( ex. Git, Svn )을 활용하면 쉽게 파악 가능!

\(\rightarrow\) 인프라를 코드로 관리하자!!


지금까지 살펴본 docker의 도커 이미지 파일 내에도, 인프라에 대한 부분이 존재!


[66] docker file 예시

FROM openjdk:8-jdk-alpine
ADD docker/target/docker-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom",
"-Dspring.profiles.active=dev","-jar","/app.jar"]
  • 위에 이미 인프라에 대한 정보 O
    • line 1) openjdk8 버전
    • line 2) 컨테이너 최상위/폴더 위치에 app.jar 파일 복사
  • 위를 통해, 인프라에 설치해야 할 자바 버전 & 빌드된 파일 뭉치의 위치 & 자바 실행 방법 모두 파악 가능!


지금 까지 했던 것들 중, code화 되지 않은 것은?

\(\rightarrow\) 인프라 자체를 새로 구축할 때도, 수작업 대신 코드화…??


나중에, 옵션에 어떠한 값을 넣고 실행했었는지 파악 어려울수 있으므로…

이런 상황 방지 위해 docker-compose.yml을 사용하자!


a) docker-compose

docker compose

  • container를 실행하는 명령어를 docker-compose.yml 파일에 뫃아놓자!
  • 직접 명령어 실행하지 말고, docker-compose 실행 구문 통해 실행하자!


[67] docker-compose.yml 파일

  • 아래와 같은 소스코드에 container 실행 명령문들 넣기!
version:'3.3'
services:
 app1:
 	image : springboot
 	ports :
 	 - 8080:8080
 	container_name:app1
 mysql:
 	image: mysql:5.7
 	environment :
 	 - MYSQL_ROOT_PASSWORD=1234
 	 - TZ=Asia/Seoul
 	container_name: mysql
 	prots:
 	 - 3306:3306


[68] 위를 실행하려면, docker-compose를 설치해야!

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$$(uname -s)-$$(uname -m)" -o /usr/local/bin/docker-compose


[69] docker-compose 사용을 일반 유저에게도 권한 부여

sudo chmod +x /usr/local/bin/docker-compose


[70] docker-compose 사용하여 컨테이너들 실행하기

docker-compose up -d


[71] 상태 확인하기

docker-compose ps


위처럼, docker-copomse를 사용하여 인프라를 코드화!

  • 컨테이너가 많아져도 OK
  • 실행 구문 따로 저장/관리 필요 X
  • 배포할때 매우 좋아~


배포할때 특히 좋은 이유?

  • 이미지 업데이트 되고 명령어 다시 실행할 경우, 베이스 이미지가 변경된 컨테이너는 자동 삭제되고 컨테이너가 다시 생성됨

  • docker-compose up -d 실행 시…

    내부적으로 아래와 같은 순서로 명령문이 실행되는 꼴!

    1) docker stop app1
    2) docker rm app1
    3) docker run --name app1 -p 8080:8080 -d springboot
    


네트워크 부분 또한 설정할 수 있음!

앞서 말했 듯, 고정 IP가 아니라 컨테이너 명으로 연결해야! ( bridge 네트워크 말고 다른거 이용하고프면 )

새 bridge 네트워크 생성 또한 docker-compose에서 지원한다!

version:'3.3'
services:
 app1:
 	image : springboot
 	ports :
 	 - 8080:8080
 	container_name:app1
 	networks :
 	 - mynetwork
 mysql:
 	image: mysql:5.7
 	environment :
 	 - MYSQL_ROOT_PASSWORD=1234
 	 - TZ=Asia/Seoul
 	container_name: mysql
 	ports:
 	 - 3306:3306
	networks :
 	 - mynetwork

networks:
 mynetwork:


2-7. Docker의 한계

a) Docker만으로 구성된 Infra의 문제점

서비스 사용자가 갑자기 증가하여, HOST 서버의 규모를 확대해야 한다면…?

\(\rightarrow\) HOST 서버 성능 스케일업 & 도커 설치 & 컨테이너 다시 실행

BUT, what if 일시적 현상…? 단순히 다운그레이드…? ㅠㅠ

( 최근에 클라우드 회사들은 “도커 사용 않고”, 인프라를 유연하게 조절할 수 잇는 솔루션 제공 )


따라서 도커 오케스트레이션 툴도 잘 알아놔야!


b) Docker Orchestration

여러 개의 HOST를 마치 단일 HOST 처럼 묶는 효과!

  • ex) 도커 스웜, 쿠버네티스, 랜처, 메소스