(GKE)のProduction環境でIstioを動かす2018-08-27by@wapa5powKubernetesで動いていた既存のサービスを、GKE上のIstioで動くようにしました。プロダクション環境のためHTTPSや監視もいれてあります。Istioはインストール時のオプションで、PrometheusとかGrafanaも一緒にインストールされて動きます。構築が楽になりそうなので気になっていました。今回新しいGKE環境を作る機会があったので、監視もととのっているIstioを導入しました。ほとんどの部分はIstioの公式ドキュメントを見れば構築できます。各種クラウドプラットフォームに対応するためにドキュメントが散らばっていたり、どの手順を適用したらいいのかわかりずらかったりするので、自分はこのパターンでやりましたというのを残しておきます。challengeを使って、certbotで証明書を更新する形にしたのでそこはドキュメントにないのでそのような状況にある場合は参考になるかもしれません。各種作業はmacOS上からやっています。IstioをGKE上で動かすまずはIstioがGKE上で動作するようにします。手順は各種飛ばしているところもあるので、以下で補いながら実施するといいと思います。Engineからクラスタを作ります。以下以外はデフォルトで作成します。ノードは3台だとリソースがなくてpodが作れなくなりがちなので4としておきます。nodesを選択するといいと思います。これは最大24時間稼働し続けることができるノードがわりあてられるもので、いつノードが削除されて再生成されるかわからないかわりに1/3とか安い費用で利用できます。Kubernetesはポッドが削除・再生される前提なので、そのテストの意味でも強制的に削除されるノードがあるのはいいかもしれません。loginなどでログインしておきます。以下を実行し、kubectlが使えるように設定します。プロジェクト名やリージョンは各自かえてください。cluster-infoがエラーなく実行できたら大丈夫です。認証系のエラーがでたら以下が参考になりそうです。http://doi-t.hatenablog.com/entry/2018/03/21/213715https://stackoverflow.com/questions/49075723/what-does-unknown-user-client-mean?rq=1Helmのインストール今回、Istioインストール時にHelmを使うのでここを参考にインストールしてください。versionが正しく実行できれば大丈夫です。Istioのインストールここを参考にして、リリース版のistioを取得します。記事を書いている時点では、1.0.1でした。パスを通すと、istioctlが使えるようになります。IstioをHelm経由でインストールする際、Helmのインストール時に入れたTillerのポッド経由でIstioを入れるか、HelmのコマンドラインでKubernetesのマニフェストを出力し、それを使うかの2種類あります。今回は、マニフェストをgitで管理したかったので、マニフェストに書き出す形にします。リリース版のistio-1.0.1のフォルダ直下に行き、以下のコマンドを打ちます。/var/tmp/istio.yaml/var/tmp/istio.yamlにKubernetesのマニフェストできるので確認します。<key>=<value>で設定できるオプションが確認できます。若干ここに書いていないもの(cert-managerのemailなど)もあるので、HelmのChartを見ながら確認するといいです。istio.yamlをKubernetesに適用する前に、現在使用しているアカウントにRBACベースのアクセス権をあたえておきます。core/account)"次に、Istioの管理で使われるネームスペースを作成します。istio-system次に、最初に作成したistio.yamlを適用します。/var/tmp/istio.yamlしばらくしたら、Istioが正しく起動できているか確認します。ここにあるように、istio-systemのネームスペースを指定して確認してください。ドキュメントの結果はやや古いので結果がやや違うこともありますが、ポッドがエラーなく起動していれば大丈夫です。istio-systemこれでIstioがインストールできました。istio-systemで見てみたときに、EXTERNAL-IPがあります。ドメインを設定する場合は、ここであらかじめDNSに設定しておいてください。IPにしておくといいかなと思います。サーバ監視せっかくGrafanaを入れたので、こちらの手順でGrafanaにアクセスできるかどうか確認してみてください。Prometheusもこちらの手順で確認できます。Istioを使っていない時は、Helmも使わないでPrometheusとGrafanaを入れて設定が非常に大変でしたが、Istioだとオプションを設定するだけでするっとはいってしまいます。その時は、ノードプールをわけたりストレージ分けたりしていましたが、今回のは、ひとまずデフォルトとしておきます。注意としてPrometheusは、デフォルトの設定では6時間しかデータを保存しないのと、保存先もとくに分けらていません。長期的なデータもみたい場合は、Prometheus用にpoolをわけるとか個別に設定したほうがいいと思います。既存WebサービスをGKE上のIstioで動かすIstio上で、既存のサービスを動かせるようにします。既存のサービスがKubernetesですでに動いている前提で書きます。Kubernetesで動いていない場合は、docker-composeを使って、ローカルで動かせれるところまでいってからKubernetesで動かすと楽です。sidecarのInjectKubernetesのマニフェストをIstio上で動作させるには、既存のマニフェストにEnvoyを通して通信するように変更する必要があります。その変更方法には、以下の2通りのやり方があります。...で適用させます。...で適用すると、hookがかかり、自動でEnvoyの設定を適用してくれます。ネームスペース単位で制御でき、istio-injection=enabledを適用したネームスペースだけEnvoyが適用されます。前者のはいちいちマニフェストファイルを変換しなければならず面倒なのでIstio-sidecar-injectorを使ったやりかたで設定します。defaultのネームスペースにIstio-sidecar-injectorを適用しないで新しいネームスペースを作ってからそちらに既存Webサービスの設定を適用します。namespace.yamlで適用します。...で適用させます。外部からIstio内部への既存ebサービスへのアクセスできるようにするための設定をします。Istioでは、GatewayとVirtualServiceでIstioのIngress設定をします。注意として、既存のWebサービスでKubernetesのIngressを使用していたとしてもIstioでは使わず、すべてingressgateway経由でアクセスされます。既存のIngressがあった場合は、IstioのIngressを設定し終わったあとに削除しても大丈夫です。今回、Gatewayは以下のように設定しました。後ほど、HTTPSの設定もしますがその設定も、あらかじめ入れておきます。"www.wapa5pow.com"VirtualServiceは以下のように設定しました。webというサービスのポートらへんは各自自分のアプリに読み替えて設定してください。マニフェスト名で適用します。指定したドメインでアクセスできるか確認してみます。--all-namespacesでistio-ingressgatewayのポッドの名前を確認して、以下のような形でログを確認すつつアクセスしてみます。-fほとんどのサービスがそうだと思いますが、データベースなどのクラスタ外部のサービスにアクセスする必要がある場合は、Egressの設定であるServiceEntryを設定する必要があります。Istio内部から外部にアクセスするサービスを定義します。今回は簡易的に、HTTP/HTTPSとPostgreSQLのポートをすべて許可するようにしておきます。TCPポッドの中から外部ドメイン経由でアクセスできれば正しく設定されています。EncryptでHTTPS通信を実現します。Istioの設定で一番つらかったのはこれです。HTTPSの設定は、はまると時間かかって大変です。通常、Kubernetesだと、Ingressのアノテーションに、cert-manager用の設定をすればさくっと、いけます。Istioは、Ingressではなく、istio-ingressgatewayを通して外部からの通信を行うので、Ingress経由では証明書を取得できません。challengeでリンクにあげられているDNSプロバイダを使っていた場合簡単にできます。Istioにはオプションを設定するとcert-managerを入れてくれて、dns-01の設定ができるのでその場合はすぐできます。challengeで行います。cert-managerだとできなかったので、certbotを使って設定していきます。challengeに成功するようにします。2の部分は/.well-known/acme-challenge/だけcertbotにリクエストがいくようにします。VirtualServiceですでに設定済みです。certbotcertbotを適当に設定し、ポッドとしてcertbotを動かして証明書を取得します。以下みたいなシェルスクリプトを走らせるDockerfileを作ってビルドすればいいかなと思います。HTTPSに書いてあるのですが、注意点として証明書と秘密鍵は、istio-systemネームスペースのistio-ingressgateway-certsのシークレットに保存する必要があります。するとistio-ingressgatewayが自動的に証明書と秘密鍵を読んでくれて、/etc/istio/ingressgateway-certs/tls.crtと/etc/istio/ingressgateway-certs/tls.keyに展開してくれます。RBACが有効になっているクラスタの場合、シークレットを作成するのに権限がいるので、ServiceAccount/ClusterRole/ClusterRoleBindingを設定してcertbotが書き込みできるようにしてあげてください。...で適用してください。これでHTTPSで通信できるはずです。blogHomeAboutTool。