Kubernetes: Есть ли способ сгенерировать файлы yml, которые будут создавать существующий кластер?

Созданный на 27 апр. 2016  ·  24Комментарии  ·  Источник: kubernetes/kubernetes

Учитывая кластер kubernetes, на котором запущено некоторое количество модулей, служб, развертываний и т. Д., Я хотел бы сгенерировать один или несколько файлов (предпочтительно формат yml), которые будут воспроизводить текущую конфигурацию при применении к новому кластеру.

Мой вариант использования - это система продвижения. У меня есть свои «файлы стека» в виде файлов yml в репозитории git, но мне нужно разрешить людям утверждать изменения, прежде чем они будут применены к кластеру.

Один из способов сделать это - использовать систему «разомкнутого цикла». Я могу использовать теги или другие механизмы, чтобы определить, какие версии были применены к кластеру, а затем сравнить последнюю доступную версию с последней развернутой версией.

Проблема с системой разомкнутого цикла заключается в том, что она не учитывает, что изменения могли быть внесены вне файлов, или что примененные изменения могли иметь проблемы и т. Д.

Если бы я мог извлечь «эквивалентные» файлы из работающего кластера, я мог бы сравнить их с теми, которые собираются применить. Это гораздо более сильная система «замкнутого цикла» - она ​​способна правильно понять, что произойдет, когда будут применены изменения, даже если мы потеряли из виду реальное целевое состояние.

если бы была такая вещь, как kubectl apply -f--dry-run, в котором перечислены только те изменения, которые будут внесены, вместо фактического внесения изменений, которые также будут работать. Это уже обсуждается по данному вопросу

Есть у кого-нибудь мысли по этому поводу? Мы новичок в kubernetes, но мы создали описанную выше функциональность для наших развертываний RedHat / Satellite на основе rpm, поэтому я хочу воссоздать ее в K8s. Конечно, в k8s есть сложность, которую может изменить сама инфраструктура, а не только установленные версии пакетов!

Самый полезный комментарий

kubectl get po, развертывание, rc, rs, ds, no, job -o yaml?

Все 24 Комментарий

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 был протестирован с помощью:

  • k8s v1.16.3
  • ОС Ubuntu Bionic 18.04.3
  • версия 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 рейтинги