우당탕탕! 쿠버네티스 설치기

이지훈 · 원프레딕트 백엔드 엔지니어
February 06, 2024

여정(?) 의 시작

팀에서 ‘백엔드에서도 인프라를 좀 더 자세하게 알고 있는 분이 계시면 좋겠습니다.’ 라는 한 마디에 자원하게 되었다.

평소에 인프라에 관심도가 높았고(높기만 하다 정말로) 언젠가는 쿠버네티스로 인프라를 구축해 보면 좋겠다는 생각을 마음 한구석에 간직하고 있었기 때문이다.

호기롭게 자원한 것과는 별개로 실제로 아는 게 별로 없었다. 쿠버네티스가 더 이상 도커 런타임과 도커 엔진을 지원하지 않는다는 것, 가상 머신과 다르게 비종속적으로 의존관계 없이 어플리케이션이 구동될 수 있어서 많은 관련자의 선택을 받고 있다는 것 정도였다.

쿠버네티스는 뭘까?

쿠버네티스(Kubernetes)는 컨테이너화된 애플리케이션을 자동으로 배포, 스케일링 및 관리해 주는 오픈소스 플랫폼이다. 대규모의 컨테이너화된 환경을 효과적으로 관리하도록 설계되어 있으며 클라우드 네이티브하게 사용자 앱을 개발 및 운영할 수 있는 플랫폼이다. 이는 원래 구글에서 개발되었으며, 현재는 Cloud Native Computing Foundation에서 관리하고 있다고 한다.

쿠버네티스의 주요 기능

  • 서비스 디스커버리 및 로드 밸런싱: DNS 이름 또는 자체 IP 주소를 사용하여 서비스를 찾을 수 있다. 트래픽이 많아질 경우, 쿠버네티스는 로드 밸런싱과 분산을 통해 트래픽을 관리할 수 있다.
  • 스토리지 오케스트레이션: 로컬 시스템, 공용 클라우드 제공자의 스토리지 시스템, 네트워크 파일 시스템 등을 자동으로 마운트할 수 있다.
  • 자동화된 롤아웃 및 롤백: 애플리케이션의 원하는 상태를 서술하고, 현재 상태를 원하는 상태로 변경하는 방법을 제어할 수 있다. 예를 들어, 애플리케이션을 배포하고 새 버전으로 업데이트하는 경우에 자동으로 롤백하는 것이 가능하다.
  • 자동화된 빈 패킹: 리소스가 필요한 컨테이너를 클러스터 내의 노드에 자동으로 배치할 수 있습니다. 이는 리소스를 보다 효율적으로 사용하면서, 애플리케이션의 가용성을 유지할 수 있게 해준다.
  • 셀프힐링: 실패(혹은 장애)한 컨테이너를 재시작하고, 노드가 정상이 아닌 경우에는 컨테이너를 다른 노드에 재배치하며, 사용자가 정의한 헬스 체크에 응답하지 않는 컨테이너를 교체하고, 서비스를 클라이언트에게 광고하기 전에 준비가 되었는지 확인한다.
  • 시크릿 및 구성 관리: 암호, OAuth 토큰, SSH 키 등의 민감한 정보를 저장하고 관리할 수 있으며, 이를 컨테이너에 안전하게 배포할 수 있다.

쿠버네티스 설치하기

쿠버네티스에 대해서 간략(?)하게 알아보았으니 이제 쿠버네티스의 문을 두드려보기로 하자.

  • 설치 환경
    • MacBook M2 pro
    • MacOS sonoma 14.2.1

HA(high availability) 환경을 구성할 것은 아니기 때문에 minikube 로 찍먹만 해보기로 하자.

https://minikube.sigs.k8s.io/docs/start/ 로 접속하면 설치법을 알 수 있다.

(사실 난 홈브류로 깔았다.ㅋㅋㅋ)

설치가 끝났으면 minikube start 와 minikube status 로 설치결과를 확인하자

Postgres 구동 하기

가장 만만한 것 중에 하나가 db 서버이니 여기서는 postgres 서버를 쿠버네티스로 구동해보자.

우선 구동에 필요한 yaml 파일들이 있어야 할 것이다.

postgres-deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:latest
        env:
          - name: POSTGRES_USER
            value: root
          - name : POSTGRES_PASSWORD
            value: test1234
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 5432

postgres-service.yml

apiVersion: v1
kind: Service
metadata:
  name: postgres-service
spec:
  selector:
    app: postgres
  ports:
  - port: 30000
  type: NodePort

로컬에서 로컬의 쿠버네티스 노드로 접속하기 위해서는 service type 을 NodePort 로 지정하고 이 때 사용할 수 있는 포트는 30000-32767 이라고 한다.

설정파일도 완벽하다. 이젠 안될리가 없다! 노드포트를 30000번으로 지정했으니 당연히 되는거다.

minikube_ip_psql_conn 이미지

어라라…?

mococo_question 이미지

kubectl_get_pod_only 이미지

뭐하고 있니….pod 랑 service 올려야지…

kubectl_apply_get_pod_get_svc 이미지

이번엔 분명히 될 것이다!

psql_fourth_try 이미지

mococo_tears 이미지

뭣 때문에 접속이 안되는 거냐고오!

구글형한테 이것저것 물어보며 꽤나 긴 시간을 삽질한 결과 minikube 도 log 가 있고 이를 볼 수 있는 방법을 찾았다.

minikube Log 확인

log 를 파일로 추출해보자.

minikube logs --file=[원하는 경로]/[원하는 파일명].txt

log 를 볼 때 드륵드륵 마우스 휠을 내리려는 습관이 있는데 조금만 참고 차분히 살펴보다 err 부분을 발견했다.

I0130 09:03:27.557167   10329 network_create.go:284  error running [docker network inspect minikube]: docker network inspect minikube: exit status 1
stdout:
[]

stderr:
Error response from daemon: network minikube not found
I0130 09:03:27.557179   10329 network_create.go:286  output of [docker network inspect minikube]: -- stdout --
[]

-- /stdout --
** stderr **
Error response from daemon: network minikube not found

** /stderr **

docker 의 minikube 라는 네트워크를 찾을 수 없단 얘기다. 그렇지! 내가 생성하지 않았으니까!

생성 하면 접속 되겠지!

docker_network_create_minikube 이미지

??? : 응 아니야. 접속 불가.

이보시오. 도커 양반 이게 어찌 된 일이오?!

이미 생성되어 있는 minikube network 를 Minikube 가 찾지 못하고 있다.

qemu 설치하기

요즘은 괴롭혀도 양심의 가책을 느끼지 않을 만한 대상이 많다.

예를 들면 GPT 3.5 라든가 GPT 4.0 이라든가…

한참을 그렇게 ChatGPT 와 뤼튼을 괴롭히며 도돌이표 같은 대화를 하다가 구글형 까지 불렀다.

그러다 결국 발견한 것이다. 신의 은총을!

How to Setup Minikube on MAC M1/M2

이미 생성되어 있는 minikube network 를 Minikube 가 못찾는 현상은 Backlog 로 남겨놓은뒤

minikube 의 네트워크를 살리기 위해 은혜로우신 인도데브옵스형님의 포스팅에 가이드를 따라 진행한다.

brew_install_qemu 이미지

qemu 설치

brew_install_socket_vmnet 이미지

socket_vmnet 설치

brew_tap_homebrew 이미지

homebrew/services 기능을 Homebrew에 추가

minikube_reinstall 이미지

혹시 몰라서 minikube 도 재설치

minikube_start_qemu 이미지

minikube 를 구동하면서 가상머신 드라이버는 먼저 설치한 qemu 로 지정하고 네트워크를 socket_vmnet 으로 설정해서 qemu 가 minikube 의 가상머신 네트워크에 직접 연결하도록 해준다.

stone_bridge 이미지

돌다리도 두드리고 건너야지. 핑테스트도 진행

kubectl_re_apply_pod_svc 이미지

pod 와 service 생성

두근두근..과연 될 것인가….

sql_fifth_try 이미지

접속 불가!

로그도 확인했고 드라이버도 바꾸어주었는데…이제 의심갈만한건 postgres 설정 파일 뿐이다.

친절하신 인공지능들을 또 괴롭혀 본다.

chatgpt_nodeport 이미지

postgres-service.yml 파일을 인공지능이 알려준 대로 수정한다.

apiVersion: v1
kind: Service
metadata:
  name: postgres-service
spec:
  selector:
    app: postgres
  ports:
  - protocol: TCP
    port: 5432  // 30000 으로 지정되어 있던 것을 postgres 포트로 변경
    targetPort: 5432 // pod 내의 포트, 서비스가 트래픽을 전달하는 대상의 포트
    nodePort: 30000 // NodePort 서비스 타입을 사용할 때 쿠버네티스 클러스터 외부 접근가능 포트
  type: NodePort

conn_success 이미지

접속 성공!

mococo_happy 이미지

마무리

이번 포스팅은 이걸로 마무리…..

아! 잠깐! 우리는 Backlog 하나를 남겨두었다.

이를 해결하기 위해 다시 log 를 살펴보자.

I0130 09:03:27.557167   10329 network_create.go:284] error running [docker network inspect minikube]: docker network inspect minikube: exit status 1
stdout:
[]

stderr:
Error response from daemon: network minikube not found
I0130 09:03:27.557179   10329 network_create.go:286] output of [docker network inspect minikube]: -- stdout --
[]

-- /stdout --
** stderr **
Error response from daemon: network minikube not found

** /stderr **

이부분 바로 뒤에 아래와 같은 로그를 확인할 수 있다.

I0131 15:14:07.594844    7033 cli_runner.go:164] Run: docker network inspect bridge --format "{"Name": "{{.Name}}","Driver": "{{.Driver}}","Subnet": "{{range .IPAM.Config}}{{.Subnet}}{{end}}","Gateway": "{{range .IPAM.Config}}{{.Gateway}}{{end}}","MTU": {{if (index .Options "com.docker.network.driver.mtu")}}{{(index .Options "com.docker.network.driver.mtu")}}{{else}}0{{end}}, "ContainerIPs": [{{range $k,$v := .Containers }}"{{$v.IPv4Address}}",{{end}}]}"
I0131 15:14:07.634053    7033 network.go:209] using free private subnet 192.168.49.0/24: &{IP:192.168.49.0 Netmask:255.255.255.0 Prefix:24 CIDR:192.168.49.0/24 Gateway:192.168.49.1 ClientMin:192.168.49.2 ClientMax:192.168.49.254 Broadcast:192.168.49.255 IsPrivate:true Interface:{IfaceName: IfaceIPv4: IfaceMTU:0 IfaceMAC:} reservation:0x140023f4650}
I0131 15:14:07.634071    7033 network_create.go:124] attempt to create docker network minikube 192.168.49.0/24 with gateway 192.168.49.1 and MTU of 65535 ...
I0131 15:14:07.634109    7033 cli_runner.go:164] Run: docker network create --driver=bridge --subnet=192.168.49.0/24 --gateway=192.168.49.1 -o --ip-masq -o --icc -o com.docker.network.driver.mtu=65535 --label=created_by.minikube.sigs.k8s.io=true --label=name.minikube.sigs.k8s.io=minikube minikube
I0131 15:14:07.717698    7033 network_create.go:108] docker network minikube 192.168.49.0/24 created
I0131 15:14:07.717721    7033 kic.go:121] calculated static IP "192.168.49.2" for the "minikube" container

대충 로그를 해석해보면 ‘minikube 라는 도커 네트워크를 찾았는데 없어서 내가 만들었어.’ 라는 뜻이다.

그렇다. 실제로는 qemu 없이 기본 설정만으로도 분명 네트워킹이 이루어져야할 거 처럼 보인다.

대체 원인이 무엇일까? 내가 돌아다녔던 흔적들을 다시 살펴보았고

qemu 설치 방법을 소개했던 블로그 포스팅의 마지막 줄을 보면

All other setups like Docker, Podman, and Virtualbox run into some sort of issue.

MacOS 에서 도커,파드맨, 그리고 버츄얼박스는 실행하는데 제약이 있다는 얘기를 하고 있고

또 다른 국내 포스팅을 돌아다니다 스택오버플로우에서도 같은 의견을 찾았다는 흔적도 발견했다.

This is a known issue, Docker Desktop networking doesn't support ports. You will have to use minikube tunnel.

어떤 제약이 있는지 그 제약을 어떻게 확인할 수 있는지는 시간을 더 많이 들여봐야겠지만 이 포스팅의 목적과는 조금 방향이 다르기에 여기서 찐 마무리 하겠다.

원프레딕트는 더 나은 제품을 고민하며 기술적인 문제를 함께 풀어낼 동료를 찾고 있습니다.
자세한 내용은 채용 사이트를 참고해 주세요.