Melakukan bootstrap node GKE secara otomatis dengan DaemonSets


Tutorial ini menunjukkan cara menyesuaikan node cluster Google Kubernetes Engine (GKE) menggunakan DaemonSets. DaemonSet memastikan bahwa semua node (atau yang dipilih) menjalankan salinan Pod. Dengan pendekatan ini, Anda dapat menggunakan alat yang sama untuk mengatur workload yang Anda gunakan untuk mengubah node GKE.

Jika alat dan sistem yang Anda gunakan untuk menginisialisasi cluster Anda berbeda dengan alat dan sistem yang Anda gunakan untuk menjalankan workload, Anda akan meningkatkan upaya yang diperlukan untuk mengelola lingkungan Anda. Misalnya, jika Anda menggunakan alat manajemen konfigurasi untuk melakukan inisialisasi node cluster, Anda mengandalkan prosedur yang berada di luar lingkungan runtime tempat sisa workload Anda berjalan.

Tujuan tutorial ini adalah untuk membantu administrator sistem, engineer sistem, atau operator infrastruktur menyederhanakan inisialisasi cluster Kubernetes.

Sebelum membaca halaman ini, pastikan Anda memahami:

Dalam tutorial ini, Anda akan mempelajari cara menggunakan label dan pemilih Kubernetes untuk memilih prosedur inisialisasi yang akan dijalankan berdasarkan label yang diterapkan ke suatu node. Pada langkah-langkah ini, Anda akan men-deploy DaemonSet agar hanya berjalan pada node dengan label default-init yang diterapkan. Namun, untuk menunjukkan fleksibilitas mekanisme ini, Anda dapat membuat node pool lain dan menerapkan label alternative-init ke node dalam pool baru ini. Di cluster, Anda kemudian dapat men-deploy DaemonSet lain yang dikonfigurasi agar berjalan hanya pada node yang memiliki label alternative-init.

Selain itu, Anda dapat menjalankan beberapa prosedur inisialisasi pada setiap node, bukan hanya satu saja. Anda dapat memanfaatkan mekanisme ini untuk menyusun prosedur inisialisasi dengan lebih baik, dan memisahkan masalah setiap proses dengan jelas.

Dalam tutorial ini, sebagai contoh, prosedur inisialisasi melakukan tindakan berikut pada setiap node yang diberi label dengan label default-init:

  1. Memasang disk tambahan ke node.
  2. Menginstal serangkaian paket dan library menggunakan pengelola paket sistem operasi node.
  3. Memuat set modul kernel Linux.

Tujuan

Dalam tutorial ini, Anda akan melakukan beberapa hal berikut:

  • Menyediakan dan mengonfigurasi cluster GKE.
  • Menyiapkan deskripsi DaemonSet untuk melakukan inisialisasi node dalam cluster.
  • Men-deploy DaemonSet di cluster.
  • Verifikasi bahwa node cluster telah diinisialisasi.

Biaya

Dalam dokumen ini, Anda akan menggunakan komponen Google Cloud yang dapat ditagih berikut:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga. Pengguna baru Google Cloud mungkin memenuhi syarat untuk mendapatkan uji coba gratis.

Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, lihat Pembersihan.

Sebelum memulai

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

Melakukan bootstrap pada lingkungan

Di bagian ini, Anda akan melakukan hal berikut:

  1. Mengaktifkan Cloud API yang diperlukan.
  2. Menyediakan akun layanan dengan hak istimewa terbatas untuk node di cluster GKE.
  3. Menyiapkan cluster GKE.
  4. Memberikan hak istimewa administrasi cluster pengguna.

Aktifkan Cloud API

  1. Buka Cloud Shell.

    BUKA Cloud Shell

  2. Pilih project Google Cloud:

    gcloud config set project project-id
    

    Ganti project-id dengan ID project Google Cloud yang Anda buat atau pilih untuk tutorial ini.

  3. Aktifkan Google Kubernetes Engine API:

    gcloud services enable container.googleapis.com
    

Menyediakan akun layanan untuk mengelola cluster GKE

Di bagian ini, Anda akan membuat akun layanan yang terkait dengan node dalam cluster. Dalam tutorial ini, node GKE menggunakan akun layanan ini, bukan akun layanan default. Sebagai praktik terbaik, cukup berikan akun layanan peran dan izin akses yang diperlukan untuk menjalankan aplikasi.

Peran yang diperlukan untuk akun layanan adalah sebagai berikut:

  • Peran Monitoring Viewer (roles/monitoring.viewer). Peran ini memberikan akses hanya baca ke konsol Cloud Monitoring dan API.
  • Peran Penulis Metrik Pemantauan (roles/monitoring.metricWriter). Peran ini mengizinkan penulisan data pemantauan.
  • Peran Penulis Log (roles/logging.logWriter). Peran ini memberikan izin yang cukup untuk menulis log.
  • Peran Pengguna Akun layanan (roles/iam.serviceAccountUser). Peran ini memberikan akses ke akun layanan dalam sebuah project. Dalam tutorial ini, prosedur inisialisasi meniru identitas akun layanan untuk menjalankan operasi dengan hak istimewa.
  • Peran Admin Compute (roles/compute.admin). Peran ini memberikan kontrol penuh atas semua resource Compute Engine. Dalam tutorial ini, akun layanan memerlukan peran ini untuk memasang disk tambahan ke node cluster.

Untuk menyediakan akun layanan, ikuti langkah-langkah berikut:

  1. Di Cloud Shell, lakukan inisialisasi variabel lingkungan yang menyimpan nama akun layanan:

    GKE_SERVICE_ACCOUNT_NAME=ds-init-tutorial-gke
    
  2. Membuat akun layanan

    gcloud iam service-accounts create "$GKE_SERVICE_ACCOUNT_NAME" \
      --display-name="$GKE_SERVICE_ACCOUNT_NAME"
    
  3. Lakukan inisialisasi variabel lingkungan yang menyimpan nama akun email akun layanan:

    GKE_SERVICE_ACCOUNT_EMAIL="$(gcloud iam service-accounts list \
        --format='value(email)' \
        --filter=displayName:"$GKE_SERVICE_ACCOUNT_NAME")"
    
  4. Ikat peran Identity and Access Management (IAM) ke akun layanan:

    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/compute.admin
    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/monitoring.viewer
    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/monitoring.metricWriter
    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/logging.logWriter
    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/iam.serviceAccountUser
    

Menyiapkan cluster GKE

Di bagian ini, Anda akan meluncurkan cluster GKE, memberikan izin, dan menyelesaikan konfigurasi cluster.

Untuk tutorial ini, cluster dengan jumlah node kecil tujuan umum yang relatif rendah sudah cukup untuk mendemonstrasikan konsep tutorial ini. Anda membuat cluster dengan satu node pool (yang default). Selanjutnya, Anda memberi label semua node di node pool default dengan label default-init.

  • Di Cloud Shell, buat dan luncurkan cluster GKE regional:

    gcloud container clusters create ds-init-tutorial \
        --enable-ip-alias \
        --image-type=ubuntu_containerd \
        --machine-type=n1-standard-2 \
        --metadata disable-legacy-endpoints=true \
        --node-labels=app=default-init \
        --node-locations us-central1-a,us-central1-b,us-central1-c \
        --no-enable-basic-auth \
        --no-issue-client-certificate \
        --num-nodes=1 \
        --region us-central1 \
        --service-account="$GKE_SERVICE_ACCOUNT_EMAIL"
    

Men-deploy DaemonSet

Di bagian ini, Anda akan melakukan hal berikut:

  1. Buat ConfigMap yang menyimpan prosedur inisialisasi.
  2. Men-deploy DaemonSet yang menjadwalkan dan menjalankan prosedur inisialisasi.

DaemonSet melakukan hal berikut:

  1. Mengonfigurasi volume yang membuat konten ConfigMap tersedia untuk container yang ditangani DaemonSet.
  2. Mengonfigurasi volume untuk area sistem file dengan hak istimewa dari node cluster yang mendasarinya. Area ini memungkinkan container yang dijadwalkan DaemonSet berinteraksi langsung dengan node yang menjalankannya.
  3. Menjadwalkan dan menjalankan container init yang menjalankan prosedur inisialisasi, kemudian dihentikan setelah selesai.
  4. Menjadwalkan dan menjalankan container yang tetap tidak ada aktivitas dan tidak menggunakan resource.

Container tanpa ada aktivitas memastikan bahwa node hanya diinisialisasi sekali. DaemonSets didesain agar semua node yang memenuhi syarat menjalankan salinan Pod. Jika Anda menggunakan container reguler, container tersebut akan menjalankan prosedur inisialisasi, lalu dihentikan setelah selesai. Secara desain, DaemonSet menjadwalkan ulang Pod. Untuk menghindari "penjadwalan ulang berkelanjutan", DaemonSet terlebih dahulu menjalankan prosedur inisialisasi dalam container init, lalu membiarkan container tetap berjalan.

Prosedur inisialisasi berikut berisi operasi dengan hak istimewa dan tidak istimewa. Dengan menggunakan chroot, Anda dapat menjalankan perintah seolah-olah sedang mengeksekusinya langsung di node, bukan hanya di dalam container.

# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: entrypoint
  labels:
    app: default-init
data:
  entrypoint.sh: |
    #!/usr/bin/env bash

    set -euo pipefail

    DEBIAN_FRONTEND=noninteractive
    ROOT_MOUNT_DIR="${ROOT_MOUNT_DIR:-/root}"

    echo "Installing dependencies"
    apt-get update
    apt-get install -y apt-transport-https curl gnupg lsb-release

    echo "Installing gcloud SDK"
    export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
    echo "deb https://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
    apt-get update
    apt-get install -y google-cloud-sdk

    echo "Getting node metadata"
    NODE_NAME="$(curl -sS http://metadata.google.internal/computeMetadata/v1/instance/name -H 'Metadata-Flavor: Google')"
    ZONE="$(curl -sS http://metadata.google.internal/computeMetadata/v1/instance/zone -H 'Metadata-Flavor: Google' | awk -F  "/" '{print $4}')"

    echo "Setting up disks"
    DISK_NAME="$NODE_NAME-additional"

    if ! gcloud compute disks list --filter="name:$DISK_NAME" | grep "$DISK_NAME" > /dev/null; then
        echo "Creating $DISK_NAME"
        gcloud compute disks create "$DISK_NAME" --size=1024 --zone="$ZONE"
    else
        echo "$DISK_NAME already exists"
    fi

    if ! gcloud compute instances describe "$NODE_NAME" --zone "$ZONE" --format '(disks[].source)' | grep "$DISK_NAME" > /dev/null; then
        echo "Attaching $DISK_NAME to $NODE_NAME"
        gcloud compute instances attach-disk "$NODE_NAME" --device-name=sdb --disk "$DISK_NAME" --zone "$ZONE"
    else
        echo "$DISK_NAME is already attached to $NODE_NAME"
    fi

    # We use chroot to run the following commands in the host root (mounted as the /root volume in the container)
    echo "Installing nano"
    chroot "${ROOT_MOUNT_DIR}" apt-get update
    chroot "${ROOT_MOUNT_DIR}" apt-get install -y nano

    echo "Loading Kernel modules"
    # Load the bridge kernel module as an example
    chroot "${ROOT_MOUNT_DIR}" modprobe bridge
...

Sebaiknya tinjau setiap prosedur inisialisasi dengan cermat karena prosedur ini dapat mengubah status node cluster Anda. Hanya sekelompok kecil individu yang berhak memodifikasi prosedur tersebut, karena prosedur tersebut dapat sangat memengaruhi ketersediaan dan keamanan cluster Anda.

Untuk men-deploy ConfigMap dan DaemonSet, lakukan hal berikut:

  1. Di Cloud Shell, ubah direktori kerja ke direktori $HOME:

    cd "$HOME"
    
  2. Buat clone repositori Git yang berisi skrip dan file manifes untuk men-deploy dan mengonfigurasi prosedur inisialisasi:

    git clone https://github.com/GoogleCloudPlatform/solutions-gke-init-daemonsets-tutorial
    
  3. Ubah direktori kerja ke direktori repositori yang baru saja di-clone:

    cd "$HOME"/solutions-gke-init-daemonsets-tutorial
    
  4. Buat ConfigMap untuk menyimpan skrip inisialisasi node:

    kubectl apply -f cm-entrypoint.yaml
    
  5. Deploy DaemonSet:

    kubectl apply -f daemon-set.yaml
    
  6. Verifikasi bahwa inisialisasi node selesai:

    kubectl get ds --watch
    

    Tunggu hingga DaemonSet dilaporkan sebagai siap dan terbaru, seperti yang ditunjukkan oleh output yang mirip dengan berikut ini:

    NAME              DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    node-initializer   3         3         3         3            3          <none>  2h
    

Memvalidasi dan memverifikasi prosedur inisialisasi

Setelah setiap node cluster yang ditandai dengan label default-init mengeksekusi prosedur inisialisasi, Anda dapat memverifikasi hasilnya.

Untuk setiap node, prosedur verifikasi akan memeriksa hal-hal berikut:

  1. Disk tambahan terpasang dan siap digunakan.
  2. Pengelola paket sistem operasi node menginstal paket dan library.
  3. Modul kernel telah dimuat.

Jalankan prosedur verifikasi:

  • Jalankan skrip verifikasi di Cloud Shell:

    kubectl get nodes -o=jsonpath='{range .items[?(@.metadata.labels.app=="default-init")]}{.metadata.name}{" "}{.metadata.labels.failure-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}' | while IFS= read -r line ; do ./verify-init.sh $line < /dev/null; done
    

    Tunggu skrip berjalan dan pastikan setiap node telah diinisialisasi dengan benar, seperti yang ditunjukkan oleh output seperti berikut:

    Verifying gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) configuration
    Disk configured successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c)
    Packages installed successfully in gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c)
    Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c)
    Verifying gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) configuration
    Disk configured successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a)
    Packages installed successfully in gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a)
    Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a)
    Verifying gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) configuration
    Disk configured successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b)
    Packages installed successfully in gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b)
    Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b)
    

Pembersihan

Agar tidak menimbulkan biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, Anda dapat menghapus project yang dibuat untuk tutorial ini. Jika membuat project khusus untuk tutorial ini, Anda dapat menghapusnya sepenuhnya. Jika Anda menggunakan project yang sudah ada, tetapi tidak ingin menghapusnya, gunakan langkah-langkah berikut untuk membersihkan project.

Membersihkan project

Untuk membersihkan project tanpa menghapusnya, Anda harus menghapus resource yang dibuat dalam tutorial ini.

  1. Di Cloud Shell, hapus cluster GKE:

    gcloud container clusters delete ds-init-tutorial --quiet --region us-central1
    
  2. Hapus disk tambahan yang Anda buat sebagai bagian dari contoh prosedur inisialisasi ini:

    gcloud compute disks list --filter="name:additional" --format="csv[no-heading](name,zone)" | while IFS= read -r line ; do DISK_NAME="$(echo $line | cut -d',' -f1)"; ZONE="$(echo $line | cut -d',' -f2)"; gcloud compute disks delete "$DISK_NAME" --quiet --zone "$ZONE" < /dev/null; done
    
  3. Hapus akun layanan:

    gcloud iam service-accounts delete "$GKE_SERVICE_ACCOUNT_EMAIL" --quiet
    
  4. Hapus direktori repositori yang di-clone:

    rm -rf "$HOME"/solutions-gke-init-daemonsets-tutorial
    

Menghapus project

Cara termudah untuk menghilangkan penagihan adalah dengan menghapus project yang Anda buat untuk tutorial.

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Langkah berikutnya