728x90
반응형

Worker Node를 잠시 내루거나, 업데이트가 필요할 때

Node 내부의 Software를 업그레이드 해야하거나, 혹은 문제가 생겼을 경우에 해당 Node를 안전하게 내리고 다시 올려야 합니다.

그럼 문제가 되는 부분은 해당 Node에서 실행되고 있던 Pod들입니다. 만약 아무도 모르는 어떠한 오류로 인하여 Worker Node-1이 내려간다고 가정하였을 때, 사용자 입장에서 해당 Pod에 접속하다가 오류를 만나게 될 것입니다.

위의 그림에서처럼 만약 사용자가 파란색 Pod에 접속하여 서비스를 이용하고 있었을때, Worker Node-1번이 이유모를 오류로 내려갔다고 가정해봅시다.

그럼 사용자는 LoadBalancer와 같은 경로를 통해 Worker Node-2번에 배포되어 있는 파란색 Pod로 접속하면 다시 서비스가 가능합니다.

이렇게 ReplicaSet이 여러 개이고, 여러 Node에 흩어져 있는 경우는 문제가 되지 않습니다.

문제가 되는 경우는 아래와 같습니다.

  1. 사용자가 초록색 Pod에 접속하다가 Worker Node-1번이 내려간 경우
  2. 사용자가 빨간색 Pod에 접속하다가 Worker Node-3번이 내려간 경우

이런 경우에는 사용자는 기존에 이용하던 서비스를 이용할 수 없게 됩니다.

쿠버네티스는 어떻게 하고 있을까?

쿠버네티스는 Worker-Node가 다시 올라오길 기다립니다.

내려갔었던 Node가 바로 다시 돌아오면 사실 문제가 없습니다. 근데 이 '바로' 는 과연 몇 초, 몇 분일까요?

이건 kube-controller-manager 가 정할 수 있으며 default는 5분입니다.

해당 내용은 아래와 같은 명령어로 수정할 수 있습니다.

즉, node가 다운될때마다 master node는 5분동안 기다립니다. 해당 시간을 Pod Eviction Timeout이라고 합니다.

만약 Pod Eviction Timeout이 지난 후에 node가 돌아오면 node는 공백이 된 상태로 돌아오게 됩니다. (안에 아무 Pod가 없는 상태)

이렇게 되면 문제가 될 수 있기 때문에 명령어를 통해 미리 방지할 수 있게 도와줍니다.

drain , uncordon , cordon

drain - worker node에 있는 Pod들을 안전하게 다른 Node들로 이동

drain 명령어는 worker node에 있는 Pod들을 안전하게 다른 Node들로 이동시켜줍니다.

만약 node-1이 문제가 생길 것 같다던가 모든 Pod들을 옮기고 update를 진행해야 하는 경우에 아래와 같은 명령어를 사용합니다

그래서 모든 작업이 다른 Node로 이동할 수 있게 합니다.

즉, drain 명령어를 실행하면 해당 node-1에서 pod 들이 정상적으로 종료되고, 다른 Node에서 Node-1에서 실행되던 Pod들이 재현되게 됩니다ㅏ.

restriction을 끝내지 않는 이상 위의 명령어를 입력하게 되면 node-1에서는 scheduling에서 제외되어서 pod 일정을 잡을 수 없게 됩니다.

그럼 다시 node-1이 정상적으로 돌아오더라도 node-1은 scheduling에서 제외됩니다.

다시 node-1이 일을 하게 하려면 uncordon 이라는 명령어를 사용하여야 합니다.

uncordon - Worker Node Restriction 해제

위의 명령어를 사용하면 node-1이 다시 Pod Schedule이 가능하게 됩니다.

물론 그렇다고 해서 이동한 Pod들이 다시 돌아오는 것은 아닙니다. 다른 Node에서 Pod는 그대로 실행되고, 이후에 Pod가 삭제되거나 새로 생성될 때 Schedule 될 수 있습니다.

그럼 만약 Node-1에 있던 Pod들을 이동시키지 않고, 해당 Node-1이 더이상 Schedule하지 않도록 하려면 cordon 명령어를 사용합니다.

cordon - 기존 node에서 pod를 종료하거나 이동시키지 않고 싶을 때

cordon은 drain과 달리 기존 node에서 pod를 종료하거나 이동시키지 않습니다.

단순히 해당 node에 새 pod가 scheduling되지 않도록 하는 명령어 입니다.

728x90
반응형
728x90
반응형

쿠버네티스를 macOs m1 환경에서 실행하기

https://velog.io/@pinion7/macOs-m1-환경에서-kubernetes-시작하기 를 참고하였습니다.

싱글 노드 클러스터 배포판 → minikube를 사용함

kubernetes로 배포 실습

  1. kubectl로 kubernetes 클러스터 생성

kubectl apply -f wordpress-k8s.yml

  1. 생성된 클러스터와 여러 컴포넌트 리스트 확인

kubectl get all

  1. port-forwarding을 해주어야 한다

kubectl port-forward service/wordpress 4000:80

  1. 위에건 로컬로 실행하는 것이고 minikube NodePort를 통해서도 접근할 수 있다.
    minikube service wordpress

  • 커맨드를 입력하면 일단 최종 target port가 보인다. 최종적으로 도달하고자 하는 오브젝트는 Pod이기 때문에, 이건 Pod에 붙는 Port를 의미한다.
  • 다만 클러스터 내부에 있는 Pod를 외부에서 접근할 수는 없기 때문에, NodePort가 외부 트래픽을 받을 수 있는 외부 노출 URL(192.168.49.2:32374)을 만들어 준 것이다. 이렇게 NodePort를 통하면 Pod에 트래픽이 전달될 수 있다.
    • 원래는 192.168.49.2:32374로 접근이 가능해야 하는데, 말했듯 m1 운영체제의 한계로 불가능하다.
  • 그래서 NodePort url을 로컬에 포워딩 할 수 있어야 하는데, minikube service 커맨드가 그걸 가능하게 해준다.
    • 보다시피 포워딩된 로컬 url(127.0.0.1:63828)이 제공된 것이다. (참고로 로컬 포트는 랜덤하게 지정된다)
  • minikube 커맨드는 동시에 해당 로컬 url로 browser를 아래처럼 자동으로 띄워주기도 한다.

4) 실습으로 살펴본 docker와 kubernetes

  • yml 파일로 본 docker와 kubernetes의 구조적 차이
    • docker: 구조가 간단하다. docker의 기본 단위는 컨테이너다.docker-compose.yml을 보면, 하나의 Service 안에 컨테이너가 모두 포함되어 있다. 즉, compose 진행을 위해 필요한 명세는 2개 이상의 컨테이너와 포트 매핑, 기타 환경변수 정도이다.
    • kubernetes: 구조가 복잡하다. kubernetes의 기본 단위는 컨테이너가 아닌 클러스터이다. 클러스터는 최소 1개 이상의 노드로 구성이 되고, 노드에 띄워지는 워크로드를 구성하는 요소들을 오브젝트라고 칭한다. wordpress-k8s.yml 파일을 보면, wordpress 워크로드와 mysql 워크로드 각각에 Deployment & Service 리소스로 만든 오브젝트가 존재한다. 그리고 그 안에는 메타데이터, 컨테이너, 환경변수, 포트 등이 상세하게 명세되어 있다.
  • docker와 kubernetes에 대한 나의 이해..
    • 구조 파악을 통해 확인할 수 있는 차이는, 배포에 있어 필요한 명세나 스케일이 확연히 다르다는 것이다. 깊게 하나하나 공부하지 않은 현 상태에서 아직 명확한 차이를 짚을 수는 없다.
    • 또한 분명한 건 kubernetes를 사용한다고 하여 docker를 배제하는 것은 아니다. minikube만 봐도 알 수 있듯이, 분명 kubernetes 내부에서 docker에 대한 의존성을 가지고 있다. kubernetes 자체적으로 docker를 nesting해서 사용하는 것이 아닐까 싶다.
    • 명확한 kubernetes의 구조 및 철학을 이해하려면 일단 클러스터와 주요 골격이 되는 노드 및 각종 컴포넌트, 오브젝트 등의 개념부터 알아야 할 것으로 보인다. 이는 추후 블로깅에서 자세히 다뤄보겠다.쿠버네티스 환경에서 애플리케이션을 배포하는 과정
    • sudo docker build --build-arg DEPENDENCY=build/dependency -t jakeheon/githubaction --platform linux/amd64 .
    • 컨테이너 이미지 생성컨테이너 레지스트리로 이미지 업로드쿠버네티스에서 컨테이너 이미지를 바탕으로 Deployment 생성
    • 스프링 어플리케이션을 실행시키기 위해서는 gradle wrapper를 사용해 jar 파일을 만든 후 실행시켜야 합니다.
    • 스프링 프로젝트를 Container 이미지 파일로 만들기 위해서는 다양한 방법들이 존재 합니다.용어 정리 및 기타
    • kubectl apply -f deployment.yaml kubectl get deployment kubectl get pod
    • 쿠버네티스에 컨테이너화 된 어플리케이션을 배포하기 위해서는 디플로이먼트를 생성해야합니다.
    • 파드 : 쿠버네티스 클러스터에서 실행되는 최소 단위로 독립적인 공간과 사용 가능한 IP를 지니고 있음
    • 레플리카셋 : 명시된 동일 파드 개수를 항상 실행시켜주는 것을 보장 시켜주는 쿠버네티스 오브젝트
    • 디플로이먼트 : 파드와 레플리카셋에 대한 선언적인 업데이트를 제공하는 쿠버네티스 오브젝트로 오늘날에는 쿠버네티스 상에서 컨테이너를 배포할 때 디플로이먼트를 사용
728x90
반응형
728x90
반응형

쿠버네티스 환경 구축 3단계 (1)

쿠버네티스

쿠버네티스는 컨테이너 애플리케이션을 분산 환경에서 운용 관리하기 위한 오케스트레이션 툴이다. (단어 하나씩 뜯어봤는데도,, 말이 어려워서 기억하기 위해..)

결과적으로는 온프레미스 환경에서 쿠버네티스를 사용할 것이지만, 일단 Azure를 사용해서 클라우드 환경에서 쿠버네티스를 사용해 보겠다!

컨테이너 이미지 빌드와 공개

전체적인 흐름

컨테이너 애플리케이션을 개발하고 운용할 때의 흐름을 알고, 순서대로 진행해 보겠다.

  1. 개발 환경 준비
    Azure를 실행하기 위해서 IDE나 로그인 등을 해야함
  2. 컨테이너 이미지의 작성 및 공유
    컨테이너를 동작시키려면 애플리케이션을 움직이기 위한 것들이 이미지로 있어야 한다. 필요한 것들로는 바이너리, OS, 네트워크 같은 설정들을 이야기 한다.
    만약 도커일 경우에는 Dockerfile이라는 텍스트 파일에 구성을 기술하고, 이것을 빌드하면 빌드된 것을 실행 환경에서 이용 가능한 레포지토리로 공유한다.
    (마치 로컬에서, github에 커밋을 하고 다른 컴퓨터에서 pull해서 사용하는 느낌이였다.)
  3. 클러스터 작성 (실제 환경 작성)
    실제로 컨테이너 애플리케이션을 작동시키는 서버를 구축해야 한다. 개발 환경이나 테스트 환경에서는 로컬 머신으로 작동시키지만, 서비스 공개할려면 클라우드 서비스를 사용하든지, 실제 서버 컴퓨터(온프레미스) 환경이 있어야 한다.

[ 1번의 진행과정 ]

쿠버네티스 클러스터

쿠버네티스 클러스터란, 쿠버네티스가 분산 환경에서 여러 대의 서버나 스토리지와 같은 컴퓨팅 리소스가 네트워크로 연결된 환경에서 각각 다른 역할을 가지면서 서로 협조해 가며 컨테이너 애플리케이션을 실행시키는 것을 의미한다.

쿠버네티스 클러스터를 만들려면 여러 대의 서버나 가상 머신에 쿠버네티스를 설치하고 네트워크 설정 등을 해야 한다.

클러스터를 쉽게 운용하기 위해서 먼저 Azure 컨테이너 서비스를 이용해보겠다!

  1. 먼저 Azure에 개인 계정을 만들어야 된다. (나는 건국대학교 학생 계정을 이용해서 1년 무료로 사용할 수 있다고 해서 학교 계정을 사용하였다)
  2. Azure 포털 사이트에서도 cli 창을 띄울 수 있었는데, 리눅스 명령어도 익힐 겸 Azure CLI 명령을 설치해서 할 수 있었다. (사이트에서 MSI 인스톨러로 다운받았다.)
  3. 만약 Azure에 로그인을 하면 cmd창을 켜서 az login을 입력하면, redirect페이지가 나오고 로그인이 된다.


4. Azure의 서비스를 이용하기 위해 리소스 프로바이더도 할당한다.

Azure 리소스 프로바이더를 활성화해야 하는 이유
Azure에서 리소스 프로바이더를 활성화해야 하는 이유는 해당 리소스를 생성하고 관리, 조작하기 위해서이다. Azure의 각각의 서비스는 Azure Resource Manager(ARM)이라는 것에 의해서 관리되는데, 리소스 프로바이더는 이 ARM에서 각각의 서비스에 대한 API 엔드포인트를 제공한다.

그래서 Azure 리소스를 만들거나 관리하려면 해당 리소스 유형에 대한 프로바이더가 활성화되어 있어야 한다.

예를 들어서 Azure Virtual Machines를 만들려면 Microsoft.Compute 리소스 프로바이더가 필요하다. 이 프로바이더는 Virtual Machine과 관련된 API 엔드포인트를 제공해서, 가상 머신의 생성, 삭제, 업데이트 등의 작업을 수행할 수 있도록 한다.

여기서는 Microsoft.Network, Storage, Compute, ContainerService 모두 활성화시켰다.

kubectl 명령

쿠버네티스 클러스터를 조작하려면 GUI를 사용해도 되는데, 일반적으로는 명령으로 조작한다고 한다.

명령으로 조작하기 위해서는 kubectl을 사용한다. kubectl 명령은 쿠버네티스 클러스터의 상태를 확인하거나 구성을 변경하기 위한 것이다. 개발을 하는 클라이언트 머신에 설치하면 된다.

나는 Window이기 때문에 쿠버네티스 페이지에 있는대로 따라하였다.

Install and Set Up kubectl on Windows

 

Install and Set Up kubectl on Windows

Before you begin You must use a kubectl version that is within one minor version difference of your cluster. For example, a v1.26 client can communicate with v1.25, v1.26, and v1.27 control planes. Using the latest compatible version of kubectl helps avoid

kubernetes.io

(몇번 잘못 입력한 다음에... 성공)

그럼 kubectl과 az 명령은 각각 언제 필요?

지금 명령만 2개를 설치했는데, 두 명령은 차이가 있다. kubectl 명령은 쿠버네티스 클러스터 안에서 움직이는 컨테이너 애플리케이션을 조작하는 것이고, az 명령은 Azure를 사용해서 쿠버네티스 클러스터 자체의 구축이나 삭제 등을 하는 것이다.

 

설치가 하다가 오래걸려서.. 2단계는 내일 써보겠다!

728x90
반응형

'CS > TIL' 카테고리의 다른 글

[DevOps] 도커  (0) 2023.03.21
가상메모리(Virtual Memory)  (0) 2023.02.17
Transaction과 Rollback  (0) 2023.02.14
Logging을 이용한 Database의 Recovery  (0) 2023.02.09
728x90
반응형

도커

  • 컨테이너를 실행하거나 컨테이너 이미지를 만들고 배포하는 플랫폼
  • 도커는 응용 프로그램을 실행 환경 단위로 패키지화해서 컨테이너 이미지를 만듬
  • 컨테이너 이미지는 컨테이너 레지스트리를 통해 개발 환경에서 배포 환경으로 배포

도커의 장점

  • 프로그램 속도가 빠르고, 릴리스하는데 문제가 없음
  • 응용 프로그램을 배포하기 쉽고 확장 가능

도커 엔진

  • 컨테이너 및 컨테이너 이미지를 관리하는 응용 프로그램
  • 클라이언트 서버 유형의 응용 프로그램(Client - Server)
  • 클라이언트인 도커 클라이언트에서 서버인 도커 데몬의 API에 접속해 컨테이너 및 컨테이너 이미지에 대한 다양한 작업을 수행할 수 있다.
  • 도커 클라리언트에서 도커 데몬 API에 접속하려면 도커 명령어를 실행해야 한다.

[도커 엔진을 구성하는 세가지 요소]

1. 도커 클라이언트

- 도커 데몬의 사용자 인터페이스가 되는 구성 요소다. 사용자는 도커 클라이언트를 조작해서 도커 데몬과 통신한다.

2. 도커 데몬

- 도커 클라이언트의 요청에 따라 도커 객체를 관리하는 구성 요소. 도커 클라이언트와 도커 데몬은 각각 클라이언트와 서버 역할을 하며, 도커 클라이언트의 요청에 따라 통신이 시작되고 도커 데몬의 응답으로 통신이 종료된다.

3. 컨테이너 레지스트리

- 컨테이너 이미지를 저장하기 위한 구성 요소. 도커 데몬은 도커 클라이언트의 요청에 따라 컨테이너 레지스트리와 통신해서 컨테이너 이미지를 내려받고 업로드한다.

도커 객체

- 도커 데몬의 관리 대상( 네트워크, 볼륨, 컨테이너, 컨테이너 이미지 등)

컨테이너 런타임

컨테이너를 다루는 도구

도커 엔진은 컨테이너 런타임을 포함하는 개념

도커

컨테이너 런타임 중에서 제일 유명한 것

컨테이너

  • 운영 체제에서 실행되는 프로세스인데 다른 프로세스와 격리되어 있다(외부 영향을 받지 않는 독립적인 환경에서 프로세스를 실행할 수 있다.)
    • 컨테이너를 외부와 격리하기 위해 네임스페이스라는 구조를 사용한다.

파일 시스템의 격리

  • 네임스페이스의 작동 방식을 구현하는 데 특히 중요한 것은 파일 시스템의 격리.
    • 파일 시스템 → 운영 체제의 기능 중 하나, 파일 시스템에 의해 데이터를 ‘파일’ 단위로 읽고 쓸 수 있다
  • 컨테이너는 컨테이너 전용 독립 파일 시스템을 사용한다.
  • 네임스페이스에서 파일 시스템을 격리하는 방식은 컨테이너 내 프로세스가 yum 및 apt와 같은 패키지 관리 시스템에 설치된 패키지에 의존하는 경우 특히 유용하다.
    • 리눅스 네임스페이스 : 프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능
    • 패키지 : 어떤 기능을 제공하는 프로그램을 한꺼번에 배포 형식으로 만든 것
    • 패키지 관리 시스템 : 패키지의 설치나 종속성을 관리하는 시스템 (yum, apt, brew)
  • 대부분의 경우 운영 체제의 파일 시스템에 다른 버전의 패키지가 공존하기는 어렵다.
  • 컨테이너를 사용하면 다른 버전의 패키지가 공존할 수 있다.

컨테이너와 가상 서버의 차이

  • 컨테이너와 가상 서버는 매우 비슷하다.
  • 결정적인 차이
    • 컨테이너는 본질적으로 프로세스와 동일
      • 하드웨어 에뮬레이션 없이 리눅스 커널을 공유해서 프로세스를 실행 
      • 네임스페이스와 같은 방식으로 다른 컨테이너와 프로세스에서 격리됨
    • 가상 서버는 하드웨어를 모방하는 소프트웨어
      • 운영체제 위에 하드웨어를 에뮬레이션하고 그 위에 운영체제를 올리고 프로세스 실행. 
      • 가상 서버에 운영 체제를 설치해 다른 가상 서버나, 가상 서버를 실행하는 물리 서버와 격리함.
    • 컨테이너는 다른 컨테이너와 프로세스와 운영체제(커널)을 공유함
    • 가상서버는 다른 가상 서버나 물리 서버와 운영 체제를 공유하지 않음
  • 컨테이너를 가상 서버와 비슷하다고 생각하는 것보다 특수한 프로세스라고 생각하는 편이 좋다.

컨테이너로 호스트 OS와 다른 OS를 사용한다는 말의 의미

  • 컨테이너는 호스트 머신의 운영 체제를 이용하고 있지만, 어떤 컨테이너가 우분투에 포함되는 소프트웨어 세트를 갖추고 있다면 그 컨테이너 내에서 실행되는 프로세스를 마치 우분투에서 실행되는 것처럼 보이게 할 수 있다.
  • 여러 운영 체제가 공존할 수 있다.

컨테이너가 있으면 가상 서버는 필요 없다?

  • 컨테이너는 운영 체제를 공유하므로 운영 체제 버전의 차이와 호환성에 따라 제대로 작동하지 않을 수 있다.
  • 반면 가상 서버는 각각 운영 체제를 설치하므로 운영 체제를 포함한 동일한 환경을 재현할 수 있다.

컨테이너 이미지

  • 컨테이너를 실행하기 위한 템플릿 → 컨테이너는 컨테이너 이미지로 생성
    • 클래스(컨테이너 이미지) - 객체(컨테이너)
  • 컨테이너 이미지의 대부분은 컨테이너를 실행하는 데 필요한 파일 시스템
    • 파일 시스템은 레이어라는 층이 겹쳐서 구성됨
    • 도커의 차분 관리와도 관련이 있다.

컨테이너 이미지의 생성

  • 컨테이너 이미지는 기본이 되는 컨테이너 이미지의 파일 시스템에 새로운 레이어가 겹쳐서 생성된다.
    • 예를 들어, Ubuntu OS 컨테이너 이미지가 있고, 이 컨테이너에 웹 서버인 nginx 프로그램과 구성 파일이 포함된 레이어를 겹쳐서 Ubuntu OS에서 실행되는 nginx 서버의 이미지를 만들 수 있다.
  • 컨테이너에서 셸을 기동한 후에 패키지 관리 시스템을 실행해서 수동으로 작성할 수 있다.
  • 그러나 보통은 컨테이너 생성 절차를 설명하는 텍스트 파일인 도커 파일을 사용해서 자동으로 만든다.

운영 체제 설치 디스크와 컨테이너 이미지로 운영 체제 사용하는 것의 차이

운영 체제 설치 디스크는 필요한 것을 복사해서 설치하는 것이지만, 컨테이너 이미지로 운영 체제를 사용하는 개념은 프로그램과 설정 파일을 컨테이너에서 접근해서 사용하는 것이다.

[컨테이너와 도커의 활용]

보통 우리가 애플리케이션을 개발하면, 로컬에서 앱을 만들고, OS, 네트워크 환경을 설정하고, 라이브러리나 미들웨어를 설치하여서 만든다. 근데 문제는 로컬에서는 잘 되던 프로그램이 실제 환경에 배포하면 정상적으로 움직이지 않는다. 이건 환경이랑 설정이 달라서 생기는 문제이다.

컨테이너를 사용하면 애플리케이션 실행에 필요한 모든 파일과 디렉토리를 통째로 컨테이너 이미지로 모을 수 있다.

그럼 우리가 앱을 개발해서 Dockerfile을 이용해서 컨테이너 이미지를 작성한다. 이 이미지는 OS 커널과 호환성이 있어서 컨테이너가 작동하는 환경이라면 이미지를 받아서 어디서든지 작동시킬 수 있다. 그럼 컨테이너를 작동시키는 곳에서는 어디서든 가능하게 되는 것이다.

컨테이너 이미지를 관리해주는 것은 레지스트리이다. 컨테이너 이미지는 레지스트리로 공유할 수 있다. 도커의 공식 레지스트리는 Docker Hub이다. 그럼 이제 우리가 Ubuntu같은 OS를 사용하고 싶으면 Ubuntu 베이스 이미지를 받아서 사용하면 된다.

(private 환경이라면 컨테이너 레지스트리는 도커 hub와 같은 시스템을 별도로 사용해야 한다)

 

 

728x90
반응형

+ Recent posts