eyecatch
Wed, Oct 11, 2017

Kubernetesのチュートリアルをやる

「Kubernetes 1.8が出たので、Minikubeを触ってみる」の続き。 Minikubeのセットアップまではできたので、Kubernetes Basicsというチュートリアルをやりながら、Goslingsをデプロイする。 (adsbygoogle = window.adsbygoogle || []).push({}); Kubernetes Basics - 概要 Kubernetes Basicsは、公式のチュートリアルで、Kubernetesクラスタのオーケストレーションの基本を学ぶことができるもの。 以下の6つのモジュールからなる。 Kubernetesクラスタを作る アプリをデプロイする アプリを調査する アプリを公開する アプリをスケールする アプリをアップデートする チュートリアルで使うのはMinikubeだけど、自分でセットアップする必要はない。 Katacodaという、ブラウザ上でIT技術を学べるプラットフォームがあり、Kubernetes Basicsはそれを利用して、ブラウザ上のターミナルからホステッドMinikubeを操作できるようにしている。 が、前回の記事で自PC上にMinikubeをセットアップしたので、そちらを使うことにする。 Kubernetes Basics - モジュール 1: Kubernetesクラスタを作る Minikubeを起動してkubectlでクラスタの状態をみるだけのモジュール。 これは前回の記事でカバーしている。 Kubernetes Basics - モジュール 2: アプリをデプロイする アプリ(i.e. コンテナ)をデプロイするにはDeploymentオブジェクトを作る。 MasterはDeploymentのspecに従って各ノードにアプリのインスタンスをスケジューリングする。 Deploymentは、アプリが落ちたら再起動してくれる、つまりself-healingも実現する。 Deploymentオブジェクトを作るコマンドはkubectl run <オブジェクト名> --image=<Dockerイメージ名>。 Goslingsをこれでデプロイする。 Goslingsコンテナは3つの引数を受け取り、指定したポートでWebサーバを起動する。 --portオプションでそのポートをexposeするようにして、--の後にコンテナに渡す引数を記述する。 C:\Users\kaitoy>kubectl run goslings --image=kaitoy/goslings:latest --port 8080 -- 8080 /tmp https://github.com/kaitoy/ deployment "goslings" created C:\Users\kaitoy>kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE goslings 1 1 1 1 27s デプロイできた。 裏でPodも作られていて、アプリが起動されている。 C:\Users\kaitoy>kubectl get pods NAME READY STATUS RESTARTS AGE goslings-1210510689-6w5tf 0/1 ContainerCreating 0 1m (kubectl getに指定するのは、省略形のdeployとかpoでもいい。) Podは隔離されたネットワークで動くので、そのままではPod同士は通信できるけど、外からはアクセスできない。 kubectlでプロキシを作ってやることで、外からアクセスできるようになる。 C:\Users\kaitoy>kubectl proxy Starting to serve on 127.0.0.1:8001 これで、kube-apiserverへのプロキシがローカルホストで起動した。 この状態でhttp://localhost:8001を開くと、kube-apiserverのAPI一覧が見れる。 例えば、http://localhost:8001/versionにアクセスすると、以下のJSONデータが返ってくる。 { "major": "1", "minor": "7", "gitVersion": "v1.7.0", "gitCommit": "d3ada0119e776222f11ec7945e6d860061339aad", "gitTreeState": "dirty", "buildDate": "2017-10-04T09:25:40Z", "goVersion": "go1.8.3", "compiler": "gc", "platform": "linux/amd64" } 各Podへも以下のURLでアクセスできる。 http://localhost:8001/api/v1/proxy/namespaces/default/pods/<Pod名>/ Pod名の部分はkubectl getで確認できる。 C:\Users\kaitoy>kubectl get po NAME READY STATUS RESTARTS AGE goslings-1210510689-6w5tf 1/1 Running 0 24m 実際に、http://localhost:8001/api/v1/proxy/namespaces/default/pods/goslings-1210510689-6w5tf/をブラウザで開いたら、GoslingsのGUIが出た。 ヒュー。 Kubernetes Basics - モジュール 3: アプリを調査する 以下のコマンドで、アプリの状態を調査するモジュール。 kubectl get: リソースをリスト表示する。 kubectl describe: リソースの詳細情報を表示する。 kubectl logs: コンテナのログを表示する。docker logs的な。 kubectl exec: コンテナ内でコマンドを実行する。docker exec的な。 kubectl getはさんざんやったので飛ばして、kubectl describeしてみる。 C:\Users\kaitoy>kubectl describe po Name: goslings-1210510689-6w5tf Namespace: default Node: minikube/192.168.99.100 Start Time: Tue, 10 Oct 2017 21:51:48 +0900 Labels: pod-template-hash=1210510689 run=goslings Annotations: kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"goslings-1210510689","uid":"c74b6518-adb9-11e7-88a0-08002798178d...
eyecatch
Tue, Oct 10, 2017

Kubernetes 1.8が出たので、Minikubeを触ってみる

Kubernetes1.8のリリースが話題になっていたので、ちょっと触って見たという話。 (1.8を触ったとは言っていない。) 具体的には、Kubernetes Basicsというチュートリアルをやりながら、MinikubeにGoslingsをデプロイしたんだけど、この記事ではMinikubeをセットアップしたところまで。 (adsbygoogle = window.adsbygoogle || []).push({}); Kubernetesとは KubernetesはOSSのコンテナオーケストレーションツール。 英語だとクーバネティスみたいに発音する。 Googleが自身のコンテナ技術であるBorgの運用で培ったノウハウを活かして開発したもの。 2014年ころに開発が始まり、2015年夏にv1がリリースされたということで、かなり新しいツール。 よく比べられるものにはDockerのSwarmモードやApache Mesosがあるが、何が違うのかは調べてないので知らない。 ただ、Dockerコンテナ管理ツールとしてはKubernetesが一番勢いがある雰囲気を感じる。 (2017/10/18追記: DockerがKubernetesとの統合を発表した。KubernetesはDockerネイティブなツールになり、Dockerとともにインストールされ、Docker ComposeのConposeファイルでデプロイできるようになったりする。Kubernetesの大勝利っぽい。) Kubernetesを使うと、複数の物理マシンからなるHAクラスタ(Kubernetesクラスタ)を構成し、その上にコンテナをデプロイして管理できる。 Kubernetesクラスタは、一組のMasterコンポーネント群(a.k.a. Kubernetes Control Plane、または単にMaster)と一つ以上のNode(昔はMinionと呼ばれてたもの)で構成される。 Nodeは、Masterの管理下でコンテナを実行する機能を備えた、一台のVMや物理マシン。 MasterはNode上で動き、クラスタを管理し、コンテナのスケジューリング、状態管理、スケーリング、アップデートなどを担う。 Kubernetesのアーキテクチャを図にすると以下の感じ。 矢印の向きとかはちょっと間違ってるかも。 ごちゃごちゃするので省いたけど、図の下部のNode内のコンポーネントは、他のNode内でも動いている。 Masterにはkube-apiserverが含まれていて、Kubernetes APIというREST APIを公開する。 このAPIを通してKubernetesオブジェクトを定義したりすることで、宣言的にコンテナの管理ができる仕組み。 ユーザは普通、kubectl(キューブシーティーエル)というコマンドでkube-apiserverとやり取りする。 KubernetesオブジェクトはMasterのetcdによって分散キーバリューストアに永続化され、そのストアをkube-controller-managerとkube-schedulerがwatchしてて、変更に応じた処理をする。 kube-controller-managerは、ノードの管理や、オブジェクトのライフサイクルの管理や、コンテナのスケーリングなど、クラスタレベルの機能を実行する。 (よくわからない。) kube-schedulerは、コンテナを実行するホストを選出し、コンテナのスケジューリングをする。 あと、図にはないけど、cloud-controller-managerというのがMasterで動くこともあって、クラウドプラットフォームとやり取りしてクラウド固有の仕事をするらしい。 クラウドベンダじゃなければ気にしなくて良さそう。 一方、各Nodeでは、kubelet(キューブレット)というMasterのエージェントになるプロセスが動く。 kubeletはkube-apiserverからの指示で、コンテナイメージを取得してコンテナを起動したり監視したり止めたりする。 kubeletがコンテナを扱うためのコンテナランタイムは、普通はDockerだけど、rktとかcri-oとかfraktiとかも使える。runcやRailCarはどうなんだろう。 コンテナはデフォルトではクラスタ内のプライベートネットワークにつながるので、そこで動いているアプリにユーザからアクセスするには、何らかの形でトラフィックを中継してやる必要がある。 これをするのがkube-proxy。 ロードバランシングもしてくれる。 Kubernetesオブジェクトとは Kubernetesオブジェクトは、Kubernetesクラスタ上で機能する構成要素を表現するもの。 オブジェクトはspecとstatusを持ち、オブジェクトに期待する状態やふるまい(spec)を定義しておくと、Kubernetesが実際の状態(status)をそれに合わせてくれる。 宣言的。 オブジェクトには以下のようなものがある。 Pod デプロイの最小単位。 一つ(またはリソースを共有する複数)のコンテナと、ストレージ、ネットワークなどを内包する。 一つのPodには一つのIPアドレスが付く。 kubeletはPodの定義に従ってコンテナを起動する。 因みに、etcd以外のMasterコンポーネントもPodとしてデプロイされる。 Service Podの論理グループ。 PodのIPアドレスは外部に公開されないので、外とのやり取りをするためにServiceがある。 kube-proxyはこいつの定義に従って働く。 Serviceには複数のEndpoint(i.e. Pod等)が紐づき、外部からのトラフィックをラウンドロビンでルーティングするので、冗長化やロードバランサ的な働きもする。 ServiceはPodを抽象化するので、Podが死んだり入れ替わったりしても外に影響が見えにくくなる。 Serviceには以下のtypeがある。 ClusterIP (デフォルト): Kubernetesクラスタ内からだけアクセスできる内部IPアドレスだけをもつ。 NodePort: ClusterIPの拡張。内部IPアドレスに加え、クラスタ外からアクセスできるポートを一つ持つ。 LoadBalancer: NodePortの拡張。外部ロードバランサを作って、固定の外部IPアドレスを付けて、内部IPアドレスへルーティングする。 ExternalName: 抽象名をもつサービス。Kubernetes DNS serverで名前解決する。詳細は読んでないので知らない。 Volume 永続化やPod内でのファイル共有のためのオブジェクト。 Podとともに作られ、Podとともに破棄される。 実態はファイルシステム上のディレクトリ。 hostPathとか、nfsとか、awsElasticBlockStoreとかの種類があるらしい。 Namespace 仮想クラスタを表すオブジェクト。 これを定義すると、ひとつの物理クラスタを複数の仮想クラスタに分割できる。 大規模ユーザ・プロジェクト向け機能。 Controller Podを管理するオブジェクト。レプリケーションしたり、スケーリングや自動再起動したり。 以下のようなものがある。 Deployment Podのデプロイを管理するオブジェクト。 PodとReplicaSetの宣言的な生成・更新を実現する。 ReplicaSet 指定した数のPodのレプリカを維持してくれる。 基本はDeploymentから作られて、Podの作成・削除・更新をオーケストレイトする。 ReplicationControllerというのもあるけど、今はReplicaSetが推奨。 StatefulSet ステートフルなアプリを管理するオブジェクト。 現時点でのKubernetes最新版の1.8でまだベータ。 DaemonSet 全てのノードで動くアプリを実現するオブジェクト。 Job ジョブを表すオブジェクト。 指定された回数、Podを成功で完了させる。 オブジェクトにはラベルというキーバリューな属性を付けることができ、PodとServiceの紐づけや、オブジェクト検索時のフィルタとかに使える。 今回Goslingsを動かすのに使ったのは、Pod、Deployment、ReplicaSet、Service (NodePort)。 Podネットワーク ちょっと細かい話だけど、Pod間の通信はどうなっているかという話についてちょっと調べたのでざっくり書いておく。 普通のDockerネットワークだと、コンテナはdocker0という仮想ブリッジ上のプライベートネットワークで動くため、同じホスト上のコンテナ間は通信できるけど、別のホスト上のコンテナ通信させたい場合は、ホストのIPアドレスのポートを割り当ててやらなければいけない。 これはめんどいので、Kubernetesは、各Podに一意なIPアドレスを与え、Podがどのホストにいるかにかかわらず、NAT無しで相互に通信できるネットワークを提供する。 これがPodネットワークとか呼ばれ、その仕様はCNIでオープンに定められていて、以下のような実装がある。 Calico Canal Flannel Kube-router Romana Weave Net Minikubeとは Kubernetesクラスタを構築する方法はいくつかあるが、中でももっとも簡単な方法がMinikube。 Minikubeは、単一NodeのKubernetesクラスタを詰めたVMをダウンロードして起動して、ローカルのkubectlから使えるようにしてくれるツール。 Linux、Windows、OS Xで動き、開発やテスト用途のKubernetes環境として使われる。 ちょっとVagrantっぽい感じ。Kubernetes専用の。 Minikubeインストール Kubernetesのドキュメントにしたがって、Minikubeをインストールする。 環境はWindows 10 Home x64。 まず、MinikubeのVMを動かす仮想化ツールを入れる。 今のところMinikubeがサポートしてるのは、WindowsだとVirtualBoxかHyper-V。 Windows 10 HomeだとHyper-Vが使えないので、VirtualBox一択。 VirtualBoxは、適当にVT-xを有効にして(してあった)、インストーラダウンロードしてインストールしただけ。 バージョンは5.1.28。 次に、minikubeコマンドを入れる。 このコマンドはGoで書かれていて、各プラットフォーム用にビルドされたバイナリがGitHubのプロジェクトページのReleasesに上がってるので、ダウンロードしてPathの通ったとこに置くだけ。 今回ダウンロードしたのはv0.22.2のminikube-windows-amd64で、これをminikube.exeにリネームして配置した。 で、minikubeがサポートしているKubernetesのバージョンを調べると、 C:\Users\kaitoy>minikube get-k8s-versions The following Kubernetes versions are available: - v1.7.5 - v1.7.4 - v1.7.3 - v1.7.2 - v1.7.0 (snip) 1.8はまだサポートされていない… 1.7.5が最新なのでそれでやることにする。 ということで、kubectlの1.7.5をインストールする。 kubectlもGoで書かれているので、以下のアドレスからWindowsバイナリをダウンロードしてPathの通ったところに置くだけ。 https://storage.googleapis.com/kubernetes-release/release/v1.7.5/bin/windows/amd64/kubectl.exe 以上でMinikubeの環境ができた。 簡単。 Minikube起動 Minikubeは、minikube startで起動することができ、Minikubeが起動したらすぐにKubernetesをいじれるようになる。 C:\Users\kaitoy>minikube start --vm-driver virtualbox --kubernetes-version v1.7.5 Starting local Kubernetes v1.7.5 cluster...
eyecatch
Sun, Mar 5, 2017

Firedrop(プライベートベータ)が全く期待外れだった件

Firedropという現在開発中のサービスがある。 WebサイトのデザインをAIがサポートしてくれるサービスだ。 2016年夏のニュースを見たとき、AIがテキストコンテンツを解析してサイトを自動構成してくれ、さらにA/Bテストなどを自動でやってサイトを継続的に改善すると言う衝撃的なふれこみだったので、即座にアーリーアクセスに登録した。 それからしばらく忘れていたが、3月2日にプライベートベータへの招待メールが来たので早速試してみたら、かなりのスモールスタートをしたようで全く期待外れだった。 (adsbygoogle = window.adsbygoogle || []).push({}); Firedrop(プライベートベータ)の機能 Firedrop(プライベートベータ)では、SachaというAIがWebサイトの構築をサポートしてくれる。 こいつが実のところほとんど知性を感じない単なるチャットボットで、なるほどこれは見事な人工無脳だと感心してしまうほどだ。 Firedropのアカウントを作るとまず、Sachaとチャットしながらサイトの概要(タイトル、概要、画像など)を教えることになる。 するとSachaがざっくりとシングルページのサイトを作ってくれるので、それをまたSachaとのチャットで調整したりコンテンツ追加したりする。 チャットと言っても、基本はこちらは5,6個ある選択肢の中からセリフを選ぶサウンドノベル方式で、一応任意の文章も入力できるがあいさつするくらいしか使い道がない。 追加コンテンツはテキストと画像を渡すと自動でレイアウトしてくれるが、すごくいい感じにしてくれるというわけでもないし、むしろ画像が見切れたりするし、細かい調整はできないので、妥協できるレイアウトになるまでチェンジを繰り返すデリヘル方式を採ることになる。 デリヘルなんて利用したことないけど。 画像は自分でアップロードもできるけどFiredropが提供しているものもあって、後者のやつはSachaにキーワードを伝えるとそれっぽい画像を探してくれるあたりに唯一知性を感じる。 デザインができたらSachaに頼むとfiredrop.meドメインで公開してくれる。 (FiredropのUIのスクリーンショットを載せようかと思ったけど、プライベートベータの規約を読んだ感じだめそうだったので載せない。) 実際に作ってみた 今回実際にFiredropでGoslingsのサイトを作ってみて、できたのがこれ。 ひどい。 そもそも当初のテキストコンテンツを解析してサイトを自動構成というコンセプトはどこへ行ったのか。 GoslingsのReadmeを入力したらシャレオツなサイトをささっと作ってくれるイメージだったんだけど。 まだまだ開発中の機能がたくさんあるそうなので、GAまでにはもうちょっとなんとかなるんだろう。 あまり期待はしない。
eyecatch
Tue, Jan 24, 2017

Goslings開発メモ - その5: Spring Boot最終編 (静的リソース処理)

「Goslings開発メモ - その4: Spring Boot続続続編 (ロギング)」の続き。 Spring Boot最終編で、静的リソース処理について。 (adsbygoogle = window.adsbygoogle || []).push({}); Spring Boot(Spring MVC)での静的リソース処理 この時点でのGoslingsは単なるREST APIサーバで、アクセスしてもJSONを返すだけだ。 アプリとしての体を成すためには、そのAPIを利用するクライアントコード、つまりHTMLドキュメントやCSSファイルやJavaScriptファイル(静的リソース)も返すようにしないといけない。 HTMLドキュメントを返す場合、普通はなんらかのテンプレートエンジンを使うものだが、Goslingsは本当に単純なGUIなので、サーバに置いたHTMLファイルをそのまま返したい。 「Getting Started Guides」にはServing Web Content with Spring MVCというのが乗っているが、これはThymeleafというテンプレートエンジンを使うものなのでちょっと違う。 Spring Bootリファレンスガイドによると、クラスパス(またはServletContextのルート)の/static/、/public/、/resources/、/META-INF/resources/のいずれかに静的リソースを置けば、特にコードを書かなくてもクライアントからアクセスできるらしい。 (逆に、一般的に静的リソースを置く場所である、プロジェクトのsrc/main/webapp/には置くべきでないとのこと。これは、jarにパッケージングするときにビルドツールに無視されることが多いため。) この仕組みについて、この記事を参考にちょろっとソースを見た感じでは、これらのパスはResourcePropertiesのCLASSPATH_RESOURCE_LOCATIONSに定義されていて、これをWebMvcAutoConfigurationがResourceHandlerRegistryでリソースロケーションとして登録することで静的リソース置き場たらしめている模様。 (このResourceHandlerRegistryはResourceHttpRequestHandlerを設定するファサード的なものっぽい。) で、@SpringBootApplication(その1参照)が付いているクラスがあって、spring-webmvc.jarがクラスパスにあると、@EnableWebMvcがSpring Bootによって付けられ、そこからごにょごにょして上記WebMvcAutoConfigurationが実行される。 spring-webmvc.jarはspring-boot-starter-web.jar(その1参照)が引っ張ってくる。 なお、Spring MVCの静的リソース処理の全体の流れについては 、ちょっと古いけど「handling static web resources」という記事が分かりやすい。 要は、URLに指定されたパスからサーバ上のリソースを探し当てるResourceResolverというものが優先度順に連なっているリゾルバチェイン(ResourceResolverChain)があって、まずこいつがリソースを取得する。 次に、そのリソースを加工するトランスフォーマチェイン(ResourceTransformerChain)というものに通し、その結果をクライアントに返す。 トランスフォーマチェインはResourceTransformerが連なったもの。 リゾルバチェインとトランスフォーマチェインは上記ResourceHttpRequestHandlerに設定される。 リゾルバには以下の様なものがある。 PathResourceResolver: ResourceHttpRequestHandlerに設定されたリソースロケーションからリソースを単純に検索するリゾルバ。 CachingResourceResolver: キャッシュからリソースを検索するリゾルバ。テンプレートエンジンの処理結果のキャッシュとかが返るのは多分ここから。 GzipResourceResolver: gzipで圧縮されたリソース、つまりURLで指定されたパスに.gzという拡張子を付けたリソースを検索するリゾルバ。 VersionResourceResolver: リソースバージョニングを実現するためのリゾルバ。 WebJarsResourceResolver: WebJarsのjarファイル内のリソースを検索するリゾルバ。 リゾルバの設定などについてはQiitaのこの記事ががよくまとまっている。 凝ったことをしたいときは参照しよう。 トランスフォーマには以下の様なものがある。 CssLinkResourceTransformer: CSSファイル内のリンクをクライアントがアクセスできるURLに変換する。 CachingResourceTransformer: 変換したリソースをキャッシュする。 AppCacheManifestTransformer: HTML5のAppCacheマニフェスト内のリソースを扱うトランスフォーマ。 デフォルトでResourceHttpRequestHandlerにはPathResourceResolverだけが設定されている。 以上をまとめると、クライアントからGetリクエストが来ると、WebMvcAutoConfigurationが設定したリソースロケーション(e.g. /static/)をPathResourceResolverが検索して、そこに置いてあるHTMLファイルとかをクライアントに返してくれる、ということであろう。 Javaのコードを全く書かなくていいので楽。 Javaのコードを書いて静的リソースファイルを明示することもできる。 Qiitaの記事によれば、@Controllerを付けたクラスのリクエストハンドラで以下の様にファイルへのパスを返せばいいらしい。 @RequestMapping("/hoge") public String hoge() { return "/hoge.html"; } 単純な静的リソースに対してこれをやるユースケースはあまりなさそう。 テンプレートエンジンを使っていてパラメータを渡したいときにはこういうリクエストハンドラを書くことになる。 Spring Bootのウェルカムページとファビコン Spring Bootはindex.htmlとfavicon.icoという名のファイルを特別扱いする。 前者がウェルカムページで後者がファビコン。 ウェルカムページ Spring Bootのリファレンスガイドにもちらっとかいてあるけど、リソースロケーションにindex.htmlというファイルを置いておくと、それがウェルカムページとして設定され、URLのパスにルート(e.g.