CentOS8にSkaffoldを導入する

f:id:fclout:20200614202723p:plain
今回は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基盤は準備されていることを前提とします。
自分で構築して用意したい場合はこちら

github.com



コンテナの準備

ベースコンテナですが今回は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で対応します。
wgetGithubのソースを取得するには

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ツールを使って自動化してみたいと思います。