CKA를 준비해보자 3일차 - Controller(Replication Controller, ReplicaSet, Deployment)

0

CKA

목록 보기
3/43

Controller

Replication Controller와 ReplicaSet

Controller는 kubernetes의 object를 모니터링하고 원하는 state로의 동작을 진행한다.

node에 하나의 pod가 다운되는 것은 당연하다고 생각하면 된다. 그렇기 때문에 여러 개의 pod를 배포하고 자동 복구할 수 있도록 해야하는데, 이를 가능하게 해주는 것이 바로 Replication Controller이다.

----------------Node---------------------
|                                       |
|   ------Replication Controller-----   |
|   |    ---pod--- ---pod----       |   |
|   |    |       | |        |       |   |
|   |    --------- ----------       |   |
|   ---------------------------------   |
|                                       |
-----------------------------------------

이렇게 Replication Controller는 user를 위해서 pod의 갯수를 설정한만큼 유지하는데, 이 갯수를 Replicas라고 한다. 이렇게 pod 갯수를 여러 개 두어서 유지하면 user는 하나의 pod가 없어져도 지속적으로 접근이 가능하게되어 높은 고가용성을 제공해줄 수 있는 것이다.

replication controller가 필요한 또 다른 이유로는 load balancingscaling에 있다. user의 수요가 늘어나면, replication controller는 여러 node에 pod들을 추가적으로 더 생성할 수 있다. 이렇게 하면 하나의 node만으로 pod를 배포하지 않아서 자원을 효율적으로 사용할 수 있고, 더 많은 pod들을 배포할 수 있어 사용자 경험에 있어 아주 좋다.

----------------Node1--------------------
|                                       |
|   ------Replication Controller-----   |
|   |    ---pod--- ---pod----       |   |
|   |    |       | |        |       |   |
|   |    --------- ----------       |   |
|   |                               |   |
|   |                               |   |
----|                               |---|
    |                               |   
----------------Node2--------------------
|   |                               |   |
|   |                               |   |
|   |    ---pod--- ---pod----       |   |
|   |    |       | |        |       |   |
|   |    --------- ----------       |   |
|   ---------------------------------   |
|                                       |
-----------------------------------------

다음과 같이 서로 다른 node간에 하나의 replication controller가 가로질러있어 pod들을 배포할 수 있고, user의 요청이 많아지면 pod의 수를 늘릴 수 있다. 반대로 user의 요청이 적어지면 pod의 수를 줄 일 수도 있다.

용어적으로 조심해야할 것이 있는데, Replication ControllerReplica Set이다. 둘 다 용도는 같지만 다르다. Replication Controller는 구버전이고 ReplicaSet이 새로운 기술이다. 이들은 작동 방식이 약간 다르지만, 위에서 설명한 방식은 동일하다.

  • re-definition.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp-rc
  labels:
    app: myapp
    type: front-end
spec:
  template:
    {pod-template}

ReplicationController는 pod의 replica를 생성하기 때문에 어떤 pod를 생성하는 지 알려주어야 한다. 이 부분들이 바로 pod-template이다. pod의 metadata, spec부분을 그대로 넣어주어한다.

  • pod-definition.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    type: front-end
spec:
  containers:
  - name: nginx-container
    image: nginx

다음의 pod 정의에서 metadataspec부분을 가져와 template에 넣어주면 된다.

  • re-definition.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp-rc
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
      - name: nginx-container
        image: nginx

이 다음 해당 pod의 복제본(Replica)를 몇 개나 유지할 지를 적어주어야 한다.

  • re-definition.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: myapp-rc
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
      - name: nginx-container
        image: nginx
  replicas: 3

이제 myapp-pod를 3개 만들어줄 것이다.

kubectl create -f ./rc-definition.yaml
kubectl get replicationcontroller
kubectl get rc

이제 ReplicaSet을 보도록 하자. 거의 다 ReplicationController와 동일하다. 단, 주의할 것은 apiVersionReplicationController처럼 v1이 아니라 apps/v1이라는 것이다.

  • replicaset-definition.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-replicaset
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
      - name: nginx-container
        image: nginx
  replicas: 3
  selector:
    matchLabels:
      type: front-end

만약 apiVersionapps/v1이 아니라 v1으로 치면 다음의 error가 발생한다.

error: resource mapping not found for name: "replicaset-1" namespace: "" from "/root/replicaset-definition-1.yaml": no matches for kind "ReplicaSet" in version "v1"
ensure CRDs are installed first

나머지 부분은 거의 동일하다는 사실을 알도록 하자. 단, 한가지 추가되는 부분이 있는데 replicas아래에 selector를 추가해야한다. pod를 식별해주는 기능인데, 왜 template가 있어서 pod를 만들어주는데, selector가 필요할까?

이는 ReplicaSet의 기능인데 selector의 label과 일치하는 pod가 이미 기존에 있었다면, ReplicaSet은 복사본 pod의 갯수에 해당 pod를 포함한다. 가령, Replicas가 3개 일때, 기존에 pod가 이미 하나있다면 두 개만 더 만드는 것이다.

따라서, ReplicaSet은 자신의 template에서 정의된 pod뿐만 아니라, label selctor로 설정된 다른 pod까지 모두 동일하게 관리를 한다는 것이다.

한 가지 명심할 것은 selectortemplate에 정의한 label이 일치해야한다. 위의 경우 type: front-end가 아니라, type: back-end라고 쓰면 error가 발생한다.

kubectl create -f ./replicaset-definition.yaml
kubectl get replicaset
kubectl get rs
kubectl get pods  

사실 ReplicaSet은 자신의 관할에 있는 pod를 관리하고 모니터링하는 것이 기능의 전부이다. 그렇다면 자신의 관할에 있는 pod라는 것을 어떻게 설정할까?? 그것이 바로 selctorlabel이라는 것이다.

만약, replica의 수를 변경하여 스케일링하고 싶다면 yaml파일 정의를 바꾸고 replace를 해주면 된다.

  • replicaset-definition.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-replicaset
  labels:
    app: myapp
    type: front-end
spec:
  ...
  replicas: 6
  selector:
    matchLabels:
      type: front-end

이 다음 replicaset-definition.yamlreplace명령어를 실행시켜주면 된다.

kubectl replace -f ./replicaset-definition.yaml

두번째 방법은 kubectl scale명령어를 사용하면 된다.

kubectl scale --replicas=6 -f ./replicaset-definition.yaml

또는

kubectl scale --replicaset=6 replicaset myapp-replicaset

단, 이 경우는 원본 file은 아무것도 변경되지 않는다는 것을 명심하자.

Deployment

deployment를 말하기 전에 application을 배포해서 사용자에게 제공하는 production 상황을 생각해보도록 하자. 우리는 한 번에 pod들을 업데이트하기 보다는 각각의 rolling update하고 싶을 것이다.

-----        ------------------
|pod|<--v1-->|                |
-----        |                |
             |                |
-----        |                |
|pod|<--v1-->|                |
-----        |                |
             |                |
-----        |                |
|pod|<--v1-->| docker registry|
-----        |                |
             |                |
-----        |                |
|pod|<--v2-->|                |
-----        |                |
             |                |
-----        |                |
|pod|<--v2-->|                |
-----        ------------------

왜 하나씩 업데이트 하는 지 생각해보면 간단한데, 모두 새로운 버전으로 업데이트했다가는 error가 발생할 경우 사용자에게 좋지 않은 경험을 줄 수 있기 때문이다. 따라서 하나씩 업데이트하는데, 만약 error가 발생하면 다시 이전 버전으로 돌아가는 rolling out이 발생한다.

이러한 rolling update, rolling out 기능을 Deployment로 가능하게 한다. DeploymentReplicaSet의 상위 개념으로 ReplicaSet처럼 Replica들을 유지하는 것을 제공해주며 rolling update, rolling out가지 제공해주는 것이다.

따라서, Deployment는 내부에 ReplicaSet있고, 추가적인 rolling기능을 넣은 것 뿐이다.

정의 역시도 ReplicaSet과 거의 일치한다.

  • deployment-definition.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
    type: front-end
spec:
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        type: front-end
    spec:
      containers:
      - name: nginx-container
        image: nginx
  replicas: 3
  selector:
    matchLabels:
      type: front-end

ReplicaSet에서 kind부분만 다른데,Deployment로만 바꾸면 된다. 참고로 deployment라고 하면 에러가 발생하니 조심하자.

kubectl create -f ./deployment-definition.yaml
kubectl get deploytments

심지어 replicaset으로도 확인이 가능하다.

kubectl get replicaset
kubectl get pods

추가적으로 생성된 모든 object들을 보고 싶다면 kubectl get all을 사용하면 된다.

kubectl run

pod와 deployment를 사용해서 pod를 배포할 때는 yaml파일을 사용해서 배포하기 보다는 kubectl run을 사용하는 것이 더 편할 때가 많다. kubectl run--image로 pod의 image를 결정하고 입력 파라미터로 pod-name을 받는다. 다음 정리를 보도록 하자.

  • create nginx pod
kubectl run nginx --image=nginx
  • pod manifest yaml file 생성
kubectl run nginx --image=nginx --dry-run=client -o yaml
  • create deployment
kubectl create deployment --image=nginx nginx
  • deployment yaml file만들기
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml
  • deployment yaml파일 생성 후 저장
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml > nginx-deployment.yaml
  • k8s version v1.19이상부터는 replicas가 설정 가능하다.
kubectl create deployment --image nginx nginx --replicas=4 --dry-run=client -o yaml > nginx-deployment.yaml

0개의 댓글