VM2台にkubeadmでk8sクラスターを構築
表題の通り。
導入要件については以下のリンクを参照。
kubernetes.io
今回利用するVMのspecは2台とも以下。
CentOS 7.8
Disk: 50G
CPU: 4core
mem: 8G
必要なステップを以下に示す。
1. OS構成
2. 必要なコンポーネントの導入
3. masterノードの構成
4. workerノードの構成
5. podのデプロイ
6. Web UIの構成(optional)
1. OS構成
2台とも同一ネットワーク / VLAN上に存在している必要がある。
masterノード,workerノードでそれぞれユニークなhostnameを構成。
#master
$ hostnamectl set-hostname "k8s-master-1"
#worker
$ hostnamectl set-hostname "k8s-worker-1"
masterノード,workerノードでそれぞれユニークなMACアドレスが割り振られていることを確認。
以下のコマンドをそれぞれの環境で実行。
$ ip a
今回利用した環境ではDHCP等で自動的にIPが割り振られなかったためnmtuiコマンドでIPを構成。
masterノード,workerノードでそれぞれユニークなproduct_uuidが割り振られていることを確認。
以下のコマンドをそれぞれの環境で実行。
cat /sys/class/dmi/id/product_uuid
ブリッジ構成。ipv4,ipv6によるブリッジ通信の有効化。
cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl --system
参考:ブリッジ通信を制御するカーネルモジュールnetfilterがロードされていることは以下から確認できる。
$ lsmod |grep br_netfilter br_netfilter 22256 0 bridge 151336 2 br_netfilter,ebtable_broute
port構成。以下リンクからmaster / workerでそれぞれ必要なポートを確認。
kubeadmのインストール | Kubernetes
必要に応じて構成。
今回の(私の)環境の場合は以下の通り新しくruleを追加構成した。
#master
$ iptables -I INPUT 1 -p tcp --dport 6443 -j ACCEPT $ iptables -I INPUT 1 -p tcp --dport 2379:2380 -j ACCEPT $ iptables -I INPUT 1 -p tcp --dport 10250:10252 -j ACCEPT
#worker
$ iptables -I INPUT 1 -p tcp --dport 10250 -j ACCEPT $ iptables -I INPUT 1 -p tcp --dport 3000:32767 -j ACCEPT
余談:構築後にiptablesで設定した各ルール毎の該当したパケットカウントは以下。
#master
$ iptables -nvxL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 1215 75074 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:179 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:10252 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:10251 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:10250 4566860 530689761 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpts:2379:2380 3752632 451693115 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6443
#worker
$ iptables -nvxL Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 556871 302247581 cali-INPUT all -- * * 0.0.0.0/0 0.0.0.0/0 /* cali:Cz_u1IQiXIMmKD4c */ 137110 23345161 KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW /* kubernetes service portals */ 137110 23345161 KUBE-EXTERNAL-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate NEW /* kubernetes externally-visible serv ice portals */ 530660 545070871 KUBE-FIREWALL all -- * * 0.0.0.0/0 0.0.0.0/0 19 836 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpts:30000:32767 753 67427 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:10250
master, workerともにSwapをoffにする。
$ swapoff -a
2. 必要なコンポーネントの導入
ランタイムをインストールする。今回はDockerを導入。手順は以下を参照。
kubernetes.io
#master, worker
$ yum install -y yum-utils device-mapper-persistent-data lvm2 $ yum-config-manager --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo $ yum update -y && yum install -y \ containerd.io-1.2.10 \ docker-ce-19.03.4 \ docker-ce-cli-19.03.4 $ mkdir /etc/docker # すでにディレクトリが存在する場合は次のステップを実行 $ cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF $ systemctl daemon-reload $ systemctl restart docker $ systemctl status docker
kubeadm、kubelet、kubectlのインストール
#master, worker
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 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 EOF # SELinuxをpermissiveモードに設定する(効果的に無効化する) setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes systemctl enable --now kubelet
3. masterノードの構成
#kubeadmでKubernetesクラスターのを構築を実施。初めにコントロールプレーンとなるmasterのみで構成し、続いてworkerをクラスターに追加する。
その前にmasterからコンテナイメージレジストリgcr.ioに繋がることを確認。
#master
kubeadm config images pull
コントロールプレーンを構成。
#master
kubeadm init --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=10.84.82.112
# podのネットワーク範囲について、Calicoは192.168.0.0/16をPodネットワークのCIDRを利用する。その場合、本コマンドの引数--pod-network-cidrにそのCIDRを指定する必要がある。
# デフォルトではデフォルトゲートウェイに関連するネットワークインターフェースを利用するが、念のため明記。
コマンドの実行が成功すると以下のような出力が表示される。
Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ Then you can join any number of worker nodes by running the following on each as root: kubeadm join 10.84.82.112:6443 --token <token value> \ --discovery-token-ca-cert-hash sha256:<hash value> [root@k8s-master-1 ~]#
最終行当たりのkubeadm joinコマンドはクラスターに追加するworkerノードで実行するコマンドであるため、書き留めておく。
前段のmkdirからsudo chownコマンドまではmasterノードのkubectlコマンドを構成するために必要なコマンド。
#master
[root@k8s-master-1 ~]# mkdir -p $HOME/.kube [root@k8s-master-1 ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@k8s-master-1 ~]# chown $(id -u):$(id -g) $HOME/.kube/config
# 他ユーザーがkubectlコマンドを利用する場合はそのユーザーのホームディレクトリ配下で上記同様にコマンド実行。
コマンドを実行して構成を確認。現在masterノードのみ。
# master
#node情報取得 [root@k8s-master-1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master-1 NotReady master 16m v1.19.2
ネットワークコンポーネントのcalicoを構成する。
# master
kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml
以下コマンドでcalicoのpodがデプロイされ稼動していることを確認。
#pod情報 [kubeuser01@k8s-master-1 ~]$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-6b8f6f78dc-l9tcx 1/1 Running 0 2m7s kube-system calico-node-hzvcb 1/1 Running 0 2m7s kube-system coredns-f9fd979d6-r5ldn 1/1 Running 0 22m kube-system coredns-f9fd979d6-x5cgz 1/1 Running 0 22m kube-system etcd-k8s-master-1 1/1 Running 0 22m kube-system kube-apiserver-k8s-master-1 1/1 Running 0 22m kube-system kube-controller-manager-k8s-master-1 1/1 Running 0 22m kube-system kube-proxy-9lvfn 1/1 Running 0 22m kube-system kube-scheduler-k8s-master-1 1/1 Running 0 22m [kubeuser01@k8s-master-1 ~]$
4. workerノードの構成
workerノードをクラスターにjoinさせる。
先ほどコピーしておいたコマンドをworkerノード側で実行する。
#worker
kubeadm join 10.84.82.112:6443 --token <token value> \ --discovery-token-ca-cert-hash sha256:<hash value>
token とhashの値を紛失してしまった場合は以下のコマンドから確認可能。
# master
kubeadm token list
5. Podのデプロイ
例えば以下コマンドで命令的にpodをデプロイ。(deprecatedなので本来はymlによる正当な宣言的方法が望ましいです)
$ kubectl run nginx --image=nginx:latest
podのデプロイを確認。
$ kubectl get po
6. Web UIの構成(optional)
Web UIの管理コンソールを利用する場合は以下コマンド実行。
#master, workerどちらでも可
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
local PCのkubectlコマンドを構成する。
kubernetes.io
kubectlコマンドを導入し、$HOMEに.kubeディレクトリを作成、ディレクトリ内に先ほどmasterで構成したconfigファイルを転送しておく。
https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/
masterでコンソールにログインするためのadminユーザー(のtoken)を作成する。
参考:
github.com
Service Accountを生成する。以下のコマンドを実行。
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard EOF
ClusterRoleBindingを構成。↑のSAのadmin-userに対して、既存の"cluster-admin"のClusterRoleを設定。
kubectl get crで現在利用可能なClsuterRoleが確認可能。
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard EOF
以上で設定作業は完了。
作成したservice accountを確認。
$ kubectl -n kubernetes-dashboard get sa/admin-user NAME SECRETS AGE admin-user 1 15m
作成したservice accountには、secretが自動的に与えられる。
$ kubectl -n kubernetes-dashboard get sa/admin-user -o yaml ... secrets: - name: admin-user-token-6mn4x
このsecretの中にtokenが保存されているので、確認する。
secretの存在を確認。
$ kubectl get secret -n kubernetes-dashboard NAME TYPE DATA AGE admin-user-token-6mn4x kubernetes.io/service-account-token 3 18m
secretの値の確認。
$ kubectl get secret -n kubernetes-dashboard admin-user-token-6mn4x -o yaml token: <base64 encoded token value>
↑のtokenをコピーしてbase64 decodeする。decodeはecho -nしてbase64 -dに渡す。
local PCで以下のコマンドを実行。macはターミナル、windowsはPowerShell。
$ kubectl proxy
ブラウザを立ち上げ、
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/にアクセス。
tokenは先ほど取得・base64 decodeしておいた値を利用。
以上。