# 실습

### 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
    ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kubernetes.youngwjung.com/core-concepts/deployment/lab.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
