본문 바로가기
공부/웹해킹

3주차 과제

by suyeon27 2023. 11. 24.

Docker : 애플리케이션을 개발, 제공 및 실행하기 위한 개방형 플랫폼
'컨테이너'라고 하는 느슨하게 격리된 환경에서 애플리케이션을 패키징하고 실행하는 기능을 제공
격리 및 보안을 통해 특정 호스트에서 동시에 많은 컨테이너를 실행 할 수 있다.
컨테이너는 가볍고 애플리케이션을 실행하는 데 필요한 모든 것을 포함하므로 호스트에 설치된 것에 의존할 필요가 없다.
Go 프로그래밍 언어로 작성되었다.

 

Docker를 사용하면
1. 애플리케이션을 인프라에서 분리하여 소프트웨어를 신속하게 제공
2. 애플리케이션을 관리하는 것과 동일한 방식으로 인프라를 관리
3. 코드 작성과 프로덕션 환경 실행 사이의 지연 시간을 크게 줄임

Docker는 컨테이너의 수명주기를 관리하기 위한 도구와 플랫폼을 제공
1. 컨테이너를 사용하여 애플리케이션과 지원 구성 요소를 개발
2. 컨테이너는 애플리케이션을 배포하고 테스트하기 위한 단위
3. 프로덕션 환경이 로컬 데이터 센터, 클라우드 공급자 또는 이 둘의 하이브리드인지 여부에 관계없이 동일하게 작동

Docker를 어떤 용도로 사용할 수 있나요?
1. 빠르고 일관된 애플리케이션 제공
Docker는 개발자가 애플리케이션과 서비스를 제공하는 로컬 컨테이너를 사용하여 표준화된 환경에서 작업할 수 있도록 하여 개발 수명 주기를 간소화한다.

2. 반응형 배포 및 확장
Docker의 컨테이너 기반 플랫폼은 이식성이 뛰어난 워크로드를 허용
Docker 컨테이너는 개발자의 로컬 노트북, 데이터 센터의 물리적 또는 가상 머신, 클라우드 공급자 또는 혼합된 환경에서 실행 할 수 있다.
비즈니스 요구에 따라 애플리케이션과 서비스를 거의 실시간으로 확장하거나 축소 할 수 있다.

3. 동일한 하드웨어에서 더 많은 워크로드 실행
하이퍼바이저 기반 가상 머신에 대한 실행 가능하고 비용 효율적인 대안을 제공하므로 더 많은 서버 용량을 사용하여 비즈니스 목표를 달성할 수 있다.
Docker는 더 적은 리소스로 더 많은 작업을 수행해야 하는 고밀도 환경과 중소형 배포에 적합

도커 아키텍처
Docker는 클라이언트-서버 아키텍처를 사용
Docker 클라이언트는 Docker 컨테이너를 구축, 실행 및 배포하는 무거운 작업을 수행하는 Docker 데몬과 통신
Docker 클라이언트와 데몬은 동일한 시스템에서 실행될 수 있으며, Docker 클라이언트를 원격 Docker 데몬에 연결할 수 있다.
Docker 클라이언트와 데몬은 UNIX 소켓 또는 네트워크 인터페이스를 통해 REST API를 사용하여 통신한다.

또 다른 Docker 클라이언트는 Docker Compose로, 이를 통해 컨테이너 세트로 구성된 애플리케이션으로 작업할 수 있다.

도커 데몬
Docker 데몬( dockerd)은 Docker API 요청을 수신하고 이미지, 컨테이너, 네트워크, 볼륨과 같은 Docker 개체를 관리한다.

데몬은 Docker 서비스를 관리하기 위해 다른 데몬과 통신할 수도 있다.

도커 클라이언트
Docker 클라이언트( docker)는 많은 Docker 사용자가 Docker와 상호 작용하는 기본 방법이다. 

docker run클라이언트는 이러한 명령을 에 보내고 dockerd이를 수행한다. 이 docker명령은 Docker API를 사용

Docker 클라이언트는 둘 이상의 데몬과 통신할 수 있다.

도커 데스크탑
Docker Desktop은 컨테이너화된 애플리케이션과 마이크로서비스를 구축하고 공유할 수 있는 Mac, Windows, Linux 환경을 위한 설치가 쉬운 애플리케이션이다.
Docker Desktop에는 Docker 데몬( dockerd), Docker 클라이언트(docker), Docker Compose, Docker Content Trust, Kubernetes 및 자격 증명 도우미가 포함되어 있다.

도커 레지스트리
Docker 레지스트리는 Docker 이미지를 저장
docker pull또는 명령을 사용하면 docker runDocker는 구성된 레지스트리에서 필요한 이미지를 가져온다.

명령을 사용하면 docker pushDocker는 이미지를 구성된 레지스트리에 푸시한다.

도커 객체
Docker를 사용하면 이미지, 컨테이너, 네트워크, 볼륨, 플러그인 및 기타 객체를 생성하고 사용하게 된다. 

이미지
이미지는 Docker 컨테이너를 생성하기 위한 지침이 포함된 읽기 전용 템플릿
이미지를 기반으로 하는 이미지를 빌드할 수 ubuntu 있지만 Apache 웹 서버와 애플리케이션은 물론 애플리케이션을 실행하는 데 필요한 구성 세부 정보도 설치된다.

컨테이너
컨테이너는 실행 가능한 이미지 인스턴스입니다. Docker API 또는 CLI를 사용하여 컨테이너를 생성, 시작, 중지, 이동 또는 삭제할 수 있다.

컨테이너를 하나 이상의 네트워크에 연결하거나, 컨테이너에 스토리지를 연결하거나, 현재 상태를 기반으로 새 이미지를 생성할 수도 있다.
기본적으로 컨테이너는 다른 컨테이너 및 해당 호스트 시스템과 비교적 잘 격리되어 있다.

컨테이너의 네트워크, 스토리지 또는 기타 기본 하위 시스템이 다른 컨테이너 또는 호스트 시스템으로부터 얼마나 격리되는지 제어할 수 있다.
컨테이너는 해당 이미지와 컨테이너를 생성하거나 시작할 때 제공하는 구성 옵션으로 정의된다.

컨테이너가 제거되면 영구 저장소에 저장되지 않은 상태에 대한 모든 변경 사항이 사라진다.

docker 실행 명령 예
다음 명령은 ubuntu컨테이너를 실행하고, 로컬 명령줄 세션에 대화형으로 연결하고, 를 실행한다 /bin/bash.

 docker run -i -t ubuntu /bin/bash
이 명령을 실행하면 다음이 발생(기본 레지스트리 구성을 사용한다고 가정).

 

docker pull ubuntu
로컬에 이미지가 없으면 ubuntuDocker는 마치 수동으로 실행한 것처럼 구성된 레지스트리에서 이미지를 가져온다.

 

docker container create 
Docker는 마치 명령을 수동으로 실행한 것처럼 새 컨테이너를 생성한다

Docker는 컨테이너에 읽기-쓰기 파일 시스템을 최종 레이어로 할당한다.

이를 통해 실행 중인 컨테이너는 로컬 파일 시스템에서 파일과 디렉터리를 생성하거나 수정할 수 있다.

네트워킹 옵션을 지정하지 않았으므로 Docker는 컨테이너를 기본 네트워크에 연결하기 위한 네트워크 인터페이스를 생성한다. 여기에는 컨테이너에 IP 주소를 할당하는 작업이 포함된다. 기본적으로 컨테이너는 호스트 머신의 네트워크 연결을 사용하여 외부 네트워크에 연결할 수 있다.

Docker는 컨테이너를 시작하고 /bin/bash. -i컨테이너는 대화형으로 실행되고 터미널에 연결되므로( 및 플래그 로 인해 -t ) Docker가 출력을 터미널에 기록하는 동안 키보드를 사용하여 입력을 제공할 수 있다.

exit명령을 종료하기 위해 실행하면 /bin/bash컨테이너가 중지되지만 제거되지는 않는다.

다시 시작하거나 제거할 수 있다.


1부: 개요
컨테이너란 무엇입니까?
해당 호스트 시스템에서 실행되는 다른 모든 프로세스와 격리된 호스트 시스템에서 실행되는 샌드박스 프로세스

컨테이너는 다음을 수행
1. 실행 가능한 이미지 인스턴스. Docker API 또는 CLI를 사용하여 컨테이너를 생성, 시작, 중지, 이동 또는 삭제
2. 로컬 머신, 가상 머신에서 실행하거나 클라우드에 배포
3. 이식 가능하며 모든 OS에서 실행
4. 다른 컨테이너와 격리되어 자체 소프트웨어, 바이너리, 구성 등을 실행

이미지란 무엇입니까?
실행 중인 컨테이너는 격리된 파일 시스템을 사용한다. 이 격리된 파일 시스템은 이미지에 의해 제공되며 이미지에는 애플리케이션을 실행하는 데 필요한 모든 것(모든 종속성, 구성, 스크립트, 바이너리 등)이 포함되어야 한다. 또한 이미지에는 환경 변수, 기본 명령과 같은 컨테이너에 대한 다른 구성도 포함되어 있다. 실행 및 기타 메타데이터.

 


2부: 애플리케이션 컨테이너화

Docker 및 Windows에 Docker Desktop 설치

 

1. Windows PowerShell을 관리자 권한으로 실행 후 WSL2 설치

WSL : Windows 환경에서 Linux 환경 사용

WSL 설치 후 재부팅

 

WSL 정보 확인, 설치된 배포판과 설정된 버전 확인

 

2. Docker Desktop 설치 후 Docker 동작 확인

httpd 이미지 다운로드

 

Docker Desktop - Images 에서 다운로드한 httpd 이미지 확인

 

httpd 컨테이너 실행

 

Docker Desktop - Containers 에서 httpd-test 컨테이너 확인

 

3. 이전 명령어로 호스트의 8080 포트와 컨테이너의 80 포트를 연결하였기 때문에 아래의 결과 화면이 나온다.

localhost:8080 접속

 

 

이미지를 빌드하려면 Dockerfile(텍스트 기반 파일)을 사용해야 한다.
Docker는 스크립트를 사용하여 컨테이너 이미지를 빌드한다.

docker run명령을 사용하면 컨테이너에서 애플리케이션을 실행할 수 있다.

$ docker run -dp 127.0.0.1:3000:3000 getting-started
플래그 -d( 의 약어 --detach)는 백그라운드에서 컨테이너를 실행합니다. 플래그 -p(의 줄임말 --publish)는 호스트와 컨테이너 간의 포트 매핑을 생성합니다. 플래그 -p는 형식의 문자열 값을 사용합니다 HOST:CONTAINER. 여기서 HOST는 호스트의 주소이고 는 CONTAINER컨테이너의 포트입니다. 이 명령은 컨테이너의 포트 3000을 호스트의 127.0.0.1:3000( )에 게시합니다. localhost:3000포트 매핑이 없으면 호스트에서 애플리케이션에 액세스할 수 없습니다.

 


3부: 애플리케이션 업데이트
$ docker build -t getting-started .
업데이트된 버전의 이미지를 빌드

$ docker run -dp 127.0.0.1:3000:3000 getting-started
업데이트된 코드를 사용하여 새 컨테이너를 시작

CLI를 사용하여 컨테이너 제거
$ docker ps
컨테이너의 ID를 가져옴.

$ docker stop <the-container-id>
docker stop컨테이너를 중지
<the-container-id>의 ID로 바꿈

$ docker rm <the-container-id>
컨테이너가 중지되면 docker rm명령을 사용하여 제거

업데이트된 앱 컨테이너 시작
$ docker run -dp 127.0.0.1:3000:3000 getting-started
업데이트된 앱을 시작

 


4부: 애플리케이션 공유
Docker 이미지를 공유하려면 Docker 레지스트리를 사용해야 한다.
기본 레지스트리는 Docker Hub이며 사용한 모든 이미지의 출처이다.

$ docker push docker/getting-started
docker pushDocker Hub에 표시되는 명령을 실행

$ docker tag getting-started YOUR-USER-NAME/getting-started
명령을 사용하여 Docker Hub에 로그인

$ docker push YOUR-USER-NAME/getting-started
docker push명령을 다시 실행

 


5부: DB 유지
컨테이너가 실행되면 파일 시스템에 대한 이미지의 다양한 레이어를 사용한다.

컨테이너에는 파일을 생성/업데이트/제거하기 위한 자체 "스크래치 공간"이 있으며,
동일한 이미지를 사용하더라도 다른 컨테이너에는 변경 사항이 표시되지 않는다.

$ docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
1에서 10000 사이의 임의의 숫자로 ubuntu이름이 지정된 파일을 생성하는 컨테이너를 시작

$ docker exec <container-id> cat /data.txt
컨테이너의 터미널에 액세스하여 출력을 볼 수 있는지 확인

$ docker run -it ubuntu ls /
콘텐츠를 가져온다.

$ docker rm -f <container-id>
첫 번째 컨테이너를 제거

볼륨은 컨테이너의 특정 파일 시스템 경로를 호스트 시스템에 다시 연결하는 기능을 제공한다.
컨테이너에 디렉터리를 탑재하면 해당 디렉터리의 변경 사항이 호스트 시스템에도 표시된다.

$ docker volume create todo-db
명령을 사용하여 볼륨을 생성

$ docker run -dp 127.0.0.1:3000:3000 --mount type=volume,src=todo-db,target=/etc/todos getting-started
todo 앱 컨테이너를 시작하고 --mount볼륨 마운트를 지정하는 옵션을 추가, 볼륨에 이름을 지정하고 /etc/todos컨테이너에 마운트하면 경로에서 생성된 모든 파일이 캡처된다.

 


6부: 바인드 마운트 사용
볼륨 마운트는 애플리케이션 데이터를 저장할 영구적인 어딘가가 필요할 때 사용
바인드 마운트는 호스트 파일 시스템의 디렉터리를 컨테이너에 공유할 수 있는 또 다른 유형의 마운트
애플리케이션 작업 시 바인드 마운트를 사용하여 소스 코드를 컨테이너에 마운트할 수 있다. 
컨테이너는 파일을 저장하자마자 코드 변경 사항을 즉시 확인한다. 
이는 파일 시스템 변경 사항을 감시하고 이에 응답하는 프로세스를 컨테이너에서 실행할 수 있음을 의미

$ docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash
이 --mount옵션은 Docker에게 바인드 마운트를 생성하도록 지시한다. 여기서는 src호스트 시스템의 현재 작업 디렉터리( getting-started-app)이고 target해당 디렉터리가 컨테이너 내부에 표시되어야 하는 위치( /src)이다.

$ docker run -dp 127.0.0.1:3000:3000 \
    -w /app --mount type=bind,src="$(pwd)",target=/app \
    node:18-alpine \
    sh -c "yarn install && yarn run dev"

-dp 127.0.0.1:3000:3000- 이전과 같습니다. 분리(백그라운드) 모드로 실행하고 포트 매핑 생성
-w /app- "작업 디렉터리" 또는 명령이 실행될 현재 디렉터리를 설정
--mount type=bind,src="$(pwd)",target=/app- 호스트의 현재 디렉터리를 /app컨테이너의 디렉터리 에 바인드 마운트
node:18-alpine- 사용할 이미지. 이는 Dockerfile의 앱 기본 이미지
sh -c "yarn install && yarn run dev"- 명령. sh(alpine에는 없음 ) 을 사용하여 셸을 시작 bash하고 실행하여 yarn install패키지를 설치한 다음 실행하여 yarn run dev개발 서버를 시작


7부: 다중 컨테이너 앱
컨테이너를 별도로 실행하는 몇 가지 이유
API와 프런트엔드를 데이터베이스와 다르게 확장해야 할 가능성이 높다.
별도의 컨테이너를 사용하면 버전을 별도로 버전화하고 업데이트할 수 있다.
로컬에서 데이터베이스용 컨테이너를 사용할 수 있지만 프로덕션 환경에서는 데이터베이스용으로 관리형 서비스를 사용할 수 있다. 그러면 데이터베이스 엔진을 앱과 함께 제공하고 싶지 않을 것이다.
여러 프로세스를 실행하려면 프로세스 관리자(컨테이너는 하나의 프로세스만 시작)가 필요하므로 컨테이너 시작/종료가 더 복잡해진다.

컨테이너 네트워킹
컨테이너는 기본적으로 격리되어 실행되며 동일한 시스템의 다른 프로세스나 컨테이너에 대해 아무것도 모른다.
두 컨테이너를 동일한 네트워크에 배치하면 서로 통신할 수 있다.

네트워크에 컨테이너를 배치하는 방법에는 두 가지
1. 컨테이너를 시작할 때 네트워크를 할당
2. 이미 실행 중인 컨테이너를 네트워크에 연결

$ docker network create todo-app
네트워크 생성

$ docker run -d \
    --network todo-app --network-alias mysql \
    -v todo-mysql-data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=secret \
    -e MYSQL_DATABASE=todos \
    mysql:8.0
MySQL 컨테이너를 시작하고 네트워크에 연결

$ docker exec -it <mysql-container-id> mysql -u root -p
데이터베이스가 실행 중인지 확인하려면 데이터베이스에 연결하고 연결되는지 확인


각 컨테이너에는 고유한 IP 주소가 있다.

 


8부: Docker Compose 사용
Docker Compose : 다중 컨테이너 애플리케이션을 정의하고 공유하는 데 도움이 되는 도구
Compose를 사용하면 YAML 파일을 생성하여 서비스를 정의할 수 있으며 단일 명령으로 모든 것을 가동하거나 해체할 수 있다.

Compose 사용의 가장 큰 장점은 애플리케이션 스택을 파일로 정의하고 이를 프로젝트 저장소의 루트에 보관하며(이제는 버전 관리됨) 다른 사람이 프로젝트에 쉽게 기여할 수 있다.
누군가는 저장소를 복제하고 Compose를 사용하여 앱을 시작하기만 하면 된다. 
실제로 GitHub/GitLab에서 현재 이 작업을 수행하는 프로젝트가 상당히 많이 있는 것을 볼 수 있다.

$ docker compose up -d
애플리케이션 스택을 시작
Docker Compose는 애플리케이션 스택을 위한 네트워크를 자동으로 생성

$ docker compose logs -f
명령을 사용하여 로그를 확인

기본적으로 compose 파일의 명명된 볼륨은 를 실행할 때 제거되지 않는다.
docker compose down. 볼륨을 제거하려면 --volumes플래그를 추가해야 한다.

'공부 > 웹해킹' 카테고리의 다른 글

7주차 과제  (0) 2024.01.14
6주차 과제  (0) 2023.12.15
5주차 과제  (0) 2023.12.08
2주차 과제  (0) 2023.11.17
1주차 과제  (0) 2023.11.10

댓글