Google cloud 的 Binary Authorization 可以帮助用户在部署 container 时采用信任的 image。可以通过配置信任的 repository,也可以通过 Key 认证的方式实现 image 的认证。


本文将介绍,如何采用 Binary Authorization 实现容器的 Image 的安全部署。


一 创建相关服务


1、开启相关的 API


首先打开 cloud shell,在 cloud shell 中检查相关的配置:


hengwei@cloudshell:~ (wh-service01)$ gcloud config list[component_manager]disable_update_check = True[compute]gce_metadata_read_timeout_sec = 5[core]account = hengwei@google.comdisable_usage_reporting = Falseproject = wh-service01[metrics]environment = devshell
复制代码


定义参数:


PROJECT_ID=wh-service01echo $PROJECT_IDWh-service01ZONE=us-central1-aecho $ZONEus-central1-a
复制代码


开启 API:


gcloud services enable >     container.googleapis.com>     containeranalysis.googleapis.com>     binaryauthorization.googleapis.comOperation "operations/acf.0587658c-ebed-42a4-ac53-5f68b3b3bb3f" finished successfully.
复制代码


可以看到,此时 Binary Authorization 的 API 已经 enable 了:



2、创建 GKE cluster


采用命令行模式创建 GKE Cluster:


gcloud container clusters create --enable-binauthz --zone $ZONE gkecluster01NAME          LOCATION       MASTER_VERSION  MASTER_IPgkecluster01  us-central1-a  1.13.11-gke.23  35.222.79.234 MACHINE_TYPE   NODE_VERSION    NUM_NODES  STATUSn1-standard-1  1.13.11-gke.23  3          RUNNINGgcloud container clusters get-credentials --zone $ZONE gkecluster01Fetching cluster endpoint and auth data.kubeconfig entry generated for gkecluster01.kubectl get nodeNAME                                          STATUS   ROLES    AGE   VERSIONgke-gkecluster01-default-pool-5ecb124a-520n   Ready    <none>   15m   v1.13.11-gke.23gke-gkecluster01-default-pool-5ecb124a-b314   Ready    <none>   16m   v1.13.11-gke.23gke-gkecluster01-default-pool-5ecb124a-vn7p   Ready    <none>   15m   v1.13.11-gke.23
复制代码


3、创建 Container Image


查看 Binauthz 的策略:


gcloud container binauthz policy exportadmissionWhitelistPatterns:- namePattern: gcr.io/google_containers/*- namePattern: gcr.io/google-containers/*- namePattern: k8s.gcr.io/*- namePattern: gke.gcr.io/*- namePattern: gcr.io/stackdriver-agents/*defaultAdmissionRule:enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOGevaluationMode: ALWAYS_ALLOWname: projects/wh-service01/policy
复制代码


Console 中的配置:



创建 docker image,并 push 到 Google Container Registry(GCR)中。


image 的 Dockerfile:


cat << EOF > DockerfileFROM alpineCMD tail -f /dev/nullEOF
复制代码


Build 和 push:


export CONTAINER_PATH=us.gcr.io/$PROJECT_ID/hello-worlddocker build -t $CONTAINER_PATH ./gcloud auth configure-docker --quietdocker push $CONTAINER_PATH
复制代码


此时可以看到 GCR 中已经有 image 上传上来:



使用这个 image 创建 deployment:


kubectl create deployment hello-world --image=$CONTAINER_PATH
复制代码


可以看到已经创建成功:


kubectl get podNAME                           READY   STATUS    RESTARTS   AGEhello-world-55b45c79cd-bwvgl   1/1     Running   0          13s
复制代码


二 配置 Binary Authorization 策略


根据前文的描述,Binary Authorization 的策略有三种:


  • Allow All Image

  • Disallow All Image

  • Allow only images that have been approved by all the following attestors


我们在第一节中,测试 Allow all image 和 Disallow all image 两个策略,在第二节中,测试 attestor 相关的策略。


1、Binary Authorization Policy


创建 policy.yaml 文件:


cat > ./policy.yaml << EOFglobalPolicyEvaluationMode: ENABLEdefaultAdmissionRule:evaluationMode: ALWAYS_DENYenforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOGEOF
复制代码


可以看到,这里把 Adminission Rule 改成了 Always Deny,除白名单内的 image,是不能创建 pod 的。



部署此策略:


gcloud container binauthz policy import policy.yaml
复制代码


此时中 console 中可以看到策略如下:



重新部署 deployment:


kubectl delete deployment --allkubectl delete event --allkubectl create deployment hello-world --image=$CONTAINER_PATH
复制代码


可以看到,pod 因为 image policy,不能创建:



手工添加白名单:



保存后,deployment 部署成功:



2、Attestor 策略


GKE 的 Binary Authorization 功能通过调用 Container Analysis 功能中的 container image 的 metadata,来确定是否是认证过的 image。具体实现方式如下:



  • 在 Container Analysis 中定义 Note,通过手工或自动的方式在创建 image 时,metadata 中加入数字签名。

  • Binary Authorization 中设置 Attestor,调用 Note,确认 image 的 metadata 中的数字签名。如果数字签名通过,可以把 image 部署到container 中,否则不允许。从而实现对 container Image 的授权。


如下是 container build的pipline:



在 Build/Test 以及 Artifact 阶段实现 Attest:



在部署阶段,实现 enforce:



A 创建 Container Analysis Note


创建 note 配置文件:


cat > ./create_note_request.json << EOM{"attestation": {"hint": {"human_readable_name": "This note represents an attestation authority"}}}EOM
复制代码


创建 note-01:


export NOTE_ID=attestor-note-01curl -vvv -X POST-H "Content-Type: application/json"  -H "Authorization: Bearer $(gcloud auth print-access-token)"  --data-binary @./create_note_request.json  "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
复制代码


查看 note:



B 创建 Attestor


用命令行:


export ATTESTOR_ID=binauthz-attestor-01gcloud container binauthz attestors create $ATTESTOR_ID --attestation-authority-note=$NOTE_ID --attestation-authority-note-project=${PROJECT_ID}
复制代码


查看 Attestor:


gcloud container binauthz attestors list
复制代码



C 添加 key


Enable KMS 服务:


gcloud services enable cloudkms.googleapis.com
复制代码


采用 Google Cloud KMS 创建 Key,并添加到 attestor 中。


创建 Key-ring、Key:


export KEY_LOCATION=globalexport KEYRING=key-ring-01export KEY_NAME=key-01export KEY_VERSION=1gcloud 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"
复制代码


查看 key 的情况:



Attestor 中添加 Key:


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}"
复制代码


此时,Attestor 中添加了 Public Key:



D 对 container Image 进行签名


先获取 Image 对 Digest:


export DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest --format='get(image_summary.digest)')
复制代码


是一串 hash 值:


echo $DIGESTsha256:e4551a5ded95740f0be38b37dbcebac081a9f5c717d223e1998c871d6a8a79dd
复制代码


手工对 Image 进行签名:


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}---attestation:attestation:genericSignedAttestation:contentType: SIMPLE_SIGNING_JSONserializedPayload: ewogICJjc……=signatures:- publicKeyId: //cloudkms.googleapis.com/v1/projects/wh-service01/locations/global/keyRings/key-ring-01/cryptoKeys/key-01/cryptoKeyVersions/1signature: MEUCIQCh_SIeuAoAzuGl7dymtgrFFclJk6EJ-u5Jeg_x3xU2gQIgKFyG__OGBdMVgVC21iIqBIa_ETeHHKJ7MrM0tB7LICo=createTime: '2020-02-04T08:01:19.206181Z'kind: ATTESTATIONname: projects/wh-service01/occurrences/9b462272-33bb-46de-ad6a-61312223cf05noteName: projects/wh-service01/notes/attestor-note-01resource:uri: https://us.gcr.io/wh-service01/hello-world@sha256:e4551a5ded95740f0be38b37dbcebac081a9f5c717d223e1998c871d6a8a79ddupdateTime: '2020-02-04T08:01:19.206181Z'
复制代码


E 更新 Binary Authorization 的策略



将策略改成,只允许 Attestor 方式的 Image。此时 Binary Authorization 的策略如下:



两张模式的 Image 都可以部署到 Container 中。


F 部署 Container


kubectl create deployment hello-world-signed--image="${CONTAINER_PATH}@${DIGEST}"
复制代码


查看部署情况:



三 总结


通过 Google Cloud 的 Binary Authorization,可以方便的对 Container 的 Image 进行管理。可以通过简单的镜像源进行粗略的管理,也可以通过 Attestor的方式对镜像签名进行验证,从而实现相对严格的验证和授权。


相关推荐