쿠버네티스 실습 2 - 기본 사용법(1) > 도커 & 쿠버네티스

본문 바로가기

[실습] 쿠버네티스 실습 2 - 기본 사용법(1)

필기자
2023-11-14 01:07 1,096 0

본문

목차
  • 매니페스트
  • 파드 생성 및 관리
  • 디플로이먼트와 서비스 사용
  • 레플리카셋 사용

매니페스트

매니페스트(manifest)
  • 쿠버네티스의 오브젝트를 생성하기 위한 메타 정보를 yaml이나 json으로 기술한 파일
  • yaml이나 json은 데이터 표현의 한 양식
  • yaml 파일은 인간이 보고 이해하기 쉬운 형태로 최근에 더 많이 사용
  • yaml 파일에는 생성할 오브젝트나 컴포넌트 유형, 이름 등이 포함

20231114001344_1148507c42f4f4b2b80a57349a5efda8_rvva.png
디플로이먼트 YAML 파일 예시



apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myfront
        image: myphpimage
        volumeMounts:
        - name: html-volume
          mountPath: /var/www/html
        ports:
        - containerPort: 80
      - name: mytaskapi
        image: myphpimage
        volumeMounts:
        - name: task-volume
          mountPath: /var/www/html
        ports:
        - containerPort: 80
      - name: myuserapi
        image: myphpimage
        volumeMounts:
        - name: user-volume
          mountPath: /var/www/html
        ports:
        - containerPort: 80
      volumes:
      - name: html-volume
        hostPath:
          path: /path/to/your/html
      - name: task-volume
        hostPath:
          path: /path/to/your/php/task
      - name: user-volume
        hostPath:
          path: /path/to/your/php/user

서비스 YAML 예시

  • nodePort를 설정하지 않으면, 30000-32767 범위 내에서 사용 가능한 포트를 자동으로 할당


apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  type: NodePort #NodePort, LoadBalancer(kubectl get services 로 외부 서비스 IP 확인), ClusterIP(클러스터 내부에서만 접속, 외부접속 X)
  selector:
    app: myapp
  ports:
  - name: myfront
    port: 8011
    targetPort: 80
  - name: mytaskapi
    port: 8012
    targetPort: 80
  - name: myuserapi
    port: 8013
    targetPort: 80


파드 생성 및 관리

파드 생성(실습)

  • 파드 생성 명령어
    • kubectl create: 클러스터에 새로운 리소스를 생성
    • kubectl apply: create와 replace(생성된 오브젝트를 삭제하고 새로운 오브젝트를 생성)의 혼합
파드 생성

#create로 파드 생성
kubectl create deployment my-httpd --image=httpd --replicas=4 --port=80
  • 명령어 내용
    • deployment: 스테이트리스(Stateless) 형태의 파드 생성
    • my-httpd: 디플로이먼트 이름
    • --image=httpd: 파드를 생성하는데 사용되는 이미지
    • --replicas=1: running 상태를 유지할 파드 개수
    • --port=80: 파드에 접근할 때 사용할 포트 번호
20231114001728_1148507c42f4f4b2b80a57349a5efda8_5aa3.png


스테이트리스와 스테이트풀
  • 스테이트리스(stateless, 상태가 없는)
    • 사용자가 애플리케이션을 사용할 때 상태나 세션을 저장해 둘 필요가 없는 애플리케이션에서 사용
  • 스테이트풀(stateful)
    • 사용자가 애플리케이션을 사용할 때 상태나 세션을 별도의 데이터베이스에 저장해야 하는 애플리케이션에서 사용
    • 예시: 상품을 장바구니에 담고 구매하는 쇼핑몰, 금융 거래 사이트 등
20231114002009_1148507c42f4f4b2b80a57349a5efda8_h3h5.png



디플로이먼트 관리(실습)

디플로이먼트 목록 확인

kubectl get deployment
  • 목록 항목
    • READY: 레플리카의 개수
    • UP-TO-DATE: 최신 상태로 업데이트된 레플리카의 개수
    • AVAILBLE: 사용 가능한 레플리카의 개수
    • AGE: 파드가 실행되고 있는 지속 시간
20231114002134_1148507c42f4f4b2b80a57349a5efda8_fznv.png

디플로이먼트의 추가 정보를 포함하여 목록 확인

kubectl get deployment -o wide
  • 목록 항목
    • CONTANERS: 파드에 포함된 컨테이너의 개수
    • IMAGES: 파드 생성에 사용된 이미지
    • SELECTOR: yaml 파일의 셀렉터를 의미(yaml 파일의 셀렉터는 라벨이 app=my-httpd인 파드만을 선택해서 서비스를 하겠다는 의미)
20231114002520_1148507c42f4f4b2b80a57349a5efda8_pu0z.png


파드 관리(실습)

파드 목록 확인

kubectl get pod


20231114002704_1148507c42f4f4b2b80a57349a5efda8_3y9u.png

파드의 추가 정보를 포함하여 목록 확인

kubectl get pod -o wide
  • 목록 항목
    • NODE: 파드가 실행되고 있는 노드
    • NOMINATED NODE: 예약된 노드의 이름(예약된 노드가 없으므로 none)
    • READINESS GATES: 파드 상태 정보로 사용자가 수정할 수 있음. 예를 들어 running, pending 상태가 기본이지만 creating 같은 좀 더 상세한 정보를 원한다면 READINESS GATES를 다음과 같이 설정하면 됨
20231114002908_1148507c42f4f4b2b80a57349a5efda8_z0nk.png
curl 명령어로 httpd 웹 서버에 IP로 접속

#‘It works!’라는 결과가 출력되었다면 웹 서비스가 정상적으로 동작하고 있다는 의미
curl 10.36.0.1


20231114003049_1148507c42f4f4b2b80a57349a5efda8_71vd.png


파드 삭제(실습)

디플로이먼트 삭제

#kubectl delete deployment [ 디플로이먼트 이름 ]
kubectl delete deployment my-httpd
  • 디플로이먼트를 삭제하면 파드도 삭제
20231114003405_1148507c42f4f4b2b80a57349a5efda8_zzkb.png


파드 관리(실습)

생성된 컨테이너나 파드에 접속

kubectl exec -it my-httpd-7547bdb59f-cdkd9 -- /bin/bash
  • 명령어 설명
    • kubectl exec: 실행 중인 파드에 접속
    • i: 컨테이너에 대화형 셸(shell)을 생성
    • t: 대화형 터미널을 도커 컨테이너에 연결
    • my-httpd-7547bdb59f-cdk9: 접속할 파드의 이름
    • -- /bin/bash: 셸의 절대 경로
    • 이후 exit 명령어를 사용해 파드를 빠져나옴
20231114003552_1148507c42f4f4b2b80a57349a5efda8_6qui.png

파드의 로그 확인

kubectl logs my-httpd-7547bdb59f-cdkd9


20231114003938_1148507c42f4f4b2b80a57349a5efda8_qbgo.png


디플로이먼트와 서비스 사용

디플로이먼트
  • 쿠버네티스에서 상태가 없는(statless) 애플리케이션을 배포할 때 사용
  • 디플로이먼트는 레플리카셋의 상위 개념으로서 파드의 개수를 유지할 뿐만 아니라 배포 작업을 좀 더 세분화해 관리할 수 있게 해줌
20231114004052_1148507c42f4f4b2b80a57349a5efda8_8664.png

디플로이먼트 배포 전략
  • 이전 버전의 애플리케이션에서 업데이트가 필요한 경우에 주로 사용되며, 배포 방법에는 롤링, 재생성, 블루/그린, 카나리가 있음
 
  • 롤링 업데이트
    • 새 버전의 애플리케이션(파드)을 배포할 때 새 버전의 애플리케이션은 하나씩 늘려가고 기존 버전의 애플리케이션은 하나씩 줄여나가는 방식으로 쿠버네티스에서 사용하는 표준 배포 방식
    • 상당히 안정적인 배포 방식이지만 업데이트가 느리게 진행된다는 단점이 있음

20231114004153_1148507c42f4f4b2b80a57349a5efda8_k9jw.png
  • 재생성 업데이트
    • 모든 이전 버전(V1)의 파드를 모두 한 번에 종료하고 새 버전(V2)의 파드로 일괄적으로 교체하는 방식
    • 빠르게 교체할 수 있지만 새로운 버전의 파드에 문제가 발생하면 대처가 늦어질 수 있다는 단점이 있음

20231114004219_1148507c42f4f4b2b80a57349a5efda8_pjnt.png
  • 블루/그린 업데이트
    • 애플리케이션의 이전 버전(블루, V1 파드)과 새 버전(그린, V2 파드)이 동시에 운영됨
    • 서비스 목적으로 접속할 수 있는 것은 새 버전의 파드만 가능하며 이전 버전의 파드는 테스트 목적으로만 접속 가능
    • 새로운 버전의 파드에 문제가 발생했을 때 빠르게 대응할 수 있으며 안정적으로 배포할 수 있음
    • 많은 파드가 필요하므로 그만큼 많은 자원(CPU, 메모리)이 필요하다는 단점이 있음

20231114004259_1148507c42f4f4b2b80a57349a5efda8_rdk2.png
  • 카나리 업데이트
    • 블루/그린과 비슷하지만 더 진보적인 단계적 접근 방식
    • 카나리는 주로 애플리케이션의 몇몇 새로운 기능을 테스트할 때 사용
    • 두 개의 버전을 모두 배포하지만 새 버전에는 조금씩 트래픽을 증가시켜 새로운 기능들을 테스트함
    • 기능 테스트가 끝나고 새 버전에 문제가 없다고 판단하면 이전 버전은 모두 종료시키고 새 버전으로만 서비스 함
20231114004411_1148507c42f4f4b2b80a57349a5efda8_9ktm.png


디플로이먼트와 서비스 사용하기(실습)
  • 디플로이먼트는 파드 배포에 관한 객체
  • 단순히 파드를 배포하는 것 뿐만 아니라 몇 개의 파드를 실행할지 결정하는 것도 디플로이먼트
  • 파드에 위치한 서비스를 외부에서 접속하려면 서비스(쿠버네티스의 서비스)를 이용해야 함
20231114004557_1148507c42f4f4b2b80a57349a5efda8_7f9y.png

디플로이먼트 yaml 파일 생성

#nano 텍스트 편집기 사용
nano nginx-deploy.yaml
  • 디플로이먼트 > 파드 > 컨테이너 순서로 이동하면서 상세한 정보들을 정의
yaml 파일 내용

apiVersion: apps/v1
kind: Deployment
metadata:               # 디플로이먼트 정보
  name: nginx-deployment    # nginx-deploy라는 이름의 디플로이먼트 생성
  labels:
    app: nginx      # 디플로이먼트의 레이블
spec:
  replicas: 2     # 2개의 파드 생성
  selector:     # 디플로이먼트가 관리할 파드를 선택
    matchLabels:
      app: nginx      # 디플로이먼트는 nginx 레이블을 갖는 파드를 선택해 관리
  template:   # template에 정의된 내용에 따라 파드를 생성
    metadata:
      labels:
        app: nginx      # 생성될 파드의 레이블
    spec:     # 컨테이너에 대한 정보
      containers:
      - name: nginx   # 컨테이너의 이름
        image: nginx:latest   # 사용할 이미지 (Nginx 웹 서버 이미지)
        ports:
        - containerPort: 80   # 컨테이너가 리스닝하는 포트 (80번 포트로 설정)


Metadata:
  • name: Deployment의 이름을 "nginx-deployment"로 지정함.
  • labels: Deployment에 "app: nginx" 라벨을 할당함. 이 레이블은 파드와 Deployment를 서로 연관시키는 데 사용됨.

Spec (Deployment의 Spec):
  • replicas : Deployment가 유지해야 하는 파드의 수를 2개로 지정함.
  • selector : Deployment가 관리할 파드를 선택하는 데 사용되는 레이블 셀렉터임. "app: nginx" 레이블을 갖는 파드를 관리함.
  • template : Deployment에 의해 생성될 파드의 템플릿을 정의함.
    • metadata : 파드에 "app: nginx" 레이블을 할당함.
    • spec : 파드에서 실행할 컨테이너들에 대한 사양을 정의함.
      • containers: 하나 이상의 컨테이너를 정의할 수 있음. "nginx"라는 이름의 단일 컨테이너를 정의하고 "nginx:latest" image를 사용함. 컨테이너가 80번 포트에서 수신하도록 설정함.


※ Kubernetes의 Deployment에서는 기본적으로 'RollingUpdate' 배포 전략을 사용


# Deployment 배포전략 수정
spec:
  strategy:
    type: Recreate #기존파드 삭제 후 새 파드 생성


yaml 파일을 사용하여 디플로이먼트 생성


kubectl apply -f nginx-deploy.yaml
  • apply: 지정된 리소스 구성을 현재 클러스터에 적용하라는 명령어
  • -f: 파일에서 리소스 정의를 읽어들이라는 옵션
20231114004945_1148507c42f4f4b2b80a57349a5efda8_y5vn.png

배포한 디플로이먼트 목록 확인

kubectl get deployments


20231114005027_1148507c42f4f4b2b80a57349a5efda8_a56w.png

파드 목록 확인

kubectl get pod


20231114005128_1148507c42f4f4b2b80a57349a5efda8_eiuo.png

서비스 yaml 파일 생성

#nano 텍스트 편집기 사용
nano nginx-svc.yaml


서비스  yaml 내용

apiVersion: v1
kind: Service
metadata:
  name: my-nginx  # 서비스의 이름
  labels:
    run: my-nginx  # 레이블 (run: my-nginx) 설정
spec:
  type: NodePort  #NodePort, LoadBalancer(kubectl get services 로 외부 서비스 IP 확인), ClusterIP(클러스터 내부에서만 접속, 외부접속 X)
  ports:
  - port: 8080  # 서비스가 리스닝하는 포트 (클러스터 내부에서 접근하는 포트)
    targetPort: 80  # 백엔드 파드가 리스닝하는 포트
    protocol: TCP  # 프로토콜 설정 (TCP)
    nodePort: 30000  # 노드포트 번호 지정 (클러스터 외부에서 접근하는 포트)
    name: http  # 포트의 이름
  selector:
    app: nginx  # 파드 선택자 설정 (app: nginx 레이블을 가진 파드와 연결)


※ 기본 서비스 포트 정책
  • NodePort 서비스는 클러스터 외부에서 바로 targetPort로 포워딩하는 것이 아니라, nodePort와 port를 거쳐서 포워딩하는 구조를 가짐. 이는 Kubernetes의 네트워킹 모델의 일부로, 클러스터 외부와 내부 간의 통신을 관리하는 방식임.
  • NodePort 서비스에서 port 필드를 지정하지 않는 경우, Kubernetes는 기본적으로 targetPort와 동일한 값을 port로 설정함. 즉, 백엔드 파드가 리스닝하는 포트와 클러스터 내부에서 서비스에 접근하기 위한 포트가 같아짐.
  • 예를 들어, targetPort가 80으로 설정되어 있고 port를 명시적으로 지정하지 않는다면, Kubernetes는 port도 80으로 설정함. 그러나 port는 클러스터 내부에서만 사용되고, 클러스터 외부에서 접근할 때는 nodePort를 사용함.
  • nodePort는 클러스터 외부에서 서비스에 접근할 때 사용되는 포트로, 이 값은 명시적으로 지정하거나 지정하지 않으면 Kubernetes가 자동으로 할당함. 자동 할당된 nodePort는 일반적으로 30000-32767 범위 내에서 선택됨.
  • 따라서, port를 지정하지 않으면 기본적으로 targetPort와 동일한 값이 사용되고, nodePort는 자동 할당되거나 지정된 값에 따라 결정됨.

yaml 파일을 사용하여 서비스 생성

kubectl apply -f nginx-svc.yaml


20231114005334_1148507c42f4f4b2b80a57349a5efda8_skfl.png

서비스 상태 정보 확인

#서비스 목록 확인 명령어
kubectl get svc


20231114005422_1148507c42f4f4b2b80a57349a5efda8_a9sm.png

파드 위치 확인하기

#파드 상세 정보 확인하는 명령어
kubectl get pods -o wide


20231114005555_1148507c42f4f4b2b80a57349a5efda8_uygp.png

노드 IP 확인

#노드 상세 정보 확인하는 명령어
kubectl get nodes -o wide


20231114005715_1148507c42f4f4b2b80a57349a5efda8_vvkm.png

웹 브라우저에서 노드의 IP와 서비스의 포트번호를 이용해서 파드에 접속하기 20231114005911_1148507c42f4f4b2b80a57349a5efda8_dkmz.png
※ 서비스의 노드벨런싱 정책
  • NodePort 서비스를 사용할 때, 클러스터 외부에서 NodePort (여기서는 30000)를 통해 서비스에 접근하면, Kubernetes는 클러스터 내의 어떤 노드로든 요청을 전달할 수 있음. 192.168.47.128:30000 (master 노드의 IP와 NodePort)으로 접근하면, Kubernetes는 이 요청을 my-nginx 서비스로 라우팅함.
  • my-nginx 서비스는 app: nginx 레이블을 가진 파드들과 연결되어 있고, 서비스의 spec.selector 필드에 의해 nginx-deployment-7c79c4bf97-9979k와 nginx-deployment-7c79c4bf97-hsxdv 파드들이 선택됨. 따라서, 192.168.47.128:30000으로 요청을 보내면, Kubernetes는 이 요청을 두 개의 Nginx 파드 중 하나로 라우팅함.
  • Kubernetes의 로드 밸런싱 메커니즘은 요청을 균등하게 분배하려고 시도하므로, 요청은 두 파드 중 하나로 무작위로 전달됨. 이 과정에서 어떤 워커 노드(worker0 또는 worker1)에 있는 파드로 요청이 전달될지는 예측할 수 없음. 요청이 어느 파드로 라우팅되는지 정확히 알고 싶으면, 각 파드의 로그를 확인하거나, 서비스에 대한 트래픽 로그를 수집하는 것이 필요함.


레플리카셋 사용

레플리카셋
  • 레플리카셋은 일정한 개수의 동일한 파드가 항상 실행되도록 관리
  • 이 기능이 필요한 이유는 서비스의 지속성 때문
  • 파드를 사용할 수 없을 때 다른 노드에서 파드를 다시 생성해 사용자에게 중단 없는 서비스를 제공
20231114010017_1148507c42f4f4b2b80a57349a5efda8_7kix.png

레플리카셋 사용(실습)

레플리카셋 yaml 파일 생성

#nano 텍스트 편집기 사용
nano replicaset.yaml


레플리카셋 yaml 내용

apiVersion: apps/v1
kind: ReplicaSet    
metadata:
  name: 3-replicaset    # 레플리카 이름
spec:
  template:
    metadata:
      name: 3-replicaset
      labels:
        app: 3-replicaset
    spec:
      containers:
      - name: 3-replicaset    
        image: nginx
        ports:
        - containerPort: 80
  replicas: 3 # 3개의 파드 생성    
  selector:
    matchLabels:
      app: 3-replicaset


apiVersion: 리소스를 정의하는데 사용되는 Kubernetes API의 버전을 나타냄. apps/v1.
kind: 생성하려는 리소스의 종류를 나타냄. ReplicaSet.
metadata: 리소스에 대한 메타데이터를 제공함.
  • name: ReplicaSet의 이름을 "3-replicaset"으로 지정함.
spec (첫 번째 spec): ReplicaSet의 사양을 정의함.
  • replicas: 유지하려는 파드의 수를 3으로 지정함.
  • selector: ReplicaSet이 관리할 파드를 선택하는 데 사용되는 레이블 셀렉터임.
    • matchLabels: ReplicaSet이 관리할 파드는 "app: 3-replicaset" 레이블을 가져야 함.
  • template: ReplicaSet에 의해 생성될 파드의 템플릿을 정의함.
    • metadata (템플릿의 metadata): 파드에 대한 메타데이터를 제공함.
      • labels: 생성될 파드에 "app: 3-replicaset" 레이블을 할당함.
    • spec (두 번째 spec): 파드의 사양을 정의함.
      • containers: 실행할 컨테이너에 대한 사양을 정의함.
        • name: 컨테이너의 이름을 "3-replicaset"으로 지정함.
        • image: 사용할 컨테이너 이미지로 "nginx"를 지정함.
        • ports: 컨테이너가 리스닝할 포트를 지정함.
          • containerPort:  80번이 컨테이너가 리스닝 포트.

yaml 파일을 사용하여 레플리카셋 생성

kubectl apply -f replicaset.yaml


20231114010249_1148507c42f4f4b2b80a57349a5efda8_av87.png

레플리카셋과 파드 정보 확인

#레플리카셋과 파드 목록 확인 명령어
kubectl get replicaset,pods


20231114010336_1148507c42f4f4b2b80a57349a5efda8_op3w.png

파드 하나 삭제

#파드 삭제 명령어
kubectl delete pod 3-replicaset-jmv9f


20231114010412_1148507c42f4f4b2b80a57349a5efda8_hdqq.png

레플리카셋과 파드 목록 재확인

#레플리카셋과 파드 목록 확인 명령어
kubectl get replicaset,pods
  • 파드가 삭제되어도 지정된 숫자 만큼 파드의 개수를 유지
20231114010510_1148507c42f4f4b2b80a57349a5efda8_3sxz.png

레플리카셋 파드 개수 늘리기

#레플리카를 늘리는 명령어
kubectl scale replicaset/3-replicaset --replicas=5


20231114010618_1148507c42f4f4b2b80a57349a5efda8_lnd8.png

레플리카셋과 파드 정보 확인

#레플리카셋과 파드 목록 확인 명령어
kubectl get replicaset,pods


20231114010643_1148507c42f4f4b2b80a57349a5efda8_82n1.png

파드는 유지하되, 레플리카셋만 삭제

#파드는 유지하고 레플리카셋만 삭제해주는 명령어
kubectl delete -f replicaset.yaml --cascade=orphan


20231114010744_1148507c42f4f4b2b80a57349a5efda8_d88l.png

댓글목록0

등록된 댓글이 없습니다.
게시판 전체검색