> 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/kubernetes-api/lab.md).

# 실습

### 쿠버네티스 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
   ```
