-
Notifications
You must be signed in to change notification settings - Fork 1
4월 19일 2~3장 질문
- 서비스 타입 중에서 NodePort와 LoadBalancer는 언제 각각 쓰는 게 더 적절할까요?
- 내부 서비스 간 통신에 사용할 때?
- 외부에서 직접 접근하지 않고, 특정 시스템에서 접근할 때(확실한 포트, 엔드포인트에서 접근)
- VPN, Bastion 등을 통해서만 접근 가능한 보안 영역 등
- NodePort == 로컬에서 간단하게 구현하기 좋음, 다중 노드 클러스터에서 로드밸런싱 효과x, 트래픽이 곧바로 노드로 인입
- LoadBalancer == prod 환경에서 사용, 외부 로드밸런서(ELB 등) 사용 시 사용, 다중 노드 클러스터에서 사용, 실무에서 사용
- Ingress를 구성할 때 경로 기반 라우팅과 서브도메인 기반 라우팅 중 어떤 게 더 관리하기 쉬울까요?
- 경로 기반이 더 나은 경우
- 단일 서비스 도메인 아래에서 여러 백엔드를 운영할 때 (/api, /admin, /client)
- 인증서 관리와 DNS 구성을 단순화하고 싶을 때
- 소규모 또는 중간 규모의 서비스에 적합한듯
- internal-api/ 시 internal-api로 가도록 path에 명시하는 방식? (인증 구현시 이런 방법도 있음)
- 서브도메인 기반이 더 나은 경우
- 범근: 최상위 도메인 하위로 앞에 각 내부 MSA 서비스 단위로 라우팅해주는 구성 시 사용
- 완전히 다른 성격의 서비스를 운영할 때 (admin.example.com, cdn.example.com)
- 보안/정책적으로 서비스 분리가 필요한 경우
- 대규모 조직/멀티팀 환경에서 독립 도메인 운영이 필요할 때
- 경로 기반이 더 나은 경우
- 실제 프로덕션 환경에서 외부 접근을 관리할 때 Ingress를 더 일반적으로 사용하는 이유는 무엇이며, service, Ingress 각각 차이가 무엇이고, 어떤 상황에서 각 방식을 선택하는 것이 가장 적절할 지 궁금합니다.
- Ingress는 클러스터 외부에서 들어오는 HTTP/HTTPS 요청을 내부의 Service로 라우팅해주는 API 객체이자 규칙 모음이다.
- 서비스와 파드는 label selector를 통해 느슨하게 연결되는 아키텍쳐를 갖고 있는데, 이런 느슨한 연결이 가지는 장단점이 궁금합니다.
- 장점:
- pod가 바뀌어도 설정이 바뀌지 않아, 확장성이 좋음(추가 하기 쉬움)
- 컨트롤러나, 서비스 객체들이 실제 파드들의 이름 혹은 ip (구체적인 사실)을 몰라도 레이블 기반으로 동작할 수 있다. 말 그대로 추상화시켜놓은? DNS 처럼
- version=canary, version=stable 같은 라벨 조합으로 Canary, Blue-Green 가능
- 단점:
- 잘못된 라벨 적으면 다른 파드가 엮이거나 연결이 끊김 -> 장애 발생
- label selector에 일치하지 않는 pod가 없으면 pod를 만들어버리니 조심해야 함
-
kube-linter, Polaris 로 예방하기
- 막는 방법(우회적/간접적 방법)
-
컨트롤러 사용 자체를 피한다 ReplicaSet, Deployment, StatefulSet 등 컨트롤러 리소스를 사용하지 않고, 직접 파드를 생성하면 자동 생성이 일어나지 않습니다.
-
replica 수를 0으로 설정 컨트롤러의 .spec.replicas 값을 0으로 설정하면, 파드가 자동으로 생성되지 않습니다.
-
Job 리소스의 manualSelector 활용 Job의 경우, manualSelector: true를 사용하면 자동 파드 생성 동작을 제어할 수 있습니다.
-
Admission Controller, Policy 등으로 생성 자체를 막는다 PodSecurityPolicy나 ValidatingAdmissionWebhook 등으로 특정 조건의 파드 생성을 거부할 수 있습니다.
-
네임스페이스 수준에서 파드 생성을 막는다 네임스페이스에 파드 생성 금지 정책을 적용할 수 있습니다.
-
- 막는 방법(우회적/간접적 방법)
-
kube-linter, Polaris 로 예방하기
- 장점:
Q. (2장) 왜 파드는 다른 노드에서 흩어져서 실행되어야 하는가?
A. 안정성
, 효율성
, 확장성
때문이다.
- 같은 서비스를 하는 파드가 하나의 노드에 몰려있는 상태에서, 그 노드가 죽으면 서비스 전체가 영향을 받는다.
- 한 노드에 파드가 몰리면 병목이 발생할 수 있음
- 수평 확장이 쉬워진다
Q.
# 성공
$ kubectl exec deploy/sleep-1 -- ping -c 2 $(kubectl get pod -l app=sleep-2 --output jsonpath='{.items[0].status.podIP}')
# 실패
$ kubectl exec deploy/sleep-1 -- ping -c 1 sleep-2
교재에는 "ping 프로토콜이 쿠버네티스에서는 안 된다"고 했는데, 그러면 둘 다 안 돼야 하는 거 아닌가?
A1. ping 명령어 자체가 금지된 것은 아님. DNS가 작동하지 않을 수 있다는 의미, 클러스터의 DNS가 동작해야만 한다. (GPT), (재영 처음 생각 : 위에꺼는 IP를 직접 호출하니까 되는거고, 아래꺼는 DNS 서버를 거쳐서 가는데, 이 DNS 서버에서 ping이 허용 안 된다고 생각)
A2. 쿠버네티스 내부 통신이 TCP / UDP 기반인데 ping은 ICMP 기반이라 안된다.
- 익스터널네임 서비스와 헤드리스 서비스 모두 HTTP 헤더 문제를 해결하지 못한다는데 그럼 이 문제를 어떻게 해결할 수 있을까?
- TCP가 아닐경우 HTTP 대상 호스트명이 들어감, 호스트가 익스터널네임랑 다르면 요청 실패함.
- ‘TCP 사용한다’ 말고 다른 대안은 없을까?
- 호스트명을 클라이언트측에서 명시적으로 설정
-
curl ~~ -H
,Host: example
-
- gateway 측에서 라우팅 로직을 변경?
- 중간에 프록시를 두고, HTTP 요청을 제대로 포워딩하거나 헤더를 조작해주는 방식이 필요함
- sidecar를 사용
- Ingress나 중간 프록시 레이어를 두는 게 실무적이고 안정적인 해결책이라고 합니다.
# 성공
$ kubectl exec deploy/sleep-1 -- ping -c 2 $(kubectl get pod -l app=sleep-2 --output jsonpath='{.items[0].status.podIP}')
# 실패
$ kubectl exec deploy/sleep-1 -- ping -c 1 sleep-2
교재에는 "ping 프로토콜이 쿠버네티스에서는 안 된다"고 했는데, 그러면 예제 둘 다 안 돼야 하는 거 아닐까요?