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)と一つ以上のNode(昔はMinionと呼ばれてたもの)で構成される。 (MasterとNodeは同一マシンに同居もできる。) Masterはクラスタを管理し、コンテナのスケジューリング、状態管理、スケーリング、アップデートなどを担う。 Node上では実際にコンテナが実行される。 Kubernetesのアーキテクチャを図にすると以下の感じ。 矢印の向きとかはちょっと間違ってるかも。 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の定義に従ってコンテナを起動する。 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)。 Minikubeとは Kubernetesクラスタを構築する方法はいくつかあるが、中でももっとも簡単な方法がMinikube。 Minikubeは、KubernetesのMasterとNodeを一つずつを詰め込んだ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
Fri, Aug 25, 2017

スタートアップはReactを使うべきではない (BSD + patentsライセンスを考慮して) — もし、いつか大企業に買収されたいと望むなら

このエントリでは、Raúl Kripalaniによる記事、If you’re a startup, you should not use React (reflecting on the BSD + patents license)を紹介する。 (Raúlから和訳と転載の許可は得た。) 以下はその全文の和訳だが、意訳超訳が混じっているので、もとのニュアンスを知りたければ元記事を読んでもいいし、読まなくてもいい。 2017/9/23追記: React、Jest、Flow、Immutable.jsがMITにリライセンスされるというアナウンスがFacebookからあった。 コミュニティの大勝利だ。 (adsbygoogle = window.adsbygoogle || []).push({}); 現在オープンソースコミュニティで起こっていることには落胆させられる。 特に、オープンソースのおかげで多くのスタートアップやビジネスが存在することを認識したときは。 独占的なソフトウェアのために法外なライセンス料を払わなければならないとしたら、それらは存続できない。 オープンソースとは、より良いソフトウェアをみんなで構築するためのコミュニティをつくることだ。 それを、— Facebookが意図しているような — 人々の権利を交換するための市場として決して使用すべきではない。 Facebookは「BSD + patents」というライセンスモデルを推進している。 広く人気のあるReactを含む、すべてのプロジェクトで。 基本的に、「BSD + patents」はコードが(誰でも参照し利用できるように)公開されていることを意味するが、しかしそれは常にFacebookの著作物でもある。 そして彼らは、君がFacebookを特許侵害で訴えないで 仲良くやっている限り、君に特許ライセンスを与える。 Facebookを訴えた瞬間、Reactの他、君の使っているあらゆるFacebookの「オープンソース」技術の特許権は自動的に取り消されてしまう。 アディオス、バイバイ、どこかへ行ってしまう。 (https://github.com/facebook/react/blob/b8ba8c83f318b84e42933f6928f231dc0918f864/PATENTS) この問題は、Apache Software Foundationによって衆目にさらされることとなった。 この制限は広大で、残忍だ。 ・・・ その知的財産がReactを使用しているドメインと関連しているかどうかは関係ない。 君がReactを使うなら、Facebookが保持する特許に逆らうことはできない。 いつまでも。 言い換えれば、代償。 Facebook、それが君らの考えるオープンソースなのか? ・・・ Fridgebook Inc. 例として、君の会社「Fridgebook Inc.」はインテリジェントな冷蔵庫を販売しているとしよう。 君の冷蔵庫にはスクリーンが付いていて、独自のアプリケーションを実行していて、そのUIにはReactが使われている。 突然、Facebookは冷蔵庫業界への進出を決め、新製品「FBfridge」をわずか1週間後に世界中でローンチすると発表した。 仮に、Facebookがあなたの特許の一部を「FBfridge」で露骨に侵害していた場合、どうすればいい? そう、君は即座に彼らを訴えることはできない。 君は顧客が使うアプリにReactを使っている、だろ? もし他のもの(vue.jsとか)に移行せずに訴えたら、Reactのために与えられたライセンスを即座に失い、思いがけず君自身が違反している状態になり、ソフトウェア不正使用の訴訟を約5000億ドルの会社から起こされる可能性と戦うことになる。 君だけで。 もちろん、君は顧客サービスを中断したくはない。 だから、もし彼らを訴えたい、もしくは少なくともそれをするための効力を保持したいのであれば、記録的な期間でReactから移行できる解決策を見つける必要がある。 それが君の陥るひどい窮地だ。そうだろ?
eyecatch
Mon, Aug 14, 2017

WebdriverIOとChromeのヘッドレスモードで自動ブラウザテストするDockerイメージ: webdriverio-chrome

「2017年夏、ブラウザテストフレームワーク」の続き。 ServiceNowアプリケーションのブラウザテストをしたくて色々調べている。 前回は、フレームワークにWebdriverIOを使うと決めたところまで書いた。 今回、最終的に、WebdriverIO、WDIO、selenium-standalone、Jasmineと、Chromeのヘッドレスモードを使って、Dockerコンテナ(Alpine Linux)上でテストスクリプトを実行して、ServiceNowのログイン画面のスクリーンショットが取れるところまでできた。 そのコンテナイメージのDockerfileはGitHubに置いた。 (adsbygoogle = window.adsbygoogle || []).push({}); とりあえずAlpine Linux テスト環境の作成は自宅でやってるけど、DockerイメージにしてDocker Hubとかに上げておけば、社内でダウンロードしてそのまま再現できる。 ダウンロードに係る社内手続きも、Dockerイメージだけに対してやればいいので、中に何を詰め込んでも、後でライブラリとか追加しても、一回こっきりで済む。 というわけでとりあえず、自PC(Windows 10 Home)に入ってるVMware Workstation Player 12.5.5でCentOS 7 x64のVMを作り、Dockerをインストールして、Alpine Linuxをpullした。 $ docker pull alpine:edge Alpine LinuxはBusyBoxとmusl libcで構成された軽量な Linuxディストリビューション。 2016年2月にすべてのオフィシャルDockerイメージがAlpine Linuxベースになるというアナウンスがあったし、他にそれっぽいものもなかったので、これをベースに環境を作ることにした。 glibcじゃないのがちょっと気になるけど、まあ問題ないか。 現在、Chrome 59のAlpine Linuxパッケージがedgeブランチで作られているので、Alpine Linuxはedge(i.e. 開発中のバージョン)をpullした。 (因みに現時点でAlpine Linuxのlatestは3.6。) で、起動。 $ docker run -it alpine:edge sh Chrome(Chromium)インストール まずはChrome(がAlpine Linuxパッケージにはないので、実際にはChromium)と、ついでにChromeDriverをインストールする。 Alpine Linux独自のパッケージマネージャーであるapkを使う。 / # apk add --update chromium chromium-chromedriver / # chromium-browser -version Chromium 59.0.3071.115 無事インストールできた。 この記事を参考にヘッドレスモードで実行してみる。 ヘッドレスモードにするために--headlessを付けて、一時的な制限事項で--disable-gpuを付ける必要があって、コンテナの権限不足を回避するために--no-sandboxを付ける。 (コンテナの権限不足回避には他に、docker runに--privilegedや--cap-add=SYS_ADMIN付ける方法がある。) / # chromium-browser --headless --no-sandbox --disable-gpu https://example.com/ [0811/145902.894023:WARNING:dns_config_service_posix.cc(326)] Failed to read DnsConfig.