# 실습

### 쿠버네티스 API 호출

#### Kubectl

1. 쿠버네티스 공식 CLI로 명령형 방식으로 객체 생성

   ```
   kubectl run nginx --image=nginx
   ```
2. 객체가 생성되었는지 확인

   ```
   kubectl get pod nginx
   ```
3. 명령형 방식으로 객체 삭제

   ```
   kubectl delete pod nginx
   ```
4. 객체 선언문 (Manifest) 파일 생성

   ```
   cat <<EOF > nginx.yaml
   apiVersion: v1
   kind: Pod
   metadata:
     name: nginx
   spec:
     containers:
     - name: nginx
       image: nginx
   EOF
   ```
5. 선언형 방식으로 객체 생성

   ```
   kubectl apply -f nginx.yaml
   ```
6. 객체가 생성되었는지 확인

   ```
   kubectl get pod nginx
   ```
7. 선언형 방식으로 객체 삭제

   ```
   kubectl delete -f nginx.yaml
   ```

#### REST API

1. 위에서 YAML 형식으로 생성한 객체 선언문을 JSON 형식으로 변환

   ```
   {
       sudo wget https://github.com/mikefarah/yq/releases/download/v4.9.3/yq_linux_amd64 -O /usr/bin/yq 
       sudo chmod +x /usr/bin/yq
       sudo yq eval -j nginx.yaml
       sudo yq eval -j nginx.yaml > nginx.json
   }
   ```
2. API 호출에 필요한 권한 설정

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: rbac.authorization.k8s.io/v1
   kind: Role
   metadata:
     name: pod-access
   rules:
     - apiGroups: [""]
       resources:
         - pods
       verbs: ["create", "list", "get", "delete"]
   ---
   apiVersion: v1
   kind: ServiceAccount
   metadata:
     name: pod-access
   ---
   apiVersion: rbac.authorization.k8s.io/v1
   kind: RoleBinding
   metadata:
     name: pod-access
   roleRef:
     apiGroup: rbac.authorization.k8s.io
     kind: Role
     name: pod-access
   subjects:
     - kind: ServiceAccount
       name: pod-access
   EOF
   ```
3. 발급된 인증 토큰 확인을 확인하고 환경변수로 지정

   ```
   {
       export TOKEN=$(kubectl get secret \
       $(kubectl get sa pod-access -o=jsonpath='{.secrets[0].name}') \
       -o=jsonpath='{.data.token}' | base64 -d)
       
       echo $TOKEN
   }
   ```
4. 위에서 확인한 토큰 내용 확인

   ```
   jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<<$TOKEN
   ```
5. API 서버 주소를 확인하고 환경변수로 지정&#x20;

   ```
   {
       export K8S_SERVER=$(kubectl config view \
       -o=jsonpath='{.clusters[*].cluster.server}')
       
       echo $K8S_SERVER
   }
   ```
6. Pod를 생성하는 API 호출

   ```
   curl -k -X POST \
   -H "Authorization: Bearer $TOKEN" \
   -H "Content-Type: application/json" \
   $K8S_SERVER/api/v1/namespaces/default/pods -d@nginx.json
   ```
7. Pod가 생성되었는지 확인

   ```
   curl -k -X GET \
   -H "Authorization: Bearer $TOKEN" \
   -H "Content-Type: application/json" \
   $K8S_SERVER/api/v1/namespaces/default/pods/nginx
   ```
8. Pod 삭제

   ```
   curl -k -X DELETE \
   -H "Authorization: Bearer $TOKEN" \
   -H "Content-Type: application/json" \
   $K8S_SERVER/api/v1/namespaces/default/pods/nginx
   ```
9. Pod가 삭제되었는지 확인

   ```
   curl -k -X GET \
   -H "Authorization: Bearer $TOKEN" \
   -H "Content-Type: application/json" \
   $K8S_SERVER/api/v1/namespaces/default/pods/nginx
   ```
10. CLI로 Pod 생성 - <https://kubernetes.io/docs/reference/kubectl/cheatsheet/#kubectl-output-verbosity-and-debugging>

    ```
    kubectl run nginx --image=nginx --v=9
    ```
11. CLI로 Pod 삭제

    ```
    kubectl delete pod nginx --v=8
    ```
12. CLI로 Pod 목록 확인

    ```
    kubectl get pod --v=9
    ```
13. 리소스 삭제

    ```
    {
        rm nginx.yaml nginx.json
        kubectl delete sa pod-access
        kubectl delete role pod-access
        kubectl delete rolebinding pod-access
    }
    ```

#### Kubernetes SDK

1. Python 가상 환경 생성&#x20;

   ```
   {
       mkdir kube-python && cd kube-python
       python3 -m venv env
       source env/bin/activate
   }
   ```
2. Kubernetes SDK for Python 설치&#x20;

   ```
   pip install kubernetes
   ```
3. Pod를 생성하는  코드 생성&#x20;

   ```
   cat <<EOF > app.py
   from kubernetes import client, config

   config.load_kube_config()

   apiClient = client.CoreV1Api()
   pod_manifest = {
       'apiVersion': 'v1',
       'kind': 'Pod',
       'metadata': {
           'name': 'nginx-from-sdk'
       },
       'spec': {
           'containers': [
               {
               'image': 'nginx',
               'name': 'nginx'
               }
           ]
       }
   }
   resp = apiClient.create_namespaced_pod(body=pod_manifest, namespace='default')
   print (resp)
   EOF
   ```
4. 코드 실행&#x20;

   ```
   python app.py
   ```
5. Pod가 생성되었는지 확인

   ```
   kubectl get pod nginx-from-sdk
   ```
6. 리소스 삭제

   ```
   {
       deactivate
       cd .. && rm -rf kube-python
       kubectl delete pod nginx-from-sdk
   }
   ```

### Deprecated API Migration

1. 현재 구축된 쿠버네티스 클러스터에 생성 가능 리소스 목록 확인&#x20;

   ```
   kubectl api-resources
   ```
2. 두개 이상의 API Resource로 생성 가능한 객체를 확인&#x20;

   ```
   kubectl api-resources --sort-by=name
   ```
3. 현재 구축된 쿠버네티스 클러스터에서 지원하는 API 버전 확인

   ```
   kubectl api-versions
   ```
4. CronJob 생성

   ```
   cat <<EOF | kubectl create -f -
   apiVersion: batch/v1beta1
   kind: CronJob
   metadata:
     name: sleepy-deprecated
   spec:
     schedule: "*/2 * * * *"
     jobTemplate:
       spec:
         template:
           spec:          
             containers:
             - name: resting
               image: busybox
               command: ["/bin/sleep"]
               args: ["5"]
             restartPolicy: Never
   EOF
   ```
5. CronJob이 생성은 되지만 아래와 같은 경고 메세지가 나옴&#x20;

   ```
   Warning: batch/v1beta1 CronJob is deprecated in v1.21+, unavailable in v1.25+; use batch/v1 CronJob
   ```
6. 위에서 생성한 CronJob를 삭제하고 해당 [문서](https://kubernetes.io/docs/reference/using-api/deprecation-guide/)를 참고해서 새로운 API 버전을 사용하는 CronJob 생성

   ```
   cat <<EOF | kubectl create -f -
   apiVersion: batch/v1
   kind: CronJob
   metadata:
     name: sleepy
   spec:
     schedule: "*/2 * * * *"
     jobTemplate:
       spec:
         template:
           spec:          
             containers:
             - name: resting
               image: busybox
               command: ["/bin/sleep"]
               args: ["5"]
             restartPolicy: Never
   EOF
   ```
7. CronJob 목록 확인

   ```
   kubectl get cronjobs \
   -o custom-columns=NAME:.metadata.name,APIVERSION:.apiVersion
   ```
8. 리소스 삭제&#x20;

   ```
   kubectl delete cronjobs sleepy sleepy-deprecated
   ```


---

# 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/kubernetes-api/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.
