kubernetes - Service
쿠버네테스 상에선 서비스를 클러스터 네트워크에서 노출되는 Pod의 논리적인 집합으로 정의한다. 클러스터상에 존재하는 Pod은 selector를 통해 연결하고자 하는 고유의 서비스를 설정할 수 있고, 서비스는 연결된 Pod을 End Point로 둔다. 서비스는 고유의 VIP를 갖고 있기 때문에 클러스터 상에선 서비스를 이용해 내부 Pod에 접근할 수 있게 되며 연결된 Pod이 여러개 있는 경우 서비스는 부하 분산도 같이 담당하게 된다. 리버스 프록시의 역할과 로드밸런서의 역할을 한다.
예제
먼저 서비스 오브젝트를 만들어보자. 아래와 같은 yaml 파일을 만들고
kind: Service
apiVersion: v1
metadata:
name: service-example
spec:
selector:
app.kubernetes.io/instance: service-example
ports:
- port: 80
아래 명령어를 이용해 생성하고 확인해보자. metadata 레이블에 선언한 이름과 동일한 서비스가 생성된 것을 확인 할 수 있다.
➜ temp kubectl create -f service-example.yaml
➜ temp kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service-example ClusterIP 172.24.224.117 <none> 80/TCP 12m
describe 명령어로 방금 생성한 서비스의 세부 정보를 호출해보자. Endpoint가 비어있는 것을 확인할 수 있을 것이다. 현재 어떠한 Pod도 이 서비스를 selector로 지정하지 않았기 때문에 서비스는 Endpoints가 없다.
➜ temp kubectl describe service service-example
Name: service-example
Namespace: example
Labels: <none>
Selector: app.kubernetes.io/instance=service-example
Type: ClusterIP
...
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: <none>
...
이번에는 Deployment 로 Pod을 생성하고 selector로 이번에 방금 전에 생성한 서비스를 추가해보자.
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-example-deploy
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/instance: service-example
template:
metadata:
labels:
app.kubernetes.io/instance: service-example
spec:
containers:
- image: ...
name: service-example-pod
args:
- --port=80
ports:
- containerPort: 80
Pod을 생성한 후 다시 describe 명령어를 실행해보면 End point에 주소가 생긴 것을 확인 할 수 있다. 이 주소는 방금 전에 생성한 Pod에 할당된 IP 값이다.
➜ temp kubectl describe service service-example
Name: service-example
Namespace: example
Labels: <none>
Selector: app.kubernetes.io/instance=service-example
Type: ClusterIP
...
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.171.141.97:80,10.171.238.17:80
...
https://kubernetes.io/ko/docs/tutorials/stateless-application/expose-external-ip-address/