OpenShiftでカスタムコントローラーのサンプルを動かす

Red HatでOpenShiftのサポートをしているid:nekopです。OpenShift 全部俺 Advent Calendar 2018 - Qiitaの14日目のエントリです。

OpenShiftで自動化をしたい、というときにカスタムコントローラーを作成するケースがあります。また、一歩進んでOperatorを作成したい、というような場合もカスタムコントローラーの知識が必要となります。KubernetesやOpenShiftはGo言語で記述されているので、カスタムコントローラーの作成もGo言語が第一候補になるでしょう。

The Go Programming Language

Go言語を使ったことがないという人も多いと思うので、クラスタ外で動作するカスタムコントローラーのサンプルを動かすところまでの手順をやってみましょう。Go 1.11, OpenShift 3.11 (Kubernetes 1.11)を利用します。

Go言語でKubernetesにアクセスするにはclient-goライブラリを利用します。バージョン対応表はclient-goのREADMEに記述されていますが、Kubernetes 1.11に対応するのはclient-go 8.0です。examplesにいくつかのコードがありますが、どのようにビルドして動かせばいいか、といった情報は書かれていないようです。

Go言語は公式サイトやOSのパッケージから取得しましょう。Fedora 29だとdnf install golanggolang-1.11.2-1.fc29.x86_6がインストールされます。Go言語ではGOPATHという環境変数に指定したディレクトリ内で作業することになります。デフォルトのGOPATH$HOME/goで、特に変更する理由もないのでそのまま利用しましょう。

export GOPATH=$HOME/go
mkdir -p $GOPATH/{bin,src}
export PATH=$GOPATH/bin:$PATH

Go言語でライブラリをインストールする方法は古いものからgo get, godep, glide, depとありますが、client-goを使う場合はまだdepには対応していないのでglideを利用することになります。

Glide | Package Management For Go

Fedora 29にはglide, depのパッケージも用意されていますが、両方ちょっと古いのでglide公式サイトからインストールする方法を利用します。確認した時点でのFedora 29のglideはglide up -vするとエラーになるバグが修正されていないバージョン0.13.1でした。

glideをインストールしましょう。以下のコマンドで$GOPATH/bin/glideがインストールされます。

curl https://glide.sh/get | sh

作業ディレクトリを作成してソースコードを配置し、glide initします。--non-interactiveオプションを付与しないと、最新バージョン固定利用するか、とかそういったことを聞いてくるウィザードが起動できますが、今回は最新バージョンを利用しないので--non-interactiveオプションを付与します。

mkdir -p $GOPATH/src/podlist-example-controller
cd $GOPATH/src/podlist-example-controller
curl -O https://raw.githubusercontent.com/kubernetes/client-go/v8.0.0/examples/out-of-cluster-client-configuration/main.go
glide init --non-interactive

ちなみにGoはライブラリを基本的にGitHubから取得するので、公開するライブラリなどのソースディレクトリはsrc/podlist-example-controllerというsrc直下ではなくsrc/github.com/nekop/podlist-example-controllerというようなGitHubのリポジトリ指定形式にします。k8s.io/client-goみたいなGitHubになっていないように見える名前の変更のカラクリにはcurl -v https://k8s.io/client-go?go-get=1というHTTPのレスポンスが利用されてます。

さて、これでmain.goglide.yamlができました。次にglide.yamlに利用バージョンを記述します。以下のようにversion行をそれぞれに追記します。今回はカジュアル用途なので、再現性を重視した固定のバージョンタグではなく、最新の修正も取り込めるブランチを指定しています。

package: podlist-example-controller
import:
- package: k8s.io/apimachinery
  version: release-1.11
  subpackages:
  - pkg/api/errors
  - pkg/apis/meta/v1
- package: k8s.io/client-go
  version: release-9.0
  subpackages:
  - kubernetes
  - tools/clientcmd

ライブラリのアップデート(初回なのでインストール)を行います。-vオプションは各ライブラリが利用するライブラリを厳格な個別管理ではなくフラットに管理するオプションです。厳格なほうはglogライブラリが問題になったりライブラリが超大量に取得されたりするので一般的にあまり利用されていません。

glide up -v

glide.lockという現状のライブラリのバージョンが記述されたファイルと、ライブラリが格納されるvendorディレクトリが生成されます。

ビルドの準備ができたのでビルドします。

go build

podlist-example-controllerというバイナリができました。次はこのサンプル動かしますが、このサンプルはクラスタの全てのpodのlistを行うのでcluster-reader権限のサービスアカウントを用意します。ここでは例としてdefaultプロジェクトのdefaultサービスアカウントを利用しますが、もちろんoc sa createしても構いません。ちなみにdefaultサービスアカウントはpodにサービスアカウントが指定されていないときに利用される、デフォルトでは何も権限を持たないサービスアカウントです。

oc adm policy add-cluster-role-to-user cluster-reader -z default -n default
oc sa create-kubeconfig default -n default > default.kubeconfig

これでpodlist-example-controllerの準備は完了です。動かしてみましょう。

$ ./podlist-example-controller -kubeconfig default.kubeconfig
There are 37 pods in the cluster
Pod example-xxxxx in namespace default not found

pod数とexample-xxxxxというメッセージが10秒ごとにリピートします。

使い終わったら付与した権限は戻しておきましょう。

oc adm policy remove-cluster-role-from-user cluster-reader -z default -n default

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。