[MLOps] 도커, 쿠버네티스 설치 및 환경 설정

업데이트:

머신러닝 엔지니어를 위한 도커, 쿠버네티스 설치 및 환경 설정

1. 서버 세팅

1.1. 주어진 서버 확인

사설IP 공인IP ssh포트
111.11.1.111 222.222.222.22 22
333.33.3.333 444.444.444.44 23

위와 같이 서버 두 대가 주어졌다고 하겠습니다. 111.11.1.111 서버를 마스터(master), 333.33.3.333 서버를 워커(worker)노드라고 하겠습니다.

1.2. 서버 접속

1.2.1. 마스터 접속

$ ssh root@222.22.222.22

초기 사용자명은 root입니다.

1.2.2. 워커 접속

$ ssh root@444.444.444.44 -p 23

워커는 포트까지 입력해줍시다.

1.3. 사용자 추가(마스터, 워커 공통)

root 계정을 그대로 사용하기는 좀 그러니 사용자를 추가하겠습니다. 유저 이름은 openup 이라고 하겠습니다.

$ adduser openup

그리고 아래와 같이 sudoers를 vim으로 열어줍니다.

$ vim /etc/sudoers

그리고 아래와 같은 문법으로 슈퍼유저 권한을 추가해줍니다.

유저이름   ALL=(ALL:ALL) ALL

이를 적용하면

openup   ALL=(ALL:ALL) ALL

그리고 openup 유저로 다음과 같이 변경 가능합니다.

$ su - openup

1.4. 디스크 파티션 생성 및 포맷(마스터, 워커 공통)

$ sudo fdisk -l
$ sudo fdisk /dev/xvdb

n : 파티션 생성

default setting

w : 저장

$ mkfs.ext4 /dev/xvdb1

1.5. 파티션 마운트(마스터, 워커 공통)

$ mkdir -p /mnt/storage
$ sudo nano /etc/fstab
UUID=파티션의UUID /mnt/storage ext4 defaults 0 0
$ sudo mount -a
$ sudo chmod 777 /mnt/storage

# 확인
$ df -h

2. 도커 세팅(마스터, 워커 공통)

2.1. 도커 데이터 영역 만들기

$ mkdir -p /mnt/storage/docker_data

2.2. 도커 설치

$ sudo apt update
$ sudo apt install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 
$ sudo add-apt-repository "deb [arch=amd64] http://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt update
$ sudo apt install -y docker-ce=5:18.09.9~3-0~ubuntu-bionic docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic containerd.io vim

2.3. 도커 데몬(daemon) 설정

$ sudo nano /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"
}
$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

restart 했으니 아래 코드로 다시 도커의 상태를 확인해봅시다.

$ sudo systemctl status docker

위 코드를 입력했을 때 중간에 초록색 글씨로 active (running)이라는 글자 보이면 성공!

3. 엔비디아 도커 세팅(그래픽 카드 없으면 생략)

3.1 cuda 설치

$ release="ubuntu"$(lsb_release -sr | sed -e "s/\.//g")
$ sudo apt install sudo gnupg
$ sudo apt-key adv --fetch-keys "http://developer.download.nvidia.com/compute/cuda/repos/"$release"/x86_64/7fa2af80.pub"
$ sudo sh -c 'echo "deb http://developer.download.nvidia.com/compute/cuda/repos/'$release'/x86_64 /" > /etc/apt/sources.list.d/nvidia-cuda.list'
$ sudo sh -c 'echo "deb http://developer.download.nvidia.com/compute/machine-learning/repos/'$release'/x86_64 /" > /etc/apt/sources.list.d/nvidia-machine-learning.list'
$ sudo apt update
$ apt-cache search nvidia
$ sudo apt install -y nvidia-384
$ sudo apt install -y dkms nvidia-modprobe
$ sudo reboot

3.2 cuda 설치 확인

$ sudo cat /proc/driver/nvidia/version | nvidia-smi

3.3 엔비디아 도커 설치

$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ 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 update
$ sudo apt install -y nvidia-docker2

3.4. 도커 데몬 설정

$ sudo vim /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" : []
        }
    }
}`
$ sudo systemctl restart docker
$ sudo docker run --runtime=nvidia --rm nvidia/cuda nvidia-smi

4. 쿠버네티스(kubernetes) 세팅

4.1 kubeadm&kubelet&kubectl 설치(마스터, 워커 공통)

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add 
$ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
$ sudo apt install -y kubelet=1.15.5-00 kubeadm=1.15.5-00 kubectl=1.15.5-00
$ sudo apt-mark hold kubelet kubeadm kubectl
$ sudo sysctl net.bridge.bridge-nf-call-iptables=1

4.2 쿠버네티스 클러스터 생성(마스터)

$ sudo swapoff -a
$ sudo kubeadm init --pod-network-cidr=192.168.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 taint nodes --all node-role.kubernetes.io/master-
$ kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml

4.3 쿠버네티스 클러스터 조인(워커)

$ sudo swapoff -a
$ sudo kubeadm join 마스터노드아이피:6443 --token 토큰 --discovery-token-ca-cert-hash sha256:해쉬값

4.4 쿠버네티스 노드 확인

$ kubectl get nodes

4.4.1 (node 상태가 not ready이라면)

### kubelet 상태 확인
$ sudo systemctl status kubelet
### kubelet 재시작
$ sudo systemctl restart kubelet
$ sudo systemctl enable kubelet
### 다시한번 kubelet 확인
$ sudo systemctl status kubelet

5. kubeflow 세팅

5.1 nfs 서버 설치 및 설정(스토리지 서버를 할 서버 하나 선택해서)

5.1.1 nfs 서버로 제공할 공간 확보

$ sudo mkdir -p /mnt/storage/nfs_storage
$ sudo chmod -R 777 /mnt/storage/nfs_storage

5.1.2 nfs 서버 설치

$ sudo apt-get -y install nfs-common nfs-kernel-server rpcbind portmap

5.1.3 마스터, 워커 노드 ip 확인

$ kubectl get node -o wide

#  NAME                 STATUS   ROLES    AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
#  master   Ready    master   42h   v1.15.5   111.11.1.111    <none>        Ubuntu 18.04.3 LTS   4.15.0-118-generic   docker://18.9.9
#  worker   Ready    <none>   42h   v1.15.5   333.33.3.333   <none>        Ubuntu 18.04.3 LTS   4.15.0-118-generic   docker://18.9.9

5.1.4 nfs 서버 설정

$ sudo vim /etc/exports
/mnt/storage/nfs_storage 마스터노드IP(rw,insecure,sync,no_root_squash,no_subtree_check)
/mnt/storage/nfs_storage 워커노드IP(rw,insecure,sync,no_root_squash,no_subtree_check)

마스터노드와 워커노드에 실제 아이피를 적으면 아래와 같습니다.

/mnt/storage/nfs_storage 111.11.1.111(rw,insecure,sync,no_root_squash,no_subtree_check)
/mnt/storage/nfs_storage 333.33.3.333(rw,insecure,sync,no_root_squash,no_subtree_check)
$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server

5.1.5 nfs client설치(워커)

$ sudo apt install nfs-common

5.1.6 nfs 서버 테스트 : 클라이언트

$ mkdir test_mount
$ sudo mount nfs서버IP:/mnt/storage/nfs_storage test_mount
$ touch test_mount/test.txt

5.1.7 nfs 서버 테스트 : 서버

$ ls /mnt/storage/nfs_storage

5.1.8 nfs 서버 테스트 종료 : 클라이언트

$ umount test_mount

5.2 동적 프로비저닝을 위한 스토리지 클래스 설치

5.2.1 로컬 패스 스토리지

$ kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml

5.2.2 helm 설치

$ curl https://raw.githubusercontent.com/helm/helm/release-2.16/scripts/get > get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh

5.2.3 nfs-client-provisioner 설치

$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
$ helm install --generate-name  --set nfs.server=111.11.1.111 --set nfs.path=/mnt/storage/nfs_storage stable/nfs-client-provisioner

5.2.4 storageclass 세팅

$ kubectl patch storageclass nfs-client -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
$ kubectl get storageclass

5.3 kubernetes상에서 그래픽카드 사용을 위한 플러그인 설치(그래픽 카드가 없다면 스킵)

kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/1.0.0-beta4/nvidia-device-plugin.yml

5.4 docker private registry 배포

$ kubectl apply -f https://raw.githubusercontent.com/mojokb/handson-kubeflow/master/registry/kubeflow-registry-deploy.yaml
$ kubectl apply -f https://raw.githubusercontent.com/mojokb/handson-kubeflow/master/registry/kubeflow-registry-svc.yaml

5.4.1 docker daemon 세팅(마스터노드 워커노드 둘다)

$ sudo vim /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" : []
            }
    },
    "insecure-registries": [
            "kubeflow-registry.default.svc.cluster.local:30000"
    ]
}

만약 그래픽 카드가 없다면 아래와 같이 작성

{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "100m"
    },
    "data-root": "/mnt/storage/docker_data",
    "storage-driver": "overlay2",
    "insecure-registries": [
            "kubeflow-registry.default.svc.cluster.local:30000"
    ]
}
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

5.4.2 host ip 등록(마스터노드 워커노드 둘다 적용)

$ sudo nano /etc/hosts
마스터노드IP   kubeflow-registry.default.svc.cluster.local

5.4.3 registry 확인(워커노드에서)

$ curl kubeflow-registry.default.svc.cluster.local:30000/v2/_catalog

6. k9s 설치

$ wget https://github.com/derailed/k9s/releases/download/v0.13.7/k9s_0.13.7_linux_i386.tar.gz
$ tar zxvf k9s_0.13.7_linux_i386.tar.gz
$ sudo mv k9s /usr/bin

설치확인

$ k9s

종료하는 방법은

:q

7. kfctl 설치

$ wget https://github.com/kubeflow/kfctl/releases/download/v1.0.2/kfctl_v1.0.2-0-ga476281_linux.tar.gz
$ tar zxvf kfctl_v1.0.2-0-ga476281_linux.tar.gz
$ sudo mv kfctl /usr/bin

8. kubeflow 설치

$ export KF_NAME=my-kubeflow
$ export BASE_DIR=/opt/kubeflow
$ export KF_DIR=${BASE_DIR}/${KF_NAME}
$ export CONFIG_URI="https://raw.githubusercontent.com/kubeflow/manifests/v1.0-branch/kfdef/kfctl_k8s_istio.v1.0.2.yaml"
$ sudo mkdir -p ${KF_DIR}
$ sudo chmod 777 ${KF_DIR}
$ cd ${KF_DIR}
$ kfctl apply -V -f ${CONFIG_URI}

9. kubeflow 설치확인

$ kubectl get pods -n kubeflow -o wide