Legacy Engineering Note · 기존 기술 블로그에서 선별 이관한 기록입니다. 작성 당시 환경과 버전을 기준으로 합니다.
Jenkins로 CI/CD를 태우기 위해 원격서버(k8s)를 준비하고 먼저 다음과 같은 과정을 선행
- Deployment 배포
- Service 배포
위 서비스 배포시 아래와 같은 yaml파일로 진행
- service.yaml 파일
shellapiVersion: 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 파일
shellapiVersion: 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을 날려보았다.
shellmaster@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 명령어 날림
shellmaster@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 파일 참고
shellapiVersion: 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
다음과 같은 문제가 발생하였다.
shellmaster@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가 <pending>로 외부에서 접근이 되지않았다.
검색해보니 온프렘 환경에서 kubernetes가 LoadBalancer를 사용하기 위해서 MetalLB설치가 필요하다고 한다.
따라서 다음과 같은 과정으로 MetalLB설치하는 과정을 기술 해 본다.
MetalLB 설치
1. ARP 모드를 활성화
shell# 명령어 실행 kubectl edit configmap -n kube-system kube-proxy # 설정 ipvs: strictARP: true
2. Manifast로 설치
shellkubectl 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 생성
shellapiVersion: 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
shellapiVersion: 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 파일
shellapiVersion: 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 조회
shellmaster@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를 통해 서비스에 할당된 포트로 접근을 시도 해 보았다.
정상적으로 배포된 서비스가 확인된다.