eyecatch
Sat, Oct 21, 2017

Kubernetes1.8のクラスタを構築する。kubeadmで。

「Kubernetes 1.8が出たので、Minikubeを触ってみる」でMinikubeをやったんだけど、もう一歩ステップアップすべく、kubeadmでKubernetesクラスタを組んでみた話。 (adsbygoogle = window.adsbygoogle || []).push({}); kubeadmとは kubeadm(キューブアダム)はKubernetesに含まれるコマンドで、Kubernetesクラスタを簡単に構築するツール。 Kubernetes 1.4で追加され、Kubernetes 1.8の時点でまだベータで、本番環境には使わないでとなっている。 Qiitaの「kubeadmが何をやっているのかみてみた」という記事が、中でどんな動作をしてるかを解説していて参考になる。 コマンドの使用感からすると、DockerのSwarmモードでのクラスタ構築の容易さをKubernetesに取り込むことを目指して開発されている気がした。 ネットで見かけた評判だと、確かに簡単にクラスタ構築できて素晴らしいけど、TLSの証明書生成など、細かく制御できなくて困るところがあって、やはり本番に使えるレベルではないとのこと。 まあとにかく試してみる価値はあろう。 kubeadmインストール Kubernetesのドキュメントに従ってkubeadmをインストールする。 バージョンは最新版の1.8.1。 VM作成 kubeadmのサポートOSは、Ubuntu 16.04+、Debian 9、CentOS 7、RHEL 7、Fedora 25/26、HypriotOS v1.0.1+となっている。 慣れているCentOS 7を使うことにする。 (HypriotOSってなんだろう?) 自前のノートPCのWindows 10 x64 Home Edition上のVMware Player 12のVMにCentOS 7を入れた。 メモリは1GB以上が要件なので、味を付けて1.4GBで。 VM間で通信できることって要件があったけど、インターネット接続も必要なはずなので、NICはNATのやつで。 このVMはMasterになる。 OS設定 Kubernetesが使うポートをいろいろ開けなければいけないんだけど、めんどいのでfirewalldを無効にする。 [[email protected] ~]# systemctl stop firewalld [[email protected] ~]# systemctl disable firewalld Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. なんとなくIPアドレスをDHCPから静的割り当てに。(192.168.171.200) [[email protected] ~]# nmcli c modify ens33 ipv4.method manual [[email protected] ~]# nmcli c modify ens33 ipv4.addresses 192.168.171.200/24 [[email protected] ~]# nmcli c modify ens33 ipv4.dns 192.168.171.2 [[email protected] ~]# nmcli c modify ens33 ipv4.gateway 192.168.171.2 [[email protected] ~]# systemctl restart network ホスト名をlocalhost.localdomainからk8s-masterに変更。 [[email protected] ~]# hostnamectl set-hostname k8s-master ログアウトログインで反映。 /etc/hostsを編集して、k8s-masterのエントリを追加。 あとで作るもう一つのVM、k8s-nodeのほうもエントリを追加。 (これはだめだったっぽい。詳細は後述。) クラスタを構成するノードは、一意のMACアドレスとproduct_uuidを持っていないといけない。 Kubernetesがそれらでクラスタ内のノードを区別してるので。 MACアドレスはip linkコマンドなどで確認できる。 [[email protected] ~]# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 00:0c:29:38:de:ae brd ff:ff:ff:ff:ff:ff product_uuidは、SMBIOSという、PC固有のデータを保存・参照するための仕様があって、それに従って保存されたシステムの識別子らしい。 product_uuidはdmidecodeコマンドなどで確認できる。 [[email protected] ~]# dmidecode -s system-uuid 58114D56-A744-3610-C3C5-9B15A838DEAE kubeletがちゃんと動くためにはswapを無効にする必要がある。 [[email protected] ~]# swapoff -a (このコマンドはよくなかった。詳細は後述。) ebtablesとethtoolを入れる必要がある。 [[email protected] ~]# yum install -y ebtables ethtool Dockerも入れないと。 v1.12が推奨で、v1.11かv1.13でもいい。 適当に入れたらv1.12.6だった。 [[email protected] ~]# yum install -y docker [[email protected] ~]# systemctl enable docker && systemctl start docker Podネットワークなどが機能する要件として、コンテナがホストファイルシステムにアクセスできる必要があるが、そのためには現状、SELinuxを無効化する必要がある。 [[email protected] ~]# setenforce 0 (このコマンドもよくなかった。詳細は後述。) RHEL系の場合、iptablesがバイパスされてトラフィックが変にルーティングされる問題があるため、net.bridge.bridge-nf-call-iptablesを1にセットしておく必要がある。 [[email protected] ~]# cat <<EOF > /etc/sysctl.d/k8s.conf > net.bridge.bridge-nf-call-ip6tables = 1 > net.bridge.bridge-nf-call-iptables = 1 > EOF [[email protected] ~]# sysctl --system * Applying /usr/lib/sysctl.d/00-system.conf ...
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)。 Podネットワーク ちょっと細かい話だけど、Pod間の通信はどうなっているかという話についてちょっと調べたのでざっくり書いておく。 普通のDockerネットワークだと、コンテナはdocker0という仮想ブリッジ上のプライベートネットワークで動くため、同じホスト上のコンテナ間は通信できるけど、別のホスト上のコンテナ通信させたい場合は、ホストのIPアドレスのポートを割り当ててやらなければいけない。 これはめんどいので、Kubernetesは、各Podに一意なIPアドレスを与え、Podがどのホストにいるかにかかわらず、NAT無しで相互に通信できるネットワークを提供する。 これがPodネットワークとか呼ばれ、色んな実装があり、PodネットワークアドオンとしてKubernetesクラスタに適用できる。 Calico、Canal、Flannel、Kube-router、Romana、Weave Netとか。 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から移行できる解決策を見つける必要がある。 それが君の陥るひどい窮地だ。そうだろ?