[C182] 서비스의 타입은 ClusterIP, NodePort, LoadBalancer, ExternalName 네 가지가 있습니다. 이들은 어떻게 다른가요?
애플리케이션 중 일부(예: 프론트엔드)는 서비스를 클러스터 밖에 위치한 외부 IP 주소에 노출하고 싶은 경우가 있을 것이다.
쿠버네티스 ServiceTypes
는 원하는 서비스 종류를 지정할 수 있도록 해준다. 기본 값은 ClusterIP
이다.
📌 Type
값과 그 동작은 다음과 같다.
ClusterIP:
(Default)service type 서비스를 클러스터-내부 IP에 노출시킨다.
이 값을 선택하면 클러스터 내에서만 서비스에 도달할 수 있다.
이것은 ServiceTypes
의 기본 값이다
NodePort:
고정 포트 (NodePort
)로 각 노드의 IP에 서비스를 노출시킨다.
NodePort
서비스가 라우팅되는 ClusterIP
서비스가 자동으로 생성된다.
<NodeIP>:<NodePort>
를 요청하여, 클러스터 외부에서 NodePort
서비스에 접속할 수 있다.
NodePort
와 ClusterIP
서비스가 자동으로 생성된다.externalName
필드의 콘텐츠 (예:foo.bar.example.com
)에 매핑한다. 어떤 종류의 프록시도 설정되어 있지 않다.참고:
ExternalName
유형을 사용하려면 kube-dns 버전 1.7 또는 CoreDNS 버전 1.7 이상이 필요하다.
인그레스를 사용하여 서비스를 노출시킬 수도 있다.
인그레스는 서비스 유형이 아니지만, 클러스터의 진입점 역할을 한다.
동일한 IP 주소로 여러 서비스를 노출시킬 수 있기 때문에 라우팅 규칙을 단일 리소스로 통합할 수 있다.
(Default)service type
서비스를 클러스터-내부 IP에 노출시킨다.
이 값을 선택하면 클러스터 내에서만 서비스에 도달할 수 있다.
이것은 ServiceTypes
의 기본 값이다.
apiVersion: v1
kind: Service
metadata:
name: my-internal-service
spec:
selector:
app: my-app
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
type
필드를 NodePort
로 설정하면, 쿠버네티스 컨트롤 플레인은 --service-node-port-range
플래그로 지정된 범위에서 포트를 할당한다 (기본값 : 30000-32767).
각 노드는 해당 포트 (모든 노드에서 동일한 포트 번호)를 서비스로 프록시한다.
서비스는 할당된 포트를 .spec.ports[*].nodePort
필드에 나타낸다.
포트를 프록시하기 위해 특정 IP를 지정하려면, kube-proxy에 대한 --nodeport-addresses
플래그 또는 kube-proxy 구성 파일의 동등한 nodePortAddresses
필드를 특정 IP 블록으로 설정할 수 있다.
이 플래그는 쉼표로 구분된 IP 블록 목록(예: 10.0.0.0/8
, 192.0.2.0/25
)을 사용하여 kube-proxy가 로컬 노드로 고려해야 하는 IP 주소 범위를 지정한다.
예를 들어, --nodeport-addresses=127.0.0.0/8
플래그로 kube-proxy를 시작하면, kube-proxy는 NodePort 서비스에 대하여 루프백(loopback) 인터페이스만 선택한다.
--nodeport-addresses
의 기본 값은 비어있는 목록이다.
이것은 kube-proxy가 NodePort에 대해 사용 가능한 모든 네트워크 인터페이스를 고려해야 한다는 것을 의미한다. (이는 이전 쿠버네티스 릴리스와도 호환된다).
특정 포트 번호를 원한다면, nodePort
필드에 값을 지정할 수 있다.
컨트롤 플레인은 해당 포트를 할당하거나 API 트랜잭션이 실패했다고 보고한다.
이는 사용자 스스로 포트 충돌의 가능성을 고려해야 한다는 의미이다. 또한 NodePort 사용을 위해 구성된 범위 내에 있는, 유효한 포트 번호를 사용해야 한다.
NodePort를 사용하면 자유롭게 자체 로드 밸런싱 솔루션을 설정하거나, 쿠버네티스가 완벽하게 지원하지 않는 환경을 구성하거나, 하나 이상의 노드 IP를 직접 노출시킬 수 있다.
이 서비스는 <NodeIP>:spec.ports[*].nodePort
와 .spec.clusterIP:spec.ports[*].port
로 표기된다. kube-proxy에 대한 --nodeport-addresses
플래그 또는 kube-proxy 구성 파일의 동등한 필드가 설정된 경우, <NodeIP>
는 노드 IP를 필터링한다.
예를 들면
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports:
*# 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.*
- port: 80
targetPort: 80
*# 선택적 필드
# 기본적으로 그리고 편의상 쿠버네티스 컨트롤 플레인은 포트 범위에서 할당한다
# (기본값: 30000-32767)*
nodePort: 30007
외부 로드 밸런서를 지원하는 클라우드 공급자 상에서, type
필드를 LoadBalancer
로 설정하면 서비스에 대한 로드 밸런서를 프로비저닝한다.
로드 밸런서의 실제 생성은 비동기적으로 수행되고, 프로비저닝된 밸런서에 대한 정보는 서비스의 .status.loadBalancer
필드에 발행된다.
예를 들면
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 192.0.2.127
외부 로드 밸런서의 트래픽은 백엔드 파드로 전달된다.
클라우드 공급자는 로드 밸런싱 방식을 결정한다.
일부 클라우드 공급자는 loadBalancerIP
를 지정할 수 있도록 허용한다.
이 경우, 로드 밸런서는 사용자 지정 loadBalancerIP
로 생성된다.
loadBalancerIP
필드가 지정되지 않으면, 임시 IP 주소로 loadBalancer가 설정된다.
loadBalancerIP
를 지정했지만 클라우드 공급자가 이 기능을 지원하지 않는 경우, 설정한 loadbalancerIP
필드는 무시된다.
ExternalName 유형의 서비스는 my-service
또는 cassandra
와 같은 일반적인 셀렉터에 대한 서비스가 아닌, DNS 이름에 대한 서비스에 매핑한다. spec.externalName
파라미터를 사용하여 이러한 서비스를 지정한다.
예를 들면, 이 서비스 정의는 prod
네임 스페이스의 my-service
서비스를 my.database.example.com
에 매핑한다.
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
참고:
ExternalName은 IPv4 주소 문자열을 허용하지만, IP 주소가 아닌 숫자로 구성된 DNS 이름을 허용한다. IPv4 주소와 유사한 ExternalName은 CoreDNS 또는 ingress-nginx에 의해 확인되지 않는데, ExternalName은 정식(canonical) DNS 이름을 지정하기 때문이다. IP 주소를 하드 코딩하려면, 헤드리스(headless) 서비스 사용을 고려한다.
my-service.prod.svc.cluster.local
호스트를 검색하면, 클러스터 DNS 서비스는 my.database.example.com
값의 CNAME
레코드를 반환한다. my-service
에 접근하는 것은 다른 서비스와 같은 방식으로 작동하지만, 리다이렉션은 프록시 또는 포워딩을 통하지 않고 DNS 수준에서 발생한다는 중요한 차이점이 있다. 나중에 데이터베이스를 클러스터로 이동하기로 결정한 경우, 해당 파드를 시작하고 적절한 셀렉터 또는 엔드포인트를 추가하고, 서비스의 유형(type)
을 변경할 수 있다.
하나 이상의 클러스터 노드로 라우팅되는 외부 IP가 있는 경우, 쿠버네티스 서비스는 이러한 externalIPs
에 노출될 수 있다. 서비스 포트에서 외부 IP (목적지 IP)를 사용하여 클러스터로 들어오는 트래픽은 서비스 엔드포인트 중 하나로 라우팅된다. externalIPs
는 쿠버네티스에 의해 관리되지 않으며 클러스터 관리자에게 책임이 있다.
서비스 명세에서, externalIPs
는 모든 ServiceTypes
와 함께 지정할 수 있다. 아래 예에서, 클라이언트는 "80.11.12.10:80
"(외부 IP:포트
)로 "my-service
"에 접근할 수 있다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
externalIPs:
- 80.11.12.10
https://kubernetes.io/docs/concepts/services-networking/service/#externalname