모음/[쿠버네티스 인 액션]

[쿠버네티스 인 액션] 5장.서비스 - 서비스 앤드포인트, 외부 클라이언트 연결 (노드포트, 로드밸러스, 인그레스)

ttoance 2024. 9. 22. 06:08

 

5.5 서비스 엔드포인트 

1) 서비스 엔드포인트란 

- 서비스는 파드에 직접 연결되지 않는다. 

- 대신 앤드포인트 리소스가 그 사이에 있다. 

kubectl describe svc kubia
kubectl get pods -o wide

 

2) externalname 서비스 생성 

서비스의 엔드포인트를 수동으로 구성해 외부 서비스를 노출하는 대신 FQDN으로 외부 서비스를 참조할 수 있다.

 

kubernetes-in-action/Chapter05/external-service-externalname.yaml at master · luksa/kubernetes-in-action (github.com)

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  type: ExternalName
  externalName: api.somecompany.com
  ports:
  - port: 80

- 서비스가 생성되면 파드는 서비스의 FQDN을 사용하는 대신 external-service.default.svc.cluster.local으로 외부 서비스에 연결할 수 있다. 

- externalname 유형의 서비스는 clusterIP를 엊지 못한다. 

 

 


5.6 외부 클라이언트에 서비스 노출 

1) 외부에서 서비스 액세스할 수 있는 방법 

- 노드포트로 서비스 유형 설정 : 노드포트 서비스의 경우 가 클러스터 노드는 노드 자체에서 포트 열고 해당 포트로 수신된 트래픽을 서비스로 전달, 이 경우 내부 클러스터 IP포트로 애게스할 수 있을 뿐만 아니라 모든 노드의 전용 포트로도 액세스 가능

- 서비스 유형을 노드포트 유형의 확장인 로드밸런서로 설정 : 로드밸런서는 트래픽을 모든 노드의 노드포트로 전달, 클라이언트는 로드밸런서의 IP로 서비스에 액세스

- 단일 IP주소로 여러 서비스를 노출하는 인그레스 리소스 만들기 : HTTP 레벨(7계층)에서 작동해 4계층 서비스 보다 많은 기능 제공 

 

 

2) 방법1. 노드포트 서비스 이용 

kubernetes-in-action/Chapter05/kubia-svc-nodeport.yaml at master · luksa/kubernetes-in-action (github.com)

apiVersion: v1
kind: Service
metadata:
  name: kubia-nodeport
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30123
  selector:
    app: kubia

kubectl get svc kubia-nodeport

이 서비스는 다음 주소에서 액세스 가능하다.

- 10.103.208.80:80 : <노드포트서비스>:80 

- <첫번째 노드의 IP>:30123

- <두번째 노드의 IP>:30123

 

내부 포드에서 nodeport 서비스로 접근

 

 

30123포트로 시도했으나 방화벽을 열어줘야 하는 거 같다. 근데 포드 안애서 하고 있는데,,   

 

 

그런다음 책에서는 방화벽을 열어줘야 한다고 한다. 

gcloud compute firewall-rules create kubia-svc-rule --alow=tcp:30123

 

kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

이걸로 ExternalIp를 받아서 30123포트로 하면 된다고 한다. 

 

 

그러나 클라이언트가 첫번째 노드에만 요청하면 해당 장애가 나면 클라이언트는 더이상 액세스할 수 없기 때문에 노드에 요청을 분산시키고 해당 시점에 오프라인 상태로 요청 보내지 않도록 로드밸런서를 배치하는 것이 좋음 

 

 

 

 

3) 방법2. 외부 로드밸런서로 서비스 노출 

kubernetes-in-action/Chapter05/kubia-svc-loadbalancer.yaml at master · luksa/kubernetes-in-action (github.com)

apiVersion: v1
kind: Service
metadata:
  name: kubia-loadbalancer
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: kubia

 

4) 방법3. 인그레스 리소스로 서비스 외부 노출 

- 인그레스가 필요한 이유 

> 로드밸랜서 서비스는 자신의 공용 IP 주소를 가진 로드밸런서가 필요하지만, 인그레스는 IP 주소로 수십 개의 서비스에 접근이 가능하도록 지원해준다. 

 

- 인그레스 리소스 생성 

> minikube ingress 활성화 

minikube addons enable ingress

 

kubernetes-in-action/Chapter05/kubia-ingress.yaml at master · luksa/kubernetes-in-action (github.com)

책 예제와 조금 달라져서 아래와 같이 수정해야 한다. 

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia
spec:
  rules:
  - host: kubia.example.com
    http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: kubia-nodeport
              port:
                number: 80

 

시간이 걸리면 address에 표시된다.

 

 

- 인그레스 동작 방식 

- 클라이언트는 먼저 kubia.example.com의 DNS 조회 수행하며, DNS 서버가 인그레스 컨트롤러의 IP 반환 

- 클라이언트는 HTTP 요청을 인그레스 컨트롤러로 전송하고 host 헤더에서 kubia.example.com 을 지정한다. 

- 컨트롤러는 해당 헤더에서 클라이언트가 액세스하려는 서비스를 결정하고 서비스와 관련된 엔드포인트 오브젝트로 파드 IP를 조회한 다음 클리아언트 요청을 다음 클라이언트 요청을 파드에 전달한다. 

 

- TLS 트래픽 처리하도록 인그레스 구성 

openssl genrsa -out tls.key 2048
openssl req -new -x509 -key tls.key -out tls.cert -days 360 -subj /CN=kubia.example.com
kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key

 

kubernetes-in-action/Chapter05/kubia-ingress-tls.yaml at master · luksa/kubernetes-in-action (github.com)

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubia
spec:
  tls:
  - hosts: 
    - kubia.example.com
    secretName: tls-secret
  rules:
  - host: kubia.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kubia-nodeport
          servicePort: 80

 

 

 

5) externalTrafficPolicy : local

kubernetes-in-action/Chapter05/kubia-svc-nodeport-onlylocal.yaml at master · luksa/kubernetes-in-action (github.com)

apiVersion: v1
kind: Service
metadata:
  name: kubia-nodeport-onlylocal
spec:
  type: NodePort
  externalTrafficPolicy: Local
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30124
  selector:
    app: kubia

 

- 서비스 정의에 이 설정이 포함돼 있고 서비스의 노드포트로 외부 연결이 열린 경우 서비스 프록시는 로컬에 실행 중인 파드를 선택한다, 로컬 파드가 존재하지 않으면 연결이 중단된다. 

- 일반적으로 연결은 모든 파드에 균등하게 분산되지만 이 어노테이션을 사용할 때는 더 이상 적용되지 않는다. 

 

 

- 로컬 외부 트래픽 정책은 연결을 수신하는 노드와 대상 파드를 호스팅하는 노드 사이에 추가 홉이 없기 때문에 클라이언트 IP 보존에 영향을 미친다 (소스 네트워크 주소 변환 snat가 수행되지 않는다.) 

 

관련해서 조금 더 자세히 설명한 글이 있어서 소개한다. 

Pod 라우팅과 ExternalTrafficPolicy 옵션 (tistory.com)

 

Pod 라우팅과 ExternalTrafficPolicy 옵션

Pod를 expose할 때 Kubernetes의 Service를 통해 다른 Pod혹은 외부에서 접근할 수 있도록 설정할 수 있다. 더 정확히는 Service를 생성하면 해당하는 Pod들에 대한 endpoint가 자동으로 생성되어, connection이 가

taemy-sw.tistory.com

 

반응형