본문 바로가기
INFRA/DevOps

Service - 1

by BTC_룰루랄라 2022. 6. 2.

반갑습니다!

💙베하💙 누구든 탑승할 수 있는 유임승차 팀의 BTC 룰루랄라 입니다!!💨😉

 

저번 포스팅은 쿠버네티스 기능 중 하나인 Deployment에 대해서 설명 드렸는데요~

이번 포스팅에서는 Kubernetes의 Service에 대해서 간략하게 설명해 드리겠습니다.

Service는 앞전 설명드렸던 개념들보다 알아두어야 할 기능들이 많으므로 2~3번에 걸쳐 포스팅 할

예정입니다!

그럼 서비스에 대해서 한번 알아 보겠습니다~

룰루랄라~♬

 

 

 

⚡️ 목표

Service(서비스)를 이용하여 Pod을 노출하고 클러스터 외부에서 접근할 수 있는 방법을 알아봅니다.

Pod은 자체 IP를 가지고 다른 Pod과 통신할 수 있지만, 쉽게 사라지고 생성되는 특징 때문에 직접 통신하는 방법은 권장하지 않습니다. 쿠버네티스는 Pod과 직접 통신하는 방법 대신, 별도의 고정된 IP를 가진 서비스를 만들고 그 서비스를 통해 Pod에 접근하는 방식을 사용합니다.

이러한 개념은 도커에 익숙할수록 처음 접하면 참 어렵습니다. 개념도 생소한데 노출 범위에 따라 CluterIP, NodePort, LoadBalancer 타입으로 나누어져 더욱 헷갈립니다. 하나씩 차근차근 알아봅시다.

 

#Service(ClusterIP) 만들기

ClusterIP는 클러스터 내부에 새로운 IP를 할당하고 여러 개의 Pod을 바라보는 로드밸런서 기능을 제공합니다. 그리고 서비스 이름을 내부 도메인 서버에 등록하여 Pod 간에 서비스 이름으로 통신할 수 있습니다.

그럼, 다중 컨테이너를 설명할 때 만들었던, counter 앱 중에 redis를 서비스로 노출해보겠습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  selector:
    matchLabels:
      app: counter
      tier: db
  template:
    metadata:
      labels:
        app: counter
        tier: db
    spec:
      containers:
        - name: redis
          image: redis
          ports:
            - containerPort: 6379
              protocol: TCP

---
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  ports:
    - port: 6379
      protocol: TCP
  selector:
    app: counter
    tier: db

구분자

하나의 YAML파일에 여러 개의 리소스를 정의할 땐 "---"를 구분자로 사용합니다.

redis를 먼저 만들어 봅니다.

kubectl apply -f counter-redis-svc.yml

# Pod, ReplicaSet, Deployment, Service 상태 확인
kubectl get all

 

실행 결과

NAME                         READY   STATUS    RESTARTS   AGE
pod/redis-57d787df44-mf5w5   1/1     Running   0          10s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP    3d19h
service/redis        ClusterIP   10.103.50.102   <none>        6379/TCP   10s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/redis   1/1     1            1           10s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/redis-57d787df44   1         1         1       10s

redis Deployment와 Service가 생성된 것을 볼 수 있습니다.

같은 클러스터에서 생성된 Pod이라면 redis라는 도메인으로 redis Pod에 접근 할 수 있습니다. (redis.default.svc.cluster.local로도 접근가능 합니다. 서로 다른 namespace와 cluster를 구분할 수 있습니다.)

CluterIP 서비스의 설정을 살펴봅니다.

정의설명

spec.ports.port 서비스가 생성할 Port
spec.ports.targetPort 서비스가 접근할 Pod의 Port (기본: port랑 동일)
spec.selector 서비스가 접근할 Pod의 label 조건

redis Service의 selector는 redis Deployment에 정의한 label을 사용했기 때문에 해당 Pod을 가리킵니다. 그리고 해당 Pod의 6379 포트로 연결하였습니다.

이제 redis에 접근할 counter 앱을 Deployment로 만듭니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: counter
spec:
  selector:
    matchLabels:
      app: counter
      tier: app
  template:
    metadata:
      labels:
        app: counter
        tier: app
    spec:
      containers:
        - name: counter
          image: ghcr.io/subicura/counter:latest
          env:
            - name: REDIS_HOST
              value: "redis"
            - name: REDIS_PORT
              value: "6379"

counter app Pod에서 redis Pod으로 접근이 되는지 테스트 해보겠습니다.

kubectl apply -f counter-app.yml

# counter app에 접근
kubectl get po
kubectl exec -it counter-<xxxxx> -- sh

# curl localhost:3000
# curl localhost:3000
# telnet redis 6379
  dbsize
  KEYS *
  GET count
  quit

Service를 통해 Pod과 성공적으로 연결되었습니다.

 

#Service 생성 흐름

Service는 각 Pod를 바라보는 로드밸런서 역할을 하면서 내부 도메인서버에 새로운 도메인을 생성합니다. Service가 어떻게 동작하는지 살펴봅니다.

API ServerEndpointControllerKube-ProxyCoreDNSservice.ymlService 감시1Endpoint 생성2loopEndpoint 감시3loopEndpoint 변경시iptables 설정Service 감시4loopService 변경시CoreDNS 설정
  1. Endpoint Controller는 Service와 Pod을 감시하면서 조건에 맞는 Pod의 IP를 수집
  2. Endpoint Controller가 수집한 IP를 가지고 Endpoint 생성
  3. Kube-Proxy는 Endpoint 변화를 감시하고 노드의 iptables을 설정
  4. CoreDNS는 Service를 감시하고 서비스 이름과 IP를 CoreDNS에 추가

iptables는 커널kernel 레벨의 네트워크 도구이고 CoreDNS는 빠르고 편리하게 사용할 수 있는 클러스터 내부용 도메인 네임 서버 입니다. 각각의 역할은 iptables 설정으로 여러 IP에 트래픽을 전달하고 CoreDNS를 이용하여 IP 대신 도메인 이름을 사용합니다.

iptables

iptables는 규칙이 많아지면 성능이 느려지는 이슈가 있어, ipvs를 사용하는 옵션도 있습니다.

CoreDNS

CoreDNS는 클러스터에서 호환성을 위해 kube-dns라는 이름으로 생성됩니다.

갑자기 Endpoint가 나왔습니다. Endpoint는 서비스의 접속 정보를 가지고 있습니다. Endpoint의 상태를 확인해 보겠습니다.

kubectl get endpoints
kubectl get ep #줄여서

# redis Endpoint 확인
kubectl describe ep/redis

 

실행 결과

Name:         redis
Namespace:    default
Labels:       <none>
Annotations:  endpoints.kubernetes.io/last-change-trigger-time: ...
Subsets:
  Addresses:          172.17.0.2
  NotReadyAddresses:  <none>
  Ports:
    Name     Port  Protocol
    ----     ----  --------
    <unset>  6379  TCP

Events:  <none>

Endpoint Addresses 정보에 Redis Pod의 IP가 보입니다. (Replicas가 여러개였다면 여러 IP가 보입니다.)

 

#마무리

다음시간에는 다양한 Service들을 실제 사용해보도록 하는 시간을 갖도록 하겠습니다

감사합니다!

'INFRA > DevOps' 카테고리의 다른 글

[Docker] Container 개요  (0) 2022.06.07
IaC란 무엇일까?  (0) 2022.06.03
쿠버네티스 service  (0) 2022.05.30
Jenkins Pipeline (2)  (0) 2022.05.25
Deployment  (0) 2022.05.20

댓글