> For the complete documentation index, see [llms.txt](https://kubernetes.youngwjung.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kubernetes.youngwjung.com/core-concepts/deployment/lab.md).

# 실습

### Deployment&#x20;

1. Deployment 생성&#x20;

   ```
   kubectl create deployment nginx --image=nginx --replicas=3
   ```
2. Deployment 상태 확인&#x20;

   ```
   kubectl get deployment nginx
   ```
3. Deployment에 발생한 Event 확인

   ```
   kubectl describe deployment nginx
   ```
4. ReplicaSet 상태 확인&#x20;

   ```
   kubectl get rs -l app=nginx
   ```
5. ReplicaSet에 발생한 Event 확인

   ```
   kubectl describe rs -l app=nginx
   ```
6. Pod 상태 확인&#x20;

   ```
   kubectl get pod -l app=nginx
   ```
7. Pod에 발생한 Event 확인

   ```
   kubectl describe pod -l app=nginx
   ```
8. Deployment에 명시된 Template 확인&#x20;

   ```
   kubectl get deploy nginx -o jsonpath='{.spec.template}' | jq
   ```
9. CLI로 동일한 이미지를 사용해서 Pod를 생성할때 나오는 Manifest 확인

   ```
   kubectl run nginx --image=nginx --dry-run=client -ojson | jq
   ```
10. Deployment에 명시된 컨테이너 이미지 확인

    ```
    kubectl get deploy nginx \
    -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
    ```
11. 실제로 생성된 Pod에 사용된 이미지 확인

    ```
    kubectl get pod -l app=nginx \
    -o jsonpath='{.items[0].status.containerStatuses[0].image}{"\n"}'
    ```
12. DockerHub에서 NGINX 도커 이미지 태그 확인 - <https://hub.docker.com/_/nginx>
13. 생성된 Deployment 객체의 Manifest를 텍스트 에디터로 열기

    ```
    kubectl edit deployment nginx
    ```
14. spec.template.spec.containers\[0].image를 *nginx*에서 *nginx:alpine*으로 변경 후 저장하고 나가기&#x20;

    ```
    ...
    ...
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: nginx
        spec:
          containers:
          - image: nginx:alpine
            imagePullPolicy: Always
            name: nginx
    ...
    ...
    ```
15. PodSpec에 이미지가 업데이트 됐는지 확인&#x20;

    ```
    kubectl get pod $(kubectl get pod -l app=nginx \
    -o=jsonpath='{.items[0].metadata.name}{"\n"}') -ojsonpath='{.spec.containers[0].image}{"\n"}'
    ```
16. 실제로 생성된 Pod에 사용된 이미지 확인

    ```
    kubectl get pod -l app=nginx \
    -o jsonpath='{.items[0].status.containerStatuses[0].image}{"\n"}'
    ```
17. 클러스터에서 발생한 Event를 시간순으로 확인

    ```
    kubectl get events --sort-by='.lastTimestamp'
    ```
18. 아래의 명령어로 컨테이너 이미지를 *nginx:stable* 로 업데이트&#x20;

    ```
    kubectl set image deployment nginx nginx=nginx:stable
    ```
19. Pod의 이미지가 업데이트 됐는지 확인&#x20;

    ```
    kubectl get pod $(kubectl get pod -l app=nginx \
    -o=jsonpath='{.items[0].metadata.name}') -ojsonpath='{.spec.containers[0].image}{"\n"}'
    ```
20. Deployment 변경사항 히스토리 확인&#x20;

    ```
    kubectl rollout history deployment nginx
    ```
21. 첫번째 버전과 현재 버전 비교

    ```
    diff <(kubectl rollout history deploy nginx --revision=1) <(kubectl rollout history deploy nginx --revision=$(kubectl get deploy nginx -o jsonpath='{.metadata.annotations.deployment\.kubernetes\.io/revision}')) -y
    ```
22. 아래의 명령어로 컨테이너 이미지를 nginx:perl 로 업데이트&#x20;

    ```
    kubectl patch deploy nginx --record --type=json \
    -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "nginx:perl"}]'
    ```
23. Deployment 변경사항 히스토리 확인&#x20;

    ```
    kubectl rollout history deployment nginx
    ```
24. 이전 Revision으로 롤백&#x20;

    ```
    kubectl rollout undo deployment nginx
    ```
25. Deployment 변경사항 히스토리 확인&#x20;

    ```
    kubectl rollout history deployment nginx
    ```
26. 클러스터에서 발생한 Event를 시간순으로 확인

    ```
    kubectl get events --sort-by='.lastTimestamp'
    ```
27. Deployment에 발생한 Event 확인

    ```
    kubectl describe deploy nginx
    ```
28. Revision 4로 롤백&#x20;

    ```
    kubectl rollout undo deployment nginx --to-revision=4
    ```
29. Deployment 변경사항 히스토리 확인&#x20;

    ```
    kubectl rollout history deployment nginx
    ```
30. Deployment 삭제&#x20;

    ```
    kubectl delete deploy nginx
    ```

### Under the hood of ReplicaSet&#x20;

1. Deployment 생성&#x20;

   ```
   kubectl create deployment nginx --image=nginx --replicas=3
   ```
2. Pod 생성 확인

   ```
   kubectl get pod -l app=nginx
   ```
3. 다른 터미널을 열고 Event 객체에 상태 변화 실시간 모니터링 - *아래의 명령어를 입력하고 엔터키를 몇번 입력해서 간격을 만들어두면 새로운 로그를 좀 더 쉽게 알아볼수 있음*

   ```
   kubectl get events -w
   ```
4. 기존 터미널로 돌아와서 3개의 Pod 중에서 한개를 삭제&#x20;

   ```
   kubectl delete pod \
   $(kubectl get pod -l app=nginx -o=jsonpath='{.items[0].metadata.name}')
   ```
5. Pod가 다시 생성됐는지 확인&#x20;

   ```
   kubectl get pod -l app=nginx
   ```
6. 다른 터미널로 이동해서 새로 발생한 Event 확인
7. 기존 터미널로 돌아와서 ReplicaSet의 Selector 조건 확인&#x20;

   ```
   kubectl get rs -l app=nginx -o=jsonpath='{.items[*].spec.selector}' | jq
   ```
8. 현재 생성된 Pod들의 Label 확인&#x20;

   ```
   kubectl get pod --show-labels
   ```
9. 다른 터미널로 이동해서 ReplicaSet 상태 변화 실시간 모니터링

   ```
   kubectl get rs -l app=nginx -w
   ```
10. 기존 터미널로 돌아와서 ReplicaSet의 Selector 조건에 명시된 Label을 가진 Pod 생성&#x20;

    ```
    kubectl run httpd --image=httpd \
    --labels="app=nginx,pod-template-hash=$(kubectl get rs -l app=nginx -o jsonpath='{.items[0].metadata.labels.pod-template-hash}')"
    ```
11. 생성된 Pod 확인

    ```
    kubectl get pod -l app=nginx
    ```
12. 다른 터미널로 이동해서 ReplicaSet 상태 변화 확인 - <https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#scaling-a-replicaset>
13. 기존 터미널로 돌아와서 ReplicaSet에 발생한 Event 확인

    ```
    kubectl describe rs -l app=nginx
    ```
14. 3개의 Pod 중에서 한개의 Pod의 app Label의 값을 nginx에서 httpd로 변경

    ```
    kubectl label pod \
    $(kubectl get pod -l app=nginx -o jsonpath='{.items[0].metadata.name}') \
    app=httpd --overwrite
    ```
15. 다른 터미널로 이동해서 ReplicaSet 상태 변화 확인
16. 현재 생성된 Pod들의 Label 확인&#x20;

    ```
    kubectl get pod --show-labels
    ```
17. 리소스 삭제&#x20;

    ```
    {
        kubectl delete deployment nginx
        kubectl delete pod -l app=httpd
    }
    ```

### Deployment Strategy

1. Deployment 생성&#x20;

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     labels:
       app: nginx
     name: nginx
   spec:
     replicas: 8
     selector:
       matchLabels:
         app: nginx
     template:
       metadata:
         labels:
           app: nginx
       spec:
         containers:
         - name: nginx
           image: youngwjung/nginx:v1
           ports:
           - name: http
             containerPort: 80
           readinessProbe:
             httpGet:
               path: /
               port: http
             initialDelaySeconds: 10
   EOF
   ```
2. 생성된 Pod 확인

   ```
   kubectl get pod -l app=nginx
   ```
3. Deployment에 명시된 배포 전략 확인

   ```
   kubectl get deploy nginx -o jsonpath='{.spec.strategy}' | jq
   ```
4. Service 생성

   ```
   kubectl expose deploy nginx
   ```
5. 부하를 생성하는 Pod 생성

   ```
   kubectl run load-generator --image=curlimages/curl --command -- \
   sh -c "while true; do curl -sSf --no-keepalive --connect-timeout 0.5 nginx; sleep 0.5; done"
   ```
6. 두번째 터미널을 열고 Deployment 상태 변화 실시간 모니터링

   ```
   kubectl get deploy nginx -w
   ```
7. 세번째 터미널을 열고 부하를 생성하는 Pod 로그 확인

   ```
   kubectl logs load-generator --tail 10 -f
   ```
8. 첫번째 터미널로 이동해서 컨테이너 이미지 변경&#x20;

   ```
   kubectl set image deployment nginx nginx=youngwjung/nginx:v2
   ```
9. 세번째 터미널로 이동해서 웹서버 응답 확인
10. 두번째 터미널을 열고 Deployment 상태 변화 확인
11. 첫번째 터미널로 이동해서 배포 전략 변경

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: nginx
      name: nginx
    spec:
      strategy:
        type: Recreate
      replicas: 8
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: youngwjung/nginx:v2
            ports:
            - name: http
              containerPort: 80
            readinessProbe:
              httpGet:
                path: /
                port: http
              initialDelaySeconds: 10
    EOF
    ```
12. Deployment에 명시된 배포 전략 확인

    ```
    kubectl get deploy nginx -o jsonpath='{.spec.strategy}' | jq
    ```
13. 컨테이너 이미지 변경&#x20;

    ```
    kubectl set image deployment nginx nginx=youngwjung/nginx:v3
    ```
14. 세번째 터미널로 이동해서 웹서버 응답 확인
15. 두번째 터미널을 열고 Deployment 상태 변화 확인
16. 첫번째 터미널로 이동해서 리소스 삭제

    ```
    {
        kubectl delete pod load-generator --grace-period=0
        kubectl delete svc nginx
        kubectl delete deploy nginx
    }
    ```

### Owners and Dependents

1. 이미 생성된 Deployment, ReplicaSet, Pod 확인

   ```
   kubectl get deploy,rs,pod
   ```
2. Deployment 생성&#x20;

   ```
   kubectl create deployment nginx --image=nginx --replicas=3
   ```
3. 생성된 ReplicaSet 확인

   ```
   kubectl get rs -l app=nginx
   ```
4. 생성된 ReplicaSet에 명시된 ownerReferences 확인

   ```
   kubectl get rs -l app=nginx \
   -o=jsonpath='{.items[0].metadata.ownerReferences}' | jq
   ```
5. 위에서 생성한 Deployment의 uid 확인

   ```
   kubectl get deploy nginx -o=jsonpath='{.metadata.uid}{"\n"}'
   ```
6. 생성된 Pod 확인

   ```
   kubectl get pod -l app=nginx
   ```
7. 생성된 Pod에 명시된 ownerReferences 확인

   ```
   kubectl get pod -l app=nginx \
   -o=jsonpath='{.items[*].metadata.ownerReferences}' | jq
   ```
8. 생성된 ReplicaSet의 이름 확인

   ```
   kubectl get rs -l app=nginx
   ```
9. 생성된 ReplicaSet의 uid 확인

   ```
   kubectl get rs -l app=nginx -o=jsonpath='{.items[0].metadata.uid}{"\n"}'
   ```
10. 하나의 Pod의 이름을 환경변수로 저장

    ```
    export ORPHAN_POD=$(kubectl get pod -l app=nginx -o=jsonpath='{.items[0].metadata.name}')
    ```
11. Pod의 이름이 환경변수로 저장되었는지 확인

    ```
    echo $ORPHAN_POD
    ```
12. Pod에 명시된 ownerReferences 확인

    ```
    kubectl get pod $ORPHAN_POD \
    -o=jsonpath='{.metadata.ownerReferences}' | jq
    ```
13. ReplicaSet의 Selector 조건 확인&#x20;

    ```
    kubectl get rs \
    $(kubectl get rs -l app=nginx -o=jsonpath='{.items[0].metadata.name}') \
    -ojsonpath='{.spec.selector}' | jq
    ```
14. Pod의 Label 확인&#x20;

    ```
    kubectl get pod $ORPHAN_POD --show-labels
    ```
15. Pod의 Label 변경

    ```
    kubectl label pod $ORPHAN_POD app=orphan --overwrite
    ```
16. Pod에 명시된 ownerReferences 확인

    ```
    kubectl get pod $ORPHAN_POD \
    -o=jsonpath='{.metadata.ownerReferences}' | jq
    ```
17. Pod의 메타데이터에 ownerReferences가 존재하는지 확인

    ```
    kubectl get pod $ORPHAN_POD \
    -o=jsonpath='{.metadata}' | jq 'del(.managedFields)'
    ```
18. 이미 생성된 Deployment, ReplicaSet, Pod 확인

    ```
    kubectl get deploy,rs,pod
    ```
19. Deployment 삭제

    ```
    kubectl delete deploy nginx
    ```
20. ReplicaSet랑 Pod도 같이 삭제되었는지 확인

    ```
    kubectl get deploy,rs,pod
    ```
21. 삭제되지 않은 Pod가 기존에 Label을 변경한 Pod 인지 학인

    ```
    echo $ORPHAN_POD
    ```
22. Pod 삭제

    ```
    kubectl delete pod $ORPHAN_POD
    ```
