[CloudClub] 90DaysOfDevOps 2차

박서연·2023년 9월 21일

Cloud

목록 보기
7/13
post-thumbnail

Containers

Day42

📌 애플리케이션을 실행하는 다른 방법

  1. 소프트웨어나 애플리케이션을 실행하는 다른 방법이 필요한 이유

=> 다양한 형태로 애플리케이션을 실행할 수 있음

(1) 물리적 하드웨어에 운영 체제와 단일 애플리케이션이 배포된 애플리케이션의 경우

(2) 가상 머신 또는 클라우드 기반 IaaS 인스턴스가 애플리케이션을 실행한 다음 다시 가상 머신의 데이터베이스에 통합되거나 퍼블릭 클라우드의 PaaS 제품으로 통합되는 경우

(3) 애플리케이션이 컨테이너에서 실행되는 경우

  1. 컨테이너 VS 가상머신

공: 애플리케이션 실행 방법

차: 구조와 실행 방식이 다름

🔻 예전에는 전체 서버 OS, 가상머신, 물리적 또는 클라우드 인스턴스가 필요했던 애플리케이션이 많았다면, 최근에는 컨테이너 기반 버전의 소프트웨어를 출시하는 경우가 증가하고 있음

📌 컨테이너

  1. 컨테니어 기술이 인기를 얻은 이유

🔻 쉽게 찾고 사용할 수 있는 이미지 에코시스템(설치 및 실행이 간단) + 소프트웨어에서 직면하는 다양한 과제에 대한 전체 공간의 일관성

  1. 좋은 컨테이너와 이미지 기술의 동시 사용

🔻 이미지는 배포 관점에서, 컨테이너는 설치와 운영에 도움이 됨

DistributionInstallationOperation
FindInstallStart
DownloadConfigurationSecurity
LicenseUninstallPorts
PackageDependenciesResource Conflicts
TrustPlatformAuto-Restart
FindLibrariesUpdates

📌 컨테이너의 배포 및 확장

  1. 문제 대두

예를 들어 nodejs에는 특정 종속성이 있고 특정 라이브러리가 필요. MySQL을 설치하려면 필요한 라이브러리와 종속성이 필요. 이와 같이 각 소프트웨어 애플리케이션에는 해당 라이브러리와 종속성 존재 => 애플리케이션이 많을수록 특정 라이브러리와 종속성이 충돌할 가능성 높아짐

  1. 컨테이너

컨테이너는 애플리케이션을 구축하고 배포하고, 독립적으로 쉽게 배포하고 확장될 수 있도록 도와줌 => 위의 문제 해결하는데 도움이 될 수 있음

  1. 컨테이너 구조

아래의 자료를 통해 아키텍처를 살펴보면 하드웨어와 운영체제가 존재하고, 그 위에 docker와 같은 컨테이너 엔진이 존재.

컨테이너 엔진은 라이브러리와 종속성을 함께 패키징하는 컨테이너를 생성하는 데 도움이 되므로 라이브러리와 종속성이 컨테이너 패키지의 일부로 제공 => 라이브러리와 종속성에 대한 걱정 없이 컨테이너를 다른 시스템으로 원활하게 이동 가능하도록 함(애플리케이션이 실행하는 데 필요한 모든 것이 컨테이너로 패키징되어 있음)

📌 컨테이너의 장점

✔️ 컨테이너 내의 모든 종속성을 패키징하고 격리할 수 있음

✔️ 관리하기 쉬움

✔️ 한 시스템에서 다른 시스템으로 이동할 수 있음

✔️ 소프트웨어 패키징하는데 도움이 되며 중복 작업 없이 쉽게 배포 가능

✔️ 쉽게 확장 가능

📌 컨테이너란 무엇인가

  1. 이미지

노트북에서 새 애플리케이션을 열거나 아이콘(파일 시스템 내의 실행 파일에 대한 링크)을 클릭하면 운영체제는 해당 실행 파일을 메모리에 로드 => 이때의 실행 파일을 이미지라고 부름

  1. 컨테이너는 프로세스로, 코드와 모든 종속성을 패키징하여 애플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 하는 소프트웨어의 표준 단위

  2. 컨테이너화된 소프트웨어는 인프라에 관계없이 항상 동일하게 실행

📌 이미지란 무엇인가

=> 컨테이너 이미지는 경량의 독립형 실행형 소프트웨어 패키지

🚀 IaaS vs PaaS vs SaaS

클라우드 서비스는 제공하는 범위에 따라 아래와 같이 나뉨

  1. IaaS (Infrastructure as a Service)

: 서비스로 제공되는 인프라스트럭처 가상화

확장성이 높고 자동화된 컴퓨팅 리소스를 가상화하여 제공하고 관리

고객에게 가상화된 물리적인 자원을 UI 형태의 대시보드 또는 API로 제공

  1. PaaS (Platform as a Service)

: 서비스로 제공되는 플랫폼 가상화

응용 프로그램을 개발할 때 필요한 플랫폼을 제공

고객에게 OS, 미들웨어, 런타임과 같은 소프트웨어 작성을 위한 플랫폼을 가상화하여 웹을 통해 제공 => 개발자는 소프트웨어 개발에만 집중할 수 있음

  1. SaaS (Software as a Servie)

: 서비스로 제공되는 소프트웨어 가상화

대부분의 SaaS 애플리케이션은 웹 브라우저를 통해 직접 실행되므로 클라이언트 측에서 다운로드하거나 설치할 필요 X

고객을 대신하여 소프트웨어와 데이터를 제공하고 관리

🔻 각 서비스의 단점

PaaS는 특정 플랫폼 서비스에 종속될 수 있으며, SaaS는 커스터마이징이 어려움

🔻 서비스 적용 및 활용 사례

IaaS 빠른 변화를 원하는 경우

ex. Amazon Web Service(AWS), Microsoft Azure, DigitalOcean, Google Compute Engine(GCE)

PaaS 신속한 개발을 원하는 경우

ex. AWS Elastic Beanstalk, Windows Azure, Heroku, Google App Engine
SaaS 비즈니스에 집중하고 싶은 경우

ex. Google Apps, Dropbox, Salesforce, WhaTap

Day 43

OCI (Open Container Initiative)

=> 컨테이너 툴체인을 선택할 때 Docker, CRI-O, Podman, LXC 등을 선택할 수 있게 됨

📌 Docker

  1. Docker

컨테이너를 빌드, 실행 및 관리하기 위한 소프트웨어 프레임워크

=> Docker Personal 사용

🔻 docker라는 용어는 개발자와 관리자가 애플리케이션을 개발, 배포 및 실행하기 위한 플랫폼인 docker 프로젝트 전반 + 이미지와 컨테이너를 관리하는 호스트에서 실행되는 docker 데몬 프로세스(docker engine)

  1. Docker Engine

🔻 애플리케이션을 빌드하고 컨테이너화하기 위한 오픈소스 컨테이너화 기술

🔻 클라이언트-서버 애플리케이션 역할

1) 장기 실행 데몬 프로세스가 있는 dockerd

2) 프로그램이 Docker 데몬과 대화하고 지시하는데 사용할 수 있는 인터페이스를 지정하는 API

3) 명령줄 인터페이스(CLI) 클라이언트 docker

=> CLI는 Docker API를 사용해 Docker 데몬을 제어하거나 상호 작용. 데몬은 이미지, 컨테이너, 네트워크, 볼륨과 같은 Docker 개체를 생성하고 관리

  1. Docker Desktop

🔻 호스트 운영 체제의 가상화 기능을 활용하는 네이티브 OS 애플리케이션

🔻 호스트 운영 체제의 하이퍼바이저 기능과 통합 기능을 제공하므로 docker는 리눅스 운영 체제에서 컨테이너를 실행할 수 있는 기능 제공

🔻 Windows에서는 WSL2와 Microsoft Hyper-Vdo 실행 가능

  1. Docker Compose

🔻 여러 컨테이너에서 더 복잡한 앱을 실행할 수 있는 도구로, 단일 파일과 명령을 사용하여 애플리케이션을 스핀업할 수 있음

  1. DockerHub

🔻 docker와 그 구성 요소로 작업하기 위한 중앙 집중식 리소스

🔻 가장 일반적으로 docker 이미지를 호스팅하는 레지스토리

  1. Dockerfile

🔻 일반적으로 docker 이미지를 빌드하기 위해 수동으로 실행하는 명령이 포함된 텍스트 파일

🔻 docker는 dockerfile에 있는 지침을 읽어 이미지 자동 빌드 가능

📌 Docker Desktop 설치

WSL2가 설치된 Windows에서 Docker Desktop 사용

🔻 WSL2는 자동으로 설치되고 적용됨

  1. docker desktop 설치

  2. cmd에 docker 명령어 작성해 확인

Day 44

📌 Docker 이미지 및 Docker Desktop 실습

  1. Docker 이미지

🔻 Docker 컨테이너에서 코드를 실행하는데 사용되는 파일

🔻 템플릿처럼 Docker 컨테이너를 빌드하기 위한 일련의 지침 역할

🔻 Docker를 사용할 때 시작점 역할을 하기도 함

  1. DockerHub

🔻 Docker 및 그 구성요소로 작업하기 위한 중앙 집중식 리소스

🔻 가장 일반적으로 docker 이미지를 호스팅하는 레지스토리로 알려짐

🔻 부분적으로 자동화와 함께 사용하거나 보안 검사뿐만 아니라 GitHub에 통합할 수 있는 많은 추가 서비스 존재

  1. Docker Desktop 구조

1) Containers/Apps

실행되고 있는 컨테이너가 나타남 + Docker Engine 실행되는 것을 볼 수 있음

2) Images

이미 다운로드하여 사용할 수 있는 이미지와 원격 리포지토리 아래에서 DockerHub에 저장한 컨테이너 이미지 찾을 수 있음

3) Volumes

지속성이 필요한 컨테이너가 있는 경우 로컬 파일 시스템이나 공유 파일 시스템에 volumes 추가 가능

📌 Docker Desktop 실습 1

  1. 시작 컨테이너 실행 명령

cmd에 docker run -d -p 80:80 docker/getting-started

🔻 이미지가 존재하지 않다고 뜨지만 조금만 더 기다리면 자동으로 다운로드

  1. Docker Desktop에서 확인

1) Containers 확인

🔻 컨테이너 클릭한 후 아래 그림에 표시된 아이콘을 눌러 웹 브라우저로 열기

🔻 웹 페이지가 열림

2) Images 확인

3) 시작 컨테이너 중단

📌 Docker Desktop 실습 2

  1. 컨테이너 이미지 중 하나를 DockerHub에 가져오기

cmd에 docker run hello-world

  1. Docker Desktop에서 확인

1) Containers 확인

🔻 실행 중인 컨테이너는 없지만, hello-world 메시지를 전달하고 종료된 컨테이너 존재

2) Images

🔻 로컬에 새로운 hello-world 이미지 존재 => 버전이 변경되지 않는 한 docker run hello-world 명령어를 다시 실행해도 가져올 것이 없음

📌 Docker Desktop 실습 3

  1. 운영체제의 전체 복사본이 아닌, 우분투의 컨테이너화된 버전 실행

docker run -it ubuntu bash

🔻 대화형 프롬프트 -it 가 나타나고 컨테이너에 bash shell 생성

🔻 cmd의 bash shell에 ip addr, curl, wget, git 등과 같은 명령어 가능

🔻 bash shell에 apt update 명령어를 통해 이미지 업데이트 및 업그레이드 가능

🔻 좋은 예시는 아니지만 apt-get install pinta 명령어를 통해 이미지 편집기 설치 가능

=> 용량이 커서 실습은 X

🔥 궁극적인 목표는 무언가를 만들어서 DockerHub 리포지토리에 업로드하고 배포하는 것

Day 45

📌 Docker 이미지의 구조

  1. Docker 이미지

🔻 Docker 플랫폼에서 실행할 수 있는 컨테이너를 만들기 위한 일련의 지침이 포함된 읽기 전용 템플릿

🔻 애플리케이션과 사전 구성된 서버 환경을 패키징하여 개인적으로 사용하거나 다른 Docker 사용자와 공개적으로 공유할 수 있는 편리한 방법 제공

🔻 Docker 이미지를 만들기 위해서는 Dockerfile을 생성해야함

📌 Docker file

  1. Dockerfile

: 일반적으로 docker 이미지를 빌드하기 위해 수동으로 실행하는 명령이 포함된 텍스트 파일

🔻 docker는 Dockerfile에 있는 지침을 읽어 이미지를 자동으로 빌드할 수 있음

  1. 레이어

: docker 이미지를 구성하는 각 파일

🔻 단계적으로 서로의 위에 빌드되는 일련의 이미지 형성하며, 각 레이어는 바로 아래 레이어에 종속됨

🔻 레이어의 순서는 docker 이미지 라이프사이클 관리 효율성의 핵심

⚡️ 가장 자주 변경되는 레이어는 가능한 한 스택에서 가장 높은 곳에 구성해야 전체 이미지를 다시 빌드하는데 필요한 작업량이 가장 적음

  1. docker

🔻 docker가 이미지로부터 컨테이너를 실행할 때(위의 실습)마다 컨테이너 레이어(쓰기 가능한 레이어) 추가

컨테이너 레이어 : 컨테이너가 실행되는 동안의 모든 변경 사항을 저장하며, 해당 레이어가 실제 운영 중인 컨테이너와 소스 이미지 자체 사이의 유일한 차이점

  1. manifest

🔻 개별 레이어 파일 세트와 함께 docker 이미지에는 manifest라는 추가 파일도 포함

manifest: 기본적으로 이미지에 대한 JSON 형식의 설명이며, 이미지 태그, 전자 서명, 다양한 유형의 호스트 플랫폼에 맞게 컨테이너를 구성하는 방법에 대한 세부 정보와 같은 정보로 구성됨

📌 Docker 이미지 생성하는 방법

  1. 기본 이미지 선택 (ex. 위 실습)

1) 기본 이미지를 선택하여 해당 컨테이너를 스핀업하고 컨테이너에 원하는 모든 소프트웨어와 종속성 설치

2) docker commit container name 명령어를 통해 이 이미지의 로컬 복사본이 docker 이미지와 Docker Desktop 이미지 탭 아래에 존재

⭕️ docker 이미지를 빌드하는 가장 빠르고 간단한 방법 => 테스트, 문제 해결, 종속성 검증에 적합

❌ 라이프사이클 관리가 매우 어렵고, 수동 구성/재구성이 많이 필요

  1. Dockerfile 사용

🔻 실제 엔터프라이즈급 컨테이너 배포에 훨씬 잘 맞음

🔻 dockerfile은 3단계 프로세스를 통해 dockerfile을 만들고 이미지를 조립하는데 필요한 명령 추가

⭕️ 깔끔하고 간결하며 반복 가능한 방법 제공. 라이프사이클 관리가 더 쉽고 지속적인 통합 및 지속적인 배포 프로세스에 쉽게 통합할 수 있음

❌ 앞의 방식보다 어려울 수 있음

⚡️ 사용자가 가장 많이 사용할 dockerfile 설정

CommandPurpose
FROM상위 이미지 지정
WORKDIRDockerfile에서 다음에 나오는 명령의 작업 디렉토리 설정
RUN컨테이너에 필요한 애플리케이션과 패키지 설치
COPY특정 위치에서 파일 또는 디렉토리 복사
ADD복사뿐만 아니라 원격 URL을 처리하고 압축 파일의 압축을 풀 수 있음
ENTRYPOINT컨테이너가 시작될 때 항상 실행되는 명령. 지정하지 않을 경우 기본값은 '/bin/sh -c'
CMD엔트리포인트로 전달된 인자. 엔트리포인트가 설정되지 않은 경우, 컨테이너가 실행하는 명령은 CMD가 됨
EXPOSE컨테이너 애플리케이션에 액세스할 포트 정의
LABEL이미지에 메타데이터 추가

📢 dockerfile 사용해 작업 디렉토리 생성 및 dockerfile 생성

💡 컨테이너는 부피가 커지지 않고 가능한 한 빠르고 컴팩트하게 만들어야 함

1) 작업 디렉토리 생성

cmd 또는 Power Shell에서 아래 코드 실행

mkdir dockerfile_90daysofdevops
cd dockerfile_90daysofdevops
code Dockerfile	//VSCode로 이동해 편집
code .dockerignore	//VSCode로 이동해 편집

2) .dockerignore 파일 생성

최종 빌드에서 제외하려는 Docker 빌드 프로세스 중에 생성되는 모든 파일 나열

cd dockerfile_90daysofdevops
code Dockerfile	//VSCode로 이동해 편집
code .dockerignore	//VSCode로 이동해 편집

3) dockerfile 생성

위에서 만든 Dockerfile에 아래 코드 추가

# 공식 우분투 18.04를 기본으로 사용하세요.
FROM ubuntu:18.04
# nginx 및 curl 설치
RUN apt-get update && apt-get upgrade -y
RUN apt-get install -y nginx curl
RUN rm -rf /var/lib/apt/lists/*

4) 이미지 생성

docker build -t 90daysofdevops:0.1 .

-t 태그를 통해 이미지 이름과 태그 설정 가능

docker images

도커 이미지 생성 확인

5) 컨테이너 생성

이미지를 생성했으므로 Docker Desktop을 사용해 이미지 실행 및 docker 커맨드라인 사용 가능

docker run [image Id]

📢 이미지 Hub로 pull할 때 Error발생

denied: requested access to the resource is denied

해결법

로그인 -> docker tag를 DockerHub Id와 동일하게 생성

1) 로그인

docker login

2) docker tag를 DockerHub Id와 동일하게 생성

docker build -t {{username}}/{{imagename}}:{{version}} 형식

[Docker Desktop]

[DockerHub]

Day 46

📢 Docker Compose

  1. 등장 배경

하나의 컨테이너를 실행할 수 있는 기능은 단일 사용 사례에 필요한 모든 것을 갖춘 독립적인 이미지가 있는 경우 유용하지만, 서로 다른 컨테이너 이미지 간에 여러 애플리케이션을 빌드하려는 경우 문제 발생 가능성 존재

  1. 예시

웹사이트 프론트엔드와 백엔드 데이터베이스가 필요한 경우 모든 것을 하나의 컨테이너에 넣는 것보다 데이터베이스용 컨테이너를 사용하는 것이 더 효율적

  1. 여러 컨테이너에서 더 복잡한 앱을 실행할 수 있는 도구인 Docker Compose 등장

=> 단일 파일과 명령을 사용하여 애플리케이션 스핀업 가능

📢 Docker Compose 설치

🔻 Docker Desktop 설치에 compose 포함

🔻 docker-compose 명령어로 설치 확인

📢 Docker Compose.yml (YAML)

  1. docker-compose.yml

🔻 리포지토리의 컨테이너 폴더에서 찾을 수 있음

🔻 단일 시스템에 여러 개의 컨테이너를 배포할 때 수행하고자 하는 작업의 구성 파일

🔻 대부분 서비스로 구성되어 있으며 각 서비스에는 버전 태그가 연결된 이미지가 정의되어 있음. 데이터베이스를 저장할 수 있도록 볼륨 생성 + 환경 변수(사용자 이름 및 비밀번호)

[docker-compose.yml 예시]

version: '3.9'

services:
  DB:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - '8000:80'
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}
  1. YAML

: 구성 파일과 데이터를 저장하거나 전송하는 일부 애플리케이션에서 사용됨

📢 프로젝트 빌드

  1. docker-compose.yml 파일이 있는 디렉토리로 이동해 docker-compose up -d 실행 => 해당 이미지 가져와 멀티 컨테이너 애플리케이션을 세우는 프로세스 시작
    -d는 분리모드를 의미하며 실행 명령이 백그라운드에서 실행 중이거나 실행될 것 의미

  2. docker ps 명령을 실행하면 2개의 컨테이너가 실행 중이며 하나는 WordPress이고 다른 하나는 MySQL인 것을 볼 수 있음

  3. 브라우저 열고 http://localhost:8000로 이동하면 WordPress 실행 중이며 설정 페이지가 표시됨 -> 워드프레스 설정 완료 후 원하는대로 웹사이트 구축 가능

  4. 새 탭을 열고 http://localhost:8000 이전과 동일한 주소로 이동하면 사이트 제목이 "90DaysOfDevOps"인 간단한 기본 테마가 표시되고 샘플 게시물이 표시

  5. Docker Desktop을 열고 볼륨 탭으로 이동하면 컨테이너와 연결된 두 개의 볼륨(하나는 워드프레스용, 다른 하나는 DB용)을 볼 수 있음

  6. 원하는대로 테마 변경

📢 정리 여부

  1. docker-compose down

컨테이너 삭제되지만 볼륨은 그대로 유지

  1. 동일 디렉토리에서 docker up -d

애플리케이션 백업하고 실행 가능

  1. 브라우저에 http://localhost:8000 입력하면 위의 6번에서 변경한 테마가 적용된 것 확인 가능

  2. docker-compose down --volumes

컨테이너와 해당 볼륨까지 제거하고 싶은 경우

이후 docker-compose up -d 명령어를 실행하면 다시 시작하지만 이미지가 우리 시스템의 로컬에 있으므로 DockerHub 리포지토리에서 다시 가져올 필요 X

📢 참고 리소스

Awesome-Compose : 여러 통합이 있는 docker-compose 애플리케이션의 샘플을 위한 리소스

Day 47

📢 Docker 네트워킹 기본 사항

  1. 터미널에 docker network

컨테이너 네트워크 구성하고 관리하는 명령어

  1. docker network list

가지고 있는 기본 Docker 네트워킹 확인 가능

각 네트워크는 고유한 ID와 이름을 가지며 단일 드라이버와 연결됨

  1. docker network inspect

네트워크 자세히 보기

  1. docker network inspect bridge

특정 네트워크 이름에 대한 모든 구성 세부 정보(이름, ID, 드라이버, 연결된 컨테이너) 확인 가능

📢 Docker: bridge 네트워킹

🔻 Docker Desktop을 표준 설치하면 bridge 라는 네트워크 제공 -> docker network list 를 통해 bridge 네트워크가 bridge 드라이버와 연결된 것 확인 가능

=> bridge 네트워크가 로컬로 범위가 지정되었음을 보여주며 네트워크가 이 Docker host에만 존재한다는 것 의미

🚫 이름이 같다고 같은 것이 아니며, 연결이 되었다고 같은 것은 아님

📢 컨테이너 연결

🔻 새로운 컨테이너는 네트워크를 지정하지 않으면 bridge 네트워크와 연결됨

  1. docker run -dt ubuntu sleep infinity

새 컨테이너 생성

  1. docker network inspect bridge

bridge 네트워크 확인 => 이전에 생성한 컨테이너가 네트워크 지정을 하지 않았기 때문에 나타남

  1. docker exec -it [컨테이너ID] bash

컨테이너 자세히 보기

docker ps : 컨테이너 ID 얻기

  1. apt-get update && apt-get install -y inputils-ping

핑할 항목이 없으므로 외부 인터페이스 주소를 핑

  1. ping -c5 [외부 인터페이스 주소]

💡 docker stop [컨테이너ID] 실행 후 docker ps를 사용해 컨테이너 ID 찾기 가능. But 컨테이너 제거됨

📢 외부 연결을 위한 NAT 구성하기

🔻 새 Nginx 컨테이너 시작하고 Docker host의 포트 8080을 컨테이너 내부 포트 80으로 매핑

  1. docker run --name web1 -d -p 8080:80 nginx

nginx 이미지 기반 컨테이너 생성

  1. docker ps

컨테이너 상태와 포트 매핑 확인

  1. WSL 터미널에서 IP addr

실제 host에 대한 IP 주소 확인

  1. 브라우저에서 http://[해당IP]:8080 로 이동

nginx 액세스

📢 컨테이너 보안

🔻 컨테이너는 전체 서버 구성에 비해 워크로드에 안전한 환경 제공

🔻 애플리케이션을 서로 격리된 훨씬 작고 느슨하게 결합된 구성 요소로 분할할 수 있어 공격 표면을 줄이는데 도움이 되지만 해커로부터 자유롭지 않음

📢 루트 권한에서 벗어나기

🔻 지금까지 배포한 모든 컨테이너는 루트 권한(컨테이너와 host 환경에 대한 모든 관리 액세스 권한 존재)을 사용

=> 루트 사용자가 아닌 사용자가 선호: dockerfile 만들 때 사용자 계정을 만들 수 있음

# 공식 Ubuntu 18.04를 기본으로 사용하세요.
FROM ubuntu:18.04
RUN apt-get update && apt-get upgrade -y
RUN groupadd -g 1000 basicuser && useradd -r -u 1000 -g basicuser basicuser
USER basicuser

docker run --user 1009 ubuntu 를 통해 모든 사용자 재정의

🚫 위의 방법은 이미지 자체의 근본적인 보안 결함을 해결하지 못하므로 dockerfile에 루트 사용자가 아닌 사용자를 지정하는 것이 좋음

Day 48

📢 Docker의 대안

  1. Podman

🔻 리눅스 시스템에서 OCI 컨테이너를 개발, 관리, 실행하기 위한 데몬이 없는 컨테이너 엔진으로, 컨테이너는 루트로 실행하거나 루트리스 모드로 실행할 수 있음

🔻 설치

sudo apt-get update && sudo apt-get upgrade

sudo apt install podman

🔻 사용

podman images

podman pull ubuntu

🔻 이미지 실행 및 확인

podman run -dit ubuntu

podman ps

🔻 컨테이너

podman attach [이미지 Names]

  1. LXC

  2. Containerd

  3. 기타 Docker 도구

Gradle / Packer / Logspout / Logstash / Portainer

Kubernetes

Day 49

⭐️ 컨테이너 오케스트레이터인 Kubernetes를 사용하면 애플리케이션과 서비스의 부하에 따라 자동화된 방식으로 확장 및 축소 가능

📢 Kubernetes란

  1. 정의

Kubernetes는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식 가능하고 확장 가능한 오픈소스 플랫폼으로, 선언적 구성과 자동화를 모두 용이하게 함

  1. 이점

1) Services discovery 및 로드 밸런싱

🔻 Kubernetes는 DNS 이름 또는 IP 주소를 사용하여 컨테이너를 노출시키며, 트래픽이 많은 경우 이를 로드 밸런싱하고 분산하여 배포가 안정적으로 이루어지도록 함

2) 스토리지 오케스트레이션

🔻 로컬 스토리지, 퍼블릭 클라우드 제공자 등 원하는 스토리지 시스템을 자동으로 마운트할 수 있음

3) 자동화된 롤아웃 및 롤백

🔻 배포된 컨테이너 상태를 설명할 수 있으며, 제어된 속도로 실제 상태를 원하는 상태로 변경할 수 있음

ex. 배포를 위한 새 컨테이너를 생성하고, 기존 컨테이너를 제거하고, 모든 리소스를 새 컨테이너에 적용하도록 Kubernetes 자동화 가능

4) 자동 bin 패킹

🔻 컨테이너화된 작업을 실행하는데 사용할 수 있는 노드 클러스터를 Kubernetes가 제공하고 각 컨테이너에 필요한 CPU와 메모리(RAM)의 양을 Kubernetes에 알려줌
Kubernetes는 리소스를 최대한 활용하기 위해 컨테이너를 노드에 맞출 수 있음

5) 자가 복구

🔻 장애가 발생한 컨테이너를 다시 시작하고, 컨테이너를 교체하고, 사용자 정의 상태 확인에 응답하지 않는 컨테이너를 죽이고, 제공할 준비가 될 때까지 클라이언트에게 알리지 않음

6) 비밀 및 구성 관리

🔻 컨테이너 이미지를 다시 빌드하거나 스택 구성에 시크릿을 노출하지 않고도 시크릿 및 애플리케이션 구성을 배포하고 업데이트할 수 있음

  1. 책임

1) 클러스터 관리는 호스트를 하나의 대상으로 묶음

2) 스케쥴 관리는 스케쥴러를 통해 컨테이너를 노드 간에 배포

3) Service discovery는 컨테이너의 위치를 파악하고 클라이언트 요청을 컨테이너에 분산

4) 복제는 요청된 워크로드에 적합한 수의 노드와 컨테이너를 사용할 수 있도록 보장

5) 상태 관리는 건강하지 않은 컨테이너와 노드를 감지하고 교체

📢 Kubernetes의 주요 구성 요소

💡 Kubernetes는 앱을 실행하는데 필요한 데이터베이스 연결, 방화벽 백엔드와의 통신, 키 보안에 도움이 되는 볼륨, 네트워크, 시크릿 등 많은 리소스를 앱에 추가할 수 있으며, 선언적으로 관리됨

💡 핵심 패러다임은 선언적 모델 : 사용자가 원하는 상태를 제공하면 Kubernetes가 이를 실현함

ex. 인스턴스가 5개 필요한 경우 사용자가 다섯 개의 인스턴스를 시작하지 않고 Kubernetes가 자동으로 상태를 조절하며, 장애가 발생하더라도 사용 가능한 노드에 인스턴스를 생성해 조절

1. Node

1) 컨트롤 플레인

🔻 모든 Kubernetes 클러스터에는 컨트롤 플레인 노드가 필요하며 클러스터에 대한 전역 결정(ex.스케쥴링)을 내리고 클러스터 이벤트를 감지 및 응답함

2) 워커 노드

🔻 워크로드를 실행하는 워커 머신으로, 물리적(베어메탈) 머신이거나 가상머신(VM)일 수도 있음

🔻 Kubernetes 노드는 컨트롤 플레인에 의해 관리되며, 각 노드는 하나 이상의 pod를 호스트할 수 있음

3) kubelet

🔻 클러스터의 각 노드에서 실행되는 에이전트로, 컨테이너가 pod에서 실행되고 있는지 확인

🔻 다양한 메커니즘을 통해 PodSpec에 설명된 컨테이너가 실행 중이고 정상인지 확인

4) kube-proxy

🔻 클러스터의 각 노드에서 실행되는 네트워크 프록시로, Kubernetes Services 개념의 일부 구현

🔻 노드에서 네트워크 규칙을 유지 관리하며 해당 네트워크 규칙은 클러스터 내부와 외부의 네트워크 세션에서 pod로의 네트워크 통신을 허용함

5) 컨테이너 런타임

🔻 컨테이너 실행을 담당하는 소프트웨어

🔻 여러 컨테이너 런타임 지원 ex. docker, containerd, CRI-O, Kubernetes CRI(Container Runtime Interface)

2. Cluster

💡 클러스터는 노드의 그룹으로, 노드는 물리적 머신 또는 가상 머신이 될 수 있음

1) Kube API 서버

🔻 컨트롤 플레인에는 워커 노드와 비교하여 몇가지 고유한 역할이 포함되며, 가장 중요한 것은 정보를 가져오거나 Kubernetes 클러스터로 정보를 푸시하기 위한 모든 통신이 이루어지는 것이 kube API 서버

🔻 API 오브젝트에 대한 데이터의 유효성을 검사하고 구성

🔻 REST 작업을 수행하고 다른 모든 구성 요소가 상호 작용하는 클러스터의 공유 상태에 대한 프론트엔드 제공

2) 스케줄러

🔻 제약 조건과 사용 가능한 리소스에 따라 각 pod를 유효한 배치가 가능한 노드에 할당하는 컨트롤 플레인 프로세스

3) 컨트롤러 매니저

🔻 Kubernetes와 함께 제공되는 핵심 제어 루프를 임베드하는 daemon

🔻 API 서버를 통해 클러스터의 공유 상태를 감시하고 현재 상태를 원하는 상태로 이동시키기 위해 변경을 시도하는 제어 루프

4) etcd

🔻 모든 클러스터 데이터에 대한 백업 저장소로 사용되는 키 값 저장소

5) kubectl

🔻 Kubernetes 커맨드-라인 도구로, 애플리케이션을 배포하고, 클러스터 리소스를 검사 및 관리하고 로그를 볼 수 있음

3. Pods

pod는 논리적 애플리케이션을 구성하는 컨테이너 그룹
공통 데이터 볼륨을 공유할 수 있으며 동일한 네트워킹 네임스페이스도 공유
임시적이며 마스터 컨트롤러에 의해 위아래로 이동할 수 있음
레이블(이름-값)을 통해 pod 식별을 간단하고 효과적으로 할 수 있음

✔️ 컨테이너의 볼륨, 시크릿 및 구성 처리

✔️ 임시적이며 죽으면 자동으로 재시작되도록 설계

✔️ ReplicationSet에 의해 앱이 수평으로 스케일될 때 복사되며 각 pod는 동일한 컨테이너 코드를 실행

✔️ 워커 노트에서 실행

4. Deployments

✔️ pod를 실행하기로 결정할 수 있지만 죽으면 끝

✔️ Deployments를 사용하면서 pod가 지속적으로 실행될 수 있음

✔️ 다운타임 없이 실행중인 앱 업데이트 가능

✔️ pod가 죽었을 때 재시작하는 전략 지정

5. ReplicaSets

✔️ Deployments는 ReplicaSets를 생성할 수 있음

✔️ ReplicaSets은 앱이 원하는 수의 pod를 갖도록 보장

✔️ ReplicaSets은 Deployments에 따라 pod를 생성하고 확장

✔️ Deployments, ReplicaSets, pod는 배타적이지는 않지만 그렇게 될 수 있음

6. StatefulSets

✔️ 앱의 상태에 대한 정보 유지

✔️ 데이터베이스에는 상태가 필요

✔️ StatefulSets의 pod는 서로 호환되지 않음

✔️ 각 pod에는 컨트롤러가 모든 스케줄링에 대해 유지하는 고유하고 영구적인 식별자 존재

6. DaemonSets

✔️ 연속 프로세스를 위한 것

✔️ 노드 당 하나의 pod 실행

✔️ 클러스터에는 새로운 노드가 추가될 때마다 pod 시작

✔️ 모니터링 및 로그 수집과 같은 백그라운드 작업에 유용

✔️ 각 pod에는 컨트롤러가 모든 스케줄링에 대해 유지하는 고유하고 영구적인 식별자 존재

7. Services

✔️ pod에 액세스하기 위한 단일 엔드포인트

✔️ 클러스터와 최종적으로 pod 목록으로 트래픽을 라우팅하는 통합된 방법

✔️ Services를 사용하면 아무 영향 없이 pod를 올리고 내릴 수 있음

Day 50

📢 Kubernetes 플랫폼 선택

  1. 베어 메탈 클러스터

  2. 가상화

ex. VMWare

  1. 로컬 데스크톱 옵션

ex. Minikube

  1. Kubernetes Managed Services

ex. Amazon EKS, Microsoft AKS, Google Kubernetes Engine

  1. 기타

ex. Red Hat의 OpenShift

Day 51

Minikube를 사용하여 로컬 머신에서 Kubernetes 클러스터 시작하고 실행할 것

📢 Minikube

🔻 Minikube: macOS, Linux, Windows에서 로컬 Kubernetes 클러스터를 빠르게 설정 가능

  1. 프로젝트 페이지로 이동

시스템에 Docker 설치

  1. arkade

arkade
: 모든 앱과 Kubernetes용 CLI를 위한 마켓플레이스로, 시스템에서 사용할 수 있는 매우 편리한 작은 도구

1) 아래 깃 저장소 참고해 설치

https://github.com/alexellis/arkade

2) arkade get을 누른 후 툴이나 CLI를 사용할 수 있는지 확인

3) arkade get minikube 명령어로 바이너리 다운 => 사용 가능

  1. Kubernetes 클러스터 실행

1) minikube start

🔻 첫번째 kubernetes 클러스터(단일 minikube 클러스터가 단일 docker 컨테이너로 구성) 배포

2) 애드온

🔻 애드온을 포함한 명령으로 클러스터 배포 가능하므로 확인

🔻 minikube addons list로 사용가능한 애드온 확인

🔻 주로 CSI-host path-drivervolumesnapshots 애드온 사용

3) 추가 구성 정의

🔻 minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --kubernetes-version=1.21.2

apiserver를 임의의 API 포트 대신 6433으로 설정하고, container runtime도 containerd로 정의 (container runtime 기본값은 docker이고 CRI-O도 사용할 수 있음), 특정 Kubernetes 버전도 설정 가능

4) kubectl 설치

arkade get kubectl

5) 실행

kubectl get nodes

  1. kubectl

: Kubernetes 클러스터와 상호 작용하는데 사용되거나 상호작용할 수 있는 클리어로 퍼블릭 클라우드 전반의 엔터프라이즈 클러스터와 상호작용하는 데도 사용 가능

🔻 kubectl 명령어

https://unofficial-kubernetes.readthedocs.io/en/latest/

Day 52

🔔 VirtualBox 사용한 멀티노드 Kubernetes 클러스터 설정

📢 Vagrant

🔻 가상 머신의 라이프사이클을 관리하는 CLI 유틸리티

🔻 다양한 플랫폼에서 가상 머신을 스핀업 및 스핀다운하는데 사용

참고
https://devopscube.com/kubernetes-cluster-vagrant/

📢 Kubernetes 랩 환경

  1. 환경 구축에 필요한 vagrantfile을 폴더에 업로드

  2. 터미널에서 이 디렉토리로 이동

  3. PowerShell을 사용해 vagrant로 워크스테이션 명령 수행

vagrant가 없는 경우 arkade get vagrant 실행해 최신 버전의 vagrant 다운로드 설치 가능

  1. vagrant up

✔️ 가상 머신을 빌드하고 노드가 있다는 것 확인 가능

✔️ 각 노드에 kubectl을 배포해 클러스터에 액세스할 수 있도록 함

  1. vagrant ssh master

✔️ 액세스 가능하며 기본 사용자 이름과 비밀번호는 vagrant/vagrant

✔️ 원하는 경우 vagrant ssh node01vagrant ssh node02를 사용해 작업자 노드에 액세스 가능

  1. kubectl get nodes

노드 클러스터와 상태 확인 가능

📢 Vagrant 파일 및 셸 스크립트 연습

  1. vagrantfile을 살펴보면 worker node, VirtualBox 내의 브리지 네트워크에 대한 네트워킹 IP 주소, 일부 이름 지정을 정의하고 있음
NUM_WORKER_NODES=2
IP_NW="10.0.0."
IP_START=10

Vagrant.configure("2") do |config|
    config.vm.provision "shell", inline: <<-SHELL
        apt-get update -y
        echo "$IP_NW$((IP_START))  master-node" >> /etc/hosts
        echo "$IP_NW$((IP_START+1))  worker-node01" >> /etc/hosts
        echo "$IP_NW$((IP_START+2))  worker-node02" >> /etc/hosts
    SHELL
    config.vm.box = "bento/ubuntu-21.10"
    config.vm.box_check_update = true

    config.vm.define "master" do |master|
      master.vm.hostname = "master-node"
      master.vm.network "private_network", ip: IP_NW + "#{IP_START}"
      master.vm.provider "virtualbox" do |vb|
          vb.memory = 4048
          vb.cpus = 2
          vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      end
      master.vm.provision "shell", path: "scripts/common.sh"
      master.vm.provision "shell", path: "scripts/master.sh"
    end

    (1..NUM_WORKER_NODES).each do |i|
      config.vm.define "node0#{i}" do |node|
        node.vm.hostname = "worker-node0#{i}"
        node.vm.network "private_network", ip: IP_NW + "#{IP_START + i}"
        node.vm.provider "virtualbox" do |vb|
            vb.memory = 2048
            vb.cpus = 1
            vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
        end
        node.vm.provision "shell", path: "scripts/common.sh"
        node.vm.provision "shell", path: "scripts/node.sh"
      end
    end
  end
  1. master.vm.provision "shell", path: "scripts/common.sh"

✔️ common.sh 스크립트는 노드를 준비하는데 초점을 맞추며 3개의 노트 모두에서 실행될 것이고 기존의 모든 Docker 구성 요소를 제거하고 Docker와 ContainerD, kubeadm, kubelet, kubectl을 다시 설치

✔️ 시스템의 기존 소프트웨어 패키지도 업데이트

  1. master.vm.provision "shell", path: "scripts/master.sh

✔️ master.sh 스크립트는 컨트롤 플레인 노드에서만 실행되며, 이 스크립트는 kubeadm 커맨드를 사용하여 Kubernetes 클러스터를 생성

  1. node.vm.provision "shell", path: "scripts/node.sh"

✔️ 단순히 마스터가 생성한 구성을 가져와서 우리 노드를 Kubernetes 클러스터에 추가

📢 Kubernetes 클러스터에 액세스

🔻 현재까지 이전 섹션에서 배포한 minikube 클러스터와 VirtualBox에서 배포한 3노드 클러스터 2개 존재

  1. 클러스터에서 kubeconfig 파일을 가져와 복사하고 $HOME/.kube/config 위치로 이동

  2. kubectl cluster-infokubectl get nodes를 실행하여 클러스터에 액세스할 수 있는지 확인

Day 53

📢 로컬 워크스테이션에 Rancher 배포 및 Rancher UI 액세스

  • 로컬 워크 스테이션을 사용하고 Rancher를 docker 컨테이너로 실행하고 싶은 경우
  1. sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher
    컨테이너 이미지를 가져온 다음 Rancher UI에 액세스

  2. 컨테이너가 실행 중이면 https://localhost

로그인 페이지가 나타나는데 Windows용 bash를 사용해 비밀번호 입력

로그인하면 다음 페이지에서 새 비밀번호 정의 가능

로그인이 완료되면 Rancher 배포의 일부로 로컬 K3 클러스터가 프로비저닝된 것 확인 가능

📢 Rancher 살펴보기

  1. 로컬로 배포된 K3S 클러스터

클러스터 내부에서 어떤 일이 일어나고 있는지 확인 가능 + pod,코어, 메모리에 대한 통계 존재

  1. 앱 및 마켓플레이스

여러 개의 다른 클러스터를 실행하거나 관리할 수 있는 기능을 제공 + 마켓플레이스를 사용해 애플리케이션 쉽게 배포 가능

  1. 클러스터 액세스 시 kubectl 사용 가능

Rancher에서 관리 중인 클러스터에 액세스해야 하는 경우 선택한 클러스터에 대한 kubectl 셸을 열 수 있음

📢 새 클러스터 생성

  1. vagrant up

virtualbox에서 3개의 가상 머신 생성하는 프로세스 시작

  1. custom으로 클러스터 생성

  2. 활성화할 적절한 서비스와 함께 각 노드에서 실행해야 하는 등록 코드(etcd, 컨트롤 플레인 및 워커)를 제공

코드는 마스터 노드의 경우로, etcd와 컨트롤 플레인이 필요

sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.6.3 --server https://10. 0.0.1 --token mpq8cbjjwrj88z4xmf7blqxcfmwdsmq92bmwjpphdkklfckk5hfwc2 --ca-checksum a81944423cbfeeb92be0784edebba1af799735ebc30ba8cbe5cc5f996094f30b --etcd --controlplane
  1. 각 워커 노드에 대한 등록 프로세스를 반복

  2. 마켓플레이스를 활용하여 애플리케이션을 배포할 수 있는 클러스터를 실행할 수 있음

sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.6.3 --server https://10. 0.0.1 --token mpq8cbjjwrj88z4xmf7blqxcfmwdsmq92bmwjpphdkklfckk5hfwc2 --ca-checksum a81944423cbfeeb92be0784edebba1af799735ebc30ba8cbe5cc5f996094f30b --worker

Day 54

📢 Kubernetes에 앱 배포

🔔 (1) YAML 파일 (2) Helm 차트 방식 존재

🔔 Minin-kube 클러스터 사용

  1. YAML 파일

🔔 표준 상태 비저장 애플리케이션 nginx 사용해 pod 제공해 호스팅하는 서비스 생성

(1) YAML 파일 생성

파일명: nginx-stateless-demo.yml

apiVersion: v1
kind: Namespace
metadata:
  name: nginx
  "labels": {
    "name": "nginx"
  }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: nginx
spec:
  selector:
    app: nginx-deployment
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

(2) 클러스터 확인

kubectl get namespace를 통해 nginx 네임스페이스가 없는지 확인

(3) 배포

🔻 YAML 파일 위치로 이동한 후 kubectl create -f nginx-stateless-demo.yml 실행

3개의 오브젝트가 생성되고 네임스페이스, 배포 및 서비스가 생성된 것 확인 가능

🔻 kubectl get namespace

새 네임스페이스 존재 확인

🔻 kubectl get pods -n nginx

네임스페이스에 pod가 있는지 확인

🔻 kubectl get service -n nginx

서비스가 생성되었는지 확인

🔻 kubectl get deployment -n nginx

deployment 확인

🔻 kubectl get all -n nginx

하나의 YAML 파일로 배포한 것 볼 수 있음

(4) 파일 편집

kubectl edit deployment nginx-deployment -n nginx

터미널 내에서 텍스트 편집기를 열고 편집

(5) kubectl 사용해 편집

kubectl scale deployment nginx-deployment --replicas=10 -n nginx

레플리카 수 변경 가능

⭐️ 빠르게 스핀업 및 스핀다운할 수 있을 뿐 아니라 애플리케이션을 빠르게 확장 및 축소할 수 있음

=> 웹 서버라면 부하가 많을 때 확장하고 부하가 적을 때 축소 가능

📢 앱 노출

  1. 개념

1) ClusterIP

🔻 표시되는 IP는 클러스터 내부 네트워크에 있는 클러스터 IP

🔻 클러스터 내에서만 사용 가능

2) NodePort

🔻 NAT를 사용해 클러스터가 선택한 각 노드의 동일한 포트에 서비스 노출

3) 로드 밸런서

🔻 현재 클라우드에 외부 로드 밸런서 생성

4) 포트 포워드

🔻 로컬 호스트에서 내부 Kubernetes 클러스터 프로세스에 액세스하고 상호작용할 수
있음

🔻 테스트 및 결함 발견에만 사용됨

  1. 실행

1) kubectl port-forward deployment/nginx-deployment -n nginx 8090:80

🔻 로컬 워크 스테이션을 사용해 액세스를 포트 포워딩

🔻 해당 터미널 사용할 수 없음

2) kubectl delete service nginx-service -n nginx

🔻 기존 서비스 삭제

3) 새로운 서비스 생성

expose 사용하고 NodePort로 변경

kubectl expose deployment nginx-deployment --name nginx-service --namespace nginx --port=80 --type=NodePort

4) 서비스에 대한 터널 생성

minikube --profile='mc-demo' service nginx-service --url -n nginx

5) 브라우저를 열고 터미널에서 링크 클릭

📢 Helm

: 애플리케이션을 배포할 수 있는 또 다른 방법으로, Kubernetes를 위한 패키지 관리자

Day 55

📢 Kubernetes의 State와 Ingress

🔻 지금까지는 상태 비저장에 관한 것이었고, Stateful 애플리케이션(저장상태)과 데이터베이스가 제대로 작동하려면 호스트 이름, IP 등 변경되지 않는 고유 ID를 통해 pod가 서로 연결될 수 있도록 해야함

ex. Stateful 애플리케이션: MySQL 클러스터, Redis, Kafka, MongoDB

📢 Stateful 애플리케이션

🔻 Kubernetes가 스케줄링 위치에 관계없이 유지 관리하는 고유하고 영구적인 ID와 안정적인 호스트 이름을 가진 pod 집합

🔻 특정 StatefulSet pod의 상태 정보 및 기타 복원력 있는 데이터는 StatefulSet과 연결된 영속성 디스크 스토리지에 유지

📢 Deployment vs StatefulSet

✔️ Stateful 애플리케이션을 복제가 더 어려움

✔️ 배포(Stateless 애플리케이션)에서 pod를 복제하는 것은 동일하며 상호 교환 가능

✔️ 임의의 해시를 사용하여 임의의 순서로 pod를 생성

✔️ 모든 pod에 로드 밸런싱하는 하나의 서비스

StatefulSet 또는 StatefulSet 애플리케이션의 경우 어려운 점

✔️ 동시에 생성하거나 삭제할 수 없음

✔️ 임의로 주소를 지정할 수 없음

✔️ 레플리카 pod는 동일하지 않음

cf) Deployment는 pod명이 app-7469bbb6d7-9mhxd와 같이 설정되지만 StatefulSet은 mongo-0과 같이 설정

📢 PV(Persistent Volume. 영속성 볼륨)

✔️ 데이터를 저장하기 위한 클러스터 리소스(예: CPU 및 RAM)

✔️ YAML 파일을 통해 생성

✔️ 실제 물리적 스토리지(NAS)가 필요

✔️ Kubernetes 클러스터에 대한 외부 통합

✔️ 스토리지에 다양한 유형의 스토리지를 사용

✔️ PV는 네임스페이스가 없음

✔️ 로컬 스토리지를 사용할 수 있지만 클러스터의 한 노드에 한정

✔️ 데이터베이스 지속성은 원격 스토리지(NAS)를 사용

📢 PVC(Persistent Volume Claims. 영속성 볼륨 Claims)

🔻 애플리케이션에서 영속성 볼륨 Claims하지 않으면 사용되지 않음

✔️ YAML 파일을 통해 생성

✔️ 영속성 볼륨 Claims은 pod 구성(볼륨 어트리뷰트)에서 사용

✔️ PVC는 pod와 동일한 네임스페이스에 존재

✔️ 볼륨이 pod에 마운트됨

✔️ pod는 여러 가지 볼륨 유형(ConfigMaps, Secrets, PVC)을 사용

📢 ConfigMaps | Secrets

✔️ pod의 구성 파일

✔️ pod의 인증서 파일

📢 StorageClass

✔️ YAML 파일을 통해 생성

✔️ PVC가 영속성 볼륨을 Claims할 때 동적으로 프로비저닝

✔️ 각 스토리지 백엔드에는 프로비저너가 있음

✔️ 스토리지 백엔드는 (프로비저너 속성을 통해) YAML에 정의됨

✔️ 기본 스토리지 공급자 추상화

✔️ 해당 스토리지에 대한 파라미터 정의

📢 실습

🔻 CSI-hostpath-driver 사용

  1. minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --kubernetes-version=1.21.2

지속성을 사용하는 기능과 애드온을 갖기 위해 사용하는 minikube 명령어

  1. StorageClass 구성

🔻 애플리케이션의 YAML 파일 구성

https://github.com/MichaelCade/90DaysOfDevOps/tree/main/2022/Days/Kubernetes

(1) kubectl patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

CSI-hostpath-sc 스토리지 클래스를 기본값으로 설정

(2) kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

StorageClass에서 기본 어노테이션 제거

(3) kubectl get storageclass

storageclass 확인

(4) kubectl get namespace

Pacman 네임스페이스가 없는 상태에서 시작

(5) kubectl create -f pacman-stateful-demo.yaml

YAML 파일 배포

(6) kubectl get namespace

네임스페이스 생성 확인

(7) kubectl get all -n pacman

네임스페이스 내부에서 여러가지 일이 일어남을 확인

(8) kubectl get pv

네임스페이스가 없는 영속성 볼륨 얻을 수 있음

(9) kubectl get pvc -n pacman

네임스페이스가 있는 영속성 볼륨 claims 얻을 수 있음

📢 게임 플레이하기

  1. 애플리케이션 액세스

kubectl port-forward svc/pacman 9090:80 -n pacman

  1. DB에 저장할 점수 생성

  2. pod 삭제

kubectl delete pod mongo-0 -n pacman

=> 일정 시간동안 점수를 볼 수 없지만 이후 다시 확인 가능

  1. 대규모 Pacman 파티 주최하는 경우 확장 가능

kubectl scale deployment pacman --replicas=10 -n pacman

📢 Ingress

🔻 지금까지는 포트 포워드를 사용하거나 Minikube 내 특정 명령어를 사용하여 애플리케이션 액세스했지만, 프로덕션 환경에서는 이 방법이 작동하지 않음

🔻 Ingress는 애플리케이션을 노출하는 더 나은 방법을 제공하며, 이를 통해 Kubernetes 클러스터 내에서 라우팅 규칙을 정의할 수 있음

🔻 Ingress의 경우, 애플리케이션의 내부 서비스에 대한 포워드 요청을 생성

📢 Minikube에서 Ingress 구성

  1. 클러스터에서 Ingress 활성화
    minikube --profile='mc-demo' addons enable ingress

  2. ingress-nginx 네임스페이스 확인
    kubectl get ns

  3. Pacman 실행을 위해 Ingress YAML 구성
    kubectl create -f pacman-ingress.yaml

  4. ingress 확인
    kubectl get ingress -n pacman

참고
Docker Desktop 설치
[https://docs.docker.com/desktop/install/windows-install/]

<추가 자료>
https://www.samsungsds.com/kr/insights/docker.html

0개의 댓글