Help us understand the problem. What is going on with this article?

Kubernetesでのローカルの開発をskaffoldで加速させる

前提とゴール

  • k8sでのデプロイはなんとなくわかる
    DeploymentとServiceのyaml用意して、kubectl applyすればいいんでしょ?くらい
  • しかし、k8sでのローカルってどうしたらいいか、なにもわからない
    • localのvolumeを、k8sでmountしてアプリを参照するの?
      これは一見シンプルに見えて、アプリビルド後に、podの再起動(=再適用)が必要になる
    • docker imageはproductionに(近い)registryに置けばいいの?
      いいけど、GCRとかに、いちいちpushしてpullするのはなんか無駄っぽい
    • docker imageはlocalでdocker buildしたimageを使えばいいの?
      これでいきます
  • localと各環境(production, ...)のyamlって絶対差分あるじゃん
    今回はkustomizeを使って解消しています
    kustomizeについてのサンプルはこちら
    Kubernetes+kustomizeでmasterをスマートにさっとデプロイする
    今回は利用しませんが、skaffoldはHelmにも対応しています
  • productionはskaffoldなしでデプロイまでできてるから、skaffoldいらないんだけど?
    全てをskaffoldに置き換える必要はありません (自分は最初勘違いしていました)
    今回はローカルの開発 だけ skaffoldを使います

skaffoldについて

ざっくり言うと、ファイルを監視して、変更があったらdocker buildして、kubectl applyまでやってくれるツールです、超快適です
ローカル専用ではないです が、今回はローカル専用として使います

細かくは公式を読みましょう
https://skaffold.dev/docs/
https://github.com/GoogleContainerTools/skaffold

skaffoldの準備

1. skaffoldコマンドをインストール

macであれば brew install skaffold

2. skaffold.yamlを書く

公式でサンプルコードをいくつも用意してくれています
https://github.com/GoogleContainerTools/skaffold/tree/master/examples
getting startやれば雰囲気は掴めます
https://skaffold.dev/docs/getting-started/

一番大切なのはskaffold.yamlのリファレンスで、これを確認しながら書くことになります
https://skaffold.dev/docs/references/yaml/

実際のディレクトリ構成

repository
├── ops
│   ├── app
│   │   ├── Dockerfile
│   │   └── app.jar
│   └── k8s
│       ├── base
│       │   ├── deployment.yaml
│       │   └── kustomization.yaml
│       ├── manifest
│       │   ├── local-k8s.yaml
│       │   └── prd-k8s.yaml
│       └── overlays
│           ├── local
│           │   ├── build.sh
│           │   └── kustomization.yaml
│           └── production
│               ├── build.sh
│               ├── deployment.yaml
│               └── kustomization.yaml
├── いろいろ
└── skaffold.yaml

kustomizeまわりの詳細についてはこちら
Kubernetes+kustomizeでmasterをスマートにさっとデプロイする

大切な要素は3つです

  • /skaffold.yaml
    skaffoldが参照するファイル
  • /ops/app/
    変更の監視をするフォルダ
    Dockerfileと、アプリのビルド後のファイルを配置している
  • /ops/k8s/overlays/local/
    kustomizeにて、ローカル環境の元になる設定

/skaffold.yaml

build.artifacts.contextで監視するフォルダを指定
useBuildkitはdockerのBuildKitという、buildが早くなる機能の有効可
docker v18.09以上で設定可

/skaffold.yaml
apiVersion: skaffold/v1beta12
kind: Config
build:
  artifacts:
    - image: app-image-local
      context: ops/app/
  tagPolicy:
    dateTime:
      format: "20060102_150405"
      timezone: "Local"
  local:
    useBuildkit: true
deploy:
  kustomize:
    path: ops/k8s/overlays/local

/ops/k8s/overlays/local/

/ops/k8s/overlays/local/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
images:
- name: app-image
  newName: app-image-local

../../base のファイル

/ops/k8s/base/deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-name
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: container-name
          image: app-image:latest
/ops/k8s/base/kustomization.yaml
commonLabels:
  app: app-label
resources:
  - deployment.yaml

(2019/07) skaffold v0.33.0 依存っぽい話

よくあるcontainersの設定である、
imagePullPolicy: Always は、ローカル環境ではあえて外しています
Alwaysつけると、下記のエラーが出るため

pull access denied for app-image-local, repository does not exist or may require 'docker login'
Back-off pulling image "app-image-local:hash"

また、skaffoldをググるとよく出てくる、ローカルのレジストリを参照するため、
docker imageにlocalhostつけて localhost:5000/hoge:fuga にする手順は不要でした
公式のリファレンスを探しましたが、localhostつける元ネタわからず、、

リポジトリ内にあるサンプルコードは、ソースファイルをDockerfileでコピーしてマルチステージビルドしてる件

元々ローカルでアプリをビルド後、Dockerfileでコピーする構成にしていたので、
どうすればいいのか悩んだポイントでしたが、
反映したいタイミングで自分でビルドし、 /ops/app に配置すれば、
再起動までskaffoldがやってくれるので、これはこれでいいかなという感じです

実行手順

skaffold dev でskaffoldの実行しますが、監視しづづけているので、このコンソールはそのままにします
Ctrl+C で終了できますが、k8sも綺麗にしてくれます!
しかし docker images はいろいろ残ります、、

別のコンソールで、監視しているcontextのファイルを更新( sbt assembly などでjarを再配置)すると、skaffoldが勝手に再起動します

yakisuzu
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away