쿠버네티스 기본 설정에서는 LoadBalancer
타입의 서비스가 외부 IP를 할당받지 못한다.
이를 해결하기 위해 MetalLB를 설치하면, 클러스터 외부에서 접근할 수 있도록 외부 IP를 할당할 수 있다.
MetalLB는 두 가지 모드로 동작:
좀 더 자세한 내용은 공식 페이지에서 확인이 가능하다. 참고로 본 핸즈온에서는 Layer 2 모드로 진행을 한다.
아래에 두 방법이 있으면 본 포스팅에서는 Manifest 방식 으로 진행을 한다.
$ kubectl edit configmap -n kube-system kube-proxy
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true # 해당 구문을 false -> true 로 변경
위 또는 아래의 방법으로 진행한다.
$ kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
$ kubectl apply -f - -n kube-system
$ kubectl get configmap kube-proxy -n kube-system -o yaml | grep strictARP
strictARP: true
설정을 제대로 했는지 확인을 위해 위 명령어를 입력하여 확인한다.
$ kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml
최신 버전 확인은 공식 리포지토리에서 확인이 가능하다.
$ helm repo add metallb https://metallb.github.io/metallb
$ helm repo update
$ helm install metallb metallb/metallb
$ kubectl get all -n metallb-system
NAME READY STATUS RESTARTS AGE
pod/controller-75447b664c-mm2mp 1/1 Running 1 (10m ago) 15h
pod/speaker-gswdj 1/1 Running 2 (10m ago) 15h
pod/speaker-mqhbg 1/1 Running 2 (10m ago) 15h
pod/speaker-s62qj 1/1 Running 2 (9m50s ago) 15h
pod/speaker-wtfld 1/1 Running 2 (9m25s ago) 15h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/webhook-service ClusterIP 10.105.31.106 <none> 443/TCP 15h
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/speaker 4 4 4 4 4 kubernetes.io/os=linux 15h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 1/1 1 1 15h
NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-75447b664c 1 1 1 15h
설치가 완료되면 metallb-system
네임스페이스에서 위와 같이 metallb
관련 리소스들이 생성이 된다.
MetalLB가 서비스에 할당할 외부 IP 대역을 지정해야 한다.
클러스터에서 사용할 IP 주소 범위를 정한 후, 아래 설정을 적용하면 된다.
본 포스팅에서는 신버전으로 진행을 하였다.
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
cp-k8s Ready control-plane 12d v1.30.0 192.168.1.10 <none> Ubuntu 22.04.2 LTS 5.19.0-28-generic containerd://1.6.31
w1-k8s Ready <none> 12d v1.30.0 192.168.1.101 <none> Ubuntu 22.04.2 LTS 5.19.0-28-generic containerd://1.6.31
w2-k8s Ready <none> 12d v1.30.0 192.168.1.102 <none> Ubuntu 22.04.2 LTS 5.19.0-28-generic containerd://1.6.31
w3-k8s Ready <none> 12d v1.30.0 192.168.1.103 <none> Ubuntu 22.04.2 LTS 5.19.0-28-generic containerd://1.6.31
참고로 작성자는 192.168.1.X 대역의 IP 대역의 클러스터를 구성하였다.
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default-pool
protocol: layer2
addresses:
- 192.168.1.100-192.168.1.200 # 사용할 외부 IP 대역
$ kubectl apply -f metallb-config.yaml
kubectl
로 적용을 한다.
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: my-ip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.100-192.168.1.200 # 사용할 외부 IP 대역
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: my-l2-adv
namespace: metallb-system
spec:
ipAddressPools:
- my-ip-pool
$ kubectl apply -f metallb-ip-pool.yaml
kubectl
로 적용을 한다.
주의: addresses
에 설정한 IP 대역은 클러스터의 서브넷과 겹치지 않도록 설정해야 해.
예를 들어, 쿠버네티스 서비스 CIDR(예: 10.96.0.0/12
) 또는 Pod CIDR(예: 10.244.0.0/16
)과 겹치지 않도록 해야한다.
# delpoyment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: np-deployment
spec:
replicas: 2
selector:
matchLabels:
app: np-pods
template:
metadata:
labels:
app: np-pods
spec:
containers:
- name: np-pods
image: sysnet4admin/echo-hname
ports:
- containerPort: 80
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: np-svc
spec:
selector:
app: np-pods
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
$ kubectl create -f delpoyment.yaml
$ kubectl create -f service.yaml
kubectl
로 적용을 한다.
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/np-deployment-c75bc98fb-fz6sn 1/1 Running 0 8m41s
pod/np-deployment-c75bc98fb-n6zdb 1/1 Running 0 8m42s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
service/np-svc LoadBalancer 10.101.225.112 192.168.1.100 80:30908/TCP 8m38s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/np-deployment 2/2 2 2 8m42s
NAME DESIRED CURRENT READY AGE
replicaset.apps/np-deployment-c75bc98fb 2 2 2 8m42s
배포가 완료 되었다면 위와 같이 확인할 수 있으며, MetalLB 를 구성하였기에 EXTERNAL-IP
에는 지정한 대역의 IP 가 확인이 될 것이다.
$ curl 192.168.1.100
np-deployment-c75bc98fb-n6zdb
$ curl 192.168.1.100
np-deployment-c75bc98fb-n6zdb
$ curl 192.168.1.100
np-deployment-c75bc98fb-fz6sn
192.168.1.100 IP 로 접근 시 각 각의 Pod 로 접근이 되는 것을 확인할 수 있었다.
참고
https://metallb.io/concepts/
https://mydevjourney.tistory.com/96