본문 바로가기

클라우드/Kubernetes(쿠버네티스)

[쿠버네티스] ReplicaSet & 디플로이먼트(Deployment) & 서비스 & 네임스페이스

레프리카셋(ReplicaSet)

https://myanjini.tistory.com/entry/04-%EB%A0%88%ED%94%8C%EB%A6%AC%EC%B9%B4%EC%85%8BReplica-Set

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

 

항상 정해진 개수의 포트가 실행되는 것을 보장



vagrant@ubuntu:~$ minikube status

! Executing "docker container inspect minikube --format={{.State.Status}}" took an unusually long time: 7.182396497s

* Restarting the docker service may improve performance.

minikube

type: Control Plane

host: Stopped

kubelet: Stopped

apiserver: Stopped

kubeconfig: Stopped

 

vagrant@ubuntu:~$ minikube start

 

vagrant@ubuntu:~$ minikube status

minikube

type: Control Plane

host: Running

kubelet: Running

apiserver: Running

kubeconfig: Configured

 

vagrant@ubuntu:~$ kubectl get pods

NAME                READY   STATUS    RESTARTS   AGE

my-nginx-pod        2/2     Running   2          2d17h

my-nginx-pod-test   1/1     Running   1          2d17h

 

vagrant@ubuntu:~$ kubectl delete pods my-nginx-pod-test

pod "my-nginx-pod-test" deleted

 

vagrant@ubuntu:~$ kubectl get pods

NAME           READY   STATUS    RESTARTS   AGE

my-nginx-pod   2/2     Running   2          2d17h

 

- 2개의 컨테이너가 실행 중인 것을 확인

   my-nginx-container

   ubuntu-sidecar-container

   → nginx-pod-with-ubuntu.yml 파일에 정의



### 파드 삭제 1. kubectl delete -f YAML_FILE

vagrant@ubuntu:~/kub01$ kubectl delete -f nginx-pod-with-ubuntu.yml

pod "my-nginx-pod" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get pods

No resources found in default namespace.

 

vagrant@ubuntu:~/kub01$ kubectl apply -f nginx-pod-with-ubuntu.yml

pod/my-nginx-pod created

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME           READY   STATUS    RESTARTS   AGE

my-nginx-pod   2/2     Running   0          11s



### 파드 삭제 2. kubectl delete pods POD_NAME

vagrant@ubuntu:~/kub01$ kubectl delete pods my-nginx-pod

pod "my-nginx-pod" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get pods

No resources found in default namespace.

 

레플리카셋 정의

vagrant@ubuntu:~/kub01$ vim replicaset-nginx.yml

apiVersion: apps/v1

kind: ReplicaSet

metadata:

  name: replicaset-nginx

spec:

  replicas: 3                          ⇐ 유지해야 하는 파드 개수

  selector:                            ⇐ 획득 가능한 파드를 식별하는 방법

    matchLabels:

      app: my-nginx-pods-label

  template:                            ⇐ 신규 생성되는 파드에 대한 데이터를 명시

    metadata:

      name: my-nginx-pod

      labels:

        app: my-nginx-pods-label

    spec:

      containers:

      - name: my-nginx-container

        image: nginx:latest

        ports:

        - containerPort: 80

          protocol: TCP

 

레플리카셋 생성 및 확인

vagrant@ubuntu:~/kub01$ kubectl apply -f replicaset-nginx.yml

replicaset.apps/replicaset-nginx created

 

vagrant@ubuntu:~/kub01$ kubectl get pod

NAME                     READY   STATUS    RESTARTS   AGE

replicaset-nginx-8hctp   1/1     Running   0          24s

replicaset-nginx-9rwdr   1/1     Running   0          24s

replicaset-nginx-sqqg7   1/1     Running   0          24s

 

vagrant@ubuntu:~/kub01$ kubectl get replicaset

NAME               DESIRED   CURRENT   READY   AGE

replicaset-nginx   3         3         3       33s



파드의 개수를 늘려서 실행

vagrant@ubuntu:~/kub01$ cp replicaset-nginx.yml replicaset-nginx-4pods.yml

vagrant@ubuntu:~/kub01$ vi replicaset-nginx-4pods.yml

    :

spec:

  replicas: 4


     :

 

vagrant@ubuntu:~/kub01$ kubectl apply -f replicaset-nginx-4pods.yml

replicaset.apps/replicaset-nginx configured ⇐ 기존 리소스를 수정했다는 의미

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                     READY   STATUS    RESTARTS   AGE

replicaset-nginx-8hctp   1/1     Running   0          5m2s

replicaset-nginx-9rwdr   1/1     Running   0          5m2s

replicaset-nginx-m4rls   1/1     Running   0          58s

replicaset-nginx-sqqg7   1/1     Running   0          5m2s

 

vagrant@ubuntu:~/kub01$ kubectl get replicaset

NAME               DESIRED   CURRENT   READY   AGE

replicaset-nginx   4         4         4       5m32s



레플리카셋을 삭제

### kubectl delete replicaset REPLICASET_NAME 

vagrant@ubuntu:~/kub01$ kubectl delete replicaset replicaset-nginx ⇐ kubectl delete rs replicaset-nginx 동일

replicaset.apps "replicaset-nginx" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get pods

No resources found in default namespace. ⇐ 레플리카셋을 삭제하면 파드도 함께 삭제



### kubectl delete -f REPLICASET_YML_FILE

vagrant@ubuntu:~/kub01$ kubectl apply -f replicaset-nginx-4pods.yml

replicaset.apps/replicaset-nginx created

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                     READY   STATUS    RESTARTS   AGE

replicaset-nginx-j2pfk   1/1     Running   0          45s

replicaset-nginx-kzxhv   1/1     Running   0          45s

replicaset-nginx-ps9nm   1/1     Running   0          45s

replicaset-nginx-r7d2p   1/1     Running   0          45s



vagrant@ubuntu:~/kub01$ kubectl delete -f replicaset-nginx-4pods.yml

replicaset.apps "replicaset-nginx" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get pods

No resources found in default namespace.

 

 

레플리카셋은 셀렉터로 정의한 파드가 일정 개수가 되도록 유지

#1 my-nginx-pods-label 라벨을 가지는 파드를 생성

vagrant@ubuntu:~/kub01$ vi nginx-pod-without-rs.yml

apiVersion: v1

kind: Pod

metadata:

  name: my-nginx-pod

  labels:

    app: my-nginx-pods-label

spec:

  containers:

  - name: my-nginx-container

    image: nginx:latest

    ports:

    - containerPort: 80

 

vagrant@ubuntu:~/kub01$ kubectl apply -f nginx-pod-without-rs.yml

pod/my-nginx-pod created

 

vagrant@ubuntu:~/kub01$ kubectl get pods --show-labels

NAME           READY   STATUS    RESTARTS   AGE   LABELS

my-nginx-pod   1/1     Running   0          19s   app=my-nginx-pods-label



#2 my-nginx-pods-label 라벨을 가지는 파드 3개를 생성하는 레플리카셋을 생성

vagrant@ubuntu:~/kub01$ vi replicaset-nginx.yml

apiVersion: apps/v1

kind: ReplicaSet

metadata:

  name: replicaset-nginx

spec:

  replicas: 3

  selector:

    matchLabels:

      app: my-nginx-pods-label

  template:

    metadata:

      name: my-nginx-pod

      labels:

        app: my-nginx-pods-label

    spec:

      containers:

      - name: my-nginx-container

        image: nginx:latest

        ports:

        - containerPort: 80

          protocol: TCP

 

vagrant@ubuntu:~/kub01$ kubectl apply -f replicaset-nginx.yml

replicaset.apps/replicaset-nginx created

 

vagrant@ubuntu:~/kub01$ kubectl get pods --show-labels

NAME                     READY   STATUS    RESTARTS   AGE     LABELS

my-nginx-pod             1/1     Running   0          4m12s   app=my-nginx-pods-label

replicaset-nginx-59992   1/1     Running   0          27s     app=my-nginx-pods-label

replicaset-nginx-gbzrr   1/1     Running   0          27s     app=my-nginx-pods-label



#3 파드를 수동으로 삭제한 후 다시 조회

vagrant@ubuntu:~/kub01$ kubectl delete pods my-nginx-pod

pod "my-nginx-pod" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                     READY   STATUS    RESTARTS   AGE

replicaset-nginx-59992   1/1     Running   0          4m40s

replicaset-nginx-gbzrr   1/1     Running   0          4m40s

replicaset-nginx-vfjqn   1/1     Running   0          14s ⇐ 새로운 파드를 생성



#4 레플리카셋이 생성한 파드의 라벨을 변경

vagrant@ubuntu:~/kub01$ kubectl edit pods replicaset-nginx-59992   ⇐ 첫번째 파드의 이름

apiVersion: v1

kind: Pod

metadata:

  creationTimestamp: "2020-09-21T02:18:06Z"

  generateName: replicaset-nginx-

  #  labels:

  #    app: my-nginx-pods-label          ⇐ 라벨을 주석처리 후 저장

  name: replicaset-nginx-59992

  namespace: default

  ownerReferences:

       :

 

vagrant@ubuntu:~/kub01$ kubectl get pods --show-labels

NAME                     READY   STATUS    RESTARTS   AGE     LABELS

replicaset-nginx-59992   1/1     Running   0          9m31s   <none> ⇐ 관리 대상으로 간주하지 않음

replicaset-nginx-bhz8w   1/1     Running   0          56s     app=my-nginx-pods-label ⇐ 새로운 파드가 추가

replicaset-nginx-gbzrr   1/1     Running   0          9m31s   app=my-nginx-pods-label

replicaset-nginx-vfjqn   1/1     Running   0          5m5s    app=my-nginx-pods-label



#5 레플리카셋 삭제 → 같은 라벨의 파드만 삭제

vagrant@ubuntu:~/kub01$ kubectl get replicaset

NAME               DESIRED   CURRENT   READY   AGE

replicaset-nginx   3         3         3       12m

 

vagrant@ubuntu:~/kub01$ kubectl get pods --show-labels

NAME                     READY   STATUS    RESTARTS   AGE     LABELS

replicaset-nginx-59992   1/1     Running   0          12m     <none>

replicaset-nginx-bhz8w   1/1     Running   0          3m49s   app=my-nginx-pods-label

replicaset-nginx-gbzrr   1/1     Running   0          12m     app=my-nginx-pods-label

replicaset-nginx-vfjqn   1/1     Running   0          7m58s   app=my-nginx-pods-label

 

vagrant@ubuntu:~/kub01$ kubectl delete replicasets replicaset-nginx

replicaset.apps "replicaset-nginx" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get replicaset

No resources found in default namespace.

 

vagrant@ubuntu:~/kub01$ kubectl get pods --show-labels

NAME                     READY   STATUS    RESTARTS   AGE   LABELS

replicaset-nginx-59992   1/1     Running   0          13m   <none> ⇐ 레플리카셋의 관리 대상이 아니므로 삭제되지 않음



#6 라벨이 삭제된 파드는 직접 삭제

vagrant@ubuntu:~/kub01$ kubectl delete pods replicaset-nginx-59992

pod "replicaset-nginx-59992" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get pods --show-labels

No resources found in default namespace.



디플로이먼트(Deployment)

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

 

레플리카셋, 파드의 배포를 관리

⇒ 애플리케이션의 업데이트와 배포를 쉽게 하기 위해 만든 개념(객체)



디플로이먼트를 생성하면, 포드, 레플리카셋도 함께 생성되는 것을 확인

vagrant@ubuntu:~/kub01$ vi deployment-nginx.yml

apiVersion: apps/v1

kind: Deployment

metadata:

  name: my-nginx-deployment

spec:

  replicas: 3

  selector:

    matchLabels:

      app: my-nginx

  template:

    metadata:

      name: my-nginx-pod

      labels:

        app: my-nginx

    spec:

      containers:

      - name: nginx

        image: nginx:1.10

        ports:

        - containerPort: 80

 

vagrant@ubuntu:~/kub01$ kubectl apply -f deployment-nginx.yml

deployment.apps/my-nginx-deployment created

 

vagrant@ubuntu:~/kub01$ kubectl get deployment

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE

my-nginx-deployment   3/3     3            3           17s

 

vagrant@ubuntu:~/kub01$ kubectl get replicasets

NAME                             DESIRED   CURRENT   READY   AGE

my-nginx-deployment-7484748b57   3         3         3       30s

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                                   READY   STATUS    RESTARTS   AGE

my-nginx-deployment-7484748b57-dlhbn   1/1     Running   0          38s

my-nginx-deployment-7484748b57-sc6bk   1/1     Running   0          38s

my-nginx-deployment-7484748b57-vr74n   1/1     Running   0          38s



디플로이먼트를 삭제했을 때, 레플리카셋, 포드도 함께 삭제되는 것을 확인

vagrant@ubuntu:~/kub01$ kubectl delete deployment my-nginx-deployment

deployment.apps "my-nginx-deployment" deleted

 

vagrant@ubuntu:~/kub01$ kubectl get deployment

No resources found in default namespace.

 

vagrant@ubuntu:~/kub01$ kubectl get replicasets

No resources found in default namespace.

 

vagrant@ubuntu:~/kub01$ kubectl get pods

No resources found in default namespace.



 

드플로이먼트를 사용하는 이유

디플로이먼트는 컨테이너 애플리케이션을 배포하고 관리하는 역할을 담당

애플리케이션을 업데이트 할 때 레플리카셋의 변경 사항을 저장하는 리비전을 남겨 롤백 가능하게 해 주고, 무중단 서비스를 위한 포드의 롤링 업데이트 전략을 지정할 있음

 

#1 --record 옵션을 추가해서 디플로이먼트를 생성

vagrant@ubuntu:~/kub01$ kubectl apply -f deployment-nginx.yml --record

deployment.apps/my-nginx-deployment created

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                                   READY   STATUS    RESTARTS   AGE

my-nginx-deployment-7484748b57-8ph87   1/1     Running   0          8s --+ ⇐ nginx:1.10 이미지를 이용해서 생성

my-nginx-deployment-7484748b57-fkc2q   1/1     Running   0          8s     |

my-nginx-deployment-7484748b57-v7hkr   1/1     Running   0          8s  --+

 

vagrant@ubuntu:~/kub01$ cat deployment-nginx.yml

apiVersion: apps/v1

kind: Deployment

metadata:

  name: my-nginx-deployment ⇐ ❶

spec:

  replicas: 3

  selector:

    matchLabels:

      app: my-nginx

  template:

    metadata:

      name: my-nginx-pod

      labels:

        app: my-nginx

    spec:

      containers:

      - name: nginx ⇐ ❷

        image: nginx:1.10

        ports:

        - containerPort: 80

 

#2 kubectl set image 명령으로 파드의 이미지를 변경

vagrant@ubuntu:~/kub01$ kubectl set image deployment my-nginx-deployment   nginx=nginx:1.11  --record

                                                                       ~~~~~~~~~~~~~~~~~~~   ~~~~~~~~~~~~~~~~

                                                                                 ❶ 디플로이먼트 이름  ❷ 컨테이너 이름 ⇒ 컨테이너를 업데이트

deployment.apps/my-nginx-deployment image updated

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                                   READY   STATUS    RESTARTS   AGE

my-nginx-deployment-556b57945d-mlj7s   1/1     Running   0          14s

my-nginx-deployment-556b57945d-sklj2   1/1     Running   0          6s

my-nginx-deployment-556b57945d-tdg2t   1/1     Running   0          4s

 

vagrant@ubuntu:~/kub01$ kubectl get replicasets

NAME                             DESIRED   CURRENT   READY   AGE

my-nginx-deployment-556b57945d   3         3         3       5m49s ⇐ 새롭게 생성된 레플리카셋

my-nginx-deployment-7484748b57   0         0         0       9m45s ⇐ 앞에서 생성되었던 레플리카셋



#3 리비전 정보를 확인

--record=ture 옵션으로 디플로이먼트를 변경하면 변경 사항을 기록하여 해당 버전의 레플리카셋을 보관할 수 있음

 

vagrant@ubuntu:~/kub01$ kubectl rollout history deployment my-nginx-deployment

deployment.apps/my-nginx-deployment

REVISION  CHANGE-CAUSE

1         kubectl apply --filename=deployment-nginx.yml --record=true

2         kubectl set image deployment my-nginx-deployment nginx=nginx:1.11 --record=true



#4 이전 버전의 레플리카셋으로 롤백

vagrant@ubuntu:~/kub01$ kubectl rollout undo deployment my-nginx-deployment --to-revision=1

deployment.apps/my-nginx-deployment rolled back

 

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                                   READY   STATUS    RESTARTS   AGE

my-nginx-deployment-7484748b57-2mks2   1/1     Running   0          12s

my-nginx-deployment-7484748b57-2xpsw   1/1     Running   0          15s

my-nginx-deployment-7484748b57-ngcd4   1/1     Running   0          14s

 

vagrant@ubuntu:~/kub01$ kubectl get replicasets

NAME                             DESIRED   CURRENT   READY   AGE

my-nginx-deployment-556b57945d   0         0         0       11m

my-nginx-deployment-7484748b57   3         3         3       15m

 

vagrant@ubuntu:~/kub01$ kubectl rollout history deployment my-nginx-deployment

deployment.apps/my-nginx-deployment

REVISION  CHANGE-CAUSE

2         kubectl set image deployment my-nginx-deployment nginx=nginx:1.11 --record=true

3         kubectl apply --filename=deployment-nginx.yml --record=true



#5 디플로이먼트 상세 정보 확인

vagrant@ubuntu:~/kub01$ kubectl describe deploy my-nginx-deployment

Name:                   my-nginx-deployment

Namespace:              default

CreationTimestamp:      Mon, 21 Sep 2020 04:13:55 +0000

Labels:                 <none>

Annotations:            deployment.kubernetes.io/revision: 3

                        kubernetes.io/change-cause: kubectl apply --filename=deployment-nginx.yml --record=true

Selector:               app=my-nginx

Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable

StrategyType:           RollingUpdate

MinReadySeconds:        0

RollingUpdateStrategy:  25% max unavailable, 25% max surge

Pod Template:

  Labels:  app=my-nginx

  Containers:

   nginx:

    Image:        nginx:1.10

    Port:         80/TCP

    Host Port:    0/TCP

    Environment:  <none>

    Mounts:       <none>

  Volumes:        <none>

Conditions:

  Type           Status  Reason

  ----           ------  ------

  Available      True    MinimumReplicasAvailable

  Progressing    True    NewReplicaSetAvailable

OldReplicaSets:  <none>

NewReplicaSet:   my-nginx-deployment-7484748b57 (3/3 replicas created)

Events:

  Type    Reason             Age                  From                   Message

  ----    ------             ----                 ----                   -------

  Normal  ScalingReplicaSet  15m                  deployment-controller  Scaled up replica set my-nginx-deployment-556b57945d to 1

  Normal  ScalingReplicaSet  15m                  deployment-controller  Scaled down replica set my-nginx-deployment-7484748b57 to 2

  Normal  ScalingReplicaSet  15m                  deployment-controller  Scaled up replica set my-nginx-deployment-556b57945d to 2

  Normal  ScalingReplicaSet  14m                  deployment-controller  Scaled down replica set my-nginx-deployment-7484748b57 to 1

  Normal  ScalingReplicaSet  14m                  deployment-controller  Scaled up replica set my-nginx-deployment-556b57945d to 3

  Normal  ScalingReplicaSet  14m                  deployment-controller  Scaled down replica set my-nginx-deployment-7484748b57 to 0

  Normal  ScalingReplicaSet  3m43s                deployment-controller  Scaled up replica set my-nginx-deployment-7484748b57 to 1

  Normal  ScalingReplicaSet  3m42s                deployment-controller  Scaled down replica set my-nginx-deployment-556b57945d to 2

  Normal  ScalingReplicaSet  3m42s                deployment-controller  Scaled up replica set my-nginx-deployment-7484748b57 to 2

  Normal  ScalingReplicaSet  3m40s (x2 over 19m)  deployment-controller  Scaled up replica set my-nginx-deployment-7484748b57 to 3

  Normal  ScalingReplicaSet  3m40s                deployment-controller  Scaled down replica set my-nginx-deployment-556b57945d to 1

  Normal  ScalingReplicaSet  3m37s                deployment-controller  Scaled down replica set my-nginx-deployment-556b57945d to 0



vagrant@ubuntu:~/kub01$ kubectl rollout history deployment my-nginx-deployment

deployment.apps/my-nginx-deployment

REVISION  CHANGE-CAUSE

3         kubectl apply --filename=deployment-nginx.yml --record=true

4         kubectl set image deployment my-nginx-deployment nginx=nginx:1.11 --record=true

 

vagrant@ubuntu:~/kub01$ kubectl rollout history deployment my-nginx-deployment --revision=3

deployment.apps/my-nginx-deployment with revision #3

Pod Template:

  Labels:       app=my-nginx

        pod-template-hash=7484748b57

  Annotations:  kubernetes.io/change-cause: kubectl apply --filename=deployment-nginx.yml --record=true

  Containers:

   nginx:

    Image:      nginx:1.10

    Port:       80/TCP

    Host Port:  0/TCP

    Environment:        <none>

    Mounts:     <none>

  Volumes:      <none>





서비스(Service)

쿠버네티스 클러스터 안에서 파드의 집합에 대한 경로나 서비스 디스커버리를 제공하는 리소스

 

타입

서비스 타입에 따라 포드에 접근하는 방법이 달라짐

  • ClusterIP 타입

    • 쿠버네티스 내부에서만 포들에 접근할 때 사용

    • 외부로 포드를 노출하지 않기 때문에 쿠버네티스 클러스터 내부에서만 사용되는 포드에 적합

  • NodePort 타입

    • 포드에 접근할 수 있는 포트를 클러스터의 모드 노드에 동일하게 개방

    • 외부에서 포드에 접근할 수 있는 서비스 타입

    • 접근할 수 있는 포트는 랜덤으로 정해지지만, 특정 포트로 접근하도록 설정할 수 있음

  • LoadBalancer 타입

    • 클라우드 플랫폼에서 제공하는 로드 밸러서를 동적으로 프로비저닝해서 포드에 연결

    • 외부에서 포드에 접근할 수 있는 서비스 타입

    • 일반적으로 AWS, GCP, … 등과 같은 클라우드 플랫폼 환경에서 사용



디플로이먼트 생성

#0 모든 리소스 삭제 

vagrant@ubuntu:~/kub01$ kubectl delete deployment,replicasets,pods --all



#1 매니페스트 파일을 정의(yml)

vagrant@ubuntu:~/kub01$ vi deployment-hostname.yml

apiVersion: apps/v1

kind: Deployment

metadata:

  name: hostname-deployment

spec:

  replicas: 3

  selector:

    matchLabels:

      app: webserver

  template:

    metadata:

      name: my-webserver

      labels:

        app: webserver

    spec:

      containers:

      - name: my-webserver

        image: alicek106/rr-test:echo-hostname   ⇐ 컨테이너(포드)의 호스트 이름을 반환하는 웹 서버 이미지

        ports:

        - containerPort: 80



### alicek106/rr-test:echo-hostname 이미지로 컨테이너를 실행

 

vagrant@ubuntu:~$ docker run -itd --name test -p 80:80  alicek106/rr-test:echo-hostname

346c0be44baebdd8be42a281fc4bd7fa56b157ffaf6ee62c6726857825df71e0

 

vagrant@ubuntu:~$ docker container ls

CONTAINER ID    IMAGE                                    COMMAND                CREATED             STATUS              PORTS       NAMES

346c0be44bae    alicek106/rr-test:echo-hostname    "/bin/sh -c /entrypo…"  6 seconds ago       Up 4 seconds     0.0.0.0:80->80/tcp   test

 

vagrant@ubuntu:~$ docker container exec -it test /bin/bash

root@346c0be44bae:/# exit

 

vagrant@ubuntu:~$ curl http://localhost:80

<!DOCTYPE html>

<meta charset="utf-8" />

<link rel="stylesheet" type="text/css" href="./css/layout.css" />

 

 

<div class="form-layout">

        <blockquote>

        <p>Hello,  346c0be44bae</p>     </blockquote> ⇐ 컨테이너 ID = 호스트 이름

</div>

 



#2 디플로이먼트를 생성

vagrant@ubuntu:~/kub01$ kubectl apply -f deployment-hostname.yml

deployment.apps/hostname-deployment created



#3 디플로이먼트를 통해서 생성된 파드를 조회(확인)

vagrant@ubuntu:~/kub01$ kubectl get pods

NAME                                   READY   STATUS    RESTARTS   AGE

hostname-deployment-7dfd748479-7zdv7   1/1     Running   0          17s

hostname-deployment-7dfd748479-pp8x4   1/1     Running   0          17s

hostname-deployment-7dfd748479-rtgzv   1/1     Running   0          17s



#4 -o wide 옵션을 이용해서 각 파드에 할당된 IP를 확인 ⇒ -o, --output='' : 출력 포맷을 지정

#5 파드를 임시로 하나 생성해서 hostname-deployment 디플로이먼트로 생성된 파드로 HTTP 요청을 전달

vagrant@ubuntu:~/kub01$ kubectl run -it --rm debug --image=alicek106/ubuntu:curl --restart=Never curl 172.18.0.3 | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-pp8x4</p>     </blockquote>

 

⇒ 디플로이먼트(레플리카세트)를 구성하고 있는 파드에 접근하기 위해서는 각 개별 파드의 주소를 알고 있어야 가능

⇒ 운영 시에 개수가 많아지고 가변적인 각 파드의 주소를 이용하는 것은 유연성이 떨어지게 된다. 

→ 일괄된 형식으로 접근이 가능하도록 서비스가 제공되는 것이 필요




 

ClusterIP 타입의 서비스 → 쿠버네티스 내부에서만 포드에 접근 가능

 

#1 매니페스트 파일을 작성

vagrant@ubuntu:~/kub01$ vi hostname-svc-clusterip.yml

apiVersion: v1

kind: Service

metadata:

  name: hostname-svc-clusterip

spec:

  ports:

    - name: web-port

      port: 8080       ⇒ 서비스의 IP에 접근할 때 사용할 포트

      targetPort: 80   ⇒ selector 항목에서 정의한 라벨에 의해 접근 대상이 된 파드 내부에서 사용하고 있는 포트

  selector:            ⇒ 어떤 라벨을 가지는 포드에 접근할 수 있게 만들 것인지를 결정

    app: webserver

  type: ClusterIP      ⇒ 서비스 타입

 

#2 서비스 생성 및 확인

vagrant@ubuntu:~/kub01$ kubectl apply -f hostname-svc-clusterip.yml

service/hostname-svc-clusterip created

 

vagrant@ubuntu:~/kub01$ kubectl get services

NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE

hostname-svc-clusterip   ClusterIP   10.110.56.159   <none>        8080/TCP   8s

kubernetes               ClusterIP   10.96.0.1       <none>        443/TCP    3d ⇐ 쿠버네티스 API에 접근하기 위한 서비스



#3 임시 포드를 생성해서 요청을 전송

vagrant@ubuntu:~/kub01$ kubectl run -it --rm debug --image=alicek106/ubuntu:curl --restart=Never -- bash

If you don't see a command prompt, try pressing enter.

root@debug:/#

root@debug:/# ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

82: eth0@if83: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:12:00:06 brd ff:ff:ff:ff:ff:ff

    inet 172.18.0.6/16 brd 172.18.255.255 scope global eth0

       valid_lft forever preferred_lft forever

root@debug:/# curl http://10.110.56.159:8080 --silent | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-pp8x4</p>     </blockquote>

root@debug:/# curl http://10.110.56.159:8080 --silent | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-pp8x4</p>     </blockquote>

root@debug:/# curl http://10.110.56.159:8080 --silent | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-rtgzv</p>     </blockquote>

root@debug:/# curl http://10.110.56.159:8080 --silent | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-pp8x4</p>     </blockquote>

 

⇒ 서비스의 IP와 PORT를 통해 파드에 접근 ⇒ 서비스와 연결된 파드에 로드밸렌싱을 수행



#4 서비스 이름으로도 파드에 접근이 가능

root@debug:/# curl http://hostname-svc-clusterip:8080 -s | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-rtgzv</p>     </blockquote>

root@debug:/# curl http://hostname-svc-clusterip:8080 -s | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-pp8x4</p>     </blockquote>

 

⇒ 내부 DNS를 구동



#5 서비스 삭제

root@debug:/# exit

exit

pod "debug" deleted

 

vagrant@ubuntu:~/kub01$ kubectl delete service hostname-svc-clusterip

service "hostname-svc-clusterip" deleted




NodePort 타입의 서비스 → 서비스를 이용해 파드를 외부에 노출이 가능

모든 노드의 특정 포트를 개방해서 서비스에 접근하는 방식

 

#1 매니페스트 파일을 작성

vagrant@ubuntu:~/kub01$ vi hostname-svc-nodeport.yml

apiVersion: v1

kind: Service

metadata:

  name: hostname-svc-nodeport

spec:

  ports:

    - name: web-port

      port: 8080

      targetPort: 80

  selector:

    app: webserver

  type: NodePort



#2 서비스 생성 및 확인

vagrant@ubuntu:~/kub01$ kubectl apply -f hostname-svc-nodeport.yml

service/hostname-svc-nodeport created

 

vagrant@ubuntu:~/kub01$ kubectl get services

NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE

hostname-svc-nodeport   NodePort    10.111.29.91   <none>        8080:30309/TCP   7s

kubernetes              ClusterIP   10.96.0.1      <none>        443/TCP          3d1h

 

vagrant@ubuntu:~/kub01$ kubectl get nodes -o wide

NAME       STATUS   ROLES    AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION       CONTAINER-RUNTIME

minikube   Ready    master   3d1h   v1.19.0   172.17.0.2    <none>        Ubuntu 20.04 LTS   4.15.0-117-generic   docker://19.3.8



#3 클러스터 외부(172.17.0.2)에서 서비스 포토(30309)로 접근

vagrant@ubuntu:~/kub01$ curl http://172.17.0.2:30309 -s | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-rtgzv</p>     </blockquote>

vagrant@ubuntu:~/kub01$ curl http://172.17.0.2:30309 -s | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-pp8x4</p>     </blockquote>



#4 ClusterIP 타입의 서비스와 같이 내부 IP와 서비스 이름으로 접근도 가능

vagrant@ubuntu:~/kub01$ kubectl run -it --rm debug --image=alicek106/ubuntu:curl --restart=Never -- bash

If you don't see a command prompt, try pressing enter.

root@debug:/#

root@debug:/# curl http://10.111.29.91:8080 -s | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-pp8x4</p>     </blockquote>

root@debug:/# curl http://10.111.29.91:8080 -s | grep Hello

        <p>Hello,  hostname-deployment-7dfd748479-7zdv7</p>     </blockquote>

root@debug:/# exit

exit

pod "debug" deleted



네임스페이스(namespace) 

리소스(포드, 레플리카세트, 디플로이먼트, 서비스, …)를 논리적으로 구분하는 기분



네임스페이스 조회 

vagrant@ubuntu:~/kub01$ kubectl get namespaces

NAME              STATUS   AGE

default           Active   3d1h

kube-node-lease   Active   3d1h

kube-public       Active   3d1h

kube-system       Active   3d1h

 

⇒ 기본적으로 kube-* 네임스페이스를 제공

⇒ default : 쿠버네티스를 설치하면 자동으로 사용하도록 설정되는 네임스페이스



특정 네임스페이에 생성된 포드 확인

vagrant@ubuntu:~/kub01$ kubectl get pods --namespace default

NAME                                   READY   STATUS    RESTARTS   AGE

hostname-deployment-7dfd748479-7zdv7   1/1     Running   0          106m

hostname-deployment-7dfd748479-pp8x4   1/1     Running   0          106m

hostname-deployment-7dfd748479-rtgzv   1/1     Running   0          106m

 

vagrant@ubuntu:~/kub01$ kubectl get pods --namespace kube-system

NAME                               READY   STATUS    RESTARTS   AGE

coredns-f9fd979d6-lsnmk            1/1     Running   2          3d1h

etcd-minikube                      1/1     Running   1          3d1h

kube-apiserver-minikube            1/1     Running   1          3d1h

kube-controller-manager-minikube   1/1     Running   2          3d1h

kube-proxy-sbghs                   1/1     Running   2          3d1h

kube-scheduler-minikube            1/1     Running   2          3d1h

storage-provisioner                1/1     Running   4          3d1h



특정 네임스페이에 생성된 서비스 확인

vagrant@ubuntu:~/kub01$ kubectl get service --namespace kube-system

NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE

kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   3d1h




네임스페이스 사용

#1 YAML 파일 생성

vagrant@ubuntu:~/kub01$ vi production-namespace.yml

apiVersion: v1

kind: Namespace

metadata:

  name: production



#2 네임스페이스 생성 및 확인

vagrant@ubuntu:~/kub01$ kubectl apply -f production-namespace.yml

namespace/production created

 

vagrant@ubuntu:~/kub01$ kubectl get namespaces

NAME              STATUS   AGE

default           Active   3d1h

kube-node-lease   Active   3d1h

kube-public       Active   3d1h

kube-system       Active   3d1h

production        Active   21s



### YML 파일 없이 네임스페이스를 생성

vagrant@ubuntu:~/kub01$ kubectl create namespace mynamespace

namespace/mynamespace created

 

vagrant@ubuntu:~/kub01$ kubectl get namespaces

NAME              STATUS   AGE

default           Active   3d1h

kube-node-lease   Active   3d1h

kube-public       Active   3d1h

kube-system       Active   3d1h

mynamespace       Active   8s

production        Active   2m4s



#3 특정 네임스페이스에 리소스를 생성하는 방법

YAML 파일에 metadata.namespace 항목에 네임스페이스를 기술

 

vagrant@ubuntu:~/kub01$ cp deployment-hostname.yml hostname-deploy-svc-ns.yml

vagrant@ubuntu:~/kub01$ vi hostname-deploy-svc-ns.yml

apiVersion: apps/v1

kind: Deployment

metadata:

  name: hostname-deployment-ns

  namespace: production

spec:

  replicas: 3

  selector:

    matchLabels:

      app: webserver

  template:

    metadata:

      name: my-webserver

      labels:

        app: webserver

    spec:

      containers:

      - name: my-webserver

        image: alicek106/rr-test:echo-hostname

        ports:

        - containerPort: 80


---

apiVersion: v1

kind: Service

metadata:

  name: hostname-svc-clusterip-ns

  namespace: production

spec:

  ports:

    - name: web-port

      port: 8080

      targetPort: 80

  selector:

    app: webserver

  type: ClusterIP

 

vagrant@ubuntu:~/kub01$ kubectl apply -f hostname-deploy-svc-ns.yml

deployment.apps/hostname-deployment-ns created

service/hostname-svc-clusterip-ns created

 

vagrant@ubuntu:~/kub01$ kubectl get pods,services --namespace production

NAME                                          READY   STATUS    RESTARTS   AGE

pod/hostname-deployment-ns-7dfd748479-4mg2b   1/1     Running   0          50s

pod/hostname-deployment-ns-7dfd748479-jgzg6   1/1     Running   0          50s

pod/hostname-deployment-ns-7dfd748479-rg8lw   1/1     Running   0          50s

 

NAME                                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE

service/hostname-svc-clusterip-ns   ClusterIP   10.97.13.64   <none>        8080/TCP   50s



#4 네임스페이스가 다른 서비스에 접근

### default 네임스페이스에 debug 파드를 생성

vagrant@ubuntu:~/kub01$ kubectl run -it --rm debug --image=alicek106/ubuntu:curl --restart=Never -- bash

If you don't see a command prompt, try pressing enter.

root@debug:/#

root@debug:/# curl http://hostname-svc-clusterip-ns:8080 ⇐ production 네임스페이스에 생성된 서비스를 호출

curl: (6) Could not resolve host: hostname-svc-clusterip-ns

⇒ 네임스페이스가 다르기 때문에 (바로)ㅠ 서비스를 이용할 수 없음



### 네임스페이스가 다른 서비스를 이용하기 위해서는 <서비스 이름>.<네임스페이스 이름>.svc 형식으로 접근해야 함

root@debug:/# curl http://hostname-svc-clusterip-ns.production.svc:8080

<!DOCTYPE html>

<meta charset="utf-8" />

<link rel="stylesheet" type="text/css" href="./css/layout.css" />

 

 

<div class="form-layout">

        <blockquote>

        <p>Hello,  hostname-deployment-ns-7dfd748479-rg8lw</p>  </blockquote>

</div>



#5 네임스페이스 삭제

vagrant@ubuntu:~/kub01$ kubectl delete namespace production

namespace "production" deleted





네임스페이스에 속하는 오브젝트 종류

vagrant@ubuntu:~/kub01$ kubectl api-resources --namespaced=true

NAME                        SHORTNAMES   APIGROUP   NAMESPACED   KIND

bindings                                                             true         Binding

configmaps                  cm                                       true         ConfigMap

endpoints                   ep                                       true         Endpoints

events                      ev                                       true         Event

limitranges                 limits                                   true         LimitRange

persistentvolumeclaims      pvc                                      true         PersistentVolumeClaim

pods                        po                                       true         Pod

podtemplates                                                         true         PodTemplate

replicationcontrollers      rc                                       true         ReplicationController

resourcequotas              quota                                    true         ResourceQuota

secrets                                                              true         Secret

serviceaccounts             sa                                       true         ServiceAccount

services                    svc                                      true         Service

controllerrevisions                      apps                        true         ControllerRevision

daemonsets                  ds           apps                        true         DaemonSet

deployments                 deploy       apps                        true         Deployment

replicasets                 rs           apps                        true         ReplicaSet

statefulsets                sts          apps                        true         StatefulSet

localsubjectaccessreviews                authorization.k8s.io        true         LocalSubjectAccessReview

horizontalpodautoscalers    hpa          autoscaling                 true         HorizontalPodAutoscaler

cronjobs                    cj           batch                       true         CronJob

jobs                                     batch                       true         Job

leases                                   coordination.k8s.io         true         Lease

endpointslices                           discovery.k8s.io            true         EndpointSlice

events                      ev           events.k8s.io               true         Event

ingresses                   ing          extensions                  true         Ingress

ingresses                   ing          networking.k8s.io           true         Ingress

networkpolicies             netpol       networking.k8s.io           true         NetworkPolicy

poddisruptionbudgets        pdb          policy                      true         PodDisruptionBudget

rolebindings                             rbac.authorization.k8s.io   true         RoleBinding

roles                                    rbac.authorization.k8s.io   true         Role



네임스페이스에 속하지 않는 오브젝트 종류

vagrant@ubuntu:~/kub01$ kubectl api-resources --namespaced=false

NAME                              SHORTNAMES   APIGROUP             NAMESPACED   KIND

componentstatuses                 cs                                          false        ComponentStatus

namespaces                        ns                                          false        Namespace

nodes                             no                                          false        Node

persistentvolumes                 pv                                          false        PersistentVolume

mutatingwebhookconfigurations                  admissionregistration.k8s.io   false        MutatingWebhookConfiguration

validatingwebhookconfigurations                admissionregistration.k8s.io   false        ValidatingWebhookConfiguration

customresourcedefinitions         crd,crds     apiextensions.k8s.io           false        CustomResourceDefinition

apiservices                                    apiregistration.k8s.io         false        APIService

tokenreviews                                   authentication.k8s.io          false        TokenReview

selfsubjectaccessreviews                       authorization.k8s.io           false        SelfSubjectAccessReview

selfsubjectrulesreviews                        authorization.k8s.io           false        SelfSubjectRulesReview

subjectaccessreviews                           authorization.k8s.io           false        SubjectAccessReview

certificatesigningrequests        csr          certificates.k8s.io            false        CertificateSigningRequest

ingressclasses                                 networking.k8s.io              false        IngressClass

runtimeclasses                                 node.k8s.io                    false        RuntimeClass

podsecuritypolicies               psp          policy                         false        PodSecurityPolicy

clusterrolebindings                            rbac.authorization.k8s.io      false        ClusterRoleBinding

clusterroles                                   rbac.authorization.k8s.io      false        ClusterRole

priorityclasses                   pc           scheduling.k8s.io              false        PriorityClass

csidrivers                                     storage.k8s.io                 false        CSIDriver

csinodes                                       storage.k8s.io                 false        CSINode

storageclasses                    sc           storage.k8s.io                 false        StorageClass

volumeattachments                              storage.k8s.io                 false        VolumeAttachment

 

 

 

교재 195 ~ 214페이지 내용을 실습하면서 복습