Kubernetes v1.11 を scratch install したら理解深まるじゃんって話
kubeadm とか使わずに Kubernetes を構築するって大変ですよね。 ただ、一から構築することで学ぶことがあると教わりまして重い腰をあげて構築してみました。
結論として順番に組み立ててくと理解深まります。できればハマった方がいいので手順は書きますが、 バージョン変えたりしてハマってみてください。
事前準備
ドキュメントを読む
公式ドキュメントは以下の通りです。予備知識なしでこの通りに進めるのは難しいかなと思いますが、 読んでおくといいです。
https://kubernetes.io/docs/setup/scratch/
頭に構成を描いておく
kubelet がいて api server がいてとかの概要図は以下を見てイメージしておくといいと思います。
※ 公式 から引用
構築環境
今回、VM 上に作成しようと思います。物理サーバでもいいですし何らか構築環境を準備してください。 Master Node 1台、Regular Node (公式曰くこう呼ぶらしい。Minions ではないのかな)を 1台の構成でいきます。
ちなみに公式ドキュメントによると以下の構成で構築するようです。
Nodes
・You can use virtual or physical machines. ・While you can build a cluster with 1 machine, in order to run all the examples and tests you need at least 4 nodes. ・Many Getting-started-guides make a distinction between the master node and regular nodes. This is not strictly necessary. ・Nodes will need to run some version of Linux with the x86_64 architecture. It may be possible to run on other OSes and Architectures, but this guide does not try to assist with that. ・Apiserver and etcd together are fine on a machine with 1 core and 1GB RAM for clusters with 10s of nodes. Larger or more active clusters may benefit from more cores. ・Other nodes can have any reasonable amount of memory and any number of cores. They need not have identical configurations.
サーバセットアップ
今回は VM を使います。 16.04.5 LTS を利用しています。
今回は、 hosts ファイルにそれぞれのサーバを登録しておきました。
net.ipv4.ip_forward を 1 にしておきます。忘れると意外と気づかないハマりポイントなので気をつけてください。
dokcer install
以下を参考にしておくと良いかと思います。 18.06.0-ce をインストールしました。
https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce
kubernetes の バイナリ を install
ここからが本題です。ちなみに SSL なしで構築します。
以下から kubernetes.tar.gz をダウンロードします。 本記事では v1.11.2 を入れています。 URL は latest にしています。
https://github.com/kubernetes/kubernetes/releases/latest
適当な場所に落としてください。後々バイナリだけ取り出します。
$ wget https://github.com/kubernetes/kubernetes/releases/download/v1.11.2/kubernetes.tar.gz
公式マニュアルにもありますが、./kubernetes/server 配下のファイルを解凍してください。
Download the latest binary release and unzip it. Server binary tarballs are no longer included in the Kubernetes final tarball, so you will need to locate and run ./kubernetes/cluster/get-kube-binaries.sh to download the client and server binaries. Then locate ./kubernetes/server/kubernetes-server-linux-amd64.tar.gz and unzip that. Then, within the second set of unzipped files, locate ./kubernetes/server/bin, which contains all the necessary binaries
kubelet や kube-proxy などバイナリ一式 /usr/local/bin へ移動しておきます。 kube-apiserver など master でのみ必要なものもありますが、分類が手間なので一式移動してしまいます。
kubetlet
kubelet は pod を起動し管理する役割を持っています。docker と apiserver の間にいるイメージです。 まずはそのことを理解をするため、Node に単体で動かしてみます。ここでは apiserver を指定しません(まだいないのですし)
nginx を起動するマニュフェストを kubelet に読み込ませて起動します。
$ kubelet --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice --pod-manifest-path /tmp/nginx.yaml &> /tmp/kubelet.log &
runtime-cgroups の部分ですが、Failed to get system container stats for のようなエラーが出たため、こちらを参考にいれています。
さて、docker コマンドで見てみましょう。nginx のコンテナできてますね。
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1f979d3281fb nginx "nginx -g 'daemon of…" 3 minutes ago Up 3 minutes k8s_nginx_nginx-komei-k8s-master_default_8041421870561284c2290a9297f98428_0 06786bd7d802 k8s.gcr.io/pause:3.1 "/pause" 3 minutes ago Up 3 minutes k8s_POD_nginx-komei-k8s-master_default_8041421870561284c2290a9297f98428_0
docker inspect を叩い て ip アドレスを覗き見してみます。直接 curl でアクセスするとデフォルトページが出てくるはずです。
# curl 192.168.99.2 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body>
kube-apiserver
api server は名前の通りですが、kubectl を叩いた時や kubelet など各コンポーネントとの通信を受け付けます。 ここから master を組み立てていきます。
etcd
etcd が必要となりますのでインストールします。
$ wget https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz $ tar xzvf etcd-v3.3.9-linux-amd64.tar.gz $ cd etcd-v3.3.9-linux-amd64 $ cp etcd* /usr/local/bin/
次に起動します。
$ etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://<master ip address>:2379 &> /tmp/etcd.log &
etcdctl を使って起動確認しておきます。
$ etcdctl cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://<master ip address>:2379 cluster is healthy
一応、 ss -ltn で 2379 が開いていることも確認しておくと良いでしょう。
kube-apiserver
kube-apiserver のバイナリはすでに配置していますので、起動するのみです。 オプションで先ほど渡した etcd を渡します。service-cluster-ip-range はその名の通りですが、kubernetes のクラスタ内でのみ疎通が可能な ClusterIP の払い出しレンジを設定しています。admission-control は off にしています(後述)
$ kube-apiserver --etcd-servers=http://localhost:2379 --service-cluster-ip-range=192.168.199.0/24 --bind-address=0.0.0.0 --admission-control="" --insecure-bind-address=0.0.0.0 &> /tmp/apiserver.log &
それでは起動確認をしてみましょう。自身の 8080 へアクセスしてみます。
$ curl http://localhost:8080/api/v1/nodes { "kind": "NodeList", "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/nodes", "resourceVersion": "37" }, "items": [] }
まだ node がいないですね。Node 側で kubelet に apiserver の値を設定してもう一回起動してみます。
ちなみに、 --api-servers
は利用できなくなっているので、以下のように kubernetes.conf を利用してみます。
$ cat /etc/kubernetes/kubelet.conf apiVersion: v1 clusters: - cluster: server: http://<master ip address>:8080 kind: Config preferences: {} users: [] $ $ kubelet --runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice --kubeconfig=/etc/kubernetes/kubelet.conf &> /tmp/kubelet.log &
では同じように curl を叩いてみましょう。node が出力されるはずです。
/etc/kubernetes/kubelet.conf と同様の内容を ~/.kube/config
に設定して kubectl を叩いてみます。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION komei-k8s-node01 Ready <none> 16s v1.11.2
$ Master でも kubelet を起動して確認してみます。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION komei-k8s-master Ready <none> 23s v1.11.2 komei-k8s-node01 Ready <none> 9m v1.11.2
kubectl get nodes が出てきましたが、 service を作ったり pod を起動したり kubernetes を利用する上での操作は理解しているものとして記載しています。ちなみに以下の参考書を一式やってみるとこのあたりは理解できると思います。
- 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
- 出版社/メーカー: オライリージャパン
- 発売日: 2018/03/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
kube scheduler
スケジューラは pod をどのノードに配置するのかを決める役割を持っています。 こちらもバイナリは配置済みなので起動だけします。
$ kube-scheduler --master=http://localhost:8080 &> /tmp/scheduler.log &
controller mangaer
Replication Controller や Service Account を管理します。これで master がほぼ完成です。 おそらくこれを立てる前に Service Account を見ても default がないはずです。
こちらも起動のみです。
$ kube-controller-manager --master=http://localhost:8080 &> /tmp/controller-manager.log &
同時に service account も作られます。
$ kubectl get serviceaccounts NAME SECRETS AGE default 0 42s
ちなみに admission-control を off にしておいたのは以下のようなエラーが出るのを避けるためです。
$ kubectl create -f /tmp/nginx.yaml Error from server (ServerTimeout): error when creating "/tmp/nginx.yaml": No API token found for service account "default", retry after the token is automatically created and added to the service account
この辺りを読んでおくと良いと思います。
Managing Service Accounts - Kubernetes
それでは pod がうまく起動したことを確認してみましょう。 ただ、無事に pod が立ったのに cluster ip でアクセスできないですよね?
ここからネットワーク周りを組み立てていきます。
kube-proxy
まさにという感じですね。Node にインストールします。
$ kube-proxy --master=http://<master ip address>:8080 &> /tmp/proxy.log &
ip a とか ip r すればわかりますが、これでも cluster ip へ疎通できる気がしないですね。
flannel
flannel です。Container Networking Interface (CNI) です。
今回、v0.10.0 を利用します。以下から落として例によってパスが通った場所へ配置します。
https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz
そして、flannel の設定を etcd へ設定します。
$ etcdctl mk /flannel/network/config/ '{"Network":"192.168.200.0/23"}'
flannel を起動します。
$ flanneld -ip-masq -kubeconfig-file /etc/kubernetes/kubernetes.conf --proxy-mode=iptables -etcd-endpoints=http://<master ip address>:2379 -etcd-prefix=/flannel/network &> /tmp/flanneld.log &
$ mkdir -p /etc/cni/net.d /opt/cni/bin/
以下の通り cni の plugin を一式配置します。
$ wget https://github.com/containernetworking/cni/releases/download/v0.6.0/cni-amd64-v0.6.0.tgz $ wget https://github.com/containernetworking/plugins/releases/download/v0.7.1/cni-plugins-amd64-v0.7.1.tgz $ cd /opt/cni/bin $ tar xzvf /tmp/cni-amd64-v0.6.0.tgz $ tar xzf /tmp/cni-plugins-amd64-v0.7.1.tgz
設定も入れておきます。
$ cat /etc/cni/net.d/flannel.conf { "name": "podnet", "type": "flannel", "delegate": { "isDefaultGateway": true } }
pod に使ってもらわないと意味がないので、conf と plugin の path を kubelet に渡します。 以下のオプションをつけて kubelet を起動し直します。
--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin
すると cni0 がインタフェースとして作成され、pod で利用する veth の master が cni0 になります。
34: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue state UP group default qlen 1000 link/ether 5a:ba:f0:7b:79:96 brd ff:ff:ff:ff:ff:ff inet 192.168.201.1/25 scope global cni0 valid_lft forever preferred_lft forever 35: veth2005db1c@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1472 qdisc noqueue master cni0 state UP group default link/ether 6a:2d:31:c9:ee:cd brd ff:ff:ff:ff:ff:ff link-netnsid 0
ちなみに docker 周りなど systemctl daemon-reload かけて restart しないと反映されない箇所を触った場合は適宜実施してください。
動作確認
ここまでくるともう完成です。 ClusterIP で接続できますよね。 次に、Node Port で service を作ってみましょう。以下のようにアクセスできるはずです。
curl <node ip address>:30073 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
まとめ
どうでしょうか?実際は理解が甘くてつまづいたりする箇所がありました。 バージョンが変わるとオプションが変わったりしますので、一度つまづいてみると理解が深まると思います。
まずは kubernetes を利用する側を勉強してみて、cluster を立てるという順番にで学習しました。 利用する部分は実際に実務で関われると良いと思いますが、機会がなければまずは網羅性の高い参考書を一冊やってみるとかなり理解は深まると思います。
シェアして頂けると嬉しいです。
参考になったという方がいれば是非お願いしますm(_ _ )m
モチベーション維持の観点で非常に励みになります。
- 作者: Kelsey Hightower,Brendan Burns,Joe Beda,松浦隼人
- 出版社/メーカー: オライリージャパン
- 発売日: 2018/03/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Docker実践ガイド impress top gearシリーズ
- 作者: 古賀政純
- 出版社/メーカー: インプレス
- 発売日: 2015/12/17
- メディア: Kindle版
- この商品を含むブログ (1件) を見る
Kubernetes完全ガイド (impress top gear)
- 作者: 青山真也
- 出版社/メーカー: インプレス
- 発売日: 2018/09/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る