Category: Kubernetes

쿠버네티스에 관한 글들의 모음.

Kubernetes API 서버 인증서에 도메인 추가하기

Kubernetes API 서버는 http 를 통해서 쿠버네티스에 대한 연산을 제공해 준다. kubectl 명령어로 실행되는 것들은 모두 API 서버를 거쳐서 이루어진다. 하지만 API 서버는 인증서를 기반으로 통신이 이루어지는데, 이 인증서에 기재된 도메인이나 IP가 아니면 통신이 이루어지지 않는다.

API 서버의 인증서는 SAN 인증서여야 한다. 도메인 리스트를 가지고 있는 SAN 인증서. 현재 API 서버의 인증서 상태는 다음과 같다.

위 apiserver.crt 파일 상태를 보면 SAN 에 이미 도메인과 IP 들이 들어가 있다. 내용을 보면 haproxy2.systemv.local 도메인, 192.168.96.7 IP 가 들어가 있는데 이 서버에서 API 서버와 통신이 가능하다.

만일 추가적으로 도메인, IP 를 추가하고 싶다면 어떻게 해야할까? 이에 대해서 알아본다.

kubeadm-config 업데이트

kubeadm-config 라고 불리는 ConfigMap 을 업데이트 해줘야 한다. 이를 위해서 먼저 기존이 설정을 뽑아내야 하는데 다음과 같이 하면 된다.

파일 내용을 보면 SAN 리스트가 없다. 도메인이나 IP 를 SAN 으로 추가하기 위해서 apiServer 아래에 certSANs 를 추가해 준다. 이미 다른 도메인이 있다면 제거하나 추가할 수도 있다.

위와같이 SAN 에 추가할 도메인, IP를 적어준다.

apiserver.crt 파일 업데이트

기존의 존재하는 apiserver.crt 파일을 백업한다.

kubeadm 을 이용해 새로운 인증서를 생성해 준다.

새로운 인증서가 생성되면서 certSANs 에 설정된 도메인, IP 주소들이 모두 인증서에 업데이트 된다. 이제 새로운 인증서를 가지고 구동되도록 api 서버를 재시작 시켜줘야 한다.

Docker 기반의 경우에는 다음과 같이 하면 된다.

  • docker ps | grep kube-apiserver 명령어로 kube-apiserver 의 컨테이너 ID 를 파악한다.
  • docker kill <containerID> 로 컨테이너를 킬(kill) 한다. 이렇게 하면 api 서버가 재시작 된다.

만약 containerd 를 이용하는 경우에는 다음과 같이 하면 된다.

  • crictl pods | grep kube-apiserver 로 kube-apiserver 의 Pod ID 를 파악한다.
  • crictl stopp <pod-id> 로 pod 를 정지
  • crictl rmp <pod-id> 로 pod 를 제거 합니다. 이렇게하면 다시 Pod 가 재시작 된다.

위와같이 Api 서버가 재시작되면서 새롭게 만들어진 API 서버 인증서를 인식하게 된다.

클러스터 설정 업데이트

마지막으로 클러스터 설정을 업데이트 해줘야 한다.

이렇게 하면 최종적으로 Api 서버에 인증서가 업데이트 된다.

Kubernetes 의 Role Based Access Control(RBAC)

쿠버네티스는 RBAC 기반으로 허가권(Permission) 을 조정하도록 설계 되었다. 그런데, 쿠버네티스는 다음과 같이 네가지의 Role 관련 리소스를 가지고 있다. 그 차이는 다음과 같다.

  1. ClusterRole – 전체 클러스터에 적용하기 위한 역할(Role) 에 할당된 허가권(Permission)
  2. ClusterRoleBinding – 특정 계정(Account) 에 ClusterRole 을 바인딩
  3. Role – 특정 네임스페이스에 적용하기 위한 역할(Role) 에 할당된 허가권(Permission)
  4. RoleBinding – 특정 계정(Account) 에 Role 을 바인딩

RBAC 을 적용하기 위해서는 계정이 필요하다. 이 계정은 쿠버네티스의 사용자를 말하는것이 아닌 쿠버네티스에서 운영되는 자원에 대한 계정을 말한다.

예를들어 ingress-nginx 라는 계정을 생성했다면 이제 이 계정에 ClusterRole 과 Role 을 Binding 을 통해서 ingress-nginx 계정과 연결하는 형식이다.

참고: Role Based Access Control (RBAC)

Istio, Pod CrashLoopBackOff 해결하기

Istio 를 설치하고 Pod 를 생성했는데, 다음과 같이 오류가 발생했다.

istio-init 컨테이너가 오류가 발생한 것을 알 수 있다. Pod 안에 컨테이너가 여러개일 경우에 컨테이너 로그를 봐야하는데 다음과 같이 Pod 에 속한 컨테이너 로그를 볼수 있다.

이 문제는 istio cni 컴포넌트를 함께 설치해주면 된다. 보통 Istio 를 설치할때에 Profile 만 지정하는데, demo 프로파일에 경우에 CNI 를 설치하지 않는다. 다음과 같이 재설치를 해준다.

이렇게 CNI 를 활성화해서 재설치를 하면 문제없이 작동 된다.

문제점

여기서 한가지 문제가 있다. CNI 는 보통 Flannel, Calico 등을 이용하는데, 이것과 별도로 Istio-cni 를 설치하게 되는 것이다. 이왕이면 기존에 있는 것을 활용하는 방안을 고려해야 한다.

Calico 의 경우에 이에 대해서 기술하고 있는 문서가 있으니 참고해서 한번 해볼만 하다.

Istio 설치

Istio 는 쿠버네티스의 Network 레벨의 Mesh 서비스다. 비교하자면 Netflix OSS 에 Ribbon 과 비슷하다고 볼 수 있다.

Istio 설치 방법

Istio 설치 방법은 다양하다. 처음에 Istio 를 시작할때에 가장 헷깔리는 것이 바로 설치 방법이다. 구글에서 검색을 하면 설치방법이 나오지만 읽어보면 제각각인 이유가 다양한 설치 방법 때문이다.

그래서인지 Istio 홈페이지에서 다양한 설치 방법을 적어놨는데 대략 3가지 방법이 많이 쓰인다.

  1. Install with Istioctl
  2. Install with Helm
  3. Install Istio Operator

여기서는 Istoctl 을 이용해 설치하는 법을 다룬다. 이 방법은 다음 문서에 잘 나와 있다.

Download Istioctl

다음과 같이 Istio 를 다운로드 한다.

istio profile

istioctl 은 말그대로 istio 관련 작업을 위한 툴이다. 설치를 할때도 이를 활용할 수 있다.

istio 설치는 미리 정의되어 있는 프로파일을 정의하면 그 프로파일에 맞는 컴포넌트들을 같이 설치해 준다. 미리정의된 프로파일은 다음과 같이 조회가 가능하다.

프로파일의 내용은 대략 다음과 같다.

  • default: 프로덕트 환경에 적합하도록 기본세팅되어 있다.
  • demo: 쇼케이스를 위해서 세팅된 값을 쓴다.
  • minimal: 오진 컨트롤 플레인만 설치된다.
  • empty: 아무것도 디폴로이 되지 않는다. 이것은 커스텀 설정을 위한 베이스 프로파일처럼 사용할 수 있다.

각 프로파일의 내용은 다음과 같이 dump 옵션을 사용해 가능하다.

위 내용을 보면, cni, egressGateway 와 istiodRemote 가 비활성화 되어 있다.

전체설정의 서브셋만 보고 싶다면 –config-path 를 사용하면 가능하다.

프로파일에 차이를 알고 싶다면 다음과 같이 확인할 수 있다.

demo profile 설치

demo 프로파일을 이용해 설치를 진행 한다. istio 문서대로 한번 해보는 것이다.

자동으로 Envoy 사이드카 프록시를 자동으로 주입시키기 위한 네임스페이스에 라벨을 추가해준다.

default 네임스페이스에 라벨링을 해줬다. default 네임스페이스에 드플로이를 해주면 Envoy 사이드카가 자동으로 주입된다.

istio 설치 확인

먼저 네임스페이스를 확인해 보자. 네임스페이스는 istio-system 이 생성된다.

그리고 이제 어떤것이 설치되었는지를 살펴보자.

CRD 도 함께 생성된다. 다음과 같이 확인 가능하다.

문제

이벤트(Events) 를 보면 다음과 같이 오류가 난것을 확인할 수 있다.

쿠버네티스 curl 사용하기

쿠버네티스에서 클러스터내에서 Pod 에 데이터가 잘 나오는지를 확인하는 방법은 CURL 일 것이다. ClusterIP 로 IP 가 할당되면 클러스터내에서 접근이 가능한데 이때에 다음과 같이 사용하면 된다.

curl 을 비롯한 ping, nslookup 도 가능하다.

Calico Metrics 모니터링 하기

Calico 는 쿠버네티스(Kubernetes) 의 CNI 다. 쉽게 말해서 쿠버네티스의 네트워킹을 가능하게 해준다. 설치도 쉽게 할수 있는데, 프로메테우스에서 Calico 모니터링을 하기 위해서는 추가적인 작업이 필요한데 여기에 대해서 알아본다.

calicoctl

calicoctl 을 설치해야 한다. 이 파일은 바이너리이며 wget, curl 명령어를 이용해서 설치가 가능하다. 설치를 한 후에 이것을 사용하기 위해서는 다음과 같이 환경변수를 설정해 준다.

calicoctl 명령어는 다양한 질의를 할 수 있다.

Calico CRD

Calico 설치를 메니페스트로 설치를 하게 되면 CRD 가 생성되면서 CRD 에 정의된 오브젝트가 함께 생성된다.

이것을 언급하는 이유는 Calico 홈페이지에 보면 이에 대한 언급이 많이 되어 있지 않은채, API 를 언급하고 있다. 만일 API 조회를 해봤는데 없다면 CRD 를 살펴보고 찾으면 된다.

Monitor Calico component metrics

Felix configuration

이제 Calico 의 컴포넌트 메트릭을 활성화 해보자. 이를 위해서는 felixconfigurations 의 설정을 먼저 바꿔야 한다. 이를 위해서 calicoctl 명령어를 활용한다.

Creating a service to expose Felix metrics

이제 프로메테우스에서 메트릭 수집을 위한 서비스를 다음과 같이 만든다.

Felix 는 쿠버네티스 WorkerNode 에서 실행되는 CNI 를 말한다. 셀렉터를 보면 k8s-app: calico-node 를 설정하고 있는데, Calico Node 의 Pods 를 지정한 것이다.

또, 나중에 ServiceMonitor 설정을 위해서 Labels 를 잘 설정해줘야 한다.

Typha 설정은 하지 않는다. 50개 노드 이하로 설치를 했기 때문에 Typha 가 없다.

Confirm prometheus metrics port

쿠버네티스는 컨트롤 설정을 하나로 모아 놨다. 이 설정을 보면 여러가지 오브젝트에 대한 내용도 나오는데, 이 오브젝트에 대한 프로메테우스 엔드포인트는 9094로 정의 되어 있다. 이 포트를 이용하면 모든 메트릭의 엔드포이트를 가지고 올 수 있다.

Creating a service to expose kube-controllers metrics

앞에 Felix 는 Node 의 CNI 라고 한다면 이를 제어하는 것이 컨트롤러이다. 이를 위한 서비스를 다음과 같이 생성해 준다.

Calico-kube-controllers 의 Pods 를 찾기 위해서 셀렉터 k8s-app: calico-kube-controllers 지정해 준다. 그리고 ServiceMonitor 에서 찾을 수 있도록 Labels 를 설정해 줬다.

Prometheus ServiceMonitor 생성

나는 프로메테우스를 Operator 로 설치했다. Prometheus-Operator 설치를 할 경우에 메트릭 수집은 ServiceMonitor 를 통해서 이루어진다. 이 ServiceMonitor 는 Prometheus 의 설정을 함께 적용하면서 동작한다. Prometheus 의 Scape 을 ServiceMonitor 가 대신하는 것이라고 생각하면 쉽다.

Felix 를 위한 ServiceMonitor

Felix 를 위한 ServiceMonitor 는 다음과 같다.

셀렉터를 이용해서 Service 의 Felix 를 지정해줬고, 스크랩에서도 Felix 를 인식하도록 서비스 이름을 지정해 줬다.

Calico Kube Controller ServiceMonitor

Calico kube controller 를 위한 ServiceMonitor 는 다음과 같다.

위와같이 한 후에 프로메테우스를 살펴보면 다음과 같이 나온다.

쿠버네티스 secret 파일 저장하기

쿠버네티스의 Secret 은 암호화해서 데이터를 저장하는데, 파일도 저장할 수 있다. 바이너리 파일이던 텍스트 파일이던 모두 base64 인코딩 스트링으로 저장이된다. 이것을 파일로 저장하는 방법에 대해서 간단하게 알아본다.

Prometheus 설정 Secret

Pormetheus 를 오퍼레이터(Operator) 로 설치를 했을 경우에 다음과 같은 Secret 을 볼 수 있다.

data 필드를 보면 prometheus.yaml.gz 파일이름이 보이고 내용이 base64 스트링이 보인다. 이 prometheus.yaml.gz 파일을 받기 위해서는 간단히 bas64 스트링을 디코딩하고 나오는 스트링을 그냥 파일명으로 저장하면 된다.

간단하게 echo “<encoded-value>” | base64 -d prometheus.yaml.gz 으로 보면 된다.

압축을 해제하고 파일을 수정한 후에 다시 압축을 한다. 그리고 이것을 base64 로 인코딩 스트링을 만들면 되는데 다음과 같이 만들 수 있다.

이렇게 하게 되면 Base64 인코딩 스트링 나오는데, Secret 에 데이터부분에 이 스트링을 넣고 편집하면 된다.

쿠버네티스에 프로메테우스(Prometheus) 오퍼레이터 설치하기

프로메테우스(Prometheus)는 모니터링 시스템을 말한다. 프로메테우스는 파일 기반의 타임시리즈(Time-Series) 데이터베이스다. 시스템의 메트릭스들을 수집하기 위해서는 익스포터(Exportor) 를 설치해야 한다. 이외에도 알람을 전달해주는 AlertManager 도 있는데, 전체적인 아키텍쳐는 다음과 같다.

프로메테우스 아키텍쳐

프로메테우스는 쿠버네티스에서도 설치가 가능한데, 이글은 쿠버네티스에 프로메테우스 설치에 대한 글이다.

환경

환경은 다음과 같다.

  • Kubernetes 버전: 1.20
  • Kubernetes Nodes: Master 3개, Worker 3개
  • Prometheus 설치 방법: Helm Operator

설치

프로메테우스(Prometheus) 설치는 매우 다양한데, 검색을 해보면 Helm 을 이용한 방법 그중에서도 오퍼레이터(Operator) 를 이용한 방법이 많이 소개 되어 있다. 여기서도 이 오퍼레이터를 이용한 방법을 사용하고자 한다.

Prometheus Operator 로 검색을 해보면 github 저장소를 찾을 수 있다.

중간에 보면 Prometheus Operator vs kube-prometheus vs community helm chart 가 보인다. 자세히 읽어보면 쿠버네티스에 설치할 수 있는 방법이 세 가지로 나뉜다는 것을 알수 있다.

이중에서 나는 Helm chart 를 이용한 방법을 이용할 생각이다.

노드 레이블 설정

노드에 레이블을 설정하게 되면 쿠버네티스에 앱을 배포할때에 레이블을 지정함으로써 특정 노드에 생성되도록 강제할 수 있다. 프로메테우스 오퍼레이터 설치를 특정 노드에 하기 위해서 레이블을 부여할 생각이다. 대상 노드는 kworker3.systemv.local 노드이며 다음과 같이 레이블을 할당해 줬다.

kworker3.systemv.local 노드에 system.rule=monitoring 레이블이 새겨졌다.

Helm Chart 가지고 오기

Helm 를 이용하면 명령어 한줄로 설치가 되지만 설정을 변경하기 위해서는 챠트(Chart) 를 수정해줘야 한다. 이를 위해서 챠트를 다운받아야만 한다. Helm 챠트는 프로메테우스 커뮤니티에서 관리하고 있다.

많은 챠트가 존재하는데, 여기서 설치 대상은 kube-prometheus-stack 이다.

설정을 하기위해서 프로메테우스 오퍼레이터의 구성을 살펴볼 필요가 있다.

  • Prometheus – 프로메테우스 리소스 정의가 되어 있다. 프로메테우스를 위한 파드(Pod) 의 리플리카(Replica) 갯수, 퍼시스턴스 볼륨 구성등이다. 프로메테이스 오퍼레이터는 파드를 StatefulSet 으로 배포 한다. 그리고 어떤 애플리케이션, 혹은 리소스를 모니터링할 것이지를 지정하는 것인데, 이것은 ServiceMonitor 로 설정이 이루어 진다.
  • ServiceMonitor – 프로메테우스 오퍼레이터는 어노테이션 기반의 서비스 디스커버리를 지원하지 않으며 대신 PodMonitor, ServiceMonitor 를 이용한다. ServiceMonitor는 애플리케이션이나 서비스의 리소스를 모니터링할 것인지를 지정한다. 쿠버네티스의 NodeSelector 처럼 LableSelector 로 서비스의 리소스를 선택할 수 있고, 엔드포인트(EndPoint) 를 통해서 애플리케이션의 메트릭을 수집할 수 있다. ServiceMonitor 는 rule 을 기반으로 Prometheus의 모니터링 대상이 되는 ServiceMonitor를 scan하여 해당 정보를 Secret으로 배포한다. 그리고 이 Secret을 Prometheus StatefulSet에 마운트한다. 이런 방식으로 Prometheus 팟은 자신이 모니터링할 Service가 무엇인지 알 수 있다.
  • Altermanager – 알람 매니저 이다. 프로메테우스 컴포넌트중에 하나다.
  • PodMonitor – 파드에 대한 모니터다. 역시나 LabelSelector 를 통해서 모니터링하고자 하는 파드를 지정할 수 있다.

위 내용을 잘 알야하는 이유는 kube-prometheus-stack 디렉토리에 values.yaml 파일에 구조와 연관이 있다.

values.yaml 파일 편집

프로메테우스 오퍼레이터를 Helm 으로 설치할 때에는 values.yaml 파일의 설정을 참고하도록 되어 있다. values.yaml 에는 altermanager, Grafana, Prometheus 등에 대한 설정 값들이 들어가 있다. 앞에서 특정 노드에 배포하도록 하기 위해서 worker3.systemv.local 노드에 레이블링을 해줬기 때문에 이들 컴포넌트의 NodeSeletor 를 지정해 줘야 한다.

Grafana, Altermanager, Prometheus 의 파드들은 system.rule=monitoring 레이블링 된 노드에만 설치되도록 해뒀다.

Node Exportor 는 system.rule=monitoring 레이블링을 할당하지 않는다. 이들은 노드마다 작동되어야 하기 때문이다.

Helm 설치

이제 설치를 해야 하는데, 설치하기 앞서 의존성 챠트를 업데이트 해야 한다.

이제 다음과 같이 설치를 실행해 준다.

확인

이제 확인을 해보자.

이렇게 설치가 된것으로 보이지만, 사실 프로메테우스의 오퍼레이터는 CRD 를 이용해 리소스를 생성하였기 때문에 이를 알아야 한다. CRD 를 포함한 monitoring 네임스페이스에 모든 리소스를 보기 위해서 다음과 같이 할 수 있다.

이를 통해 확인할 수 있는 CRD 예로 ServiceMonitor, Prometheus 등을 확인해 볼 수 있다.

필자는 Metallb 를 이용해서 LoadBalancer 를 사용할 수 있기 때문에 grafana, prometheus 서비스에 대해서 타입을 ClusterIP 를 LoadBalancer 로 변경해 외부접속이 가능하도록 할 수 있다.

Metallb 에 의해서 EXTERNAL-IP 에 외부접속 IP 가 할당 되었다.

Ingress Nginx

인그레스(Ingress) 는 쿠버네티스에 설치하는 클러스터 내의 서비스에 대한 외부 접근을 관리하는 API 오브젝트이며, 일반적으로 HTTP를 관리한다. 인그레스를 위해서는 인그레스 오브젝트를 설치해야 하는데, 이를 구현한 것들이 꽤 있지만 nginx 가 대표적이다.

여기서는 Ingress-Nginx 에 대해서 간단히 알아 본다.

설치전 고려사항

첫째로 일단 쿠버네티스에 서비스(Service) 에 고려 해야 한다. 쿠버네티스의 서비스는 클러스터내에 접속지점을 생성해 준다. ClusterIP, LoadBalancer, NodePort 세 가지의 타입이 존재한다. 문제는 LoadBalancer 타입인데, 이 타입을 지정해주면 EXTERNAL-IP 가 할당되어야 하지만 일반적인 환경에서는 할당되지 않는다.

LoadBalancer 는 클라우드 서비스 제공 사업자를 위한 것으로 AWS, GCP, Azure 클라우드에서 제공하는 로드밸런서를 위한 것이다. 그래서 일반적인 베어메탈(Bare Metal) 이나 VM 환경(VMware, VirtualBox, KVM) 에서 쿠버네티스를 구성한 상태에서 LoadBalancer 를 사용하게 되면 EXTERNAL-IP 할당되지 않는다.

이렇게 하면 외부에서 접속이 되지 않는다. 이 접속은 클러스터내에 파드(Pod) 에서 호출할 수 있지만 외부에서는 호출이 되지 않는다.

그래서 베어메탈이나 가상환경에서 쿠버네티스에서 LoadBalancer 를 사용할 수 있도록 해주는 Metallb 을 이용했다. 이를 이용하면 서비스 타입을 LoadBalancer 로 지정했을 경우, EXTERNAL-IP 가 할당돼 외부에서 접속이 가능해 진다.

두번째로 ingress-nginx 를 Helm 으로 설치하지 말아야 한다. 현재 Helm 저장소에 올라온 ingress-nginx 는 api 버전이 과거에 버전이다. v1beta 버전으로 되어 있는데, 필자의 쿠버네티스에서는 오래된 버전으로 인식된다.

이를 해결하기 위해서는 github 저장소에 baremetal 버전에 deploy.yaml 파일을 이용해야 한다.

설치

먼저 ingress-nginx 의 github 에 접속해 baremetal 버전을 다운로드 받는다.

이 deploy.yaml 은 baremetal 버전인데, 여기의 서비스 타입은 NodePort 로 되어 있다. 필자는 앞에서도 말했지만 Metallb 를 설치했기 때문에 LoadBalancer 타입으로 변경을 해줘야 한다. deploy.yaml 파일을 열어서 바꿔 준다.

서비스 타입을 바꿨다면 이제 설치를 해 준다.

이 방법으로 설치를 하게 되면 다음과 같은 특징을 갖게 된다.

  • ingress-nginx 네임스페이스가 생성 된다.
  • LoadBalancer 타입이며, Metallb 으로 인해 EXTERNAL-IP 가 할당 된다.
  • apiVersion 이 networking.k8s.io/v1 최신 버전을 지원 한다.

LoadBalancer 에 EXTERNAL-IP 에 외부 접속을 하기 위한 IP가 할당되어 있다.

예제

예제는 springboot 를 이용한 서비스를 배포하고 ingress 를 통해서 접속해 본다. 이 예제는 하나의 서비스에 대한 것이다.

먼저 Deployment, Service 를 다음과 같이 작성 한다.

정상적으로 생성이 되었다. 이제 이것을 인그래스와 연결을 해줘야 한다. 인그래스에서 URI 가 /springboot 이면 지금 배포한 springboot 의 메시지가 화면 표시되도록 했다.

직접해보면 위와같이 오류가 발생한다. 이는 보안 관련 쪽에 문제가 있는 것으로 보이는데, 아마도 TLS 설정에 문제가 있기 때문인 것으로 추정 된다. 이를 해결하기 위해서는 webhook 설정을 삭제해주면 된다.

그리고 다시 한번 ingress-springboot.yaml 파일을 적용해주면 인그래스가 생성 된다.

/springboot URI 는 springboot-service 백엔드로 연결이 되어 있다걸 확인할 수 있다. 이제 인그레스 서비스에 LoadBalancer 의 외부 접속 IP 로 접속을 시도해 보자.

위와같이 인그레스가 정상적으로 동작함을 알 수 있다.

정리

지금까지의 예제는 쿠버네티스 인그레스 문서의 첫번째 다이어그램과 정확하게 같은 것이다.

단일 서비스에 인그레스 적용 다이어그램

클라이언트가 인그레스 로드 밸런서로 접속이 가능해야 했기 때문에 Metallb 을 이용해서 외부접속 IP를 할당해 주도록 설정을 했다.

인그레스 서비스는 설치할때 한번 생성되어지고 이것을 통해서 뒤에 서비스들과 연결이 되어지는데, 이 백엔드 서비스들에 어떻게 연결을 할 것이지에 대한 설정은 인그레스 컨트롤러에 의해서 결정되게 된다.

Metallb 설치하기

쿠버네티스(Kubernetes) 의 서비스(Service) 에 타입에는 Loadbalancer, NodePort 등을 지원한다. 문제는 Loadbalancer 는 클라우드(Cloud) 서비스 사업자를 위한 것으로 AWS, GCP, Azure 에서 제공하는 Loadbalancer 를 위한 것이다.

그런데, 많은 쿠버네티스의 사례를 살펴보면 Loadbalancer 를 사용한 사례가 아주 많다. 그래서 굳이 클라우드 서비스 사업자가 아니라고 하더라도 Loadbalancer 를 사용할 수 있도록 해보자해서 만들어진게 바로 Metallb 이다.

필자는 KVM 리눅스 가상화에 쿠버네티스를 설치했다. KVM 가상 시스템의 게스트 OS 들은 브릿지 네트워크 모드로 이기 때문에 필자의 공유기에서 자동으로 아이피를 할당 받거나, 공유기의 대역에 IP를 고정으로 사용하기도 한다. 필자의 공유기는 192.168.96.0/20 대역폭을 사용하도록 세팅을 해놨기 때문에 할당 가능한 IP는 차고도 넘친다.

Metalb 는 이렇게 외부에서 접속이 가능한 아이피 대역을 할당해 사용한다.

설치

설치를 위해서 필요한게 있는데, CNI 가 먼저 있어야 한다. Flannel, Calico 와 같은 CNI 가 설치가 먼저 되어 있어야 한다. 설치는 설치를 위한 메니페스토 파일을 이용한다.

namespace.yaml 은 그냥 네임스페이스를 만들도록 되어 있어서 명령어로도 가능하다.

이렇게 하면 설치는 되지만 아직 동작하지는 않는데, Metallb 에서 사용할 외부 아이피나 운영 모드등을 설정해줘야 하는데, 이는 ConfigMap 를 이용해 다음과 같이 설정해 줘야 한다.

위와같이 Metal Loadbalancer 에서 사용할 외부 주소 IP 주소 대역을 할당해 준다.

또, 이제 Metallb 의 컴포넌트의 통신을 보호하기 위해서 Secret 를 다음과 같이 생성해 준다.

Ingress-nginx 설치

테스트를 위해서 Ingress-nginx 를 설치해 본다. Ingress-nginx 를 설치하게되면 서비스에 Loadbalancer 타입으로 설치가 되는데, EXTERNAL-IP 가 Metallb 에서 할당해준 IP가 할당이 된다.

EXTERNAL-IP 에 할당한 IP 로 웹 접속을 하게되면 nginx 가 나오게 된다.