Minikube (k8s 1.28.2) + Kubeflow 1.8 설치하기

2024. 7. 9. 01:29개발 일지/인공지능

[1단계] Minikube 로 K8S 세팅하기

이번 글에서는 Minikube로 Kubernetes 버전 1.28.2버전을 설치하고, 현재 기준 최신 버전인 kubeflow 1.8을 설치할 거에요

먼저 k3s, kubespray, kubeadm등 다양한 방식으로 설치해볼 수 있지만,

Kubeflow를 설치하고 파이프라인을 작성해보는 것이 목적이라면 Minikube로도 충분합니다.

 

sudo minikube start --driver=none \\
  --kubernetes-version=v1.28.2 \\
  --extra-config=apiserver.service-account-signing-key-file=/var/lib/minikube/certs/sa.key \\
  --extra-config=apiserver.service-account-issuer=kubernetes.default.svc

 

--driver=none가상 드라이버를 설정하지 않겠다는 의미입니다.

이렇게 하면 docker driver 를 사용하여 실행하며, 손쉽게 kubeflow에서 GPU를 사용할 수 있게 됩니다.

이외의 방법으로는 kvm2 드라이버가 있습니다. 

https://minikube.sigs.k8s.io/docs/drivers/kvm2/

 

kvm2

Linux KVM (Kernel-based Virtual Machine) driver

minikube.sigs.k8s.io

 

먼저 아래 두 옵션은 kubeflow 공식 문서에 minikube 로 사용시 signing-key-file 과 issuer 경로를 적용해달라고 적혀있어 적게 되었습니다. 

https://v1-2-branch.kubeflow.org/docs/started/workstation/minikube-linux/

  --extra-config=apiserver.service-account-signing-key-file=/var/lib/minikube/certs/sa.key \\
  --extra-config=apiserver.service-account-issuer=kubernetes.default.svc

Kube let&ctl&adm

kubelet, kubectl, kubeadm 을 apt로 설치하고 버전을 업데이트 하지 않도록 hold 합니다.

sudo apt-get install -qy kubelet=1.28.2-00 kubectl=1.28.2-00 kubeadm=1.28.2-00
sudo apt-mark hold kubelet kubeadm kubectl

# hold 풀기
sudo apt-mark unhold kubelet kubeadm kubectl

 

 

CNI 설치 (Container Network Interface)

네트워크 인터페이스는 말 그대로 쿠버네티스에서의 Pod (container)들의 network interface 역할을 수행해요.

컨테이너 런타임과 오케스트레이터 사이의 네트워크 계층을 각자 다르게 작성하는것을 방지하기 위해 공통된 인터페이스를 제공하고 있습니다. (https://github.com/containernetworking/cni)

 

GitHub - containernetworking/cni: Container Network Interface - networking for Linux containers

Container Network Interface - networking for Linux containers - GitHub - containernetworking/cni: Container Network Interface - networking for Linux containers

github.com

 

# 설치하기

# 오류가 많았음 flannel 
# kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

calico 비교적 오류가 덜했음
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

설치시 아래처럼 떠야함

(mytorch) eduenv@master:~/mlops/kubeflow/manifests$ kubectl get pods -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-7ddc4f45bc-djrlt   1/1     Running   0          55s
kube-system   calico-node-qj5dl                          1/1     Running   0          55s
kube-system   coredns-5dd5756b68-ksbjn                   1/1     Running   0          3m47s
kube-system   etcd-master                                1/1     Running   0          3m59s
kube-system   kube-apiserver-master                      1/1     Running   0          4m1s
kube-system   kube-controller-manager-master             1/1     Running   0          3m59s
kube-system   kube-proxy-nj6sk                           1/1     Running   0          3m48s
kube-system   kube-scheduler-master                      1/1     Running   0          3m59s
kube-system   storage-provisioner                        1/1     Running   0          3m58s

 

 

 

[2단계] GPU 작동하도록 세팅하기

[Step 1]

우선 PC가 GPU 세팅이 되어 있는지 확인이 필요합니다.

sudo docker run --rm --gpus all nvidia/cuda:(현재 pull이 가능한 tag) nvidia-smi

sudo docker run --rm --gpus all nvidia/cuda:12.3.1-base-ubuntu22.04 nvidia-smi

https://hub.docker.com/r/nvidia/cuda

위 링크에서 현재 pull 이 가능한 tag 버전을 확인해주세요! (tag는 12.3.1-base-ubuntu22.04) 를 의미함.

[Step 2]

/etc/docker/daemon.json 를 열어 내용을 바꿔주세요

[기존 시스템]

{"exec-opts":["native.cgroupdriver=systemd"],"log-driver":"json-file","log-opts":{"max-size":"100m"},"storage-driver":"overlay2"}

[변경할 값]

{
"exec-opts":["native.cgroupdriver=systemd"],"log-driver":"json-file","log-opts":{"max-size":"100m"},"storage-driver":"overlay2",

  "default-runtime": "nvidia",
  "runtimes": {
      "nvidia": {
          "path": "nvidia-container-runtime",
          "runtimeArgs": []
  }
  }

}

[Step 3]

도커를 재시작합니다.

sudo systemctl daemon-reload
sudo service docker restart

 

 

[Step 4]

k8s nvidia device plugin 설치 (https://github.com/NVIDIA/k8s-device-plugin)

$ kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.3/nvidia-device-plugin.yml

 

 

 

 

[3단계] Kubeflow 설치하기

https://github.com/kubeflow/manifests/tree/v1.8.0

(manifest 에서 "v1.8.0" branch 로 이동)

 

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

 

git clone https://github.com/kubeflow/manifests.git
cd manifests
git checkout v1.8.0

# 자 이제 시작이야!
while ! kustomize build example | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done

# 한방에 됬다면?

# 포트포워딩
kubectl port-forward --address 0.0.0.0 svc/istio-ingressgateway -n istio-system 8080:80

# 기본 계정 로그인
ID : user@example.com
PW : 12341234

 

 

 

 

 

[4단계] Kubeflow 계정 생성하기 (Profile)

위에서 기본 계정으로 로그인을 해보셨죠?

아래 처럼 입력해보시면, 방금 접속했던 계정이 나타날 거에요

kubectl get profile -A

 

kubeflow 계정을 생성하려면? profile 을 만들면 됩니다.

 

https://www.kubeflow.org/docs/components/central-dash/profiles/

 

Profiles and Namespaces

About Kubeflow Profiles and Namespaces for multi-user isolation

www.kubeflow.org

 

이 부분을 살짝 수정해볼까요? 

1. metadata의 네임스페이스 부분

- 해당 계정 profile이 metadata의 name으로 namespace가 나타나게 됩니다. 

2. owner 의 name 부분

- 로그인할 계정의 이메일 주소입니다.

apiVersion: kubeflow.org/v1
kind: Profile
metadata:
  ## the profile name will be the namespace name
  ## WARNING: unexpected behavior may occur if the namespace already exists
  name: xxxxx # 여기에 네임스페이스를 입력해주세요
spec:
  ## the owner of the profile
  ## NOTE: you may wish to make a global super-admin the owner of all profiles
  ##       and only give end-users view or modify access to profiles to prevent
  ##       them from adding/removing contributors
  owner:
    kind: User
    name: xxx@xxx.xxx # 여기에 이메일 주소를 입력해주세요

  ## plugins extend the functionality of the profile
  ## https://github.com/kubeflow/kubeflow/tree/master/components/profile-controller#plugins
  plugins: []
  
  ## optionally create a ResourceQuota for the profile
  ## https://github.com/kubeflow/kubeflow/tree/master/components/profile-controller#resourcequotaspec
  ## https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/resource-quota-v1/#ResourceQuotaSpec
  resourceQuotaSpec: {}

 

 

그리고 kubectl 로 해당 파일을 apply 해주세요!

kubectl apply -f my-profile.yaml


# 프로파일 확인
kubectl get profile -A

 

그 다음 dex의 config-map 을 수정해줍니다.

 

nano common/dex/base/config-map.yaml

 

이 부분을 아래에 복사 붙여넣기 하여 계정추가하거나 수정합니다. 

비밀번호는 https://bcrypt-generator.com/#google_vignette 에서 비밀번호를 입력하고 Encrypt를 진행한 후!

hash 부분에 입력해주세요!

 

 

 

완료되었으면, 아래 명령어를 실행해 기존 dex 를 제거해주시고

kubectl delete deployments.apps dex -n auth

 

 

 

manifest 에서 dex의 build 명령어를 찾아 apply 해줍니다.

kustomize build common/dex/overlays/istio | kubectl apply -f -

 

 

이렇게 하면, kubeflow에 개인 계정으로 로그인이 가능해집니다!

 


[+] Troubleshooting

 

Kubeflow 설치시 위 방식대로 쉽게 된다면 좋겠지만, 안될 경우가 많습니다.

설치시 겪어봤던 오류 기록들을 나열해봅니다.

 

1. failed to acquire lock ~~ permission denied

 

Error caching kubectl: failed to acquire lock

"/root/.minikube/cache/linux/v1.21.7/kubectl.lock"

: {Name:mkb7aeee46cbc538b25888dfad3e62407ad50c5a Clock:{} Delay:500ms Timeout:1m0s Cancel:<nil>}: unable to open /tmp/juju-mkb7aeee46cbc538b25888dfad3e62407ad50c5a: permission denied

 

위와 같은 에러 발생 시 다음 명령어 실행

 

sudo rm -rf /tmp/juju-mk*
sudo rm -rf /tmp/minikube.*

 

2. ingateway 가 0/1 상태로 Running 일때

내부에 접속하여 로그를 확인해보면 다른 pod 으로 네트워크 접속을 시도하다가 막히는 것을 볼 수 있었다.

이 경우 주로

1. CNI 설정 문제이거나

# flannel 은 시도해보았을 때 오류가 많았다.
# https://github.com/flannel-io/flannel/tree/master
# kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

# calico 는 오류가 덜했다.
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

 

2. docker None profile 로 적용했을 경우의 방화벽 문제였다.

 

## 방화벽을 해제하게 되면 보안이 취약해지니 해제해도 되는지 한번 검토해주세요! ##

 

# 현재 설정되어 있는 방화벽 규칙 확인하기
iptables --list
또는 
iptables -L


iptables v1.8.7 (nf_tables): 
Could not fetch rule set generation id: Permission denied (you must be root)
# 위와 같은 오류시 sudo 같이 넣어 입력하기

sudo iptables --list
또는 
sudo iptables -L


# 방화벽 해제하기
sudo iptables -P INPUT ACCEPT # "INPUT" 체인에 대한 기본 정책을 "ACCEPT"로 설정합니다.
sudo iptables -P FORWARD ACCEPT # "FORWARD" 체인에 대한 기본 정책을 "ACCEPT"로 설정합니다.
sudo iptables -P OUTPUT ACCEPT # "OUTPUT" 체인에 대한 기본 정책을 "ACCEPT"로 설정합니다.

sudo iptables -F  # 모든 방화벽 규칙을 삭제합니다.
# 설명을 보고 본인에게 맞는 방화벽 규칙을 제거해보세요

 

 

3. [403] Could not find CSRF cookie XSRF-TOKEN in the request.

접근시 문제 해결하기

 

# Jupyter 수정

sudo kubectl edit deploy jupyter-web-app-deployment -n kubeflow

 

 

# Volumes 수정

sudo kubectl edit deploy volumes-web-app-deployment -n kubeflow

 

 

contrib/kserve/models-web-app/overlays/kubeflow/kustomization.yaml
이 파일에 APP_SECURE_COOKIES=false 를 추가해주세요!
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Adds namespace to all resources.
namespace: kubeflow

# Labels to add to all resources and selectors.
commonLabels:
  app: kserve
  app.kubernetes.io/name: kserve

bases:
- ../../base
- web-app-authorization-policy.yaml

patchesStrategicMerge:
- patches/web-app-sidecar.yaml

patchesJson6902:
- target:
    group: networking.istio.io
    version: v1beta1
    kind: VirtualService
    name: kserve-models-web-app
    namespace: kserve
  path: patches/web-app-vsvc.yaml

generatorOptions:
  disableNameSuffixHash: true

# To make namespace for standalone installation kustomizable,
# variabalize ingress gateway, webhook service name and
# kserve namespace in webhook configurations
configMapGenerator:
  - name: kserve-models-web-app-config
    behavior: replace
    literals:
    - USERID_HEADER=kubeflow-userid
    - APP_PREFIX=/kserve-endpoints
    - APP_SECURE_COOKIES=false # 여기!!

configurations:
- params.yaml

 

 

이번 글에서는 Minikube를 활용한 Kubernetes 설치에 초점이 더욱 맞추어져 있었는데요. 

다음 글에서는 Kubeflow 를 활용한 ML Pipeline 설명과 예제를 기입해보겠습니다.