Kubernetes on CentOS on ESXi 環境を構築してみた
これまでは GKE 環境を使って Kubernetes で遊んでいましたが、Kubernetes 自体の動きを見てみたいこともあり、手元にクラスタを構築しました。
kubeadm を使って、CentOS 上に Kubernetes クラスタを構築し、ダッシュボードの導入まで行いました。メモを兼ねて手順を紹介します。
システム構成
タイトル通り「Kubernetes on CentOS on ESXi」の構成となっており、ESXi 自体は Intel NUC で動いています。
- Kubeadm 1.9.6
- Kubernetes 1.9
- CentOS 7.4
- VMware ESXi 6.0
- Intel NUC6i5SYH
0. 事前確認
今回は、Master 1台、Worker Node 2台の構成。(仮想CPU2コア・メモリ4GB × 3台)
ひとまず作って動かすことを優先するため、kubeadm
で構築。
参考にした公式ドキュメント: Installing kubeadm | Kubernetes
1. サーバ共通部分の構築
CentOS を用意し、NIC やネットワーク周りが正常に動作していることを確認。yum update
なども済ませておく。
ポート開放は後回しとして、Docker をインストール。
Installing kubeadm | Kubernetes – Installing Docker
$ sudo yum install -y docker
$ sudo systemctl enable docker && systemctl start docker
Kubernetes 用のリポジトリを追加。
$ sudo vi /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
Kubeadm, Kubelet, Kubectl をインストール。
$ sudo yum install -y kubelet kubeadm kubectl
$ sudo systemctl enable kubelet && systemctl start kubelet
SELinux を無効化。(未対応らしい)
$ sudo setenforce 0
$ sudo vi /etc/selinux/config
SELINUX=enforcing
↓
SELINUX=disabled
iptables のバイパスを避けるパラメータ追加。
$ sudo echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.d/kubernetes.conf
$ sudo echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.d/kubernetes.conf
$ sudo sysctl -p
Cgroup Driver
が、Docker とKubelet で一致していることを確認。
$ docker info | grep -i cgroup
→systemd
$ grep -i cgroup /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
→systemd
swap が有効になっている場合は無効化。/etc/fstab
の記載も削る。
$ sudo swapoff -a
$ sudo vi /etc/fstab
/etc/hosts
に自サーバのホスト名を追記。
$ sudo vi /etc/hosts
192.168.xxx.yyy kube-master
2. サーバクローン
今回は ESXi を利用しているため、VMware 自身の機能でサーバを複製する。
2台複製し、ホスト名・IPアドレス・hosts の修正をしておく。
念のため、MACアドレスが重複していない(再生成されている)ことも確認。
3. Master 構築
1台を選定し、Master としてセットアップを進める。
序盤にスキップした firewalld の設定を追加。
Installing kubeadm | Kubernetes – Check required ports
$ sudo firewall-cmd --add-port=6443/tcp --zone=public --parmanent
$ sudo firewall-cmd --add-port=2379-2380/tcp --zone=public --parmanent
$ sudo firewall-cmd --add-port=10250/tcp --zone=public --parmanent
$ sudo firewall-cmd --add-port=10251/tcp --zone=public --parmanent
$ sudo firewall-cmd --add-port=10255/tcp --zone=public --parmanent
本題の Kubernetes クラスタを作成。
--pod-network-cidr
は Kubernetes で利用するネットワーク指定でデフォルトのまま。--apiserver-advertise-address
は kube-apiserver 用アドレス指定。ここでは master サーバ自身の IP とする。
$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.xxx.yyy
無事に構築できたことを確認し、kubeadm join ……
のコマンドを控えておく。
Your Kubernetes master has initialized successfully!
(中略)
You can now join any number of machines by running the following on each node
as root:
kubeadm join --token aaaa.bbbbbb 192.168.xxx.yyy:6443 --discovery-token-ca-cert-hash sha256:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
普段使うユーザに切り替え、kubectl
の接続設定を反映。
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl cluster-info
Kubernetes master is running at https://10.0.xxx.yyy:6443
4. Pod ネットワーク構築
Using kubeadm to Create a Cluster | Kubernetes – (3/4) Installing a pod network
今回は Flannel を利用するため、yml ファイルを一旦ダウンロード。
$ curl https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml -o kube-flannel.yml
利用する NIC 名を command:
の末尾に追記。
$ vi kube-flannel.yml
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.9.1-amd64
command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr", "--iface=ens160" ]
編集済みの yml ファイルを適用。kube-dns
が Running
になれば完了。
$ kubectl apply -f kube-flannel.yml
$ kubectl get pod -n kube-system | grep kube-dns
kube-dns-6f4fd4bdf-vmtnx 3/3 Running 0 2d
$ kubectl cluster-info
Kubernetes master is running at https://10.0.xxx.yyy:6443
KubeDNS is running at https://10.0.xxx.yyy:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
5. Worker Node 構築
先ほどクローンしたサーバの状態からスタート。
今度は Worker Node 用の設定を追加。
Installing kubeadm | Kubernetes – Check required ports
$ sudo firewall-cmd --add-port=10250/tcp --zone=public --parmanent
$ sudo firewall-cmd --add-port=10255/tcp --zone=public --parmanent
$ sudo firewall-cmd --add-port=30000-32767/tcp --zone=public --parmanent
Master 構築時に提示されたコマンドだけでノード追加完了。
$ kubeadm join --token aaaa.bbbbbb 192.168.xxx.yyy:6443 --discovery-token-ca-cert-hash sha256:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
kubectl から結果を確認。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
kube-master Ready master 2d v1.9.6
kube-worker01 Ready <none> 2d v1.9.6
同様に2台目の Worker Node も追加。
6. Kubernetes Dashboard 導入
Kubernetes Dashboard – README.md に従ってデプロイするだけ。
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
$ kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard ClusterIP 10.103.221.252 <none> 443/TCP 2d
ClusterIP には外から直接アクセスできないため、ローカルプロキシを作成。
$ kubectl proxy
この状態で http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
にアクセス。
クラスタ情報取得のため、ログインを求められる。
7. Dashboard 用ユーザ作成
Creating sample user · kubernetes/dashboard Wiki を参考に yaml ファイルを作成して設定追加。
まずはユーザ作成。
$ cat <<EOF >admin-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
EOF
$ kubectl create -f admin-user.yaml
ロールを割り当て。
$ cat <<EOF >admin-user_role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
EOF
$ kubectl create -f admin-user_role.yaml
アクセストークンを取得。最後の token:
部分だけコピーして、Dashboard に貼り付け。
$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
token: eyJhbhp(略)o700OSpvTT9zlBsu-b35lzXGBRHzv5g_RA
ダッシュボードが見えるようになった。かっこいい。
7. Dashboard を NodePort 化
毎度 kubectl proxy
するのも手間なので、NodePort からアクセスできるようにする。
Accessing Dashboard 1.7.X and above · kubernetes/dashboard Wiki
Service の設定を編集。
$ kubectl -n kube-system edit service kubernetes-dashboard
エディタが開くので type:
欄を修正して上書き保存。
type: ClusterIP
↓
type: NodePort
Service を確認すると NodePort が付与された。
$ kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 2d
kubernetes-dashboard NodePort 10.103.221.252 <none> 443:32701/TCP 2d
これにより https://<MasterのIPアドレス>:32701
でアクセス可能となった。
Google Chrome だと証明書エラーで開けない場合があるので、Firefox からアクセス。
まとめ
- kubeadm を利用して CentOS 上に Kubernetes クラスタを構築しました
- Dashboard のデプロイ&初期設定&NodePort 対応を行いました
自宅に一つ Kubernetes を用意することで、費用を気にせずコンテナ立て放題・yaml 検証可能な環境が整いました。
CoreOS も試したいと考えているため、近い内にノードとしてクラスタに追加予定です。