構築MLOps所需的Kubeflow和基于Kubernetes设定(第一部分)

发布日期:2021年4月9日
作者:高久隆史,日立制作株式会社

首先

Kubeflow是一个在Kubernetes平台上实现MLOps的开源工具包。它于2020年3月发布了1.0版本,截至2021年4月仍在积极进行开发,并被广泛视为推动利用机器学习进行系统开发和运营的有效手段之一。

在本系列中,我們將介紹關於Kubeflow 1.2版本(於連載開始時為最新版本,於2020年11月發布)的構建步驟,Kubeflow Pipelines以及KFServing的基本使用方法。

在第1回的本文中,将介绍如何在Amazon Web Services(以下简称AWS)的EC2上,从仅安装操作系统的环境开始,构建包括Kubeflow和Kubernetes在内的环境。
本文介绍的构建步骤不仅适用于在AWS EC2上构建,也可用于在本地环境中构建,希望对您有所帮助。

由于构建过程较长,因此只会在中途记录,并在第二次发布中提供续篇内容。

投稿一覽:
1. 構建包含Kubernetes的Kubeflow框架实现MLOps(前篇)(本投稿)
2. 構建包含Kubernetes的Kubeflow框架实现MLOps(後篇)
3. 使用Kubeflow Pipelines訓練和評估scikit-learn的機器學習模型
4. 使用Kubeflow KFServing公開基於scikit-learn預訓練模型的推論服務

Kubeflow的构建模式和最低规格。

Kubeflow 可以在本地或公共云上进行构建。下面是官方网站中列出的构建模式。

Kubeflow的构建模式

#分類OSKubernetes構築手順のURL1任意のKubernetesクラスタにKubeflowをデプロイ-任意http://www.kubeflow.org/docs/started/k8s/2ワークステーションにシングルノードKubernetesクラスタを構築してKubeflowをデプロイLinuxMicroK8shttps://www.kubeflow.org/docs/started/workstation/getting-started-linux/3MiniKF4Minikube5Multipass6WindowsMicroK8shttps://www.kubeflow.org/docs/started/workstation/getting-started-windows/7MiniKF8Multipass9macOSMicroK8shttps://www.kubeflow.org/docs/started/workstation/getting-started-macos/10MiniKF11Multipass12パブリッククラウドのKubernetes環境にKubeflowをデプロイ-AWS EKShttps://www.kubeflow.org/docs/aws/deploy/13-Microsoft Azure AKShttps://www.kubeflow.org/docs/azure/deploy/14-Google Cloud Platform GKEhttps://www.kubeflow.org/docs/gke/deploy/15-IBM IKShttps://www.kubeflow.org/docs/ibm/deploy/16パブリッククラウドのKubernetes環境にKubeflowをデプロイ-OpenShifthttps://www.kubeflow.org/docs/openshift/

以下是在Kubeflow官方网站上确认的构建Kubeflow所需的最低规格。

用于构建Kubeflow的最低规格要求

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

在构建过程中需要注意的事项。

如果在搭建Kubeflow时出现问题,即使在网站上进行了搜索也找不到原因,可能会遇到困难。以下是在进行Kubeflow环境搭建时需要注意的事项,请参考。

在进行Kubeflow环境搭建时需要注意的事项。

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

构建的前提信息

本篇将记录在仅安装操作系统的环境中,新建Kubernetes和Kubeflow环境的步骤。
具体而言,Kubernetes作为Kubeflow的前提,将使用kubeadm进行构建,并在此基础上部署Kubeflow。每个步骤都将按照以下官方网站提供的指南进行构建。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
http://www.kubeflow.org/docs/started/k8s/

以下是该手稿的构建步骤,不仅局限于特定的公有云,也可以在本地构建,但是根据操作系统类型、Kubeflow版本以及其他初始配置的不同可能会有不同的步骤,请注意。

下面列出了本书中使用的机器环境信息以及安装的软件及其版本信息。

使用了哪台机器的环境信息进行了此构建步骤?

#項目内容1マシン概要AWS EC2 (1インスタンス)2インスタンスタイプt3a.2xlarge3VCPU44RAM32GiB5ストレージ192GB6OSUbuntu 18.04 LTS – Bionic7ポートSSH(22)、および、以下のkubeadmが利用するポートは解放しておく。
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#check-required-ports

本段描述经过此构建步骤所安装的软件及其版本信息。

#ソフトウェアバージョン補足1Docker CE19.03.11kubeadm前提のコンテナランタイムとして選択。2Kubernetes1.20.1Kubeflow前提のKubernetesとして選択。3
kubeadm1.20.1-00 amd644kubectl1.20.1-00 amd645kubelet1.20.1-00 amd646Flannelv0.11.0kubeadm前提のPodネットワークアドオンとして選択。7Kubernetes Dashboardv2.0.0必須ではないが、状態確認用途として構築。8Local-path-provisionerv0.0.19Kubeflow前提のDynamic Volume Provisionerとして選択。9Kubeflow1.2.0
10
kfctlv1.2.0-0-gbc038f9

建造过程

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

構築の流れ

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

建立程序

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

使用SSH登录

使用SSH登录到要构建的机器。

2. 禁用交换功能

在安装kubeadm之前,需要禁用Swap,因此我们要禁用Swap。

# 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仪表盘的部署。
https://kubernetes.io/zh/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_input_token.png
    取得したトークンを入力して、「サインイン」をクリックします。
Kubernetes_Dashboard_top.png

最後

下一次我们将介绍剩余的构建步骤,本文已经介绍了基于Kubernetes构建包括Kubeflow在内的MLOps的步骤。

第二篇:构建实现MLOps的Kubeflow并包含Kubernetes的前提条件(下篇)

广告
将在 10 秒后关闭
bannerAds