도커와 쿠버네티스 - 쿠버네티스(1)

Ho Kim·2021년 3월 13일
3
post-thumbnail

쿠버네티스란 무엇인가


도커는 컴퓨터에 격리된 프로세스 공간을 만들어 가상 환경을 구축해 주었습니다. 그렇다면 도커와 같이 자주 언급되는 쿠버네티스는 무엇일까요?

쿠버네티스를 한단어로 표현하면 "관리자" 입니다.

도커파일 하나에 모든 서비스를 집어넣고 구동시킨다면 굳이 관리자가 따로 필요하지는 않을겁니다. 하지만 단일 서비스로 구동시키게 되면 그 안에서 오류가 발생해 서비스 하나가 다운될 경우, 그 안에 포함된 모든 서비스를 이용할 수 없게 됩니다.

phpmyadmin, mysql, wordpress를 하나의 서비스로 구동시키는 중에 phpmyadmin가 다운되면 모든 서비스가 같이 다운됩니다.

각 컨테이너의 서비스를 독립적으로 보장해 주기 위해 때문에 컨테이너를 여럿 만들게 되었고, 그 컨테이너를 관리해주어야할 필요성이 생겼습니다.

그래서 사용하는 것이 쿠버네티스입니다.

쿠버네티스는 만들어둔 컨테이너들을 자동으로 배포해주고, 스케줄링해주며, 오류가 생겼을때 알아서 처리해줍니다. 그 외에도 여러 관리 기능을 가지고 있습니다.

 1. 각 서비스에 대해 고유한 ip주소를 부여 
 
 2. 업데이트중에서 서비스를 사용할 수 있도록 스케줄링
 
 3. 오류가 생긴 컨테이너는 자동으로 재시작
 
 4. 실행중에 문제가 발생하면 쿠버네티스는 자동적으로 변경사항을 롤백
 
 ...

몇가지 설정만 해주면 거의 모든걸 쿠버네티스가 알아서 해주는 셈입니다.

쿠버네티스로 파드 생성하기


자세한 튜토리얼은 subicura님의 '쿠버네티스 안내서'를 추천드립니다.
여기서는 대강의 흐름만 설명드릴 예정입니다.


쿠버네티스를 만났을 때 처음 저를 반긴 건 '파드' 라는 낯선 이름이었습니다.

파드가 뭘까요?

파드(Pod) 는 하나 이상의 컨테이너의 그룹이다.

파드는 간단하게 생각하자면 일종의 그룹입니다. 파드는 그 안에서 컨테이너끼리 저장소의 리소스, 임시 네트워크 ID를 공유합니다. 하나의 단일 컨테이너만 들어있어도 되지만, 여러 컨테이너가 어떤 데이터를 밀접하게 공유해야한다면 하나의 파드에 넣어서 관리를 쉽게 합니다.


1. 파드의 라이프사이클

쿠버네티스를 작동시키다보면 상태를 자주 확인해야 합니다.

어떤 단어가 어떤 상태를 의미하는지 알아봅시다.

+) 노드란 애플리케이션을 구동하는 작업자(worker machine)를 말합니다.
1. Pending
파드가 준비되고 있을때 나타납니다.

2. Running
파드가 노드에 바인딩되었고, 적어도 하나의 컨테이너가 실행 중일때 나타납니다.

3. Succeeded	
파드에 있는 모든 컨테이너가 성공적으로 종료되었을때 나타납니다.

4. Failed
파드에서 적어도 하나 이상의 컨테이너가 실패로 종료되었을때 나타납니다. 
non-zero 상태로 빠져나왔거나(exited) 시스템에 의해서 종료(terminated)되었을때 실패로 간주됩니다.

5. Unknown
알 수 없는 이유로 파드의 상태를 얻을 수 없을때 나타납니다. 
일반적으로 파드가 실행되어야 하는 노드와 통신하는데 오류가 발생했을때 생깁니다.

2. 쿠버네티스에서의 파드 생성

쿠버네티스를 처음 접했을때 제일 많이 보이는 단어는 "파드"지만 직접 개별 파드를 만드는 경우는 드뭅니다. 파드를 만들고 관리해주는 <워크로드 리소스>라는것이 있기 때문입니다.

워크로드는 쿠버네티스에서 구동되는 애플리케이션입니다.

1) 워크로드 리소스

워크로드 리소스는 파드에 문제가 생겼을때 복제/롤아웃/자동복구를 실행합니다. 파드에 오류가 생겼을 경우 파드의 작동 중지를 감지하고 대체 파드를 생성한 뒤, 대체 파드를 정상 노드에 배치하는 작업을 알아서 해줍니다.

워크로드 리소스에는 무엇이 있을까요?

1. 레플리카셋 
 레플리카, 즉 여러 복제 파드의 실행을 항상 안정적으로 유지합니다. 
 레플리카셋은 잘 쓰지 않고 대신 레플리카셋을 포함하고 있는 디플로이먼트를 사용합니다.

1. 디플로이먼트
  파드와 레플리카셋에 대한 업데이트를 제공합니다.
  
  디플로이먼트는 의도하는 상태를 명시하고 있고, 
  디플로이먼트 컨트롤러를 통해 현재 상태에서 의도하는 상태로 비율을 조정하며 변경합니다.
  이 덕분에 여러 레플리카셋을 사용하면 서비스가 끊기지 않은 상태로 업데이트를 적용할 수 있습니다.
  
  디플로이먼트에서 레플리카셋을 사용하면 파드가 예기치 못하게 종료되었을때 자동으로 다시 실행시킵니다.
 
2. 스테이트풀셋
디플로이먼트와 유사하지만, 파드들의 순서 및 고유성을 보장하며 각 파드의 독자성을 유지합니다.
 
3. 데몬(Daemon)셋
 노드가 파드의 사본을 실행하도록 합니다.

4.Job
 파드를 생성하고, 지정된 수의 파드가 성공적으로 종료될 때까지 계속해서 파드의 실행을 재시도합니다.

이 포스트에서는 디플로이먼트를 이용해 파드를 생성하는 방법에 대해 알아보겠습니다.

2) yaml 파일 작성하기

쿠버네티스를 통해 파드를 생성하려면 yaml 파일을 작성해야 합니다.
yaml은 띄어쓰기를 특히 엄격하게 지켜야 합니다.

쿠버네티스의 yaml 파일은 네가지를 명시해야 합니다.

apiVersion:
kind:
metadata:
spec:


1. apiVersion
쿠버네티스에서 사용할 API 버전을 의미합니다.
서비스는 v1, 워크로드 리소스는 대부분 apps/v1을 사용합니다.

2. kind
무엇을 배포할지를 명시하는 부분입니다. 
이번에는 디플로이먼트를 배포할 것이므로 kind: Deployment 로 적어줍니다.

3.metadata
정보를 명시하는 부분입니다. 
name으로 디플로이먼트가 명명됩니다.
(kubectl get all 등의 명령어로 확인 했을때 해당 이름으로 나타납니다.)
어플리케이션을 서비스하거나 레플리카셋을 만들때, 
메타데이터 안의 라벨을 통해 서비스/복제할 대상을 구분합니다.

4.spec
 디플로이먼트를 어떻게 구성할 것인지에 대해 자세히 서술하는 부분입니다. 
 어떤 이미지를 가져오고 어떤 템플릿으로 레플리카셋을 만들 것인지 등을 명시합니다.

간단하게 nginx를 만들어봅시다
파일 이름은 nginx.yaml 로 하겠습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Deployment를 배포할 것이므로

apiVersion에는 apps/v1를
kind에는 Deployment를 넣어줍니다.
metadata에 이름과 라벨을 붙여줍니다.

spec에는 Deployment를 어떻게 구성할 것인지 적혀있습니다.
containers: 컨테이너를 구성하는데
- name: nginx 그 컨테이너의 이름은 nginx이고,
image: nginx:1.14.2 도커허브에서 nginx이미지를 가져와 실행시킵니다.
ports: - containerPort: 80 그리고 80번 포트를 열어줍니다.

이제 디플로이먼트를 실행시켜봅시다.

kubectl apply -f nginx.yaml

디플로이먼트가 작동하고있는지 확인하고 싶다면
kubectl get all 혹은 kubectl get deployments 명령어를 이용하면 됩니다.

포트를 열어주긴 했지만 아직 웹페이지에 접속해 확인해 볼 수는 없습니다.
파드가 네트워크 서비스에 노출되어있지 않기 때문입니다.
네트워크에 연결해주기 위해서는 생성한 디플로이먼트를 expose 해주거나 Service 시켜주어야 합니다.

그 방법에 대해서는 다음포스트에서 디플로이먼트로 레플리카 만드는 방법과 함께 알아보겠습니다.




+) yaml에서 -는 배열을 의미합니다. 컨테이너도 여러개일 수 있고, 포트도 여러개일 수 있기 때문에 데이터의 배열을 넣어주어야 합니다.

컨테이너가 여러개라면

      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
      - name: nginx2
        image: nginx:1.14.2
        ports:
        - containerPort: 80

포트가 여러개라면

      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443

이렇게 나타낼 수 있습니다.

배열에 값이 여러개 들어있다면 반드시 이름을 지정해주어야 합니다.

0개의 댓글