6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SkaffoldのGetting StartedをMinikubeでサクッと試す

Last updated at Posted at 2019-05-07

Cloud Native Online #01に登壇した際のスライドもご覧ください。

Skaffoldとは

Skaffold継続的なKubernetesアプリケーション開発を促進するツールで、
ソースコードの変更をトリガとして以下を自動で行ってくれることで、我々開発者はアプリケーションの開発に注力できるようになります。

  • コンテナイメージのビルド
  • コンテナレジストリへのpush
  • k8sクラスタへのデプロイ
    • kubectlの他、helmkustomizeも記述できる

画像はskaffold.dev/docsより引用
ソースコードの変更をトリガとしてk8sクラスタにデプロイされるまでの流れが示されています。
skaffold.png

Forerver(Node)RailsDjangoがソースコードの変更を検出してサーバを再起動する機能のKubernetes版と考えて良さそうです。

本エントリにはSkaffoldのGetting StartedをMinikubeで実施する場合に必要となる手順を記載します。

環境

Ubuntu 17.10Minikube v1.0.0を使用しています。

$ uname -a
Linux mina 4.13.0-46-generic #51-Ubuntu SMP Tue Jun 12 12:36:29 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=17.10
DISTRIB_CODENAME=artful
DISTRIB_DESCRIPTION="Ubuntu 17.10"
$ minikube version
minikube version: v1.0.0
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.0", GitCommit:"641856db18352033a0d96dbc99153fa3b27298e5", GitTreeState:"clean", BuildDate:"2019-03-25T15:53:57Z", GoVersion:"go1.12.1", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.0", GitCommit:"641856db18352033a0d96dbc99153fa3b27298e5", GitTreeState:"clean", BuildDate:"2019-03-25T15:45:25Z", GoVersion:"go1.12.1", Compiler:"gc", Platform:"linux/amd64"}
$

Minikubeの準備

MinikubeとSkaffoldを組み合わせて使用する場合、留意事項があります。

Skaffoldは、k8sクラスタがMinikubeであると認識した場合、
docker buildは行いますが、docker pushは行いません。

これは、docker buildコマンドが、MinikubeのVM内でのdocker buildとなるよう設定されていることが前提となっていると考えられます。

これには、minikubeのdocker-envコマンドを活用できます。
このコマンドは以下のように、ローカルのdockerコマンドをMinikubeのVM内のdockerに接続するための環境変数設定を表示してくれます。

$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/loft/.minikube/certs"
export DOCKER_API_VERSION="1.35"
# Run this command to configure your shell:
# eval $(minikube docker-env)
$

以下のようにevalで実行すると環境変数が設定されます。

$ eval $(minikube docker-env)

以降、dockerコマンドはMinikubeのVM内のdockerに対する操作になることに留意する必要はありますが、
この機構によりコンテナイメージをわざわざレジストリにpushしなくても
minikubeにアプリケーションをデプロイできるので素早い開発サイクルを回せるメリットがあります。

これを行なっていない場合、dockerイメージはMinikubeのVMの外のローカルでビルドされるため、当然PodのStatusはImagePullBackOffとなります。

Skaffoldのインストール

installing-skaffoldを参照

例) Linuxの場合

$ curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
$ chmod +x skaffold
$ sudo mv skaffold /usr/local/bin

Skaffold サンプルの入手

リポジトリをcloneし、examples/getting-startedディレクトリに移動しましょう。
構成物については後述します。

$ git clone https://github.com/GoogleContainerTools/skaffold
$ cd examples/getting-started
$ ls -Fla
total 28
drwxrwxr-x  2 loft loft 4096  5月  7 21:00 ./
drwxrwxr-x 19 loft loft 4096  5月  7 21:00 ../
-rw-rw-r--  1 loft loft  144  5月  7 21:00 Dockerfile
-rw-rw-r--  1 loft loft  153  5月  7 21:00 k8s-pod.yaml
-rw-rw-r--  1 loft loft  131  5月  7 21:00 main.go
-rw-rw-r--  1 loft loft  734  5月  7 21:00 README.adoc
-rw-rw-r--  1 loft loft  158  5月  7 21:00 skaffold.yaml
$

動作確認

ターミナルを2つ(terminal-1terminal-2)用意し、以下を実行します。

terminal-1

skaffold devコマンドを実行します。
以下が行われる様子を確認できます。

  • docker build ( MinikubeのVM内でbuild )
  • docker push ( Minikubeの場合は行わない )
    • Found [minikube] context, using local docker daemon.より、Minikubeを認識していることが分かる
  • kubectl apply
  • 標準出力ログの表示
  • ソースコードの変更の監視
$ skaffold dev
Generating tags...
 - gcr.io/k8s-skaffold/skaffold-example -> gcr.io/k8s-skaffold/skaffold-example:v0.28.0-89-gf25b09fa-dirty
Tags generated in 7.774075ms
Starting build...
Found [minikube] context, using local docker daemon.
Building [gcr.io/k8s-skaffold/skaffold-example]...
Sending build context to Docker daemon  3.072kB
Step 1/6 : FROM golang:1.10.1-alpine3.7 as builder
 ---> 52d894fca6d4
Step 2/6 : COPY main.go .
 ---> Using cache
 ---> 04e5f4a5d5e2
Step 3/6 : RUN go build -o /app main.go
 ---> Using cache
 ---> eb45bd0c0ce1
Step 4/6 : FROM alpine:3.7
 ---> 6d1ef012b567
Step 5/6 : CMD ["./app"]
 ---> Using cache
 ---> da76805ab2e2
Step 6/6 : COPY --from=builder /app .
 ---> Using cache
 ---> 9c5ffabae1d9
Successfully built 9c5ffabae1d9
Successfully tagged gcr.io/k8s-skaffold/skaffold-example:v0.28.0-89-gf25b09fa-dirty
Build complete in 72.162899ms
Starting test...
Test complete in 5.744µs
Starting deploy...
kubectl client version: 1.14
pod/getting-started created
Deploy complete in 301.514962ms
Watching for changes every 1s...
[getting-started] Hello world!
[getting-started] Hello world!
[getting-started] Hello world!
( 略 : )

terminal-2

アプリケーションのソースコードを書き換えてみましょう。

# 書き換え前
$ cat main.go
( 略 : )
        fmt.Println("Hello world!")
( 略 : )

# 書き換え
$ vim main.go

# 書き換え後
$ cat main.go
( 略 : )
        fmt.Println("Hello skaffold!")
( 略 : )

terminal-1

再びterminal-1を確認してみると、ソースコードの変更をトリガとして以下が行われる様子を確認できます。

  • docker build ( MinikubeのVM内でbuild )
  • docker push ( Minikubeの場合は行わない )
  • kubectl apply
  • 標準出力ログの表示
  • ソースコードの変更の監視

手作業でイメージをビルドし、レジストリにpushし、クラスタにデプロイする手間が省かれていますね。

( 略 : )
[getting-started] Hello world!
[getting-started] Hello world!
[getting-started] Hello world!
Generating tags...
 - gcr.io/k8s-skaffold/skaffold-example -> gcr.io/k8s-skaffold/skaffold-example:v0.28.0-89-gf25b09fa-dirty
Tags generated in 21.094584ms
Starting build...
Found [minikube] context, using local docker daemon.
Building [gcr.io/k8s-skaffold/skaffold-example]...
Sending build context to Docker daemon  3.072kB
Step 1/6 : FROM golang:1.10.1-alpine3.7 as builder
 ---> 52d894fca6d4
Step 2/6 : COPY main.go .
 ---> 4a61f315455a
Step 3/6 : RUN go build -o /app main.go
 ---> Running in 30ee9d0e606f
Removing intermediate container 30ee9d0e606f
 ---> 6a9d5e79631a
Step 4/6 : FROM alpine:3.7
 ---> 6d1ef012b567
Step 5/6 : CMD ["./app"]
 ---> Using cache
 ---> da76805ab2e2
Step 6/6 : COPY --from=builder /app .
 ---> 16dbf70b67d6
Successfully built 16dbf70b67d6
Successfully tagged gcr.io/k8s-skaffold/skaffold-example:v0.28.0-89-gf25b09fa-dirty
Build complete in 1.75830858s
Starting test...
Test complete in 11.741µs
Starting deploy...
kubectl client version: 1.14
pod/getting-started configured
Deploy complete in 296.352796ms
Watching for changes every 1s...
[getting-started] Hello skaffold!
[getting-started] Hello skaffold!
( 略 : )

構成物の確認

main.go

アプリケーションのソースコード。
1sec毎に標準出力にHello world!を表示する。

$ cat main.go
package main

import (
    "fmt"
    "time"
)

func main() {
    for {
        fmt.Println("Hello world!")
        time.Sleep(time.Second * 1)
    }
}

Dockerfile

main.goをビルドしコンテナ起動時のコマンドとしている。

$ cat Dockerfile
FROM golang:1.10.1-alpine3.7 as builder
COPY main.go .
RUN go build -o /app main.go

FROM alpine:3.7
CMD ["./app"]
COPY --from=builder /app .
$

k8s-pod.yaml

gcr.io/k8s-skaffold/skaffold-exampleというイメージを使用するPodの定義。

$ cat k8s-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: getting-started
spec:
  containers:
  - name: getting-started
    image: gcr.io/k8s-skaffold/skaffold-example
$

skaffold.yaml

Skaffoldの設定ファイル。

  • build設定
    • ビルドするイメージ名としてgcr.io/k8s-skaffold/skaffold-exampleを指定している
  • deploy設定
    • kubectlコマンドを使用している
    • k8s-で始まるマニフェストファイル(yaml)を指定している
$ cat skaffold.yaml
apiVersion: skaffold/v1beta9
kind: Config
build:
  artifacts:
  - image: gcr.io/k8s-skaffold/skaffold-example
deploy:
  kubectl:
    manifests:
      - k8s-*
$

まとめ

いかがでしたか?
Skaffoldを使うと、クラスタにデプロイされるまでのルーチンが自動化されるので効率良く開発できそうですね。
特にMinikubeを開発環境として使用している場合は恩恵が大きそうです。

今回はSkaffoldのさわりであるGetting Startedを試してみましたが、Tutorialsも用意されています。
本記事がSkaffold導入の参考になりましたら幸いです。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?