Kubernetes: Apakah ada cara untuk menghasilkan file yml yang akan menghasilkan cluster yang ada?

Dibuat pada 27 Apr 2016  ·  24Komentar  ·  Sumber: kubernetes/kubernetes

Mengingat kluster kubernetes yang menjalankan sejumlah pod, layanan, penerapan, dll, saya ingin membuat satu atau lebih file ( lebih disukai format yml) yang akan menghasilkan ulang konfigurasi saat ini, bila diterapkan ke kluster baru.

Kasus penggunaan saya adalah sistem promosi. Saya memiliki 'file tumpukan' sebagai file yml di git repo, tetapi saya harus mengizinkan manusia untuk menyetujui perubahan sebelum diterapkan ke cluster.

Salah satu cara untuk melakukannya adalah dengan menggunakan sistem 'loop terbuka'. Saya dapat menggunakan tag atau mekanisme lain untuk menentukan versi mana yang telah diterapkan ke cluster, dan kemudian membandingkan versi terbaru yang tersedia dengan versi terbaru yang diterapkan.

Masalah dengan sistem loop terbuka adalah bahwa ia tidak menganggap bahwa perubahan dapat dilakukan di luar file, atau bahwa perubahan yang diterapkan dapat menimbulkan masalah, dll.

Jika saya dapat mengekstrak file 'setara' dari cluster yang sedang berjalan, saya dapat membandingkannya dengan yang akan diterapkan. Ini adalah sistem 'loop tertutup' yang jauh lebih kuat-- ia dapat memahami dengan benar apa yang akan terjadi ketika perubahan diterapkan, bahkan jika kita kehilangan jejak keadaan target sebenarnya.

jika ada yang namanya kubectl apply -f--dry-run, yang hanya mencantumkan perubahan yang akan dibuat, daripada benar-benar melakukan perubahan, itu juga akan berhasil. Itu sudah dibahas di masalah https://github.com/kubernetes/kubernetes/issues/11488

Apakah ada yang punya pemikiran tentang ini? Kami baru mengenal kubernet, tetapi kami telah membuat fungsionalitas yang saya jelaskan di atas untuk penerapan berbasis rpm RedHat/Satelit kami, jadi saya ingin membuatnya kembali di K8s. Tentu saja, di k8s, kami memiliki kerumitan yang dapat diubah oleh infrastruktur itu sendiri, bukan hanya versi paket yang diinstal!

Komentar yang paling membantu

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

Semua 24 komentar

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

Ah ya, tentu saja! Ini berhasil, tetapi bukan itu yang saya cari. Itu menjawab pertanyaan saya, tetapi tidak memberi saya file yang cocok dengan yang saya gunakan.

Saya mengetahui bahwa jawaban untuk pertanyaan ini adalah dengan membaca anotasi 'last-applied-configuration' yang ditambahkan oleh kubectl. ini akan memberikan file yang digunakan untuk menghasilkan konfigurasi.

@dcowden juga lihat kubectl get --export

ah itu lebih baik! Terima kasih!

Menggabungkan jawaban lain, inilah yang saya buat untuk 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

Untuk orang-orang yang datang ke sini dari Google, pada contoh pengujian saya, komentar terakhir all tampaknya tidak menyertakan ingress , dan Anda juga harus mengatakan --all-namespaces untuk mendapatkannya membuang namespace lain.

Terkait: https://github.com/kubernetes/kubernetes/issues/42885 dan https://github.com/kubernetes/kubernetes/pull/42954#issuecomment -285949856 dll.

Variasi di atas solusi yang disediakan oleh @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

Ini untuk memiliki semua file yaml dalam satu direktori untuk kubectl apply -f . Itu juga mengecualikan rahasia akun layanan default yang tidak dapat diekspor.

Versi lain: Mengekspor semua yaml dari semua ruang nama. Untuk setiap namespace sebuah direktori dibuat.

  • termasuk volume persisten!
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

dan untuk mengimpor lagi:

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

Tweak kecil lainnya untuk mengecualikan token akun layanan:

#!/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

Bagi mereka yang bekerja di windows Powershell, inilah satu kalimat:
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
Saya pikir grep -v 'secrets/default-token' harus diubah menjadi grep -v 'secret/default-token'
secrets tidak bekerja dengan saya.

Saya menggunakan versi kubectl dan k8s cluster berikut

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 Anda benar! Terima kasih!

Hai teman-teman baru saja membuat gambar buruh pelabuhan ini untuk mengekspor file yaml yang diperlukan untuk setiap komponen per namespace. cadangan ini diekspor kemudian dienkripsi dengan kata sandi dan diunggah ke S3 Bucket.

Jika ada yang ingin melakukan perubahan atau berbagi komentar, Anda dipersilahkan :+1:
ambien-inovasi/k8s-backup

contoh: menghasilkan 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

Script ini harus menghasilkan semua pvc untuk setiap namespace kemudian mengekspor file yaml untuk setiap pv, lihat

Buat folder ${HOME}/clusterstate/, lalu jalankan:
kubectl cluster-info dump --all-namespaces --output-directory=${HOME}/clusterstate/ -o yaml
Semua entitas Anda akan berada dalam struktur folder terpisah, sesuai dengan ruang nama.
Ekstensi .json, yaitu deployments.json, menyesatkan, karena flag -o yaml akan membuat ekspor yaml.

Buat folder ${HOME}/clusterstate/, lalu jalankan:
kubectl cluster-info dump --all-namespaces --output-directory=${HOME}/clusterstate/ -o yaml
Semua entitas Anda akan berada dalam struktur folder terpisah, sesuai dengan ruang nama.
Ekstensi .json, yaitu deployments.json, menyesatkan, karena flag -o yaml akan membuat ekspor yaml.

FYI, ini tampaknya membutuhkan jumlah RAM yang layak untuk penyebaran besar, 2GB RAM CLI jumpbox VM saya tidak dapat menanganinya (mungkin perlu 4 atau 8 saya bayangkan):

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

Saya menjalankan ulang di desktop saya dan melacak penggunaan memori proses kubectl, puncaknya hanya sekitar 4GB, jadi 8GB!

Tampaknya kira-kira cocok dengan ukuran total keluaran dump, yang mencakup log dan beberapa pod kami (90 di antaranya) mengeluarkan log dengan ukuran lebih dari 100MB. Ini akan menunjukkan kepada saya bahwa perintah dump menyimpan semua yang ada di RAM meskipun sedang ditulis ke disk, mungkin dapat dioptimalkan untuk menghapus RAM karena log selesai ditulis.

Adakah yang bisa memberi tahu saya perintah atau skrip yang akan mengambil cadangan cluster (termasuk file ns, penyebaran, svc, rahasia, pv pvc, cm yaml saja) dengan semua informasi dan mengembalikannya di cluster baru.
Saya telah mencoba dengan --export perintah tetapi dalam layanan nama file yaml layanan tidak ada dan jika saya mengambil cadangan tanpa --export maka itu termasuk IP clusterIP , nodePort ,
kubernetes cluster versi 1.14 dan seterusnya 1.15/16/17 (mencoba melakukan backup/restore di GCP gke atau AWS eks).

Terima kasih kepada kubectl api-resources ! Saya bisa mendapatkan manifes (file yaml) dari semua sumber daya di semua ruang nama di k8s menggunakan skrip bash berikut:

#!/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')

Skrip bash di atas diuji dengan:

  • k8s v1.16.3
  • Ubuntu Bionic 18.04.3 OS
  • versi versi bash 4.4.20(1)-release (x86_64-pc-linux-gnu)

@vhosakot Penyederhanaan kecil untuk skrip Anda.

Anda dapat mengganti: kubectl api-resources | awk '{print $1}' | grep -v '^NAME'
Dengan: 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}')

saya sedikit memperpanjang skrip di atas (dan memperlambatnya). ini memuat semua ruang nama, memuat semua sumber daya di semua ruang nama dan kemudian memuat setiap konfigurasi sebagai satu file di setiap sumber daya di setiap ruang nama. itu bertele-tele dan menunjukkan beberapa kesalahan, tetapi hasil akhirnya (dump) harus bersih.

#!/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

Terinspirasi oleh @scones tetapi berjalan sedikit lebih cepat karena proses forking dan pengurangan loop nesting yang berguna jika Anda memiliki banyak definisi sumber daya khusus!

Sama seperti @nathan-c
Saya menghapus events dari daftar sumber daya untuk memperbaiki kesalahan

#!/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
Apakah halaman ini membantu?
0 / 5 - 0 peringkat