この記事は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はマルチノードを作ることができるので、折角なので利用しましょう。
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上で動いています。実際にブラウザからアクセスしてみましょう。
もし今動かしている環境がAKS
やGKE
などのマネージドサービスを利用している場合は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などがあります。