Jenkins로 CI/CD를 태우기 위해 원격서버(k8s)를 준비하고 먼저 다음과 같은 과정을 선행
- Deployment 배포
- Service 배포
위 서비스 배포시 아래와 같은 yaml파일로 진행
- service.yaml 파일
apiVersion: v1
kind: Service
metadata:
name: springboot-service
spec:
selector:
app: springboot
ports:
- protocol: TCP
port: 8080 # 외부에서 접근할 포트
targetPort: 8080 # Pod 내 컨테이너의 포트
nodePort: 30061 # NodePort를 유효 범위 내로 설정
type: NodePort
# type: LoadBalancer
- deployment.yaml 파일
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-deployment
spec:
replicas: 3
selector:
matchLabels:
app: springboot
template:
metadata:
labels:
app: springboot
spec:
containers:
- name: springboot
image: iiblackcode/springboot-6060:latest
ports:
- containerPort: 8080
서비스를 NodePort Type으로 배포했기 때문에 서비스 주소가
노드주소+포트
가 되었고 master노드에서 노드 주소를 조회해서 curl을 날려보았다.
master@master:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
springboot-deployment-576d94d7fd-j4w4s 1/1 Running 1 (33m ago) 16h 10.244.1.27 node2 <none> <none>
springboot-deployment-576d94d7fd-p9dmt 1/1 Running 1 (33m ago) 16h 10.244.1.28 node2 <none> <none>
springboot-deployment-576d94d7fd-x48v5 1/1 Running 1 (33m ago) 16h 10.244.2.23 node1 <none> <none>
master@master:~$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready control-plane 66d v1.29.5 10.0.0.4 <none> Ubuntu 20.04.6 LTS 5.15.0-1067-azure containerd://1.7.18
node1 Ready <none> 66d v1.29.5 10.0.1.4 <none> Ubuntu 20.04.6 LTS 5.15.0-1064-azure containerd://1.6.31
node2 Ready <none> 66d v1.29.5 10.0.2.4 <none> Ubuntu 20.04.6 LTS 5.15.0-1064-azure containerd://1.6.31
curll 명령어 날림
master@master:~$ curl 10.0.1.4:30061
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>SB Admin 2 - Dashboard</title>
결과는 성공적이였다. 즉 Nodeport타입으로 배포하게 되면 서비스의 포트번호를 통해 배포된 노드의 내부 ip로 배포된다.
다음 서비스 타입을 LoadBalancer로 변경 후 배포테스트를 진행하였다.
- service.yaml 파일 참고
apiVersion: v1
kind: Service
metadata:
name: springboot-service
spec:
selector:
app: springboot
ports:
- protocol: TCP
port: 8080 # 외부에서 접근할 포트
targetPort: 8080 # Pod 내 컨테이너의 포트
nodePort: 30061 # NodePort를 유효 범위 내로 설정
type: LoadBalancer
# type: NodePort
다음과 같은 문제가 발생하였다.
master@master:~/web$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 66d <none>
springboot-service LoadBalancer 10.105.231.9 <pending> 8080:30061/TCP 7m1s app=springboot
배포한 서비스(springboot-service)의 EXTERNAL-IP가
검색해보니 온프렘 환경에서 kubernetes가 LoadBalancer를 사용하기 위해서 MetalLB
설치가 필요하다고 한다.
따라서 다음과 같은 과정으로 MetalLB설치하는 과정을 기술 해 본다.
MetalLB 설치
1. ARP 모드를 활성화
# 명령어 실행
kubectl edit configmap -n kube-system kube-proxy
# 설정
ipvs:
strictARP: true
2. Manifast로 설치
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/metallb.yaml
3. configmap yaml 생성
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses: # 각 노드에 할당된 subnet의 범위를 지정
- 10.0.0.240-10.0.0.250
- 10.0.1.240-10.0.1.250
- 10.0.2.240-10.0.2.250
4. service.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot-service
spec:
selector:
app: springboot
ports:
- protocol: TCP
port: 8080 # 외부에서 접근할 포트
targetPort: 8080 # Pod 내 컨테이너의 포트
nodePort: 30061 # NodePort를 유효 범위 내로 설정
type: LoadBalancer
# type: NodePort
5. deployment.yaml 파일
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-deployment
spec:
replicas: 3
selector:
matchLabels:
app: springboot
template:
metadata:
labels:
app: springboot
spec:
containers:
- name: springboot
image: iiblackcode/springboot-6060:latest
ports:
- containerPort: 8080
service 및 node ip 조회
master@master:~/web$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 66d
springboot-service LoadBalancer 10.105.172.46 10.0.0.240 8080:30061/TCP 4m54s
master@master:~/web$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready control-plane 66d v1.29.5 10.0.0.4 <none> Ubuntu 20.04.6 LTS 5.15.0-1067-azure containerd://1.7.18
node1 Ready <none> 66d v1.29.5 10.0.1.4 <none> Ubuntu 20.04.6 LTS 5.15.0-1064-azure containerd://1.6.31
node2 Ready <none> 66d v1.29.5 10.0.2.4 <none> Ubuntu 20.04.6 LTS 5.15.0-1064-azure containerd://1.6.31
문제는 LoadBalancer 타입이였다. 온프렘에서는 따로 LoadBalancer을 위한 조취가 필요했는데 해당 플러그인이 없어 Service에서 EXTERNAL-IP을 할당받지 못하고 있었다.
마지막으로 master노드의 외부 public ip를 통해 서비스에 할당된 포트로 접근을 시도 해 보았다.
정상적으로 배포된 서비스가 확인된다.