새소식

Recent Study/udemy - CKA with Practice Tests

Section 3 : Core Concepts

  • -

k8s Controllers는 k8s에 숨은 두뇌입니다. k8s 객체 모니터링을 진행하고, 이에 반응합니다.

Replication Controller

: k8s 클러스터에 있는 단일 Pod의 다중 인스턴스를 실행하도록 도와 고가용성을 제공합니다. 항상 Pod가 실행되도록 보장합니다. 개수에 상관없이. 서로 다른 노드의 여러 Pod에 걸쳐 부하를 분산하는 데 도움이 되고, 수요가 증가하면 앱 스케일도 조정할 수 있습니다. (Replication Controller vs ReplicaSet 서로 비슷하지만 다르고, controller는 구식이다)

 

Replication Controller

 

 이에 대한 yaml 파일도 apiVersion, kind, metadata, spec으로 구성되어 있습니다. Replication Controller yaml 파일을 작성할 때는 pod의 내용이 rc.yaml의 spec: template: [pod.yaml] 들어가면 됩니다.

위 파일을 해석해보면 2개의 metadata 존재합니다. 1번째는 Replication Controller, 2번째는 Pod 용입니다. 그리고 각각의 spec이 존재하며, rc는 부모 pod는 자식입니다.

 

 

ReplicaSet

: yaml 파일 구성은 위와 같고, apiVersion을 주의해서 작성해야 합니다. 나머지는 모두 같고 딱 하나만 추가 정의가 필요합니다. selector: 라는 replicas: 와 같은 depth에 존재합니다. selector: 은 ReplicaSet에 놓인 pod를 식별할 수 있게 해줍니다. 왜 식별하고, 지정해야 하냐면 ReplicaSet은 ReplicaSet으로 생성하지 않은 Pod를 관리할 수 있습니다.

 

 예로 ReplicaSet이 만들어지기 전에 selector에 지정된 label과 일치하는 Pod가 생성되어 있었다면 ReplicaSet은 생성 후 이 Pod를 고려하게 될 것입니다. Replication Controller에서도 selector 사용이 가능하지만 필수가 아니며, ReplicaSet은 추가적으로 Label의 옵션을 부여하는 기능이 더 많습니다.

 

만약 Pod의 개수를 조정하고 싶다면 대표적으로 2가지 방법이 있습니다.

> kubectl replace -f replicaset-defintion.yml (직접 들어가서 수정)

> kubectl scale --replicas=6 -f replicaset-definition.yml (replicas 값 변경)'

 

 

[ 명령어 정리 ]

> kubectl create -f replicaset-definition.yml

> kubectl get replicaset

> kubectl delete replicaset myapp-replicaset

 

 

 Kubernetes를 활용한 Pod, Replication Controller, ReplicaSet 예시

: Pod, Replication Controller, 그리고 ReplicaSet은 Kubernetes에서 애플리케이션을 관리하는 데 사용되는 중요한 리소스입니다. 이러한 리소스를 관리하기 위해 라벨(label)과 셀렉터(selector)를 사용합니다. 라벨은 리소스에 부여되는 키-값 쌍이며, 셀렉터는 특정 라벨을 기반으로 리소스를 선택하는 방법을 나타냅니다.

 

 간단한 예시를 통해 설명하겠습니다. 예를 들어, 웹 애플리케이션을 배포하고자 한다고 가정해봅시다. 이 웹 애플리케이션은 "app=web"이라는 라벨을 가지고 있습니다.

먼저, 웹 애플리케이션을 담은 Pod을 생성합니다. 이 Pod에는 다음과 같이 "app=web"라는 라벨을 부여할 수 있습니다.

 

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  labels:
    app: web
spec:
  containers:
  - name: web-container
    image: nginx


apiVersion: v1
kind: ReplicationController
metadata:
  name: web-controller
spec:
  replicas: 3
  selector:
    app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web-container
        image: nginx


apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: web-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web-container
        image: nginx

 

 

[ tier 간단정리 ]

 Kubernetes에서 "tier"애플리케이션을 구성하는 서비스 또는 컴포넌트의 우선순위 또는 계층을 나타내는 라벨(label)로 사용됩니다. 일반적으로, 애플리케이션 내에서 서로 다른 우선순위를 가진 서비스 또는 컴포넌트를 구분하기 위해 tier 라벨을 사용합니다. 이는 서비스나 컴포넌트 간의 우선순위에 따라 관리 및 운영을 쉽게 할 수 있도록 도와줍니다.

 

 예를 들어, 웹 애플리케이션을 배포할 때, 이를 구성하는 다양한 컴포넌트가 있을 수 있습니다. 이 중에서는 웹 프론트엔드, 백엔드 API 서버, 데이터베이스 등이 있을 수 있습니다. 각각의 컴포넌트는 다른 우선순위를 가질 수 있으며, 이를 tier 라벨을 사용하여 구분할 수 있습니다.

 

 

Services

: 쿠버네티스 서비스는 다양한 구성 요소간의 통신을 가능하게 합니다. 대표적인 Services Type으로는 총 3개가 있습니다. 

 

NodePort : 서비스가 노드의 포트부터 포트까지 매핑해 줄 수 있습니다.  

ClusterIP : 클러스터 안에서 가상 IP를 만들어 다른 서비스 간의 통신을 가능하게 합니다.

LoadBalancer : NodePort와 같은 성격을 띄고, 추가로 트래픽 분산을 해준다. 그리고 지원되는 것에 맞춰야 사용이 가능하다.

 

 

Namespaces

: 처음 k8s를 설정하면 기본적으로 Pod 생성, Service 생성 같은 부분은 Default 네임스페이스에서 이루어졌습니다. 또한 내부적 목적으로 네트워킹 솔루션, DNS 서비스에 요구되는 것과 같습니다. 사용자들이 실수로 건드리지 않도록 이는 kube-system으로 다른 네임스페이스에 생성되어 있습니다. kube-public도 있는데 이는 모든 사용자가 사용할 수 있는 자원입니다.

 

원래 사용했던 > kubectl get pods는 Default 내 존재하는 것만 볼 수 있었습니다. 이를 해결하기 위해 아래와 같이 사용할 수 있습니다.

> kubectl get pods --namespace=kube-system

 

또한 네임스페이스에서  리소스를 제한하려면 Resource Quota를 사용할 수 있습니다. 

 


Imperative vs Declartive

 

 

: Imperative는 관리자에게 까다롭습니다. 현재 인프라의 환경을 전부 인지하고, 확인 후 해야할 일을 적용해야 하기 때문입니다. 중간에 어떤 에러 때문에 처음부터 재실행하는 경우, imperative 에서는 중복 실행 이슈와 같은 것들을 처리하기 어렵습니다. declarative 는 상태를 규정하는 것이기 때문에 시스템이 인텔리하게 처리할 수 있습니다.

 

차이점을 자세하게 확인해보자면

 

Imperative :

1) run, create, expose, edit, scale, set, create -f, replace -f, delete -f 와 같은 커맨드

2)이미 해당 오브젝트가 존재하는데 create -f 를 날리거나 혹은 해당 오브젝트가 없는데 replace -f 를 날리면 에러가 생김 (명령형의 단점)

 

Declartive :

1) 원하는 상태(desired state)를 yaml 파일에 정의하고 apply -f 커맨드로 실행

2) API 는 현재 파일을 보고 어떤 점이 바뀌었는 지 체크해서 적절한 조치를 취해 줌(create  replace를 한번에)

3) 오브젝트가 없으면 만들어주고 있는 경우 바뀐 부분만 체크해서 업데이트 해줌

4) 반복해서 실행해도 항상 같은 상태가 유지됨을 보장(idempotent == 멱등성)

 

 

Apply Command

 

: Local에서 첫 번째로 변경이 있었다면 이는 Live Object configuration과 비교하여 변화시키고, 마지막으로 적용된 Json은 항상 최신으로 업데이트 됩니다. Live Object configuration은 k8s 메모리 내에 존재하고, Json은 Live Object configuration 안에 annotations 내에 존재합니다.

 

1) 로컬에 있는 yaml 파일을 가지고 오브젝트를 생성합니다. 이와 동시에 로컬 파일과 비슷하게 생긴(상태 정보가 추가된) live object configuration 을 k8s 내에 생성합니다.

 

2) 또한 json 파일로 변환된 last applied configuration 파일도 저장됩니다.

 

3) 이 세가지 파일(로컬 yaml, last applied configuration, live object configuration) 이 비교되면서 실제 오브젝트에 어떤 변화를 줄지 정해집니다.

 

[Ex] 예를 들어 로컬 파일에서 이미지를 nginx:1.19 로 변경하고 apply 커맨드를 날리면, 먼저 클러스터에 있는 live object configuration 과 비교되어 차이점이 발견되고 업데이트 됨 -> last applied 파일도 이에따라 최신 값으로 업데이트 됨

 

*local file: 디스크에 있는 파일

*live object configuration: 클러스터 메모리에 있는 정보

*last applied configuration 은 apply 커맨드를 사용했을때만 annotation 에 기록이 남음

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.