반응형

 

 

 

 

디플로이먼트

디플로이먼트(Deployment) 는 파드와 레플리카셋(ReplicaSet)에 대한 선언적 업데이트를 제공한다.

디플로이먼트에서 의도하는 상태 를 설명하고, 디플로이먼트 컨트롤러(Controller)는 현재 상태에서 의도하는 상태로 비율을 조정하며 변경한다. 새 레플리카셋을 생성하는 디플로이먼트를 정의하거나 기존 디플로이먼트를 제거하고, 모든 리소스를 새 디플로이먼트에 적용할 수 있다.

 

Deployment -> Replicaset -> Pod 

 

 

디플로이먼트 롤링 업데이트

디플로이먼트는 .spec.strategy.type==RollingUpdate 이면 파드를 롤링 업데이트 방식으로 업데이트 한다. maxUnavailable 와 maxSurge 를 명시해서 롤링 업데이트 프로세스를 제어할 수 있다.

 

최대 불가(Max Unavailable)

.spec.strategy.rollingUpdate.maxUnavailable 은 업데이트 프로세스 중에 사용할 수 없는 최대 파드의 수를 지정하는 선택적 필드이다. 이 값은 절대 숫자(예: 5) 또는 의도한 파드 비율(예: 10%)이 될 수 있다. 절대 값은 내림해서 백분율로 계산한다. 만약 .spec.strategy.rollingUpdate.maxSurge 가 0이면 값이 0이 될 수 없다. 기본 값은 25% 이다.

 

예를 들어 이 값을 30%로 설정하면 롤링업데이트 시작시 즉각 이전 레플리카셋의 크기를 의도한 파드 중 70%를 스케일 다운할 수 있다. 새 파드가 준비되면 기존 레플리카셋을 스케일 다운할 수 있으며, 업데이트 중에 항상 사용 가능한 전체 파드의 수는 의도한 파드의 수의 70% 이상이 되도록 새 레플리카셋을 스케일 업할 수 있다.

 

최대 서지(Max Surge)

.spec.strategy.rollingUpdate.maxSurge 는 의도한 파드의 수에 대해 생성할 수 있는 최대 파드의 수를 지정하는 선택적 필드이다. 이 값은 절대 숫자(예: 5) 또는 의도한 파드 비율(예: 10%)이 될 수 있다. MaxUnavailable 값이 0이면 이 값은 0이 될 수 없다. 절대 값은 올림해서 백분율로 계산한다. 기본 값은 25% 이다.

 

예를 들어 이 값을 30%로 설정하면 롤링업데이트 시작시 새 레플리카셋의 크기를 즉시 조정해서 기존 및 새 파드의 전체 갯수를 의도한 파드의 130%를 넘지 않도록 한다. 기존 파드가 죽으면 새로운 래플리카셋은 스케일 업할 수 있으며, 업데이트하는 동안 항상 실행하는 총 파드의 수는 최대 의도한 파드의 수의 130%가 되도록 보장한다

 

 

Deployment 설정

# deployment 생성 YAML을 작성

jinsu@jinsu:~$ cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mynginx-deploy
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%  
      maxSurge: 25%
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
jinsu@jinsu:~$ 

# deployment 생성
jinsu@jinsu:~$ kubectl apply -f deployment.yaml 
deployment.apps/mynginx-deploy created
jinsu@jinsu:~$ 

# deployment 상태 및 pod 상태 확인
jinsu@jinsu:~$ kubectl get pod
NAME                              READY   STATUS              RESTARTS   AGE
mynginx-deploy-55fbd9fd6d-jfm8k   0/1     ContainerCreating   0          15s
mynginx-deploy-55fbd9fd6d-f2pzv   0/1     ContainerCreating   0          15s
mynginx-deploy-55fbd9fd6d-kwf4k   0/1     ContainerCreating   0          15s
mynginx-deploy-55fbd9fd6d-dwljg   0/1     ContainerCreating   0          15s
mynginx-deploy-55fbd9fd6d-p75wx   1/1     Running             0          15s
jinsu@jinsu:~$ kubectl get deployment
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
mynginx-deploy   1/5     5            1           17s
jinsu@jinsu:~$

# deployment 설정값 확인
jinsu@jinsu:~$ kubectl get deployment mynginx-deploy -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"mynginx-deploy","namespace":"default"},"spec":{"replicas":5,"selector":{"matchLabels":{"app":"nginx"}},"strategy":{"rollingUpdate":{"maxSurge":"25%","maxUnavailable":"25%"},"type":"RollingUpdate"},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx"}]}}}}
  creationTimestamp: "2022-08-14T08:24:38Z"
  generation: 1
  name: mynginx-deploy
  namespace: default
  resourceVersion: "16065"
  selfLink: /apis/apps/v1/namespaces/default/deployments/mynginx-deploy
  uid: 8262ede4-69af-499f-9f93-cba18f9b31c1
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.7.9
        imagePullPolicy: IfNotPresent
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 5
  conditions:
  - lastTransitionTime: "2022-08-14T08:25:02Z"
    lastUpdateTime: "2022-08-14T08:25:02Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2022-08-14T08:24:38Z"
    lastUpdateTime: "2022-08-14T08:25:06Z"
    message: ReplicaSet "mynginx-deploy-55fbd9fd6d" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 5
  replicas: 5
  updatedReplicas: 5
jinsu@jinsu:~$ 

# deployment로 생성한 레플리카셋 확인
jinsu@jinsu:~$ kubectl get rs
NAME                        DESIRED   CURRENT   READY   AGE
mynginx-deploy-55fbd9fd6d   5         5         5       5m44s
jinsu@jinsu:~$

 

deployment 배포시 image 에러가 발생

# 존재하지 않는 이미지로 이미지를 업데이트 하였을 때
jinsu@jinsu:~$ kubectl set image deployment mynginx-deploy nginx=nginx:1.9.30 --record
deployment.apps/mynginx-deploy image updated
jinsu@jinsu:~$

# deploy 하였을 때 maxUnavailabel을 25% 설정
jinsu@jinsu:~$ kubectl get deploy mynginx-deploy -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "3"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"mynginx-deploy","namespace":"default"},"spec":{"replicas":5,"selector":{"matchLabels":{"app":"nginx"}},"strategy":{"rollingUpdate":{"maxSurge":"25%","maxUnavailable":"25%"},"type":"RollingUpdate"},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.7.9","name":"nginx"}]}}}}
    kubernetes.io/change-cause: kubectl set image deployment mynginx-deploy nginx=nginx:1.9.30
      --record=true
  creationTimestamp: "2022-08-14T08:24:38Z"
  generation: 3
  name: mynginx-deploy
  namespace: default
  resourceVersion: "16969"
  selfLink: /apis/apps/v1/namespaces/default/deployments/mynginx-deploy
  uid: 8262ede4-69af-499f-9f93-cba18f9b31c1
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate


# pod에 에러가 발생하여도 전부 변경되지 않음
jinsu@jinsu:~$ kubectl get pod
NAME                              READY   STATUS         RESTARTS   AGE
mynginx-deploy-7f9686c8fd-fbtxv   1/1     Running        0          9m20s
mynginx-deploy-7f9686c8fd-h7pms   1/1     Running        0          9m7s
mynginx-deploy-7f9686c8fd-4q92b   1/1     Running        0          9m5s
mynginx-deploy-7f9686c8fd-vq8lt   1/1     Running        0          9m20s
mynginx-deploy-69d67779d8-zq7bz   0/1     ErrImagePull   0          45s
mynginx-deploy-69d67779d8-lxkhm   0/1     ErrImagePull   0          45s
mynginx-deploy-69d67779d8-jhvcm   0/1     ErrImagePull   0          45s
jinsu@jinsu:~$

 

 

 

Deployment 명령어

# 이미지 변경
kubectl set image

jinsu@jinsu:~$ kubectl set image deployment mynginx-deploy nginx=nginx:1.9.1 --record
deployment.apps/mynginx-deploy image updated
jinsu@jinsu:~$

jinsu@jinsu:~$ kubectl get deploy
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
mynginx-deploy   4/5     3            4           9m9s
jinsu@jinsu:~$

# 이미지가 변경된 것을 확인
jinsu@jinsu:~$ kubectl get pod mynginx-deploy-7f9686c8fd-vq8lt -oyaml |  grep image
  - image: nginx:1.9.1
    imagePullPolicy: IfNotPresent
    image: nginx:1.9.1
    imageID: docker-pullable://nginx@sha256:2f68b99bc0d6d25d0c56876b924ec20418544ff28e1fb89a4c27679a40da811b
jinsu@jinsu:~$ 


# 업데이트 상태 확인
kubectl rollout status deployment mynginx-deploy

jinsu@jinsu:~$ kubectl rollout status deployment mynginx-deploy
deployment "mynginx-deploy" successfully rolled out
jinsu@jinsu:~$ 


# 업데이트 히스토리 확인
kubectl rollout history deployment mynginx-deploy

jinsu@jinsu:~$ kubectl rollout history deployment mynginx-deploy       
deployment.apps/mynginx-deploy 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment mynginx-deploy nginx=nginx:1.9.1 --record=true

jinsu@jinsu:~$ 

# deployment 세부정보 가져오기
jinsu@jinsu:~$ kubectl describe deployment mynginx-deploy
Name:                   mynginx-deploy
Namespace:              default
CreationTimestamp:      Sun, 14 Aug 2022 08:24:38 +0000
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 2
                        kubectl.kubernetes.io/last-applied-configuration:
                          {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"mynginx-deploy","namespace":"default"},"spec":{"replicas"...
                        kubernetes.io/change-cause: kubectl set image deployment mynginx-deploy nginx=nginx:1.9.1 --record=true
Selector:               app=nginx
Replicas:               5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:1.9.1
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   mynginx-deploy-7f9686c8fd (5/5 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  14m    deployment-controller  Scaled up replica set mynginx-deploy-55fbd9fd6d to 5
  Normal  ScalingReplicaSet  5m43s  deployment-controller  Scaled up replica set mynginx-deploy-7f9686c8fd to 2
  Normal  ScalingReplicaSet  5m43s  deployment-controller  Scaled down replica set mynginx-deploy-55fbd9fd6d to 4
  Normal  ScalingReplicaSet  5m43s  deployment-controller  Scaled up replica set mynginx-deploy-7f9686c8fd to 3
  Normal  ScalingReplicaSet  5m30s  deployment-controller  Scaled down replica set mynginx-deploy-55fbd9fd6d to 3
  Normal  ScalingReplicaSet  5m30s  deployment-controller  Scaled up replica set mynginx-deploy-7f9686c8fd to 4
  Normal  ScalingReplicaSet  5m28s  deployment-controller  Scaled down replica set mynginx-deploy-55fbd9fd6d to 2
  Normal  ScalingReplicaSet  5m28s  deployment-controller  Scaled up replica set mynginx-deploy-7f9686c8fd to 5
  Normal  ScalingReplicaSet  5m26s  deployment-controller  Scaled down replica set mynginx-deploy-55fbd9fd6d to 1
  Normal  ScalingReplicaSet  5m26s  deployment-controller  (combined from similar events): Scaled down replica set mynginx-deploy-55fbd9fd6d to 0
jinsu@jinsu:~$ 


# 롤백 기능
kubectl rollout undo deployment mynginx-deploy

# 해당 상태에서
jinsu@jinsu:~$ kubectl get pod
NAME                              READY   STATUS         RESTARTS   AGE
mynginx-deploy-7f9686c8fd-fbtxv   1/1     Running        0          9m20s
mynginx-deploy-7f9686c8fd-h7pms   1/1     Running        0          9m7s
mynginx-deploy-7f9686c8fd-4q92b   1/1     Running        0          9m5s
mynginx-deploy-7f9686c8fd-vq8lt   1/1     Running        0          9m20s
mynginx-deploy-69d67779d8-zq7bz   0/1     ErrImagePull   0          45s
mynginx-deploy-69d67779d8-lxkhm   0/1     ErrImagePull   0          45s
mynginx-deploy-69d67779d8-jhvcm   0/1     ErrImagePull   0          45s
jinsu@jinsu:~$

# 롤백
jinsu@jinsu:~$ kubectl rollout undo deployment mynginx-deploy
deployment.apps/mynginx-deploy rolled back
jinsu@jinsu:~$

jinsu@jinsu:~$ kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
mynginx-deploy-7f9686c8fd-fbtxv   1/1     Running   0          13m
mynginx-deploy-7f9686c8fd-h7pms   1/1     Running   0          13m
mynginx-deploy-7f9686c8fd-4q92b   1/1     Running   0          13m
mynginx-deploy-7f9686c8fd-vq8lt   1/1     Running   0          13m
mynginx-deploy-7f9686c8fd-vn2gf   1/1     Running   0          13s
jinsu@jinsu:~$ 



# scaling 기능
kubectl scale deployment mynginx-deploy --replicas=5 --record

jinsu@jinsu:~$ kubectl scale deployment mynginx-deploy --replicas=10 --record
deployment.apps/mynginx-deploy scaled
jinsu@jinsu:~$ 

# pod가 10개로 생성
jinsu@jinsu:~$ kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
mynginx-deploy-7f9686c8fd-fbtxv   1/1     Running   0          15m
mynginx-deploy-7f9686c8fd-h7pms   1/1     Running   0          15m
mynginx-deploy-7f9686c8fd-4q92b   1/1     Running   0          15m
mynginx-deploy-7f9686c8fd-vq8lt   1/1     Running   0          15m
mynginx-deploy-7f9686c8fd-vn2gf   1/1     Running   0          2m11s
mynginx-deploy-7f9686c8fd-jxjrc   1/1     Running   0          15s
mynginx-deploy-7f9686c8fd-xv69q   1/1     Running   0          15s
mynginx-deploy-7f9686c8fd-r2dzt   1/1     Running   0          15s
mynginx-deploy-7f9686c8fd-vvvfp   1/1     Running   0          15s
mynginx-deploy-7f9686c8fd-576xz   1/1     Running   0          15s
jinsu@jinsu:~$ 

# 레플리카셋 확인
jinsu@jinsu:~$ kubectl get rs
NAME                        DESIRED   CURRENT   READY   AGE
mynginx-deploy-55fbd9fd6d   0         0         0       25m
mynginx-deploy-69d67779d8   0         0         0       7m27s
mynginx-deploy-7f9686c8fd   10        10        10      16m
jinsu@jinsu:~$

 

 

deployment 삭제

# 현재 동작중인 deployment
jinsu@jinsu:~$ kubectl get deployment
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
mynginx-deploy   5/5     5            4           25s
jinsu@jinsu:~$

# deployment 삭제
jinsu@jinsu:~$ kubectl delete deploy mynginx-deploy
deployment.apps "mynginx-deploy" deleted
jinsu@jinsu:~$ 

# 삭제되는 pod들 
jinsu@jinsu:~$ kubectl get pod
NAME                              READY   STATUS        RESTARTS   AGE
mynginx-deploy-7f9686c8fd-jxjrc   1/1     Terminating   0          2m23s
mynginx-deploy-7f9686c8fd-vq8lt   1/1     Terminating   0          17m
mynginx-deploy-7f9686c8fd-576xz   1/1     Terminating   0          2m23s
mynginx-deploy-7f9686c8fd-xv69q   1/1     Terminating   0          2m23s
mynginx-deploy-7f9686c8fd-vvvfp   1/1     Terminating   0          2m23s
jinsu@jinsu:~$

 

 

한번에 원하는 이미지로 deployment 생성

# 원하는 정보를 한번에 생성
kubectl create deployment httpd-frontend --image=httpd:2.4-alpine --replicas=3

 

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/workloads/controllers/deployment/

 

 

반응형
반응형

 

 

 

 

레플리카셋

레플리카셋의 목적은 레플리카 파드 집합의 실행을 항상 안정적으로 유지하는 것이다. 이처럼 레플리카셋은 보통 명시된 동일 파드 개수에 대한 가용성을 보증하는데 사용한다.

 

레플리카셋의 작동 방식

레플리카셋을 정의하는 필드는 획득 가능한 파드를 식별하는 방법이 명시된 셀렉터, 유지해야 하는 파드 개수를 명시하는 레플리카의 개수, 그리고 레플리카 수 유지를 위해 생성하는 신규 파드에 대한 데이터를 명시하는 파드 템플릿을 포함한다. 그러면 레플리카셋은 필드에 지정된 설정을 충족하기 위해 필요한 만큼 파드를 만들고 삭제한다. 레플리카셋이 새로운 파드를 생성해야 할 경우, 명시된 파드 템플릿을 사용한다.

레플리카셋은 파드의 metadata.ownerReferences 필드를 통해 파드에 연결되며, 이는 현재 오브젝트가 소유한 리소스를 명시한다. 레플리카셋이 가지고 있는 모든 파드의 ownerReferences 필드는 해당 파드를 소유한 레플리카셋을 식별하기 위한 소유자 정보를 가진다. 이 링크를 통해 레플리카셋은 자신이 유지하는 파드의 상태를 확인하고 이에 따라 관리 한다.

레플리카셋은 셀렉터를 이용해서 필요한 새 파드를 식별한다. 만약 파드에 OwnerReference이 없거나 OwnerReference가 컨트롤러(Controller) 가 아니고 레플리카셋의 셀렉터와 일치한다면 레플리카셋이 즉각 파드를 가지게 될 것이다.

 

레플리카셋은 언제 사용하는가?

레플리카셋은 지정된 수의 파드 레플리카가 항상 실행되도록 보장한다. 그러나 디플로이먼트는 레플리카셋을 관리하고 다른 유용한 기능과 함께 파드에 대한 선언적 업데이트를 제공하는 상위 개념이다. 따라서 우리는 사용자 지정 오케스트레이션이 필요하거나 업데이트가 전혀 필요하지 않은 경우라면 레플리카셋을 직접적으로 사용하기 보다는 디플로이먼트를 사용하는 것을 권장한다.

이는 레플리카셋 오브젝트를 직접 조작할 필요가 없다는 것을 의미한다. 대신 디플로이먼트를 이용하고 사양 부분에서 애플리케이션을 정의하면 된다

 

 

Replicaset 과 ReplicationController 의 차이점

  • 복제 Pod를 만드는 역활은 둘다 똑같다.
  • Replicaset은 selector 기능으로 Label을 입력하여 Pods들을 보기쉽게, 효율적으로 관리할 수 있습니다. 

 

 

 

레플리카셋 생성

# 레플리카셋 YAML파일 생성
jinsu@jinsu:~$ cat replicaset.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: mynginx-rs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mynginx-rs
  template:
    metadata:
      labels:
        app: mynginx-rs
    spec:
      containers:
      - name: nginx
        image: nginx
jinsu@jinsu:~$ 

jinsu@jinsu:~$ kubectl apply -f replicaset.yaml
replicaset.apps/mynginx-rs created
jinsu@jinsu:~$

# 레플리카셋 생성 확인
jinsu@jinsu:~$ kubectl get replicaset
NAME         DESIRED   CURRENT   READY   AGE
mynginx-rs   1         1         1       28s
jinsu@jinsu:~$
jinsu@jinsu:~$ kubectl get rs
NAME         DESIRED   CURRENT   READY   AGE
mynginx-rs   1         1         1       32s
jinsu@jinsu:~$

# 레플리카셋 pod 1개 생성 확인
jinsu@jinsu:~$ kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
mynginx-rs-hlw2j   1/1     Running   0          7m16s
jinsu@jinsu:~$



# 레플리카셋 설정값 확인
jinsu@jinsu:~$ kubectl get rs mynginx-rs -oyaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"name":"mynginx-rs","namespace":"default"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"mynginx-rs"}},"template":{"metadata":{"labels":{"app":"mynginx-rs"}},"spec":{"containers":[{"image":"nginx","name":"nginx"}]}}}}
  creationTimestamp: "2022-08-14T07:40:17Z"
  generation: 1
  name: mynginx-rs
  namespace: default
  resourceVersion: "13994"
  selfLink: /apis/apps/v1/namespaces/default/replicasets/mynginx-rs
  uid: ad48f6a2-ef69-403b-b96a-5cefa8d94372
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mynginx-rs
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: mynginx-rs
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  fullyLabeledReplicas: 1
  observedGeneration: 1
  readyReplicas: 1
  replicas: 1
jinsu@jinsu:~$

# 레플리카셋에 pod 생성을 2개로 설정(spec: replicas: 2)
jinsu@jinsu:~$ kubectl get rs mynginx-rs -oyaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"name":"mynginx-rs","namespace":"default"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"mynginx-rs"}},"template":{"metadata":{"labels":{"app":"mynginx-rs"}},"spec":{"containers":[{"image":"nginx","name":"nginx"}]}}}}
  creationTimestamp: "2022-08-14T07:40:17Z"
  generation: 2
  name: mynginx-rs
  namespace: default
  resourceVersion: "14633"
  selfLink: /apis/apps/v1/namespaces/default/replicasets/mynginx-rs
  uid: ad48f6a2-ef69-403b-b96a-5cefa8d94372
spec:
  replicas: 2
  
# 설정값을 변경하자마자 pod가 2개로 생성
jinsu@jinsu:~$ kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
mynginx-rs-hlw2j   1/1     Running   0          13m
mynginx-rs-t8wx2   1/1     Running   0          10s
jinsu@jinsu:~$ 

jinsu@jinsu:~$ kubectl get rs
NAME         DESIRED   CURRENT   READY   AGE
mynginx-rs   2         2         2       13m
jinsu@jinsu:~$

 

레플리카셋 삭제

# 현재 동작중인 레플리카셋 확인
jinsu@jinsu:~$ kubectl get rs
NAME         DESIRED   CURRENT   READY   AGE
mynginx-rs   2         2         2       42m
jinsu@jinsu:~$ 

# 레플리카셋 삭제
jinsu@jinsu:~$ kubectl delete rs mynginx-rs
replicaset.apps "mynginx-rs" deleted
jinsu@jinsu:~$ 

jinsu@jinsu:~$ kubectl get rs
No resources found in default namespace.
jinsu@jinsu:~$

 

 

레플리카셋 Scale 수정

# Replicaset 만들었던 Yaml 파일 수정하여 replace
kubectl replace -f replicaset-definition.yaml

# scale 명령으로 레플리카셋 3에서 6으로 수정
kubectl scale --replicas=6 -f replicaset-definition.yaml

# scale 명령으로 name을 지정해서 수정
kubectl scale --replicas=6 replicaset myapp-replicaset

 

 

동작중인 레플리카셋 정보를 수정 및 yaml로 생성

# 현재 동작중인 replicaset을 edit으로 수정
kubectl edit replicaset new-replica-set

# 현재 동작중인 replicaset을 yaml파일로 변경
kubectl get replicaset new-replica-set -o yaml > new-replica-set.yaml

 

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/workloads/controllers/replicaset/

 

반응형
반응형

 

 

 

서비스

  • Pod에서 실행중인 애플리케이션을 서로 통신하게 만들어주는 역활
  • 쿠버네티스는 Pod에게 고유한 IP 주소와 Pod 집합에 대한 단일 DNS 명을 부여하고, 그것들 간에 로드밸런싱을 수행할 수 있다

 

 

서비스 리소스

  • 쿠버네티스에서 Service는 Pod의 논리적으로 분리된 집합과 그 집합에 접근할 수 있는 정책을 정의하는 개념이다. (때로는 이 패턴을 마이크로-서비스라고 한다.)
  • 서비스가 대상으로 하는 파드 집합은 일반적으로 Selector가 결정한다. 서비스 엔드포인트를 정의하는 다른 방법에 대한 자세한 내용은 셀렉터가 없는 서비스를 참고한다.

 

서비스 정의

  • 쿠버네티스의 서비스는 파드와 비슷한 REST 오브젝트이다.
  • 모든 REST 오브젝트와 마찬가지로, 서비스 정의를 API 서버에 POST하여 새 인스턴스를 생성할 수 있다.
  • 서비스 오브젝트의 이름은 유효한 RFC 1035 레이블 이름이어야 한다.

 

 

 

 

Service 연동

# 먼저 nginx를 띄울 pod를 생성해줍니다.
jinsu@jinsu:~$ kubectl run mynginx --image nginx --restart Never
pod/mynginx created
jinsu@jinsu:~$ 
jinsu@jinsu:~$ kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
mynginx   1/1     Running   0          6s
jinsu@jinsu:~$

# Service를 만든 후 실행
jinsu@jinsu:~$ cat Service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: mynginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: mynginx
jinsu@jinsu:~$ 

jinsu@jinsu:~$ kubectl apply -f Service.yaml 
service/mynginx unchanged
jinsu@jinsu:~$

# mynginx 서비스가 잘 동작중인걸 확인
jinsu@jinsu:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.43.0.1      <none>        443/TCP   144m
mynginx      ClusterIP   10.43.42.124   <none>        80/TCP    32m
jinsu@jinsu:~$

# client pod에 들어가 dns를 설치
jinsu@jinsu:~$ kubectl exec -it client -- bash
root@client:/# apt update && apt install -y dnsutils

# nslookup을 해보면 mynginx를 만들었던 pod의 dns가 보이는 걸 확인
root@client:/# nslookup mynginx
Server:         10.43.0.10
Address:        10.43.0.10#53

Name:   mynginx.default.svc.cluster.local
Address: 10.43.42.124

root@client:/# nslookup mynginx.default
Server:         10.43.0.10
Address:        10.43.0.10#53

Name:   mynginx.default.svc.cluster.local
Address: 10.43.42.124

root@client:/#

# nginx 동작 확인
root@client:/# curl mynginx
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@client:/#

 

 

 

 

 

 

 

 

 

서비스 타입 (ServiceTypes)

Pod내의 애플리케이션 중 일부는 서비스를 클러스터 밖에 위치한 외부 IP 주소에 노출하고 싶은 경우가 있을 것이다.

쿠버네티스 ServiceTypes는 원하는 서비스 종류를 지정할 수 있도록 해준다. 기본 값은 ClusterIP이다.

 

Type 값과 그 동작은 다음과 같다.

  • ClusterIP - 서비스를 클러스터-내부 IP에 노출시킨다. 이 값을 선택하면 클러스터 내에서만 서비스에 도달할 수 있다. 이것은 ServiceTypes의 기본 값이다.
  • NodePort - 고정 포트 (NodePort)로 각 노드의 IP에 서비스를 노출시킨다. NodePort 서비스가 라우팅되는 ClusterIP 서비스가 자동으로 생성된다. <NodeIP>:<NodePort>를 요청하여, 클러스터 외부에서 NodePort 서비스에 접속할 수 있다.
  • LoadBalancer - 클라우드 공급자의 로드 밸런서를 사용하여 서비스를 외부에 노출시킨다. 외부 로드 밸런서가 라우팅되는 NodePort와 ClusterIP 서비스가 자동으로 생성된다.
  • ExternalName - 값과 함께 CNAME 레코드를 리턴하여, 서비스를 externalName 필드의 콘텐츠 (예:foo.bar.example.com)에 매핑한다. 어떤 종류의 프록시도 설정되어 있지 않다.
참고: ExternalName 유형을 사용하려면 kube-dns 버전 1.7 또는 CoreDNS 버전 1.7 이상이 필요하다.

인그레스를 사용하여 서비스를 노출시킬 수도 있다. 인그레스는 서비스 유형이 아니지만, 클러스터의 진입점 역할을 한다. 동일한 IP 주소로 여러 서비스를 노출시킬 수 있기 때문에 라우팅 규칙을 단일 리소스로 통합할 수 있다.

 

NodePort 유형

type 필드를 NodePort로 설정하면, 쿠버네티스 컨트롤 플레인은 --service-node-port-range 플래그로 지정된 범위에서 포트를 할당한다 (기본값 : 30000-32767). 각 노드는 해당 포트 (모든 노드에서 동일한 포트 번호)를 서비스로 프록시한다. 서비스는 할당된 포트를 .spec.ports[*].nodePort 필드에 나타낸다.

 

포트를 프록시하기 위해 특정 IP를 지정하려면, kube-proxy에 대한 --nodeport-addresses 플래그 또는 kube-proxy 구성 파일의 동등한 nodePortAddresses 필드를 특정 IP 블록으로 설정할 수 있다.

 

이 플래그는 쉼표로 구분된 IP 블록 목록(예: 10.0.0.0/8, 192.0.2.0/25)을 사용하여 kube-proxy가 로컬 노드로 고려해야 하는 IP 주소 범위를 지정한다.

 

예를 들어, --nodeport-addresses=127.0.0.0/8 플래그로 kube-proxy를 시작하면, kube-proxy는 NodePort 서비스에 대하여 루프백(loopback) 인터페이스만 선택한다. --nodeport-addresses의 기본 값은 비어있는 목록이다. 이것은 kube-proxy가 NodePort에 대해 사용 가능한 모든 네트워크 인터페이스를 고려해야 한다는 것을 의미한다. (이는 이전 쿠버네티스 릴리스와도 호환된다).

 

특정 포트 번호를 원한다면, nodePort 필드에 값을 지정할 수 있다. 컨트롤 플레인은 해당 포트를 할당하거나 API 트랜잭션이 실패했다고 보고한다. 이는 사용자 스스로 포트 충돌의 가능성을 고려해야 한다는 의미이다. 또한 NodePort 사용을 위해 구성된 범위 내에 있는, 유효한 포트 번호를 사용해야 한다.

 

NodePort를 사용하면 자유롭게 자체 로드 밸런싱 솔루션을 설정하거나, 쿠버네티스가 완벽하게 지원하지 않는 환경을 구성하거나, 하나 이상의 노드 IP를 직접 노출시킬 수 있다.

 

이 서비스는 <NodeIP>:spec.ports[*].nodePort와 .spec.clusterIP:spec.ports[*].port로 표기된다. kube-proxy에 대한 --nodeport-addresses 플래그 또는 kube-proxy 구성 파일의 동등한 필드가 설정된 경우, <NodeIP> 는 노드 IP를 필터링한다.

 

Service IP 서비스

# mynginx IP로 서비스를 연동
jinsu@jinsu:~$ kubectl get pod -owide
NAME      READY   STATUS             RESTARTS   AGE    IP           NODE     NOMINATED NODE   READINESS GATES
mynginx   1/1     Running            0          103m   10.42.0.15   master   <none>           <none>
busybox   1/1     Running            0          12m    10.42.0.20   master   <none>           <none>
curl      0/1     CrashLoopBackOff   7          14m    10.42.0.19   master   <none>           <none>
jinsu@jinsu:~$ 

# args 부분에 연동할 pod의 IP를 입력
jinsu@jinsu:~$ cat curl.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: curl
spec:
  containers:
  - name: curl
    image: curlimages/curl
    command: ["curl"]
    args: ["10.42.0.15"]
jinsu@jinsu:~$

# pod를 생성
insu@jinsu:~$ kubectl apply -f curl.yaml 
pod/curl created
jinsu@jinsu:~$ 

# logs로 확인했을때 nginx 와 통신 확인
jinsu@jinsu:~$ kubectl get pod
NAME      READY   STATUS             RESTARTS   AGE
mynginx   1/1     Running            0          82m
curl      0/1     CrashLoopBackOff   1          12s
jinsu@jinsu:~$ kubectl logs curl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615  100   615    0     0  1918k      0 --:--:-- --:--:-- --:--:--  600k

# nginx pod에도 연결 확인
jinsu@jinsu:~$ kubectl logs mynginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/08/14 04:52:51 [notice] 1#1: using the "epoll" event method
2022/08/14 04:52:51 [notice] 1#1: nginx/1.23.1
2022/08/14 04:52:51 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
2022/08/14 04:52:51 [notice] 1#1: OS: Linux 4.15.0-191-generic
2022/08/14 04:52:51 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/08/14 04:52:51 [notice] 1#1: start worker processes
2022/08/14 04:52:51 [notice] 1#1: start worker process 32
2022/08/14 04:52:51 [notice] 1#1: start worker process 33
2022/08/14 04:52:51 [notice] 1#1: start worker process 34
2022/08/14 04:52:51 [notice] 1#1: start worker process 35
10.42.0.16 - - [14/Aug/2022:04:56:07 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"
10.42.0.16 - - [14/Aug/2022:04:56:10 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"

 

Cluster IP 서비스

# Service.yaml 파일 생성 ClusterIP를 입력안할경우 delfault로 적용
jinsu@jinsu:~$ cat Service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: mynginx
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: mynginx
jinsu@jinsu:~$

# Service 생성 및 상태확인
jinsu@jinsu:~$ kubectl apply -f Service.yaml 
service/mynginx unchanged
jinsu@jinsu:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.43.0.1      <none>        443/TCP   4h45m
mynginx      ClusterIP   10.43.42.124   <none>        80/TCP    173m
jinsu@jinsu:~$

# Service CLUSTER-IP를 입력해서 연동
jinsu@jinsu:~$ cat curl.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: curl
spec:
  containers:
  - name: curl
    image: curlimages/curl
    command: ["curl"]
    args: [ "10.43.42.124" ]                                                                    
jinsu@jinsu:~$

# curl 생성 및 상태 확인
jinsu@jinsu:~$ kubectl apply -f curl.yaml 
pod/curl created
jinsu@jinsu:~$ kubectl get pod
NAME      READY   STATUS             RESTARTS   AGE
mynginx   1/1     Running            0          89m
curl      0/1     CrashLoopBackOff   1          12s
jinsu@jinsu:~$

# curl logs 확인시 통신 확인
jinsu@jinsu:~$ kubectl logs curl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615  100   615    0     0   523k      0 --:--:-- --:--:-- --:--:--  600k

# nginx logs 확인시 통신 확인
jinsu@jinsu:~$ kubectl logs mynginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/08/14 04:52:51 [notice] 1#1: using the "epoll" event method
2022/08/14 04:52:51 [notice] 1#1: nginx/1.23.1
2022/08/14 04:52:51 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
2022/08/14 04:52:51 [notice] 1#1: OS: Linux 4.15.0-191-generic
2022/08/14 04:52:51 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/08/14 04:52:51 [notice] 1#1: start worker processes
2022/08/14 04:52:51 [notice] 1#1: start worker process 32
2022/08/14 04:52:51 [notice] 1#1: start worker process 33
2022/08/14 04:52:51 [notice] 1#1: start worker process 34
2022/08/14 04:52:51 [notice] 1#1: start worker process 35
10.42.0.19 - - [14/Aug/2022:06:21:39 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"
10.42.0.19 - - [14/Aug/2022:06:21:43 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"
10.42.0.19 - - [14/Aug/2022:06:21:58 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"

 

NodePort  서비스

# 기존에 사용중인 서비스가 ClusterIP TYPE
jinsu@jinsu:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.43.0.1      <none>        443/TCP   4h51m
mynginx      ClusterIP   10.43.42.124   <none>        80/TCP    179m
jinsu@jinsu:~$ 

# Service를 edit 수정하여 nodePort, type을 변경
jinsu@jinsu:~$ kubectl edit service mynginx
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"mynginx","namespace":"default"},"spec":{"ports":[
  creationTimestamp: "2022-08-14T03:24:02Z"
  name: mynginx
  namespace: default
  resourceVersion: "11731"
  selfLink: /api/v1/namespaces/default/services/mynginx
  uid: b11eaf09-9376-4e90-adb3-75d9a7754dd1
spec:
  clusterIP: 10.43.42.124
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30080
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: mynginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}
  
  
# TYPE이 NodePort로 변경  
jinsu@jinsu:~$ kubectl get service
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.43.0.1      <none>        443/TCP        5h27m
mynginx      NodePort    10.43.42.124   <none>        80:30080/TCP   3h35m
jinsu@jinsu:~$ 

# 본인 Kubernetes 서버 IP 확인
jinsu@jinsu:~$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
inet 192.168.0.211  netmask 255.255.255.0  broadcast 192.168.0.255

# IP에 Port를 입력해서 nginx 동작 확인
jinsu@jinsu:~$ curl 192.168.0.211:30080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
jinsu@jinsu:~$

 

LoadBalancer 서비스

# type을 LoadBalancer로 변경 후 저장
jinsu@jinsu:~$ kubectl get service mynginx -oyaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"mynginx","namespace":"default"},"spec":{"ports":[{"port":80,"protocol":"TCP","targetPort":80}],"selector":{"run":"mynginx"}}}
  creationTimestamp: "2022-08-14T03:24:02Z"
  name: mynginx
  namespace: default
  resourceVersion: "12339"
  selfLink: /api/v1/namespaces/default/services/mynginx
  uid: b11eaf09-9376-4e90-adb3-75d9a7754dd1
spec:
  clusterIP: 10.43.42.124
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30080
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: mynginx
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 192.168.0.211
jinsu@jinsu:~$ 

# 서비스 상태 확인
jinsu@jinsu:~$ kubectl get svc
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
kubernetes   ClusterIP      10.43.0.1      <none>          443/TCP        5h32m
mynginx      LoadBalancer   10.43.42.124   192.168.0.211   80:30080/TCP   3h40m
jinsu@jinsu:~$

# EXTERNAL-IP로 확인해보면 nginx 서비스 동작 확인
jinsu@jinsu:~$ curl 192.168.0.211
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
jinsu@jinsu:~$

 

ExternalName 서비스

# external 서비스를 google 도메인으로 생성
jinsu@jinsu:~$ cat external.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-google-svc
spec:
  type: ExternalName
  externalName: google.com
jinsu@jinsu:~$
jinsu@jinsu:~$ kubectl apply -f external.yaml 
service/my-google-svc created
jinsu@jinsu:~$ 

# google도메인으로 externalName 만든 서비스 확인
jinsu@jinsu:~$ kubectl get svc
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)        AGE
kubernetes      ClusterIP      10.43.0.1      <none>          443/TCP        5h37m
mynginx         LoadBalancer   10.43.42.124   192.168.0.211   80:30080/TCP   3h45m
my-google-svc   ExternalName   <none>         google.com      <none>         8s
jinsu@jinsu:~$

# google로 생성한 pod랑 연동
jinsu@jinsu:~$ cat curl.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: curl
spec:
  containers:
  - name: curl
    image: curlimages/curl
    command: ["curl"]
    args: [ "my-google-svc" ]
jinsu@jinsu:~$ 
jinsu@jinsu:~$ kubectl apply -f curl.yaml 
pod/curl created
jinsu@jinsu:~$ 

# logs를 확인해보면 google도메인으로 연동 확인
jinsu@jinsu:~$ kubectl logs curl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1561  100  1561    0     0  19763      0 --:--:-- --:--:-- --:--:-- 20012
<!DOCTYPE html>
<html lang=en>
  <meta charset=utf-8>
  <meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
  <title>Error 404 (Not Found)!!1</title>
  <style>
    *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
  </style>
  <a href=//www.google.com/><span id=logo aria-label=Google></span></a>
  <p><b>404.</b> <ins>That’s an error.</ins>
  <p>The requested URL <code>/</code> was not found on this server.  <ins>That’s all we know.</ins>
jinsu@jinsu:~$

 

 

 

 

 

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/services-networking/service/

https://kubernetes.io/ko/docs/concepts/cluster-administration/networking/

 

반응형
반응형

 

 

 

 

컨테이너 프로브(probe)

프로브 는 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단(diagnostic)이다. 진단을 수행하기 위해서, kubelet은 컨테이너 안에서 코드를 실행하거나, 또는 네트워크 요청을 전송한다.

 

 

Check 순서 

프로브를 사용하여 컨테이너를 체크하는 방법에는 4가지가 있다. 각 프로브는 다음의 4가지 메커니즘 중 단 하나만을 정의해야 한다.

  • exec - 컨테이너 내에서 지정된 명령어를 실행한다. 명령어가 상태 코드 0으로 종료되면 진단이 성공한 것으로 간주한다.
  • grpc - gRPC를 사용하여 원격 프로시저 호출을 수행한다. 체크 대상이 gRPC 헬스 체크를 구현해야 한다. 응답의 status 가 SERVING 이면 진단이 성공했다고 간주한다. gRPC 프로브는 알파 기능이며 GRPCContainerProbe 기능 게이트를 활성화해야 사용할 수 있다.
  • httpGet - 지정한 포트 및 경로에서 컨테이너의 IP주소에 대한 HTTP GET 요청을 수행한다. 응답의 상태 코드가 200 이상 400 미만이면 진단이 성공한 것으로 간주한다.
  • tcpSocket - 지정된 포트에서 컨테이너의 IP주소에 대해 TCP 검사를 수행한다. 포트가 활성화되어 있다면 진단이 성공한 것으로 간주한다. 원격 시스템(컨테이너)가 연결을 연 이후 즉시 닫는다면, 이 또한 진단이 성공한 것으로 간주한다.

 

프로브 결과

각 probe는 다음 세 가지 결과 중 하나를 가진다.

  • Success - 컨테이너가 진단을 통과함.
  • Failure - 컨테이너가 진단에 실패함.
  • Unknown - 진단 자체가 실패함(아무런 조치를 수행해서는 안 되며, kubelet이 추가 체크를 수행할 것이다)

 

 

프로브 종류

kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지 종류의 프로브를 수행하고 그에 반응할 수 있다.

  • livenessProbe - 컨테이너가 동작 중인지 여부를 나타낸다. 만약 활성 프로브(liveness probe)에 실패한다면, kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 된다. 만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는 Success 이다.
  • readinessProbe - 컨테이너가 요청을 처리할 준비가 되었는지 여부를 나타낸다. 만약 준비성 프로브(readiness probe)가 실패한다면, 엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거한다. 준비성 프로브의 초기 지연 이전의 기본 상태는 Failure 이다. 만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는 Success 이다.
  • startupProbe - 컨테이너 내의 애플리케이션이 시작되었는지를 나타낸다. 스타트업 프로브(startup probe)가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다. 만약 스타트업 프로브가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다. 컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는 Success 이다.

 

 

 

 

 

Health Check 기능

livenessProve

# livenessProbe 커맨드를 추가하여 해당 Pod가 정상인지 health check
jinsu@jinsu:~$ cat liveness.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: liveness
spec:
  containers: 
  - name: mynginx
    image: nginx
    livenessProbe:
      httpGet:
        path: /
        port: 80

# READY 부분이 1/1로 정상임을 확인
jinsu@jinsu:~$ kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
liveness   1/1     Running   0          2m19s
jinsu@jinsu:~$

readnessProve

# readinessProve 커맨드를 추가하여 80포트를 Health check
jinsu@jinsu:~$ cat readiness.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: readiness
spec:
  containers: 
  - name: mynginx
    image: nginx
    readinessProbe:
      httpGet:
        path: /
        port: 80
jinsu@jinsu:~$ 

# READY 상태를 체크하여 1/1 정상임을 확인
jinsu@jinsu:~$ kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
liveness    1/1     Running   0          3m50s
readiness   1/1     Running   0          14s
jinsu@jinsu:~$

exec를 이용하여 health check

# readinessProbe와 exec를 추가하여 pod안에 moby파일이 여부에 따라 상태 체크
jinsu@jinsu:~$ cat readiness-command.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: readiness-command
spec:
  containers: 
  - name: mynginx
    image: nginx
    readinessProbe:
      exec:
        command: [ "ls", "/work-dir/moby" ]
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  initContainers:
  - name: git
    image: alpine/git
    command: ["sh"]
    args:
    - "-c"
    - "git clone https://github.com/moby/moby.git \
          /work-dir/moby"
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  volumes:
  - name: workdir
    emptyDir: {}
jinsu@jinsu:~$ 


jinsu@jinsu:~$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-command   0/1     Running   0          47s
jinsu@jinsu:~$

# moby 디렉토리를 삭제해봅니다.
jinsu@jinsu:~$ kubectl exec readiness-command -- rm -rf /work-dir/moby

jinsu@jinsu:~$ kubectl get pod                                        
NAME                READY   STATUS    RESTARTS   AGE
readiness-command   1/1     Running   0          2m17s
jinsu@jinsu:~$
# READY항복이 0으로 변경된것을 확인할 수 있습니다.
jinsu@jinsu:~$ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-command   0/1     Running   0          2m36s
jinsu@jinsu:~$

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/

반응형
반응형

 

 

 

init 컨테이너

초기화 컨테이너는 파드의 앱 컨테이너들이 실행되기 전에 실행되는 특수한 컨테이너이다. 초기화 컨테이너는 앱 이미지에는 없는 유틸리티 또는 설정 스크립트 등을 포함할 수 있다.

초기화 컨테이너는 containers 배열(앱 컨테이너를 기술하는)과 나란히 파드 스펙에 명시할 수 있다.

 

init 컨테이너 이해하기

파드는 앱들을 실행하는 다수의 컨테이너를 포함할 수 있고, 또한 앱 컨테이너 실행 전에 동작되는 하나 이상의 초기화 컨테이너도 포함할 수 있다.

다음의 경우를 제외하면, 초기화 컨테이너는 일반적인 컨테이너와 매우 유사하다.

  • 초기화 컨테이너는 항상 완료를 목표로 실행된다.
  • 각 초기화 컨테이너는 다음 초기화 컨테이너가 시작되기 전에 성공적으로 완료되어야 한다.

만약 파드의 초기화 컨테이너가 실패하면, kubelet은 초기화 컨테이너가 성공할 때까지 반복적으로 재시작한다. 그러나, 만약 파드의 restartPolicy 를 절대 하지 않음(Never)으로 설정하고, 해당 파드를 시작하는 동안 초기화 컨테이너가 실패하면, 쿠버네티스는 전체 파드를 실패한 것으로 처리한다.

컨테이너를 초기화 컨테이너로 지정하기 위해서는, 파드 스펙에 initContainers 필드를 container 항목(앱 container 필드 및 내용과 유사한)들의 배열로서 추가한다. 컨테이너에 대한 더 상세한 사항은 API 레퍼런스를 참고한다.

초기화 컨테이너의 상태는 컨테이너 상태의 배열(.status.containerStatuses 필드와 유사)로 .status.initContainerStatuses 필드에 반환된다.

일반적인 컨테이너와의 차이점

초기화 컨테이너는 앱 컨테이너의 리소스 상한(limit), 볼륨, 보안 세팅을 포함한 모든 필드와 기능을 지원한다. 그러나, 초기화 컨테이너를 위한 리소스 요청량과 상한은 리소스에 문서화된 것처럼 다르게 처리된다.

또한, 초기화 컨테이너는 lifecycle, livenessProbe, readinessProbe 또는 startupProbe 를 지원하지 않는다. 왜냐하면 초기화 컨테이너는 파드가 준비 상태가 되기 전에 완료를 목표로 실행되어야 하기 때문이다.

만약 다수의 초기화 컨테이너가 파드에 지정되어 있다면, kubelet은 해당 초기화 컨테이너들을 한 번에 하나씩 실행한다. 각 초기화 컨테이너는 다음 컨테이너를 실행하기 전에 꼭 성공해야 한다. 모든 초기화 컨테이너들이 실행 완료되었을 때, kubelet은 파드의 애플리케이션 컨테이너들을 초기화하고 평소와 같이 실행한다

 

 

init 컨테이너를 이용하여 pod 생성

# YAML 파일을 이용하여 init 컨테이너 생성
master@master:~$ cat init-container.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: init-container
spec:
  containers: 
  - name: busybox
    image: k8s.gcr.io/busybox
    command: [ "ls" ]
    args: [ "/work-dir/moby" ]
    volumeMounts:
    - name: workdir
      mountPath: /work-dir
  initContainers:
  - name: git
    image: alpine/git
    command: ["sh"]
    args:
    - "-c"
    - "git clone https://github.com/moby/moby.git \
          /work-dir/moby"
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  volumes:
  - name: workdir
    emptyDir: {}
master@master:~$ 

master@master:~$ kubectl apply -f init-container.yaml 
pod/init-container created
master@master:~$ 

master@master:~$ kubectl get pod
NAME             READY   STATUS     RESTARTS   AGE
init-container   0/1     Init:0/1   0          10s
master@master:~$ 

master@master:~$ kubectl logs init-container 
Error from server (BadRequest): container "busybox" in pod "init-container" is waiting to start: PodInitializing

master@master:~$ kubectl logs init-container -c git
Cloning into '/work-dir/moby'...

master@master:~$ kubectl logs init-container -c git -f
Cloning into '/work-dir/moby'...
Updating files: 100% (7258/7258), done.
master@master:~$ 

master@master:~$ kubectl logs init-container 
AUTHORS
CHANGELOG.md
CONTRIBUTING.md
Dockerfile
Dockerfile.e2e
Dockerfile.simple
Dockerfile.windows
Jenkinsfile
LICENSE
MAINTAINERS
Makefile
NOTICE
README.md
ROADMAP.md
SECURITY.md
TESTING.md
VENDORING.md
api
builder
cli
client
cmd
codecov.yml
container
contrib
daemon
distribution
docker-bake.hcl
dockerversion
docs
errdefs
hack
image
integration
integration-cli
internal
layer
libcontainerd
libnetwork
oci
opts
pkg
plugin
profiles
project
quota
reference
registry
reports
restartmanager
rootless
runconfig
testutil
vendor
vendor.mod
vendor.sum
volume
master@master:~$

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/

 

 

반응형
반응형

 

 

 

 

 

 

파드안에 두개이상 컨테이너 생성 및 확인

YAML파일안에 sleep 5초를 준 이유는 Pod 안에 컨테이너가 동시에 시작되면 nginx 컨테이너에 오류가 발생할 수 있기에 mynginx 컨테이너 먼저 러닝상태가 되면 jinsunginx 컨테이너가 동작할 수 있게 옵션을 준 것입니다.

# 파드안에 두개의 컨테이너 생성하는 YAML파일 생성
master@master:~$ cat two-container.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mynginx
spec:
  containers: 
  - name: mynginx
    image: nginx
  - name: jinsunginx
    image: curlimages/curl
    command: ["sh"]
    args: 
    - "-c"
    - "sleep 5 && curl localhost"
master@master:~$ 

master@master:~$ kubectl apply -f two-container.yaml 
pod/mynginx created
master@master:~$ 

master@master:~$ kubectl get pod
NAME      READY   STATUS    RESTARTS   AGE
mynginx   1/2     Running   0          18s
master@master:~$

# 그냥 pod의 logs를 조회하면 컨테이너를 선택하라는 문구가 나온다.
master@master:~$ kubectl logs mynginx 
error: a container name must be specified for pod mynginx, choose one of: [mynginx jinsunginx]

# 두개의 컨테이너가 있을떄는 -c 옵션을 사용한다.
master@master:~$ kubectl logs mynginx -c mynginx 
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/08/09 12:59:15 [notice] 1#1: using the "epoll" event method
2022/08/09 12:59:15 [notice] 1#1: nginx/1.23.1
2022/08/09 12:59:15 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 
2022/08/09 12:59:15 [notice] 1#1: OS: Linux 4.15.0-189-generic
2022/08/09 12:59:15 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/08/09 12:59:15 [notice] 1#1: start worker processes
2022/08/09 12:59:15 [notice] 1#1: start worker process 32
2022/08/09 12:59:15 [notice] 1#1: start worker process 33
2022/08/09 12:59:15 [notice] 1#1: start worker process 34
2022/08/09 12:59:15 [notice] 1#1: start worker process 35
127.0.0.1 - - [09/Aug/2022:12:59:28 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"
127.0.0.1 - - [09/Aug/2022:12:59:36 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"
127.0.0.1 - - [09/Aug/2022:12:59:58 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.84.0-DEV" "-"
master@master:~$

master@master:~$ kubectl logs mynginx 
error: a container name must be specified for pod mynginx, choose one of: [mynginx jinsunginx]
master@master:~$ kubectl logs mynginx -c jinsunginx 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   615  100   615    0     0  1002k      0 --:--:-- --:--:-- --:--:--  600k
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
master@master:~$

 

 

 

참고자료

https://kubernetes.io/ko/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/

 

반응형
반응형

 

파드 및 컨테이너 리소스 관리

파드를 생성 및 지정할 때, 컨테이너에 필요한 리소스의 자원을 선택하여 지정할 수 있다. 지정할 가장 일반적인 리소스는 CPU와 메모리(RAM) 그리고 다른 것들이 있다.

파드에서 컨테이너에 대한 리소스 요청(request) 을 지정하면, kube-scheduler는 이 정보를 사용하여 파드가 배치될 노드를 결정한다. 컨테이너에 대한 리소스 제한(limit) 을 지정하면, kubelet은 실행 중인 컨테이너가 설정한 제한보다 많은 리소스를 사용할 수 없도록 해당 제한을 적용한다. 또한 kubelet은 컨테이너가 사용할 수 있도록 해당 시스템 리소스의 최소 요청 자원을 예약한다.

요청 및 제한

파드가 실행 중인 노드에 사용 가능한 리소스가 충분하면, 컨테이너가 해당 리소스에 지정한 request 보다 더 많은 리소스를 사용할 수 있도록 허용된다. 그러나, 컨테이너는 리소스 limit 보다 더 많은 리소스를 사용할 수는 없다.

예를 들어, 컨테이너에 대해 256MiB의 memory 요청을 설정하고, 해당 컨테이너가 8GiB의 메모리를 가진 노드로 스케줄된 파드에 있고 다른 파드는 없는 경우, 컨테이너는 더 많은 RAM을 사용할 수 있다.

해당 컨테이너에 대해 4GiB의 memory 제한을 설정하면, kubelet(그리고 컨테이너 런타임)이 제한을 적용한다. 런타임은 컨테이너가 구성된 리소스 제한을 초과하여 사용하지 못하게 한다. 예를 들어, 컨테이너의 프로세스가 허용된 양보다 많은 메모리를 사용하려고 하면, 시스템 커널은 메모리 부족(out of memory, OOM) 오류와 함께 할당을 시도한 프로세스를 종료한다.

제한은 반응적(시스템이 위반을 감지한 후에 개입)으로 또는 강제적(시스템이 컨테이너가 제한을 초과하지 않도록 방지)으로 구현할 수 있다. 런타임마다 다른 방식으로 동일한 제약을 구현할 수 있다.

 

파드와 컨테이너의 리소스 요청 및 제한

각 컨테이너에 대해, 다음과 같은 리소스 제한(limit) 및 요청(request)을 지정할 수 있다.

  • spec.containers[].resources.limits.cpu
  • spec.containers[].resources.limits.memory
  • spec.containers[].resources.limits.hugepages-<size>
  • spec.containers[].resources.requests.cpu
  • spec.containers[].resources.requests.memory
  • spec.containers[].resources.requests.hugepages-<size>

 

쿠버네티스의 리소스 단위

CPU 리소스 단위

CPU 리소스에 대한 제한 및 요청은 cpu 단위로 측정된다. 쿠버네티스에서, 1 CPU 단위는 노드가 물리 호스트인지 아니면 물리 호스트 내에서 실행되는 가상 머신인지에 따라 1 물리 CPU 코어 또는 1 가상 코어 에 해당한다.

요청량을 소수점 형태로 명시할 수도 있다. 컨테이너의 spec.containers[].resources.requests.cpu를 0.5로 설정한다는 것은, 1.0 CPU를 요청했을 때와 비교하여 절반의 CPU 타임을 요청한다는 의미이다. CPU 자원의 단위와 관련하여, 0.1 이라는 수량 표현은 "백 밀리cpu"로 읽을 수 있는 100m 표현과 동일하다. 어떤 사람들은 "백 밀리코어"라고 말하는데, 같은 것을 의미하는 것으로 이해된다.

CPU 리소스는 항상 리소스의 절대량으로 표시되며, 상대량으로 표시되지 않는다. 예를 들어, 컨테이너가 싱글 코어, 듀얼 코어, 또는 48 코어 머신 중 어디에서 실행되는지와 상관없이 500m CPU는 거의 같은 양의 컴퓨팅 파워를 가리킨다.

참고: 쿠버네티스에서 CPU 리소스를 1m보다 더 정밀한 단위로 표기할 수 없다. 이 때문에, CPU 단위를 1.0 또는 1000m보다 작은 밀리CPU 형태로 표기하는 것이 유용하다. 예를 들어, 0.005 보다는 5m으로 표기하는 것이 좋다.

메모리 리소스 단위

memory 에 대한 제한 및 요청은 바이트 단위로 측정된다. E, P, T, G, M, k 와 같은 수량 접미사 중 하나를 사용하여 메모리를 일반 정수 또는 고정 소수점 숫자로 표현할 수 있다. Ei, Pi, Ti, Gi, Mi, Ki와 같은 2의 거듭제곱을 사용할 수도 있다. 예를 들어, 다음은 대략 동일한 값을 나타낸다.

128974848, 129e6, 129M, 128974848000m, 123Mi

접미사의 대소문자에 유의한다. 400m의 메모리를 요청하면, 이는 0.4 바이트를 요청한 것이다. 이 사람은 아마도 400 메비바이트(mebibytes) (400Mi) 또는 400 메가바이트 (400M) 를 요청하고 싶었을 것이다.

 

 

 

 

YAML을 이용하여 request 리소스 pod 생성

# reqeust 리소스를 이용하여 cpu 0.25 코어 RAM 500M 생성
master@master:~$ cat request.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: request 
spec:
  containers: 
  - name: nginx
    image: nginx
    resources:
      requests:
        cpu: 250m
        memory: 500Mi
master@master:~$

master@master:~$ kubectl apply -f request.yaml 
pod/request created
master@master:~$ 

master@master:~$ kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
volume-nginx   1/1     Running   1          2d4h
env-pod        1/1     Running   1          2d3h
request        1/1     Running   0          6s
master@master:~$ 

master@master:~$ kubectl get pod request -oyaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"request","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":"nginx","resources":{"requests":{"cpu":"250m","memory":"500Mi"}}}]}}
  creationTimestamp: "2022-08-09T12:33:02Z"
  name: request
  namespace: default
  resourceVersion: "15774"
  selfLink: /api/v1/namespaces/default/pods/request
  uid: 53aec9d6-6831-4d6e-b7ff-870a35eff92a
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: nginx
    resources:
      requests:
        cpu: 250m
        memory: 500Mi

 

 

YAML을 이용하여 limit 리소스 pod 생성

# limit 리소스를 이용하여 cpu 0.5 코어 RAM 1G 생성
master@master:~$ cat limits.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: limit 
spec:
  containers: 
  - name: nginx 
    image: nginx
    resources:
     limits:
       cpu: 500m
       memory: 1Gi
master@master:~$ 

master@master:~$ kubectl apply -f limits.yaml 
pod/limit created
master@master:~$ 

master@master:~$ kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
volume-nginx   1/1     Running   1          2d4h
env-pod        1/1     Running   1          2d4h
request        1/1     Running   0          14m
limit          1/1     Running   0          13m
master@master:~$ 

master@master:~$ kubectl get pod limit -oyaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"limit","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":"nginx","resources":{"limits":{"cpu":"500m","memory":"1Gi"}}}]}}
  creationTimestamp: "2022-08-09T12:34:54Z"
  name: limit
  namespace: default
  resourceVersion: "15864"
  selfLink: /api/v1/namespaces/default/pods/limit
  uid: 25e779dd-5f44-4c14-af31-108df5f8658d
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: nginx
    resources:
      limits:
        cpu: 500m
        memory: 1Gi
      requests:
        cpu: 500m
        memory: 1Gi

 

 

 

 

 

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/configuration/manage-resources-containers/

반응형
반응형

 

 

 

매개변수로 정보 전달하기

# Pod 생성하는 YAML파일 생성
master@master:~$ cat arg-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: arg-pod
spec:
  containers: 
  - name: ubuntu
    image: ubuntu:18.04
    command: [ "echo" ]
    args: [ "abc", "def" ]
master@master:~$ 

master@master:~$ kubectl apply -f arg-pod.yaml 
pod/arg-pod created
master@master:~$

master@master:~$ kubectl logs arg-pod     
abc def
master@master:~$

 

 

환경변수 설정하기

# pod 생성을 위한 YAML 파일 생성
master@master:~$ cat env-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: env-pod
spec:
  containers: 
  - name: nginx
    image: nginx
    env:
    - name: my_env
      value: "this is jinsu nginx!"
master@master:~$

master@master:~$ kubectl apply -f env-pod.yaml 
pod/env-pod created
master@master:~$

master@master:~$ kubectl get pod
NAME           READY   STATUS             RESTARTS   AGE
volume-nginx   1/1     Running            0          41m
env-pod        1/1     Running            0          44s
master@master:~$

# exec 명령으로 env-pod 환경변수 확인
master@master:~$ kubectl exec env-pod -- printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=env-pod
my_env=this is jinsu nginx!
KUBERNETES_PORT=tcp://10.43.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.43.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.43.0.1
KUBERNETES_SERVICE_HOST=10.43.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
NGINX_VERSION=1.23.1
NJS_VERSION=0.7.6
PKG_RELEASE=1~bullseye
HOME=/root
master@master:~$

 

 

 

 

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/tasks/inject-data-application/_print/

 

 

 

반응형
반응형

 

 

 

볼륨(volume)

컨테이너 내의 디스크에 있는 파일은 임시적이며, 컨테이너에서 실행될 때 애플리케이션에 적지 않은 몇 가지 문제가 발생한다. 한 가지 문제는 컨테이너가 크래시될 때 파일이 손실된다는 것이다. kubelet은 컨테이너를 다시 시작하지만 초기화된 상태이다. 두 번째 문제는 Pod에서 같이 실행되는 컨테이너간에 파일을 공유할 때 발생한다. 쿠버네티스 볼륨 추상화는 이러한 문제를 모두 해결한다. Pod에 대해 익숙해지는 것을 추천한다

 

 

 

volume-pod 생성 

# YAML파일 생성
master@master:~$ cat volume-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: volume-nginx
spec:
  containers: 
  - name: jinsunginx
    image: nginx
    volumeMounts:
    - mountPath: /test-volume
      name: my-volume
  volumes:
  - name: my-volume
    hostPath:
      path: /home
      type: Directory
master@master:~$ 

# Pod 생성
master@master:~$ kubectl apply -f volume-pod.yaml 
pod/volume-nginx created

 

 

volume 연결 확인

# 로컬 디렉토리와 volume-nginx pod 디렉토리와 연결 확인
master@master:~$ kubectl exec volume-nginx -- ls -alh /test-volume/master
total 64K
drwxr-xr-x 6 1000 1000 4.0K Aug  7 07:54 .
drwxr-xr-x 3 root root 4.0K Aug  6 16:27 ..
-rw------- 1 1000 1000 1.2K Aug  7 07:13 .bash_history
-rw-r--r-- 1 1000 1000  220 Apr  4  2018 .bash_logout
-rw-r--r-- 1 1000 1000 3.8K Aug  7 05:36 .bashrc
drwx------ 2 1000 1000 4.0K Aug  6 16:30 .cache
drwx------ 3 1000 1000 4.0K Aug  6 16:30 .gnupg
drwxrwxr-x 4 1000 1000 4.0K Aug  7 04:38 .kube
-rw-r--r-- 1 1000 1000  807 Apr  4  2018 .profile
drwx------ 2 1000 1000 4.0K Aug  6 16:28 .ssh
-rw-r--r-- 1 1000 1000    0 Aug  7 03:44 .sudo_as_admin_successful
-rw------- 1 1000 1000 8.8K Aug  7 07:54 .viminfo
-rw-rw-r-- 1 1000 1000  155 Aug  7 07:14 jinsu2nginx.yaml
-rw-rw-r-- 1 1000 1000  137 Aug  7 06:25 jinsunginx.yaml
-rw-rw-r-- 1 1000 1000  270 Aug  7 07:54 volume-pod.yaml
master@master:~$ 

master@master:~$ ls -al
total 64
drwxr-xr-x 6 master master 4096 Aug  7 07:54 .
drwxr-xr-x 3 root   root   4096 Aug  6 16:27 ..
-rw------- 1 master master 1165 Aug  7 07:13 .bash_history
-rw-r--r-- 1 master master  220 Apr  4  2018 .bash_logout
-rw-r--r-- 1 master master 3838 Aug  7 05:36 .bashrc
drwx------ 2 master master 4096 Aug  6 16:30 .cache
drwx------ 3 master master 4096 Aug  6 16:30 .gnupg
-rw-rw-r-- 1 master master  155 Aug  7 07:14 jinsu2nginx.yaml
-rw-rw-r-- 1 master master  137 Aug  7 06:25 jinsunginx.yaml
drwxrwxr-x 4 master master 4096 Aug  7 04:38 .kube
-rw-r--r-- 1 master master  807 Apr  4  2018 .profile
drwx------ 2 master master 4096 Aug  6 16:28 .ssh
-rw-r--r-- 1 master master    0 Aug  7 03:44 .sudo_as_admin_successful
-rw------- 1 master master 8970 Aug  7 07:54 .viminfo
-rw-rw-r-- 1 master master  270 Aug  7 07:54 volume-pod.yaml
master@master:~$

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/storage/volumes/

반응형
반응형

레이블과 셀렉터

레이블은 Pod와 같은 오브젝트에 첨부된 키와 값의 쌍이다. 레이블은 오브젝트의 특성을 식별하는 데 사용되어 사용자에게 중요하지만, 코어 시스템에 직접적인 의미는 없다. 레이블로 오브젝트의 하위 집합을 선택하고, 구성하는데 사용할 수 있다. 레이블은 오브젝트를 생성할 때에 붙이거나 생성 이후에 붙이거나 언제든지 수정이 가능하다. 오브젝트마다 키와 값으로 레이블을 정의할 수 있다. 오브젝트의 키는 고유한 값이어야 한다.

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

레이블은 UI와 CLI에서 효율적인 쿼리를 사용하고 검색에 사용하기에 적합하다. 식별되지 않는 정보는 어노테이션으로 기록해야 한다.

 

사용 동기

레이블을 이용하면 사용자가 간단하게 결합한 방식으로 조직 구조와 시스템 오브젝트를 매핑할 수 있으며, 클라이언트에 매핑 정보를 저장할 필요가 없다.

 

레이블 셀렉터

이름과 UID와 다르게 레이블은 고유하지 않다. 일반적으로 우리는 많은 오브젝트에 같은 레이블을 사용한다.

레이블 셀렉터를 통해 클라이언트와 사용자는 오브젝트를 식별할 수 있다. 레이블 셀렉터는 쿠버네티스 코어 그룹의 기본이다.

API는 현재 일치성 기준 과 집합성 기준 이라는 두 종류의 셀렉터를 지원한다. 레이블 셀렉터는 쉼표로 구분된 다양한 요구사항 에 따라 만들 수 있다. 다양한 요구사항이 있는 경우 쉼표 기호가 AND(&&) 연산자로 구분되는 역할을 하도록 해야 한다.

비어있거나 지정되지 않은 셀렉터는 상황에 따라 달라진다. 셀렉터를 사용하는 API 유형은 유효성과 의미를 따로 정의하여 정리해야 한다.

참고: 레플리카셋(ReplicaSet)과 같은 일부 API 유형에서 두 인스턴스의 레이블 셀렉터는 네임스페이스 내에서 겹치지 않아야 한다. 그렇지 않으면 컨트롤러는 상충하는 명령으로 보고, 얼마나 많은 복제본이 필요한지 알 수 없다.
주의: 일치성 기준과 집합성 기준 조건 모두에 대해 논리적인 OR (||) 연산자가 없다. 필터 구문이 적절히 구성되어 있는지 확인해야 한다.

 

labels 확인 

master@master:~$ kubectl get pod
NAME          READY   STATUS    RESTARTS   AGE
jinsunginx    1/1     Running   0          9s
jinsu2nginx   1/1     Running   0          9s
master@master:~$ 

master@master:~$ kubectl get pod -L run
NAME          READY   STATUS    RESTARTS   AGE     RUN
jinsunginx    1/1     Running   0          2m58s   jinsunginx
jinsu2nginx   1/1     Running   0          2m58s   jinsu2nginx
master@master:~$ 

master@master:~$ kubectl get pod jinsunginx --show-labels
NAME         READY   STATUS    RESTARTS   AGE     LABELS
jinsunginx   1/1     Running   0          3m21s   run=jinsunginx
master@master:~$

 

 

labels 추가 및 확인

# color를 red로 labels 설정
master@master:~$ cat jinsu2nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: jinsu2nginx
    color: red 
  name: jinsu2nginx
spec:
  containers:
  - name: nginx
    image: nginx
master@master:~$

# labels 확인
master@master:~$ kubectl get pod jinsu2nginx --show-labels
NAME          READY   STATUS    RESTARTS   AGE   LABELS
jinsu2nginx   1/1     Running   0          27s   color=red,run=jinsu2nginx
master@master:~$

 

 

Pod edit으로 labels 수정

# kubectl edit pod로 color 오렌지색으로 labels 수정
master@master:~$ kubectl edit pod jinsunginx
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"run":"jinsunginx"},"name":"jinsunginx","names
  creationTimestamp: "2022-08-07T07:08:05Z"
  labels:
    color: orange
    run: jinsunginx
  name: jinsunginx
  namespace: default
  resourceVersion: "7343"
  selfLink: /api/v1/namespaces/default/pods/jinsunginx
  uid: 22d83e8b-4d1e-4072-a09c-b19eabc47a95"
...

  
# color labels 수정 확인
master@master:~$ kubectl get pod jinsunginx --show-labels
NAME         READY   STATUS    RESTARTS   AGE   LABELS
jinsunginx   1/1     Running   0          12m   color=orange,run=jinsunginx
master@master:~$

 

 

labels 필터링으로 찾기

aster@master:~$ kubectl get pod -l run
NAME          READY   STATUS    RESTARTS   AGE
jinsu2nginx   1/1     Running   0          7m15s
jinsunginx    1/1     Running   0          14m
master@master:~$

master@master:~$ kubectl get pod -l run=jinsunginx
NAME         READY   STATUS    RESTARTS   AGE
jinsunginx   1/1     Running   0          15m
master@master:~$

 

 

node selector 이용하여 disktype 구분

master@master:~$ kubectl label node master disktype=ssd
# node/master labeld
master@master:~$ 

master@master:~$ cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: jinsunginx
  name: jinsunginx
spec:
  containers: 
  - name: jinsunginx
    image: nginx
  nodeSelector:
    disktype: ssd
EOF
master@master:~$

 

 

 

 

 

참고자료

https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/labels/

반응형

+ Recent posts