はじめに
OpenShift Advent Calendar 2022 20日目 の投稿です。
みなさん、こんにちは。レッドハットでOpenShiftのソリューションアーキテクトをしている小野です。主にエッジコンピューティングを担当しています。
以前の記事で、エッジデバイス向けの軽量版OpenShiftであるMicroShiftというオープンソースをご紹介しました。
Kubernetesでエッジデバイスのアプリケーションのライフサイクルを管理する場合、エッジデバイスが数台の内は直接kubectlで事足りますが、本番展開時に数万以上のエッジデバイスを対象にする必要が出てくると、効率化を考える必要が出てきますよね。そんな時は、Advanced Cluster Management for Kubernetes(以降、ACMと略)を使うと便利です。このACMが、正に「エッジへもクラウドネイティブなアプローチを拡張する」ために大事な役割を担います。
本稿では、エッジデバイスへインストールしたMicroShiftをAWS上に展開したACMから管理する簡単な手順をご紹介します。 なお、「そもそもACMとは?」という方は、以下の記事をご参照いただけますと幸いです。
それでは、始めていきましょう〜!
ACMをMicroShiftで使う場合の構成
まずはACMとMicroShiftとでどの様な構成になるのか見てみたいと思います。

この絵を見てみると、ACMがエッジのHubとなって、HelmやGit、ArgoCDなどの外部システムと連携したオペレーションをエッジへも適用する役割に見えます。
OpenShiftでACMを利用する場合は、ACMがAPIドリブンのOpenShiftクラスタのプロビジョニング機能(OpenShift Hive)と連携し、OpenShiftクラスタのインストールをACMから行うことも可能です。一方、MicroShiftでACMを利用する場合は、(少なくとも現時点は)エッジデバイスへプロビジョニング済みのMicroShiftをACMへインポートして利用します。
一番シンプルな使い方は、クラウドやオンプレミスの環境でセットアップしたHubクラスタ側でアプリケーションの配置ポリシ(Placement)を定義し、Hubクラスタ側で管理されるクラスタラベルに応じて、MicroShiftへのアプリケーションの配置をコントロールする使い方です。
構築に当たっては、そもそもMicroShiftやACMがインストールされた状態で、
①まずHubクラスタを作る
②次にMicroShiftをHubクラスタへ登録するための認証情報を取得する
③そして、MicroShiftへKlusterletとAddon Agentをデプロイし、取得した認証情報を使ってHubクラスタに登録する、
の3ステップで完了です。以下、構築を進めていきましょう。
事前準備
エッジデバイスへMicroShiftをインストール
まずは肝心のMicroShiftをエッジデバイスにインストールする方法を記載しておきます。MicroShiftのインストールは以下の公式ドキュメントを参照してください。 RHELへインストールする場合は、レッドハッとのパッケージリポジトリからdnfでインストールできます。
# CRI-Oのインストール
$ command -v subscription-manager &> /dev/null \
&& subscription-manager repos --enable rhocp-4.8-for-rhel-8-x86_64-rpms
$ sudo dnf install -y cri-o cri-tools
$ sudo systemctl enable crio --now
# MicroShiftのインストール
$ sudo dnf copr enable -y @redhat-et/microshift
$ sudo dnf install -y microshift
ちなみに、UbuntuなどのDebian系へインストールしたい場合は、以下の手順でインストールすることができます。 いずれもCRI-Oを入れて、MicroShiftバイナリを配置し、起動する、という流れです。
参考サイト. microshift-on-jetson.md · GitHub
# CRI-Oのインストール
$ echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
$ echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
$ curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add -
$ curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -
$ apt-get update
$ apt-get install cri-o cri-o-runc
# MicroShiftのインストール
$ export ARCH=arm64
$ export VERSION=$(curl -s https://api.github.com/repos/redhat-et/microshift/releases | grep tag_name | head -n 1 | cut -d '"' -f 4)
$ curl -LO https://github.com/redhat-et/microshift/releases/download/$VERSION/microshift-linux-${ARCH}
$ mv microshift-linux-${ARCH} /usr/local/bin/microshift; chmod 755 /usr/local/bin/microshift
## systemdで管理するようにする
$ cat << EOF > /usr/lib/systemd/system/microshift.service
[Unit]
Description=MicroShift
After=crio.service
[Service]
WorkingDirectory=/usr/local/bin/
ExecStart=/usr/local/bin/microshift run
Restart=always
User=root
[Install]
WantedBy=multi-user.target
EOF
$ systemctl enable crio --now
$ systemctl enable microshift.service --now
MicroShiftのバイナリをsystemdなりで起動すると、CRI-Oと連携してPodが起動してくる、という仕組みでインストールが走る感じですね。

最終的に以下のPodがRunningになれば正常にインストールできています。
$ oc get po -A NAMESPACE NAME READY STATUS kube-system console-deployment-57cdc94d5d-tsbzr 1/1 Running kube-system kube-flannel-ds-ch28c 1/1 Running kubevirt-hostpath-provisioner kubevirt-hostpath-provisioner-q75vd 1/1 Running openshift-dns dns-default-qjlfh 2/2 Running openshift-dns node-resolver-nq4jl 1/1 Running openshift-ingress router-default-6c96f6bc66-sv6wn 1/1 Running openshift-service-ca service-ca-7bffb6f6bf-r6z4n 1/1 Running
ACMをインストール
次に、OpenShiftがインストールされた環境にて、Operatorを用いてACMをインストールしておきます。
ACMのインストール自体は超簡単で、OperatorHubから「Advanced Cluster Management」を検索してインストールボタンを押す、たったこれだけです!(使いたいバージョンがある場合はインストールボタンを押した後の画面で適宜選択してください)

なお、本稿ではAWS上へOpenShift 4.11をインストールして構築しています。
ACMでMicroShiftを管理する
準備が整いましたので、ACMへMicroShiftを管理できる様にしてみます。
①Hubクラスタのセットアップ
インストール済みのOperatorのACMの画面を開き、「MultiClusterHub」インスタンスを作成します。ここでは、「インスタンスの作成」ボタンを押して、特に何も変更せず[作成]ボタンを押します。

すると、順次Podが起動し、OpenShiftのコンソール画面が更新されて、左メニューにクラスタ選択のメニューが追加されます。

②MicroShiftをHubクラスタに登録するための認証情報の取得
HubクラスタへManagedクラスタを登録するのに必要な認証情報を発行します。
登録したいクラスタの名前でProject(Namespace)を作り、ACMのカスタムリソースであるManagedClusterリソースとKlusterletAddonConfigリソースを作成します。
$ export CLUSTER_NAME=device01
$ oc new-project ${CLUSTER_NAME}
$ oc label namespace ${CLUSTER_NAME} cluster.open-cluster-management.io/managedCluster=${CLUSTER_NAME}
# ManagedClusterリソースを作成
$ cat <<EOF | oc apply -f -
apiVersion: cluster.open-cluster-management.io/v1
kind: ManagedCluster
metadata:
name: device01
spec:
hubAcceptsClient: true
EOF
# KlusterletAddonConfigを作成
$ cat <<EOF | oc apply -f -
apiVersion: agent.open-cluster-management.io/v1
kind: KlusterletAddonConfig
metadata:
name: device01
namespace: device01
spec:
clusterName: device01
clusterNamespace: device01
applicationManager:
enabled: true
certPolicyController:
enabled: false
clusterLabels:
cloud: auto-detect
vendor: auto-detect
iamPolicyController:
enabled: false
policyController:
enabled: false
searchCollector:
enabled: true
version: 2.5.0
EOF
マニフェストをapplysすると、Hubクラスタに以下の2つのカスタムリソースが作成されます。
$ oc get klusterletaddonconfig device01 NAME AGE device01 29s $ oc get managedcluster device01 NAME HUB ACCEPTED MANAGED CLUSTER URLS JOINED AVAILABLE AGE device01 true
また、MicroShift側でapplyする必要があるカスタムリソースとHubクラスタへ登録するための認証情報がSecretとして自動作成されますので、yamlファイルとして吐き出しておきます。
$ oc get secret ${CLUSTER_NAME}-import -n ${CLUSTER_NAME} -o jsonpath={.data.crds\\.yaml} | base64 --decode > klusterlet-crd.yaml
$ oc get secret ${CLUSTER_NAME}-import -n ${CLUSTER_NAME} -o jsonpath={.data.import\\.yaml} | base64 --decode > import.yaml
③MicroShiftの環境をHubクラスタへ登録
②で作成したklusterlet-crd.yamlとimport.yamlをMicroShift上でoc applyし、KlusterletとAddon AgentをMicroShift環境へデプロイします。
なお、オープンソースのMicroShift上にデプロイするにはレッドハットカスタマーポータルのアカウントが必要です。購入したサブスクリプションを管理するアカウントと同じものを利用するか、Red Hat Developerプログラムや、30日間の試用版サブスクリプションを使うなどして、開発者用のレッドハットのコンテナレジストリ(registry.redhat.io)へログインできるように準備しておく必要があります。
詳細は以下のリンクをご参照ください。
②で出力したマニフェストをMicroShift側でapplyします。
$ oc apply -f klusterlet-crd.yaml $ oc apply -f import.yaml
registry.redhat.ioへのImagePullSecretを指定します。
$ export RH_USERNAME=<レッドハットカスタマーポータルのアカウントのユーザ名>
$ export RH_PASSWORD=<レッドハットカスタマーポータルのアカウントのパスワード>
$ export EMAIL=<登録したメールアドレス>
$ oc project open-cluster-management-agent
$ oc create secret docker-registry open-cluster-management-image-pull-credentials \
--docker-server=registry.redhat.io \
--docker-username=${RH_USERNAME} \
--docker-password=${RH_PASSWORD} \
--docker-email=${EMAIL}
$ oc secrets link klusterlet open-cluster-management-image-pull-credentials --for=pull
$ oc secrets link klusterlet-registration-sa open-cluster-management-image-pull-credentials --for=pull
$ oc secrets link klusterlet-work-sa open-cluster-management-image-pull-credentials --for=pull
$ oc project open-cluster-management-agent-addon
$ oc create secret docker-registry open-cluster-management-image-pull-credentials \
--docker-server=registry.redhat.io \
--docker-username=$RH_USERNAME \
--docker-password=$RH_PASSWORD \
--docker-email=$EMAIL
$ oc secrets link cluster-proxy open-cluster-management-image-pull-credentials --for=pull
$ oc secrets link klusterlet-addon-search open-cluster-management-image-pull-credentials --for=pull
$ oc secrets link application-manager open-cluster-management-image-pull-credentials --for=pull
$ oc secrets link klusterlet-addon-workmgr open-cluster-management-image-pull-credentials --for=pull
MicroShift上に下記のPodが起動してきます。Runningとなるまで待ちましょう。
$ oc get po -A | grep open-cluster open-cluster-management-agent-addon application-manager-7488766d49-vs4f2 1/1 Running open-cluster-management-agent-addon cluster-proxy-proxy-agent-66dd8845b-ndzpw 2/2 Running open-cluster-management-agent-addon cluster-proxy-proxy-agent-66dd8845b-qm8ts 2/2 Running open-cluster-management-agent-addon klusterlet-addon-search-5bdfd9685-tc4br 1/1 Running open-cluster-management-agent-addon klusterlet-addon-workmgr-7c6b8679bd-vqbcc 1/1 Running open-cluster-management-agent klusterlet-54d4bfd556-zm7gr 1/1 Running open-cluster-management-agent klusterlet-registration-agent-557cb5bb4b-vtclx 1/1 Running open-cluster-management-agent klusterlet-work-agent-5598cdf789-lht8k 1/1 Running
MicroShift側でklusterlet-registration-agent PodがRunningとなると、Hubクラスタの方からManagedクラスタのStatusがReadyへ変わるはずです。

アドオンも全てAvailableになったら完了です。

HubクラスタからManagedクラスタへアプリをデプロイしてみる
HubクラスタでMicroShiftを管理できるようになったので、ACMを用いてアプリケーションをMicroShiftへデプロイしてみましょう。まずは、Hubクラスタ上で管理下のMicroShiftに任意のラベルを付与しておきます。
◎Hubクラスタ側
$ kubectl label managedcluster device01 device=device01
このラベルはHubクラスタでアプリケーションの配置ポリシを定義する際に、どのクラスタへアプリケーションを配置するか判断するために使用されます。同じラベルを複数のMicroShiftクラスタへ付与しておけば、同じアプリケーションをそのラベルが付与される複数のMicroShiftへ一斉にデプロイできます。
ラベルを付与したら、今度はHubクラスタでSubscriptionを作成してみます。以下に参考として、https://github.com/stolostron/application-samplesのnginxをデプロイするマニフェストを記載しておきます。
◎Hubクラスタ側
$ vi nginx-subscription.yaml
apiVersion: v1
kind: Namespace
metadata:
name: nginx-sample
---
apiVersion: app.k8s.io/v1beta1
kind: Application
metadata:
name: nginx-sample
namespace: nginx-sample
spec:
componentKinds:
- group: apps.open-cluster-management.io
kind: Subscription
descriptor: {}
selector:
matchExpressions:
- key: app
operator: In
values:
- nginx-sample
---
apiVersion: apps.open-cluster-management.io/v1
kind: Subscription
metadata:
annotations:
apps.open-cluster-management.io/git-branch: production
apps.open-cluster-management.io/git-path: nginx
apps.open-cluster-management.io/reconcile-option: merge
labels:
app: nginx-sample
name: nginx-sample-subscription-1
namespace: nginx-sample
spec:
channel: ggithubcom-stolostron-application-samples-ns/ggithubcom-stolostron-application-samples
placement:
placementRef:
kind: PlacementRule
name: nginx-sample-placement-1
---
apiVersion: apps.open-cluster-management.io/v1
kind: PlacementRule
metadata:
labels:
app: nginx-sample
name: nginx-sample-placement-1
namespace: nginx-sample
spec:
clusterSelector:
matchLabels:
'device': 'device01'
$ oc apply -f nginx-subscription.yaml
namespace/nginx-sample unchanged
application.app.k8s.io/nginx-sample created
subscription.apps.open-cluster-management.io/nginx-sample-subscription-1 created
placementrule.apps.open-cluster-management.io/nginx-sample-placement-1 created
MicroShift側を見てみると、Hubクラスタで指定したnginx-sample Namespaceにnginxが起動しているのがわかります。
◎MicroShift側
$ oc get po -n nginx-sample NAME READY STATUS RESTARTS AGE nginx-sample-7667b4ff65-6dg4r 1/1 Running 0 3m35s nginx-sample-7667b4ff65-rwlpx 1/1 Running 0 3m35s nginx-sample-7667b4ff65-zvbng 1/1 Running 0 3m35s
もちろん、Hubクラスタ側にはnginxは作成されていません。
◎Hubクラスタ側
$ oc get po -n nginx-sample No resources found in nginx-sample namespace.
ACMのGUIから、以下のようなトポロジービューでリソースの作成状況を確認することもできます。

まとめ
本稿では、Advanced Cluster Management for Kubernetseを使ってMicroShiftがインストールされたエッジデバイスへアプリケーションを展開する簡単な手順をご紹介しました。今回ご紹介した方法を基本として、例えばArgoCDとACMを連携させることでエッジデバイスに対してGitOpsでアプリケーションをリリースすることも可能になります。その辺りの話も近々したいと思います〜!
最後に...
Save the date!!! 27th Jan ==> "OpenShift.Run 2023"
年明けやります!OpenShift.Run! まだOpenShift User Groupに入ってない人はぜひご参加の程よろしくお願いします!
また、OpenShift.Runに至る道のり…ということで、「トレラン!エブリデイOpenShift」を開催中です。初心者の方から上級者の方まで「実際に手を動かしながら OpenShift を楽しんで頂く」会として、ご自身のスピード感でじっくりトレランできます。こちらも奮ってご参加くださいませ〜