Istio Sidecar

개요

사이드카 리소스는 이름 그대로 사이드카 프록시에 대해 설정을 적용하는 리소스이다.
이스티오 버츄얼서비스는 트래픽을 보낼 대상들에 대해 클러스터 설정을 가한다면, 이 놈은 진짜 트래픽을 받을 대상에 대한 설정을 하는 역할을 수행한다.

기능

주 기능은 특정 워크로드가 통신할 대상에 대한 세부 지정을 하는 것이다.
기본적으로 이스티오에서는 메시 내 모든 서비스가 다른 모든 서비스의 모든 포트를 알도록 세팅된다.
이는 컨트롤 플레인에서 데이터 플레인으로 보낼 설정 파일 크기 자체를 증가시키고, 설정을 받아야 할 워크로드 수를 증가시키기 때문에 대규모 클러스터 환경에서는 심각한 성능 저하를 초래할 수 있다.
그래서 통신이 필요한 사이드카끼리만 관련한 설정이 전달되도록 바운더리를 짓는 작업을 해줘야 하는데 이때 사용하는 것이 이 사이드카 리소스이다.

위의 케이스를 해결하는 흔한 전략은 워크로드에서 나가는 트래픽에 대해 설정을 하는 것이다.
기본적으로 모든 프록시는 아예 서로를 모르고 컨트롤 플레인만 알도록 세팅을 먼저 한 상태에서 필요한 프록시끼리만 사이드카 리소스 설정을 통해 통신이 가능하도록 열어주는 것이다.
필요한 범위에 필요한 설정만 들어가니 성능 향상을 기대할 수 있고, 추가적으로 불필요한 트래픽 접근성을 줄이니 보안적으로도 이득이다.
(그렇다고 해서 나가는 트래픽을 제어한다는 것은 아니니 주의하자)

이놈도 셀렉팅 방식이 다른 리소스들과 똑같다.

게이트웨이에는 설정되지 않는다.

일반 패턴

apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
  name: default
  namespace: istio-system
spec:
  egress:
  - hosts:
    - "./*"
    - "istio-system/*"

셀렉터 없이 모든 네임스페이스에서 나가는 트래픽에 대한 설정을 하는 예시다.
이렇게 하면 기본적으로 모든 프록시들은 자신 네임스페이스와 루트 네임스페이스를 제외한 엔드포인트를 아예 모르게 된다.
이걸 먼저 세팅하고 다른 사이드카 리소스들을 만들어서 특정한 경로를 더 알게 해준다던가 하는 게 기본 방침.

양식 작성법

apiVersion: networking.istio.io/v1
kind: Sidecar
metadata:
  name: ratings
  namespace: prod-us1
spec:
  workloadSelector:
    labels:
      app: ratings
  ingress:
  - port:
      number: 9080
      protocol: HTTP
      name: somename
    defaultEndpoint: unix:///var/run/someuds.sock
  egress:
  - port:
      number: 9080
      protocol: HTTP
      name: egresshttp
    hosts:
    - "prod-us1/*"
  - hosts:
    - "istio-system/*"

기본적으로 이 리소스의 대상이 될 워크로드를 라벨로 선택하고, 이후에 인그레스와 이그레스에 대해 설정한다.
ingress에서는 워크로드에 들어올 수 있는 트래픽에 대한 설정을 진행한다.
만약 이 필드가 없다면 해당 워크로드 리소스 양식에서 자체적으로 포트나 관련 서비스 등의 정보를 얻어내어 알아서 설정된다.
있다면 워크로드와 서비스와 연결되는 포트만 설정된다.
egress에서는 해당 워크로드에서 나갈 수 있는 트래픽에 대한 설정을 한다.

ingress

  ingress:
    - port:
        number: 80
      bind: localhost
      defaultEndpoint: 127.0.0.1:8080
      captureMode: DEFAULT
      connectionPool:
        http:
          h2UpgradePolicy: DEFAULT
      tls:
        mode: SIMPLE

port는 필수 필드이다.
bind는 리스너가 받을 호스트 이름, defaultEndpoint는 트래픽을 보낼 어플리케이션의 엔드포인트를 나타낸다.
defaultEndpoint에는 127.0.0.1, 0.0.0.0이나 unix:{소켓 파일 경로}밖에 넣을 수 없다.

captureMode는 트래픽을 어디에서 캡쳐할지 지정하는 필드이다.
보통 워크로드에 초기화 컨테이너를 통해 iptables를 세팅하다보니 흔히 쓸 일은 없긴 하다.
그래서 어떤 포트를 설정하더라도 알아서 엔보이가 기본으로 트래픽을 수신받는 15001 포트로 트래픽이 들어가게 될 것이다.

annotations:
  sidecar.istio.io/interceptionMode: "NONE"
  sidecar.istio.io/includeInboundPorts: "0"

그런데 위와 같이 프록시 설정에 includeInboundPorts: "0", interceptionMode: NONE 등의 설정을 넣게 되면 iptables 세팅이 되지 않으며, 그럴 경우에는 사이드카 리소스로 이 필드를 필수적으로 세팅해야 한다.
(참고로 Istio Operator 양식, Istio ProxyConfig 등을 통해서도 설정할 수 있다.)

tls 필드에는 mode만 넣을 수 있으며 현재는 그냥 mTLS할지 그냥 할지(SIMPLE, MUTUAL)만 지정할 수 있다.
connectionPool은 말 그대로 커넥션 풀 세팅인데 아래 [[#inboundConnectionPool]] 참고.

apiVersion: networking.istio.io/v1alpha3
kind: ProxyConfig
metadata:
  name: custom-proxy-config
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  proxyMetadata:
    ISTIO_META_INTERCEPTION_MODE: "NONE"
    ISTIO_META_INCLUDE_INBOUND_PORTS: "0"

egress

  egress:
  - hosts:
    - "*/mysql.foo.com"
    port:
      number: 3306
      protocol: MYSQL
      name: egressmysql
    captureMode: NONE # 프록시 전역 세팅으로 들어가 있으면 필요 없음
    bind: 127.0.0.1

egress도 설정법 자체는 ingress와 비슷하다.
대신 hosts 필드가 있고 이 값이 필수이다.
이 필드는 {네임스페이스}/{DNS이름}으로 설정해주면 된다.

inboundConnectionPool

inboundConnectionPool는 엔보이가 받을 커넥션에 대한 설정을 하는 필드로, 이스티오 데스티네이션룰의 커넥션 풀과 똑같은 방식으로 작성한다.
이 값은 모든 리스너 설정, 그리고 ingress 필드에 명시된 포트에 대해 각각 적용된다.

흔히 알기로, 커넥션 풀은 이스티오 데스티네이션룰을 통해 트래픽을 보내는 엔보이 측에 대해 설정하는 값이다.
그러나 사실 엔보이 리스너 쪽 네트워크 필터에도 커넥션에 대한 설정을 할 수 있는 부분이 있다.[1]
즉 이스티오에서 커넥션 풀로서 제공하는 필드는 사실 요청을 보낼 엔보이의 클러스터 설정, 그리고 요청을 받을 엔보이의 리스너 설정을 짬뽕하여 추상화한 것이다.
아무튼 사이드카 리소스에서 커넥션 풀은 리스너 쪽에 적용되는 설정이다.
이로 인해 사이드카 리소스 설정과 데룰의 설정이 겹치는 구간이 발생할 수 있다.
그럴 때는 한쪽이 덮어씌워지며, 다음의 순서로 우선권을 가진다.

outboundTrafficPolicy

  outboundTrafficPolicy:
    mode: ALLOW_ANY

outboundTrafficPolicy는 트래픽이 나갈 때 관련한 정책을 넣는 필드이다.
ALLOW_ANY는 어떤 곳으로든 트래픽이 나갈 수 있음을 뜻하며, 메시 외부로 나가는 트래픽에 대해 이스티오 이그레스 게이트웨이를 설정하지 않는다면 이걸 웬만해서 사용하게 될 것이다.
REGISTRY_ONLY를 하면 메시 내에서 인식되지 못하는 모든 엔드포인트로의 트래픽은 드랍된다.
이때는 Istio ServiceEntry를 이용해야 할 것이다.

관련 문서

Dataview: custom view not found for 'scripts/templates/dataview-tp/subnotelist.js' or 'scripts/templates/dataview-tp/subnotelist/view.js'.

참고


  1. https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/connection_limit_filter ↩︎