MirantisKubernetes で Istio Ingress

# はじめに
前回は以下の記事で MirantisKubernetes (旧 DockerEnterprise) を構築してみました。

> MirantisKubernetes構築（旧DockerEnterprise）
> https://qiita.com/t_ume/items/2350e4f3cf283de38aac

今回は構築した MirantisKubernetes に Istio Ingress を導入し外部から Pod にアクセスを行ってみます。
構築にあたり、CREATIONLINE さんのページを参考にさせて頂きました。

> Istio Ingress入門：Kubernetesアプリのトラフィックを簡単に管理する方法
> https://www.creationline.com/lab/35694)

また Istio についての図解は以下のサイトが分かりやすかったので、ご紹介までに。

> Istio 導入への道 – 図解
> https://blog.1q77.com/2020/03/istio-part10/

# 環境構成
MirantisKubernetes の構築は上記にある前回の記事を参考に構築しています。

**ホストマシン**
- Windows 10 Pro (20H2)
- VirtualBox：6.1.16
- Vagrant：2.2.14

**ゲストマシン**
- ubuntu：18.04.5
- docker-ee：19.03.12
- k8s：1.18.8
- launchpad：1.1.0

|役割|ホスト名|台数|vCPU|Memory|IP Address|
|:---|:---|:---:|:---:|:---:|:---|
|Manager|k8s01|1|4|16 Gi|192.168.10.70|
|Worker|k8s02|1|4|16 Gi|192.168.10.71|
|Client|lpd01|1|2|8 Gi|192.168.10.72|

※Windows 側の hosts ファイル (C:\Windows\System32\drivers\etc\hosts) に以下を登録しています
※「k8s01」は WebUI 用に、「httpbin.internal」はアクセス確認用に登録しています

```
192.168.10.71 k8s01
192.168.10.70 httpbin.internal
```

# IngressGateway 作成
まずは Istio を構築します。GUI からさくっと作れます。

1. 左メニューから「admin」⇒「Admin Settings」をクリック
2. 「Ingress」をクリックし「HTTP ingress for Kubernetes」画面が表示される
3. 「HTTP ingress for Kubernetes enabled」を有効化（クリックすると●が右に移動し、色が灰色から青に変わる）
4. 「Save」をクリックして完了

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/cf089704-415a-bef2-e91c-7c8bdf79f376.png)

※外部アクセスとして NodePort でサービスが公開されます。
　また、ポート指定が「Configure proxy」で出来ます。
　（デフォルトでは HTTP：33000、HTTPS：33001 で公開されます）
※注意書きにもあるのですが導入されるのは Istio Ingress のみのため、フルサービスメッシュの導入、関連する UI の導入をする場合は一般的なIstioの導入をお勧めします
> Istio Getting Started
> https://istio.io/latest/docs/setup/getting-started/

「Save」すると通知のポップアップが出ます。
「Dashboad」の画面に戻り、デプロイを確認します。

1. 「Kubernetes」⇒「Namespaces」をクリック
2. 「istio-system」をマウスオーバーし、「Set Context」をクリックすると、対象「Namespace」が変更されます<br>※「Namespaces」の下の灰色の枠の表示が変わります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/4ce4c99c-aa6f-e051-470e-835819ee39a6.png)
3. 「Controllers」、「Services」、「Pods」などを確認し、istio の各コンポーネントが構築されていることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/cb9006c8-da51-e4c6-ec95-2e5ef54cb92d.png)

# Pod デプロイ
アクセス確認用に Pod を作成します。

1. 「Kubernetes」⇒「Namespaces」で対象の「Namespace」を「default」に戻します
2. 「Kubernetes」の下にある「Create」をクリックしするとオブジェクトの作成画面が表示されます
3. 「Namespace」で「default」を選択し、「Object YML」に以下を入力し、「Create」をクリックします

```yaml:SamplePod
apiVersion: v1
kind: ServiceAccount
metadata:
  name: httpbin
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
      version: v1
  template:
    metadata:
      labels:
        app: httpbin
        version: v1
    spec:
      serviceAccountName: httpbin
      containers:
      - image: docker.io/asankov/httpbin:1.0
        imagePullPolicy: IfNotPresent
        name: httpbin
        ports:
        - containerPort: 80
```

これでデプロイ完了です。
「Controllers」や「Pods」で Pod が起動していることを確認しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/683cf560-972b-a04e-3a19-cf16eaf3f26f.png)

# Gateway / VirtualService 作成
最後にアクセス用の設定を行っていきます。
受け口の「Gateway」と経路設定の「VirtualService」を作成していきます。

## Gateway 作成
1. 「Kubernetes」⇒「Ingress」と辿り、「Gateways」タブの「Create」をクリック
2. 以下を指定し、「Generate YML」をクリック<br>Gateway name：httpbin-gateway<br>Protocol：HTTP<br>Port number：80<br>Port name：gateway-port<br>Hosts：*
3. 生成された yaml が表示されます。<br>「Namespace」で「default」を選択し、「Create」をクリックし作成します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/1914a662-c354-4e36-752b-81206be1be8e.png)

## VirtualService 作成
次に VirtualService を作成します。

1. 「Kubernetes」⇒「Ingress」と辿り、「Virtual Services」タブの「Create」をクリック
2. 以下を指定し、「Generate YML」をクリック<br>Virtual service name：httpbin-vs<br>Hosts：*<br>Gateways：httpbin-gateway
3. 生成された yaml が表示されます。「Namespace」で「default」を選択します。<br>行末に以下を追記し、「Create」をクリック

```yaml:VirtualService
・・・
  gateways:
    - httpbin-gateway
以下を追記
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: httpbin
        port:
          number: 8000
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/2021f034-9c8c-c80b-7e50-f7c0548db3b6.png)

# アクセス確認（IP / Port 指定）
設定が完了したのでアクセスしてみます。
http://```<worker ノードのIP>```:33000
※今回の設定では「http://192.168.10.72:33000/」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/a5965d02-16a0-724d-5aba-f7c7f100ce7e.png)

今度は FQDN でアクセスできるように設定を変更していきます。

# Gateway / VirtualService 修正

## Gateway 修正
1. 「Kubernetes」⇒「Ingress」と辿り、「Gateways」タブで「httpbin-gateway」をクリック
2. 右上の歯車アイコンをクリックし、yaml 編集画面が表示されるので以下を修正し、「Save」をクリック

```
・・・
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - 'httpbin.internal'　　★「*」から「httpbin.internal」に修正
    port:
・・・
```

## VirtualService 修正
1. 「Kubernetes」⇒「Ingress」と辿り、「Virtual Services」タブで「httpbin-vs」をクリック
2. 右上の歯車アイコンをクリックし、yaml 編集画面が表示されるので以下を修正し、「Save」をクリック

```
spec:
  gateways:
  - httpbin-gateway
  hosts:
  - 'httpbin.internal'　　★「*」から「httpbin.internal」に修正
  http:
・・・
```

# nginx 構築
FQDN アクセス用に今回はリバースプロキシとして nginx を構築します。
テスト用なので launchpad を動かしたサーバ（lpd01：192.168.10.70）に構築します。

```shell-session
$ sudo apt-get update
$ sudo apt-get install nginx
$ nginx -v
nginx version: nginx/1.14.0 (Ubuntu)
```

アクセス用に設定ファイルを作成します。
※server_name：アクセス FQDN
※proxy_pass：転送先サーバの IP / Port
※istio が HTTP/1.0 では受信出来ないため、「proxy_http_version」で 1.1 を指定
※リクエストヘッダにホストヘッダを指定するため「proxy_set_header」を指定


```shell-session
$ sudo vi /etc/nginx/conf.d/httpbin.internal
以下を入力
server {
    server_name httpbin.internal;

    location / {
        proxy_pass http://192.168.10.72:33000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
    }
}
```

設定ファイルを確認し、nginx に再読み込みさせます。

```shell-session
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

$ sudo systemctl reload nginx
```

# アクセス確認（FQDN 指定）
[環境構成](https://qiita.com/drafts#%E7%92%B0%E5%A2%83%E6%A7%8B%E6%88%90) の作業で hosts に FQDN を設定していたので、以下でアクセスし確認します。
http://httpbin.internal/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317159/6d72bb00-6085-5d7c-9b06-4277e32a787f.png)

# まとめ
今回は Mirantis Kubernetes で Istio Ingress を利用してみました。
作業自体は簡単に導入できるのですが、Gateway や VirtualService などの設計をしていくのが難しいのかなと感じました。
特に VirtualService の設定は色々指定できるので、本家サイトを読んで勉強できればと思います。

> Istio Virtual Service
> https://istio.io/latest/docs/reference/config/networking/virtual-service/

※ちなみに FQDN を利用して画面を出すのに数日かかりました、ずっと 404 で・・・
　nginx でリクエストヘッダに Host を付与し忘れていて（泣）
> 404 if VirtualService.spec.hosts is set to FQDN
> https://github.com/istio/istio/issues/11828