はじめに
前記事では、K8sのコントロールプレーンをEKSとしてKubeEdgeの構築を試みました。結果、EKSはEKSに最適化されたAMIから構築されたEC2しか利用できず、AWS外のエッジノードはWorkerNodeとしてJoinできないことがわかりました。
今回はkubeadm
を利用してコントロールプレーンも構築した上で、KubeEdgeの構築を試みます。
KubeEdgeの概要についてはこちらをご参照ください。
なお、前記事では、EKSのバージョン表記の問題からKubeEdgeのインストールツールであるkeadm
がうまく動作しないバグがあり、そのバグがリリースされていないものの、HEADで解決されていたことから、keadm
を自分でビルドし、構築を行う方法を取りました。
※KubeEdge 1.2.1の次のバージョンにて改修版がリリースされるものと思われます
本記事においてはピュアなコントロールプレーンを構築するため、上記の問題は発生せず、自分でビルドする必要はないのですが、せっかくなのでより新しいバイナリを、ということでこれをそのまま使い回すこととします。
実行環境
今回ためした実行環境は以下の通りです。
ローカル
- macOS Catalina(10.15.3)
- zhs + prezto
- aws-cli/1.18.24 Python/3.8.2 Darwin/19.3.0 botocore/1.15.24
- Homebrew 2.2.10
K8s Control plane & KubeEdge Master Node
K8sのコントロールプレーンとKubeEdgeマスターノードは同居の構成とします。
(KubeEdgeのマスターノードは大してメモリも食わないので!)
- Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-07f4cb4629342979c (64 ビット x86)
- t3.medium
- K8s 1.18.0
- kubeadm 1.18.0
- kubectl 1.18.0
- golang 1.13.8
- keadm HEAD(506b130)
- KubeEdge 1.2.1
KubeEdge Worker Node
本来はエッジサーバやRaspberry Piなどの機器で実行するものですが、NWのつなぎこみ等手間がかかるので今回はEC2で構築し、これをEdgeNodeとして見立てます。
EC2は以下のインスタンスを立てました。HEADを見る限り、CentOSなどへの対応が進められていますが、現状はMasterNodeもEdgeNodeもUbuntuのみ対応です。
- Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-07f4cb4629342979c (64 ビット x86)
- t3.medium
K8s Control plane & KubeEdge Master Nodeのセットアップ
早速セットアップしていきます。
諸々アップデート
おまじないですが、やっておきます。
# apt-get update
# apt-get upgrade
K8s Control plane & KubeEdge Master Nodeの構築
公式ドキュメントをみながら構築を進めます。
K8s Control planeのインストール
こちらも同じく公式ドキュメントをみながらインストールを進めます。
##初期設定
##ブリッジされたトラフィックをiptablesからフィルタリングできるように変更する
##br_netfilterのロード
# modprobe br_netfilter
##ロード確認。表示されればロードされている
# lsmod | grep br_netfilter
br_netfilter 24576 0
bridge 155648 1 br_netfilter
##設定の投入
# cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
##設定の反映
# sysctl --system
~
##設定の確認。2行表示されれば設定できている
# sysctl -a | grep -e "net.bridge.bridge-nf-call-ip6tables = 1" -e "net.bridge.bridge-nf-call-iptables = 1"
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
##Dockerのインストール
# apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
# add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# apt-get update
# apt-get install docker-ce docker-ce-cli containerd.io
# cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
# mkdir -p /etc/systemd/system/docker.service.d
# systemctl daemon-reload
# systemctl restart docker
##kubeadm, kubelet, kubectlのインストール
# apt-get update && apt-get install -y apt-transport-https curl
Hit:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic InRelease
Hit:2 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic-updates InRelease
Hit:3 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic-backports InRelease
Hit:4 https://download.docker.com/linux/ubuntu bionic InRelease
Hit:5 http://security.ubuntu.com/ubuntu bionic-security InRelease
Reading package lists... Done
Reading package lists... Done
Building dependency tree
Reading state information... Done
curl is already the newest version (7.58.0-2ubuntu3.8).
apt-transport-https is already the newest version (1.6.12).
0 upgraded, 0 newly installed, 0 to remove and 3 not upgraded.
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
# cat <<EOF | tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
deb https://apt.kubernetes.io/ kubernetes-xenial main
# apt-get update
# apt-get install -y kubelet kubeadm kubectl
# apt-mark hold kubelet kubeadm kubectl
kubelet set on hold.
kubeadm set on hold.
kubectl set on hold.
##kubeletが利用するcgroup driverの設定
##Dockerのcgroup dirverにあわせてsystemdに変更する
# echo 'KUBELET_EXTRA_ARGS=--cgroup-driver=systemd' > /etc/default/kubelet
# systemctl daemon-reload
# systemctl restart kubelet
##kubeadmをつかったK8sコントロールプレーンの構築
##--pod-network-cidrはPodのCIDRを指定するオプション。今回はCNIとしてFlannelを利用するため、
##FlannelのCIDRにあわせる必要がある。
##※Flannelが利用するCIDRを変更することも可能だが、その場合、本オプションとFlannnelをデプロイする際のyamlを書き換えてデプロイする必要がある
# kubeadm init --pod-network-cidr=10.244.0.0/16
W0408 13:57:33.184817 5951 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[init] Using Kubernetes version: v1.18.0
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
〜
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
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
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
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 172.31.26.4:6443 --token hogehoge \
--discovery-token-ca-cert-hash sha256:hogehoge
##kubectlの初期設定
# mkdir -p $HOME/.kube
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# chown $(id -u):$(id -g) $HOME/.kube/config
##Flannnelのデプロイ
# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds-amd64 created
daemonset.apps/kube-flannel-ds-arm64 created
daemonset.apps/kube-flannel-ds-arm created
daemonset.apps/kube-flannel-ds-ppc64le created
daemonset.apps/kube-flannel-ds-s390x created
##デプロイの確認
##動作しているPodを確認し、kube-flannnel-ds-amd64がデプロイされ、STATUSがRunningであることを確認する
# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-66bff467f8-6l5vx 1/1 Running 0 2m25s
kube-system coredns-66bff467f8-zlsx4 1/1 Running 0 2m25s
kube-system etcd-ip-172-31-26-4 1/1 Running 0 2m43s
kube-system kube-apiserver-ip-172-31-26-4 1/1 Running 0 2m43s
kube-system kube-controller-manager-ip-172-31-26-4 1/1 Running 0 2m42s
kube-system kube-flannel-ds-amd64-hncgd 1/1 Running 0 39s
kube-system kube-proxy-kv52x 1/1 Running 0 2m25s
kube-system kube-scheduler-ip-172-31-26-4 1/1 Running 0 2m42s
KubeEdgeのインストール
keadmのビルド
##golangのインストール
##インストールにはgoenvを利用し、インストール手順(https://github.com/syndbg/goenv/blob/master/INSTALL.md)に従ってインストールする
##goenvのチェックアウト
# git clone https://github.com/syndbg/goenv.git ~/.goenv
##パスの追加。
##Ubuntuはbash_profile読まないのでbashrcへパスを通す
# echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.bashrc
# echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.bashrc
# echo 'eval "$(goenv init -)"' >> ~/.bashrc
##ターミナルの再起動
##golang 1.13系の最新版(執筆時点)の1.13.8をインストール
# goenv install 1.13.8
Downloading go1.13.8.linux-amd64.tar.gz...
-> https://dl.google.com/go/go1.13.8.linux-amd64.tar.gz
Installing Go Linux 64bit 1.13.8...
Installed Go Linux 64bit 1.13.8 to /root/.goenv/versions/1.13.8
# goenv global 1.13.8
##go versionを実行してインストールしたバージョンが表示されれば完了
# go version
go version go1.13.8 linux/amd64
##keadmのビルド
##リポジトリのクローン。ブランチはHEADを使いたいため、Masterでよい
# git clone https://github.com/kubeedge/kubeedge.git $GOPATH/src/github.com/kubeedge/kubeedge
##ビルドの実行
# cd $GOPATH/src/github.com/kubeedge/kubeedge
# make all WHAT=keadm
# #エラーが出なければOK
##以下のパスにkeadmのバイナリが作成されていれば完了
# cd _output/local/bin/
# ls -l
total 37064
-rwxr-xr-x 1 root root 37952949 Mar 19 14:10 keadm
KubeEdgeのインストール
ビルドしたkeadmを実行します。最後にCloudCore started
と出たら完了です。
##keadm initを実行するとcloudcoreのバイナリダウンロードや証明書類の発行、デフォルトのコンフィグ作成などが行われる
# ./keadm init
Kubernetes version verification passed, KubeEdge installation will start...
~中略~
Certificates got generated at: /etc/kubeedge/ ca and /etc/kubeedge/ certs
certs/
certs/edge.csr
certs/edge.crt
certs/edge.key
Certificates got tared at: /etc/kubeedge/ path, Please copy it to desired edge node (at /etc/kubeedge/ path)
KubeEdge cloudcore is running, For logs visit: /var/log/kubeedge/cloudcore.log
CloudCore started
KubeEdge Worker Nodeのセットアップ
諸々アップデート
おまじないですが、やっておきます。
# apt-get update
# apt-get upgrade
Dockerのインストール
公式ドキュメントをみてインストールします。
# apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
##x86_64/amd64はコレ
##arm等の場合は公式を見てリポジトリのURLを判断すること
# add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# apt-get update
# apt-get install docker-ce docker-ce-cli containerd.io
KubeEdgeのインストール
MasterNodeの/etc/kubeedge/
配下のファイル郡をWorkerNodeの/etc/kubeedge
配下へコピーします。
また、先程ビルドしたkeadm
も同様に自分のホームディレクトリや/usr/local/bin
などにコピーします。
クラスターへのJoin
以下のコマンドを実行すれば、EdgeNodeのバイナリ郡がダウンロードされ、KubeEdgeのMasterを経由してK8sにWorkerNodeとして登録されます。
~# ./keadm join --cloudcore-ipport=192.168.10.195:10000
# keadm join --cloudcore-ipport=172.31.26.4:10000 --interfacename=ens5 --runtimetype docker --edgenode-name edge-01
〜略〜
kubeedge-v1.2.1-linux-amd64/
kubeedge-v1.2.1-linux-amd64/edge/
kubeedge-v1.2.1-linux-amd64/edge/edgecore
kubeedge-v1.2.1-linux-amd64/cloud/
kubeedge-v1.2.1-linux-amd64/cloud/csidriver/
kubeedge-v1.2.1-linux-amd64/cloud/csidriver/csidriver
kubeedge-v1.2.1-linux-amd64/cloud/admission/
kubeedge-v1.2.1-linux-amd64/cloud/admission/admission
kubeedge-v1.2.1-linux-amd64/cloud/cloudcore/
kubeedge-v1.2.1-linux-amd64/cloud/cloudcore/cloudcore
kubeedge-v1.2.1-linux-amd64/version
KubeEdge edgecore is running, For logs visit: /var/log/kubeedge/edgecore.log
動作確認
WorkerNodeの登録確認
K8s Control plane & KubeEdge Master Nodeからkubectlで確認してみます。
ノードが登録され、STATUSがReadyであれば無事動作しています。
# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
edge-01 Ready edge 14d v1.17.1-kubeedge-v1.2.1 172.31.19.17 <none> Ubuntu 18.04.4 LTS 4.15.0-1065-aws remote://19.3.8
Podのデプロイ
以下のyamlでPodをデプロイしてみます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-edge-deployment
labels:
k8s-app: nginx-edge
namespace: default
spec:
replicas: 1
selector:
matchLabels:
k8s-app: nginx-edge
template:
metadata:
labels:
k8s-app: nginx-edge
spec:
nodeSelector:
node-role.kubernetes.io/edge: ""
containers:
- name: nginx
image: nginx:1.15.12
ports:
- containerPort: 80
hostPort: 80
# kubectl apply -f nginx-edge-deployment.yaml
deployment.apps/nginx-edge-deployment configured
# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-edge-deployment-6747b6875c-sd4rb 1/1 Running 0 9s 172.17.0.2 edge-01 <none> <none>
無事、Podが起動しています!
ただし、PodのIPはFlannnelのCIDRとは異なるようです。調べてみたところ、現状の仕様のようです(これは次回解明します)
WorkerNodeからも見てみます。
同様に問題なさそうです!!
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7a31727ab1b1 53f3fd8007f7 "nginx -g 'daemon of…" About a minute ago Up About a minute k8s_nginx_nginx-edge-deployment-6747b6875c-sd4rb_default_dbf2b7fd-dcee-4e77-9647-bd15657f57a2_0
7dbd20393fbc kubeedge/pause:3.1 "/pause" About a minute ago Up About a minute 0.0.0.0:80->80/tcp k8s_POD_nginx-edge-deployment-6747b6875c-sd4rb_default_dbf2b7fd-dcee-4e77-9647-bd15657f57a2_0
まとめ
kubeadm
を利用しK8sのコントロールプレーンを構築し、KubeEdge1.2.1を用いてWorkerNodeをクラスターに参加させました。
また、その上でPodが動作することも確認できました。
次回は構築できたKubeEdgeを用いてK8sと同様に使える機能、使えない機能、特徴等について深堀りしていきたいと思います。