[kubernetes] 쿠버네티스 오브젝트

쿠버네티스 > 네임스페이스, 파드, 디플로이먼트, 서비스

develop, kubernetes
written byzuhern1zuhern

in

2021. 03. 21


공부하는 책
알면 더 쉬운 도커 쿠버네티스 복습을 위해 요약한 것.
kubernetes.io
kubernetes basic

목표

kubernetes 책 3장 내용 숙지

  • 쿠버네티스 오브젝트
  • 쿠버네티스의 구성 요소를 가볍게 알아보자

3.3 쿠버네티스의 오브젝트

  • 쿠버네티스는 모든 요소를 yaml 파일로 생성하여 관리

3.3.1 네임스페이스 namespace

  • 하나의 물리적인 공간에 있는 쿠버네티스를 다수의 팀이 사용할 때 유용
  • 네임스페이스가 작업되는 부분에 대해서 논리적으로 분리해 줄 수 있음

1. 네임스페이스 조회

% kubectl get namespace
NAME              STATUS   AGE
default           Active   26m
kube-node-lease   Active   26m
kube-public       Active   26m
kube-system       Active   26m

2. yaml 파일 생성

apiVersion: v1
kind: Namespace
metadata:
  name: team1

3. 구성 파일 실행

% kubectl apply -f namespace.yaml
namespace/team1 created

4. 해당 네임스페이스를 이용하여 파드 생성

% kubectl run nginx --image=nginx --namespace=team1
pod/nginx created

5. 파드 조회

% kubectl get pod -n team1
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          71s
# -n 를 사용하지 않음 = -n default 의미
% kubectl get pod
No resources found in default namespace.

3.3.2 파드 pod

  • 파드는 쿠버네티스의 구성 요소 중 가장 작은 단위의 객체
  • 파드는 해당 클러스터에서 러닝 프로세스를 나타냄
  • 파드는 쿠버네티스에서 컨테이너와 같다고 보면 된다.
  • 도커 쿠버네티스
    단일 컨테이너가 가장 작은 단위의 객체 파드 내에 여러 개의 컨테이너가 존재 가능
  • 파드의 공유 컨텍스트는 Linux 네임스페이스1, 컨트롤 그룹(cgroup)2 및 도커 컨테이너를 격리하는 것과 같이 서로 다른 격리요소들 이다.
  • 파드 안의 컨테이너들은 IP 주소와 포트 공간을 공유하고, localhost를 통해 서로를 찾을 수 있음.
  • 도커의 구조 관점에서 보면, 파드는 공유 네임스페이스와 공유 볼륨을 가진 도커 컨테이너 그룹으로 모델링 된다.

3.3.2.1 생명주기

상태 설명
pending 승인 후 파드를 위한 컨테이너 이미지 생성이 완료되지 않은 상태 (네트워크를 통한 이미지 다운로드 시간 포함)
running 파드가 한 노드에 결합되었고, 모든 컨테이너 생성이 완료됨. 하나 이상의 컨테이너가 동작중 or (재)시작중
succeeded 파드에 있는 모든 컨테이너가 성공적으로 생성된 상태
failed 파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패료 종료된 상태
unknown 어떤 이유에 의해 파드의 상태를 얻을 수 없는 상태. 일반적으로 파드 호스트와의 통신 오류에 의해 발생

3.3.2.2 파드 생성

  • 파드 생성해보기

    예제소스

    # 파드생성 (책 예제 대상 yaml 파일 틀림.)
    % kubectl apply -f nodejs-app.yaml 
    pod/nodejs-app created
    # 파드확인
    % kubectl get pod       
    NAME         READY   STATUS    RESTARTS   AGE
    nodejs-app   1/1     Running   0          106s
  • 파드에 두개의 컨테이너를 포함해보자

    예제소스2

    # 파드생성 (책 예제 대상 yaml 파일과 metadata/name 명칭 틀렸음!)
    % kubectl apply -f nodejs-app-multi.yaml
    pod/nodejs-app-multi created
    # 파드확인
    kubectl get pod
    NAME               READY   STATUS    RESTARTS   AGE
    nodejs-app         1/1     Running   0          23m
    nodejs-app-multi   2/2     Running   0          47s
    # 파드상세
    % kubectl describe pod nodejs-app-multi
    Name:         nodejs-app-multi
    Namespace:    default
    Priority:     0
    Node:         docker-desktop/192.168.65.3
    Start Time:   Sun, 04 Apr 2021 15:00:02 +0900
    Labels:       <none>
    Annotations:  <none>
    Status:       Running
    IP:           10.1.0.33
    ...
    ....
  • 삭제

    % kubectl delete -f nodejs-app-multi.yaml
    pod "nodejs-app-multi" deleted
  • 파드에 여러개의 컨테이너를 배치 -> 하나의 서비스에 필요한 부분들을 그루핑
  • 파드 내의 컨테이너들끼리는 자유롭게 통신 & 다른 파드와는 노출된 포트로만 통신
  • 하나의 마이크로서비스를 만드는 것과 유사
  • 복제 관리를 해야하기 때문에 싱글톤이라 해도 디플로이먼트와 같은 컨트롤러 사용

3.3.3 디플로이먼드 deployment

디플로이먼트
파드와 레플리카셋에 대한 선언과 업데이트를 제공하는 상위개념의 컨트롤러

안정적인 서비스를 유지하기 위해 복제의 조절은 필수적
디플로이먼트는 파드의 복제뿐만 아니라 여러 부분을 조절하도록 해 줌

  • 디플로이먼트 생성

    예제소스

    # 이전 실습한 파드 모두 delete 하고 시작 
    # replicas: 1
    # 디플로이먼트 생성
    % kubectl apply -f deployment/nodejs.yaml
    deployment.apps/nodejs-app created
    # 파드
    % kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    nodejs-app-6f8cbf844f-dmvv4   1/1     Running   0          3m22s
    # 리플리카셋
    % kubectl get replicaset
    NAME                    DESIRED   CURRENT   READY   AGE
    nodejs-app-6f8cbf844f   1         1         1       3m55s
    # 디플로이먼트
    % kubectl get deployment
    NAME         READY   UP-TO-DATE   AVAILABLE   AGE
    nodejs-app   1/1     1            1           4m28s
  • replicas: 2 로 다시 생성
    기존 생성된 파드, 리플리카셋, 디플로이먼트 그대로 둔 상태로 실행하면
    업데이트 되는 것으로 보임

    # 파드
    % kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    nodejs-app-6f8cbf844f-dmvv4   1/1     Running   0          11m
    nodejs-app-6f8cbf844f-vlnjg   1/1     Running   0          19s
    # 리플리카셋
    % kubectl get replicaset
    NAME                    DESIRED   CURRENT   READY   AGE
    nodejs-app-6f8cbf844f   2         2         2       12m
    # 디플로이먼트
    % kubectl get deployment
    NAME         READY   UP-TO-DATE   AVAILABLE   AGE
    nodejs-app   2/2     2            2           13m
디플로이먼트를 이용하면 파드의 복제를 관리할 수 있음
  • 설정 변경 후 다시 실행

    # 실행
    % kubectl apply -f deployment/nodejs.yaml 
    deployment.apps/nodejs-app configured
    # 업데이트 확인 
    % kubectl rollout status deployment.apps/nodejs-app
    deployment "nodejs-app" successfully rolled out
  • 히스토리 조회

    # 디플로이먼트의 변경 히스토리
    % kubectl rollout history deployment.apps/nodejs-app
    deployment.apps/nodejs-app 
    REVISION  CHANGE-CAUSE
    1         <none>
    2         <none>
  • change-cause 지정하여 다시 히스토리 조회

    % kubectl annotate deployment.apps/nodejs-app kubernetes.io/change-cause="image updated to lastest"
    deployment.apps/nodejs-app annotated
    % kubectl rollout history deployment.apps/nodejs-app
    deployment.apps/nodejs-app 
    REVISION  CHANGE-CAUSE
    1         <none>
    3         <none>
    4         image updated to lastest

    이전의 이미지로 생성된 파드는 삭제되고 새로운 이미지의 파드가 생성됨

  • 이전 버전으로 롤백

    % kubectl rollout undo deployment.apps/nodejs-app
    deployment.apps/nodejs-app rolled back
  • 특정 리비전으로 롤백

    % kubectl rollout undo deployment.app/nodejs-app --to-revision=2
    # 중간에 이것저것한게 꼬였는지 실패

3.3.4 서비스 service

  • 쿠버네티스에서의 서비스는 파드에 접근할 수 있도록 적책을 정의하는 것
  • 파드끼리 통신할 수 있도록 엔드포인트를 만들어 주고, 파드가 외부에 노출될 수 있도록 함

3.3.4.1 옵션

  1. ClusterIP

    • 서비스가 클러스터-내부IP에 노출되도록 함
    • 클러스터 내에서만 서비스에 도달할 수 있다
    • serviceTypes의 기본 값이다.
  2. NodePort

    • 고정 포트로 각 노드의 IP에 서비스가 노출되도록 한다.
    • NodePort 서비스가 라우팅 되는 ClusterIP 서비스가 자동으로 생성 됨
    • :를 요청하여, 클러스터 외부에서 NodePort 서비스에 접속할 수 있다.
  3. LoadBalancer

    • 클라우드 공급자의 로드 밸런서를 사용하여 서비스가 외부에 노출 되도록 한다.
    • 외부 로드 밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동으로 생성된다.
  4. ExternalName

    • 값과 함께 CNAME 레코드를 리턴하여, 서비스를 externalName 필드의 콘텐츠(foo.bar.example.com 등)에 매핑한다. 이 때 어떤 종류의 프록시도 설정되어 있지 않다.
이 네가지 옵션은 서비스가 파드를 노출해 줄 수 있는 방식을 나타낸 것이다.

3.3.4.2 디플로이먼트 노출

  • 클러스터 내부IP에 노출 (clusterIP)

    # 이전에 생성한 디플로이먼트 nodejs-app을 사용하여 서비스 생성  
    % kubectl expose deploy nodejs-app       
    service/nodejs-app exposed
    # 확인
    % kubectl get svc nodejs-app
    NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    nodejs-app   ClusterIP   10.97.11.79   <none>        3000/TCP   3m38s

    아무런 옵션을 지정하지 않으면 clusterIP 옵션이 자동으로 부여된다.

  • 클러스터 외부에 노출 (NodePort)
    일단 이전 서비스 삭제

    % kubectl delete svc nodejs-app          
    service "nodejs-app" deleted

    동일한 서비스 생성하니 이미 있다고 그래서 삭제 필요
    다시 실행

    # 실행
    % kubectl expose deploy nodejs-app --type=NodePort
    service/nodejs-app exposed
    # 확인
    % kubectl get svc nodejs-app
    NAME         TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    nodejs-app   NodePort   10.99.35.178   <none>        3000:30551/TCP   27s

    지금까지 실행한 내용을 설정파일로 정의
    예제소스

    apiVersion: v1
    kind: Service
    metadata:
    name: nodejs-app
    spec:
    selector:
    app: nodejs-app
    ports:
    - protocol: TCP
      port: 30551
      targetPort: 3000
    type: NodePort



  1. Linux 네임스페이스: 리눅스 네임스페이스는 프로세스를 실행할 때 시스템의 리소스를 분리해서 실행할 수 있도록 도와주는 기능

  2. cgroup: 컨트롤 그룹 (CGROUPS) 소개