Skip to content

Commit

Permalink
week1: idea of ml workflow, kubeflow, kubernetes
Browse files Browse the repository at this point in the history
  • Loading branch information
julia-ing committed Mar 16, 2023
1 parent 2c44810 commit f1b4fe1
Show file tree
Hide file tree
Showing 3 changed files with 313 additions and 0 deletions.
74 changes: 74 additions & 0 deletions 예원/BASIC/1.1 ML_workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# 🦦 ML 워크플로우란
: 데이터 분석/가공 -> 모델 학습 -> 최적화 -> 배포 의 일련의 과정

크게 모델 실험 단계와 모델 생산 단계로 나뉨
### 모델 실험 단계
1. identify problem and collect / analyse data
2. choose an ML algorithm and code model
3. experiment with data and model training
4. tune the model hyperparameters
5. iterate tuning, training

- 데이터 분석, 수집
- ML 모델, 프레임워크 선택
- 모델 코드 작성
- 실험, 학습
- 하이퍼파라미터 튜닝

### 모델 생산 단계
1. transform data
2. train model
3. serve the model for online/batch prediction
4. monitor the model's performance

- 학습시스템에 맞게 실제 데이터 재가공
- 실제 데이터로 모델 학습
- 모델 배포
- 모니터링

---

# 🦄 MLOps Intro

![image](https://user-images.githubusercontent.com/77239220/225042465-d00ea6a4-a778-46a7-a055-64c7a51b6146.png)

출처: [https://papers.nips.cc/paper/5656-hidden-technical-debt-in-machine-learning-systems.pdf](https://papers.nips.cc/paper/5656-hidden-technical-debt-in-machine-learning-systems.pdf)

전체 ML 시스템을 보면, 모델 자체 뿐 아니라 데이터나 인프라 등 모든 부분이 포함됨

이 전체를 유기적으로 통합하기 위해 MLOps 도입!

---

비즈니스 요구 사항 정의 → 데이터 수집, 전처리 → 모델 빌드 → 학습 → 배포.. 반복

### 수동 프로세스

- 데이터 준비, 모델 학습, 검증이 수동으로 이루어짐

![image](https://user-images.githubusercontent.com/77239220/225042710-b6068b6e-8d0c-48cb-9810-1a14a097c0c4.png)
출처: [https://cloud.google.com/architecture/mlops-continuous-delivery-and-automation-pipelines-in-machine-learning?hl=ko](https://cloud.google.com/architecture/mlops-continuous-delivery-and-automation-pipelines-in-machine-learning?hl=ko)

- 문제점
- [training-serving skew](https://developers.google.com/machine-learning/guides/rules-of-ml/#training-serving_skew)
- 최신 데이터로 모델을 재학습하는 과정이 자주 일어나지 않음

## ML 파이프라인 자동화, CI/CD 파이프라인 자동화

![image](https://user-images.githubusercontent.com/77239220/225042925-a29b954c-3827-4e6a-84e2-f1b1dbbdbff0.png)
![image](https://user-images.githubusercontent.com/77239220/225042993-f2a2d401-e3a1-484c-990c-da95a1a027b1.png)
1. 개발 및 실험: 새 ML 알고리즘과 실험 단계가 조정되는 새 모델링을 반복적으로 시도
2. 파이프라인 CI: 소스 코드를 빌드하고 다양한 테스트를 실행 **(데이터, 스키마 등 모델 관련 정보들을 고려해서)**
3. **파이프라인 CD**: CI 단계에서 생성된 아티팩트를 대상 환경에 배포
4. **CT**: 파이프라인은 일정 또는 트리거에 대한 응답에 따라 프로덕션 단계에서 자동으로 실행
5. **모델 CD**: 학습된 모델을 예측의 예측 서비스로 제공.
6. 모니터링: 실시간 데이터를 기반으로 모델 성능의 통계를 수집. 이후 파이프라인을 실행하거나 새 실험 주기를 실행하게 됨

## vs. DevOps

| | DevOps | MLOps |
| --- | --- | --- |
| CI | 코드, 구성요소 테스트 및 검증 | + 데이터, 데이터 스키마, 모델 테스트 및 검증 |
| CD | 소프트웨어 패키지 서비스 자동 배포 | + 모델 서비스 자동 배포하는 ML 학습 파이프라인 |
| CT | | 모델을 자동으로 재학습시키고 서빙 |

164 changes: 164 additions & 0 deletions 예원/BASIC/1.2 kubeflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# 🏖 kubeflow?
: 리소스 오케스트레이션 플랫폼인 쿠버네티스 위에서 실행되는 ML toolkit

**목표** : ML 워크플로우에 필요한 서비스를 만드는게 아니라 **각 영역에서 가장 적합한 오픈소스 시스템들을 제공하는 것**

컴포넌트들 : 주피터 노트북, 메인 대쉬보드, 하이퍼파라미터 튜닝, 파이프라인, 서빙, 학습, 그 외..

# 🔥 How to Install

kubeflow 설치 최소 사양:
- 4 CPU 이상
- 50 GB 스토리지 이상
- 12 GB 메모리 이상

방법은 다양함

1. minikube / minikf (kubeflow 만 사용할거라면 단일 노드 환경도 괜찮음)

참고: https://magoker.tistory.com/93, https://rfriend.tistory.com/676
2. 클라우드 서비스 (AWS EKS, NCP NKS, GCP GKE..)
3. VM 마스터 & 워커 띄우기

사실 모두 시도해봤는데 책 실습 중에 막히는게 없으면 그냥 minikf 사용할 것 같다. ~~문제가 있다면 3번으로 그대로 가는걸로...~~

## 도커 세팅
```
$ sudo apt-get update
$ sudo apt-get 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] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get 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
$ sudo su
$ cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
$ mkdir -p /etc/systemd/system/docker.service.d
$ systemctl daemon-reload
$ systemctl restart docker
$ exit
```

## 쿠버네티스 세팅
- 공통
```
$ 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
```

- 마스터
```
$ 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
```

- 워커
```
$ sudo su
$ swapoff -a
$ sudo vi /etc/fstab # swap 쪽 주석처리
$ sudo kubeadm join 마스터노드아이피:6443 --token 토큰 --discovery-token-ca-cert-hash sha256:해쉬값
```

## nfs 설정 (스토리지 서버를 한개 선택해서 진행)
```
$ sudo mkdir -p /mnt/storage/nfs_storage
$ sudo chmod -R 777 /mnt/storage/nfs_storage
$ sudo apt-get -y install nfs-common nfs-kernel-server
$ kubectl get node -o wide
$ sudo vi /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)
$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server
$ sudo apt install nfs-common
$ mkdir test_mount
$ sudo mount nfs서버ip:/mnt/storage/nfs_storage test_mount
$ touch test_mount/file.txt
$ ls /mnt/storage/nfs_storage
$ kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
$ curl https://raw.githubusercontent.com/helm/helm/release-2.16/scripts/get > get_helm.sh
$ chmod 700 get_helm.sh
$ ./get_helm.sh
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
$ helm install --generate-name --set nfs.server=ip주소 --set nfs.path=/mnt/storage/nfs_storage stable/nfs-client-provisioner
$ kubectl patch storageclass nfs-client -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
$ kubectl get storageclass
```

## 도커 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
$ sudo vi /etc/docker/daemon.json
### 추가
"insecure-registries": [
"kubeflow-registry.default.svc.cluster.local:30000"
]
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
$ sudo vi /etc/hosts
# 마스터노드 ip kubeflow-registry.default.svc.cluster.local
# 워커에서 확인
$ curl kubeflow-registry.default.svc.cluster.local:30000/v2/_catalog
```

## 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
```

## 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
```

## kubeflow 설치
```
$ export KF_NAME=yw-kubeflow
$ export BASE_DIR=/home/${USER}
$ 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}
# 설치 확인
$ kubectl get pods -n kubeflow -o wide
```
75 changes: 75 additions & 0 deletions 예원/BASIC/1.3 kubernetes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 컨테이너 개발 시대

## 🐳 기존의 가상화 기술 vs 도커

기존 VM 기술은 단일 물리서버 위에 가상 OS들을 실행해 커플리케이션 격리 - 논리적으로 구분된 공간에서 독립되어 있어 가상환경끼리 서로 영향을 주지 않음

<img width="630" alt="스크린샷 2023-03-16 오후 2 31 39" src="https://user-images.githubusercontent.com/77239220/225523866-95e192bd-dc30-4903-9348-1e69be233ad4.png">

그러나.. 호스트 OS 위에 또 다른 OS를 실행하기 때문에 실행 비용에 대한 부담이 큼.
-> 컨테이너 기술은 실행 비용을 cgroup, namespace 등의 커널 기능으로 해결 (운영체제는 공유하되 리소스만 격리)

정리해보면 도커와의 차이점은 게스트OS의 유무! VM는 하나씩 늘어날 때마다 OS를 위한 자원을 할당해주어야 하는 반면에 도커는 어플리케이션을 구동하는데 필요한 모든 패키지만 있으면 컨테이너를 구동시킬 수 있다.


# ⚓ 쿠버네티스
개념 정리 ing..

## 아키텍처
쿠버네티스는 크게 마스터(Master)와 노드(Node) 두 개의 컴포넌트로 분리됨

- 마스터: 쿠버네티스의 설정 환경 저장, 전체 클러스터 관리
- 노드: 파드나 컨테이너 처럼 쿠버네티스 위에서 동작하는 워크로드를 호스팅


<details>
<summary>마스터 구성</summary>
<div markdown="1">

1. API 서버
쿠버네티스는 모든 명령과 통신을 API를 통해서 함. API 서버는 쿠버네티스의 모든 기능들을 REST API로 제공하고 그에 대한 명령을 처리

2. Etcd
DB 역할을 하는 서버.
etcd라는 분산형 키/밸류 스토어 오픈소스로 k8s 클러스터의 의 설정정보나 클러스터의 상태를 저장함.

3. 스케쥴러
파드,서비스 등 각 리소스들을 적절한 노드에 할당하는 역할을 함

4. 컨트롤러 매니져
컨트롤러를 생성하고 이를 각 노드에 배포/관리

컨트롤러? : 파드를 관리하는 역할을 함.
- 레플리카셋 (지정된 수의 파드가 항상 실행되도록 유지)
- 디플로이먼트 (가장 기본, stateless 어플리케이션 배포 시 사용)
참고로 디플로이먼트를 생성하면 replica 수대로 파드 생성되고 이를 관리할 레플리카셋도 생성됨
- 데몬셋 (데몬 프로세스로 띄워야 할 앱이 있을 때 사용, 단 하나의 파드 실행하기 때문에 노드가 죽으면 사라짐. 예시: 로그 수집기, 모니터링 프로세스)
- 스테이트풀셋 (상태를 갖고 있는 파드를 관리)
- 잡 (파드가 요청된 작업을 실행 후 정상적으로 종료되었는지 관리. 한번만 실행하는 작업들에 적합함! 예시: 도커이미지, 머신러닝 학습)
등이 있음

5. DNS
쿠버네티스는 리소스의 엔드포인트(Endpoint)를 DNS로 맵핑하고 관리함. Pod, 서비스 등은 ip를 배정받는데, 이 ip는 동적으로 생성되기 때문에 변경이 됨 -> 쿠버네티스에서는 이를 내부 DNS서버를 두는 방식으로 해결! 새로운 리소스가 생기면, 그 리소스의 ip와 DNS 이름을 등록.

</div>
</details>

<details>
<summary>노드</summary>
<div markdown="1">

1. Kubelet
노드에 배포되는 에이전트 - 마스터 *API서버*와 통신해서 노드가 수행해야 할 명령을 받아 수행하고, 반대로 노드의 상태 등을 마스터로 전달

2. Kube-proxy
네트워크 트래픽을 적절한 컨테이너로 라우팅 및 로드밸런싱. 노드로 들어오는/나가는 네트워크 트래픽과, 마스터와의 네트워크 통신을 관리.

3. Container runtime
파드를 통해서 배포된 컨테이너를 실행. 도커같은..

4. cAdvisor
각 노드에서 동작하는 모니터링 에이전트. 노드 내 컨테이너들의 상태와 성능 등의 정보를 수집하여 마스터 서버의 API 서버로 전달!

</div>
</details>

0 comments on commit f1b4fe1

Please sign in to comment.