$ kubectl create deployment my-housing-prices --image=kde6260/housing-prices:0.0.1
deployment.apps/my-housing-prices created
생성된 애플리케이션을 확인하려면 $ kubectl get deployments 를 실행한다.
➜ ~ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
my-housing-prices 0/1 1 0 4m29s
쿠버네티스에서는 컨테이너를 pod라는 단위로 관리하므로 $ kubectl get pods 를 통해 생성된 pod를 조회해보자. pod의 이름은 my-housing-prices-65db4dc56b-jxcnr 이고 STATUS 필드를 통해 아직 컨테이너를 생성하고 있음을 알 수 있다.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-housing-prices-65db4dc56b-jxcnr 0/1 ContainerCreating 0 68s
pod 이름이 너무 길기 때문에 POD_NAME 이라는 환경변수에 이름을 저장해서 쓰기로 한다.
pod에 할당된 IP주소, DNS 이름, 컨테이너 등의 자세한 정보를 확인하려면 $ kubectl describe pod <pod이름> 을 실행한다.
➜ ~ kubectl describe pod $POD_NAME
Name: my-housing-prices-65db4dc56b-jxcnr
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/192.168.64.2
Start Time: Sun, 26 Jan 2020 20:29:00 +0900
Labels: app=my-housing-prices
pod-template-hash=65db4dc56b
Annotations: <none>
Status: Running
IP: 172.17.0.4
Controlled By: ReplicaSet/my-housing-prices-65db4dc56b
Containers:
housing-prices:
Container ID: docker://8d850e074cc9c80a74a84768f2ae49ed79e10d886b56c78b0912ab67b1a9287a
Image: kde6260/housing-prices:0.0.1
Image ID: docker-pullable://kde6260/housing-prices@sha256:abb95f9a835e5e09cfa8832b9d751a24cb1d604930e1f7c6de98d1f8495a7e1b
Port: <none>
Host Port: <none>
State: Running
Started: Sun, 26 Jan 2020 20:37:44 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-l9tww (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-l9tww:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-l9tww
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 9m24s default-scheduler Successfully assigned default/my-housing-prices-65db4dc56b-jxcnr to minikube
Warning Failed 4m48s kubelet, minikube Failed to pull image "kde6260/housing-prices:0.0.1": rpc error: code = Unknown desc = context canceled
Warning Failed 4m48s kubelet, minikube Error: ErrImagePull
Normal BackOff 4m47s kubelet, minikube Back-off pulling image "kde6260/housing-prices:0.0.1"
Warning Failed 4m47s kubelet, minikube Error: ImagePullBackOff
Normal Pulling 4m35s (x2 over 9m23s) kubelet, minikube Pulling image "kde6260/housing-prices:0.0.1"
Normal Pulled 40s kubelet, minikube Successfully pulled image "kde6260/housing-prices:0.0.1"
Normal Created 40s kubelet, minikube Created container housing-prices
Normal Started 40s kubelet, minikube Started container housing-prices
생성된 pod의 IP주소는 172.17.0.4이고 Containers 항목을 통해 pod 안에 생성된 컨테이너의 상세정보를 알 수 있다. Events 항목에서는 pod의 생성 과정을 볼 수 있다.
3. 노드에 배포된 애플리케이션과 통신하기
클러스터 내 노드에 배포된 애플리케이션과 통신하기 위해서는 프록시 서버가 있어야 한다. 프록시 서버를 실행하는 명령어는 기본적으로 아래와 같다.
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
$ kubectl proxy creates a proxy server or application-level gateway between localhost and the Kubernetes API Server. It also allows serving static content over specified HTTP path. All incoming data enters through one port and gets forwarded to the remote kubernetes API Server port, except for the path matching the static content path.
마스터노드에 생성된 flask 애플리케이션은 루트 URL로 요청이 왔을 때 아래와 같이 응답을 보낸다.
@app.route("/")defhome(): html =f"<h3>Sklearn Prediction Home</h3>"return html.format(format)
프록시 서버에 요청을 보냈을 때 배포된 flask 애플리케이션으로부터 응답이 제대로 오는지 확인해보자.
쿠버네티스 클러스터에서 namespace는 물리적인 클러스터 위에 여러 개의 논리적인 클러스터를 식별하는 용도로 쓰인다. 현재 클러스터에서 namespace는 default 1개만 존재한다. default로 식별되는 가상 클러스터 안에 있는 pod들 중에 $POD_NAME에 배포된 애플리케이션의 API에 접근하는 URL은 아래와 같다.
$ kubectl log $POD_NAME
log is DEPRECATED and will be removed in a future version. Use logs instead.
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
/usr/local/lib/python3.7/site-packages/sklearn/externals/joblib/__init__.py:15: FutureWarning: sklearn.externals.joblib is deprecated in 0.21 and will be removed in 0.23. Please import this functionality directly from joblib, which can be installed with: pip install joblib. If this warning is raised when loading pickled models, you may need to re-serialize those models with scikit-learn 0.21+.
warnings.warn(msg, category=FutureWarning)
/usr/local/lib/python3.7/site-packages/sklearn/utils/deprecation.py:144: FutureWarning: The sklearn.ensemble.gradient_boosting module is deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.ensemble. Anything that cannot be imported from sklearn.ensemble is now part of the private API.
...
flask 애플리케이션의 로그가 출력되는 것을 확인할 수 있다.
5. 호스트에 pod 포워딩하기
pod에서 동작하는 애플리케이션 서버에 접속하기 위해서는 프록시 대신에 포트포워딩을 사용할 수도 있다.
$ kubectl port-forward $POD_NAME <호스트포트번호>:<애플리케이션 서버 포트번호>