月10ドルで海外VPSでKubernetesを試してみる(kubernetes v1.9版)

VultrでのKubernetesセットアップ方法

以前書いた記事

inajob.hatenablog.jp

で反響があったのですが、今試すとずいぶんやり方が変わっているところがあるので、Kubernetes1.9のやり方をまとめました。

例によって下記からVultrに申し込んでもらうと僕に$10入ります。 (以前の記事で$10ゲットしたので、やる気が出てこの記事を書く気になりました! この記事読んで試してみたいと思った人はぜひ下記リンクからお願いします。僕へのご褒美になります)

www.vultr.com

以前の記事では1台のマシンで構築したのですが、さすがにつらかったので、今回は奮発して$10/monthで2台構成のクラスタを作成します。 この手順で作るkubernetesはアルファの機能を使っていたり、セキュリティ上まずい設定を指定しているところもあるので、このままインターネットにさらし続けるのは危険です。

今回はコマンドやmanifestをgit上にまとめました。 github.com

準備

f:id:inajob:20180228170636p:plain

サーバは上記のプランで2つ用意する。 OSはUbuntu 17.10 x64

master, worker共通のセットアップ手順

事前にパッケージは最新化しておく

# apt-get update && apt-get upgrade
#必要に応じてリブートする
# reboot
# git clone https://github.com/inajob/my-vps-kubernetes.git
# cd my-vps-kubernetes/
# sh init-scripts/setup.sh

init-scripts/setup.shの解説

#!/bin/sh

# dockerをインストール
apt-get install -y docker.io

# kubeadm kubelet kubectlのインストール
apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl

# swapの設定(非推奨だが非力なマシンなので設定します)
dd if=/dev/zero of=/swapfile count=2048 bs=1M
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo "/swapfile   none    swap    sw    0   0" >> /etc/fstab

#kubeletの設定ファイルを作るためにkubeadm initを実行(実際は失敗する)
kubeadm init

# kubeletの設定を変更しswapがonの状態でも起動できるようにする
sed -i 's/\/usr\/bin\/kubelet/\/usr\/bin\/kubelet --fail-swap-on=false /' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

# kubeadmのお片づけをする(これをしないとこのあとのkubeadm initが実行できない)
kubeadm reset

# kubeletの設定変更を反映する
systemctl daemon-reload
systemctl restart kubelet

masterのセットアップ手順

# kubeadm init --ignore-preflight-errors=Swap

--ignore-preflight-errors=Swapは本来Swapが有効だとこのコマンドは失敗するのだが、それを無視して進めるようするためのオプションです。

kubeadm join .... といったworker接続用の文字列が出るのでメモ帳などにコピーしておきます。

workerのセットアップ手順

さきほどコピーしたkubeadm join .... の末尾に同様に--ignore-preflight-errors=Swapをつけて実行します。

# kubeadm join ....--ignore-preflight-errors=Swap

手元のラップトップ

kubectlをインストールしておきます。

SCPでmasterサーバのadmin.confを持ってきます。

$ scp root@masterサーバのアドレス:/etc/kubernetes/admin.conf ./admin.conf

ラップトップ内にmasterサーバへのプロキシを作成します。

$ kubectl --kubeconfig=:admin.conf proxy  --port=8080 --disable-filter=true --accept-hosts='^*$' --reject-paths='^$'

nodeを確認します

$ kubectl get nodes
NAME         STATUS     ROLES     AGE       VERSION
kubernetes   NotReady   master    4m        v1.9.3
worker01     NotReady   <none>    3m        v1.9.3

CNIネットワークを指定していないのでNotReadyのままですが2台のサーバでクラスタが組めていることが確認できます。

Weaveのデプロイ

CNIネットワークプラグインであるweaveををインストールします。 ほかのネットワークプラグインを使うこともできるので気になる人は公式ページから探してみてください

Using kubeadm to Create a Cluster | Kubernetes

$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=1.9"

Readyになりました。

$ kubectl get nodes
NAME         STATUS    ROLES     AGE       VERSION
kubernetes   Ready     master    6m        v1.9.3
worker01     Ready     <none>    5m        v1.9.3

kube-dnsカスタム設定のデプロイ

$ git clone https://github.com/inajob/my-vps-kubernetes.git
$ cd my-vps-kubernetes/
$ kubectl apply -f manifests/dns/
configmap "kube-dns" created

これの中身は下記です

apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-dns
  namespace: kube-system
data:
  upstreamNameservers: |
    ["8.8.8.8", "8.8.4.4"]

ubuntu固有の問題らしく kube-dns copies 127.0.0.35 from host's /etc/resolv.conf, doesn't work · Issue #45828 · kubernetes/kubernetes · GitHub これを入れないとpodから外への名前解決が失敗します。

どうもUbuntuは内部にDNSサーバを持っているようで、127.0.0.53が/etc/resolv.confに書かれています。しかしPodの中からはこのIPに到達できないので、kube-dnsから外の名前を引くことができなくなるようです。 このConfigMapを入れることで外のDNSを明示的に指定しています。

ingress-controllerのデプロイ

$ kubectl apply -f manifests/ingress-controller/
deployment "default-http-backend" created
service "default-http-backend" created
serviceaccount "ingress" created
clusterrole "ingress-clusterrole" created
role "ingress-role" created
rolebinding "ingress-role-binding" created
clusterrolebinding "ingress-clusterrole-binding" created
deployment "nghttpx-ingress-controller" created
service "nginhttpx-health" created

今後のためにingress-controllerをデプロイします。

prometheus, node-exporter, grafanaのデプロイ

$ kubectl apply -f manifests/monitoring/
deployment "monitoring-grafana" created
service "monitoring-grafana" created
daemonset "node-exporter" created
configmap "prometheus-config" created
clusterrole "prometheus" created
serviceaccount "prometheus" created
clusterrolebinding "prometheus" created
deployment "prometheus" created
service "prometheus" created

負荷状況のメトリクスを取得、可視化するために追加します。

動作確認

Pod一覧

$ kubectl get pods -n kube-system
NAME                                         READY     STATUS    RESTARTS   AGE
default-http-backend-55c6c69b88-vlqcx        1/1       Running   0          1m
etcd-kubernetes                              1/1       Running   0          10m
kube-apiserver-kubernetes                    1/1       Running   0          9m
kube-controller-manager-kubernetes           1/1       Running   0          9m
kube-dns-6f4fd4bdf-c2995                     3/3       Running   0          10m
kube-proxy-622sq                             1/1       Running   0          9m
kube-proxy-j5754                             1/1       Running   0          10m
kube-scheduler-kubernetes                    1/1       Running   0          9m
monitoring-grafana-8dd9cb57f-4ms82           1/1       Running   0          43s
nghttpx-ingress-controller-78749dc54-jl4nv   1/1       Running   0          1m
node-exporter-5294m                          1/1       Running   0          43s
prometheus-8694d8cdd8-vmw7h                  1/1       Running   0          43s
weave-net-r5jft                              2/2       Running   0          4m
weave-net-wm7sn                              2/2       Running   0          4m

PrometheusのUIを確認

Prometheusは固定のポートでexposeしてあります。

http://masterまたはworkerのIPアドレス:30090/

GraphanaのUIを確認

Graphanaも固定のポートでexposeしてあります。

http://masterまたはworkerのIPアドレス:30091/

grafanaの設定方法は 月5ドルの海外VPSでKubernetesを試してみる - inajob's blog の記事のままです。参考にしてください。

f:id:inajob:20180228174920p:plain

next

このリポジトリではingress-controllerもデプロイしています。 ドメインを持っている人は、DNSの設定とIngressリソースのデプロイを行うことで、オリジナルドメインのサービスを提供することができます。

それについては次の記事に記載しています。

inajob.hatenablog.jp