[![logo](https://www.hongsnet.net/images/logo.gif)](https://www.hongsnet.net)

# `minicube`로 POD 배포 검증

`파드(Pod)`는 쿠버네티스에서 생성하고 관리할 수 있는 **배포 가능한 가장 작은 컴퓨팅 단위** 이다.

> 실제 Application이 수행되는 단위라고 이해하면 된다.

**파드(pod)**는 하나 이상의 컨테이너의 그룹이다. 이 그룹은 **스토리지 및 네트워크를 공유**하고, 해당 컨테이너를 구동하는 방식에 대한 명세를 갖는다. 파드의 콘텐츠는 항상 함께 배치되고, 함께 스케줄되며, 공유 콘텍스트에서 실행된다. 파드는 애플리케이션 별 "논리 호스트"를 모델링한다. 여기에는 상대적으로 밀접하게 결합된 하나 이상의 애플리케이션 컨테이너가 포함된다. 

클라우드가 아닌 콘텍스트에서, 동일한 물리 또는 가상 머신에서 실행되는 애플리케이션은 동일한 논리 호스트에서 실행되는 클라우드 애플리케이션과 비슷하다.

애플리케이션 컨테이너와 마찬가지로, 파드에는 파드 시작 중에 실행되는 초기화 컨테이너가 포함될 수 있다. 클러스터가 제공하는 경우, 디버깅을 위해 임시 컨테이너를 삽입할 수도 있다.


# POD 생성

현재 다음과 같이 아무런 POD도 존재하지 않는다.

```bash
# kubectl get pods
No resources found in default namespace.
```

여기서의 예시는 간단한 nginx 컨테이너를 생성하고 배포할 것이다.

```bash
# kubectl run test-nginx --image=nginx --replicas=2 --port=80
Flag --replicas has been deprecated, has no effect and will be removed in the future.
pod/test-nginx created
```

> `!중요` : --replicas 옵션은 더 이상 사용되지않는 옵션이다. **K8S v1.18.0 이후**에는 아래와 같이 **yaml 파일**을 이용하여, POD를 생성하는 것이 권장된다.

```bash
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  # Create 2 nginx containers
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
```

생성은 kubectl 명령에 **apply 인자**를 주면 된다.

```bash
# kubectl apply -f nginx-deploy.yaml
deployment.apps/nginx-deployment created
```

그럼, 다음과 같이 nginx 컨테이너가 배포되는 것을 확인할 수 있다.

```bash
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-8wndj 1/1 Running 0 29s
nginx-deployment-66b6c48dd5-pjnxz 1/1 Running 0 29s
```

또한 배포한 대한 정보를 확인하려면, 다음과 같이 **deployment 인자**를 주면 된다.

```bash
# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 49s
```


# POD 환경정보 및 접속

아래와 같이 **docker 명령과 유사**한 것을 알 수 있다.

```bash
# kubectl exec nginx-deployment-66b6c48dd5-8wndj -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-deployment-66b6c48dd5-8wndj
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
NGINX_VERSION=1.14.2-1~stretch
NJS_VERSION=1.14.2.0.2.6-1~stretch
HOME=/root
```

컨테이너의 접속도 **docker 명령과 유사**한 것을 알 수 있다.

```bash
# kubectl exec -it nginx-deployment-66b6c48dd5-8wndj -- bash
root@nginx-deployment-66b6c48dd5-8wndj:/# hostname
nginx-deployment-66b6c48dd5-8wndj
```

# POD 배포

최초 시작은 2개로 시작되었다(replicas = 2). 현재 이 구성에 **하나 더 추가**하여, 다음과 같이 배포해보자.

```bash
# kubectl scale deployment nginx-deployment --replicas=3
deployment.apps/nginx-deployment scaled
```

그럼, POD가 하나 더 생성된 것을 확인할 수 있다.

```bash
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-8wndj 1/1 Running 0 6m18s
nginx-deployment-66b6c48dd5-pjnxz 1/1 Running 0 6m18s
nginx-deployment-66b6c48dd5-qpkmm 1/1 Running 0 13s
```


# POD 확장

현재까지 진행된 상태에서는 최초 컨테이너 이미지의 내역에 대한 구성만 존재한다.

```bash
# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26m
```

여기에 추가적으로 80번 포트를 expose(외부노출) 해본다.

```bash
# kubectl expose deployment nginx-deployment --type="NodePort" --port 80
service/nginx-deployment exposed
```

그럼, 다음과 같이 **nginx-deployment**라는 이름의 포트가 외부에 **노출(expose)**되는 것을 확인할 수 있다.

```bash
# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26m
nginx-deployment NodePort 10.105.61.102 <none> 80:31846/TCP 23s
```

추가적으로 서비스를 시스템에서 접근해보자.

```bash
# minikube service nginx-deployment --url
http://192.168.39.24:31846
```

위와 같이 80번이 아니라.. 내부 포트(tcp/31846)가 연결된 것을 확인할 수 있다. 이제 이 정보를 호스트에서 다음과 같이 접근해보자.

```bash
# curl http://192.168.39.24:31846
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

위와 같이 nginx의 default index.html 파일이 호출되는 것을 확인할 수 있다.


# POD의 제거

현재 POD의 상태는 다음과 같다.

```bash
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-8wndj 1/1 Running 0 9m14s
nginx-deployment-66b6c48dd5-pjnxz 1/1 Running 0 9m14s
nginx-deployment-66b6c48dd5-qpkmm 1/1 Running 0 3m9s
```

먼저 서비스부터 **제거**해보자.

```bash
# kubectl delete services nginx-deployment
service "nginx-deployment" deleted
```

그럼 위에서 **외부로 노출(expose)한 80번 포트와 nginx-deployment라는 서비스가 제거된 것을 확인할 수 있다.**

```bash
# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27m
```

최종적으로 다음과 같이 **POD를 삭제**해보자.

```bash
# kubectl delete deployment nginx-deployment
deployment.apps "nginx-deployment" deleted
```

확인해보면, 다음과 같이 **POD가 제거**된 것을 확인할 수 있다.

```bash
# kubectl get pods
No resources found in default namespace.
```

만약 아래와 같이 POD를 제거했는데도, 정보가 남아있다면, 이는 업데이트 주기에 대한 영향으로 보이기 때문에 어느 정도의 시간이 지나면 위와 같이 아무런 리스트도 출력되지 않을 것이다.

```bash
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-66b6c48dd5-8wndj 0/1 Terminating 0 10m
```

