Build Aman & Men-deploy dengan Cloud Build, Artifact Registry, dan GKE

1. Pengantar

Container Analysis menyediakan pemindaian kerentanan dan penyimpanan metadata untuk container. Layanan pemindaian melakukan pemindaian kerentanan pada image di Artifact Registry dan Container Registry, lalu menyimpan metadata yang dihasilkan dan menyediakannya untuk digunakan melalui API. Penyimpanan metadata memungkinkan Anda menyimpan informasi dari berbagai sumber, termasuk pemindaian kerentanan, layanan Google Cloud, dan penyedia pihak ketiga.

Pemindaian kerentanan dapat dilakukan secara otomatis atau sesuai permintaan:

  • Jika pemindaian otomatis diaktifkan, pemindaian akan otomatis terpicu setiap kali Anda mengirimkan image baru ke Artifact Registry atau Container Registry. Informasi kerentanan terus diperbarui saat kerentanan baru ditemukan.
  • Jika Pemindaian On-Demand diaktifkan, Anda harus menjalankan perintah untuk memindai image lokal atau image di Artifact Registry atau Container Registry. Pemindaian On-Demand memberi Anda fleksibilitas terkait waktu pemindaian container. Misalnya, Anda dapat memindai image yang dibuat secara lokal dan memperbaiki kerentanan sebelum menyimpannya di registry. Hasil pemindaian tersedia hingga 48 jam setelah pemindaian selesai, dan informasi kerentanan tidak diperbarui setelah pemindaian.

Dengan Container Analysis yang terintegrasi ke dalam pipeline CI/CD, Anda dapat membuat keputusan berdasarkan metadata tersebut. Misalnya, Anda dapat menggunakan Otorisasi Biner untuk membuat kebijakan deployment yang hanya mengizinkan deployment untuk image yang mematuhi kebijakan dari registry tepercaya.

Yang akan Anda pelajari

  • Cara mengaktifkan pemindaian otomatis
  • Cara melakukan Pemindaian On-Demand
  • Cara mengintegrasikan pemindaian dalam pipeline build
  • Cara menandatangani gambar yang disetujui
  • Cara menggunakan pengontrol Penerimaan GKE untuk memblokir image
  • Cara mengonfigurasi GKE agar hanya mengizinkan image yang disetujui dan ditandatangani

2. Penyiapan dan Persyaratan

Penyiapan lingkungan mandiri

  1. Login ke Google Cloud Console dan buat project baru atau gunakan kembali project yang sudah ada. Jika belum memiliki akun Gmail atau Google Workspace, Anda harus membuatnya.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Project name adalah nama tampilan untuk peserta project ini. String ini adalah string karakter yang tidak digunakan oleh Google API. Anda dapat memperbaruinya kapan saja.
  • Project ID bersifat unik di semua project Google Cloud dan tidak dapat diubah (tidak dapat diubah setelah ditetapkan). Cloud Console otomatis membuat string unik; biasanya Anda tidak mementingkan kata-katanya. Di sebagian besar codelab, Anda harus merujuk Project ID-nya (umumnya diidentifikasi sebagai PROJECT_ID). Jika tidak suka dengan ID yang dibuat, Anda dapat membuat ID acak lainnya. Atau, Anda dapat mencobanya sendiri dan melihat apakah ID tersebut tersedia. ID tidak dapat diubah setelah langkah ini dan akan tetap ada selama durasi project.
  • Sebagai informasi, ada nilai ketiga, Project Number, yang digunakan oleh beberapa API. Pelajari lebih lanjut ketiga nilai ini di dokumentasi.
  1. Selanjutnya, Anda harus mengaktifkan penagihan di Konsol Cloud untuk menggunakan resource/API Cloud. Menjalankan operasi dalam codelab ini seharusnya tidak memerlukan banyak biaya, bahkan mungkin tidak sama sekali. Guna mematikan resource agar tidak menimbulkan penagihan di luar tutorial ini, Anda dapat menghapus resource yang dibuat atau menghapus seluruh project. Pengguna baru Google Cloud memenuhi syarat untuk mengikuti program Uji Coba Gratis senilai $300 USD.

Memulai Cloudshell Editor

Lab ini dirancang dan diuji untuk digunakan dengan Editor Google Cloud Shell. Untuk mengakses editor,

  1. akses project Google Anda di https://console.cloud.google.com.
  2. Di sudut kanan atas, klik ikon editor cloud shell

8560cc8d45e8c112.png

  1. Panel baru akan terbuka di bagian bawah jendela

Penyiapan Lingkungan

Di Cloud Shell, tetapkan project ID dan nomor project untuk project Anda. Simpan sebagai variabel PROJECT_ID dan PROJECT_ID.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

Mengaktifkan layanan

Aktifkan semua layanan yang diperlukan:

gcloud services enable \
  cloudkms.googleapis.com \
  cloudbuild.googleapis.com \
  container.googleapis.com \
  containerregistry.googleapis.com \
  artifactregistry.googleapis.com \
  containerscanning.googleapis.com \
  ondemandscanning.googleapis.com \
  binaryauthorization.googleapis.com 

Membuat Repositori Artifact Registry

Di lab ini, Anda akan menggunakan Artifact Registry untuk menyimpan dan memindai image. Buat repositori dengan perintah berikut.

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

Konfigurasikan Docker untuk menggunakan kredensial gcloud Anda saat mengakses Artifact Registry.

gcloud auth configure-docker us-central1-docker.pkg.dev

3. Pemindaian Otomatis

Pemindaian artefak dipicu secara otomatis setiap kali Anda mengirimkan image baru ke Artifact Registry atau Container Registry. Informasi kerentanan terus diperbarui saat kerentanan baru ditemukan. Di bagian ini, Anda akan mengirim image ke Artifact Registry dan mempelajari hasilnya.

Membuat dan mengubah ke direktori kerja

mkdir vuln-scan && cd vuln-scan

Menentukan gambar sampel

Buat file bernama Dockerfile dengan konten berikut.

cat > ./Dockerfile << EOF
FROM gcr.io/google-appengine/debian9@sha256:ebffcf0df9aa33f342c4e1d4c8428b784fc571cdf6fbab0b31330347ca8af97a

# System
RUN apt update && apt install python3-pip -y

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==1.1.4
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app

EOF

Buat file bernama main.py dengan konten berikut

cat > ./main.py << EOF
import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    name = os.environ.get("NAME", "Worlds")
    return "Hello {}!".format(name)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF

Mem-build dan Mengirim image ke AR

Gunakan Cloud Build untuk mem-build dan otomatis mengirim container Anda ke Artifact Registry. Perhatikan tag bad pada gambar. Hal ini akan membantu Anda mengidentifikasinya untuk langkah berikutnya.

gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad

Meninjau Detail Gambar

Setelah proses build selesai, tinjau gambar dan hasil Vulnerability di dasbor Artifact Registry.

  1. Buka Artifact Registry di Cloud Console
  2. Klik artifact-scanning-repo untuk melihat kontennya
  3. Klik detail gambar
  4. Klik ringkasan terbaru gambar Anda
  5. Setelah pemindaian selesai, klik tab kerentanan untuk image

Dari tab kerentanan, Anda akan melihat hasil pemindaian otomatis untuk image yang baru saja Anda build.

361be7b3bf293fca.png

Pemindaian otomatis diaktifkan secara default. Pelajari Setelan Artifact Registry untuk melihat cara menonaktifkan/mengaktifkan pemindaian otomatis.

4. Pemindaian On-Demand

Ada berbagai skenario yang mengharuskan Anda menjalankan pemindaian sebelum mengirim image ke repositori. Misalnya, developer penampung dapat memindai image dan memperbaiki masalah, sebelum mendorong kode ke kontrol sumber. Pada contoh di bawah, Anda akan mem-build dan menganalisis gambar secara lokal sebelum menindaklanjuti hasilnya.

Mem-build Image

Pada langkah ini, Anda akan menggunakan docker lokal untuk mem-build image ke cache lokal.

docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .

Memindai gambar

Setelah gambar dibuat, minta pemindaian gambar. Hasil pemindaian disimpan di server metadata. Tugas selesai dengan lokasi hasil di server metadata.

gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --format="value(response.scan)" > scan_id.txt

Meninjau File Output

Luangkan waktu untuk meninjau output langkah sebelumnya yang disimpan dalam file scan_id.txt. Perhatikan lokasi laporan hasil pemindaian di server metadata.

cat scan_id.txt

Meninjau hasil pemindaian mendetail

Untuk melihat hasil pemindaian yang sebenarnya, gunakan perintah list-vulnerabilities di lokasi laporan yang tercantum dalam file output.

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) 

Output berisi data dalam jumlah yang signifikan tentang semua kerentanan dalam image.

Menandai Masalah penting

Manusia jarang menggunakan data yang disimpan dalam laporan secara langsung. Biasanya, hasilnya digunakan oleh proses otomatis. Gunakan perintah di bawah untuk membaca detail laporan dan mencatat jika ada kerentanan KRITIS yang ditemukan

export SEVERITY=CRITICAL

gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt) --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq ${SEVERITY}; then echo "Failed vulnerability check for ${SEVERITY} level"; else echo "No ${SEVERITY} Vulnerabilities found"; fi

Output dari perintah ini akan menjadi

Failed vulnerability check for CRITICAL level

5. Pemindaian Pipeline Build

Di bagian ini, Anda akan membuat pipeline build otomatis yang akan mem-build image container, memindainya, lalu mengevaluasi hasilnya. Jika tidak ada kerentanan KRITIS yang ditemukan, image akan di-push ke repositori. Jika ditemukan kerentanan KRITIS, build akan gagal dan keluar.

Memberikan akses untuk Akun Layanan Cloud Build

Cloud Build akan memerlukan hak untuk mengakses API pemindaian on-demand. Berikan akses dengan perintah berikut.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
        
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/ondemandscanning.admin"

Membuat pipeline Cloud Build

Perintah berikut akan membuat file cloudbuild.yaml di direktori Anda yang akan digunakan untuk proses otomatis. Untuk contoh ini, langkah-langkahnya terbatas pada proses build container. Namun, dalam praktiknya, Anda akan menyertakan petunjuk dan pengujian khusus aplikasi selain langkah-langkah penampung.

Buat file dengan perintah berikut.

cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#pushing to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']

images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image
EOF

Menjalankan pipeline CI

Kirim build untuk diproses guna memverifikasi kerusakan build saat kerentanan tingkat keparahan CRITICAL ditemukan.

gcloud builds submit

Meninjau Kegagalan Build

Build yang baru saja Anda kirimkan akan gagal karena image berisi kerentanan KRITIS.

Tinjau kegagalan build di halaman Histori Cloud Build

Memperbaiki Kerentanan

Perbarui Dockerfile untuk menggunakan image dasar yang tidak berisi kerentanan KRITIS.

Ganti Dockerfile untuk menggunakan image Debian 10 dengan perintah berikut

cat > ./Dockerfile << EOF
from python:3.8-slim  

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app

EOF

Menjalankan proses CI dengan gambar yang baik

Kirim build untuk diproses guna memverifikasi bahwa build akan berhasil jika tidak ada kerentanan dengan tingkat keparahan CRITICAL yang ditemukan.

gcloud builds submit

Tinjau Keberhasilan Build

Build yang baru saja Anda kirimkan akan berhasil karena image yang diupdate tidak berisi kerentanan KRITIS.

Tinjau keberhasilan build di halaman Cloud Build History

Meninjau Hasil pemindaian

Meninjau image yang baik di Artifact Registry

  1. Buka Artifact Registry di Cloud Console
  2. Klik artifact-scanning-repo untuk melihat kontennya
  3. Klik detail gambar
  4. Klik ringkasan terbaru gambar Anda
  5. Klik tab kerentanan untuk image

6. Menandatangani Gambar

Membuat Catatan Attestor

Catatan Pengesah hanyalah sedikit data yang berfungsi sebagai label untuk jenis tanda tangan yang diterapkan. Misalnya, satu catatan mungkin menunjukkan pemindaian kerentanan, sementara catatan lainnya mungkin digunakan untuk persetujuan QA. Catatan tersebut akan dirujuk selama proses penandatanganan.

Membuat catatan

cat > ./vulnz_note.json << EOM
{
  "attestation": {
    "hint": {
      "human_readable_name": "Container Vulnerabilities attestation authority"
    }
  }
}
EOM

Menyimpan catatan

NOTE_ID=vulnz_note

curl -vvv -X POST \
    -H "Content-Type: application/json"  \
    -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
    --data-binary @./vulnz_note.json  \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"

Memverifikasi catatan

curl -vvv  \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"

Membuat Attestor

Pengesah digunakan untuk melakukan proses penandatanganan gambar yang sebenarnya dan akan melampirkan kemunculan catatan ke gambar untuk verifikasi di lain waktu. Buat pengautentikasi untuk digunakan nanti.

Buat Attestor

ATTESTOR_ID=vulnz-attestor

gcloud container binauthz attestors create $ATTESTOR_ID \
    --attestation-authority-note=$NOTE_ID \
    --attestation-authority-note-project=${PROJECT_ID}

Memverifikasi Attester

gcloud container binauthz attestors list

Perhatikan baris terakhir yang menunjukkan NUM_PUBLIC_KEYS: 0 yang akan Anda berikan kuncinya di langkah berikutnya

Perhatikan juga bahwa Cloud Build otomatis membuat pengautentikasi built-by-cloud-build di project Anda saat Anda menjalankan build yang menghasilkan image. Jadi, perintah di atas menampilkan dua pengautentikasi, vulnz-attestor dan built-by-cloud-build. Setelah image berhasil di-build, Cloud Build akan otomatis menandatangani dan membuat pengesahan untuk image tersebut.

Menambahkan Peran IAM

Akun layanan Otorisasi Biner akan memerlukan hak untuk melihat catatan pengesahan. Berikan akses dengan panggilan API berikut

PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}"  --format="value(projectNumber)")

BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"


cat > ./iam_request.json << EOM
{
  'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
  'policy': {
    'bindings': [
      {
        'role': 'roles/containeranalysis.notes.occurrences.viewer',
        'members': [
          'serviceAccount:${BINAUTHZ_SA_EMAIL}'
        ]
      }
    ]
  }
}
EOM

Gunakan file untuk membuat Kebijakan IAM

curl -X POST  \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    --data-binary @./iam_request.json \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"

Menambahkan Kunci KMS

Pengesah memerlukan kunci kriptografis untuk melampirkan catatan dan memberikan tanda tangan yang dapat diverifikasi. Pada langkah ini, Anda akan membuat dan menyimpan kunci di KMS agar dapat diakses oleh Cloud Build nanti.

Pertama, tambahkan beberapa variabel lingkungan untuk mendeskripsikan kunci baru

KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1

Membuat key ring untuk menyimpan kumpulan kunci

gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"

Membuat pasangan kunci penandatanganan asimetris baru untuk pengautentikasi

gcloud kms keys create "${KEY_NAME}" \
    --keyring="${KEYRING}" --location="${KEY_LOCATION}" \
    --purpose asymmetric-signing   \
    --default-algorithm="ec-sign-p256-sha256"

Anda akan melihat kunci Anda muncul di halaman KMS di Konsol Google Cloud.

Sekarang, kaitkan kunci dengan pengautentikasi Anda melalui perintah gcloud binauthz:

gcloud beta container binauthz attestors public-keys add  \
    --attestor="${ATTESTOR_ID}"  \
    --keyversion-project="${PROJECT_ID}"  \
    --keyversion-location="${KEY_LOCATION}" \
    --keyversion-keyring="${KEYRING}" \
    --keyversion-key="${KEY_NAME}" \
    --keyversion="${KEY_VERSION}"

Jika Anda mencetak daftar otoritas lagi, Anda akan melihat kunci yang terdaftar:

gcloud container binauthz attestors list

Membuat Pengesahan yang Ditandatangani

Pada tahap ini, Anda telah mengonfigurasi fitur yang memungkinkan Anda menandatangani gambar. Gunakan Attester yang Anda buat sebelumnya untuk menandatangani Image Container yang telah Anda gunakan

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
    --format='get(image_summary.digest)')

Sekarang, Anda dapat menggunakan gcloud untuk membuat pengesahan. Perintah ini hanya mengambil detail kunci yang ingin Anda gunakan untuk penandatanganan, dan image penampung tertentu yang ingin Anda setujui

gcloud beta container binauthz attestations sign-and-create  \
    --artifact-url="${CONTAINER_PATH}@${DIGEST}" \
    --attestor="${ATTESTOR_ID}" \
    --attestor-project="${PROJECT_ID}" \
    --keyversion-project="${PROJECT_ID}" \
    --keyversion-location="${KEY_LOCATION}" \
    --keyversion-keyring="${KEYRING}" \
    --keyversion-key="${KEY_NAME}" \
    --keyversion="${KEY_VERSION}"

Dalam istilah Analisis Penampung, tindakan ini akan membuat kemunculan baru, dan melampirkan ke catatan penguji keaslian Anda. Untuk memastikan semuanya berfungsi seperti yang diharapkan, Anda dapat mencantumkan pengesahan

gcloud container binauthz attestations list \
   --attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}

7. Menandatangani dengan Cloud Build

Anda telah mengaktifkan penandatanganan Gambar dan menggunakan Attester secara manual untuk menandatangani gambar contoh. Dalam praktiknya, Anda sebaiknya menerapkan Attestation selama proses otomatis seperti pipeline CI/CD.

Di bagian ini, Anda akan mengonfigurasi Cloud Build untuk melakukan Attestasi image secara otomatis

Peran

Tambahkan peran Binary Authorization Attestor Viewer ke Akun Layanan Cloud Build:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/binaryauthorization.attestorsViewer

Tambahkan peran Cloud KMS CryptoKey Signer/Verifier ke Akun Layanan Cloud Build (Penandatanganan berbasis KMS):

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/cloudkms.signerVerifier

Tambahkan peran Container Analysis Notes Attacher ke Akun Layanan Cloud Build:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/containeranalysis.notes.attacher

Menyiapkan Langkah Cloud Build Build Kustom

Anda akan menggunakan langkah Build Kustom di Cloud Build untuk menyederhanakan proses pengesahan. Google menyediakan langkah Build Kustom ini yang berisi fungsi bantuan untuk menyederhanakan proses. Sebelum digunakan, kode untuk langkah build kustom harus di-build ke dalam penampung dan di-push ke Cloud Build. Untuk melakukannya, jalankan perintah berikut:

git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community

Menambahkan langkah penandatanganan ke cloudbuild.yaml

Pada langkah ini, Anda akan menambahkan langkah pengesahan ke pipeline Cloud Build yang telah Anda buat sebelumnya.

  1. Tinjau langkah baru yang akan Anda tambahkan.

Hanya tinjau. Jangan Salin

#Sign the image only if the previous severity check passes
- id: 'create-attestation'
  name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
  args:
    - '--artifact-url'
    - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image'
    - '--attestor'
    - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
    - '--keyversion'
    - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
  1. Ganti file cloudbuild.yaml dengan pipeline lengkap yang telah diperbarui.
cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#pushing to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#Sign the image only if the previous severity check passes
- id: 'create-attestation'
  name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
  args:
    - '--artifact-url'
    - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
    - '--attestor'
    - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
    - '--keyversion'
    - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'



images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF

Menjalankan Build

gcloud builds submit

Meninjau build di Histori Cloud Build

Buka Konsol Cloud ke halaman Histori Cloud Build dan tinjau build terbaru tersebut serta keberhasilan eksekusi langkah-langkah build.

8. Kebijakan Kontrol Penerimaan

Otorisasi Biner adalah fitur di GKE dan Cloud Run yang memberikan kemampuan untuk memvalidasi aturan sebelum image container diizinkan untuk berjalan. Validasi dijalankan pada setiap permintaan untuk menjalankan image, baik dari pipeline CI/CD tepercaya maupun pengguna yang mencoba men-deploy image secara manual. Kemampuan ini memungkinkan Anda mengamankan lingkungan runtime secara lebih efektif daripada pemeriksaan pipeline CI/CD saja.

Untuk memahami kemampuan ini, Anda akan mengubah kebijakan GKE default untuk menerapkan aturan otorisasi yang ketat.

Membuat Cluster GKE

Buat cluster GKE:

gcloud beta container clusters create binauthz \
    --zone us-central1-a  \
    --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE

Izinkan Cloud Build men-deploy ke cluster ini:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/container.developer"

Kebijakan Izinkan Semua

Pertama, verifikasi status kebijakan default dan kemampuan Anda untuk men-deploy gambar apa pun

  1. Meninjau kebijakan yang ada
gcloud container binauthz policy export
  1. Perhatikan bahwa kebijakan penegakan disetel ke ALWAYS_ALLOW

evaluationMode: ALWAYS_ALLOW

  1. Men-deploy Contoh untuk memverifikasi bahwa Anda dapat men-deploy apa pun
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Memverifikasi bahwa deployment berhasil
kubectl get pods

Anda akan melihat output berikut

161db370d99ffb13.png

  1. Hapus deployment
kubectl delete pod hello-server

Kebijakan Tolak Semua

Sekarang perbarui kebijakan untuk melarang semua gambar.

  1. Mengekspor kebijakan saat ini ke file yang dapat diedit
gcloud container binauthz policy export  > policy.yaml
  1. Ubah kebijakan

Di editor teks, ubah evaluationMode dari ALWAYS_ALLOW menjadi ALWAYS_DENY.

edit policy.yaml

File YAML kebijakan akan muncul sebagai berikut:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_DENY
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. Buka Terminal dan terapkan kebijakan baru, lalu tunggu beberapa detik hingga perubahan diterapkan
gcloud container binauthz policy import policy.yaml
  1. Mencoba deployment sampel workload
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Deployment gagal dengan pesan berikut
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule

Kembalikan kebijakan ke izinkan semua

Sebelum melanjutkan ke bagian berikutnya, pastikan untuk mengembalikan perubahan kebijakan

  1. Ubah kebijakan

Di editor teks, ubah evaluationMode dari ALWAYS_DENY menjadi ALWAYS_ALLOW.

edit policy.yaml

File YAML kebijakan akan muncul sebagai berikut:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. Menerapkan kebijakan yang dikembalikan
gcloud container binauthz policy import policy.yaml

9. Memblokir Kerentanan di GKE

Di bagian ini, Anda akan menggabungkan hal-hal yang telah Anda pelajari sejauh ini dengan menerapkan pipeline CI/CD dengan Cloud Build yang memindai gambar, lalu memeriksa kerentanan sebelum menandatangani gambar dan mencoba men-deploy. GKE akan menggunakan Otorisasi Biner untuk memvalidasi bahwa image memiliki tanda tangan dari Pemindaian kerentanan sebelum mengizinkan image berjalan.

d5c41bb89e22fd61.png

Memperbarui Kebijakan GKE untuk Mewajibkan Pengesahan

Mewajibkan image ditandatangani oleh Pengesah dengan menambahkan clusterAdmissionRules ke Kebijakan BinAuth GKE

Ganti kebijakan dengan konfigurasi yang diperbarui menggunakan perintah di bawah.

COMPUTE_ZONE=us-central1-a

cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
  evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
  ${COMPUTE_ZONE}.binauthz:
    evaluationMode: REQUIRE_ATTESTATION
    enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
    requireAttestationsBy:
    - projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM

Menerapkan kebijakan

gcloud beta container binauthz policy import binauth_policy.yaml

Mencoba men-deploy image yang tidak ditandatangani

Buat deskripsi deployment untuk aplikasi yang Anda build sebelumnya menggunakan perintah berikut. Image yang digunakan di sini adalah image yang Anda build sebelumnya yang berisi kerentanan kritis dan TIDAK berisi pengesahan yang ditandatangani.

Pengontrol akses GKE perlu mengetahui image yang tepat untuk di-deploy agar dapat memvalidasi tanda tangan secara konsisten. Untuk melakukannya, Anda harus menggunakan ringkasan gambar dan tag sederhana.

Mendapatkan ringkasan image untuk gambar yang buruk

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image


DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
    --format='get(image_summary.digest)')

Menggunakan ringkasan dalam konfigurasi Kubernetes

cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
  name: deb-httpd
spec:
  selector:
    app: deb-httpd
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deb-httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deb-httpd
  template:
    metadata:
      labels:
        app: deb-httpd
    spec:
      containers:
      - name: deb-httpd
        image: ${CONTAINER_PATH}@${DIGEST}
        ports:
        - containerPort: 8080
        env:
          - name: PORT
            value: "8080"

EOM

Mencoba men-deploy aplikasi ke GKE

kubectl apply -f deploy.yaml

Tinjau workload di konsol dan perhatikan error yang menyatakan bahwa deployment ditolak:

No attestations found that were valid and signed by a key trusted by the attestor

Men-deploy image yang ditandatangani

Mendapatkan ringkasan image untuk gambar yang buruk

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image


DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
    --format='get(image_summary.digest)')

Menggunakan ringkasan dalam konfigurasi Kubernetes

cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
  name: deb-httpd
spec:
  selector:
    app: deb-httpd
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deb-httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deb-httpd
  template:
    metadata:
      labels:
        app: deb-httpd
    spec:
      containers:
      - name: deb-httpd
        image: ${CONTAINER_PATH}@${DIGEST}
        ports:
        - containerPort: 8080
        env:
          - name: PORT
            value: "8080"

EOM

Men-deploy aplikasi ke GKE

kubectl apply -f deploy.yaml

Tinjau beban kerja di konsol dan perhatikan deployment image yang berhasil.

10. Selamat!

Selamat, Anda telah menyelesaikan codelab!

Yang telah kita bahas:

  • Cara mengaktifkan pemindaian otomatis
  • Cara melakukan Pemindaian On-Demand
  • Cara mengintegrasikan pemindaian dalam pipeline build
  • Cara menandatangani gambar yang disetujui
  • Cara menggunakan pengontrol Penerimaan GKE untuk memblokir image
  • Cara mengonfigurasi GKE agar hanya mengizinkan image yang disetujui dan ditandatangani

Langkah berikutnya:

Pembersihan

Agar tidak dikenai biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus project

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