いくつかのポッド、サービス、デプロイなどを実行しているkubernetesクラスターを前提として、新しいクラスターに適用したときに現在の構成を再現する1つ以上のファイル(yml形式を推奨)を生成したいと思います。
私のユースケースはプロモーションシステムです。 「スタックファイル」をgitリポジトリにymlファイルとして持っていますが、変更をクラスターに適用する前に、人間が変更を承認できるようにする必要があります。
これを行う1つの方法は、「開ループ」システムを使用することです。 タグまたはその他のメカニズムを使用して、クラスターに適用されているバージョンを判別し、使用可能な最新バージョンを最新のデプロイ済みバージョンと比較できます。
開ループシステムの問題は、ファイルの外部で変更が行われた可能性があるとは見なされないこと、または適用された変更に問題があった可能性があることなどです。
実行中のクラスターから「同等の」ファイルを抽出できれば、それらを適用しようとしているファイルと比較できます。 これは、はるかに強力な「閉ループ」システムです。実際のターゲット状態を見失った場合でも、変更が適用されたときに何が起こるかを正しく理解できます。
kubectl apply-fのようなものがあった場合
誰かがこれについて考えていますか? kubernetesは初めてですが、RedHat / Satellite rpmベースのデプロイ用に上記で説明した機能を作成したので、K8sで再作成したいと思います。 もちろん、k8sでは、インストールされたパッケージバージョンだけでなく、インフラストラクチャ自体が変更される可能性があるという複雑さがあります。
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
と言う必要があります。他の名前空間をダンプします。
関連: https : https://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 IP 、 nodePort Port 、 loadBalancer IPが含まれ、新しいクラスターにデプロイできません。不変です(clusterIPとloadBalancer)。
kubernetesクラスターバージョン1.14以降1.15 / 16/17(GCPgkeまたはAWSeksでバックアップ/復元を試みます)。
kubectl api-resources
感謝します! 次のbashスクリプトを使用して、k8sのすべての名前空間にあるすべてのリソースのマニフェスト(yamlファイル)を取得できました。
#!/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スクリプトは、次のコマンドでテストされました。
v1.16.3
18.04.3
OS4.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
最も参考になるコメント
kubectl get po、deployment、rc、rs、ds、no、job -o yaml?