외부 사용자가 파드를 이용하는 방법
서비스 : 외부에서 쿠버네티스 클러스터에 접속하는 방법
노드포트(NodePort) 서비스
: 외부에서 쿠버네티스 클러스터의 내부에 접속하는 가장 쉬은 방법
노드포트 서비스 설정
-> 모든 워커 노드의 특정 포트(노드포트)를 엶
-> 여기로 오는 모든 요청을 노드포트 서비스로 전달
-> 해당 업무를 처리할 수 있는 파드로 요청 전달
디플로이먼트로 파드 생성
kubectl create deployment np-pods --image=sysnet4admin/echo-hname
파드 확인
kubectl get pods
노드포트 서비스 생성 (이미 정의된 오브젝트 스펙 이용)
kubectl create -f ~/_Book_k8sInfra/ch3/3.3.1/nodeport.yaml
# <nodeport.yaml>
apiVersion: v1
kind: Service
metadata:
name: np-svc
spec:
selector:
app: np-pods
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30000
type: NodePort
-> 기존 파드 구조에서 kind가 Service로 바뀜
-> spec에 컨테이너에 대한 정보가 없음
-> 서비스 타입을 NodePort로 지정
노드포트 서비스로 생성한 np-svc 서비스 확인
kubectl get services
-> 노드포트의 포트 번호가 30000번으로 지정됨
-> CLUSTER-IP는 클러스터의 내부에서 사용되는 IP (자동 지정됨)
워커 노드 IP 확인
kubectl get nodes -o wide
호스트 PC에 웹 브라우저를 띄우고 워커 노드 IP와 노드포트의 포트 번호로 접속해 외부에서 접근되는지 확인 (화면에 파드 이름이 표시되는지)
-> 파드가 하나라서 이름은 모두 동일하게 나옴
디플로이먼트로 생성된 파드 1개에 접속하고 있다가 파드가 3개로 증가하면 부하가 분산되는가?
호스트 PC에서 파워셸 명령 창을 띄우고 명령 실행
(반복적으로 192.168.1.101:30000에 접속해 접속한 파드 이름을 화면에 표시 -> 파드가 1개에서 3개로 늘어나는 시점 관찰하기 위함)
$i=0; while($true)
{
% { %i++; write-host -NoNewline "$i $_" }
(Invoke-RestMethod "http://192.168.1.101:30000")-replace '\n', " "
}
-> 호스트 이름 순서대로 출력됨
마스터 노드에서 파드를 3개로 증가
kubectl scale deployment np-pods --replicas=3
배포된 파드 확인
kubectl get pods
파드 이름에 배포된 파드 3개가 돌아가면서 표시되는지 확인
(부하 분산이 되는지)
-> 노드포트의 오브젝트 스펙에 np-pods와 디플로이먼트 이름이 동일하면 같은 파드로 간주하여 외부에서 추적해서 접속됨
추적 방법은 이름 외에도 많음
서비스로 내보낼 디플로이먼트를 np-pods로 지정
서비스 이름: np-svc-v2, 타입: NodePort(대소문자 구분!)
연결 포트: 80
kubectl expose deployment np-pods --type=NodePort --name=np-svc-v2 --port=80
서비스 확인
kubectl get services
노드포트의 포트 번호를 지정할 수 없음 -> 임의 지정
호스트 PC에서 웹 브라우저로 포트 번호에 접속하여 배포된 파드 중 하나의 이름이 표시되는지 확인
디플로이먼트와 서비스 삭제
kubectl delete deployment np-pods
kubectl delete services np-svc
kubectl delete services np-svc-v2
노드포트 서비스는 포트를 중복으로 사용할 수 없음
-> 1개의 노드포트에 1개의 디플로이먼트 적용
인그레스
: 고유한 주소를 제공해 사용 목적에 따라 다른 응답 제공
: 트래픽에 대한 L4/L7 로드밸런서와 보안 인증서 처리 기능 제공
사용자는 노드마다 설정된 노드포트를 통해 노드포트 서비스로 접속
노드포트 서비스는NGINX 인그레스 컨트롤러로 구성함
NGINX 인그레스 컨트롤러가 사용자 접속 경로에 따라 적합한 클러스터 IP 서비스로 경로 제공
클러스터 IP 서비스가 사용자를 해당 파드로 연결
인그레스 컨트롤러는 파드와 직접 통신할 수 없음!
-> 노드포트 or 로드밸런서 서비스와 연동해서 통신
테스트용 디플로이먼트 2개 배포
kubectl create deployment in-hname-pod --image=sysnet4admin/echo-hname
kubectl create deployment in-ip-pod --image=sysnet4admin/echo-ip
파드 상태 확인
kubectl get pods
NGINX 인그레스 컨트롤러 설치
kubectl apply -f ~/_Book_k8sInfra/ch3/3.3.2/ingress-nginx.yaml
NGINX 인그레스 컨트롤러의 파드가 배포됐는지 확인
default 네임스페이스가 아닌 ingress-nginx 네임스페이스에 속함
-> -n ingress-nginx
옵션 추가해야함
kubectl get pods -n ingress-nginx
-n
: namespace의 약어, default 외의 네임스페이스 확인할 때 사용
파드, 서비스 확인할 때 동일한 옵션
경로와 작동을 정의해 사용자 요구 사항에 맞게 설정 (파일로)
kubectl apply -f ~/_Book_k8sInfra/ch3/3.3.2/ingress-config.yaml
# <ingress-config.yaml>
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path:
backend:
serviceName: hname-svc-default
servicePort: 80
- path: /ip
backend:
serviceName: ip-svc
servicePort: 80
- path: /your-directory
backend:
serviceName: your-svc
servicePort: 80
-> 들어오는 주소 값과 포트에 따라 노출된 서비스를 연결하는 역할을 설정
-> 외부에서 주소 값과 노드포트를 가지고 들어오면 hname-svc-default 서비스와 연결된 파드로 넘김
-> 외부에서 들어오는 주소 값, 노드포트와 함께 뒤에 /ip를 추가한 주소 값은 ip-svc 서비스와 연결된 파드로 접속
인그레스 설정 파일 등록 확인
kubectl get ingress
인그레스에 요청한 내용이 적용됐는지 확인
kubectl get ingress -o yaml
-> 인그레스에 적용된 내용을 야믈 형식으로 출력
-> 적용한 내용 외에 시스템에서 자동으로 생성하는 것까지 확인 가능
외부에서 NGINX 인그레스 컨트롤러에 접속할 수 있게 노드포트 서비스로 외부에 노출
kubectl apply -f ~/_Book_k8sInfra/ch3/3.3.2/ingress.yaml
# <ingress.yaml>
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx # 네임스페이스를 ingress-nginx로 지정
spec:
ports:
# http를 처리하기 위한 30100번 포트 요청은 80번 포트로 넘김
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30100
# http를 처리하기 위한 30101번 포트 요청은 443번 포트로 넘김
- name: https
protocol: TCP
port: 443
targetPort: 443
nodePort: 30101
selector: # 요구 사항에 따라 셀렉터를 ingress-nginx로 지정
app.kubernetes.io/name: ingress-nginx
type: NodePort
노드포트 서비스로 생성된 인그레스 컨트롤러 확인
(네인스페이스 지정해야함!)
kubectl get services -n ingress-nginx
디플로이먼트도 서비스로 노출 (외부와 통신하기 위해 클러스터 외부에 노출할 수 있는 구역으로 옮김)
kubectl expose deployment in-hname-pod --name=hname-svc-defaul --port=80, 443
kubectl expose deployment in-ip-pod --name=ip-svc --port=80, 443
서비스 점검으로 디플로이먼트들이 서비스에 정상적으로 노출되는지 확인 (새로 생성된 서비스는 default에 있어서 네임스페이스 지정 안해도 됨)
kubectl get services
호스트 PC 웹 브라우저에서 192.168.1.101:30100 접속하여 파드 이름이 표시되는지 확인 (101, 102, 103 중에 하나 사용)
경로 뒤에 /ip 추가하여 요청 방법과 파드 ip가 표시되는지 확인
https://192.168.1.101:30101 접속하여 https 연결도 잘 되는지, 파드 이름 표시되는지 확인
(경고 메시지 뜨면 고급>주소(안전하지 않음)로 이동 클릭)
https://192.168.1.101:30101/ip 에서도 요청 방법과 파드 IP가 표시되는지 확인
테스트 끝 / 서비스 삭제
kubectl delete deployment in-hname-pod
kubectl delete deployment in-ip-pod
kubectl delete services hname-svc-default
kubectl delete services ip-svc
NGINX 인그레스 컨트롤러 관련 내용 삭제
kubectl delete -f ~/_Book_k8sInfra/ch3/3.3.2/ingress-nginx.yaml
로드밸런서 : 간단한 구조로 파드를 외부에 노출하고 부하를 분산
로드밸런서를 사용하려면 로드밸런서를 이미 구현해 둔 서비스업체의 도움을 받아 외부에 구현해야 함
클라우드에서 제공하는 쿠버네티스를 사용하고 있으면 선언만 하면 사용할 수 있음
-> 로드밸런서 서비스가 생성되고 외부와 통신할 수 있는 ip가 부여되고 외부와 통신할 수 있으며 부하도 분산됨
MetalLB : 로드밸런서 서비스를 받아주는 구성을 지원
온프레미스에서 로드밸런서를 사용하려면 내부에서 서비스를 받아주는 구성이 있어야함
베어메탈(bare metal, 운영 체제가 설치되지 않은 하드웨어)로 구성된 쿠버네티스에서도 로드밸런서를 사용할 수 있게 함
MetalLB 컨트롤러
: 작동 방식(Protocol)을 정의하고 EXTERNAL-IP를 부여해 관리함
MetalLB 스피커(speaker)
: 정해진 작동 방식(L2/ARP, L3/BGP)에 따라 경로를 만들 수 있게 네트워크 정보를 수집해 각 파드의 경로 제공
: L2는 스피커 중에서 리더를 선출해서 총괄하게 함
디플로이먼트를 이용해 2종류 파드 생성하고 3개로 늘려 노드당 1개씩 파드 배포
kubectl create deployment lb-hname-pods --image=sysnet4admin/echo-hname
kubectl scale deployment lb-hname-pods --replicas=3
kubectl create deployment lb-ip-pods --image=sysnet4admin/echo-ip
kubectl scale deployment lb-ip=pods --replicas=3
2종류 파드 총 6개 배포 확인
kubectl get pods
사전에 정의된 오브젝트 스펙으로 MetalLB 구성
kubectl apply -f ~/_Book_k8sInfra/ch3/3.3.4/metallb.yaml
-> MetalLB에 필요한 요소 모두 설치됨
-> 독립적인 네임스페이스(metallb-system) 만들어짐
MetalLB 파드 5개(controller 1, speaker 4)인지, IP, 상태 확인
kubectl get pods -n metallb-system -o wide
ConfigMap 오브젝트 사용하여 MetalLB 설정 적용
kubectl apply -f ~/_Book_k8sInfra/ch3/3.3.4/metallb-l2config.yaml
# <metallb-l2config.yaml>
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: nginx-ip-range
protocol: layer2
addresses:
- 192.168.1.11-192.168.1.13
ConfigMap 생성 확인
kubectl get configmap -n metallb-system
MetalLB 설정 적용 확인
kubectl get configmap -n metallb-system -o yaml
디플로이먼트를 로드밸런서 서비스로 노출
kubectl expose deploymnet lb-hname-pods --type=LoadBalancer --name=lb-hname-svc --port=80
kubectl expose deploymnet lb-ip-pods --type=LoadBalancer --name=lb-ip-svc --port=80
로드밸런서 서비스별로 CLUSTER-IP, EXTERNAL-IP가 잘 적용됐는지, EXTERNAL-IP에 ConfigMap을 통한 IP가 잘 부여됐는지 확인
kubectl get servies
EXTERNAL-IP 작동 확인위해 호스트 PC 브라우저로 lb-hname-svc의 EXTERNAL-IP로 접속 후 파드 이름이 표시되는지 확인
lb-ip-svc의 EXTERNAL-IP로 접속 후 요청 방법과 IP가 표시되는지 확인
파워셸 명령 창에 스크립트 실행
$i=0; while($true)
{
% { $i++; write-host -NoNewline "$i $_" }
(Invoike-RestMethod "http://[lb-hname-svc의 EXTERNAL-IP]")-replace '\n', " "
}
파드 6개로 늘림
kubectl scale deployment lb-hname-pods --replicas=6
늘어난 파드도 EXTERNAL-IP 접근되는지 확인
MetalLB 설정 제외 나머지 삭제
코드 스킵
HPA(Horizontal Pod Autoscaler)
사용자가 갑자기 늘어 파드가 감당할 수 없게되어 서비스 불가되는 경우를 대비해 부하량에 따라 디플로이먼트의 파드 수를 유동적으로 관리하는 기능
디플로이먼트 1개 생성
kubectl create deployment hpa-hname-pods --image=sysnet4admin/echo-hname
hpa-hname-pods를 로드밸런서 서비스로 설정
(앞에서 MetalLB 구성 했음)
kubectl expose deployment hpa-hname-pods --type=LoadBalancer --name=hpa-hname-svc --port=80
로드밸런서 서비스 IP 확인
kubectl get services
HPA 작동하기 위해 파드 자원 어느 정도 사용되는지 파악
(부하 확인)
kubectl top pods
-> 자원 요청 설정 없다고 에러 발생
-> HPA가 자원 요청할 때 메트릭 서버를 통해 계측값을 전달받음
-> 메트릭 서버가 없어서 에러 발생!
메트릭 서버 생성
kubectl create -f ~/_Book_k8sInfra/ch3/3.3.5/metrics-server.yaml
메트릭 서버 설정 후 ④ 결과 제대로 확인
-> 부하 없어서 CPU, MEMORY 값이 매우 낮음
파드에 부하가 걸리기 전에 scale이 실행되게 수정
kubectl edit deployment hpa-hname-pods
resources: {}
에서 {} 부분 수정
resources:
requests:
cpu: "10m"
-> 파드의 CPU 0.01 사용을 기준으로 파드 증설
limits:
cpu: "50m"
-> CPU 사용 제한 0.05 (순간적인 부하 대비)
스펙이 변경되고 새로운 파드 생성됐는지 확인
kubectl top pods
autoscale 설정하여 특정 조건이 만족되면 자동으로 scale 수행
kubectl autoscale deployment hpa-hname-pods --min=1 --max=30 --cpu-percent=50
-> CPU 사용량이 50% 넘으면 autoscale
왼: 마스터 노드 창 2개, 오: 파워셸
마스터 노드 1 : watch kubectl top pods
마스터 노드 2 : watch kubectl get pods
watch
: 2초에 한 번씩 자동으로 상태 확인
HPA 테스트 위해 파워셸에 반복문 실행
로드밸런서 테스트 코드와 동일
-> 마스터 노드 1 창에서 부하량 감지하는지 확인
마스터 노드 2 창에서 파드 새로 생성되는지 확인
부하 분산으로 생성된 파드의 부하량 증가하는지 확인
안정적인 상태가 되는지 확인하고 파워셸 창 종료
부하가 없어지면 autoscale 최소 조건인 파드 1개로 돌아가기 위해 파드가 종료되는지 확인
파드 모두 종료되고 1개 남게되는지 확인
디플로이먼트, 서비스, 메트릭 서버 삭제
코드 생략