地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【k8s】Istioを使ってB/Gとかカナリーとかやってみる

概要

istio/envoyを使ってB/Gデプロイとかカナリアリリースとかを試してみた際のメモです。

github.com

github.com

Istio/Envoyとは

ざっくりいうとクラウドネイティブなWebサービスのために設計されたロードバランサーのツール群。サービスメッシュの通信なんかを(多分)楽にしてくれるツールです。分散システムを構築・運用する際に直面する課題を解決してくレたりもします。

IstioがコントロールプレーンならEnvoyはデータプレーンに相当する。

https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F14124%2Fc8b259b2-5c8a-256c-0a1f-5c3ab71a5b66.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=97dc759e81ba41ec58afc526d7687f9b

https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F3470%2Fa7f18d7e-840a-a31b-fad9-57459298558c.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=dbf2bbf39db8a2438477b453a49dea84

Istioを利用すればこんな感じのプロキシーサイドカーとして手間なく組み込むことができます。

Istioのインストール

最新版を以下の手順で入れます。特に困ることはなかったですが情報が古い記事が多く今は使えない手順が多かったので公式をみておくのが一番良さげです。

Istio / Getting Started

サンプルアプリを作成する

B/Gやるにしろカナリアをやるにしろアプリケーションの変更が分かりやすい仕組みが必要なので以下のimageを使用してサンプルDeploymenとServiceを生成します。

Docker Hub

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin-deployment-v1
  labels:
    app: httpbin
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            path: /status/200
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /status/200
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 5
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin-deployment-v2
  labels:
    app: httpbin
    version: v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v2
  template:
    metadata:
      labels:
        app: httpbin
        version: v2
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            path: /status/200
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /status/200
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin-service
spec:
  selector:
    app: httpbin
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80

動作確認としてClusterIPに対してcurlを実行して問題ないことを確認します。この時点ではサイドカーはデプロイされていないのでhttpヘッダーは特に何も設定されていません。

inject

kube-injectを毎回実行する必要をなくすために以下のコマンドでサイドカーのinjectを自動実行させるよう設定します。istioctl kube-inject -f ${yaml}を都度打つ必要がなくなります。

$ kubectl label namespace default istio-injection=enabled

$ kubectl describe namespaces default
Name:         default
Labels:       istio-injection=enabled
Annotations:  <none>
Status:       Active

No resource quota.

No LimitRange resource.

この設定を有効化したら先ほど作成したサンプルアプリをapplyします。その後にcurlをすることでhttpヘッダーにenvoyの情報が追加されていることを確認します。

curl -o /dev/null -sv 10.107.7.138
* About to connect() to 10.107.7.138 port 80 (#0)
*   Trying 10.107.7.138...
* Connected to 10.107.7.138 (10.107.7.138) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.107.7.138
> Accept: */*
>
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Sun, 20 Dec 2020 03:56:29 GMT
< content-type: text/html; charset=utf-8
< content-length: 9593
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 2
< x-envoy-decorator-operation: httpbin-service.default.svc.cluster.local:80/*
<
{ [data not shown]
* Connection #0 to host 10.107.7.138 left intact

Destination Rule

Destination Ruleはサービスへのルーティングを定義するためのカスタムリソースです。

Istio / Destination Rule

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: httpbin-destination-rule
spec:
  host: httpbin-service
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

Virtual Service

Virtual Serviceは実際のトラフィックの流量を制御するための設定を記載します。以下ではカナリアリリースを想定しv1へ90%のトラフィックを10%をアップデート対象のv2へとトラフィックを流す設定です。

Istio / Virtual Service

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: httpbin-virtual-service
spec:
  hosts:
  - httpbin-service
  http:
  - route:
    - destination:
        host: httpbin-service
        subset: v1
      weight: 90
    - destination:
        host: httpbin-service
        subset: v2
      weight: 10

その他できること

  • パスベースでアプリバージョンを制御
  • httpヘッダーベースでアプリバージョンを制御
  • cookieなどで宛先podをある程度固定できる

訳しながら理解していくIstio_Traffic Management編 - Qiita

まとめ

Istio/Envoyはさっとやる分には便利。ただブラックボックスな点が多いので今後もちゃんと理解していかないと運用には持っていけないなという印象。