GeekFactory

int128.hatenablog.com

Helmfile supports inlined values in YAML

HelmfileはKubernetesクラスタのHelm releasesを管理するツールです。 helmfile.yaml にデプロイしたいHelm chartを書いて helmfile sync を実行するだけでインストールやアップグレードを冪等にやってくれるので便利です。

例えば、Kubernetes DashboardとHeapsterをクラスタに配置したい場合は以下のYAMLを書くだけでOKです。

releases:
  - name: kubernetes-dashboard
    namespace: kube-system
    chart: stable/kubernetes-dashboard
  - name: heapster
    namespace: kube-system
    chart: stable/heapster
    values:
      - rbac:
          create: true

設定値を変更したい場合はYAMLを変更して helmfile sync を実行すると反映されます。

これまで、Helm chartに設定値を渡したい場合は設定値をkey=valueの形式で記述する必要がありました。Helmコマンドは設定値をYAMLで書けるのに、Helmfileではkey=valueのリストで書く必要がありました。例えばこんな感じです。

releases:
  - name: kubernetes-dashboard-proxy
    namespace: kube-system
    chart: int128.github.io/kubernetes-dashboard-proxy
    set:
      - name: ingress.enabled
        value: true
      - name: ingress.hosts[0]
        value: {{ requiredEnv "KUBE_DASHBOARD_DOMAIN" }}

Helmfile 0.16.0から設定値をインラインで書けるようになりました。これによりYAMLの可読性が大きく改善しました。

releases:
  - name: kubernetes-dashboard-proxy
    namespace: kube-system
    chart: int128.github.io/kubernetes-dashboard-proxy
    values:
      - ingress:
          enabled: true
          hosts:
            - {{ requiredEnv "KUBE_DASHBOARD_DOMAIN" }}

もしHelmコマンドとvalues.yamlファイルで構成管理を行っている場合、それらを1つの helmfile.yaml にまとめると管理しやすくなります。ぜひ試してみてください。

See also


入門 Kubernetes

入門 Kubernetes

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

Read dynamic type values from YAML in Golang

GolangYAMLを読み込む際、要素の型が実行時に決まる場合を考えます。例えば、以下のYAMLでは values で数値、文字列、マップの値が列挙されています。

values:
  - 100
  - foo
  - key: value

このようなYAMLを読み込む場合、型宣言を interface{} にすると実行時に型をチェックして値を処理できます。

type Spec struct {
    Values []interface{} `yaml:"values"`
}

func main() {
    spec := Spec{}
    yaml.NewDecoder(file).Decode(&spec)
    for _, value := range spec.Values {
        switch typedValue := value.(type) {
        case string:
            // 文字列を表示する
            fmt.Printf("string=%s\n", typedValue)
        case int:
            // 数値を表示する
            fmt.Printf("int=%d\n", typedValue)
        case map[interface{}]interface{}:
            // マップに含まれる key の値を表示する
            fmt.Printf("key=%+v\n", typedValue["key"])
        }
    }
}

この方法を応用するとYAMLの部分木を出力することも可能です。先ほどのYAMLに対して以下を実行すると key: value が表示されます。

   for _, value := range spec.Values {
        case map[interface{}]interface{}:
            // 部分木を表示する
            e := yaml.NewEncoder(os.Stdout)
            defer e.Close()
            e.Encode(typedValue)
    }

Full example

package main

import (
    "fmt"
    "os"

    "gopkg.in/yaml.v2"
)

type Spec struct {
    Values []interface{} `yaml:"values"`
}

func main() {
    file, err := os.Open("fixture.yaml")
    if err != nil {
        panic(err)
    }
    spec := Spec{}
    yaml.NewDecoder(file).Decode(&spec)

    for _, value := range spec.Values {
        switch typedValue := value.(type) {
        case string:
            fmt.Printf("string=%s\n", typedValue)
        case int:
            fmt.Printf("int=%d\n", typedValue)
        case map[interface{}]interface{}:
            e := yaml.NewEncoder(os.Stdout)
            defer e.Close()
            e.Encode(typedValue)
        }
    }
}

See also

kubectl getでカスタムカラムを表示する

kubectl getはデフォルトでは以下のカラムを表示するが、どのカラムを表示するかはオプションで変更できる。

% kubectl get po --all-namespaces
NAMESPACE     NAME                                                                  READY     STATUS    RESTARTS   AGE

特定のカラムを表示するには -o custom-columns オプションを渡せばよい。

例えば、Pod名、実行ホスト、リソース要求を表示したい場合は以下のように指定する。

% kubectl get po --all-namespaces -o "custom-columns=NAME:.metadata.name,IP:.status.hostIP,RES:.spec.containers[0].resources.requests" --sort-by .status.hostIP
NAME                                                                  IP              RES
kube-dns-6c4cb66dfb-w69l7                                             172.20.57.157   map[cpu:100m memory:70Mi]
heapster-heapster-697757c69d-4fjpr                                    172.20.57.157   map[cpu:190m memory:224Mi]
...
kube-apiserver-ip-172-20-60-136.us-west-2.compute.internal            172.20.60.136   map[cpu:150m]
kube-scheduler-ip-172-20-60-136.us-west-2.compute.internal            172.20.60.136   map[cpu:100m]
kube-controller-manager-ip-172-20-60-136.us-west-2.compute.internal   172.20.60.136   map[cpu:100m]
kube-proxy-ip-172-20-60-136.us-west-2.compute.internal                172.20.60.136   map[cpu:100m]
~

ここでは --sort-by オプションを渡して実行ホストでソートしている。

See Also