티스토리 뷰

Infra/Kubernetes

About Service(2), Basic Concept 2

Jordy-torvalds 2019. 11. 23. 15:03

Outline

이전 글에 이어서 서비스에 대하여 세부적으로 알아보도록 하겠다.

-

Examples

Example1-Allocating Ports to Service

항목 명이 ports 인 만큼 포트 여러 개를 설정 할 수 있다.

apiVersion: v1
kind: Service
metadata:
  name: jordy-svc-alloc-port
spec:
  ports:
  - name: http
    port: 80
    targetPort: 8080
  - name: https
    port: 443
    targetPort: 8443
  selector:
    app: jordy
# jordy-pod-alloc-port.yaml

http와 https포트를 할당했다.

-

Example 2-Using Named Ports

친숙하지 않는 번호를 대신해 이름을 부여해 포트를 관리해보자.

apiVersion: v1
kind: Pod
metadata:
    name: jordy-alloc-named-pod
    labels:
      app: jordy
spec:
    containers:
    -   image: bearstark/jordy
        name: jordy
        ports:
        -  name: jordy-http
           containerPort: 8080
           protocol: TCP
        -  name: jordy-https
           containerPort: 8443
           protocol: TCP
# jordy-pod-alloc-named-port.yaml

-

apiVersion: v1
kind: Service
metadata:
  name: jordy-svc-alloc-named-port
spec:
  ports:
  - name: http
    port: 80
    targetPort: jordy-http
  - name: https
    port: 443
    targetPort: jordy-https
  selector:
    app: jordy
# jordy-svc-alloc-named-port.yaml

-

생성 후에 curl로 테스트를 해보자. 테스트 방식은 이전 글과 동일하기 때문에 세부적인 테스트 방법은 이전글을 참조하자.

kubectl exec <pod-name> -- curl <node-cluster-ip>

-

그러면 응답을 받을 수 있다.

이를 활용하면 Pod 내 포트의 변경되도 서비스에는 영향이 가지 않는다. 결합도가 낮아지게 되는 것이다.

-

Exampe 3-Looking up environment variables of a specific pod

특정 포드의 환경 변수를 조회해보자.

kubectl exec <pod-name> env

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=jordy-alloc-named-pod
...
JORDY_SVC_ALLOC_NAMED_PORT_SERVICE_HOST=10.51.249.98
JORDY_SVC_ALLOC_NAMED_PORT_SERVICE_PORT=80
...

해당 포드를 가리키고 있는 서비스의 아이피와 포트가 출력된다.

Exampe 4-Looking up Endpoints of a specific Services

선택자가 app=jordy 인 포드를 하나 더 생성한 다음 아래 명령어를 실행한 결과 아래와 같은 결과가 출력되었다.
kubectl describe svc jordy-svc-alloc-named-port

Name:              jordy-svc-alloc-named-port
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=jordy
Type:              ClusterIP
IP:                10.51.249.98
Port:              http  80/TCP
TargetPort:        jordy-http/TCP
Endpoints:         10.48.1.82:8080,10.48.2.116:8080
Port:              https  443/TCP
TargetPort:        jordy-https/TCP
Endpoints:         10.48.1.82:8443,10.48.2.116:8443
Session Affinity:  None
Events:            <none>

Endpoint에 출력되는 아이피들은 서비스의 셀렉터와 동일한 포드들의 아이피 정보다.

엔드포인트 정보만 조회할 수 있는 명령어는 아래와 같다.

kubectl get endpoints <service-name>
kubectl get ep <service-name>

NAME                         ENDPOINTS                                                      AGE
jordy-svc-alloc-named-port   10.48.1.82:8443,10.48.2.116:8443,10.48.1.82:8080 + 1 more...   3d19h

-

해당 엔드포인트 정보는 클라이언트가 서비스 아이피를 통해 요청했을 때 kube-proxy 뒷단에 있는 포드 쪽으로 리다이렉트하는 과정에서 참조한다.

-

Pod의 Selector 정보와 Service의 Selector 정보 자체를 활용해서 포드에 리다이렉트하진 않는다.대신 Selector 정보로 대상 포드를 찾은 다음 IP와 포트 리스트 만들고, 이를 엔드포인트 정보로 저장한다.

-

Exampe 5-Decoupled between Service and Service`s endpoints

이전 까지의 예제들은 Service의 Selector와 Pod의 Selector 간에 Coupling(결합도)가 높다. 그래서 Pod의 Selector를 수정할 경우 Service의 Selector 또한 변경해주어야 할 것이다.

-

그래서 Service와 이름이 동일한 Endpoint를 생성하여 Service-Pod 간 Selector로 생기는 커플링은 깨줄 수 가 있는데, 그렇게 할 경우 Pod의 아이피를 명시적으로 제시해주어야 해서 오히려 더 불편하다고 생각이 든다.
-
해당 예제의 내용은 기존의 레거시 시스템이 있고 신규 생성한 포드와 기존 시스템을 한 서비스에 두고 싶을 때 사용하는 것을 권장한다.
-
더 창의적인 활용법이 있다면 댓글 작성을 부탁한다.

apiVersion: v1
kind: Endpoints
metadata:
  name: jordy-svc-alloc-named-port-ep 
subsets:
  - addresses:
    - ip: 11.11.11.11 # Pod or External System Ip 
    - ip: 22.22.22.22 # Pod or External System Ip 
    ports:
    - port: 80 
****

위 YAML에서 주의해야 할 것은 metadata.name이 service의 name과 같아야 한다는 것인데, 해당 서비스가 Selector가 있을 경우 endpoint가 생성되므로 해당 서비스의 Selector 항목을 비워야 한다.

이상으로 서비스의 기본 개념 2편을 마치겠다.

서비스 3편에서는 서비스를 외부의 클라이언트 들에게 노출 시키는 것에 대해 다뤄보도록 하겠다.


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함