読者です 読者をやめる 読者になる 読者になる

uyamazakのブログ

仕事中の問題と解決メモ。PythonとGoogle Cloudがメイン。bizoceanで新規事業の企画と開発担当。 BigQueryを使ったビッグデータ収集・解析・リアルタイム処理プロジェクト進行中 https://github.com/uyamazak/oceanus

Google Container Engineでdeploymentとserviceをコピーするために設定を出力する

Google Container Engineで運用しているアプリケーションをそろそろ東京リージョンに移そうと思った。

これまで、

kubectl get service -o yaml
kubectl get deployment -o yaml

で出力されるyamlは手作業で必要な項目消したり、書き換えていたりしてから、kubectl -f {ファイル名}で新しいコンテナクラスタに読み込んでいた。


でも、それぞれ数が増えてきて、やってられないので自動化しようと思った。

JSONで出力して、Pythonなり、何らかのプログラムでパースするしかないかなと思ってたけど、Kubernetesのドキュメントを漁っていたらtempleteというのを見つけた。

公式で探したけど、過渡期なのかリンク切れがひどくて見つけられない。

ともかく使い方としては下記のようなコマンド。

※kcは.zshrcで設定しているkubectlのエイリアス

% kc get service -o=go-template-file=service-backup-template.txt
% kc get deploy -o=go-template-file=deploy-backup-template.txt

go-template-file=には、Go言語の表示パッケージであるtemplate形式でファイルを作る。

template - The Go Programming Language

何度もエラーと戦いながら2時間以上書けて書いた。環境によっては足りない項目等で、そのままでは使えない場合がある。

deploy-backup-template.txt

apiVersion: {{.apiVersion}}
items:{{with .items}}{{range . }}
- apiVersion: {{.apiVersion}}
  kind: {{.kind}}
  metadata:
    name: {{.metadata.name}}
  spec:
    replicas: {{.spec.replicas}}
    template:
      metadata:
        labels:
          run: {{.spec.template.metadata.labels.run}}
      spec:{{with .spec.template.spec.containers}}{{range .}}
        containers:
        - name: {{.name}}
          {{with .env}}env:{{range .}}
          - name: {{.name}}
            value: {{.value}}{{- end}}{{end}}
          {{with .command}}command:{{range .}}
          - {{.}}{{end}}{{end}}
          image: {{.image}}
          {{with .ports}}{{range .}}
          ports:
            - containerPort: {{.containerPort}}
              protocol: {{.protocol}}
          {{end}}{{end}}
          {{with .volumeMounts}}{{range .}}
          volumeMounts:
            - mountPath: {{.mountPath}}
              name: {{.name}}
        {{end}}{{end}}
      {{end}}{{end}}
      {{with .spec.template.spec.volumes}}{{range .}}
        volumes:
        - gcePersistentDisk:
            fsType: {{.gcePersistentDisk.fsType}}
            pdName: {{.gcePersistentDisk.pdName}}
          name: {{.name}}{{end}}{{end}}
{{end}}{{end}}
kind: List
metadata: {}
resourceVersion: ""
selfLink: ""

この可読性保持のために出力されたファイルには不要な空白行が含まれるけど、読み込みには問題ない。

出力後、いくつか手作業が必要。

  • envのvalueに数字のみの値がある場合、出力した後に手作業で""で囲む
  • Volumeに使う永続ディスクを変更する。


service-backup-template.txt

apiVersion: {{.apiVersion}}
items:{{with .items}}{{range .}}{{ if ne .metadata.name "kubernetes"}}
- apiVersion: {{.apiVersion}}
  kind: {{.kind}}
  metadata:
    name: {{.metadata.name}}
  spec:
    ports:{{with .spec.ports}}{{range .}}
    - port: {{.port}}
      {{if .nodePort}}nodePort: {{.nodePort}}{{end}}
      protocol: {{.protocol}}
      targetPort: {{.targetPort}}{{end}}{{end}}
    selector:
      run: {{.spec.selector.run}}
    sessionAffinity: {{.spec.sessionAffinity}}
    type: {{.spec.type}}
{{end}}{{end}}{{end}}
kind: List

こちらはデフォルトで存在するkubernetesのサービスを{{ if ne .metadata.name "kubernetes"}}で飛ばすようにしてある。
HTTPSロードバランサーを使っているので、KubernetesのロードバランサーのServiceは使っている場合は、変更が必要だと思う。

これを作ったことで、今後のバックアップと複製から大幅に手作業をカットできた。