Kubernetes: 既存のクラスターを生成するymlファイルを生成する方法はありますか?

作成日 2016年04月27日  ·  24コメント  ·  ソース: kubernetes/kubernetes

いくつかのポッド、サービス、デプロイなどを実行しているkubernetesクラスターを前提として、新しいクラスターに適用したときに現在の構成を再現する1つ以上のファイル(yml形式を推奨)を生成したいと思います。

私のユースケースはプロモーションシステムです。 「スタックファイル」をgitリポジトリにymlファイルとして持っていますが、変更をクラスターに適用する前に、人間が変更を承認できるようにする必要があります。

これを行う1つの方法は、「開ループ」システムを使用することです。 タグまたはその他のメカニズムを使用して、クラスターに適用されているバージョンを判別し、使用可能な最新バージョンを最新のデプロイ済みバージョンと比較できます。

開ループシステムの問題は、ファイルの外部で変更が行われた可能性があるとは見なされないこと、または適用された変更に問題があった可能性があることなどです。

実行中のクラスターから「同等の」ファイルを抽出できれば、それらを適用しようとしているファイルと比較できます。 これは、はるかに強力な「閉ループ」システムです。実際のターゲット状態を見失った場合でも、変更が適用されたときに何が起こるかを正しく理解できます。

kubectl apply-fのようなものがあった場合--dry-runは、実際に変更を行うのではなく、行われる変更のみを一覧表示します。 それはすでに問題https://github.com/kubernetes/kubernetes/issues/11488で議論されてい

誰かがこれについて考えていますか? kubernetesは初めてですが、RedHat / Satellite rpmベースのデプロイ用に上記で説明した機能を作成したので、K8sで再作成したいと思います。 もちろん、k8sでは、インストールされたパッケージバージョンだけでなく、インフラストラクチャ自体が変更される可能性があるという複雑さがあります。

最も参考になるコメント

kubectl get po、deployment、rc、rs、ds、no、job -o yaml?

全てのコメント24件

kubectl get po、deployment、rc、rs、ds、no、job -o yaml?

もちろんです! これは機能しますが、私が探していたものではありません。 それは私の質問に答えますが、私が使用したものと一致するファイルを私に与えません。

この質問に対する答えは、kubectlが追加する「last-applied-configuration」アノテーションを読むことであることを学びました。 これにより、構成の作成に使用されたファイルが提供されます。

@dcowdenは、kubectl get

ああ、それはさらに良いです! ありがとう!

他の答えを組み合わせて、これは私がbashのために思いついたものです:

for n in $(kubectl get -o=name pvc,configmap,serviceaccount,secret,ingress,service,deployment,statefulset,hpa,job,cronjob)
do
    mkdir -p $(dirname $n)
    kubectl get -o=yaml --export $n > $n.yaml
done

k8s 1.8

kubectl get all --export=true -o yaml

私のテストインスタンスでは、Googleからここに来る人々にとって、最後のコメントのallにはingressが含まれていないようです。また、 --all-namespacesと言う必要があります。他の名前空間をダンプします。

関連: httpshttps://github.com/kubernetes/kubernetes/pull/42954#issuecomment-285949856など。

@alahijaniによって提供されるソリューションに

for n in $(kubectl get -o=name pvc,configmap,ingress,service,secret,deployment,statefulset,hpa,job,cronjob | grep -v 'secret/default-token')
do
    kubectl get -o=yaml --export $n > $(dirname $n)_$(basename $n).yaml
done

これは、簡単なkubectl apply -fために、すべてのyamlファイルを単一のディレクトリに置くことです。 また、エクスポートできないデフォルトのサービスアカウントシークレットも除外されます。

別のバージョン:すべての名前空間からすべてのyamlをエクスポートします。 名前空間ごとにディレクトリが作成されます。

  • 永続ボリュームを含む!
i=$((0))
for n in $(kubectl get -o=custom-columns=NAMESPACE:.metadata.namespace,KIND:.kind,NAME:.metadata.name pv,pvc,configmap,ingress,service,secret,deployment,statefulset,hpa,job,cronjob --all-namespaces | grep -v 'secrets/default-token')
do
    if (( $i < 1 )); then
        namespace=$n
        i=$(($i+1))
        if [[ "$namespace" == "PersistentVolume" ]]; then
            kind=$n
            i=$(($i+1))
        fi
    elif (( $i < 2 )); then
        kind=$n
        i=$(($i+1))
    elif (( $i < 3 )); then
        name=$n
        i=$((0))
        echo "saving ${namespace} ${kind} ${name}"
        if [[ "$namespace" != "NAMESPACE" ]]; then
            mkdir -p $namespace
            kubectl get $kind -o=yaml --export $name -n $namespace > $namespace/$kind.$name.yaml
        fi
    fi
done

再度インポートする場合:

path=$(pwd)
for n in $(ls -d */)
do
    echo "Creating namespace ${n:0:-1}"
    kubectl create namespace ${n:0:-1}

    for yaml in $(ls $path/$n)
    do
        echo -e "\t Importing $yaml"
        kubectl apply -f $path/$n$yaml -n ${n:0:-1}
    done

done

サービスアカウントトークンを除外するためのもう1つの微調整:

#!/bin/env bash

## https://github.com/kubernetes/kubernetes/issues/24873#issuecomment-416189335

i=$((0))
for n in $(kubectl get -o=custom-columns=NAMESPACE:.metadata.namespace,KIND:.kind,NAME:.metadata.name pv,pvc,configmap,ingress,service,secret,deployment,statefulset,hpa,job,cronjob --all-namespaces | grep -v 'secrets/default-token')
do
    if (( $i < 1 )); then
        namespace=$n
        i=$(($i+1))
        if [[ "$namespace" == "PersistentVolume" ]]; then
            kind=$n
            i=$(($i+1))
        fi
    elif (( $i < 2 )); then
        kind=$n
        i=$(($i+1))
    elif (( $i < 3 )); then
        name=$n
        i=$((0))
        if [[ "$namespace" != "NAMESPACE" ]]; then
            mkdir -p $namespace

            yaml=$((kubectl get $kind -o=yaml $name -n $namespace ) 2>/dev/null)
            if [[ $kind != 'Secret' || $yaml != *"type: kubernetes.io/service-account-token"* ]]; then
                echo "Saving ${namespace}/${kind}.${name}.yaml"
                kubectl get $kind -o=yaml --export $name -n $namespace > $namespace/$kind.$name.yaml
            fi
        fi
    fi
done

Windows Powershellで作業する人のために、ここにワンライナーがあります:
Foreach ($i in $(kubectl get -o=name pvc,configmap,ingress,service,secret,deployment,statefulset,hpa,job,cronjob)) {If($i -notmatch "default-token") {kubectl get -o=yaml --export $i | Out-File -filepath $($i.Replace("/", "-") + ".yaml")}}

@mrwulf @acondrat
grep -v 'secrets/default-token'grep -v 'secret/default-token'変更する必要があると思います
secretsは私と一緒に動作しませんでした。

次のバージョンのkubectlとk8sクラスターを使用しています

Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.2", GitCommit:"17c77c7898218073f14c8d573582e8d2313dc740", GitTreeState:"clean", BuildDate:"2018-10-24T06:54:59Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.5", GitCommit:"32ac1c9073b132b8ba18aa830f46b77dcceb0723", GitTreeState:"clean", BuildDate:"2018-06-21T11:34:22Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}

@ 4m3ndyあなたは正しいです! ありがとう!

名前空間ごとに各コンポーネントに必要なyamlファイルをエクスポートするために、このDockerイメージを作成しました。 これらのバックアップはエクスポートされ、パスワードで暗号化されてS3バケットにアップロードされます。

誰かが変更をコミットしたりコメントを共有したい場合は、大歓迎です:+1:
アンビエント-イノベーション/ k8s-バックアップ

例:pvyamlを生成します。

kubectl get pv -o yaml --export | sed -e '/resourceVersion: "[0-9]\+"/d' -e '/uid: [a-z0-9-]\+/d' -e '/selfLink: [a-z0-9A-Z/]\+/d' -e '/status:/d' -e '/phase:/d' -e '/creationTimestamp:/d' > pvList.yaml

@ xiaoping378
https://github.com/ambient-innovation/k8s-backup/blob/01c1bfe750136648fd91e14dd691ba39bb05f282/k8s-backup.sh#L38

このスクリプトは、各名前空間のすべてのpvcを生成してから、各pvのyamlファイルをエクスポートする必要があります。

$ {HOME} / clusterstate /フォルダーを作成し、次のコマンドを実行します。
kubectl cluster-info dump --all-namespaces --output-directory=${HOME}/clusterstate/ -o yaml
すべてのエンティティは、名前空間に対応する個別のフォルダ構造になります。
-o yamlフラグがyamlエクスポートを作成するため、.json拡張機能(deployments.json)は誤解を招く可能性があります。

$ {HOME} / clusterstate /フォルダーを作成し、次のコマンドを実行します。
kubectl cluster-info dump --all-namespaces --output-directory=${HOME}/clusterstate/ -o yaml
すべてのエンティティは、名前空間に対応する個別のフォルダ構造になります。
-o yamlフラグがyamlエクスポートを作成するため、.json拡張機能(deployments.json)は誤解を招く可能性があります。

参考までに、これは大規模な展開にはかなりの量のRAMを必要とするようですが、私の2GB RAM CLIジャンプボックスVMはそれを処理できません(おそらく4または8が必要です):

fatal error: runtime: out of memory

runtime stack:
runtime.throw(0x1ab7c29, 0x16)
        /usr/local/go/src/runtime/panic.go:774 +0x72
runtime.sysMap(0xc068000000, 0x10000000, 0x2da7238)
        /usr/local/go/src/runtime/mem_linux.go:169 +0xc5
runtime.(*mheap).sysAlloc(0x2d8e9a0, 0x10000000, 0x0, 0x0)
        /usr/local/go/src/runtime/malloc.go:701 +0x1cd
runtime.(*mheap).grow(0x2d8e9a0, 0x8000, 0xffffffff)
        /usr/local/go/src/runtime/mheap.go:1255 +0xa3
runtime.(*mheap).allocSpanLocked(0x2d8e9a0, 0x8000, 0x2da7248, 0x42c7bc)
        /usr/local/go/src/runtime/mheap.go:1170 +0x266
runtime.(*mheap).alloc_m(0x2d8e9a0, 0x8000, 0x101, 0xc000103f18)
        /usr/local/go/src/runtime/mheap.go:1022 +0xc2

デスクトップで再実行し、kubectlプロセスのメモリ使用量を追跡しました。ピークは約4 GBでしたので、8GBです。

どうやらそれは、ログを含むダンプの合計出力サイズとほぼ一致し、ポッドの一部(90個)は100MBを超えるサイズのログを出力しています。 これは、dumpコマンドがディスクへの書き込み中であってもすべてをRAMに保存していることを示しています。おそらく、ログの書き込みが終了したときにRAMをクリアするように最適化できます。

クラスターのバックアップ(ns、deployment、svc、secrets、pv pvc、cm yamlファイルのみを含む)をすべての情報とともに取得し、新しいクラスターに復元するコマンドまたはスクリプトを教えてもらえますか?
--exportコマンドを試してみましたが、サービスでyamlファイル名がありません。--exportなしでバックアップを作成すると、 clusterIP IPnodePort PortloadBalancer IPが含まれ、新しいクラスターにデプロイできません。不変です(clusterIPとloadBalancer)。
kubernetesクラスターバージョン1.14以降1.15 / 16/17(GCPgkeまたはAWSeksでバックアップ/復元を試みます)。

kubectl api-resources感謝します! 次のbashスクリプトを使用して、k8sのすべての名前空間にあるすべてのリソースのマニフェスト(ya​​mlファイル)を取得できました。

#!/usr/bin/env bash

while read -r line
do
    output=$(kubectl get "$line" --all-namespaces -o yaml 2>/dev/null | grep '^items:')
    if ! grep -q "\[\]" <<< $output; then
        echo -e "\n======== "$line" manifests ========\n"
        kubectl get "$line" --all-namespaces -o yaml
    fi
done < <(kubectl api-resources | awk '{print $1}' | grep -v '^NAME')

上記のbashスクリプトは、次のコマンドでテストされました。

  • k8s v1.16.3
  • Ubuntu Bionic 18.04.3 OS
  • bashバージョンバージョン4.4.20(1)-release (x86_64-pc-linux-gnu)

@vhosakotスクリプトを

置き換えることができます: kubectl api-resources | awk '{print $1}' | grep -v '^NAME'
あり: kubectl api-resources -o name

#!/usr/bin/env bash

while read -r namespace
do
    echo "scanning namespace '${namespace}'"
    mkdir -p "${HOME}/cluster-backup/${namespace}"
    while read -r resource
    do
        echo "  scanning resource '${resource}'"
        mkdir -p "${HOME}/cluster-backup/${namespace}/${resource}"
        while read -r item
        do
            echo "    exporting item '${item}'"
            kubectl get "$resource" -n "$namespace" "$item" -o yaml > "${HOME}/cluster-backup/${namespace}/${resource}/$item.yaml"
        done < <(kubectl get "$resource" -n "$namespace" 2>&1 | tail -n +2 | awk '{print $1}')
    done < <(kubectl api-resources --namespaced=true 2>/dev/null | tail -n +2 | awk '{print $1}')
done < <(kubectl get namespaces | tail -n +2 | awk '{print $1}')

私はスクリプトを少し上に拡張しました(そしてそれを遅くしました)。 これにより、すべての名前空間が読み込まれ、すべての名前空間のすべてのリソースが読み込まれ、各構成が各名前空間の各リソースの単一ファイルとして読み込まれます。 冗長でいくつかのエラーが表示されますが、最終結果(ダンプ)はクリーンである必要があります。

#!/usr/bin/env bash
ROOT=${HOME}/clusterstate

while read -r resource
do
    echo "  scanning resource '${resource}'"
    while read -r namespace item x
    do
        mkdir -p "${ROOT}/${namespace}/${resource}"        
        echo "    exporting item '${namespace} ${item}'"
        kubectl get "$resource" -n "$namespace" "$item" -o yaml > "${ROOT}/${namespace}/${resource}/$item.yaml" &
    done < <(kubectl get "$resource" --all-namespaces 2>&1 | tail -n +2)
done < <(kubectl api-resources --namespaced=true 2>/dev/null | tail -n +2 | awk '{print $1}')

wait

@sconesに触発され速度が少し速くなりました。これは、カスタムリソース定義がたくさんある場合に便利です。

@ nathan-cと同じ
エラーを修正するためにリソースリストからeventsを削除しました

#!/usr/bin/env bash
ROOT=${HOME}/clusterstate
while read -r resource
do
    echo "  scanning resource '${resource}'"
    while read -r namespace item x
    do
        mkdir -p "${ROOT}/${namespace}/${resource}"        
        echo "    exporting item '${namespace} ${item}'"
        kubectl get "$resource" -n "$namespace" "$item" -o yaml > "${ROOT}/${namespace}/${resource}/$item.yaml" &
    done < <(kubectl get "$resource" --all-namespaces 2>&1  | tail -n +2)
done < <(kubectl api-resources --namespaced=true 2>/dev/null | grep -v "events" | tail -n +2 | awk '{print $1}')

wait
このページは役に立ちましたか?
0 / 5 - 0 評価