# 실습

### Security Context&#x20;

1. Pod 생성&#x20;

   <pre data-full-width="true"><code>cat &#x3C;&#x3C;EOF | kubectl apply -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: nginx
   spec:
     containers:
     - image: nginx
       name: nginx
   EOF
   </code></pre>
2. 컨테이너에서 프로세스를  실행중인 유저 확인&#x20;

   <pre data-full-width="true"><code>kubectl exec nginx -- id 
   </code></pre>
3. 프로세스 유틸리티 설치&#x20;

   ```
   kubectl exec nginx -- bash -c "apt update && apt install -y procps"
   ```
4. 실행중인 프로세스 확인&#x20;

   ```
   kubectl exec nginx -- ps aux
   ```
5. *nginx* 유저 확인&#x20;

   ```
   kubectl exec nginx -- id nginx
   ```
6. Pod 재생성&#x20;

   ```
   cat <<EOF | kubectl replace --force -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: nginx
   spec:
     securityContext:
       runAsNonRoot: true
     containers:
     - image: nginx
       name: nginx
   EOF
   ```
7. Pod가 생성되었는지 확인

   ```
   kubectl get pod nginx
   ```
8. Pod에 명시된 컨테이너가 실행 되지 않는다면 그 이유를 확인

   ```
   kubectl describe pod nginx
   ```
9. Pod 재생성&#x20;

   ```
   cat <<EOF | kubectl replace --force -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: nginx
   spec:
     securityContext:
       runAsNonRoot: true
       runAsUser: 101
     containers:
     - image: nginx
       name: nginx
   EOF
   ```
10. Pod가 생성되었는지 확인

    ```
    kubectl get pod nginx
    ```
11. Pod에 명시된 컨테이너가 실행 되지 않는다면 그 이유를 확인

    ```
    kubectl describe pod nginx
    ```
12. Pod 로그 확인&#x20;

    ```
    kubectl logs nginx
    ```
13. NGINX 설정 파일 확인

    ```
    kubectl run nginx-tmp --image=nginx --rm -it --restart=Never \
    -- cat /etc/nginx/nginx.conf
    ```
14. Pod 재생성&#x20;

    ```
    cat <<EOF | kubectl replace --force -f -
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx
    data:
      nginx.conf: |
        
        worker_processes  auto;
        
        error_log  /var/log/nginx/error.log notice;
        pid        /var/run/nginx.pid;
        
        
        events {
            worker_connections  1024;
        }
        
        
        http {
            include       /etc/nginx/mime.types;
            default_type  application/octet-stream;
        
            log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                              '$status $body_bytes_sent "$http_referer" '
                              '"$http_user_agent" "$http_x_forwarded_for"';
        
            access_log  /var/log/nginx/access.log  main;
        
            sendfile        on;
            #tcp_nopush     on;
        
            keepalive_timeout  65;
        
            #gzip  on;
        
            include /etc/nginx/conf.d/*.conf;
        }
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 101
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-conf
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
      volumes:
      - name: nginx-conf
        configMap:
          name: nginx
          items:
          - key: nginx.conf
            path: nginx.conf
    EOF
    ```
15. Pod가 생성되었는지 확인

    ```
    kubectl get pod nginx
    ```
16. Pod에 명시된 컨테이너가 실행 되지 않는다면 그 이유를 확인

    ```
    kubectl describe pod nginx
    ```
17. Pod 로그 확인&#x20;

    ```
    kubectl logs nginx
    ```
18. 아래의 Dockerfile로 새로운 컨테이너 이미지 생성&#x20;

    ```
    FROM nginx
    WORKDIR /app
    RUN chown -R nginx:nginx /app && chmod -R 755 /app && \
            chown -R nginx:nginx /var/cache/nginx && \
            chown -R nginx:nginx /var/log/nginx && \
            chown -R nginx:nginx /etc/nginx/conf.d
    RUN touch /var/run/nginx.pid && \
            chown -R nginx:nginx /var/run/nginx.pid
    USER nginx
    CMD ["nginx", "-g", "daemon off;"]
    ```
19. Pod 재생성&#x20;

    ```
    cat <<EOF | kubectl replace --force -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 101
      containers:
      - image: youngwjung/nginx-nonroot
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-conf
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
      volumes:
      - name: nginx-conf
        configMap:
          name: nginx
          items:
          - key: nginx.conf
            path: nginx.conf
    EOF
    ```
20. Pod 상태 확인

    ```
    kubectl get pod nginx
    ```
21. Pod 로그 확인&#x20;

    ```
    kubectl logs nginx
    ```
22. Pod 재생성&#x20;

    <pre data-full-width="true"><code>cat &#x3C;&#x3C;EOF | kubectl replace --force -f -
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx
    data:
      nginx.conf: |
        
        worker_processes  auto;
        
        error_log  /var/log/nginx/error.log notice;
        pid        /var/run/nginx.pid;
        
        
        events {
            worker_connections  1024;
        }
        
        
        http {
            include       /etc/nginx/mime.types;
            default_type  application/octet-stream;
        
            log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                              '$status $body_bytes_sent "$http_referer" '
                              '"$http_user_agent" "$http_x_forwarded_for"';
        
            access_log  /var/log/nginx/access.log  main;
        
            sendfile        on;
            #tcp_nopush     on;
        
            keepalive_timeout  65;
        
            #gzip  on;
            
            server {
                listen       8080;
                server_name  localhost;
                location / {
                    root   /usr/share/nginx/html;
                    index  index.html index.htm;
                }
            }
        }
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 101
      containers:
      - image: youngwjung/nginx-nonroot
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-conf
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
      volumes:
      - name: nginx-conf
        configMap:
          name: nginx
          items:
          - key: nginx.conf
            path: nginx.conf
    EOF
    </code></pre>
23. Pod 상태 확인&#x20;

    ```
    kubectl get pod nginx
    ```
24. 컨테이너가 정상적으로 실행중인지 확인

    ```
    kubectl exec nginx -- curl -s localhost:8080
    ```
25. 새로운 Pod 생성&#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: ubuntu
    spec:
      securityContext:dddd
        runAsNonRoot: true
        runAsUser: 101
      containers:
      - image: ubuntu
        name: ubuntu
        command: ["sleep", "3600"]
    EOF
    ```
26. 컨테이너에서 프로세스를  실행중인 유저 확인&#x20;

    ```
    kubectl exec ubuntu -- id 
    ```
27. 실행중인 프로세스 확인&#x20;

    ```
    kubectl exec ubuntu -- ps aux
    ```
28. NGINX 설치 시도&#x20;

    ```
    kubectl exec ubuntu -- bash -c "apt update && apt install -y nginx"
    ```
29. Pod 재생성

    ```
    cat <<EOF | kubectl replace --force -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: ubuntu
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 101
      containers:
      - image: ubuntu
        name: ubuntu
        command: ["sleep", "3600"]
        securityContext:
          runAsUser: 0
    EOF
    ```
30. Pod가 정상적으로 생성되었는지 확인&#x20;

    ```
    kubectl get pod ubuntu
    ```
31. Pod에 명시된 컨테이너가 실행되지 않는다면 그 이유를 확인

    ```
    kubectl describe pod ubuntu
    ```
32. Pod 재생성

    ```
    cat <<EOF | kubectl replace --force -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: ubuntu
    spec:
      securityContext:
        runAsUser: 101
      containers:
      - image: ubuntu
        name: ubuntu
        command: ["sleep", "3600"]
        securityContext:
          runAsUser: 0
    EOF
    ```
33. 컨테이너에서 프로세스를  실행중인 유저 확인&#x20;

    ```
    kubectl exec ubuntu -- id 
    ```
34. 새로운 Pod 생성&#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: alpine
    spec:
      containers:
      - image: alpine
        name: alpine
        command: ["sleep", "3600"]
        volumeMounts:
        - name: dev
          mountPath: /mnt/dev
      volumes:
      - name: dev
        hostPath:
          path: /dev
    EOF
    ```
35. 생성된 컨테이너를 통해 호스트의 디스크 디바이스 접근 시도&#x20;

    ```
    kubectl exec alpine -- head /mnt/dev/xvda
    ```
36. 컨테이너에서 프로세스를  실행중인 유저 확인&#x20;

    ```
    kubectl exec ubuntu -- id 
    ```
37. Pod 재생성&#x20;

    ```
    cat <<EOF | kubectl replace --force -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: alpine
    spec:
      containers:
      - image: alpine
        name: alpine
        command: ["sleep", "3600"]
        volumeMounts:
        - name: dev
          mountPath: /mnt/dev
        securityContext:
          privileged: true
      volumes:
      - name: dev
        hostPath:
          path: /dev
    EOF
    ```
38. 생성된 컨테이너를 통해 호스트의 디스크 디바이스 접근 시도&#x20;

    ```
    kubectl exec alpine -- head /mnt/dev/xvda
    ```
39. 리소스 삭제&#x20;

    ```
    {
        kubectl delete pod ubuntu alpine nginx
        kubectl delete cm nginx
    }
    ```

### Seccomp

1. Pod 생성&#x20;

   <pre data-full-width="true"><code>cat &#x3C;&#x3C;EOF | kubectl apply -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: ubuntu
   spec:
     containers:
     - image: ubuntu
       name: ubuntu
       command: ["sleep", "3600"]
   EOF
   </code></pre>
2. 새로운 리눅스 네임스페이스를 만드는 명령어 실행

   ```
   kubectl exec -it ubuntu -- unshare
   ```
3.
4. Pod 생성&#x20;

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: v1
   kind: Pod
   metadata:
     name: ubuntu
   spec:
     securityContext:
       seccompProfile:
         type: RuntimeDefault
     containers:
     - image: ubuntu
       name: ubuntu
       command: ["sleep", "3600"]
   EOF
   ```

### Network Policy

1. Tigera Calico Operator 설치&#x20;

   ```
   {
       helm repo add projectcalico https://docs.projectcalico.org/charts
       helm repo update
       helm install calico projectcalico/tigera-operator --version v3.21.4
   }
   ```
2. Calico Operator 설치 확인&#x20;

   ```
   kubectl get all -n tigera-operator
   ```
3. Calico CNI 설치 확인

   ```
   kubectl get all -n calico-system
   ```
4. 모든 Calico 구성 요소들이 정상 동작중인지 확인 - *에러메시지가 없으면 정상으로 판단*

   ```
   {
       kubectl logs deploy/tigera-operator -n tigera-operator | grep ERROR
       kubectl logs ds/calico-node -n calico-system | grep ERROR
       kubectl logs deploy/calico-typha -n calico-system | grep ERROR
   }
   ```
5. 리소스 생성&#x20;

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: v1
   kind: Namespace
   metadata:
     name: red
     labels:
       env: red
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     name: client
     namespace: red
     labels:
       role: client
   spec:
     containers:
     - image: curlimages/curl
       name: client
       command: ["sleep", "3600"]
   ---
   apiVersion: v1
   kind: Namespace
   metadata:
     name: blue
     labels:
       env: blue
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     name: client
     namespace: blue
     labels:
       role: client
   spec:
     containers:
     - image: curlimages/curl
       name: client
       command: ["sleep", "3600"]
   ---
   apiVersion: v1
   kind: Namespace
   metadata:
     name: web
     labels:
       env: web
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     name: server
     namespace: web
     labels:
       role: server
   spec:
     containers:
     - image: httpd
       name: httpd
   ---
   apiVersion: v1
   kind: Pod
   metadata:
     name: client
     namespace: web
     labels:
       role: client
   spec:
     containers:
     - image: curlimages/curl
       name: client
       command: ["sleep", "3600"]
   EOF
   ```
6. *web* Namespace에 있는 *server* Pod의 IP 주소 확인&#x20;

   ```
   kubectl get pod server -o wide -n web
   ```
7. *red* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출&#x20;

   ```
   kubectl -n red exec client -- \
   curl -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
   ```
8. *red* 및 *blue* Namespace에 Network Policy 생성&#x20;

   ```
   cat <<EOF | kubectl apply -f -
   apiVersion: networking.k8s.io/v1
   kind: NetworkPolicy
   metadata:
     name: default-deny-egress
     namespace: red
   spec:
     podSelector: {}
     policyTypes:
     - Egress
   ---
   apiVersion: networking.k8s.io/v1
   kind: NetworkPolicy
   metadata:
     name: default-deny-egress
     namespace: blue
   spec:
     podSelector: {}
     policyTypes:
     - Egress
   EOF
   ```
9. *red* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

   ```
   kubectl -n red exec client -- \
   curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
   ```
10. *red* Namespace에 새로운 Network Policy 생성&#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-egress-server
      namespace: red
    spec:
      podSelector:
        matchLabels:
          role: client
      policyTypes:
      - Egress
      egress:
      - to:
        - ipBlock:
            cidr: $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')/32
        ports:
        - protocol: TCP
          port: 80
    EOF
    ```
11. 위에서 생성한 Network Policy 확인&#x20;

    ```
    kubectl -n red describe networkpolicy allow-egress-server
    ```
12. *red* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

    ```
    kubectl -n red exec client -- \
    curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
    ```
13. *blue* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

    ```
    kubectl -n blue exec client -- \
    curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
    ```
14. *blue* Namespace에 새로운 Network Policy 생성&#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-egress-server
      namespace: blue
    spec:
      podSelector:
        matchLabels:
          role: client
      policyTypes:
      - Egress
      egress:
      - to:
        - podSelector:
            matchLabels:
              role: server
        ports:
        - protocol: TCP
          port: 80
    EOF
    ```
15. 위에서 생성한 Network Policy 확인&#x20;

    ```
    kubectl -n blue describe networkpolicy allow-egress-server
    ```
16. *blue* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

    ```
    kubectl -n blue exec client -- \
    curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
    ```
17. 위에서 생성한 Network Policy 수정&#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-egress-server
      namespace: blue
    spec:
      podSelector:
        matchLabels:
          role: client
      policyTypes:
      - Egress
      egress:
      - to:
        - namespaceSelector:
            matchLabels:
              env: web
        ports:
        - protocol: TCP
          port: 80
    EOF
    ```
18. 위에서 수정한 Network Policy 확인&#x20;

    ```
    kubectl -n blue describe networkpolicy allow-egress-server
    ```
19. *blue* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

    ```
    kubectl -n blue exec client -- \
    curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
    ```
20. *web* Namespace에 Network Policy 생성&#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: default-deny-all
      namespace: web
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
      - Egress
    EOF
    ```
21. *blue* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

    ```
    kubectl -n blue exec client -- \
    curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
    ```
22. *web* Namespace에 새로운 Network Policy 생성 - *Egress 정책*

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-all-egress
      namespace: web
    spec:
      podSelector: {}
      policyTypes:
      - Egress
      egress:
      - {}
    EOF
    ```
23. *web* Namespace에 새로운 Network Policy 생성 - *Ingress 정책*&#x20;

    ```
    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-ingress-blue-client
      namespace: web
    spec:
      podSelector:
        matchLabels:
          role: server
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              env: blue
          podSelector:
            matchLabels:
              role: client
    EOF
    ```
24. *blue* Namespace에 있는 *client* Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

    ```
    kubectl -n blue exec client -- \
    curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
    ```
25. *blue* Namespace에 새로운 Pod를 생성&#x20;

    ```
    kubectl -n blue run nginx --image=nginx
    ```
26. 위에서 생성한 Pod에서 *web* Namespace에 있는 *server* Pod 호출 - *timeout을 1초로 설정*&#x20;

    ```
    kubectl -n blue exec nginx -- \
    curl -m 1 -s $(kubectl get pod server -n web -o=jsonpath='{.status.podIP}')
    ```
27. 리소스 삭제

    ```
    kubectl delete ns red blue web
    ```
28. Calico 삭제&#x20;

    ```
    helm uninstall calico
    ```
29. Calico가 삭제되었는지 확인

    ```
    kubectl get ns tigera-operator calico-system
    ```
30. 한개의 Node로 Session Manager 연결

    ```
    aws ssm start-session --target \
    $(kubectl get node -o jsonpath='{.items[0].spec.providerID}{"\n"}' | grep -oE "i-[a-z0-9]+")
    ```
31. Calico CNI가 생성한 iptable 규칙들이 남아 있는지 확인

    ```
    sudo iptables-save | grep -i cali
    ```
32. Session Manager 종료&#x20;

    ```
    exit
    ```
33. 모든 Node 삭제 - *관리형 노드그룹에 의해서 새로운 Node가 자동으로 생성됨*

    ```
    aws ec2 terminate-instances --instance-ids \
    $(kubectl get node -o jsonpath='{.items[*].spec.providerID}' | grep -oE "i-[a-z0-9]+" | column)
    ```
34. Node를 새로 생성할수 없는 경우에는 해당 문서를 참고 - <https://github.com/projectcalico/calico/blob/master/calico/hack/remove-calico-policy/remove-policy.md>
35. 새로운 Node가 생성되었는지 확인&#x20;

    ```
    kubectl get node
    ```
36. 한개의 Node로 Session Manager 연결

    ```
    aws ssm start-session --target \
    $(kubectl get node -o jsonpath='{.items[0].spec.providerID}{"\n"}' | grep -oE "i-[a-z0-9]+")
    ```
37. Calico CNI가 생성한 iptable 규칙들이 남아 있는지 확인

    ```
    sudo iptables-save | grep -i cali
    ```
38. Session Manager 종료&#x20;

    ```
    exit
    ```


---

# 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/advanced-topics/security/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.
