Kubernetes, Istioの環境構築(Linux, kind, istioctl使用、helm 不使用)


この記事は2019新卒 エンジニア Advent Calendar 2019の11日目の記事です。

普段業務でkubernetesやistioに触れる機会が多いので、復習も兼ねて環境構築の一例を紹介したいと思います。

(登場するIPアドレスは一時的なものなのでアクセスしても何もありません。。。)

予備知識

kubernetesとは

宣言的に管理できるコンテナオーケストレーションツールです。

yamlという形式で(ある必要はないですが)「nginxのイメージを使ったコンテナを3台立ち上げる」と書いておけば3台立ち上げてくれて、立てたコンテナに負荷分散する形でサービスを公開したり、ヘルスチェックしてリスタートしたりと、コンテナアプリケーションをデプロイする上で必要な機能が揃っています。

kubernetesは通常複数のNodeから構成され、Nodeというのはコンテナのホストとなるマシンのことで物理マシンだったりVMだったりします。

Node上には複数のコンテナが展開することになるのですが、このコンテナの1まとまりをPodと呼びます。

Podの中のコンテナは互いにファイルシステムやIPアドレスを共有するという特徴があり、1つのPodが複数のNodeに跨ってdeployされることはありません。

istioとは

サービスメッシュを実現するためのツールです。これをkubernetes内で動かすことで、各コンテナごとに専用のプロキシがついて全ての通信がそのプロキシを経由するようになるため、可観測性が上がり、リトライしたりサーキットブレーカーを導入したりといったことがやりやすくなります。

istioはkubernetes上ではPodの中に専用のプロキシとして動作するコンテナが入る形になるため、1つのPodにアプリケーション用のコンテナとプロキシ用のコンテナが入ることになります。

本題

環境構築

環境構築は面倒なのでconohaでVPSを借ります。1時間1円程度で汚れない環境が手に入ると思うと安いですね。自宅のネットの上り下りが1Mbpsなことを考慮しても賢い選択肢だと思います。

OS: Ubuntu 18.04.2 LTS
Docker: 19.03.1

kind(kubernetes)

今回はdocker環境でk8sを動かせるkind(kubernetes in docker)を使っていきます。実際のkubernetesを使えればそれでいいのですが、テストで使うにはわざわざ感があるので、kindを使います。

簡易的なk8sを実現するツールは、k3sやminikubeなど他の選択肢もあるのですが、今回はkindを使っていきます。

quick-startを頼りにinstallします。公式のコンポーネントのテストにも使われています。
https://kind.sigs.k8s.io/docs/user/quick-start/

curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.6.1/kind-$(uname)-amd64
chmod +x ./kind
mv ./kind /usr/local/bin/kind

kindはマルチノードを作ることができるので、折角なので利用しましょう。

config.yml
kind: Cluster
apiVersion: kind.sigs.k8s.io/v1alpha3
nodes:
- role: control-plane
- role: worker
- role: worker

そして適用しましょう。

kind create cluster --config config.yml

kubectl

kubectlというコマンドラインツールもinstallしましょう。
公式

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl

うまく行けばnodeの情報が取れると思います。

root@150-95-200-74:~# kubectl get node
NAME                 STATUS   ROLES    AGE    VERSION
kind-control-plane   Ready    master   117s   v1.16.3
kind-worker          Ready    <none>   75s    v1.16.3
kind-worker2         Ready    <none>   75s    v1.16.3

マルチノードなclusterを作成することができました。

istio

次にistioを入れます。istioは1.3まではhelmというkubernetesのパッケージマネージャ的なやつを使って入れることができましたが、最近リリースされた1.4ではhelmは使えなくなりました。代わりにistioctlというクライアントツールを利用します。(やっていることは大量のyamlファイルをいい感じに適用してくれるだけです)

こちらをもとに入れていきます。
https://istio.io/docs/setup/getting-started/

curl -L https://istio.io/downloadIstio | sh -
cd istio-1.4.1
mv bin/istioctl /usr/local/bin
# pathを通せれば何でもいいです

istioctl manifest apply --set profile=demo

これでistioの主要なコンポーネントがinstallされたので機能を使うことができるようになります。

root@150-95-200-74:~# kubectl get pod -A
NAMESPACE      NAME                                         READY   STATUS    RESTARTS   AGE
istio-system   grafana-6b65874977-j8htn                     1/1     Running   0          5m11s
istio-system   istio-citadel-86d9c5dc-6fwrh                 1/1     Running   0          5m12s
istio-system   istio-egressgateway-7cb7fdff55-hmskf         1/1     Running   0          5m13s
istio-system   istio-galley-6ff4cbc457-rvm7s                1/1     Running   0          5m12s
istio-system   istio-ingressgateway-68884574c5-9skg7        1/1     Running   0          5m14s
istio-system   istio-pilot-5646cc96d4-nc49t                 1/1     Running   0          5m12s
istio-system   istio-policy-7c76fb7fdb-kfvg9                1/1     Running   3          5m14s
istio-system   istio-sidecar-injector-5464f6dff-7t4bt       1/1     Running   0          5m12s
istio-system   istio-telemetry-557d4bf784-n7xf8             1/1     Running   3          5m13s
istio-system   istio-tracing-c66d67cd9-ckxqd                1/1     Running   0          5m14s
istio-system   kiali-8559969566-nf4th                       1/1     Running   0          5m12s
istio-system   prometheus-66c5887c86-kf9rw                  1/1     Running   0          5m12s
kube-system    coredns-5644d7b6d9-8wpjp                     1/1     Running   0          10m
kube-system    coredns-5644d7b6d9-fhw2n                     1/1     Running   0          10m
kube-system    etcd-kind-control-plane                      1/1     Running   0          10m
kube-system    kindnet-jx4qc                                1/1     Running   0          10m
kube-system    kindnet-v2bch                                1/1     Running   0          10m
kube-system    kindnet-x2v8c                                1/1     Running   0          10m
kube-system    kube-apiserver-kind-control-plane            1/1     Running   0          9m52s
kube-system    kube-controller-manager-kind-control-plane   1/1     Running   0          9m53s
kube-system    kube-proxy-2dgzx                             1/1     Running   0          10m
kube-system    kube-proxy-gw9ld                             1/1     Running   0          10m
kube-system    kube-proxy-hdtw9                             1/1     Running   0          10m
kube-system    kube-scheduler-kind-control-plane            1/1     Running   0          10m
root@150-95-200-74:~#

まだ何のアプリケーションも動かしていないのに凄いコンポーネントの量ですね

istioのサンプルアプリケーションを動かしてみる

空っぽだとつまらないので、サンプルアプリケーションを動かしてみましょう。
https://istio.io/docs/examples/bookinfo/#deploying-the-application

kubectl label namespace default istio-injection=enabled
# defaultというnamespaceにラベルを付けて、全てのpodに自動的にistioのプロキシを追加するようにするコマンド。こういう形でdefaultのnamespaceを普通は汚したくない笑

# istio-1.4.1配下にsamplesディレクトリがある
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

# gatewayとvirtual serviceというリソースの追加。
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

GatewayはLoad Balancerに対して特定のリクエストを取得するための設定です。hostがhogehogeで、portが80番はこのGatewayで受け付けるといった感じです。

VirtualServiceは、Gatewayと合わせて利用することで、L7の情報を利用してルーティングの設定を行うことができ、今回は先程設定したGatewayを通ったリクエストのうち特定のpathに合致するものをproductpageというserviceに送る設定となっています。

VirtualServiceを利用してheaderを追加したり、削除したりも出来るので触る機会が多いリソースです。

実際にアクセス!

さて、これでbookinfoというアプリケーションがkubernetes上で動いています。実際にブラウザからアクセスしてみましょう。

もし今動かしている環境がAKSGKEなどのマネージドサービスを利用している場合はistioのLoad BalancerのIPにアクセスできますが、今回はそうではないので、リクエストを振り分けるPodにport-forwardを経由してアクセスします。(詳しく知りたい方はkubernetesのServiceのLoadBalancer typeを調べてみてください)

kubectl port-forward -n istio-system istio-ingressgateway-68884574c5-9skg7 80:80 --address 0.0.0.0

istio-ingressgateway-68884574c5-9skg7というのはPod名で取得するためにはkubectl get pod -n istio-systemなどを実行してください。

addressオプションを使用してlocalhost以外でもアクセスできるようにしているので、今動かしているhostのIPアドレス/productpageにブラウザからアクセスしてみましょう。

おめでとうございます。こんなページが表示されれば実際にアクセスすることが出来ています。

ほんとにアクセス出来ているの?という懐疑心旺盛な方のためにistioのvisualizeツール的な存在であるkialiを使って見てみましょう。

本来であればistioctl dashboard kialiというコマンドを叩けばport-forwardされてブラウザが開くのですが、何分sshしている身ですので、localhostで見れても仕方がないのでもう一度先程のようなコマンドを叩きます。

kubectl port-forward -n istio-system kiali-8559969566-nf4th  --address 0.0.0.0 80:20001

kialiはコンテナが20001番で公開しているのでそれに合わせるために上記のような形になります。Pod名はランダムで変わるので取得し直してください。

IPアドレス/kialiでアクセスして、最初のログイン画面はadmin,adminで突破しましょう。

そして以下のようなマイクロサービスっぽい画面が出てきたら成功です。

どういうリクエストが成功しているかが分かりやすくていいですね。左上のnamespaceの設定をistioとdefaultの両方をチェックしておくと画像のようになります。

今後

今回紹介した環境構築はわりと楽な部類だと思います。MacやWindowsに入れるとなると諸所異なるところが出るので難しいとは思いますが。VPSを使うときれいな環境でrootでドカドカ作業できるので結構おすすめです。

次の記事では今回作った環境を用いてistioの様々な機能を試して行きたいと思います。例えば、Retry, fault injectionなどがあります。