최근 AWS에서도 ML 최적화 환경(EKS cluster, sagemaker, ...)을 제공해주고 있다. 때문에 여러 ML 관련 tool들을 핸들링하기가 쉬워졌다.
그래서인지 Kubeflow 관련 세팅을 찾아보면, 대다수가 Public Cloud에 의존적으로 아키텍쳐가 모델링이 되어있다.
적용해보는 것도 나쁘지 않지만, low하게 구축해보는 것도 경험이라 생각해서, ubuntu image 위에서 활용할 수 있도록 진행해볼 예정이다.
진행 스펙
- AWS Instance Type : g4dn.xlarge
- OS Image : Ubuntu Server 20.04 LTS (HVM), SSD Volume Type
- Storage : 150GB, EBS, 범용 SSD(gp2)
1. cuDNN 설치
AWS 스펙 상 NVIDIA GPU(g4dn)을 사용하기 때문에, GPU 가속화를 위해 cuDNN을 설치한 후 nvidia Docker(2)를 이용해서 GPU 가속을 할 것이다.
Working Directory는 Home DIirectory에서 진행한다.
먼저 다음 Shell script를 실행한다.
#!/bin/bash
sudo apt-get -y update
sudo apt-get -y remove --purge '^nvidia-.*'
sudo apt-get -y remove --purge 'cuda-.*'
sudo apt-get -y install nvidia-cuda-tookit
sudo apt-get -y install nvidia-cuda-toolkit
nvcc -V
whereis cuda
mkdir ~/nvidia
cd ~/nvidia
CUDNN_TAR_FILE="cudnn-10.1-linux-x64-v7.6.5.32.tgz"
wget https://developer.download.nvidia.com/compute/redist/cudnn/v7.6.5/${CUDNN_TAR_FILE}
tar -xzvf ${CUDNN_TAR_FILE}
sudo cp cuda/include/cudnn.h /usr/lib/cuda/include/
sudo cp cuda/lib64/libcudnn* /usr/lib/cuda/lib64/
sudo chmod a+r /usr/lib/cuda/lib64/libcudnn*
sudo chmod a+r /usr/lib/cuda/include/cudnn.h
echo "export LD_LIBRARY_PATH=/usr/lib/cuda/lib64:$LD_LIBRARY_PATH" >> ~/.bashrc
export "LD_LIBRARY_PATH=/usr/lib/cuda/include:$LD_LIBRARY_PATH" >> ~/.bashrc
source ~/.bashrc
ubuntu-drivers devices
sudo apt install -y nvidia-driver-470
echo "reboot....."
Docker 설치
위 설치가 완료되면 다음 Shell script를 실행한다.
#!/bin/bash
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update -y
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
sudo docker run hello-world
sudo usermod -aG docker $USER && newgrp docker
sudo service docker restart
Docker 설치가 끝나면, 재부팅을 해준다.
$ sudo reboot
2. Nvidia Docker 설치
reboot를 완료했다면, 다음 shell script를 활용해서 nvidia docker를 설치해준다.
#!/bin/bash
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get -y update
sudo apt-get -y install nvidia-docker2
sudo systemctl restart docker
sudo docker run --runtime nvidia nvidia/cuda:11.4.3-base-ubuntu20.04 /usr/bin/nvidia-smi
sudo bash -c 'cat <<EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"data-root": "/mnt/storage/docker_data",
"storage-driver": "overlay2",
"default-runtime" : "nvidia",
"runtimes" : {
"nvidia" : {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs" : []
}
}
}
EOF'
sudo systemctl restart docker
nvidia-smi 명령어를 실행하게끔 해놨기 때문에, 해당 창이 떠야 한다.
추가로 docker hub의 tag가 업데이트가 계속 이어지기 때문에, 이미지를 잘 확인해야 한다
3. k8s 설치 및 초기화
nvidia-smi를 통해 지표가 동작함을 확인했다면, 다음 shell script를 실행시킨다.
#!/bin/bash
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
sudo apt-get install -y iptables arptables ebtables
sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet=1.21.10-00 kubeadm=1.21.10-00 kubectl=1.21.10-00 --allow-downgrades --allow-change-held-packages
sudo apt-mark hold kubelet kubeadm kubectl
kubeadm version
kubelet --version
kubectl version --client
설치가 완료되었다면, 다음 shell script를 실행한다.
#!/bin/bash
# init k8s
sudo kubeadm init --pod-network-cidr=10.217.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl cluster-info
# CNI
kubectl create -f https://raw.githubusercontent.com/cilium/cilium/v1.6/install/kubernetes/quick-install.yaml
kubectl get pods -n kube-system --selector=k8s-app=cilium
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/1.0.0-beta6/nvidia-device-plugin.yml
#test GPU
kubectl -n kube-system get pod -l name=nvidia-device-plugin-ds
kubectl -n kube-system logs -l name=nvidia-device-plugin-ds
# default storageclass
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
kubectl get storageclass
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
kubectl get sc
# install kusomize
#
if [ ! -f /usr/local/bin/kusomize ]
then
echo "kustomize"
wget https://github.com/kubernetes-sigs/kustomize/releases/download/v3.2.0/kustomize_3.2.0_linux_amd64
mv ./kustomize_3.2.0_linux_amd64 kustomize
sudo chmod 777 kustomize
sudo mv kustomize /usr/local/bin/kustomize
fi
# autocomplete k8s
shellname=`echo $SHELL | rev | cut -d '/' -f1 | rev`
shellconf=`echo ~/.\${shellname}rc`
grep -n "kubectl completion" $shellconf
if [ $? = 1 ]
then
echo 'install autocomplete k8s'
sudo apt-get install bash-completion -y
echo 'source <(kubectl completion '$shellname')' >>$shellconf
echo 'alias k=kubectl' >>$shellconf
echo 'complete -F __start_kubectl k' >>$shellconf
fi
$SHELL
CNI는 cilium 1.6 이상은 제대로 동작하지 않기 때문에 사용하지 않는 것을 추천 (안 되면 cilium말고 calico로 설치하면 잘 된다)
kustomize는 3.2.0 이상 버전은 지원이 안되기 때문에, 이상의 버전 사용을 권장하지 않는다.
4. kubeflow 설치
kubeflow 설치를 위해 kubeflow github에 들어가서 manifests를 다운받아야 한다.
Home Directory에 clone을 받도록 하자
GitHub - kubeflow/manifests: A repository for Kustomize manifests
A repository for Kustomize manifests. Contribute to kubeflow/manifests development by creating an account on GitHub.
github.com
$ cd ~
$ git clone https://github.com/kubeflow/manifests.git
$ cd manifests
$ git checkout v1.5.1 # kubeflow 1.5.1 설치를 위해
일단 이전에 github에 써 있는 내용 중, cert-manager를 먼저 설치하고, 나머지는 single command로 설치할 것이다.
$ kustomize build common/cert-manager/cert-manager/base | kubectl apply -f -
# 확인
$ watch -n1 kubectl get pod -A
pod을 보았을 때, 모두 Running 상태면 다음 단계를 진행하면 된다.
$ kustomize build common/cert-manager/kubeflow-issuer/base | kubectl apply -f -
# 위 작업이 완료가 되면, 아래 싱글 커맨드를 진행
$ while ! kustomize build example | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done
# 다시 확인
$ watch -n1 kubectl get pod -A
이후 전체 pod가 running 상태가 될 때까지 대기한다.
5. Kubeflow 접속
이제 Kubeflow 설치가 완료가 되었고, Kubeflow에 접근하기 위해 port forwarding을 진행해주어야 한다.
# istio-system이 있는 지 확인
$ kubectl get namespaces
# istio-ingressgatewy PORT 확인
$ kubectl get svc -n istio-system
# 원하는 포트(8080)로 port-forwarding 진행
$ kubectl port-forward --address=0.0.0.0 svc/istio-ingressgateway -n istio-system 8080:80
그럼 지금 상태로는. http에 본인 public ip 주소와 8080포트로 kubeflow에 접근이 가능하다.
처음 이메일 및 패스워드는 다음과 같다.
- Email Address : user@example.com
- Password : 12341234
- Namespace : kubeflow-user-example-com
6. Kubeflow 환경 설정
테스트하기 위해 notebook을 새로 만들어보자
해당 페이지에서, 노트북 이름과 이미지 설정만 한 다음, Launch 버튼을 누르면 다음과 같은 CSRF 오류가 난다.
해결 방법은 2가지가 있다.
a. APP_SECURE_COOKIES를 false로 변경
기본적으로 웹 애플리케이션 같은 경우는 APP_SECURE_COOKIES를 사용하고 있다.
이 값을 false로 하면 접근을 할 수는 있지만 CSRF 공격을 막을 수는 없다. 그래서 권장하진 않는다.
하는 방법은 다음과 같다.
$ kubectl get deployments.apps -n kubeflow | grep web
이 부분에서 app deployment 확인 후 설정을 바꿔주면 된다.
$ kubectl edit deployments.apps -n kubeflow jupyter-web-app-deployment
b. HTTPS로 접속할 수 있도록 변경
해당 방법을 권장하며, 다음 페이지를 참고해서 진행하면 된다.
Securing the Kubeflow authentication with HTTPS
How to secure the Kubeflow authentication with HTTPS using the network load balancer
ibm.github.io
요약하면, 두 yaml 파일을 작성해서 배포하면 된다.
$ kubectl apply -f gateway.yaml
$ kubectl apply -f certificate.yaml
이렇게 두 파일을 적용을 해주면 https로 접근할 수가 있다.
# gateway가 443이 https로 되어있으므로, 443으로 port forwarding 진행
$ kubectl port-forward --address=0.0.0.0 svc/istio-ingressgateway -n istio-system 8080:443
이후에 아까와 같이 접속을 진행한다.
이제 노트북을 생성하면, CSRF 오류가 뜨지 않는다.
아, 그리고
본인은 requested CPUs를 0.1로 설정했는데, 자원 설정에 따라 status가 loading 상태에 머무를 수 있으니 잘 확인하자
7. Kubeflow 1.6.0 설치
kubeflow 1.6.0을 설치하기 위해서는 kubeflow 초기화를 해주어야 한다.
$ sudo kubeadm reset
$ rm $HOME/.kube/config
이후 3번 과정에 있는 k8s initiation을 다시 진행한다.
그리고 후속 과정 중, v1.6.0 tag로 checkout 후 같은 과정을 진행하면 된다.
명령어만 간단하게 정리해보겠다.
# 1.6.0 tag로 이동
$ git checkout v1.6.0
# cert-manager 설치
$ kustomize build common/cert-manager/cert-manager/base | kubectl apply -f -
# pod이 모두 running 상태인 지 확인 후 진행
$ kubectl get pod -A
$ kustomize build common/cert-manager/kubeflow-issuer/base | kubectl apply -f -
# 이후 single command로 install
$ while ! kustomize build example | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done
# 이후 pod이 모두 running 상태인 지 확인
$ kubectl get pod -A
# 작성한 yaml 파일이 있는 디렉토리로 돌아가서 내용 배포
$ kubectl apply -f gateway.yaml
$ kubectl apply -f certificate.yaml
# 이후 kubeflow 접속
$ kubectl port-forward --address=0.0.0.0 svc/istio-ingressgateway -n istio-system 8080:443
'IT_Study > Ops' 카테고리의 다른 글
[MLOps] Kubeflow Notebook 핸들링 방법, custom notebook 생성 (1) | 2023.11.02 |
---|---|
[MLOps] Kubeflow 계정 관리, PV와 PVC 개념 (0) | 2023.11.01 |
[MLOps] Docker 개념 및 흐름 간단 정리 (1) | 2023.10.31 |
[MLOps] 코드 품질 관리(Quality Control) 관련 개념 (0) | 2023.10.30 |
[MLOps] Kubeflow 개요 : 아키텍쳐 및 파이프라인 이해 (1) | 2023.10.27 |