k8s 클러스터에 애플리케이션 서버 실행하기
최초작성일 [2020.01.26]
쿠버네티스 클러스터에서 가동되고 있는 노드(node)를 확인한다.
마스터 노드 1개가 작동중임을 알 수 있다.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready master 7d5h v1.17.0
1. 노드에 컨테이너 생성하기
도커이미지로 만들어진 애플리케이션을 노드에 배포하는 명령어는 아래와 같다.
$ kubectl create deployment <pod이름> --image=<이미지이름>
dockerhub에 올라가있는 이미지를 이용하여 컨테이너를 노드에 생성해보자.
$ 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
이라는 환경변수에 이름을 저장해서 쓰기로 한다.
$ export POD_NAME=my-housing-prices-65db4dc56b-jxcnr
2. 생성된 pod 정보 확인하기
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("/")
def home():
html = f"<h3>Sklearn Prediction Home</h3>"
return html.format(format)
프록시 서버에 요청을 보냈을 때 배포된 flask 애플리케이션으로부터 응답이 제대로 오는지 확인해보자.
쿠버네티스 클러스터에서 namespace
는 물리적인 클러스터 위에 여러 개의 논리적인 클러스터를 식별하는 용도로 쓰인다. 현재 클러스터에서 namespace
는 default
1개만 존재한다. default
로 식별되는 가상 클러스터 안에 있는 pod들 중에 $POD_NAME
에 배포된 애플리케이션의 API에 접근하는 URL은 아래와 같다.
http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
curl로 요청을 보내면 flask 애플리케이션에 작성한 응답이 돌아오는 것을 확인할 수 있다.
$ curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
<h3>Sklearn Prediction Home</h3>%
4. 애플리케이션 로그 확인하기
컨테이너로 실행중인 애플리케이션 서버의 로그를 조회하려면 아래 명령어를 실행한다.
$ kubectl log <pod이름>
$ 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 <호스트포트번호>:<애플리케이션 서버 포트번호>
Dockerfile을 참고하면 flask 애플리케이션은 포트번호 80
에서 동작한다.
EXPOSE 80
로컬호스트에서 포트번호 8888
으로 pod에서 실행중인 flask 애플리케이션 서버에 접속하려면 아래와 같이 포트포워딩을 해주면 된다.
$ kubectl port-forward $POD_NAME 8888:80
출처
Last updated
Was this helpful?