본문 바로가기
WIKI 기술 지식 베이스

Kubernetes Service

원문 보기 위키 갱신

출처: Kubernetes Service

본문

Service

Service는 Traefik HTTP 서비스의 구현이에요.

전용 CRD는 없으며, Service는 다음의 일부로 존재해요:

  • IngressRoute

  • TraefikService

참고로, IngressRoute나 TraefikService 객체를 만들기 전에 Traefik Kubernetes CRD를 Kubernetes 클러스터에 적용해야 해요.

이렇게 하면 Traefik 전용 리소스가 등록돼요.

Configuration Example (설정 예시)

Service는 아래와 같이 IngressRoute의 일부로 또는 TraefikService의 일부로 선언할 수 있어요:

IngressRoute

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test-name
  namespace: apps
spec:
  entryPoints:
    - web
  routes:
  - kind: Rule
    # Rule on the Host
    match: Host(`test.example.com`)
    services:
    # Target a Kubernetes Service
    - kind: Service
      name: foo
      namespace: apps
      # Customize the connection between Traefik and the backend
      passHostHeader: true
      port: 80
      responseForwarding:
        flushInterval: 1ms
      scheme: https
      sticky:
        cookie:
          httpOnly: true
          name: cookie
          secure: true
      strategy: wrr
      # Attach middlewares to this service
      middlewares:
        - name: my-middleware
          namespace: apps

TraefikService

apiVersion: traefik.io/v1alpha1
kind: TraefikService
metadata:
  name: wrr1
  namespace: apps

spec:
  weighted:
    services:
    # Target a Kubernetes Service
    - kind: Service
      name: foo
      namespace: apps
      # Customize the connection between Traefik and the backend
      passHostHeader: true
      port: 80
      responseForwarding:
        flushInterval: 1ms
      scheme: https
      sticky:
        cookie:
          httpOnly: true
          name: cookie
          secure: true
      strategy: wrr

Configuration Options (설정 옵션)

| Field | Description | Default | Required | | kind | 대상 서비스의 종류예요. 두 값이 허용돼요: - Service: Kubernetes Service TraefikService: Traefik Service. 자세한 내용은 여기를 참고해 주세요. | "Service" | No | | name | 서비스 이름이에요. @ 문자는 허용되지 않아요. 자세한 내용은 여기를 참고해 주세요. | | Yes | | namespace | 서비스 네임스페이스예요. 서비스가 IngressRoute와 같은 네임스페이스에 있으면 비워둘 수 있어요. 자세한 내용은 여기를 참고해 주세요. | | No | | port | 서비스 포트(숫자 또는 포트 이름)예요. kind가 Service인 경우에만 평가돼요. | | No | | responseForwarding. flushInterval | 응답 본문을 복사하면서 클라이언트로 플러시 사이의 간격(밀리초)이에요. 음수 값은 클라이언트로 쓸 때마다 즉시 플러시한다는 뜻이에요. 응답이 스트리밍 응답이면 이 구성은 무시되고, 그러한 응답에 대해서는 쓰기가 즉시 클라이언트로 플러시돼요. kind가 Service인 경우에만 평가돼요. | 100ms | No | | scheme | 업스트림 Kubernetes Service로의 요청에 사용할 스킴이에요. kind가 Service인 경우에만 평가돼요. | "http", port가 443이거나 문자열 https를 포함하면 "https" | No | | serversTransport | Traefik과 서버 사이의 전송을 구성하는 데 사용할 ServersTransport 리소스 이름이에요. kind가 Service인 경우에만 평가돼요. | "" | No | | passHostHeader | 클라이언트 Host 헤더를 서버로 전달해요. kind가 Service인 경우에만 평가돼요. | true | No | | healthCheck.scheme | 헬스 체크 엔드포인트의 서버 URL 스킴이에요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "" | No | | healthCheck.mode | 헬스 체크 모드예요. grpc로 정의하면 gRPC 헬스 체크 프로토콜로 서버를 프로빙해요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "http" | No | | healthCheck.path | 헬스 체크 엔드포인트의 서버 URL 경로예요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "" | No | | healthCheck.interval | 정상 타깃에 대한 헬스 체크 호출 빈도예요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "30s" | No | | healthCheck.unhealthyInterval | 비정상 타깃에 대한 헬스 체크 호출 빈도예요. 정의하지 않으면 interval 값으로 기본 설정돼요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "30s" | No | | healthCheck.method | 헬스 체크 엔드포인트의 HTTP 메서드예요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "GET" | No | | healthCheck.status | 헬스 체크 요청에 대한 응답의 예상 HTTP 상태 코드예요. 타입이 ExternalName인 Kubernetes service에만 적용돼요. 설정하지 않으면 200~399 사이 상태를 기대해요. kind가 Service인 경우에만 평가돼요. | | No | | healthCheck.port | 헬스 체크 엔드포인트의 URL 포트예요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | | No | | healthCheck.timeout | 서버를 비정상으로 간주하기 전에 기다리는 최대 시간이에요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "5s" | No | | healthCheck.hostname | 헬스 체크 요청의 Host 헤더 값이에요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | "" | No | | healthCheck. followRedirect | 헬스 체크 중 리다이렉션을 따라갈지 여부예요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요. | true | No | | healthCheck.headers | 헬스 체크 엔드포인트로 보낼 헤더 맵이에요. kind가 Service인 경우에만, 그리고 타입이 ExternalName인 Kubernetes service에만 평가돼요). | | No | | sticky. cookie.name | 고정 세션(stickiness)에 사용되는 쿠키의 이름이에요. 고정 세션이 활성화되면 첫 응답에 Set-Cookie 헤더가 설정되어 클라이언트가 어떤 서버가 첫 응답을 처리했는지 알 수 있어요. 이후 요청에서 같은 서버로 세션을 유지하려면 클라이언트는 값이 설정된 쿠키를 보내야 해요. 쿠키에 지정된 서버가 비정상이 되면 요청은 새 서버로 전달되고(쿠키는 새 서버를 계속 추적해요). kind가 Service인 경우에만 평가돼요. | "" | No | | sticky. cookie.httpOnly | JavaScript 같은 클라이언트 측 API가 쿠키에 접근하지 못하도록 해요. kind가 Service인 경우에만 평가돼요. | false | No | | sticky. cookie.secure | 쿠키가 암호화된 연결(즉 HTTPS)에서만 전송되도록 허용해요. kind가 Service인 경우에만 평가돼요. | false | No | | sticky. cookie.sameSite | SameSite 정책이에요. 허용 값: -none -lax strict. kind가 Service인 경우에만 평가돼요. | "" | No | | sticky. cookie.maxAge | 쿠키가 만료될 때까지의 초 수예요. 음수면 쿠키가 즉시 만료돼요. 0이면 쿠키가 절대 만료되지 않아요. kind가 Service인 경우에만 평가돼요. | 0 | No | | sticky. cookie.path | 브라우저가 Cookie 헤더를 보내기 위해 요청된 URL에 존재해야 하는 경로예요. 제공되지 않으면 쿠키는 도메인에 대한 모든 요청에서 전송돼요. kind가 Service인 경우에만 평가돼요. | "/" | No | | sticky. cookie.domain | 쿠키가 전송될 호스트예요. kind가 Service인 경우에만 평가돼요. | "" | No | | strategy | 서버 사이의 로드 밸런싱 전략을 정의해요. 지원 값: wrr (가중치 라운드 로빈), p2c (two choices 중 하나), hrw (Highest Random Weight), leasttime (Least-Time). kind가 Service인 경우에만 평가돼요. | "wrr" | No | | nativeLB | Traefik이 제공하는 것이 아닌, 파드 사이에서 Kubernetes Service 로드 밸런싱을 사용할 수 있게 해 줘요. kind가 Service인 경우에만 평가돼요. | false | No | | nodePortLB | 서비스 타입이 NodePort일 때 nodePort IP 주소를 사용해요. Traefik이 Kubernetes 클러스터 외부에 있지만 노드와 같은 네트워크 안에서 실행될 때 서비스에 도달할 수 있게 해 줘요. kind가 Service인 경우에만 평가돼요. | false | No | | middlewares | 서비스에 적용할 Middleware 리소스 참조 목록이에요. 미들웨어는 어떤 라우터가 요청을 전달하든 서비스가 처리하는 모든 요청에 적용돼요. kind가 Service인 경우에만 평가돼요. 자세한 내용은 여기를 참고해 주세요. | | No | | middlewares[n].name | 미들웨어 이름이에요. @ 문자는 허용되지 않아요. | | Yes | | middlewares[n].namespace | 미들웨어 네임스페이스예요. 미들웨어가 IngressRoute와 같은 네임스페이스에 있으면 비워둘 수 있어요. | | No |

ExternalName Service

Traefik 백엔드 생성은 포트가 설정되어야 하지만, Kubernetes ExternalName Service는 포트 없이 정의될 수 있어요. 따라서 Traefik은 다음과 같은 두 가지 방식으로 포트 정의를 지원해요:

  • IngressRoute service에만 정의

  • 양쪽 모두에 정의(포트가 일치하지 않으면 경고가 표시되고 IngressRoute service 포트가 사용돼요)

따라서 양쪽에 포트가 정의된 경우 Traefik은 포트가 일치하기를 기대해요.

Resource에 포트가 정의된 경우

IngressRoute

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test.route
  namespace: apps

spec:
  entryPoints:
    - foo
  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc
      port: 80

Service ExternalName

apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName

Service에 포트가 정의된 경우

IngressRoute

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test.route
  namespace: apps

spec:
  entryPoints:
    - foo
  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc

Service ExternalName

apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80

양쪽에 포트가 정의된 경우

IngressRoute

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test.route
  namespace: apps

spec:
  entryPoints:
    - foo
  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc
      port: 80

Service ExternalName

apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: apps

spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80

Port Definition (포트 정의)

Traefik 백엔드 생성은 포트가 설정되어야 하지만, Kubernetes ExternalName Service는 포트 없이 정의될 수 있어요. 따라서 Traefik은 다음과 같은 두 가지 방식으로 포트 정의를 지원해요:

  • IngressRoute service에만 정의

  • 양쪽 모두에 정의(포트가 일치하지 않으면 경고가 표시되고 IngressRoute service 포트가 사용돼요)

따라서 양쪽에 포트가 정의된 경우 Traefik은 포트가 일치하기를 기대해요.

Example (예시)

IngressRoute

---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test.route
  namespace: default

spec:
  entryPoints:
    - foo

  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc
      port: 80

---
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: default
spec:
  externalName: external.domain
  type: ExternalName

ExternalName Service

---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test.route
  namespace: default

spec:
  entryPoints:
    - foo

  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc

---
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: default
spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80

Both sides (양쪽)

---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test.route
  namespace: default

spec:
  entryPoints:
    - foo

  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: external-svc
      port: 80

---
apiVersion: v1
kind: Service
metadata:
  name: external-svc
  namespace: default
spec:
  externalName: external.domain
  type: ExternalName
  ports:
    - port: 80

Load Balancing (로드 밸런싱)

Kubernetes Service 로드 밸런싱은 아래와 같이 선언하고 사용할 수 있어요:

IngressRoute

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: ingressroutebar
  namespace: default

spec:
  entryPoints:
    - web
  routes:
  - match: Host(`example.com`) && PathPrefix(`/foo`)
    kind: Rule
    services:
    - name: svc1
      namespace: default
    - name: svc2
      namespace: default

K8s Service

apiVersion: v1
kind: Service
metadata:
  name: svc1
  namespace: default

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: traefiklabs
    task: app1
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: default

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: traefiklabs
    task: app2

Kubernetes Service 네이티브 로드 밸런싱

파드 IP로 서버 로드 밸런서를 만들지 않고 Kubernetes Service clusterIP를 직접 사용하려면, 서비스의 NativeLB 옵션을 true로 설정해야 해요. 기본적으로 Traefik은 성능을 위해 백엔드와의 수립된 연결을 재사용한다는 점에 유의하세요. 이는 해당 옵션을 설정했을 때 복제본 사이의 요청 로드 밸런싱이 예상대로 동작하지 않을 수 있게 합니다. 기본적으로 NativeLB는 false예요.

Example (예시)

---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test.route
  namespace: default

spec:
  entryPoints:
    - foo

  routes:
  - match: Host(`example.net`)
    kind: Rule
    services:
    - name: svc
      port: 80
      # Here, nativeLB instructs to build the server load-balancer with the Kubernetes Service clusterIP only.
      nativeLB: true

---
apiVersion: v1
kind: Service
metadata:
  name: svc
  namespace: default
spec:
  type: ClusterIP
  ...

Middlewares (미들웨어)

각 서비스에 미들웨어 목록을 연결할 수 있어요. 미들웨어는 어떤 라우터가 요청을 전달하든 서비스가 처리하는 모든 요청에 적용돼요.

서비스 레벨 미들웨어에 대한 자세한 내용은 service middlewares를 참고해 주세요.

서비스에 미들웨어 연결하기

IngressRoute

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: test-name
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - kind: Rule
      match: Host(`example.com`)
      services:
        - kind: Service
          name: whoami
          port: 80
          middlewares:
            - name: add-header
              namespace: default

Middleware

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: add-header
  namespace: default
spec:
  headers:
    customRequestHeaders:
      X-Custom-Header: "service-middleware"

Whoami Service

apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: default
spec:
  ports:
    - port: 80
  selector:
    app: whoami

Configuring Backend Protocol (백엔드 프로토콜 구성)

Traefik과 파드 사이의 통신을 위한 백엔드 프로토콜을 구성하는 방법은 3가지예요:

  • 스킴을 명시적으로 설정하기 (http/https/h2c)

  • Kubernetes service 포트 이름을 https로 시작하도록 구성하기 (https)

  • Kubernetes service 포트를 443을 사용하도록 설정하기 (https)

위 중 어느 것도 구성하지 않으면 Traefik은 http 연결로 가정해요.

더 알아보기 (Learn more)