Учитывая кластер kubernetes, на котором запущено некоторое количество модулей, служб, развертываний и т. Д., Я хотел бы сгенерировать один или несколько файлов (предпочтительно формат yml), которые будут воспроизводить текущую конфигурацию при применении к новому кластеру.
Мой вариант использования - это система продвижения. У меня есть свои «файлы стека» в виде файлов yml в репозитории git, но мне нужно разрешить людям утверждать изменения, прежде чем они будут применены к кластеру.
Один из способов сделать это - использовать систему «разомкнутого цикла». Я могу использовать теги или другие механизмы, чтобы определить, какие версии были применены к кластеру, а затем сравнить последнюю доступную версию с последней развернутой версией.
Проблема с системой разомкнутого цикла заключается в том, что она не учитывает, что изменения могли быть внесены вне файлов, или что примененные изменения могли иметь проблемы и т. Д.
Если бы я мог извлечь «эквивалентные» файлы из работающего кластера, я мог бы сравнить их с теми, которые собираются применить. Это гораздо более сильная система «замкнутого цикла» - она способна правильно понять, что произойдет, когда будут применены изменения, даже если мы потеряли из виду реальное целевое состояние.
если бы была такая вещь, как kubectl apply -f
Есть у кого-нибудь мысли по этому поводу? Мы новичок в kubernetes, но мы создали описанную выше функциональность для наших развертываний RedHat / Satellite на основе rpm, поэтому я хочу воссоздать ее в K8s. Конечно, в k8s есть сложность, которую может изменить сама инфраструктура, а не только установленные версии пакетов!
kubectl get po, развертывание, rc, rs, ds, no, job -o yaml?
Ах да, конечно! Это работает, но это не то, что я искал. Он отвечает на мой вопрос, но не дает мне файлов, соответствующих тем, которые я использовал.
Я узнал, что ответ на этот вопрос - прочитать аннотацию «last-apply-configuration», которую добавляет kubectl. это даст файлы, которые использовались для создания конфигурации.
@dcowden также см. kubectl get --export
ах это даже лучше! Благодарность!
Объединив другие ответы, это то, что я придумал для 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://github.com/kubernetes/kubernetes/issues/42885 и 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
Это делается для того, чтобы все файлы yaml были в одном каталоге для простого kubectl apply -f
. Он также исключает секрет учетной записи службы по умолчанию, который не может быть экспортирован.
Другая версия: экспорт всего 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
Еще одна небольшая настройка для исключения токенов учетной записи службы:
#!/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 cluster
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 для каждого компонента в пространстве имен. эти резервные копии экспортируются, затем шифруются паролем и загружаются в S3 Bucket.
Если кто-то захочет зафиксировать какие-либо изменения или поделиться какими-либо комментариями, добро пожаловать: +1:
окружающие инновации / k8s-резервное копирование
пример: сгенерировать pv yaml.
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 для каждого пространства имен, а затем экспортировать файл yaml для каждого pv, посмотрите
Создайте папку $ {HOME} / clusterstate /, затем запустите:
kubectl cluster-info dump --all-namespaces --output-directory=${HOME}/clusterstate/ -o yaml
Все ваши объекты будут в отдельной структуре папок, соответствующей пространствам имен.
Расширения .json, например deployments.json, вводят в заблуждение, поскольку флаг -o yaml
создаст экспорт yaml.
Создайте папку $ {HOME} / clusterstate /, затем запустите:
kubectl cluster-info dump --all-namespaces --output-directory=${HOME}/clusterstate/ -o yaml
Все ваши объекты будут в отдельной структуре папок, соответствующей пространствам имен.
Расширения .json, например deployments.json, вводят в заблуждение, поскольку флаг-o yaml
создаст экспорт yaml.
К вашему сведению, похоже, для крупных развертываний требуется приличный объем ОЗУ, моя виртуальная машина с интерфейсом командной строки с 2 ГБ ОЗУ не может справиться с этим (возможно, потребуется 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 ГБ, то есть 8 ГБ!
Очевидно, что about соответствует общему размеру вывода дампа, который включает журналы, и некоторые из наших модулей (90 из них) размещают журналы размером более 100 МБ. Это будет означать, что команда dump сохраняет все в ОЗУ даже во время записи на диск, возможно, ее можно оптимизировать для очистки ОЗУ по мере завершения записи журналов.
Может ли кто-нибудь сказать мне команду или сценарий, который будет выполнять резервное копирование кластера (включая ns, развертывание, svc, секреты, pv pvc, только файлы cm
Я пробовал с командой --export, но в сервисе имя файла yaml отсутствует, и если я беру резервную копию без --export, тогда он включает IP-адрес кластера, порт nodePort, IP- адрес loadBalancer, который не позволяет мне развернуть его в новом кластере как он неизменен (clusterIP и loadBalancer).
kubernetes cluster версии 1.14 и новее 1.15 / 16/17 (пытается сделать резервную копию / восстановить в GCP gke или AWS eks).
Спасибо kubectl api-resources
! Мне удалось получить манифесты (файлы yaml) всех ресурсов во всех пространствах имен в k8s, используя следующий сценарий bash:
#!/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
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
Самый полезный комментарий
kubectl get po, развертывание, rc, rs, ds, no, job -o yaml?