1. Введение
Container Analysis предоставляет инструменты для сканирования уязвимостей и хранения метаданных для контейнеров. Сервис сканирования выполняет проверку на уязвимости образов в Artifact Registry и Container Registry, затем сохраняет полученные метаданные и делает их доступными для использования через API. Хранение метаданных позволяет сохранять информацию из различных источников, включая сканирование уязвимостей, сервисы Google Cloud и сторонних поставщиков.
Сканирование на уязвимости может происходить автоматически или по запросу:
- При включении автоматического сканирования оно запускается автоматически каждый раз, когда вы загружаете новый образ в реестр артефактов или реестр контейнеров. Информация об уязвимостях постоянно обновляется при обнаружении новых уязвимостей.
- При включении сканирования по запросу необходимо выполнить команду для сканирования локального образа или образа в реестре артефактов или реестре контейнеров. Сканирование по запросу обеспечивает гибкость в выборе времени сканирования контейнеров. Например, вы можете просканировать локально собранный образ и устранить уязвимости перед его сохранением в реестре. Результаты сканирования доступны в течение 48 часов после завершения сканирования, и информация об уязвимостях не обновляется после завершения сканирования.
Благодаря интеграции анализа контейнеров в ваш конвейер CI/CD, вы можете принимать решения на основе этих метаданных. Например, вы можете использовать авторизацию бинарных файлов для создания политик развертывания, которые разрешают развертывание только для совместимых образов из доверенных реестров.
Что вы узнаете
- Как включить автоматическое сканирование
- Как выполнить сканирование по запросу
- Как интегрировать сканирование в конвейер сборки
- Как подписать утвержденные изображения
- Как использовать контроллеры допуска GKE для блокировки изображений
- Как настроить GKE, чтобы разрешать только подписанные и одобренные изображения.
2. Настройка и требования
Настройка среды для самостоятельного обучения
- Войдите в консоль Google Cloud и создайте новый проект или используйте существующий. Если у вас еще нет учетной записи Gmail или Google Workspace, вам необходимо ее создать .



- Название проекта — это отображаемое имя участников данного проекта. Это строка символов, не используемая API Google. Вы можете изменить её в любое время.
- Идентификатор проекта уникален для всех проектов Google Cloud и является неизменяемым (его нельзя изменить после установки). Консоль Cloud автоматически генерирует уникальную строку; обычно вам неважно, какая она. В большинстве практических заданий вам потребуется указать идентификатор проекта (обычно он обозначается как
PROJECT_ID). Если сгенерированный идентификатор вас не устраивает, вы можете сгенерировать другой случайный идентификатор. В качестве альтернативы вы можете попробовать свой собственный и посмотреть, доступен ли он. После этого шага его нельзя изменить, и он останется неизменным на протяжении всего проекта. - К вашему сведению, существует третье значение — номер проекта , который используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .
- Далее вам потребуется включить оплату в консоли Cloud для использования ресурсов/API Cloud. Выполнение этого практического задания не должно стоить дорого, если вообще что-либо. Чтобы отключить ресурсы и избежать дополнительных расходов после завершения этого урока, вы можете удалить созданные ресурсы или удалить весь проект. Новые пользователи Google Cloud имеют право на бесплатную пробную версию стоимостью 300 долларов США .
Запустить редактор Cloudshell
Данная лабораторная работа разработана и протестирована для использования с редактором Google Cloud Shell. Для доступа к редактору,
- Получите доступ к своему проекту Google по адресу https://console.cloud.google.com .
- В правом верхнем углу нажмите на значок редактора облачной оболочки.

- В нижней части вашего окна откроется новое окно.
Настройка среды
В Cloud Shell укажите идентификатор проекта и номер проекта. Сохраните их как переменные PROJECT_ID и PROJECT_ID .
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
Включить службы
Включите все необходимые службы:
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
Создать репозиторий реестра артефактов
В этой лабораторной работе вы будете использовать Artifact Registry для хранения и сканирования изображений. Создайте репозиторий с помощью следующей команды.
gcloud artifacts repositories create artifact-scanning-repo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
Настройте Docker для использования ваших учетных данных gcloud при доступе к реестру артефактов.
gcloud auth configure-docker us-central1-docker.pkg.dev
3. Автоматическое сканирование
Сканирование артефактов запускается автоматически каждый раз, когда вы загружаете новый образ в реестр артефактов или реестр контейнеров. Информация об уязвимостях постоянно обновляется по мере обнаружения новых уязвимостей. В этом разделе вы загрузите образ в реестр артефактов и изучите результаты.
Создайте и перейдите в рабочую директорию.
mkdir vuln-scan && cd vuln-scan
Определите пример изображения
Создайте файл с именем Dockerfile со следующим содержимым.
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
Создайте файл с именем main.py со следующим содержимым.
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
Создайте и загрузите изображение в AR.
Используйте Cloud Build для сборки и автоматической отправки вашего контейнера в Artifact Registry. Обратите внимание на метку bad на образе. Это поможет вам идентифицировать его на последующих этапах.
gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad
Просмотреть подробности изображения
После завершения процесса сборки просмотрите образ и результаты поиска уязвимостей на панели мониторинга Реестра артефактов.
- Откройте реестр артефактов в облачной консоли.
- Нажмите на ссылку artifact-scanning-repo, чтобы просмотреть содержимое.
- Нажмите на подробности изображения
- Перейдите по ссылке, чтобы просмотреть последнюю версию вашего изображения.
- После завершения сканирования перейдите на вкладку «Уязвимости» для изображения.
На вкладке «Уязвимости» вы увидите результаты автоматического сканирования только что созданного вами образа.

Автоматическое сканирование включено по умолчанию. Чтобы узнать, как включить/выключить автоматическое сканирование, ознакомьтесь с настройками реестра артефактов.
4. Сканирование по запросу
Существует множество сценариев, когда перед загрузкой образа в репозиторий может потребоваться выполнить сканирование. Например, разработчик контейнеров может просканировать образ и исправить проблемы, прежде чем загрузить код в систему контроля версий. В приведенном ниже примере вы соберете и проанализируете образ локально, прежде чем применять полученные результаты.
Создать образ
На этом этапе вы будете использовать локальный Docker для сборки образа в локальном кэше.
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image .
Отсканируйте изображение
После создания образа запросите его сканирование. Результаты сканирования сохраняются на сервере метаданных. Задание завершается указанием местоположения результатов на сервере метаданных.
gcloud artifacts docker images scan \
us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
--format="value(response.scan)" > scan_id.txt
Проверка выходного файла
Уделите немного времени, чтобы просмотреть результаты предыдущего шага, которые были сохранены в файле scan_id.txt. Обратите внимание на местоположение отчета с результатами сканирования на сервере метаданных.
cat scan_id.txt
Просмотрите подробные результаты сканирования.
Для просмотра фактических результатов сканирования используйте команду list-vulnerabilities , указав местоположение отчета в выходном файле.
gcloud artifacts docker images list-vulnerabilities $(cat scan_id.txt)
В выходных данных содержится значительный объем информации обо всех уязвимостях в изображении.
Отметить критические проблемы
Люди редко используют данные, хранящиеся в отчете, напрямую. Как правило, результаты используются автоматизированным процессом. Используйте приведенные ниже команды, чтобы прочитать подробности отчета и зарегистрировать обнаруженные критические уязвимости.
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
Результатом выполнения этой команды будет следующее:
Failed vulnerability check for CRITICAL level
5. Создание конвейера сканирования
В этом разделе вы создадите автоматизированный конвейер сборки, который соберет образ вашего контейнера, просканирует его и оценит результаты. Если критических уязвимостей не будет обнаружено, образ будет отправлен в репозиторий. Если будут обнаружены критические уязвимости, сборка завершится с ошибкой.
Предоставить доступ для учетной записи службы Cloud Build.
Для доступа к API сканирования по запросу Cloud Build потребуются права. Предоставьте доступ с помощью следующих команд.
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"
Создайте конвейер Cloud Build.
Следующая команда создаст в вашем каталоге файл cloudbuild.yaml, который будет использоваться для автоматизированного процесса. В этом примере шаги ограничены процессом сборки контейнера. Однако на практике, помимо шагов, связанных с контейнером, вам следует включить инструкции и тесты, специфичные для конкретного приложения.
Создайте файл с помощью следующей команды.
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
Запустите конвейер CI.
Отправьте сборку на обработку, чтобы убедиться, что сборка прерывается при обнаружении уязвимости критического уровня.
gcloud builds submit
Проверка ошибки сборки
Отправленная вами сборка завершится неудачей, поскольку образ содержит КРИТИЧЕСКИЕ уязвимости.
Просмотрите информацию о сбое сборки на странице «История сборок в облаке» .
Устраните уязвимость
Обновите Dockerfile, чтобы использовать базовый образ, не содержащий критических уязвимостей.
Для использования образа Debian 10 замените файл Dockerfile, выполнив следующую команду.
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
Запустите процесс CI с корректным образом.
Отправьте сборку на обработку, чтобы убедиться в ее успешном завершении, если не будут обнаружены уязвимости критического уровня.
gcloud builds submit
Обзор успешной сборки
Отправленная вами сборка будет успешно завершена, поскольку обновленный образ не содержит критических уязвимостей.
Просмотрите информацию об успешном завершении сборки на странице « История сборок в облаке» .
Просмотрите результаты сканирования.
Проверьте корректность изображения в реестре артефактов.
- Откройте реестр артефактов в облачной консоли.
- Нажмите на ссылку artifact-scanning-repo, чтобы просмотреть содержимое.
- Нажмите на подробности изображения
- Перейдите по ссылке, чтобы просмотреть последнюю версию вашего изображения.
- Нажмите на вкладку «Уязвимости», чтобы увидеть изображение.
6. Фотографии с автографами
Создать примечание аттестатора
Заметка аттестатора — это просто небольшой фрагмент данных, который служит обозначением типа применяемой подписи. Например, одна заметка может указывать на сканирование уязвимостей, а другая — на подтверждение качества. На эту заметку будут ссылаться в процессе подписания.
Создать заметку
cat > ./vulnz_note.json << EOM
{
"attestation": {
"hint": {
"human_readable_name": "Container Vulnerabilities attestation authority"
}
}
}
EOM
Сохраните записку
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}"
Проверьте записку.
curl -vvv \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
Создание аттестатора
Аттестаторы используются для выполнения фактического процесса подписания изображения и прикрепляют к изображению экземпляр заметки для последующей проверки. Создайте аттестатора для последующего использования.
Создать аттестатора
ATTESTOR_ID=vulnz-attestor
gcloud container binauthz attestors create $ATTESTOR_ID \
--attestation-authority-note=$NOTE_ID \
--attestation-authority-note-project=${PROJECT_ID}
Подтверждение подлинности аттестатора
gcloud container binauthz attestors list
Обратите внимание, что в последней строке указано NUM_PUBLIC_KEYS: 0 ключи будут указаны на более позднем этапе.
Также обратите внимание, что Cloud Build автоматически создает аттестатор built-by-cloud-build в вашем проекте при запуске сборки, генерирующей образы. Таким образом, приведенная выше команда возвращает два аттестатора: vulnz-attestor и built-by-cloud-build . После успешной сборки образов Cloud Build автоматически подписывает их и создает для них аттестации.
Добавление роли IAM
Для просмотра примечаний к аттестации учетной записи службы Binary Authorization потребуются права доступа. Предоставьте доступ с помощью следующего вызова API.
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
Используйте этот файл для создания политики 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"
Добавление ключа KMS
Аттестатору необходимы криптографические ключи для прикрепления заметки и предоставления проверяемых подписей. На этом этапе вы создадите и сохраните ключи в KMS для последующего доступа к ним через Cloud Build.
Сначала добавьте несколько переменных окружения для описания нового ключа.
KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1
Создайте брелок для ключей.
gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"
Создайте новую пару асимметричных ключей подписи для аттестатора.
gcloud kms keys create "${KEY_NAME}" \
--keyring="${KEYRING}" --location="${KEY_LOCATION}" \
--purpose asymmetric-signing \
--default-algorithm="ec-sign-p256-sha256"
Ваш ключ должен отобразиться на странице KMS в консоли Google Cloud.
Теперь свяжите ключ с вашим аттестатором с помощью команды 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}"
Если вы снова распечатаете список полномочий, то увидите зарегистрированный ключ:
gcloud container binauthz attestors list
Создание подписанного подтверждения
На этом этапе у вас настроены функции, позволяющие подписывать образы. Используйте созданный ранее аттестатор для подписи образа контейнера, с которым вы работали.
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)')
Теперь вы можете использовать gcloud для создания аттестации. Команда просто принимает данные ключа, который вы хотите использовать для подписи, и конкретный образ контейнера, который вы хотите утвердить.
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}"
В терминах анализа контейнеров это создаст новое событие и прикрепит его к заметке вашего аттестатора. Чтобы убедиться, что все сработало как ожидалось, вы можете перечислить свои аттестации.
gcloud container binauthz attestations list \
--attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}
7. Подписание с помощью Cloud Build
Вы включили подписание образов и вручную использовали аттестатор для подписи вашего тестового образа. На практике вам потребуется применять аттестации в автоматизированных процессах, таких как конвейеры CI/CD.
В этом разделе вы настроите Cloud Build для автоматической проверки образов.
Роли
Добавьте роль «Просмотрщик двоичных данных для авторизации» в учетную запись службы Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/binaryauthorization.attestorsViewer
Добавьте роль Cloud KMS CryptoKey Signer/Verifier в учетную запись службы Cloud Build (подписание на основе KMS):
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/cloudkms.signerVerifier
Добавьте роль "Участник примечаний анализа контейнеров" в учетную запись службы Cloud Build:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
--role roles/containeranalysis.notes.attacher
Подготовка к этапу сборки пользовательского облака
Для упрощения процесса аттестации в Cloud Build вы будете использовать шаг пользовательской сборки. Google предоставляет этот шаг пользовательской сборки, который содержит вспомогательные функции для оптимизации процесса. Перед использованием код для шага пользовательской сборки необходимо скомпилировать в контейнер и отправить в Cloud Build. Для этого выполните следующие команды:
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
Добавьте этап подписания в файл cloudbuild.yaml.
На этом шаге вы добавите этап аттестации в созданный ранее конвейер Cloud Build.
- Проверьте новый шаг, который вы собираетесь добавить.
Только для ознакомления. Копирование запрещено.
#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'
- Замените файл cloudbuild.yaml обновленным полным конвейером сборки.
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
Запустите сборку
gcloud builds submit
Просмотрите историю сборок в Cloud Build History.
Откройте консоль Cloud Console на странице «История сборок Cloud Build» и просмотрите последнюю сборку, а также успешное выполнение шагов сборки.
8. Правила приема
Бинарная авторизация — это функция GKE и Cloud Run, которая позволяет проверять правила перед запуском образа контейнера. Проверка выполняется при каждом запросе на запуск образа, будь то запрос из доверенного конвейера CI/CD или от пользователя, пытающегося развернуть образ вручную. Эта возможность позволяет более эффективно защитить среду выполнения, чем просто проверки с помощью конвейеров CI/CD.
Чтобы понять эту возможность, вам потребуется изменить политику GKE по умолчанию, чтобы обеспечить применение строгих правил авторизации.
Создайте кластер GKE.
Создайте кластер GKE:
gcloud beta container clusters create binauthz \
--zone us-central1-a \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
Разрешите Cloud Build развертывать приложения в этом кластере:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
--role="roles/container.developer"
Разрешить все политики
Сначала проверьте состояние политики по умолчанию и возможность развертывания любого образа.
- Пересмотрите существующую политику.
gcloud container binauthz policy export
- Обратите внимание, что для параметра принудительного применения установлено значение
ALWAYS_ALLOW
evaluationMode: ALWAYS_ALLOW
- Разверните пример, чтобы убедиться, что вы можете развернуть что угодно.
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Убедитесь, что развертывание прошло успешно.
kubectl get pods
Вы увидите следующий результат.

- Удалить развертывание
kubectl delete pod hello-server
Политика «Отказать во всем»
Теперь обновите политику, чтобы запретить все изображения.
- Экспортируйте текущую политику в редактируемый файл.
gcloud container binauthz policy export > policy.yaml
- Изменить политику
В текстовом редакторе измените параметр evaluationMode с ALWAYS_ALLOW на ALWAYS_DENY .
edit policy.yaml
Файл политики в формате YAML должен выглядеть следующим образом:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_DENY enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Откройте Терминал, примените новую политику и подождите несколько секунд, пока изменения вступят в силу.
gcloud container binauthz policy import policy.yaml
- Попытка развертывания тестовой рабочей нагрузки
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
- Развертывание завершается с ошибкой, выдавая следующее сообщение.
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
Восстановить политику, разрешив все.
Прежде чем перейти к следующему разделу, обязательно отмените изменения в политике.
- Изменить политику
В текстовом редакторе измените параметр evaluationMode с ALWAYS_DENY на ALWAYS_ALLOW .
edit policy.yaml
Файл политики в формате YAML должен выглядеть следующим образом:
globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: ALWAYS_ALLOW enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG name: projects/PROJECT_ID/policy
- Примените отмененную политику.
gcloud container binauthz policy import policy.yaml
9. Блокировка уязвимостей в GKE
В этом разделе вы объедините полученные знания, реализовав конвейер CI/CD с использованием Cloud Build, который сканирует образы, затем проверяет их на наличие уязвимостей, прежде чем подписать образ и попытаться развернуть его. GKE будет использовать авторизацию бинарных файлов для проверки наличия подписи образа по результатам сканирования на уязвимости, прежде чем разрешить его запуск.

Обновить политику GKE, чтобы она требовала подтверждения подлинности.
Для того чтобы изображения были подписаны вашим аттестатором, добавьте параметр clusterAdmissionRules в политику GKE BinAuth.
Перезапишите политику обновленной конфигурацией, используя приведенную ниже команду.
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
Примените политику
gcloud beta container binauthz policy import binauth_policy.yaml
Попытка развертывания неподписанного образа.
Создайте дескриптор развертывания для приложения, которое вы создали ранее, используя следующую команду. Здесь используется образ, который вы создали ранее, содержащий критические уязвимости и НЕ содержащий подписанную аттестацию.
Контроллерам допуска GKE необходимо знать точный образ, который нужно развернуть, чтобы обеспечить согласованную проверку подписи. Для этого потребуется использовать дайджест образа, а не простой тег.
Получите дайджест изображения для некорректного изображения.
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)')
Используйте дайджест в конфигурации 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
Попытка развертывания приложения в GKE.
kubectl apply -f deploy.yaml
Просмотрите данные о нагрузке в консоли и обратите внимание на ошибку, указывающую на отказ в развертывании:
No attestations found that were valid and signed by a key trusted by the attestor
Развернуть подписанный образ
Получите дайджест изображения для некорректного изображения.
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)')
Используйте дайджест в конфигурации 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
Разверните приложение в GKE.
kubectl apply -f deploy.yaml
Просмотрите данные о рабочей нагрузке в консоли и отметьте успешное развертывание образа.
10. Поздравляем!
Поздравляем, вы завершили практическое занятие!
Что мы рассмотрели:
- Как включить автоматическое сканирование
- Как выполнить сканирование по запросу
- Как интегрировать сканирование в конвейер сборки
- Как подписать утвержденные изображения
- Как использовать контроллеры допуска GKE для блокировки изображений
- Как настроить GKE, чтобы разрешать только подписанные и одобренные изображения.
Что дальше:
- Обеспечение безопасности развертывания образов в Cloud Run и Google Kubernetes Engine | Документация Cloud Build
- Быстрый старт: Настройка политики бинарной авторизации с помощью GKE | Google Cloud
Уборка
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, используемые в этом руководстве, либо удалите проект, содержащий эти ресурсы, либо сохраните проект и удалите отдельные ресурсы.
Удаление проекта
Самый простой способ избежать выставления счетов — удалить проект, созданный для этого урока.