Service
Service
각 Pod는 고유한 IP 주소를 갖습니다. 하지만 Deployment를 사용하여 애플리케이션을 배포할 때, 한 시점에 실행되는 Pod 집합과 다음 시점에서 실행되고 있는 Pod 집합이 다를 수 있습니다. 이런 상황에서 해당 Pod 집합을 사용해야하는 서비스가 존재한다면, 이 변화를 추적해야하는 문제가 생깁니다. 이러한 문제를 해결하기 위해 Service 리소스가 필요합니다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # ClusterIP(default)|NodePort|LoadBalancer|ExternalName
selector: # selector를 사용하지 않으면 Endpoints를 생성하여 수동으로 매핑
app: my-app # Pod의 label에 해당 key: value 가 있는 것을 선택
ports:
- name: http
port: 8080 # service port
targetPort: 8080 # pod port. pod에 port.name을 정의했다면 name으로 대체 가능
protocol: TCP # TCP(default)|UDP|SCTP|HTTP|PROXY
kubectl explain [--recursive] service[.<fieldName>]
을 통해 자세한 설명을 볼 수 있습니다.
FQDN
<name>.<namespace>.svc.cluster.local
이 Kubernetes DNS에 등록됩니다.
컨테이너 내부에서 Service를 찾을 때, <name>
, <name>.<namespace>
등을 사용하여 찾을 수 있습니다. 앞의 일부만 적었을 때, /etc/resolv.conf
파일의 search
옵션에 적힌 값을 기준으로 탐색합니다.
...
search <namespace>.svc.cluster.local svc.cluster.local cluster.local us-west-2.compute.internal
...
NodePort
NodePort는 <nodeIP>:<nodePort>
-> <serviceIP>:<port>
-> <podIP>:<targetPort>
연결을 통해 외부에서 pod로 접근 할 수 있게 만들어주는 서비스 입니다. <nodeIP>
는 클러스터에 있는 Node라면 어느 Node에서든 접근이 가능합니다.
apiVersion: v1
kind: Service
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
# nodePort: <30000-32767> # 설정하지 않으면 해당 범위에서 랜덤하게 선택
NodePort의 범위를 변경하고 싶은 경우 kube-apiserver의 --service-node-port-range=<startPort>-<endPort>
옵션을 추가하면 됩니다.
spec:
containers:
- command:
- kube-apiserver
- ...
- --service-node-port-range=30000-32767
- ...
Kubernetes 1.28 부터는 ServiceNodePortStaticSubrange라는 기능이 기본적으로 활성화 됩니다. 이 기능은 NodePort의 시작 포트 부터 min(max(16, nodeportSize / 32), 128)
개의 포트의 동적 할당 우선순위를 낮춥니다. 예를 들어 30000-32767의 범위를 갖는 경우 30000-30085까지는 다른 포트를 모두 사용하기 전까지는 동적 할당이 되지 않으므로 사용자가 정적 할당으로 사용하기에 좋습니다.
Selector 없이 Service 생성
apiVersion: v1
kind: Service
metadata:
name: <serviceName>
namespace: <namespace>
spec:
ports:
- name: <portName>
port: <port>
targetPort: <targetPort>
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: <name>
namespace: <namespace>
labels:
kubernetes.io/service-name: <serviceName>
addressType: <addressType>
ports:
- name: <portName>
appProtocol: <appProtocol>
protocol: TCP
port: <targetPort>
endpoints:
- addresses:
- <IP>
addressType: <addressType>
: IPv4, IPv6, FQDNports
appProtocol: <appProtocol>
- 어떤 프로토콜을 쓰는지에 대한 힌트입니다.
endpoints
conditions
ready: <bool>
: Pod의 Ready와 매핑되는 값으로 외부 주소를 설정한 경우 직접true
로 설정해야 합니다.
Debug
kubectl run tmp-shell --rm -it --image nicolaka/netshoot -- sh