今回はCentOS8にSkaffoldをインストールして、kubernetesクラスタへデプロイしたいと思います。
はじめに
SkaffoldとはGoogleが提供するkubernetesネイティブなアプリ開発をするための支援ツールです。
Skaffoldは、Kubernetesネイティブアプリケーションの継続的な開発を促進するコマンドラインツールです。Skaffoldはアプリケーションのビルド、プッシュ、デプロイのワークフローを処理し、CI/CDパイプラインを作成するためのビルディングブロックを提供します。これにより、Skaffold がローカルまたはリモートの Kubernetes クラスタに継続的にデプロイしている間、ローカルでのアプリケーションのイテレーションに集中することができます。
https://skaffold.dev/docs/
おもにCDがメインとなりますが、既存のJenkinsパイプライン等に簡単に組み込むことができ、
Dockerイメージのビルド・プッシュ・デプロイまでを自動でやってくれるので、
手動でDockerイメージを扱っている人にとっては開発効率が上がるのではないかと思います。
今回は実用性を考慮して、Skaffoldはコンテナ化して自身が動いているDocker基盤へデプロイさせてみます。(Docker in Docker)
kubernetes基盤は準備されていることを前提とします。
自分で構築して用意したい場合はこちら
コンテナの準備
ベースコンテナですが今回はDocker公式のDockerイメージ(https://hub.docker.com/_/docker)を使用します。
ただしエンジンはkubernetes基盤のDockerサーバを使用するため、コンテナデプロイ時にソケット部分をマウントさせます。
# docker run -t -i -d -v /var/run/docker.sock:/var/run/docker.sock --name skaffold --privileged docker /sbin/init # docker exec -it skaffold sh
コンテナにログインしたら、Skaffoldをインストールします。
※Dockerイメージはcurlがないためwgetで対応
cd ~ && wget https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 chmod +x skaffold-linux-amd64 && mv skaffold-linux-amd64 /usr/local/bin/skaffold
次にデプロイで使用するkubectlをインストールします。
wget https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl chmod +x ./kubectl && mv ./kubectl /usr/local/bin/kubectl
この段階でkubectlを実行してもリクエスト先が定義されていないためエラーになります。
# kubectl version error: Missing or incomplete configuration info. Please point to an existing, complete config file: 1. Via the command-line flag --kubeconfig 2. Via the KUBECONFIG environment variable 3. In your home directory as ~/.kube/config To view or setup config directly use the 'config' command.
なので、クラスタのワーカーノードを参考に「~/.kube/config」を用意します。
コンテナに同じものを用意するとkubectlが使えるようになります。
# kubectl version Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.0", GitCommit:"9e991415386e4cf155a24b1da15becaa390438d8", GitTreeState:"clean", BuildDate:"2020-03-25T14:58:59Z", GoVersion:"go1.13.8", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.1", GitCommit:"7879fc12a63337efff607952a323df90cdc7a335", GitTreeState:"clean", BuildDate:"2020-04-08T17:30:47Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
これでSkaffoldの導入は完了です。かなり簡単ですね。
サンプルアプリとskaffold.yamlの準備
Skaffold環境はできたので、CD対象となるアプリとSkaffoldに渡すための設定ファイル(skaffold.yaml)を準備します。
今回はSkaffoldが更改しているサンプルアプリ(https://github.com/GoogleContainerTools/skaffold/tree/master/examples)を使いたいと思います。
まずはGithubからソース群を持ってきますが、コンテナにはgitが入っていないためここも例のごとくwgetで対応します。
wgetでGithubのソースを取得するには
https://github.com/<対象リポジトリ>/archive/master.tar.gz
を渡してやれば、tar.gzとして取得できます。便利ですね(?)
今回は数あるサンプルアプリの中の「getting-started」を使ってみます。
# wget --no-check-certificate https://github.com/GoogleContainerTools/skaffold/archive/master.tar.gz # tar xvzf master.tar.gz # cd skaffold-master/examples/getting-started
getting-startedにはすでにskaffold.yamlが用意されています。見てみましょう。
# cat skaffold.yaml apiVersion: skaffold/v2beta5 kind: Config build: artifacts: - image: skaffold-example deploy: kubectl: manifests: - k8s-*
skaffold.yamlの詳しい書き方については公式のリファレンスがわかりやすいです。
skaffold.dev
このまま使ってしまうとイメージリポジトリにpushしてしまうので、
以下のように編集します。
# cat skaffold.yaml apiVersion: skaffold/v2beta5 kind: Config build: artifacts: - image: skaffold-example + local: + push: false deploy: kubectl: manifests: - k8s-*
これで準備完了です。
試しにskaffoldをdevモードで実行してみます。
# skaffold dev Listing files to watch... - skaffold-example Generating tags... - skaffold-example -> skaffold-example:latest Some taggers failed. Rerun with -vdebug for errors. Checking cache... - skaffold-example: Not found. Building Building [skaffold-example]... Sending build context to Docker daemon 3.072kB Step 1/7 : FROM golang:1.12.9-alpine3.10 as builder ---> e0d646523991 Step 2/7 : COPY main.go . ---> Using cache ---> 0f3f059bc721 Step 3/7 : RUN go build -o /app main.go ---> Using cache ---> b256814f4725 Step 4/7 : FROM alpine:3.10 ---> be4e4bea2c2e Step 5/7 : ENV GOTRACEBACK=single ---> Using cache ---> 3d29777a8f71 Step 6/7 : CMD ["./app"] ---> Using cache ---> cb8cfda7b7ce Step 7/7 : COPY --from=builder /app . ---> Using cache ---> 976ee01c0630 Successfully built 976ee01c0630 Successfully tagged skaffold-example:latest Tags used in deployment: - skaffold-example -> skaffold-example:976ee01c06301b46d7aa1910eeb0add9e3db71abdf5f842ce74bacce87e5fd09 Starting deploy... - pod/getting-started created Waiting for deployments to stabilize... Deployments stabilized in 295.699066ms Press Ctrl+C to exit Watching for changes... [getting-started] Hello world! [getting-started] Hello world! [getting-started] Hello world! [getting-started] Hello world! [getting-started] Hello world! ^CCleaning up... - pod "getting-started" deleted Help improve Skaffold! Take a 10-second anonymous survey by running skaffold survey
うまくいきました!
出力内容を見てみると、docker buildした後にk8s-pod.yamlをkubectlでデプロイしているのがわかります。
デプロイ後はサンプルアプリが起動して「[getting-started] Hello world!」と正常に表示されています。
なおdevモードとrunモードではskaffoldの処理方式が少し違うので詳しくはマニュアルを参照ください。
このように、Skaffoldを使えばGithubにあるソースを自動でビルド・プッシュ(今回は省略)・デプロイすることができます。
ちなみにプッシュ先にはパブリック/プライベート両方のリポジトリを指定できます。
※プッシュするには事前にdocker loginしておく必要があるので注意してください。
ただ、今回のこの手順だけでは完全に自動化できたわけではありません。
Githubにpushした後に、いちいちコンテナにログインしてskaffold runをしなけれなならないのは面倒です。
次回はこの部分をCIツールを使って自動化してみたいと思います。