kubeflow를 급히 써봐야 할 일이 있어서 minikube 환경에서 설치를 해보려고 했는데...

 

주위에 계신 어떤 한 분이 손쉽게 성공하셨다고 하셔서 나도 그렇게 될거라 믿고 해봤는데,

뭔가의 이유로 잘 진행이 되지 않아서 짜증이 솓구쳐서 결국은 Kubernetes 환경에서 진행했다.

 

 

이하 포스팅은 설치 가이드라기 보다는

Kubeflow 설치 성공한 과정에 대한 기록이다.

 

 

0. Kubernetes

- 다음 링크의 포스트와 동일한 방법으로 설치된 환경이다.

  . https://www.whatwant.com/entry/Kubernetes-Install-1

 

단, 이 때 Kubernetes를 설치한 3대 VM의 Spec은 좀 높여야 한다.

Memory가 부족하면 Kubeflow 설치가 안된다.

memory

 

Processor도 좀 더 잡아주는 것이 좋다.

CPU

 

처음에 4GB memory, 2 core 환경에서 Kubeflow 설치를 진행했을 때 제대로 진행이 안되었다.

 

일부 Pod가 pending 상태에 있길래 살펴봤었는데

자기가 실행될 여유 memory가 있는 worker node가 없어서 였다.

 

테스트가 쉽지 않아서 세부 Spec 조정까지는 못해봤고

8GB memory, 4 core 환경으로 했을 때 성공을 했다.

 

 

1. Kubeflow & Kubernetes version

 

현재 설치되어있는 Kubernetes version은 다음과 같다.

- Kubernetes v1.25.6

kubectl get nodes

 

현재 Kubeflow 최신 Version은 v1.7이다.

https://www.kubeflow.org/docs/releases/kubeflow-1.7/

Kubeflow v1.7

 

다행히 Kubernetes v1.25와 궁합이 잘 맞는다 !!!

 

 

2. How to install Kubeflow

뒤늦게 Kubeflow를 살펴본다 ^^

- https://www.kubeflow.org/

https://www.kubeflow.org/

 

공식 가이드에서 알려주는 설치법에는 어떤 것이 있을까?

How to install

 

① Use a packaged distribution

주로 Cloud 업체에서 maintain 하면서 제공되는 배포판들이다. 즉, 나에겐 쓸모없는....^^

Active Distributions

 

② Use the raw manifests

advanced user를 위한 설치 방법이란다 ^^

Raw Kubeflow Manifests

 

manifests는 GitHub를 통해 배포되고 있다.

- https://github.com/kubeflow/manifests#installation

https://github.com/kubeflow/manifests#installation

 

우리는 이제 manifests를 이용한 Kubeflow 설치를 진행할 것이다.

 

 

3. Prerequisites

앞에서 살펴봤듯이 3개의 사전 준비 항목이 있다.

 

① Kubernetes (up to 1.26) with a default StorageClass

- Kubernetes v1.25에서도 잘 된다 ^^

- 여기서 무심히 넘기면 안되는 항목이 default StorageClass 이다. 뒤에서 깊게 살펴보겠다!

 

② kustomize 5.0.3

Kubernetes native configuration management

최근에는 kubectl 내부에 포함되어 있다고 하는데, manifests를 사용하기 위해서는 별도로 설치를 해줘야 한다.

- https://kubectl.docs.kubernetes.io/installation/kustomize/binaries/

https://kubectl.docs.kubernetes.io/installation/kustomize/binaries/

 

❯ curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash

❯ sudo install -o root -g root -m 0755 kustomize /usr/local/bin/kustomize

 

가이드에서 요구한 버전은 v5.0.3 이지만, 설치된 버전은 v5.1.1이다.

잘된다 ^^

 

③ kubectl

kubernetes 버전과 동일한 버전의 kubectl을 사용하는 것이 좋다.

Kubernetes node가 아닌 다른 workspace에서 kubectl을 사용하기 위해서는 직접 설치를 해줘야 한다.

 

❯ curl -LO "https://dl.k8s.io/release/v1.25.6/bin/linux/amd64/kubectl"

❯ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

 

kubectl을 새로 설치했다면, 자동완성 설정을 해주는 것이 편리하다.

zsh을 사용하는 경우 아래와 같은 명령어를 사용하거나, ~/zshrc에 넣어주면 좋다.

 

 source <(kubectl completion zsh)

 

~/.zshrc 파일에서 plugin에도 추가로 넣어주면 더 좋다.

 

plugins=(kubectl kube-ps1 git zsh-syntax-highlighting zsh-autosuggestions)

 

접근 권한을 얻기 위한 인증 정보(config) 파일을 얻어오는 부분은 여기에서는 생략하겠다.

 

 

4. StorageClass

Kubeflow 설치 관련한 많은 포스팅에서 잘 언급해주지 않는 부분이 바로 이 부분이다.

 

Kubeflow 설치 과정에서 약 4개의 PV(PersistentVolume) 생성을 하게 된다.

- 10Gi 용량의 PV 2개

- 20Gi 용량의 PV 2개

 

60Gi 이상의 PV를 생성할 수 있는 환경이어야 하는 것이다.

 

처음에 간단히 설치한다고 낮은 Spec의 환경에서 설치 진행하면, 이런 부분 때문에 어려움을 겪게 된다.

나도 마찬가지였다. Worer Node의 Disk 용량을 충분히 잡아놓지 않았기 때문이다.

 

그래서, NFS를 이용해서 StorageClass 설정을 진행하기로 했다.

 

① NFS Server 설치

NFS Server를 만드는 방법은 다음 포스팅을 참고하기 바란다.

- https://www.whatwant.com/entry/NFS-Server-Ubuntu-1804

 

② NFS Provisioner

Kubernetes에서 NFS를 사용하기 위한 Provisioner를 설치하자.

- https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

 

Helm을 이용하려고 하는데, 혹시 Helm이 설치 안되어 있다면 다음과 같이 진행하면 된다.

- https://github.com/helm/helm/releases

 

❯ wget https://get.helm.sh/helm-v3.12.3-linux-amd64.tar.gz

tar zxvf helm-v3.12.3-linux-amd64.tar.gz

sudo install -o root -g root -m 0755 helm /usr/local/bin/helm

 

NFS Provisioner 설치는 다음과 같이 하면 된다.

 

❯ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/

❯ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \                 
    --set nfs.server=192.168.100.153 \
    --set nfs.path=/srv/nfs

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

 

잘 되는지 테스트를 해보면 다음과 같다.

 

 kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-claim.yaml -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-pod.yaml

❯ kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-claim.yaml -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-pod.yaml

 

NFS 서버에 생성된 디렉토리와 SUCCESS 파일이 확인되면 된다.

필요 없어진 디렉토리/파일 삭제는, 직접 수작업으로 NFS Server에서 진행하면 된다.

 

 

5. kubeflow install

이제 준비는 끝났다. manifest를 이용한 설치를 진행해보자.

- https://github.com/kubeflow/manifests#install-with-a-single-command

https://github.com/kubeflow/manifests#installation

 

Kubeflow 실제 설치는 정말 쉽다.

kubeflow install

 

❯ git clone https://github.com/kubeflow/manifests.git 

❯ cd manifests   

❯ while ! kustomize build example | kubectl apply -f -; do echo "Retrying to apply resources"; sleep 10; done

 

끝!

 

이제 기다리면 된다. 시간이 좀 걸린다.

k9s

 

모든 Pod가 Running이면 된 것이다.

 

 

6. Service

웹 접근을 위해서는 현재 ClusterIP로 설정되어 있는 서비스를 NodePort 또는 LoadBalancer로 변경해주는 것이 좋다.

ClusterIP

 

설정을 변경해보자.

 

> kubectl edit service istio-ingressgateway -n istio-system

 

type 부분을 수정하고 저장하면 된다.

NodePort

 

다시 확인해보자.

NodePort

 

이제 웹브라우저로 접근하면 된다. (IP는 각자 상황에 맞게, 포트는 위와 같이 확인되는대로)

- http://192.168.100.150:31537/

login

 

기본 계정 정보는 다음과 같다.

- Email: user@example.com

- Password: 1234123 

 

kubeflow

 

수고 많으셨습니다!!!

반응형

https://minikube.sigs.k8s.io/

 

Kubernetes를 공부할 때 실습 환경으로 종종 minikube가 언급되지만

개인적으로 Kubernetes 공부 용도로는 minikube를 절대 추천하지 않는다.

 

사실 여러 부분에서 K8s를 제대로 구성한 것과의 차이가 꽤 크기 때문이다.

 

그리고 제대로 K8s 공부하기 위해서는 3대 이상의 머신 구성이 필요하지만

minikube로는 그런 상황에 대해서 실습을 할 수 없다.

 

그리고, 결정적으로 실제 업무 용도로 minikube를 사용하지 않기에

굳이 minikube에 시간 투자할 필요가 없다고 생각했었다.

 

하지만, 세상 모든 것은 나름의 쓸모가 있다!

 

그렇다. minikube가 필요해서 설치 과정을 정리해보고자 한다 ^^

 

 

0. What you’ll need

- 2 CPUs or more

- 2GB of free memory

- 20GB of free disk space

- Internet connection

- Container or virtual machine manager

  . such as: Docker, QEMU, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware Fusion/Workstation

 

1. 실습 환경

나는 VirtualBox를 이용하기로 했다.

VirtualBox

 

- 2 CPUs or more

- 4GB of free memory

- 50GB of free disk space

- Internet connection

 

VBox

 

- OS: Ubuntu 20.04 LTS

- Container or virtual machine manager : Docker

  . Docker 설치 방법: https://www.whatwant.com/entry/docker-buildx

docker

 

2. minikube 설치

- 공식 홈페이지에서는 각 환경 別 설치 방법을 상당히 편리한 UX로 제공해주고 있다.

  . https://minikube.sigs.k8s.io/docs/start/

 

https://minikube.sigs.k8s.io/docs/start/

 

> curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

> sudo install minikube-linux-amd64 /usr/local/bin/minikube

 

그대로 실행하면 끝이다.

minikube install

 

3. minikube start

minikube를 구동시키면 귀여운 이모지들과 함께 다운로드 및 설치 등이 진행된다.

minikube start

 

4. kubectl 설치

Kubernetes(minikube)에 명령어를 전달하기 위해서는 'kubectl'가 필요하다.

  . https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

 

가이드 문서에 있는 내용을 참조해서 설치 진행하면 된다.

kubectl install

 

❯ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

❯ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

❯ kubectl version --client

 

잘 동작하는지 살펴보자.

kubectl

 

5. Dashboard

대시보드도 손쉽게 볼 수 있다.

dashboard

 

❯ minikube addons enable metrics-server

❯ minikube dashboard 

 

 

간단하게 Kubernetes를 맛보기 하는 용도로 정말 간단하게 설치할 수 있는 좋은 도구이다!!!

 

반응형

요즘 어떤 서비스의 아키텍처를 설계한다고 하면

당연히 "마이크로서비스 아키텍처(MSA)"를 떠올리게 될 정도로 MSA는 이제 거의 표준처럼 되어 버렸다.

 

그렇기에 당연히 우리는 "마이크로서비스 아키텍처(MSA)"를 공부해야 하고,

아마존에서 설계/아키텍처 부분 베스트셀러인 이 책을 살펴보는 것은 자연스러운 수순일 것이다 ^^

 

표지

 

2017년도에 초판으로 출간된 책인데,

빠른 변화와 신기술의 등장에 발맞춰서 얼마전에 전면 개정판으로 새로운 책으로 거듭났다!

 

전면 개정판

 

이 책의 저자는 특정 회사에 속하지 않고 프리랜서로 활동하시는 것 같고,

옮긴이는 포동 서비스를 언급하신 것으로 봐서 LG유플러스에서 근무하시는 것이 아닌가 싶다 ^^

 

지은이/옮긴이

 

책 제목에 "아키텍처"가 들어가있다보니

이 책의 대상독자로 제일 먼저 떠오르는 것이 "어?! 이 책은 Architect를 위한 책인가?"였다.

 

하지만, 뒤에 설명할 목차 등을 보면 알겠지만

이 책은 개발자부터 PL 및 C-level에게도 도움이 될 수 있는

"마이크로서비스 아키텍처(MSA)"에 대한 모든 것을 담고 있는 책이다.

 

대상 독자

 

이 책은 크게 "기초/구현/사람"이라는 3개의 부로 나뉘어져 있다.

 

응?

 

사람?

 

1부 기초

 

개인적으로는 2부 구현 부분에 가장 관심이 많이 간다.

 

2부 구현

 

정말 의외인 "3부 사람" ...

 

뭐 세상 모든 일은 다 사람하기 나름이니.... 가장 중요한 것이 사람인 것 맞지만.... 호오....!

 

3부 사람

 

회사를 다니고 있다면

처음부터 아무 것도 없는 상태에서 새롭게 설계하는 일 보다는

이미 모놀리스 아키텍처로 구성되어 있는 기존의 서비스를

마이크로 서비스 아키텍처로 마이그레이션하는 일이 더 많을 것이다.

 

그래서 "Chapter3. 모놀리스 분해" 부분에 관심이 많이 갔다.

 

CH3 - 모놀리스 분해

 

아마존에서 괜히 베스트셀러가 된 것은 아니기에

책 구성과 내용은 정말 훌륭한 것 같다.

 

다만, 개인적인 취향으로 아쉬운 것은...... 풀컬러가 아니라는 점!?

ㅋㅋ 사실 책 주제 자체가 굳이 풀컬러일 필요가 전혀 없기에 이마저도 단점이 아닌 것 같다 ^^

 

CH1

 

책 내용이 훌륭하다는 예시를 들어보자면,

모놀리스의 유형 중 하나인 "모듈식 모놀리스"에 대한 설명을 한 번 살펴보자.

 

모듈식 모놀리스

 

당연하게 보일 수도 있겠지만

개인적으로는 저렇게 모듈로 나눠서 구성하면

그것을 가지고 마치 마이크로 서비스인 것처럼 착각하는 경우가 종종 있다.

그런 부분에 대한 설명이 차분하게 잘 서술되어 있는 것을 보면 이 책의 내공이 정말 탄탄한 것 같다.

 

그리고 또, 개인적으로 애정하는 쿠버네티스...

 

K8s

 

마이크로서비스 아키텍처(MSA)하면 빼놓을 수 없는 짝꿍 쿠버네티스(Kubernetes) !!!

 

 

전반적으로 이 책은 정말 "마이크로서비스 아키텍처(MSA)"의 교과서라고 불리워도 무방할만큼

탄탄한 내공이 가득차 있는 정말 좋은 책이다.

 

쿠버네티스(Kubernetes)를 공부하는 분들도 필수 도서로 같이 공부하면 정말 많은 도움이 될 것이다!!!

 

 

 

"한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평입니다."

 

반응형

Kubernetes 설치를 저와 같이 했다면, addon으로 Dashboard도 설치가 되었을 것이다.

https://www.whatwant.com/entry/Kubernetes-Install-1

 

 

그런데, 정말 설치가 잘 되었을까?

K8s master 서버에 접속 후 한 번 살펴보자.

 

(master)$ kubectl get deployments --namespace kube-system

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
calico-kube-controllers      1/1     1            1           3d19h
coredns                      2/2     2            2           3d19h
dns-autoscaler               1/1     1            1           3d19h
kubernetes-dashboard         1/1     1            1           3d19h
kubernetes-metrics-scraper   1/1     1            1           3d19h
metrics-server               1/1     1            1           3d19h

 

오옷! 뭔가 보인다.

"kubernetes-dashboard"라는 항목이 보인다.

 

어떻게 접근해야할지 확인하기 위해 service 항목들을 살펴보자.

 

(master)$ kubectl get services --namespace kube-system

NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
coredns                     ClusterIP   10.233.0.3      <none>        53/UDP,53/TCP,9153/TCP   3d19h
dashboard-metrics-scraper   ClusterIP   10.233.43.183   <none>        8000/TCP                 3d19h
kubernetes-dashboard        ClusterIP   10.233.51.126   <none>        443/TCP                  3d19h
metrics-server              ClusterIP   10.233.30.232   <none>        443/TCP                  3d19h

 

아직 ClusterIP로만 연결되었기 때문에 K8s 밖에서 연결해볼 수 없는 상태다.

밖에서 접근할 수 있는 경로를 만들어보자.

 

dashboard의 service 항목을 수정해보자.

 

(master)$ kubectl edit service --namespace kube-system kubernetes-dashboard

 

ClusterIP 부분을 "NodePort"로 변경하면 된다.

 

...
  selector:
    k8s-app: kubernetes-dashboard
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

 

다시 확인해보자.

 

(master)$ kubectl get services --namespace kube-system

NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
coredns                     ClusterIP   10.233.0.3      <none>        53/UDP,53/TCP,9153/TCP   3d21h
dashboard-metrics-scraper   ClusterIP   10.233.43.183   <none>        8000/TCP                 3d21h
kubernetes-dashboard        NodePort    10.233.51.126   <none>        443:31934/TCP            3d21h
metrics-server              ClusterIP   10.233.30.232   <none>        443/TCP                  3d21h

 

NodePort로 잘 변경되었으며 "31934"포트로 연결할 수 있음을 알려주고 있다.

바로 웹브라우져로 열어보자.

 

 

kubernetes-dashboard는 기본적으로 443포트, https 방식으로 제공되고 있다.

하지만, 당연하게도 인증서가 공인 인증서가 아니기에 ...

 

그러나, 고급 버튼을 누르면 길이 보인다.

 

 

안전하지 않다고 하지만, 전부 내거인데 뭐~ 그냥 이동하자 ^^

 

 

어!? 인증이 필요하단다.

이런...

 

그래... 권한이 필요하겠지...

 

 

dashboard를 위한 Service Account를 하나 생성하자.

 

(master)$ nano dashboard-serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
   name: k8s-dashboard
   namespace: kube-system

 

ClusterRole Admin 권한을 부여하자.

 

(master)$ nano dashboard-clusterrolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: k8s-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: k8s-dashboard
  namespace: kube-system

 

전부 create 해주면 된다.

 

(master)$  kubectl create -f dashboard-serviceaccount.yaml

(master)$  kubectl create -f dashboard-clusterrolebinding.yaml

 

만들어진 Service Account 정보를 살펴보자.

 

(master)$ kubectl describe serviceaccounts --namespace kube-system k8s-dashboard

Name:                k8s-dashboard
Namespace:           kube-system
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

 

어?! Tokens 부분에 아무런 정보가 없다! 이게 뭐지!?

https://kubernetes.io/docs/concepts/configuration/secret/#service-account-token-secrets

 

Kubernetes 1.22 이후 버전부터는 token이 자동 생성되지 않는단다! 이런!

 

(master)$ kubectl get nodes

NAME       STATUS   ROLES           AGE     VERSION
master     Ready    control-plane   3d20h   v1.25.6
worker01   Ready    <none>          3d20h   v1.25.6
worker02   Ready    <none>          3d20h   v1.25.6

 

나는 지금 v1.25.6 버전이구나.

그럼 직접 token을 생성하는 수밖에 ...

 

(master)$ nano dashboard-token.yaml

apiVersion: v1
kind: Secret
metadata:
  name: k8s-dashboard-secret
  annotations:
    kubernetes.io/service-account.name: "k8s-dashboard"
type: kubernetes.io/service-account-token

 

Service Account가 있는 kube-system namespace에다가 만들어주면 된다.

 

(master)$ kubectl create -f dashboard-token.yaml --namespace kube-system

 

만들어진 secret 정보를 살펴보면 token 정보도 보일 것이다.

 

(master)$ kubectl describe secrets --namespace kube-system k8s-dashboard-secret

Name:         k8s-dashboard-secret
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: k8s-dashboard
              kubernetes.io/service-account.uid: 037ee808-781e-424b-a17a-215113708a3b

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1099 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IkdBa0Mtc29XS1NGYl9pb1VuZzhpOHhQWlZaZEVOVTBIMWFQTHlVY21VNVUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrOHMtZGFzaGJvYX...

 

그러면, Service Account 정보를 다시 살펴보자.

 

(master)$ kubectl describe serviceaccounts --namespace kube-system k8s-dashboard

Name:                k8s-dashboard
Namespace:           kube-system
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              k8s-dashboard-secret
Events:              <none>

 

token 정보가 연결되었음을 볼 수 있다.

 

이제, 앞에서 확인한 token 정보를 복사한 뒤에 dashboard에 입력해보자.

 

 

음?! 표시할 데이터가 없단다.

얼마나 힘들게 여기까지 들어왔는데!!!!

 

 

검색창 옆에 namespace 부분을 "kube-system"으로 변경해보자.

 

 

뭔가 많이 보인다~~~!!!

 

 

 

눈에 뭔가 보이니까 좋다! ^^

반응형

간만에 Kubernetes 실습 환경 구축할 일이 생겨서

새로운 마음으로 진행하면서 기록으로 남겨 보고자 한다.

 

 

1. Server

  - master 1대 + worker 2대 = 총 3대의 Server를 준비하자.

  - 실습 환경은 VirtualBox로 하겠지만, 물리적인 Server로 이하 과정을 진행해도 무방하다.

 

VirtualBox

 

① CPU / Memory

  - Kubernetes 설치를 위해서는 다음과 같은 최소 사양이 필요하다

    . master: 2core, 2048MB

    . worker: 1core, 1280MB

  - 하지만, 원활한 동작을 위해서는 모두 2core, 2GB Spec으로 구성하자

 

CPU

 

Memory

 

② Network

  - VirtualBox의 경우 사실 NAT 방식으로도 Kubernetes 설치가 가능하긴 하다.

  - 하지만, 실제 서버 구성과 같은 환경으로 실습을 진행해보기 위해서는 브리지 방식으로 구성해보자.

 

네트워크

 

  - 보통 집에서 인터넷을 쓰는 방식이라고 하면 아래 그림과 같은 구성이 될 것이다.

 

 

③ Hostname, IP

  - 각 서버의 hostname 및 IP를 확인해 놓자.

 

hostname, IP

 

  - worker01 / worker02 서버들의 정보도 추가 확인하자.

 

 

2. Server Configure

  - Kubernetes 설치를 위해 서버 환경 셋팅을 좀 해줘야 한다.

  - 아래 과정은 서버 3대 모두 똑같이 진행해줘야 한다.

 

① swap off

  - K8s에서는 swap 기능이 켜져 있으면 문제가 발생할 수 있으므로 꺼줘야 한다.

 

(master/worker)$ sudo swapoff -a

(master/worker)$ sudo nano /etc/fstab

 

  - 재부팅되더라도 유지될 수 있도록 아래와 같이 swap 부분을 주석 처리해준다.

 

# /swap.img   none    swap    sw  0   0

 

② ip_forward

  - 가상화 머신끼리 패킷을 주고받을 수 있도록 ip_forward 기능을 켜줘야 한다.

 

(master/worker)$ sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

 

③ hosts

  - 서버끼리 서로 알 수 있도록 hosts 정보도 등록해주자.

 

(master/worker)$ sudo nano /etc/hosts

 

  - 정보는 각자 상황에 맞춰서...

 

192.168.100.150 master
192.168.100.151 worker01
192.168.100.152 worker02

 

  - 혹시 상단에 아래와 같은 부분이 있으면 삭제하자

 

127.0.0.1 master

 

 

 

여기까지 진행했으면 깔끔한 진행을 위해 재부팅을 한 번 해주자.

VirtualBox의 장점을 살리기 위해서는 안전한 진행을 위해 snapshot 한 번 찍어주는 것도 좋다.

 

 

3. Kubernetes 설치

  - Kubespray를 이용해서 Kubernetes 설치를 진행하도록 하겠다.

 

① Python3 설치

  - 일단 기본 패키지로 설치하자

 

(master)$ sudo apt install -y python3 python3-pip

 

② ssh-key 생성

  - 서버間 연결을 위해 ssh-key 생성 및 등록 과정이 필요하다.

  - 이와 관련해 가장 깔끔한 가이드 문서는 아래와 같다. 참고하면 좋다.

    . https://cloud.google.com/compute/docs/connect/create-ssh-keys?hl=ko 

 

  - 여기에서는 가장 간단하게 그냥 무조건 기본값으로 그냥 막 엔터만 쳐서 생성하도록 하자.

 

(master)$ ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/home/whatwant/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/whatwant/.ssh/id_rsa
Your public key has been saved in /home/whatwant/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:MtIQVARuKNcksL0D3beQ2aMMbMYfcdybNFVZVRGgDnQ whatwant@master
The key's randomart image is:
+---[RSA 3072]----+
|....*=+. o.E.+o+*|
| * B B. = . o    |
|+ @ @ +. = .     |
| * * B oo o      |
|  o = = S  .     |
|   . . o         |
|                 |
|                 |
|                 |
+----[SHA256]-----+

 

③ copy key

  - ssh-key 인증을 통해 master에서 worker로 접속할 수 있도록 하기 위한 과정이다

  - 명령어에 있는 IP는 worker들의 IP이다. 각자 상황에 맞춰 사용하면 된다.

  - 자기 자신(master)에도 등록을 하자.

 

(master)$ ssh-copy-id 192.168.100.151

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/whatwant/.ssh/id_rsa.pub"
The authenticity of host '192.168.100.151 (192.168.100.151)' can't be established.
ED25519 key fingerprint is SHA256:Nu127IO/HdpFbO3HvWB8J61ZdhGjXpYDBSb3qg3rSY8.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
whatwant@192.168.100.151's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '192.168.100.151'"
and check to make sure that only the key(s) you wanted were added.

(master)$ ssh-copy-id 192.168.100.152

(master)$ ssh-copy-id 192.168.100.150

 

④ Kubespray 내려받기

  - git clone 방식으로 내려 받고, 최신 버전으로 switch 하자.

 

(master)$ git clone https://github.com/kubernetes-sigs/kubespray.git

(master)$ cd kubespray

(master)$ git switch release-2.21

 

⑤ 의존성 패키지 설치

  - Kubespray에서 필요로 하는 의존성 패키지들을 설치해주자

 

(master)$ sudo pip3 install -r requirements.txt

 

⑥ 인벤토리 생성

  - sample을 기반으로 나만의 설정을 업데이트해주면 된다.

  - 당연히 아래 IP 정보는 각자 상황에 맞춰서...

 

(master)$ cp -rfp inventory/sample inventory/mycluster


(master)$ declare -a IPS=(192.168.100.150 192.168.100.151 192.168.100.152)
(master)$ CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

 

  - 이렇게 생성된 hosts.yaml 파일을 확인 및 수정하자.

 

(master)$ nano ./inventory/mycluster/hosts.yaml

 

  - 아래 수정 내역은 공부를 위한 설정이다. 실제 운영 환경이라면 기본 설정대로 하는 것이 낫다.

 

all:
  hosts:
    master:
      ansible_host: 192.168.100.150
      ip: 192.168.100.150
      access_ip: 192.168.100.150
    worker01:
      ansible_host: 192.168.100.151
      ip: 192.168.100.151
      access_ip: 192.168.100.151
    worker02:
      ansible_host: 192.168.100.152
      ip: 192.168.100.152
      access_ip: 192.168.100.152
  children:
    kube_control_plane:
      hosts:
        master:
    kube_node:
      hosts:
        worker01:
        worker02:
    etcd:
      hosts:
        master:
    k8s_cluster:
      children:
        kube_control_plane:
        kube_node:
    calico_rr:
      hosts: {}

 

  - addon은 다음 3가지 정도만 설정해보자.

 

(master)$ nano ./inventory/mycluster/group_vars/k8s_cluster/addons.yml
dashboard_enabled: true
helm_enabled: true
metrics_server_enabled: true

 

  - proxy mode도 iptables로 설정하자.

 

(master)$ nano ./inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
# Kube-proxy proxyMode configuration.
# Can be ipvs, iptables
kube_proxy_mode: iptables

 

⑦ install

  - 이제 설치를 진행하자 !

 

(master)$ ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root cluster.yml

 

  - 혹시라도 에러가 발생하면 윗 단계들을 다시 한 번 꼼꼼하게 살펴보기 바란다.

  - 지금 직접 해보면서 포스팅하는 것이기에, 분명히 된다 !!! ^^

 

 

4. kubectl

  - master 서버에서 root 아닌 계정도 kubectl 명령을 사용할 수 있도록 하자

 

① 인증 정보 복사

  - root 계정에 등록된 인증 정보를 복사해오면 된다.

 

(master)$ mkdir -p ~/.kube

(master)$ sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config

(master)$ sudo chown $(id -u):$(id -g) ~/.kube/config

 

② 자동완성

  - bash 쉘 환경에서 자동완성 기능을 추가하려면 다음과 같이 하면 된다.

 

(master)$ echo 'source <(kubectl completion bash)' >>~/.bashrc

(master)$ source ~/.bashrc

 

③ check

  - 잘 동작하는지 해보자.

 

(master)$ kubectl cluster-info

Kubernetes control plane is running at https://127.0.0.1:6443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.


(master)$ kubectl get nodes

NAME       STATUS   ROLES           AGE   VERSION
master     Ready    control-plane   21m   v1.25.6
worker01   Ready    <none>          20m   v1.25.6
worker02   Ready    <none>          20m   v1.25.6

 

 

잘 된다!!!!!

 

반응형

 

GCP, AWS와 같은 Cloud 업체에서 제공해주는 Managed K8s 환경을 사용하는 것이 아니라,

Local 환경에서 직접 K8s를 설치하는 경우

Ingress를 이용하기 위해서는 추가적인 설치를 해야 한다.

 

다른 네트워크 관련된 것들과 마찬가지로

Ingress도 여러가지 중에 선택적으로 설치해서 사용해야 한다.

 

직접 설치해서 사용하는 경우 일반적으로 Nginx 기반의 Ingress를 선택한다.

그런데, 이 부분에서 고생을 했던 이유가 Nginx 기반 Ingress 자체도 종류가 여러가지라는 것이다.

 

그 중에서 대표적인 Nginx Ingress Controller는 다음의 2가지 이다.

  - kubernetes/ingress-nginx

  - nginxinc/kubernetes-ingress

 

첫번째 것은 Kubernetes 진영에서 배포하고 있는 ingress-nginx 이고,

두번째 것은 Nginx 진영에서 배포하고 있는 nginx-ingress 이다.

 

두 배포판의 차이점을 정리한 내용은 다음 링크에서 확인해보면 된다.

  - https://docs.nginx.com/nginx-ingress-controller/intro/nginx-ingress-controllers

 

 

 

 

기능적으로 Nginx에서 배포하는 것이 좀 더 다양한 것 같기는 한데,

아무래도 Kubernetes 문서에서 보이는 Ingress 내용들의 기준이 되는 것은

`kubernetes/ingress-nginx`일 것이다.

 

 

 

그런데, 문제는 Kubespray로 Kubernetes를 설치할 때

addon으로 ingress를 선택하게 되면

이 때 설치되는 것이 'kubernetes/ingress-nginx'가 아니다.

(잘못알고 있을 수도 있으니, 정확히 알고 계신 분들 계시면 제보 바랍니다)

 

 

 

그래서,

Kubespray를 이용해서 Kubernetes를 설치할 때

addon 설정할 때 ingress를 선택하지 말고

나중에 직접 Ingress를 설치하는 방법으로 하고자 한다.

 

 

Kubernetes는 설치를 마친 상태에서

Ingress 설치를 하는 과정으로 진행해보자.

 

Reference

  - https://github.com/kubernetes/ingress-nginx/

  - https://kubernetes.github.io/ingress-nginx/deploy/

 

 

다양한 환경에서의 설치 방법이 각각 있지만,

우리가 여기에서 살펴볼 것은 Bare-Metal 환경을 기준으로 하겠다.

  - https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal

 

그리고, 이 방법은 `Nodeport` 방식으로 설정된다.

(LoadBalancer가 있으면 그것을 이용하겠지만, 개인적으로 구축한 K8s 환경에서는...)

 

 

 

사실, 설치 방법은 너무나 쉽다.

단 1줄 !!!

 

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml

 

정말 중요한 것은

잘 동작하는지 검증을 해보는 것일 것이다.

 

Namespace로 작업 공간 확보한 다음

Deployment 만들고 Service 만들어서

Ingress로 접근하도록 해보자.

 

 

① 따로 방을 잡아놓기 위해 Namespace 만들고,

$ nano 01.Namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: test-ingress

 

② Deployment를 이용해 Pod를 만들어 놓자

$ nano 02.Deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deploy

spec:
  replicas: 3

  selector:
    matchLabels:
      app: web

  template:
    metadata:
      name: web-pod
      labels:
        app: web

    spec:
      containers:
      - image: whatwant/node-web:1.0
        name: web
        ports:
        - containerPort: 8080
          protocol: TCP

 

③ Pod들을 연결할 Service를 만들자

$ nano 03.Service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-svc

spec:
  ports:
  - port: 80
    targetPort: 8080

  selector:
    app: web

 

지금까지 만들어 놓은 YAML을 실행하자

$ kubectl create -f ./01.Namespace.yaml

$ kubectl create --namespace=test-ingress -f ./02.Deployment.yaml

$ kubectl create --namespace=test-ingress -f ./03.Service.yaml

 

 

이제, 본론이다!

Ingress를 만들어서 Service를 외부로 오픈해보자.

$ nano ./04.Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /

spec:
  rules:
  - http:
      paths:
      - path: /test
        pathType: Prefix
        backend:
          service:
            name: web-svc
            port:
              number: 80

 

만들어 놓은 YAML을 실행하자

$ kubectl create --namespace=test-ingress -f ./04.Ingress.yaml

 

 

이제 Web-Browser로 확인을 하면 되는데,

ingress-nginx가 지금 어떤 IP의 어떤 Port로 서비스 되고 있는 것일까?

$ kubectl get services --namespace=ingress-nginx

NAME                                       TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                               AGE
ingress-nginx-controller                 NodePort    10.233.29.64    <none>          80:32035/TCP,443:32407/TCP   11h
ingress-nginx-controller-admission   ClusterIP     10.233.38.85    <none>          443/TCP                              11h

 

`ingress-nginx`는 지금 `NodePort` 방식으로 서비스 되고 있으므로 IP는 node들의 IP 아무것이나 ...

Port는 http는 32035, https는 32407을 사용하고 있음을 확인할 수 있다.

(당연히 각자의 환경에서 Port는 다를 수 있다)

 

 

그러면, 이제 웹브라우저로 확인해보자.

 

 

어?! 왜 안되지 ?!

멍청하면 손발이 고생한다고... 이 문제를 해결하려고 3일 넘게 잠도 잘 못자고 정말 고생했다 ㅠㅠ

 

엄청난 구글링 시도를 했지만 속시원한 해결책을 찾지 못하다가... 결국은 방법을 찾았다.

 

 

일단, ingress-nginx의 로그를 확인해야 했었다.

$ kubectl logs --namespace=ingress-nginx ingress-nginx-controller-57ffff5864-p52bb -f
-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:       v1.0.0
  Build:         041eb167c7bfccb1d1653f194924b0c5fd885e10
  Repository:    https://github.com/kubernetes/ingress-nginx
  nginx version: nginx/1.20.1

-------------------------------------------------------------------------------

W0918 04:05:51.466315       6 client_config.go:615] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
I0918 04:05:51.466488       6 main.go:221] "Creating API client" host="https://10.233.0.1:443"
I0918 04:05:51.476011       6 main.go:265] "Running in Kubernetes cluster" major="1" minor="20" git="v1.20.7" state="clean" commit="132a687512d7fb058d0f5890f07d4121b3f0a2e2" platform="linux/amd64"
I0918 04:05:51.723687       6 main.go:104] "SSL fake certificate created" file="/etc/ingress-controller/ssl/default-fake-certificate.pem"
I0918 04:05:51.740515       6 ssl.go:531] "loading tls certificate" path="/usr/local/certificates/cert" key="/usr/local/certificates/key"
I0918 04:05:51.769911       6 nginx.go:253] "Starting NGINX Ingress controller"
I0918 04:05:51.783535       6 event.go:282] Event(v1.ObjectReference{Kind:"ConfigMap", Namespace:"ingress-nginx", Name:"ingress-nginx-controller", UID:"9e277dae-b490-471f-806f-c88f9554da0f", APIVersion:"v1", ResourceVersion:"32531", FieldPath:""}): type: 'Normal' reason: 'CREATE' ConfigMap ingress-nginx/ingress-nginx-controller
I0918 04:05:52.972526       6 nginx.go:295] "Starting NGINX process"
I0918 04:05:52.972784       6 nginx.go:315] "Starting validation webhook" address=":8443" certPath="/usr/local/certificates/cert" keyPath="/usr/local/certificates/key"
I0918 04:05:52.972852       6 leaderelection.go:243] attempting to acquire leader lease ingress-nginx/ingress-controller-leader...
I0918 04:05:52.973417       6 controller.go:150] "Configuration changes detected, backend reload required"
I0918 04:05:52.985822       6 leaderelection.go:253] successfully acquired lease ingress-nginx/ingress-controller-leader
I0918 04:05:52.992811       6 status.go:84] "New leader elected" identity="ingress-nginx-controller-57ffff5864-p52bb"
I0918 04:05:53.007665       6 status.go:204] "POD is not ready" pod="ingress-nginx/ingress-nginx-controller-57ffff5864-p52bb" node="worker2"
I0918 04:05:53.043798       6 controller.go:167] "Backend successfully reloaded"
I0918 04:05:53.043952       6 controller.go:178] "Initial sync, sleeping for 1 second"
I0918 04:05:53.044349       6 event.go:282] Event(v1.ObjectReference{Kind:"Pod", Namespace:"ingress-nginx", Name:"ingress-nginx-controller-57ffff5864-p52bb", UID:"6b9e8d63-801f-4ac2-8533-8a0164e792bf", APIVersion:"v1", ResourceVersion:"32685", FieldPath:""}): type: 'Normal' reason: 'RELOAD' NGINX reload triggered due to a change in configuration
I0918 05:25:59.272392       6 main.go:101] "successfully validated configuration, accepting" ingress="web-ingress/test-ingress"
I0918 05:25:59.278726       6 store.go:361] "Ignoring ingress because of error while validating ingress class" ingress="test-ingress/web-ingress" error="ingress does not contain a valid IngressClass"
I0918 05:38:54.461751       6 store.go:336] "Ignoring ingress because of error while validating ingress class" ingress="test-ingress/web-ingress" error="ingress does not contain a valid IngressClass"
I0918 05:39:44.049518       6 main.go:101] "successfully validated configuration, accepting" ingress="web-ingress/test-ingress"
I0918 05:39:44.053660       6 store.go:361] "Ignoring ingress because of error while validating ingress class" ingress="test-ingress/web-ingress" error="ingress does not contain a valid IngressClass"

 

그렇다. 원인은 로그에 다 있었다 ㅠㅠ

 

`IngressClass`가 문제란다.

이걸 해결하면 되는데...

$ nano ./04.Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    ingressclass.kubernetes.io/is-default-class: true

spec:
  rules:
  - http:
      paths:
      - path: /test
        pathType: Prefix
        backend:
          service:
            name: web-svc
            port:
              number: 80

 

annotation 한 줄 추가해주면 된다.

 

 

모든 Ingress에 저렇게 입력하기 싫다면,

기본 IngressClass nginx를 수정하면 된다.

 

`ingress-nginx` namespace에 있는 ingressclass를 살펴보면 `nginx` 이름으로 존재하고 있다.

$ kubectl get ingressclasses --namespace=ingress-nginx 

NAME    CONTROLLER             PARAMETERS   AGE
nginx     k8s.io/ingress-nginx     <none>          12h

 

edit 하면 되는데,

막간을 이용해서 tip 하나 추가하자면,

기본적으로 `kubectl edit`를 하게되면 기본 에디터로 `vi`가 실행된다.

 

vi를 싫어하는 나같은 사람들을 위해 에디터 변경을 하는 방법이 있다.

$ export KUBE_EDITOR=nano

 

그리고, 이제 edit를 해보자.

$ kubectl edit ingressclasses nginx --namespace=ingress-nginx
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"networking.k8s.io/v1","kind":"IngressClass","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"controller","app.kubernetes.io/instance":"ingress-nginx","app.kubernetes.io/managed-by":"Helm","app.kubernetes.io/name":"ingress-nginx","app.kubernetes.io/version":"1.0.0","helm.sh/chart":"ingress-nginx-4.0.1"},"name":"nginx"},"spec":{"controller":"k8s.io/ingress-nginx"}}
  creationTimestamp: "2021-09-18T04:05:10Z"
  generation: 1
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/version: 1.0.0
    helm.sh/chart: ingress-nginx-4.0.1
  name: nginx
  resourceVersion: "102271"
  uid: 13fa4354-bb3d-4dee-ae56-5d14600354cb
spec:
  controller: k8s.io/ingress-nginx

 

나머지는 모르겠고 ... 위에 색으로 칠한 부분만 추가되어 있으면 된다.

 

 

문제 해결을 위해 열심히 구글링 하면서 알게된 지식 추가 공유 !

 

- Ingress 생성할 때, 연결하고자 하는 Service가 있는 namespace에 같이 존재해야 한다

  . Ingress Controller는 전체 namespace를 바라보고 있기에 가능하다.

 

- Ingress와 연결되는 Service는 Cluster IP와 매핑이 된다.

  . 그래서 Service는 Nodeport 타입이어도 되고, 아니어도 된다.

 

 

이번에는 여기까지~

반응형

 

오늘 포스팅을 위해

그동안 많은 과정을 거쳐왔나보다 ^^

 

- 오래된 노트북 - 우분투 서버로 만들기 (Ubuntu 20.04 Server)

- Ubuntu 18.04 에서 Python3 편하게 사용하기
- Kubernetes Install (Ubuntu 20.04)
- Kubespray 이용하여 Kubernetes 설치하기
- Vagrant 이미지 업로드 (VirtualBox)
- Vagrant 사용하기 - 기본

- Vagrant 여러 개의 VM 생성하기

 

포스팅으로만 하면 위의 내용 정도뿐이지만,

그 뒤에서 공부하고 시행착오를 겪은 것을 합치면.... 에휴...

멍청하면 손발 뿐만 아니라 온몸이 고생한다더니...

 

 

로컬 환경에서 VM을 이용한 Kubernetes 실습 환경을 갖추는 것이 목표이다.

 

VM 생성도 Vagrant를 이용해서 기본적인 사항은 편하게 할 수 있도록 했고,

Kubernetes 설치 과정은 공부를 위해 직접 수행하는 방식으로 구성했다.

 

즉, Ubuntu 꾸미기(?) 등과 같은 과정은 Skip 하고

공부가 필요한 Kubernetes 설치 과정은 가급적 직접 수행해보자.

 

(물론 Kubespray를 사용하지 않고 정말 쌩으로 해보면 좋겠지만... 어느 정도는 ^^)

 

 

 

0. Host Environment

  - 다음 Spec이 최소사양이라는 말은 아니고, 참고하시라고...

    . CPU: AMD Ryzen 5 3600X

    . RAM: 32GB

    . VGA: Nvidia GeForce RTX 2060

    . OS: Windows 10 Pro

 

 

1. Vagrant 설치

  - https://www.vagrantup.com/

 

 

2. VirtualBox 설치

  - https://www.virtualbox.org/

 

 

3. Vagrant Up

  - 다음 내용의 Vagrantfile을 이용해서 VM을 생성하자

    (개인적인 취향으로 Host의 git-bash 환경에서 작업하는 것을 좋아하기에

     아래 sh 명령어들이 linux 스타일로 되어있다)

 

host$ mkdir k8s-vm
host$ cd k8s-vm
host$ nano Vagrantfile
host$ vagrant up

 

# -*- mode: ruby -*-
# vi: set ft=ruby :

N = 2


Vagrant.configure("2") do |config|


  config.vm.define "w-k8s-master" do |cfg|

    cfg.vm.box = "whatwant/Ubuntu-20.04-Server"
    cfg.vm.box_version = "0.2.0"

    cfg.vm.hostname = "master"
    cfg.vm.network "public_network", ip: "192.168.100.200"

    cfg.vm.provider "virtualbox" do |vb|
      vb.gui = false
      vb.cpus = "2"
      vb.memory = "2048"
    end

    cfg.vm.provision "shell", inline: <<-SHELL
      apt-get update
      apt-get upgrade -y
    SHELL

  end


  (1..N).each do |i|
    config.vm.define "w-k8s-worker#{i}" do |cfg|

      cfg.vm.box = "whatwant/Ubuntu-20.04-Server"
      cfg.vm.box_version = "0.2.0"

      cfg.vm.hostname = "worker#{i}"
      cfg.vm.network "public_network", ip: "192.168.100.20#{i}"

      cfg.vm.provider "virtualbox" do |vb|
        vb.gui = false
        vb.cpus = "1"
        vb.memory = "1280"
      end

      cfg.vm.provision "shell", inline: <<-SHELL
        apt-get update
        apt-get upgrade -y
      SHELL

    end
  end

end

 

  - master 1대, worker 2대 구성으로 했다.

  - VM 이미지는 Ubuntu 20.04 Server 기반으로 미리 살짝 꾸며둔 것을 이용했다.

  - VM의 CPU/RAM 설정은 가급적 최소한의 규격으로 잡아두었다.

  - `vagrant up` 했을 때 종종 실패를 하는데, 여러 번 try하면 결국 된다.

  - IP 설정은 각자의 공유기 셋팅에 따라 수정이 필요하다.

 

 

4. (master) Kubespray 실행 환경 만들기

  - Kubespray는 ansible 기반이기에 그에 따른 환경을 갖춰야 한다.

  - 필요한 package 설치 후 ssh 접근이 가능하도록 키 생성 & 배포를 진행한다.

  - 패스워드는 `vagrant`이다.

 

host$ ssh vagrant@192.168.100.200

master$ sudo apt install ansible python3-argcomplete

master$ ssh-keygen

master$ ssh-copy-id 192.168.100.200

master$ ssh-copy-id 192.168.100.201

master$ ssh-copy-id 192.168.100.202

 

  - ansible에서 접근할 서버 정보들을 입력해놓자

$ sudo nano /etc/ansible/hosts
[all]
master  ansible_ssh_host=192.168.100.200 ip=192.168.100.200 ansible_user=vagrant
worker1 ansible_ssh_host=192.168.100.201 ip=192.168.100.201 ansible_user=vagrant
worker2 ansible_ssh_host=192.168.100.202 ip=192.168.100.202 ansible_user=vagrant

[k8s_master]
master

[k8s_worker]
worker1
worker2

  - 테스트

$ ansible all -m ping

 

 

5. (master/worker) Kubernetes 설치를 위한 환경 설정

  - master/worker 모두 Kubernetes 설치를 위한 환경 설정을 진행해야 한다.

  - swap 공간 사용하지 않도록 하고, 서로 접근이 용이하게 되도록 host 설정을 해주자.

  - ip forward 기능도 활성화 시켜줘야 한다.

 

  - master/worker 접근은 앞에서 했던 것과 마찬가지로 `ssh vagrant@192.168.100.200/201/202` 방식으로...

 

master/worker$ sudo swapoff -a

master/worker$ sudo nano /etc/fstab
# /swap.img   none    swap    sw  0   0

master/worker$ sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

master/worker$ sudo nano /etc/hosts
192.168.100.200 master
192.168.100.201 worker1
192.168.100.202 worker2

 

 

6. (master/worker) Restart

  - 깔끔한 진행을 위해 이 시점에서 모두 restart 진행하고 이후 진행하자!

 

 

7. (master) Kubespray 이요한 Kubernetes 설치

  - 이제 기본환경 준비는 끝났다.

  - Kubespray 설치 준비를 할 차례다.

host$ ssh vagrant@192.168.100.200

master$ cd /srv/install

master$ git clone https://github.com/kubernetes-sigs/kubespray.git

master$ cd kubespray

master$ git checkout v2.16.0

master$ sudo pip install -r requirements.txt

master$ cp -rfp inventory/sample inventory/mycluster

master$ declare -a IPS=(192.168.100.200 192.168.100.201 192.168.100.202)

master$ CONFIG_FILE=inventory/mycluster/hosts.yaml python contrib/inventory_builder/inventory.py ${IPS[@]}

master$ nano ./inventory/mycluster/hosts.yaml

  - 아래와 같이 수정해보자.

all:
  hosts:
    master:
      ansible_host: 192.168.100.200
      ip: 192.168.100.200
      access_ip: 192.168.100.200
    worker1:
      ansible_host: 192.168.100.201
      ip: 192.168.100.201
      access_ip: 192.168.100.201
    worker2:
      ansible_host: 192.168.100.202
      ip: 192.168.100.202
      access_ip: 192.168.100.202
  children:
    kube_control_plane:
      hosts:
        master:
    kube_node:
      hosts:
        worker1:
        worker2:
    etcd:
      hosts:
        master:
    k8s_cluster:
      children:
        kube_control_plane:
        kube_node:
    calico_rr:
      hosts: {}

  - 당연하게도 위의 설정은 각자 IP 환경에 맞게 업데이트

 

master$ nano ./inventory/mycluster/group_vars/k8s_cluster/addons.yml

 

  - addons는 아래 3개 정도만 해보자. (ingress는 나중에 직접 설치할 것이다)

dashboard_enabled: true
helm_enabled: true
metrics_server_enabled: true

 

  - proxy mode도 iptables로 변경해보자

master$ nano ./inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml
# Kube-proxy proxyMode configuration.
# Can be ipvs, iptables
kube_proxy_mode: iptables

 

 

8. (master) execute

  - 이제 정말로 준비는 끝났다. 설치 시작~!!

master$ cd /srv/install/kubespray

master$ ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root cluster.yml

 

 

9. (master) 계정 설정

  - root가 아닌 일반 계정에서 `kubectl` 명령어를 사용하기 위한 설정을 하자

 

master$ mkdir -p $HOME/.kube

master$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

master$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

master$ echo "source <(kubectl completion zsh)" >> ~/.zshrc

master$ source ~/.zshrc

 

 

10. (master) 점검

  - 잘 되었는지 살펴보자.

master$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:6443

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.



master$ kubectl get nodes
NAME    STATUS     ROLES                  AGE   VERSION
node1   Ready      control-plane,master   14m   v1.20.7
node2   NotReady   <none>                 13m   v1.20.7
node3   NotReady   <none>                 13m   v1.20.7

 

 

성공~!!!

반응형

'Dev Tools > Kubernetes' 카테고리의 다른 글

Kubernetes 설치  (0) 2023.04.17
Install `NGINX Ingress Controller` in Kubernetes  (4) 2021.09.18
MinIO StandAlone in Kubernetes  (0) 2021.05.13
Kubespray 이용하여 Kubernetes 설치하기  (4) 2021.05.04
Kubernetes Install (Ubuntu 20.04)  (0) 2020.12.28

MinIO

Amazon S3 서비스를 On-Premise 환경에서 사용할 수 있도록 해주는

최근 많은 인기를 얻고 있는 유명한 Object Storage 프로젝트이다.

 

https://min.io/

 

MinIO | High Performance, Kubernetes Native Object Storage

MinIO's High Performance Object Storage is Open Source, Amazon S3 compatible, Kubernetes Native and is designed for cloud native workloads like AI.

min.io

 

AI 개발환경을 On-Premise에서 구축할 때

사진, 동영상 같은 데이터 또는 컨테이너 이미지와 같은 비정형 데이터를 저장하기 위한 서비스 中

설치도 간편하고 Amazon S3와 호환이 되다보니 MinIO가 아주 유명세를 떨쳤다.

 

 

그래서, 신규 시스템을 구축할 때 스토리지 용도로 MinIO를 선택했는데...

막상 해보니... 쉬운 아이가 아닌 것 같다는....

 

 

 

지금부터 설명할 과정은 다음과 같은 환경에서 진행하였다.

 

- VirtualBox Guest 3개 구성

  . Guest OS : Ubuntu 20.04 Server - 64bit

  . Guest HW : CPU 2 core, MEM 4 GB

 

- Kubernetes : 1 master, 2 worker node 구성

  . 설치 도구 : Kubespray

  . K8s version : 1.20.6

 

 

 

MinIO 설치는 Kubernetes 환경에서 Standalone 방식으로 진행해보고자 한다.

 

참고했던 컨텐츠는 아래와 같다.

 

https://github.com/kubernetes/examples/tree/master/staging/storage/minio

 

kubernetes/examples

Kubernetes application example tutorials. Contribute to kubernetes/examples development by creating an account on GitHub.

github.com

 

 

1. StorageClass

    - 특정 노드의 local storage를 실제 저장공간으로 사용하기 위한 내용으로 작성했다.

    - dynamic provisioning을 위해 volumeBindingMode를 'WaitForFirstComsumer'로 잡았다.

 

 

[ minio-standalone-storageclass.yaml ]

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage

provisioner: kubernetes.io/no-provisioner

volumeBindingMode: WaitForFirstConsumer

 

 

2. PersistentVolume

    - worker node 中 하나인, 'worker2'의 특정 디렉토리를 실제 저장 공간으로 정했다.

 

[ minio-standalone-pv.yaml ]

apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv

spec:
  capacity:
    storage: 1Gi

  accessModes:
  - ReadWriteOnce

  persistentVolumeReclaimPolicy: Retain

  storageClassName: local-storage

  local:
    path: /data/volumes/pv1

  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - worker2

 

 

3. PersistentVolumeClaim

    - 앞에서 선언한 StorageClass, PersistentVolume과 매핑되는 PVC를 작성했다.

 

[ minio-standalone-pvc.yaml ]

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: minio-pv-claim
  labels:
    app: minio-storage-claim

spec:
  accessModes:
    - ReadWriteOnce

  storageClassName: local-storage

  resources:
    requests:
      storage: 1Gi

 

 

4. Deployment

    - MinIO 서비스를 위한 Deployment이며, 당연히 앞에서 선언한 PVC를 사용했다.

 

[ minio-standalone-deployment.yaml ]

apiVersion: apps/v1
kind: Deployment
metadata:
  name: minio-deployment

spec:
  selector:
    matchLabels:
      app: minio

  strategy:
    type: Recreate

  template:
    metadata:
      labels:
        app: minio

    spec:
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: minio-pv-claim

      containers:
      - name: minio
        image: minio/minio:latest
        args:
        - server
        - /storage
        env:
        - name: MINIO_ACCESS_KEY
          value: "minio"
        - name: MINIO_SECRET_KEY
          value: "minio123"
        ports:
        - containerPort: 9000
          hostPort: 9000
        volumeMounts:
        - name: storage
          mountPath: "/storage"

 

 

5. Service

    - MinIO 서비스를 외부로 노출하기 위한 Service를 선언해보았다.

 

[ minio-standalone-service.yaml ]

apiVersion: v1
kind: Service
metadata:
  name: minio-service

spec:
  type: NodePort

  ports:
    - port: 9000
      targetPort: 9000
      nodePort: 30333

  selector:
    app: minio

 

 

[ 결과 ]

여기까지

차례대로 create 하면 MinIO 서비스 웹을 볼 수 있다.

 

MinIO

 

Access Key / Secret Key 값은 Deployment YAML을 보면 확인할 수 있다.

 

 

MinIO

 

 

오른쪽 하단에 있는 "+" 버튼을 통해 bucket도 생성할 수 있고, 파일도 업로드 할 수 있다.

물론 다운로드도 가능한 Storage 웹서비스를 확인할 수 있다.

 

 

반응형

+ Recent posts