LoginSignup
32
31

More than 3 years have passed since last update.

MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(前編)

Last updated at Posted at 2021-04-09

初版: 2021/4/9
著者: 高久 隆史, 株式会社日立製作所

はじめに

KubeflowはKubernetes上でMLOpsを実現するためのOSSのツールキットです。2020/3にバージョン1.0がリリースされ、2021/4現在も活発に開発が行われており、機械学習を利用したシステムの開発/運用のライフサイクルを回すための有効な手段の1つとして注目されています。

本連載では、Kubeflowのバージョン1.2(連載開始時点の最新版、2020年11月リリース)について、構築手順、Kubeflow Pipelines、KFServingの基礎的な利用手順についての情報を紹介いたします。

第1回の本稿では、Amazon Web Services(以降AWSと記載します) EC2上で、OSのみインストールされている環境から、Kubeflowを前提のKubernetesも含めて構築する手順を記載いたします。
本稿で紹介する構築手順は、AWS EC2上だけでなく、オンプレミスで構築する場合も流用できる手順となっていますので、是非参考にしてください。

なお、構築手順は長くなるため、途中まで記載し、続きは、第2回の投稿で記載いたします。

投稿一覧:
1. MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(前編) (本投稿)
2. MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(後編)
3. Kubeflow Pipelinesでscikit-learnの機械学習モデルを訓練・評価してみる
4. Kubeflow KFServingでscikit-learnの学習済みモデルを用いた推論サービスを公開する

Kubeflowの構築パターンと最小スペック

Kubeflowは、オンプレミス、パブリッククラウドのどちらでも構築できます。公式サイトに記載されている構築パターンを次に示します。

Kubeflowの構築パターン

# 分類 OS Kubernetes 構築手順のURL
1 任意のKubernetesクラスタにKubeflowをデプロイ - 任意 http://www.kubeflow.org/docs/started/k8s/
2 ワークステーションにシングルノードKubernetesクラスタを構築してKubeflowをデプロイ Linux MicroK8s https://www.kubeflow.org/docs/started/workstation/getting-started-linux/
3 MiniKF
4 Minikube
5 Multipass
6 Windows MicroK8s https://www.kubeflow.org/docs/started/workstation/getting-started-windows/
7 MiniKF
8 Multipass
9 macOS MicroK8s https://www.kubeflow.org/docs/started/workstation/getting-started-macos/
10 MiniKF
11 Multipass
12 パブリッククラウドのKubernetes環境にKubeflowをデプロイ - AWS EKS https://www.kubeflow.org/docs/aws/deploy/
13 - Microsoft Azure AKS https://www.kubeflow.org/docs/azure/deploy/
14 - Google Cloud Platform GKE https://www.kubeflow.org/docs/gke/deploy/
15 - IBM IKS https://www.kubeflow.org/docs/ibm/deploy/
16 パブリッククラウドのKubernetes環境にKubeflowをデプロイ - OpenShift https://www.kubeflow.org/docs/openshift/

Kubeflowの公式サイトで確認できた、Kubeflow構築のための最小スペックを次に示します。

Kubeflow構築のための最小スペック

# 構築パターン 最小スペック 参考URL
CPU RAM ストレージ
1 KubernetesクラスタにKubeflowをデプロイ 4コア 12GB 50GB https://www.kubeflow.org/docs/started/k8s/overview/
2 Minikubeを使用 8コア 16GB 250GB https://www.kubeflow.org/docs/started/workstation/minikube-linux/

構築時の留意事項

Kubeflowの構築時に問題が発生した場合、Webサイトなどで調べても原因が分からず、苦労することがあります。Kubeflowの環境構築を行う上での留意点を次に示しますので参考にしてください。

Kubeflowの環境構築を行う上での留意点

# 留意点 理由
1 スペックに余裕のあるマシンを利用する。 リソース不足で予期しないエラーが発生して構築や実行ができない可能性があるため。
2 プロキシのないネットワーク環境を利用する。 構築時にインターネットアクセスが発生するが、プロキシ設定を行っていても、その設定が効かずにエラーとなって正しく構築できない可能性があるため。
3 Docker Hub Pull数制限に引っ掛からないようにする(必要に応じて無料アカウントの登録などを検討する)。 構築時にDocker pullが発生するため。
4 KubernetesとOSの組合せに注意する。 ・kubeadmやMicroK8sを利用する場合、OSがRHEL8やCentOS8では(iptables-legacyに対応していないため)動作しない。
・Minikubeを利用する場合は、OSはUbuntuのみに対応していると思われる。公式サイトの「Kubeflow on Windows」や「Kubeflow on macOS」のページにもMinikubeの記載があるが、その先のページはUbuntu前提となっていたため。また、実際にWindowsで構築してみようとしたが、kubectlのWindows用媒体がなく、構築できなかった。

構築の前提情報

本稿では、OSのみインストールされている環境に、KubernetesおよびKubeflow環境を新規に構築するときの手順を記載します。
具体的には、Kubeflowの前提となるKubernetesはkubeadmを利用して構築し、そこにKubeflowをデプロイする形で構築します。それぞれ以下の公式サイトの手順に沿って構築します。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
http://www.kubeflow.org/docs/started/k8s/

本稿の構築手順は、特定のパブリッククラウドなどに限定せずに、オンプレミスでも構築できる手順となりますが、OSの種類、Kubeflowのバージョン、その他の初期設定などによって、手順が異なる場合がありますので、留意願います。
本書の構築手順で利用したマシンの環境情報、および、インストールしたソフトウェアとそのバージョン情報を次に示します。

本構築手順で利用したマシンの環境情報

# 項目 内容
1 マシン概要 AWS EC2 (1インスタンス)
2 インスタンスタイプ t3a.2xlarge
3 VCPU 4
4 RAM 32GiB
5 ストレージ 192GB
6 OS Ubuntu 18.04 LTS - Bionic
7 ポート SSH(22)、および、以下のkubeadmが利用するポートは解放しておく。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#check-required-ports

本構築手順でインストールしたソフトウェアとそのバージョン情報

# ソフトウェア バージョン 補足
1 Docker CE 19.03.11 kubeadm前提のコンテナランタイムとして選択。
2 Kubernetes 1.20.1 Kubeflow前提のKubernetesとして選択。
3 kubeadm 1.20.1-00 amd64
4 kubectl 1.20.1-00 amd64
5 kubelet 1.20.1-00 amd64
6 Flannel v0.11.0 kubeadm前提のPodネットワークアドオンとして選択。
7 Kubernetes Dashboard v2.0.0 必須ではないが、状態確認用途として構築。
8 Local-path-provisioner v0.0.19 Kubeflow前提のDynamic Volume Provisionerとして選択。
9 Kubeflow 1.2.0
10 kfctl v1.2.0-0-gbc038f9

構築の流れ

今回記載する構築の一連の流れを次に記載します。

構築の流れ

# 作業項目 概要
1 SSHでログイン 構築対象マシンにSSHでログインします。
2 Swapの無効化 kubeadmの前提の設定作業として、Swapを無効化します。
3 iptablesにブリッジトラフィックを表示 kubeadmの前提の設定作業として、iptablesにブリッジトラフィックを表示します。
4 コンテナラインタイムのインストール kubeadmの前提の設定作業として、コンテナランタイムをインストールします。
5 kubeadm、kubelet、kubectlのインストール Kubeflow前提のKubernetesとしてkubeadmおよびkubeadmの関連ソフトウェアであるkubelet、kubectlをインストールします。
6 kubeadmを使用したシングルコントロールプレーンクラスターの作成 kubeadmの設定作業として、シングルコントロールプレーンクラスターを作成します。
7 Podネットワークアドオンのインストール kubeadmのPod同士の通信のため、Podネットワークアドオンのインストールを行います。
8 コントロールプレーンノードの隔離 kubeadmを、1台のクラスタで利用するため、コントロールプレーンノードの隔離の設定を行います。
9 Kubernetes Dashboard のデプロイ、アクセス(任意) 状態確認などをブラウザから行いたい場合は、Kubernetes Dashboardのデプロイを実施します。本手順は任意となります。
10 Dynamic Volume Provisionerのインストール Kubeflowの前提の設定作業として、Dynamic Volume Provisionerをインストールします。
11 Kubeflowのデプロイ Kubeflowのインストール作業として、KubernetesにKubeflowをデプロイします。
12 Kubeflow Central Dashboardへのアクセス デプロイしたKubeflowにKubeflow Central Dashboardからアクセスできることを確認します。
13 Notebook Serverの作成、接続 Kubeflow Central DashboardからNotebook Serverを作成し、接続します。

構築手順

第1回の本稿では、上で記載した「構築の流れ」の#9まで(Kubeflowの前提Kubernetesとするkubeadmの構築まで)の手順を記載します。#10以降の手順は第2回の投稿を参照してください。

1. SSHでログイン

構築するマシンにSSHでログインします。

2. Swapの無効化

kubeadmの前提として、Swapが無効化されている必要があるため、Swapを無効化します。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#before-you-begin

# Swapが無効になっているか確認
free
# --- 実行結果例 ここから -----------------------------------------------------------
#               total        used        free      shared  buff/cache   available
# Mem:       32613620      243620    30588784         768     1781216    31908148
# Swap:             0           0           0
# --- 実行結果例 ここまで -----------------------------------------------------------

# 今回は、Swapが0になっており、すでにSwapは無効でしたが、有効となっている場合は、
# 「sudo swapoff -a」コマンドの実行、および、「/etc/fstab」で定義されている
# Swapの設定をコメントアウトすることで無効化できます。

3. iptablesにブリッジトラフィックを表示

iptablesにブリッジトラフィックを表示させます。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#letting-iptables-see-bridged-traffic

# br_netfilterモジュールがロードされているか確認
lsmod | grep br_netfilter
# --- 実行結果例 ここから -----------------------------------------------------------
# (何も表示されない)
# --- 実行結果例 ここまで -----------------------------------------------------------

# (ロードされていない場合) br_netfilterモジュールをロードする
sudo modprobe br_netfilter

# ロードされていることを確認
lsmod | grep br_netfilter
# --- 実行結果例 ここから -----------------------------------------------------------
# br_netfilter           24576  0
# bridge                155648  1 br_netfilter
# --- 実行結果例 ここまで -----------------------------------------------------------

# iptablesがブリッジを追加するトラフィックを処理できるようにカーネルパラメータを変更
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# カーネルパラメータを反映
sudo sysctl --system

4. コンテナラインタイムのインストール

コンテナを実行するランタイムとしてDockerをインストールします。
(他にcontainerdやCRI-Oもありますが、Kubeflow Pipelinesに必要なArgoはDockerでのみ動作するため、本手順ではDockerをインストールします。)
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-runtime
https://kubernetes.io/docs/setup/production-environment/container-runtimes/

# Dockerのインストール
# https://docs.docker.com/engine/install/ubuntu/
# https://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker

# HTTPS経由でリポジトリを使用できるようにする
sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

# Dockerの公式GPGキーを追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# --- 実行結果例 ここから -----------------------------------------------------------
# OK
# --- 実行結果例 ここまで -----------------------------------------------------------

# Dockerのリポジトリを設定(安定版)
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

# Docker Engineとcontainerdをインストール
sudo apt-get update
sudo apt-get install -y \
  containerd.io=1.2.13-2 \
  docker-ce=5:19.03.11~3-0~ubuntu-$(lsb_release -cs) \
  docker-ce-cli=5:19.03.11~3-0~ubuntu-$(lsb_release -cs)

# DockerEngineが正しくインストールされていることを確認
sudo docker run hello-world
# --- 実行結果例 ここから -----------------------------------------------------------
# Unable to find image 'hello-world:latest' locally
# latest: Pulling from library/hello-world
# 0e03bdcc26d7: Pull complete
# Digest: sha256:1a523af650137b8accdaed439c17d684df61ee4d74feac151b5b337bd29e7eec
# Status: Downloaded newer image for hello-world:latest
# 
# Hello from Docker!
# This message shows that your installation appears to be working correctly.
# 
# To generate this message, Docker took the following steps:
#  1. The Docker client contacted the Docker daemon.
#  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
#     (amd64)
#  3. The Docker daemon created a new container from that image which runs the
#     executable that produces the output you are currently reading.
#  4. The Docker daemon streamed that output to the Docker client, which sent it
#     to your terminal.
# 
# To try something more ambitious, you can run an Ubuntu container with:
#  $ docker run -it ubuntu bash
# 
# Share images, automate workflows, and more with a free Docker ID:
#  https://hub.docker.com/
# 
# For more examples and ideas, visit:
#  https://docs.docker.com/get-started/
# --- 実行結果例 ここまで -----------------------------------------------------------

# Dockerデーモンを設定
cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

# /etc/systemd/system/docker.service.d ディレクトリを作成
sudo mkdir -p /etc/systemd/system/docker.service.d

# Dockerをリスタート
sudo systemctl daemon-reload
sudo systemctl restart docker

# Dockerサービスを有効化
sudo systemctl enable docker
# --- 実行結果例 ここから -----------------------------------------------------------
# Synchronizing state of docker.service with SysV service script with /lib/systemd/systemd-sysv-install.
# Executing: /lib/systemd/systemd-sysv-install enable docker
# --- 実行結果例 ここまで -----------------------------------------------------------

5. kubeadm、kubelet、kubectlのインストール

kubeadm、kubelet、kubectlをインストールします。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#installing-kubeadm-kubelet-and-kubectl

# 前提パッケージをインストール
sudo apt-get update
sudo apt-get install -y apt-transport-https curl

# Googleの公式GPG keyを追加
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
# --- 実行結果例 ここから -----------------------------------------------------------
# OK
# --- 実行結果例 ここまで -----------------------------------------------------------

# GoogleのKubernetesのリポジトリを設定
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF

# Kubernetesの関連パッケージをインストール
sudo apt-get update
sudo apt-get install -y kubelet=1.20.1-00 kubeadm=1.20.1-00 kubectl=1.20.1-00

sudo apt-mark hold kubelet kubeadm kubectl
# --- 実行結果例 ここから -----------------------------------------------------------
# kubelet set on hold.
# kubeadm set on hold.
# kubectl set on hold.
# --- 実行結果例 ここまで -----------------------------------------------------------

6. kubeadmを使用したシングルコントロールプレーンクラスターの作成

kubeadmを使用したシングルコントロールプレーンクラスターを作成します。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/

# gcr.ioコンテナイメージレジストリに接続できるかどうかを確認
sudo kubeadm config images pull
# --- 実行結果例 ここから -----------------------------------------------------------
# [config/images] Pulled k8s.gcr.io/kube-apiserver:v1.20.1
# [config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.20.1
# [config/images] Pulled k8s.gcr.io/kube-scheduler:v1.20.1
# [config/images] Pulled k8s.gcr.io/kube-proxy:v1.20.1
# [config/images] Pulled k8s.gcr.io/pause:3.2
# [config/images] Pulled k8s.gcr.io/etcd:3.4.13-0
# [config/images] Pulled k8s.gcr.io/coredns:1.7.0
# --- 実行結果例 ここまで -----------------------------------------------------------

# Kubelet初期化用の設定ファイルを作成(PodネットワークアドオンにFlannelを使用するのに必要な設定を記載)
cat <<EOF > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
networking:
  podSubnet: "10.244.0.0/16" # --pod-network-cidr
EOF

# 上記作成したファイルを使用して、コントロールプレーンノード(Master)を初期化
sudo kubeadm init --config kubeadm-config.yaml
# --- 実行結果例 ここから -----------------------------------------------------------
# [init] Using Kubernetes version: v1.20.1
# [preflight] Running pre-flight checks
# [preflight] Pulling images required for setting up a Kubernetes cluster
# [preflight] This might take a minute or two, depending on the speed of your internet connection
# [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
# [certs] Using certificateDir folder "/etc/kubernetes/pki"
# [certs] Generating "ca" certificate and key
# [certs] Generating "apiserver" certificate and key
# [certs] apiserver serving cert is signed for DNS names [ip-x-x-x-x kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 x.x.x.x]
# [certs] Generating "apiserver-kubelet-client" certificate and key
# [certs] Generating "front-proxy-ca" certificate and key
# [certs] Generating "front-proxy-client" certificate and key
# [certs] Generating "etcd/ca" certificate and key
# [certs] Generating "etcd/server" certificate and key
# [certs] etcd/server serving cert is signed for DNS names [ip-x-x-x-x localhost] and IPs [x.x.x.x 127.0.0.1 ::1]
# [certs] Generating "etcd/peer" certificate and key
# [certs] etcd/peer serving cert is signed for DNS names [ip-x-x-x-x localhost] and IPs [x.x.x.x 127.0.0.1 ::1]
# [certs] Generating "etcd/healthcheck-client" certificate and key
# [certs] Generating "apiserver-etcd-client" certificate and key
# [certs] Generating "sa" key and public key
# [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
# [kubeconfig] Writing "admin.conf" kubeconfig file
# [kubeconfig] Writing "kubelet.conf" kubeconfig file
# [kubeconfig] Writing "controller-manager.conf" kubeconfig file
# [kubeconfig] Writing "scheduler.conf" kubeconfig file
# [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
# [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
# [kubelet-start] Starting the kubelet
# [control-plane] Using manifest folder "/etc/kubernetes/manifests"
# [control-plane] Creating static Pod manifest for "kube-apiserver"
# [control-plane] Creating static Pod manifest for "kube-controller-manager"
# [control-plane] Creating static Pod manifest for "kube-scheduler"
# [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
# [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
# [apiclient] All control plane components are healthy after 8.506934 seconds
# [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
# [kubelet] Creating a ConfigMap "kubelet-config-1.20" in namespace kube-system with the configuration for the kubelets in the cluster
# [upload-certs] Skipping phase. Please see --upload-certs
# [mark-control-plane] Marking the node ip-x-x-x-x as control-plane by adding the labels "node-role.kubernetes.io/master=''" and "node-role.kubernetes.io/control-plane='' (deprecated)"
# [mark-control-plane] Marking the node ip-x-x-x-x as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
# [bootstrap-token] Using token: iexug3.l1dd4ka1szzuzpmr
# [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
# [bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
# [bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
# [bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
# [bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
# [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
# [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
# [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
#   sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
#   sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 
# Alternatively, if you are the root user, you can run:
# 
#   export KUBECONFIG=/etc/kubernetes/admin.conf
# 
# 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 x.x.x.x:6443 --token iexug3.l1dd4ka1szzuzpmr \
#     --discovery-token-ca-cert-hash sha256:xxxxx
# --- 実行結果例 ここまで -----------------------------------------------------------

# kubectlの設定ファイルをユーザ領域にコピー
mkdir $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

7. Podネットワークアドオンのインストール

Podネットワークアドオンとして、Flannelをインストールします。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network
https://kubernetes.io/ja/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network

# Flannelをインストール
sudo kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml
# --- 実行結果例 ここから -----------------------------------------------------------
# podsecuritypolicy.policy/psp.flannel.unprivileged created
# Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
# clusterrole.rbac.authorization.k8s.io/flannel created
# Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBinding
# 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が起動するまで少し待つ(数十秒~数分くらい)

# Podネットワークが動作していることを確認。CoreDNS PodがRunning状態であればOK
kubectl get pods --all-namespaces
# --- 実行結果例 ここから -----------------------------------------------------------
# NAMESPACE     NAME                                  READY   STATUS    RESTARTS   AGE
# kube-system   coredns-74ff55c5b-fnvg8               1/1     Running   0          3m48s
# kube-system   coredns-74ff55c5b-zw8nq               1/1     Running   0          3m48s
# kube-system   etcd-ip-x-x-x-x                      1/1     Running   0          4m1s
# kube-system   kube-apiserver-ip-x-x-x-x            1/1     Running   0          4m1s
# kube-system   kube-controller-manager-ip-x-x-x-x   1/1     Running   0          4m1s
# kube-system   kube-flannel-ds-amd64-wxln5           1/1     Running   0          45s
# kube-system   kube-proxy-qd5n2                      1/1     Running   0          3m48s
# kube-system   kube-scheduler-ip-x-x-x-x            1/1     Running   0          4m1s
# --- 実行結果例 ここまで -----------------------------------------------------------

8. コントロールプレーンノードの隔離

デフォルトでは、クラスタはコントロールプレーンノードにPodをスケジューリングしません。本手順では、1台のクラスタでPodをコントロールプレーンノードにスケジューリングしたいため、その設定を行います。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#control-plane-node-isolation

sudo kubectl taint nodes --all node-role.kubernetes.io/master-
# --- 実行結果例 ここから -----------------------------------------------------------
# node/ip-x-x-x-x untainted
# --- 実行結果例 ここまで -----------------------------------------------------------

# クラスタのノード一覧とIPアドレスを確認
kubectl get nodes
# --- 実行結果例 ここから -----------------------------------------------------------
# NAME          STATUS   ROLES                  AGE   VERSION
# ip-x-x-x-x   Ready    control-plane,master   43m   v1.20.1
# --- 実行結果例 ここまで -----------------------------------------------------------

# Service一覧とPortを確認
kubectl get services -A
# --- 実行結果例 ここから -----------------------------------------------------------
# NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
# default       kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  44m
# kube-system   kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   44m
# --- 実行結果例 ここまで -----------------------------------------------------------

# Pod一覧を確認
kubectl get pods --all-namespaces
# --- 実行結果例 ここから -----------------------------------------------------------
# NAMESPACE     NAME                                  READY   STATUS    RESTARTS   AGE
# kube-system   coredns-74ff55c5b-fnvg8               1/1     Running   0          44m
# kube-system   coredns-74ff55c5b-zw8nq               1/1     Running   0          44m
# kube-system   etcd-ip-x-x-x-x                      1/1     Running   0          44m
# kube-system   kube-apiserver-ip-x-x-x-x            1/1     Running   0          44m
# kube-system   kube-controller-manager-ip-x-x-x-x   1/1     Running   0          44m
# kube-system   kube-flannel-ds-amd64-wxln5           1/1     Running   0          41m
# kube-system   kube-proxy-qd5n2                      1/1     Running   0          44m
# kube-system   kube-scheduler-ip-x-x-x-x            1/1     Running   0          44m
# --- 実行結果例 ここまで -----------------------------------------------------------

9. Kubernetes Dashboard のデプロイ、アクセス(任意)

※本手順は任意です。Kubernetes Dashboardを利用しない場合はスキップしてください。

Kubernetes Dashboardのデプロイを行います。
https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/

# DashboardのYAMLを取得
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml

# 取得したファイルを編集(行頭に+がついている行を追加)し、外部からアクセス可能にする
vi recommended.yaml
# --- ファイル編集例 ここから -------------------------------------------------------
#   kind: Service
#   apiVersion: v1
#   metadata:
#     labels:
#       k8s-app: kubernetes-dashboard
#     name: kubernetes-dashboard
#     namespace: kubernetes-dashboard
#   spec:
# +   type: NodePort
#     ports:
#       - port: 443
#         targetPort: 8443
# +       nodePort: 30843
#     selector:
#       k8s-app: kubernetes-dashboard
# --- ファイル編集例 ここまで -------------------------------------------------------

# デプロイを実行
kubectl apply -f recommended.yaml
# --- 実行結果例 ここから -----------------------------------------------------------
# namespace/kubernetes-dashboard created
# serviceaccount/kubernetes-dashboard created
# service/kubernetes-dashboard created
# secret/kubernetes-dashboard-certs created
# secret/kubernetes-dashboard-csrf created
# secret/kubernetes-dashboard-key-holder created
# configmap/kubernetes-dashboard-settings created
# role.rbac.authorization.k8s.io/kubernetes-dashboard created
# clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
# rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
# clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
# deployment.apps/kubernetes-dashboard created
# service/dashboard-metrics-scraper created
# deployment.apps/dashboard-metrics-scraper created
# --- 実行結果例 ここまで -----------------------------------------------------------

# Serviceの一覧からkubernetes-dashboardのPort 30843を確認
kubectl get services -A
# --- 実行結果例 ここから -----------------------------------------------------------
# NAMESPACE              NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
# default                kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP                  47m
# kube-system            kube-dns                    ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   47m
# kubernetes-dashboard   dashboard-metrics-scraper   ClusterIP   10.108.221.215   <none>        8000/TCP                 37s
# kubernetes-dashboard          NodePort    10.104.134.142   <none>        443:30843/TCP            37s
# --- 実行結果例 ここまで -----------------------------------------------------------

# IPを確認
kubectl get nodes -o wide
# --- 実行結果例 ここから -----------------------------------------------------------
# NAME          STATUS   ROLES                  AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION   CONTAINER-RUNTIME
# ip-x-x-x-x   Ready    control-plane,master   48m   v1.20.1   x.x.x.x      <none>        Ubuntu 18.04.5 LTS   5.4.0-1029-aws   docker://19.3.11
# --- 実行結果例 ここまで -----------------------------------------------------------

# アカウントを作成
# https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
EOF
# --- 実行結果例 ここから -----------------------------------------------------------
# serviceaccount/admin-user created
# --- 実行結果例 ここまで -----------------------------------------------------------

# ClusterRoleBindingを作成
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
# --- 実行結果例 ここから -----------------------------------------------------------
# clusterrolebinding.rbac.authorization.k8s.io/admin-user created
# --- 実行結果例 ここまで -----------------------------------------------------------

# ログイン用トークンを取得
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
# --- 実行結果例 ここから -----------------------------------------------------------
# Name:         admin-user-token-pbcnr
# Namespace:    kubernetes-dashboard
# Labels:       <none>
# Annotations:  kubernetes.io/service-account.name: admin-user
#               kubernetes.io/service-account.uid: e29f699a-ea03-4084-8eec-75e116086d31
# 
# Type:  kubernetes.io/service-account-token
# 
# Data
# ====
# ca.crt:     1066 bytes
# namespace:  20 bytes
# token:      xxxxx
# --- 実行結果例 ここまで -----------------------------------------------------------

# ステータスを確認(Runningになるまで待ってから次の手順に進むこと)
kubectl get pods -n kubernetes-dashboard
# --- 実行結果例 ここから -----------------------------------------------------------
# NAME                                         READY   STATUS    RESTARTS   AGE
# dashboard-metrics-scraper-7b59f7d4df-jbskk   1/1     Running   0          3m21s
# kubernetes-dashboard-74d688b6bc-v5f8z        1/1     Running   0          3m21s
# --- 実行結果例 ここまで -----------------------------------------------------------
  • ブラウザからKubernetes Dashboardにアクセスします。
    https://<構築したマシンのIPアドレス>:30843/

Kubernetes Dashboard トークン入力画面
Kubernetes_Dashboard_input_token.png

  • 取得したトークンを入力して、「サインイン」をクリックします。

Kubernetes Dashboard トップページ
Kubernetes_Dashboard_top.png

おわりに

本稿では、MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する手順として、前提Kubernetesの構築までを紹介しました。次回は、残りの構築手順を紹介します。

第2回:MLOpsを実現するKubeflowを前提のKubernetesも含めて構築する(後編)

32
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
31