본문 바로가기

인프라/kubernetes

kubernetes 서비스

서비스: 클라이언트가 파드를 검색하고 통신을 가능하게 한다.

파드가 다른 파드에게 서비스를 제공하려면 다른 파드를 찾아야한다.

만약 서버의 정확한 ip 주소나 호스트를 이용해 접근을 한다면 이런 문제점을 갖는다.

 

  • 파드는 일시적이기 때문에, 언제든 사라지거나 이동 할 수 있다.
  • 쿠버네티스는 노드에 파드를 스케줄링 한 후 파드가 시작되기 전에 ip를 할당해서 미리 ip를 알 수 없다.
  • 수평 스케일링은 여러 파드가 동일한 서비스를 제공 할 수 있음을 의미하는데, 클라이언트는 어떤 파드에 요청 하는지 알 수 없어야 한다. 모든 파드는 단일 ip로 엑세스 할 수 있어야 한다.
  1.  

이러한 문제를 해결하려고 또 다른 리소스 유형인 서비스(Service) 를 제공.

 

서비스 소개

서비스란? 
동일한 기능을 파드 그룹에 지속적으로 단일 접점을 만들려고 할 때 생성하는 리소스다.

각 서비스는 서비스가 존재하는 동안 절대 바뀌지 않는 ip 주소와 포트가 있다.

클라이언트는 해당 ip와 포트로 접속해서 해당 기능을 제공하는 파드로 연결 된다.

 

 

 

서비스 생성

서비스가 파드를 찾는 방법

  • 레이블 셀렉터를 이용한다.

레이블 셀렉터를 이용해 어떤 파드가 서비스에 속하는지 정한다.

 

 

YAML 디스크립터를 통한 서비스 생성

- YAML 파일 생성

 

apiVersion: v1 
kind: Service 
metadata: 
  name: kubia
spec:
  ports:
    - port: 80 # 서비스가 사용할 포트
      targetPort: 8080 # 서비스가 포워딩 할 포트
  selector:
    app: kubia # 레이블 셀렉터 설정

 

서비스 검사하기

kubectl get svc

 

서비스 테스트 하기

파드를 조회해보고 다음과 같은 명령어를 실행해본다

실행 결과 확인

kubectl exec kubia-7szjl -- curl -s http://10.111.249.153

 

 

- 동작 방식 

kubectl exec 로 파드 접속

curl 명령어를 실행하면 컨테이너 내에서 명령어가 실행된다.

curl은 HTTP GET 메서드로 요청을 보내고 서비스에서는 HTTP 연결을 임의의 파드로 연결한다.

HTTP 응답을 curl로 전송이되고

결과를 화면에 출력한다.

 

 

서비스에서 여러 포트 노출 가능

apiVersion: v1
 kind: Service
 
metadata:
  name: kubia
 
spec: 
  ports :
    - name: http
      port: 80
      targetPort: 8080
    - name: https
      port: 443
      targetPort: 8443
  selector:
    app: kubia 

 

타켓 포드를 지정 이름으로도 사용할 수 있다.

 

targetPort 에 pod name 으로 쓸 수 있다.

 

 

클러스터 외부에 있는 것들과의 연결

서비스가 클러스터 내부 파드가 아니라 외부 ip와 포트로 연결을 전달 할 수도 있다. 

 

 

 

 

서비스는 파드에 직접 연결되지 않고 그 사이에 Endpoint Resource가 있다.

kubectl describe svc <<서비스명>>

으로 서비스의 endpoint를 알 수 있다.

 

 

서비스의 엔드포인트 수동 구성

 

엔드포인트를 수동으로 구성할 수 있다.

파드 셀렉터 없이 서비스를 만들면 유저가 직접 엔드포인트 리소스를 만들어서 적용 할 수 있다.

 

apiVersion: v1
kind: Endpoints
metadata:
 name: external-service # 서비스의 이름과 일치해야 한다
 subsets: - addresses: # 서비스가 연결을 전달할 엔드포인트의 IP
   - ip: 11.11.11.11
   - ip: 22.22.22.22
   ports:
    - port: 80 # 엔드포인트의 대상 포트

 

FQDN 으로 더 간단하게 만들수도있다.

- External Name 서비스 생성

 

외부 클라이언트에 서비스 노출

외부 클라이언트에서 클러스터에 접속하고 싶으면 어떻게 해야 할까

 

  • 노드 포트로 서비스 유형을 설정 - 노드 포트 서비스는 각 클러스터 노드 자체에서 포트를 열고 해당 포트로 수신된 트래픽을 서비스로 전달한다.
  • 서비스 유형을 로드밸런서로 설정 
  • 단일 ip 주소로 여러 서비스를 노출하는 인그레스 리소스 만들기

 

노드 포트에 연결하는 외부 클라이언트

 

노드포트 서비스

  • 쿠버네티스는 모든 노드에 특정 포트를 할당하고 서비스를 구성하는 파드로 들어오는 연결을 전달

노드 포트 서비스 생성

apiVersion: v1
kind: Service
metadata:
  name: kubia-nodeport
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30123 #

 

 

 

첫번째 노드에 30123 포트로 온 연결은 첫번째 또는 두번째 노트에 실행 중인 파드로 연결이 전달된다.

 

외부 로드 밸런서로 노출

로드밸런서는 공개적으로 접근 가능한 고유 IP 주소를 가지고 모든 연결을 서비스에 전달한다.

따라서 로드밸런서 ip로 서비스에 연결 할 수 있다.

 

 

로드 밸런서 생성

apiVersion: v1
 
kind: Service
metadata:
  name: loadbalancer
spec: 
  type: LoadBalancer
  ports:
   - port: 80
     targetPort: 8080
 
selector:
  app: podName

 

kubectl get svc loadbalancer

로 명령어를 치면 external ip 가 나온다.

해당 ip로 서비스에 접근 가능하다.

 

 

ingress

 

인그레스는 한개의 ip 주소로 수십개의 서비스에 접근이 가능하도록 지원한다.

클라이언트가 HTTP 요청을 인그레스에 보낼때 요청한 호스트와 경로에 따라 요청을 전달할 서비스가 결정된다.

 

 

인그레스 생성

 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubia
  spec:
    rules:
- host: kubia.example.com # 인그레스는 해당 도메인 이름을 서비스에 매핑
http:
  paths:
    - path: / # 모든 요청은 kubia-nodeport서비스의 포트 80으로 전달
      backend:
        serviceName:kubia-nodeport
        servicePort: 80

 

파드가 연결을 수락할 준비가 됐을 때 신호 보내기

레디니스 프로브

주기적으로 특정 파드가 요청을 수신할 수 있는지 결정

컨테이너의 레디니스 프로브가 성공을 반환하면 요청을 수락할 준비가 됐다

 

레디니스 프로브 유형

  • exec 프로브: 컨테이너 상태를 프로세스의 종료 상태 코드로 결정
  • http get 프로브: http get 요청을 보내고 응답의 상태 코드를 보고 결정
  • tcp socket 프로브: tcp 연결을 열어서 소켓이 연결되면 준비된 것으로 결정

 

 

라이브니스 프로브와 레디니스 프로브 차이

  • 라이브니스 프로브: 상태가 좋지 않은 컨테이너를 제거하고 새롭고 건강한 컨테이너로 교체에 파드의 상태를 정상으로 유지
  • 레디니스 프로브: 요청을 처리할 준비가 된 파드의 컨테이너만 요청을 수신

'인프라 > kubernetes' 카테고리의 다른 글