Kubernetes* 上でコンテナアプリケーションを実行するためにはまずクラスターと呼ばれるものを構築する必要があります。(参考)
今回と次回の記事を通じて、Terasic社製のDE10-Nanoを用いてKubernetesのディストビューションの1つであるK3s*を用いてFPGAクラスターを構築して最後にFPGAのアップデートを試してみます。
注意事項: 本記事では、あくまでクラスター構築に必要な部分のみしか解説しないため、細かい用語等には触れません。
KubernetesとAzure IoT Edge*はコンテナベースの開発という観点のみに着目すると非常に親和性が高いため、
Intel®︎ Developer Zone(IDZ)に公開されているドキュメント(英語版), (日本語(ページ内中央左にあるチュートリアル・モジュール1-4))をよく引用しますので、合わせて読むことを推奨します。
クラスター構成
著者環境
- Host OS : MacOS Catalina 10.15.7
- Guest OS(Server Node) : Ubuntu 18.04.5
- DE10-Nanos' OS(Agent Node) : Ubuntu 16.04.6
- K3s version : v1.20.4+k3s1 (838a906a)
クラスター全体図はこのようになっています。Host OSの環境をならべく汚さないようにする+様々なOSから利用できるようにするため、Server Node(Kubernetesでは一般的にMaster Nodeとも言います)はVMを立ててその中に構築しました。
Server Nodeとして利用するVMのOSとしては、Ubuntu18.04を利用していますが、K3s自体にはOS Dependencyがないそうなので、どのOSを使っても問題ありません。
Host OS側には、Server Nodeにアクセスするためのクライアントとしてkubectl
のみをインストールします。
Agent Node(Kubernetesでは一般的にWorker Nodeとも言います)には今回はTerasic社製のDE10-Nanoを利用します。
OSイメージとしては、同社が公開しているコンテナがすでに使える状態になっている、DE10-Nano-Cloud_native.img
を使います。
コンテナのイメージ格納庫としてAmazon ECR*(Amazon Elastic Container Registry)というAWS(Amazon Web Service)のサービスを利用しました。
開発用に使うには、こういったクラウドのサービスを活用してプライベートレポジトリを作成するのが最も簡単なので、私はよく利用しています。
Microsoft AzureやGCP(Google Cloud Platform)にも同様なサービスがあるので、こちらを利用するのもよいでしょう。
Note: 今後コマンドを実行する際は、どこから実行したかをわかりやすくするため前に(devPC=Client),(Guest=Server Node=VM),(de10nano=Agent Node)の三種類を付属します。
本記事はdevPC/Guestに焦点を当てています。de10nano側の構築に関しては、後編をご覧ください。
今回の記事は前準備の内容が多いため、FPGAの話はあまり出てきませんのでご承知ください。
Server Node準備(Development PC)
お使いのPCが普段からLinuxかつIPアドレスをstaticで運用している場合は特にこのステップは不要です。
それ以外の場合は下記3つの手順を必要に応じてカスタムしながら行ってください。
- VirtualBoxのインストール
- Ubuntu18.04のインストール
- VMの設定変更(VirtualBoxの設定 / IPアドレスの固定 / Hostnameの変更(Optional))
私はMacを開発用PCとして普段から利用していますので、その際の手順を説明します。
Macの場合、multipassなども考えられますが、multipassは外部からVMに直接アクセスできないなどNetwork Bridgeの周りが不調の場合も多いため、今回はVirtualBoxを利用しています。
VirtualBoxのインストール
Oracle VM VirtualBox Official Siteにアクセスしお好きなバージョンをダウンロード・インストールします。
インストール後にVirtualBoxを起動し、新規を押した時に、任意のLinux64bitsOSが指定できれば完了です。
Windowsの場合、Securityの設定などで64bitsが指定できない場合があります。その時はOSやBIOSの設定を見直してください。
Ubuntu18.04のインストール
Ubuntu 18.04 Release PageからUbuntu18.04のISOをダウンロードしてインストールします。Server, Desktopどちらでも構いません。私はServerを使いました。
新規作成時に設定のカスタマイズは必要ありませんが、もしPCに余裕があるのであればメモリは少し増やしておくとよいかもしれません。Diskは可変長にしておくことをお勧めします。
ユーザー名やパスワードについてもお好きなものを利用できます。
ISOを抜いてUbuntuが起動/設定したユーザーでログインできれば完了です。
VMの設定変更(VirtualBoxの設定 / IPアドレスの固定 / Hostnameの変更(Optional))
-
VirtualBoxの設定
一度起動したら一度VMを落とします。落としたら該当のVM設定を開きます。ネットワークのカテゴリに行き、割り当てをブリッジアダプターに変更します。(デフォルトはNAT)
名前は使っているホストのアダプタの名前を指定します。(特に問題なければデフォルト)
変更を保存したら、VMを起動し、ネットワークに接続されるか再確認します。
-
IPアドレスの固定
接続されるのが確認できたら次は、IPアドレスの固定を行います。
この作業をしないと、VMを再起動するたびServer NodeのIPアドレスが変わる可能性があり、Agentと通信できなくなるのを防ぐためです。
先にも述べたように、設定内容に関しては、基本的にはルータの設定に依存します。ルータ側にも利用するIPをDHCPから外さない場合、ネットワーク環境に影響が出る可能性があります。
(Guest)$ ip addr
ファイルの設定はUbuntu18.04 Desktopであれば設定のGUI上から行えますし、Serverの場合には、netplanというサービスを利用します。例えば下記です。
(Guest)$ sudo vi /etc/netplan/50-cloud-init.yaml #Edit (Guest)$ cat /etc/netplan/50-cloud-init.yaml #Check # This file is generated from information provided by # the datasource. Changes to it will not persist across an instance. # To disable cloud-init's network configuration capabilities, write a file # /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following: # network: {config: disabled} network: ethernets: enp0s3: addresses: [192.168.100.100/24] gateway4: 192.168.100.1 nameservers: addresses: [192.168.100.1] search: [] optional: true #dhcp4: true version: 2 (Guest)$ sudo netplan apply #Enable the new setting
-
(Optional) Hostnameの変更
Hostnameの変更はk3s導入時にNode名を被らないようにするためです。
/etc/hosts
と/etc/hostname
を編集して、VMを再起動します。Note: 現在はAgent側の構築時にNode名を自由に指定できるオプションが追加されているため、必ずしも行う必要はありません。
例では、k3sserverとしました。
(Guest)$ sudo vi /etc/hostname #Edit (Guest)$ sudo vi /etc/hosts #Edit (Guest)$ cat /etc/hostname #Check k3sserver (Guest)$ cat /etc/hosts #Check 127.0.0.1 localhost 127.0.1.1 k3sserver
開発環境準備
今回はFPGAノードへのコンテナのビルドおよびデプロイを試すので、それらに必要なツールを準備します。
Docker Buildxのインストール
DE10-Nanoに乗っているCPUのアーキテクチャはArm32v7のため、PCでコンテナビルドをするためには、Dockerのクロスビルド機能、Docker Buildxが必要です。Dockerを通常通りインストールしたのち、公式ガイドに従って、インストールします。
Docker BuildxはMacおよびLinuxが前提ですが、Windowsでも。WSL2をDocker Backendとして使うとできるそうです。(筆者はWindows環境がないため未検証) Linux環境の資料とはなってしまいますが、英語版, 日本語版にも同様の手順が書いてあるのでよろしければどうぞ。
Container Registryの準備
先にも述べたように、今回はコンテナイメージの格納庫(Container Registry)として、Amazon ECR*(Amazon Elastic Container Registry)を利用します。Microsoft AzureやGCP,その他オンプレミスなどのサービスを利用する方はそれぞれのやり方に従ってください。
本節では、コンテナレジストリを作成するところまでですが、後のKubernetesのsecretを作成するところでも手順が異なる可能性がありますので、適宜検索してください。
また、本節は特に覚書的な要素が強いため、より詳しい内容が知りたい方は他の記事等も同時に参考にすることを推奨します。
さて、1からECRを構築するためには、管理者(Root User)からの観点とIAMユーザーからの観点の2つが必要です。
AWSでは、実際に何かを行う際は、IAM(Identity and Access Management)ユーザーを使うことを推奨していますので、その流儀にのっとります。
AWSの記事およびこちらのQiitaの記事はとても参考になりました。
やり方は、2021/7月時点のものであり、変更になっている可能性もあります。
管理者向け手順
前提として、すでにAWSには登録し利用するリージョンも決まっている状態でスタートします。
-
アクセス用のIAMユーザの作成
ECRに対してアクセスするIAMユーザーを作成します。既存のユーザーを使い回す場合はこの手順は不要です。
AWSにログイン後、IAM Serviceにアクセス(上部のsearchboxでECRで検索など)->Add User
->Programmatic access
にチェック、AWS Management Console
(Optional)でチェックします。
Permission等は後からでも登録できるため、今は特に何も設定せずスキップします。
作成後、Userのページにいき、User ARN
(arn:aws:iam:XXXXXXXXXX)をコピーしておきます。 -
レポジトリの作成
アカウントが作成できたら、ECRのページへアクセス(上部のsearchboxでECRで検索など)->Create repository
->Visibility settings
をPrivate
->お好みの名前をつけます。
その他の設定は必要に応じて設定してください。私は初期設定のまま行っています。 -
レポジトリのPermissionの変更
リストからレポジトリをクリックした後、左のサイドバーの中にあるPermissions
を選択します。
右上の
Edit policy JSON
を選択し、下記のJSONをコピペ後、Statement:Principal:AWSの下のARNを先ほどのARNに変更します。{ "Version": "2008-10-17", "Statement": [ { "Sid": "Test", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::XXXXXXX" ] }, "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr:CompleteLayerUpload", "ecr:DescribeImages", "ecr:DescribeRepositories", "ecr:GetDownloadUrlForLayer", "ecr:InitiateLayerUpload", "ecr:PutImage", "ecr:UploadLayerPart" ] } ] }
公式のガイドの
DescribeRepositories
やDescribeImages
を除いた7つでも実行自体はできますが、これらの権限がないと、Web Browserからは確認できなかったので、つけておくことをお勧めします。
問題なく解釈できれば、statementが追加されます。
User向け
-
IAMユーザ/レポジトリ情報の共有(Access Keys)
情報をもらいます。以下の情報が必要です。- IAM Username(Optional): Web Browser等でログインする時に必要
- IAM Password(Optional): Web Browser等でログインする時に必要
- AWS Access Key ID
- AWS Secret Access Key
- ECR Repository URL
-
AWS CLIのインストール
AWSの公式サイトからダウンロードしたり、お好みのパッケージマネージャーを使ってインストールしてください。
Macであれば次のコマンド。(devPC) $ brew install awscli
-
Credentialの確保 / Docker Loginテスト
(devPC) $ aws configure AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name [None]: Default output format [None]: json
の順番に表示されるので、適宜
0. IAMユーザ/レポジトリ情報の共有(Access Keys)
で共有された情報に従って登録してください。
もし、すでにアカウントを持っている人は、次に従って適宜プロファイルを編集してください。登録できれば、次のコマンドで、レジストリのログインに必要なCredentialを取得できます。
(devPC) $ aws ecr get-login-password eyJwYXl...(omit)
Note: このCredentialは12時間のみ有効になっているようなので、適宜アップデートが必要なようです。
試しにコンテナレジストリにビルド済みのイメージをPushするやり方について記述します。
イメージのビルドに関しては、後述のビルドイメージ作成というセクションで説明します。(devPC) $ aws ecr get-login-password | docker login --username AWS --password-stdin <AWS account ID>.dkr.ecr.<region>.amazonaws.com Login Succeeded (devPC) $ docker tag <original> <AWS account ID>.dkr.ecr.<region>.amazonaws.com/<repository name>:<tag> #e.g. $ docker tag 058 309190452075.dkr.ecr.us-east-2.amazonaws.com/kubernetes-demo-image:testv0 (devPC) $ docker push <AWS account ID>.dkr.ecr.<region>.amazonaws.com/kubernetes-demo-image:testv0 (devPC) $ aws ecr describe-images --repository-name <repository name> #e.g. $ aws ecr describe-images --repository-name kubernetes-demo-image imageDetails: - artifactMediaType: application/vnd.docker.container.image.v1+json imageDigest: sha256:343e914b63d7c717396c3c75427f4badc64fa23fa64234cc5254dea87c4aa662 imageManifestMediaType: application/vnd.docker.distribution.manifest.v2+json imagePushedAt: '2021-03-31T14:14:27+09:00' imageSizeInBytes: 40383911 imageTags: - testv0 registryId: '309190452075' repositoryName: kubernetes-demo-image
K3sインストール(Server Node)
今回は公式インストールに従って行いますが、k3supというユーティリティーツール現在ではリリースされています。こちらを用いるのもよいでしょう。
前編ではk3s serverをServer NodeとなるGuest(VM)にインストールします。後編ではAgent Nodeを準備します。
この部分は基本的にK3sの公式インストールに従います。
下記のコマンドを打ち込むと最新バージョンのK3sがインストールされます。また、自動的に、k3s-serverが実行されるためこれで十分です。
(Guest) $ curl -sfL https://get.k3s.io | sh -
念のため状態を確認します。
(Guest) $ sudo systemctl status k3s.service
● k3s.service - Lightweight Kubernetes
Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2021-03-31 14:48:35 JST; 6min ago
Docs: https://k3s.io
Process: 918 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Process: 906 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS)
Main PID: 931 (k3s-server)
Tasks: 31
CGroup: /system.slice/k3s.service
├─ 931 /usr/local/bin/k3s server
└─1252 containerd
(Guest) $ sudo k3s kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3sserver Ready control-plane,master 5m v1.20.4+k3s1
クライアントのkubectl設定
ここまでで、Server NodeからはKubernetesのコントロールプレーンにアクセスできるようになりました。しかしながら毎回GUIを立ち上げたり、SSHなどでログインするのは面倒です。
そこで、Contextをコピーすることでdevelopment PCから直接コントロールプレーンへとアクセスできるようにします。
まずは、公式ガイドを参考にでkubectlをインストールします。
Macであれば、下記のコマンド。
(devPC) $ brew install kubectl
続いて、VM内で参照しているContextファイルをコピーします。ファイルは/etc/rancher/k3s/k3s.yaml
です。このファイルはrootユーザしか参照権限がないので、注意しましょう。
(Guest) $ sudo cp /etc/rancher/k3s/k3s.yaml $HOME
(Guest) $ sudo chmod 644 $HOME/k3s.yaml
(devPC) $ scp (VM):$HOME/k3s.yaml ~/.kube/
コピ-してきたファイルのclusters:cluster:server
(おそらく5行目)はローカルホスト(127.0.0.1)を参照するようになっているので、ここは、先のK3S_URL
と同様に、Server NodeのIPアドレス+ポート番号に変更します。
Before : server : https://127.0.0.1:6443
After : server : https://192.168.100.100:6443
kubectlが参照するファイルは、$HOME/.kube/config
です。そのまま上書きしてしまうと、別のコンテキスト情報が消えてしまうので、次のようにすることで回避します。
(devPC) $ mv $HOME/.kube/config $HOME/.kube/config-backup #Backup
(devPC) $ KUBECONFIG=$HOME/.kube/config-backup:$HOME/.kube/k3s.yaml kubectl config view --flatten > $HOME/.kube/config
(devPC) $ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
default default default
* minikube minikube minikube default
(devPC) $ kubectl config use-context default #Switch default context
(devPC) $ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3sserver Ready control-plane,master 47m v1.20.4+k3s1
これで、development PCからコントロールプレーンにアクセスできるようになりました。
ECRの認証情報登録
認証情報なしにKubernetesのクラスターはプライベートレポジトリにアクセスできません。
そのため、認証情報をSecretとして登録しておくことで、ECR内にアップロードされたコンテナイメージをPullできるようになります。
今回は使いませんがテストもかねてここで登録してしまいましょう。
#Get username and password from AWS CLI
AWS_PASSWORD=`aws ecr get-login-password`
(devPC) $ kubectl create secret docker-registry aws \
--docker-server=<AWS account ID>.dkr.ecr.<region>.amazonaws.com \
--docker-username=AWS \
--docker-password=$AWS_PASSWORD \
--docker-email=<your-email>
#kubectl get secrets aws -o yaml #Check
これで前準備となるServer Nodeの準備およびクライアントの準備が終了しました。
後編に続く
References
- Kubernetesのコンポーネント
- Build, Deploy, and Manage your FPGA-Based IoT Edge Applications using Microsoft* Azure
- インテルのエッジセントリック FPGA ソリューション
- Amazon ECR | Docker Container Registry | Amazon Web Services
- Oracle VM VirtualBox
- Ubuntu 18.04 Release
- Docker Buildx | Docker Documentation
- Docker Desktop WSL 2 backend | Docker Documentation
- Build an Azure* Container-based Application using Visual Studio Code
- FPGA クラウド・コネクティビティー・キット・チュートリアル・モジュール 2
- Amazon ECR イメージリポジトリ内のイメージをプッシュまたはプルするためのセカンダリアカウントを許可するにはどうすればよいですか?
- Amazon ECR に特定 IAM ユーザからのみのアクセスを許可
- IAM dashboard
- AWS Command Line Interface
- AWS Named profiles
- alexellis/k3sup: bootstrap Kubernetes with k3s over SSH
- Rancher Docs: Installation
- Install and Set UP kubectl
Notices & Disclaimers
No product or component can be absolutely secure.
Your costs and results may vary.
Copies of documents which have an order number and are referenced in this document may be obtained by calling 1-800-548-4725 or visiting http://www.intel.com/design/literature.htm.
Intel disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade.
No license (express or implied, by estoppel or otherwise) to any intellectual property rights is granted by this document.
© Intel Corporation. Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries. Other names and brands may be claimed as the property of others.