[도커] 중간점검 6장 ~ 10장 문제 만들기

공효은·2023년 8월 6일
0
post-thumbnail

1. 컨테이너 파일시스템에 대한 설명으로 옳지 않은것을 고르시오

  1. 컨테이너의 파일 시스템은 서로 독립적이다.
  2. 컨테이너의 파일시스템은 이미지 레이어와 기록 가능 레이어로 구성된다.
  3. 각 컨테이너가 따로 갖는 기록 가능 레이어는 컨테이너와 같은 생애주기를 갖는다.
  4. 이미지 레이어는 컨테이너와 같은 생애주기를 갖는다.

답: 4.이미지 레이어는 이미지를 내려 받는 순간부터 삭제할 때 까지 로컬 컴퓨터의 이미지 레이어에 존재한다.

2. 도커 볼륨에 대한 설명으로 옳지 않은것을 고르시오

  1. 도커 볼륨은 도커에서 스토리지를 다루는 단위이다. 컨테이너를 위한 USB 메모리라고 생각하면 이해하기 쉽다.
  2. 볼륨은 컨테이너에 종속적이며 컨테이너와 같은 생애주기를 갖는다.
  3. 볼륨을 생성해 애플리케이션 컨테이너에 연결하면 컨테이너 파일 시스템의 한 디렉터리가 된다.
  4. 애플리케이션을 업데이트 할때 새로운 컨테이너에 다시 볼륨을 연결하면 데이터가 유지된다.

답: 2. 볼륨은 컨테이너와 독립적으로 존재하며 별도의 생애주기를 갖지만, 컨테이너에 연결할 수 있다.

3. 아래 Dockerfile 스크립트에서 VOLUME 인스트럭션의 역할을 설명하시오

// 볼륨이 사용된 멀티 스테이지 빌드 Dockerfile 스크립트의 일부
FROM diamol/dotnet-aspnet
WORKDIR /app
ENTRYPOINT ["dotnet", "ToDoList.dll"]

VOLUME /data
COPY --from=builder /out/ .

답: 이 인스트럭션을 사용해 만든 이미지로 컨테이너를 실행하면 자동으로 볼륨을 생성해 컨테이너에 연결해준다.
실행된 컨테이너에는 /data 디렉터리가 있는데 (윈도 컨테이너라면 C:\data) 이 디렉터리는 다른 디렉터리와 똑같이 사용할 수 있는데 이 디렉터리의 내용은 볼륨에 영구적으로 저장된다.

4. volumes-from 플래그에 대해서 서술하시오.

답: 도커 이미지에서 볼륨을 정의하면 컨테이너를 생성할 때마다 새로운 볼륨을 만든다. 하지만 컨테이너가 같은 볼륨을 공유하게 할 수도있다.
volumes-from 플래그를 적용하면 다른 컨테이너의 볼륨을 연결할 수 있다.

//이 컨테이너는 todo1 컨테이너의 볼륨을 공유한다. /data 디렉터리의 내용도 같다.
docker container run -d --name t3 --volumes-from todo1 diamol/ch06-todo-list

⭐️ 애플리케이션 컨테이너는 종종 자신만이 접근할 수 있는 파일을 필요로한다. 이러한 파일을 다른 컨테이너가 동시에 접근하게 허용하면 애플리케이션이 비정상적으로 동작할 수 있다. 볼륨은 컨테이너 간 파일공유보다는 업데이트 간 상태를 보존하기 위한 용도로 사용해야한다. 이미지에 정의하는 것 보다는 명식적으로 관리하는 편이 낫다.
볼륨에 이름을 붙여 생성하고 업데이트 시 다른 컨테이너로 옮겨 연결하면 된다.

5. Dockerfile 스크립트의 VOLUME 인스트럭션과 docker container 명령의 --volume 플래그에 대한 설명으로 옳지 않은것을 고르시오.

참고

# 데이터를 저장할 볼륨도 생성한다
// 새로운 볼륨을 이름을 붙여 만든다. 지금은 그냥 빈 스토리지다.
docker volume create todo-list


# 볼륨을 연결해 v1 애플리케이션을 실행한다.
// -v 플래그를 사용해 새 컨테이너를 실행한다. 이 플래그는 컨테이너의 파일 시스템 경로 /data에 지정한 볼륨을 마운트 하라는 의미다.

docker container run -d -p 8011:80 -v todo-list:/data --name todo-v1 diamol/ch06-todo-list
  1. Dockerfile 에서 VOLUME 인스트럭션을 사용해 빌드된 이미지로 docker container run 명령에서 볼륨을 지정하지 않으면 항상 새로운 볼륨을 함께 생성한다.
  2. --volume 플래그는 이미지에 볼륨이 정의되어 있어도 지정된 볼륨을 컨테이너에 마운트 한다.
  3. --volume 플래그를 사용했을때 이미지에 볼륨이 정의돼 있으면 새로운 볼륨이 생성된다.
  4. 이미지를 만드는 입장에서는 안전장치 삼아 VOLUME 인스트럭션 이미지 정의에 포함해 두는게 좋다. 그러면 사용자가 볼륨을 지정하지 않더라도 데이터를 유실하지 않는다.

답: 3 이미지에 볼륨이 정의돼 있더라도 이 정의가 무시되므로 새로운 볼륨이 생성되지 않는다.

6. 파일 시스템 마운트에 대한 설명으로 옳지 않는것을 고르시오.

참고

// 호스트 컴퓨터의 로컬 디렉터리를 컨테이너에 바인드 마운트로 연결해 보라. 파일 시스템 경로는 호스트 운영체제의 방식을 따라야한다.
// 본문의 명령을 그대로 복사해 사용할 수 있도록 경로를 환경 변수로 설정한다.
source="$(pwd)/databases" && target='/data'

// 바인드 마운트를 적용해 컨테이너를 실행. 호스트 컴퓨터의 data 디렉터리를 컨테이너 안에서 사용한다.
mkdir ./databases 
docker container run --mount type=bind,source=$source,target=$target -d -p 8012:80 diamol/ch06-todo-list

// to-do 애플리케이션에 HTTP 요청을 보낸다. 이 요청을 받아 애플리케이션이 시작되며 데이터베이스 파일이 생성된다.
// 컨테이너 포트 80번을 호스트의 8012번 포트로 공개한다. curl 명령으로 컨테이너에 HTTP 요청을 보내면 애플리케이션이 시작되면서 data 에 데이터 베이스 파일이 생성된다.
curl http://localhost:8012

// 호스트 컴퓨터에 연결된 데렉터리에 데이터 베이스 파일이 생성된것을 확인하는 명령어 이다.
ls ./databases
  1. 바인드 마운트는 호스트 컴퓨터 파일 시스템의 디렉터리를 컨테이너 파일 시스템의 디렉터리로 만든다.
  2. 컨테이너가 호스트 컴퓨터의 파일에 직접 접근할 수 있다.(양방향으로 동작한다.)
  3. 속도 면에서 뛰어는 SSD 디스크, 고사용성 디스트 어레이, 네트워크 상에서 사용하는 분산 스토리지 까지 호스트 컴퓨터에 접근 가능한 파일 시스템이라면 무엇이든 컨테이너에서도 사용이 가능하다.
  4. 이미지레이어에 이미 존재하는 대상 디렉터리에 호스트 컴퓨터의 디렉터리를 마운트 하면 마운트의 원본 디렉터리와 기존 디렉터리가 공존한다.
docker-compose up

답: 4 이미 존재하는 대상 디렉터리에 마운트하면 마운트의 원본 디렉터리가 기존 디렉터리를 완전히 대체한다. 그래서 이미지에 포함돼 있던 원래 파일을 사용할 수 없다.

7. 도커 컴포즈 파일에 대한 설명으로 옳지 않은 것을 로그시오

  1. 도커 컴포즈 파일은 애플리케이션의 '원하는 상태', 모든 컴포넌트가 실행중일 때 어떤 상태여야 하는지 기술하는 파일이다.
  2. docker container run 명령으로 컨테이너를 실행할 때 지정하는 모든 옵션을 한데 모아 놓은 단순한 형식의 파일이다.
  3. 각각의 컨테이너를 일일히 옵션을 지정해 가며 실행하야 하기때문에 오류의 원천이 된다.
  4. 도커 컴포즈 파일을 작성하고 나면 도커 컴포즈 도구르 사용해 애플리케이션을 실행한다. 그러면 도커 컴포즈가 컨테이너, 네트워크, 볼륨 등 필요한 모든 도커 객체를 만들도록 도커 API에 명령을 내린다.
  5. 도커 컴포즈를 사용하여 애플리케이션을 시작하려면 up 명령을 실행해야한다. 그러면 도커가 컴포즈가 컴포즈 파일을 체크하고 애플리케이션을 정의된 상태로 실행하기 위해 필요한 요소들을 준비하기 시작한다.

답: 3. 각각의 컨테이너를 일일히 옵션을 지정해가며 실행하는게 문제가 되기 때문에 옵션을 한데 모아놓은 도커 컴포즈 파일을 사용하는 것이다.

8. 다음 docker compose file 에 대한 설명으로 옳지 않은 것을 고르시오.

version: '3.7' 1️⃣

services:
  
  todo-web: 2️⃣
    image: diamol/ch06-todo-list 
    ports:
      - "8020:80"  3️⃣ 
    networks:
      - app-net 4️⃣

networks: 5️⃣
  app-net: // 서비스가 구성될 네트워크 이름
    external:  // nat 네트워크가 이미 존재하므로 새로 생성하지 말라는뜻
      name: nat // app-net은 nat이라는 이름의 외부 네트워크로 연결됨
  1. 이 파일에 사용된 도커 컴포즈 파일 형식의 버전을 가리킨다.
  2. 서비스 이름은 컨테이너의 이름이자 도커 네트워크 상에서 다른 컨테이너들이 해당 컨테이너를 식별하기 위한 DNS 네임으로 쓰인다.
  3. 공개할 포트에 대한 정보이다. 컴포즈 파일을 실행했을때 해당 컨테이너는 호스트 컴퓨터의 8020번 포트로 자신의 80 포트를 공개한다.
  4. 컨테이너가 접속할 도커 네트워크를 정의한다.
  5. 서비스 컨테이너가 연결될 모든 도커 네트워크를 열거한다.

답: 3번 포트가 호스트 컴퓨터의 80번 포트로 자신의 8020 포트를 공개한다.

9. 아래 docker compose file에서 depends_on 에 대해서 설명하시오

version: '3.7'

services:

  accesslog:
    image: diamol/ch04-access-log
    networks:
      - app-net

  iotd:
    image: diamol/ch04-image-of-the-day
    ports:
      - "80"
    networks:
      - app-net

  image-gallery:
    image: diamol/ch04-image-gallery
    ports:
      - "8010:80" 
    // 이 서비스는 다른 두 서비스에 의존한다는 사실을 기술했다.
    depends_on:
      - accesslog
      - iotd
    networks:
      - app-net

networks:
  app-net:
    external:
      name: nat

답: image-gallery 서비스를 시작하기 전에 accesslog와 iotd 서비스를 먼저 시작한다. 이것은 컴포즈 파일에 서비스 간의 의존관계를 설정하는 것이다.

10. 도커는 애플리케이션의 상태가 실제로 정상인지 확인할 수 있는 정보를 도커 이미지에 직접 넣을 수 있는 기능을 제공한다. Dockerfile에서 HEALTHCHECK 인스트럭션에 대한 설명으로 옳지 않은것을 고르시오

참고

FROM diamol/dotnet-sdk AS builder

WORKDIR /src
COPY src/Numbers.Api/Numbers.Api.csproj .
RUN dotnet restore

COPY src/Numbers.Api/ .
RUN dotnet publish -c Release -o /out Numbers.Api.csproj

# app image
FROM diamol/dotnet-aspnet

ENTRYPOINT ["dotnet", "/app/Numbers.Api.dll"]
HEALTHCHECK CMD curl --fail http://localhost/health

WORKDIR /app
COPY --from=builder /out/ .% 
  1. 컨테이너 런타임은 HEALTHCHECK 인스트럭션에 정의된 정보를 이용해 컨테이너에서 동작중인 애플리케이션의 상태가 정상인지 확인할 수 있다.
  2. 도커카 컨테이너 안에서 실행하는 명령을 지정하게 된다. 이 명령이 반환하는 상태 코드를 보고 애플리케이션 상태를 판단한다.
  3. 도커는 일정한 시간 간격으로 컨테이너 안에서 지정된 명령을 실행한다. 상태코드가 정상이면 컨테이너도 정상, 상태코드가 연속으로 일정횟수 이상 실패로 나오면 해당 컨테이너를 이상 상태로 간주한다.
  4. --fail 옵션을 붙이면 curl이 전달받은 상태 코드를 도커에 전달한다. 요청이 성공하면 curl이 0을 반환하고, 실패하면 0이외의 숫자를 반환한다. 도커는 0을 헬스 체크 정상, 0 이외의 값을 비정상으로 간주한다.
  5. 도커는 이상 상태에 있는 컨테이너를 재시작하거나 다른 컨테이너로 교체한다.

답: 5 도커 엔진은 이상 상태에 있는 컨테이너를 재시작하거나 다른 컨테이너로 자동 교체하지 않는다.

  • 도커 엔진은 단일 서버에서 동작하는데, 이상이 생긴 컨테이너를 도커가 중지하고 재시작 할 수 있지만 그 시간동안에 애플리케이션이 동작하지 않는다.(데이터 유실)
  • 도커 입장에서는 이상 상태를 보이는 컨테이너를 교체하는 작업을 직접 수행했을 때 상황을 더 악화시키지 않을것이라는 보장이 없으므로, 이상 상태 발생을 통보할 뿐 컨테이너는 그대로 둔다.
  • 도커 스웜이나 쿠버네티스가 관리하는 클러스터 환경에서는 헬스 체크 기능이 유용하다. 클러스터는 컨테이너를 추가로 실행할 여력이 항상 있기 때문에 이상 상태를 보이는 컨테이너를 그대로 두고 대체 컨테이너를 실행해 애플리케이션의 중단 시간 없이 상태를 회복할 수 있다.

11. 도커 컴포즈에 헬스 체크와 디펜던시 체크를 정의할 수 있다. 다음 도커 컴포즈에 대한 설명으로 옳지 않는것을 고르지오.

version: "3.7"

services:
  numbers-api:
    image: diamol/ch08-numbers-api:v3
    ports:
      - "8087:80"
    healthcheck:
      interval: 5s
      timeout: 1s
      retries: 2
      start_period: 5s
    networks:
      - app-net

  numbers-web:
    image: diamol/ch08-numbers-web:v3
    restart: on-failure
    environment:
      - RngApi__Url=http://numbers-api/rng
    ports:
      - "8088:80"
    healthcheck:
      test: ["CMD", "dotnet", "Utilities.HttpCheck.dll", "-t", "150"]
      interval: 5s
      timeout: 1s
      retries: 2
      start_period: 10s
    networks:
      - app-net

networks:
  app-net:
    external:
      name: nat
  1. interval은 헬스 실시 간격을 의미한다 여기서는 5초로 설정 됐다.
  2. timeout 은 그때까지 응답을 받지 못하면 실패로 간주하는 제한 시간을 의미한다.
  3. start_period는 컨테이너 실행 후 첫 헬스체크를 실시하는 시간 간격을 의미한다. 애플리케이션을 시작하는 데 시간이 오래 걸리는 경우 필요하다.
  4. 도커 컴포즈 파일에서는 헬스 체크의 옵션을 상세하게 설정할 수 있을뿐, 헬스 체크는 반드시 이미지에서 정의해야한다.
  5. 스크립트에는 restart:on-failure 설정이 잆으므로 컨테이너가 예기치 않게 종료되면 컨테이너를 재시작한다.
    답: 4 이미지에 헬스 체크가 정의되지 않았다면 컴포즈 파일에서 정의하는 방법도 있다. 서비스에 헬스 체크를 추가했다. 설정값은 API 서비스와 같은 값을 적용했다. test 필드가 헬스 체크를 위해 실행하는 명령이다.

12. 프로메테우스에서 측정값을 수집하는 과정을 OOOO이라한다.

답: 스크래핑

13. 도커 컴포즈다 도커 리소스가 어떤 애플리케이션의 일부인지 아닌지를 판정하기 위해 프로젝트라는 개념을 사용한다. 프로젝트에 대한 설명으로 옳지 않은것을 고르시오.

  1. 프로젝트 이름의 기본값은 도커 컴포즈 파일이 들어 있던 디렉터리 명이다.
  2. 이미 같은 디렉터리에서 실행한 애플리케이션을 하나 더 실행하려고 하면 실행되지 않는다.
  3. 도커 컴포즈가 도커리소스를 만들 때 이 프로젝트 이름을 리소스의 이름에 접두사로 붙이고, 컨테이너 이름에는 번호를 접비사로 붙인다.
  4. 컴포즈가 사용하는 프로젝트의 기본값을 바꿀 수 없다.

답: 4 컴포즈가 사용하는 프로젝트 이름의 기본값을 바꿀 수 있으므로 이 프로젝트 이름을 바꾸는 방법으로 단일 도커 호스트에 같은 애플리케이션을 여러 벌 실행시킬 수 있다.


docker-compose -f ./todo-list/docker-compose.yml -p todo-test up -d
docker container ls
// 컨테이너의 공개된 포트를 알려주므로 컨테이너 이름으로 애플리케이션의 포트도 알 수 있다.
docker container port todo-test-todo-web-1 80

14. 다음은 무작위 숫자 애플리케이션을 여러 환경용 설정으로 실행했다. 환경마다 별도의 프로젝트 이름과 기본 컴포즈 파일, 오버라이드 파일이 있다. 이에 대한 설명으로 옳지 않은 것을 고르시오.

# 기존 컨테이너 모두 제거하기
docker container rm -f $(docker container ls -aq)

# 개발 환경용 설정으로 실행하기
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-dev.yml -p numbers-dev up -d

# 테스트 환경용 설정으로 실행하기
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-test.yml -p numbers-test up -d

# 인수 테스트 환경용 설정으로 실행하기
docker-compose -f ./numbers/docker-compose.yml -f ./numbers/docker-compose-uat.yml -p numbers-uat up -d
  1. 이들 각각은 모두 별개의 도커 네트워크를 사용하므로 서로 독립적이다.
  2. 개발 팀에서는 이들 모두를 한 서버에서 실행하고, 팀마다 포트를 달리해 관련된 환경에 접근할 수 있다.(예를 들어 사용자 인수 테스트 환경은 80번 포트로 접근, 시스템 테스트 환경은 8080번 포트, 개발 팀의 통합 테스트 환경은 8088번 포트로 접근하는 식이다.)
  3. 이들은 모든 환경의 API 컨테이너와 통신 할 수 있다.
  4. 이들 환경별로 실행된 컨테이너는 도메인 네임을 사용해 서로를 식별하지만, 같은 도커 네트워크에 접속한 컨테이너끼리만 통신이 가능하다.

답: 3 : 이들은 모든 자신만의 네트워크 안에서 해당 환경의 API 컨테이너와만 통신할 수 있다. 이 때문에 세 환경의 애플리케이션은 서로 독립적이다.
개발 환경의 애플리케이션에 여러 번 무작위 숫자를 요청해 API가 버그를 일으키더라도 시스템 테스트 환경이나 사용자 인수 테스트 환경의 애플리케이션은 잘 동작한다.

profile
잼나게 코딩하면서 살고 싶어요 ^O^/

0개의 댓글