1. ภาพรวม
Artifact Registry เป็นเครื่องมือจัดการแพ็กเกจที่มีการจัดการเต็มรูปแบบสำหรับ และมีเครื่องมือแบบรวมเพื่อจัดการอิมเมจคอนเทนเนอร์ OCI และแพ็กเกจภาษา (เช่น Maven และ npm)
Artifact Registry ผสานรวมกับบริการอื่นๆ ของ Google Cloud อย่างเต็มรูปแบบ เช่น ตัวอย่างต่อไปนี้
- Cloud Build สามารถอัปโหลดอาร์ติแฟกต์รูปภาพไปยัง Artifact Registry ได้โดยตรง
- Cloud Deploy สามารถติดตั้งใช้งานอิมเมจ Artifact Registry ไปยังสภาพแวดล้อมรันไทม์ต่างๆ ได้โดยตรง
- โดยจะจัดเตรียมอิมเมจให้กับรันไทม์ของคอนเทนเนอร์ เช่น Cloud Run และ GKE รวมถึงเปิดใช้ความสามารถในการเพิ่มประสิทธิภาพขั้นสูง เช่น การสตรีมมิงอิมเมจ
- Artifact Registry สามารถใช้เป็นจุดตรวจจับสำหรับการวิเคราะห์อาร์ติแฟกต์เพื่อตรวจสอบช่องโหว่ที่ทราบอย่างต่อเนื่อง
- Cloud IAM ช่วยให้ควบคุมสิทธิ์เข้าถึงและสิทธิ์ของอาร์ติแฟกต์ได้อย่างละเอียดและสอดคล้องกัน
ห้องทดลองนี้จะแนะนำฟีเจอร์เหล่านี้หลายอย่างในรูปแบบของบทแนะนำแบบลงมือปฏิบัติ
สิ่งที่คุณจะได้เรียนรู้
วัตถุประสงค์การเรียนรู้ของแล็บนี้คืออะไร
- สร้างที่เก็บที่แตกต่างกันสำหรับคอนเทนเนอร์และแพ็กเกจภาษา
- สร้างและใช้อิมเมจคอนเทนเนอร์กับ Artifact Registry
- ใช้ Artifact Registry เพื่อวิเคราะห์ท่าทางด้านความปลอดภัยและเนื้อหาของอาร์ติแฟกต์
- กำหนดค่าและใช้ Artifact Registry สำหรับทรัพยากร Dependency ของ Java Maven
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง
- ลงชื่อเข้าใช้ Google Cloud Console แล้วสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี



- ชื่อโปรเจ็กต์คือชื่อที่แสดงสำหรับผู้เข้าร่วมโปรเจ็กต์นี้ ซึ่งเป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ คุณอัปเดตได้ทุกเมื่อ
- รหัสโปรเจ็กต์จะไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมดและเปลี่ยนแปลงไม่ได้ (เปลี่ยนไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ ซึ่งโดยปกติแล้วคุณไม่จำเป็นต้องสนใจว่าสตริงนั้นคืออะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยทั่วไปจะระบุเป็น
PROJECT_ID) หากไม่ชอบรหัสที่สร้างขึ้น คุณอาจสร้างรหัสแบบสุ่มอีกรหัสหนึ่งได้ หรือคุณอาจลองใช้ชื่อของคุณเองและดูว่ามีชื่อนั้นหรือไม่ คุณจะเปลี่ยนแปลงรหัสนี้หลังจากขั้นตอนนี้ไม่ได้ และรหัสจะคงอยู่ตลอดระยะเวลาของโปรเจ็กต์ - โปรดทราบว่ายังมีค่าที่ 3 ซึ่งคือหมายเลขโปรเจ็กต์ที่ API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 นี้ได้ในเอกสารประกอบ
- จากนั้นคุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของ Cloud การทำตาม Codelab นี้จะไม่มีค่าใช้จ่ายมากนัก หรืออาจไม่มีค่าใช้จ่ายเลย หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินนอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่สร้างขึ้นหรือลบโปรเจ็กต์ได้ ผู้ใช้ Google Cloud รายใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรีมูลค่า$300 USD
ตั้งค่า gcloud
ใน Cloud Shell ให้ตั้งค่ารหัสโปรเจ็กต์และหมายเลขโปรเจ็กต์ บันทึกเป็นตัวแปร PROJECT_ID และ PROJECT_NUMBER
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
เปิดใช้บริการของ Google
gcloud services enable \
cloudresourcemanager.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
containerregistry.googleapis.com \
containerscanning.googleapis.com \
binaryauthorization.googleapis.com \
cloudbuild.googleapis.com
รับซอร์สโค้ด
ซอร์สโค้ดสำหรับแล็บนี้อยู่ในองค์กร GoogleCloudPlatform บน GitHub โคลนด้วยคำสั่งด้านล่าง
git clone https://github.com/GoogleCloudPlatform/java-docs-samples
3. การพุชอิมเมจคอนเทนเนอร์
สร้างที่เก็บ Docker ใน Artifact Registry
ดังที่กล่าวไว้ก่อนหน้านี้ Artifact Registry รองรับรูปแบบที่เก็บที่แตกต่างกัน ซึ่งช่วยให้คุณจัดการอิมเมจคอนเทนเนอร์และแพ็กเกจภาษาได้ การโต้ตอบกับที่เก็บที่แตกต่างกันของอาร์ติแฟกต์ประเภทต่างๆ จะกำหนดไว้ในข้อกำหนดและเป็นมาตรฐานที่ใช้กันอย่างแพร่หลาย เช่น คำขอสำหรับทรัพยากร Dependency ของ Maven จะแตกต่างจากคำขอสำหรับทรัพยากร Dependency ของ Node
Artifact Registry ต้องจัดการอาร์ติแฟกต์ในประเภทที่เก็บที่เกี่ยวข้องเพื่อรองรับข้อกำหนดเฉพาะของ API อาร์ติแฟกต์ เมื่อสร้างที่เก็บใหม่ คุณจะส่งแฟล็ก --repository-format เพื่อระบุประเภทของที่เก็บ
หากต้องการสร้างที่เก็บแรกสำหรับอิมเมจ Docker ให้เรียกใช้คำสั่งต่อไปนี้จาก Cloud Shell
gcloud artifacts repositories create container-example --repository-format=docker \
--location=us-central1 --description="Example Docker repository"
คลิก "ให้สิทธิ์" หากข้อความแจ้งการให้สิทธิ์ Cloud Shell ปรากฏขึ้น
ไปที่ Google Cloud Console - Artifact Registry - ที่เก็บ แล้วสังเกตที่เก็บ Docker ที่สร้างขึ้นใหม่ชื่อ container-example หากคลิกที่ที่เก็บดังกล่าว คุณจะเห็นว่าที่เก็บนั้นว่างเปล่าในขณะนี้

กำหนดค่าการตรวจสอบสิทธิ์ Docker ไปยัง Artifact Registry
เมื่อเชื่อมต่อกับ Artifact Registry คุณจะต้องระบุข้อมูลเข้าสู่ระบบเพื่อมอบสิทธิ์เข้าถึง คุณสามารถกำหนดค่า Docker ให้ใช้ข้อมูลเข้าสู่ระบบ gcloud ได้อย่างราบรื่นแทนที่จะตั้งค่าข้อมูลเข้าสู่ระบบแยกต่างหาก
จาก Cloud Shell ให้เรียกใช้คำสั่งต่อไปนี้เพื่อกำหนดค่า Docker ให้ใช้ Google Cloud CLI เพื่อตรวจสอบสิทธิ์คำขอไปยัง Artifact Registry ในภูมิภาค us-central1
gcloud auth configure-docker us-central1-docker.pkg.dev
หากคำสั่งแจ้งให้ยืนยันการเปลี่ยนการกำหนดค่า Docker ของ Cloud Shell ให้กด Enter
สำรวจแอปพลิเคชันตัวอย่าง
เรามีแอปพลิเคชันตัวอย่างในที่เก็บ Git ที่คุณโคลนไว้ในขั้นตอนก่อนหน้า เปลี่ยนเป็นไดเรกทอรี java แล้วตรวจสอบโค้ดแอปพลิเคชัน
cd java-docs-samples/run/helloworld/
ls
โฟลเดอร์นี้มีแอปพลิเคชัน Java ตัวอย่างที่แสดงหน้าเว็บอย่างง่าย นอกจากไฟล์ต่างๆ ที่ไม่เกี่ยวข้องกับแล็บนี้แล้ว ยังมีซอร์สโค้ดในโฟลเดอร์ src และ Dockerfile ที่เราจะใช้เพื่อสร้างอิมเมจคอนเทนเนอร์
สร้างอิมเมจคอนเทนเนอร์
คุณจะต้องสร้างที่เก็บก่อนจึงจะจัดเก็บอิมเมจคอนเทนเนอร์ใน Artifact Registry ได้
เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างอิมเมจคอนเทนเนอร์และติดแท็กด้วยเส้นทาง Artifact Registry แบบเต็ม
docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:tag1 .
พุชอิมเมจคอนเทนเนอร์ไปยัง Artifact Registry
เรียกใช้คำสั่งต่อไปนี้เพื่อพุชอิมเมจคอนเทนเนอร์ไปยังที่เก็บที่สร้างไว้ก่อนหน้านี้
docker push us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:tag1
ตรวจสอบอิมเมจใน Artifact Registry
ไปที่ Cloud Console - Artifact Registry - ที่เก็บ ของ Google. เปิดที่เก็บ container-example แล้วตรวจสอบว่ามีอิมเมจ java-hello-world อยู่

คลิกรูปภาพและจดบันทึกรูปภาพที่ติดแท็ก tag1 เนื่องจากเราเปิดใช้การสแกนรูปภาพอัตโนมัติผ่านบริการ containerscanning.googleapis.com คุณจึงเห็นว่าการสแกนช่องโหว่กำลังทำงานอยู่หรือเสร็จสมบูรณ์แล้ว เมื่อเสร็จแล้ว คุณจะเห็นจำนวนช่องโหว่ที่ตรวจพบสำหรับการแก้ไขอิมเมจนี้ เราจะมาดูช่องโหว่และข้อมูลเชิงลึกอื่นๆ ของอาร์ติแฟกต์ในส่วนถัดไป

4. การตรวจสอบอิมเมจคอนเทนเนอร์
ตอนนี้คุณได้พุชอิมเมจแรกไปยังที่เก็บ container-example แล้ว เรามาดูรายละเอียดเพิ่มเติมกัน ในแท็บเวอร์ชัน ให้คลิกเวอร์ชันที่เราเพิ่งสร้าง วิธีแสดงรูปภาพโดยละเอียดเพิ่มเติม

ปุ่มคัดลอกด้านบนมีประโยชน์อย่างยิ่งเนื่องจากช่วยให้เข้าถึง URI ของรูปภาพที่มีคุณสมบัติครบถ้วนไปยังเวอร์ชันรูปภาพนั้นๆ ได้อย่างง่ายดาย รวมถึงแฮช SHA จากนั้นจะใช้ URI นี้เพื่อดึงเวอร์ชันรูปภาพที่เฉพาะเจาะจงหรือใช้เป็นข้อมูลอ้างอิงรูปภาพในการติดตั้งใช้งาน Kubernetes หรือบริการ Cloud Run ได้ หากต้องการทดสอบ URI ของอิมเมจ ให้เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
docker pull $IMAGE_URI
ทำความเข้าใจทรัพยากร Dependency
เมื่อไปที่แท็บ "การขึ้นต่อกัน" ที่ด้านบน คุณจะเห็นการขึ้นต่อกันทั้งหมดที่ตรวจพบในอิมเมจ โปรดทราบว่ารายการนี้จะแสดงทั้งทรัพยากร Dependency ที่ทรัพยากร Dependency ของภาษาและระดับระบบปฏิบัติการ นอกจากนี้ คุณยังดูใบอนุญาตซอฟต์แวร์ที่แนบมากับแต่ละการอ้างอิงได้ด้วย

หากสังเกตดีๆ คุณจะเห็นว่าระบบยังไม่ได้ป้อนข้อมูล SBOM หากต้องการสร้าง SOM สำหรับอาร์ติแฟกต์ ให้เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell โดยใช้ URI ของอิมเมจแบบเต็มที่เราคัดลอกจากแถบเบรดครัมบ์ที่ด้านบนได้
gcloud artifacts sbom export --uri $IMAGE_URI
เมื่อรีเฟรชหน้าเว็บแล้ว หน้าเว็บจะมีลิงก์ไปยัง SBOM ที่สร้างขึ้นโดยอัตโนมัติซึ่งจัดเก็บไว้ใน Cloud Storage หากคุณใช้ SBOM สำหรับอิมเมจ คุณอาจต้องการสร้าง SBOM สำหรับอาร์ติแฟกต์โดยอัตโนมัติและทำให้การสร้างเป็นส่วนหนึ่งของไปป์ไลน์ CI/CD
การสำรวจช่องโหว่ของอิมเมจ
เมื่อคลิกแท็บ "ช่องโหว่" ที่ด้านบนของมุมมอง คุณจะเห็นช่องโหว่ทั้งหมดที่ตรวจพบในอิมเมจ นอกจากสรุปช่องโหว่ที่ด้านบนแล้ว คุณยังดูรายการช่องโหว่ทั้งหมดได้ในตารางที่ด้านล่าง แต่ละแถวจะลิงก์ไปยังกระดานข่าว CVE ซึ่งระบุความรุนแรงและแพ็กเกจที่เกิดช่องโหว่ สำหรับช่องโหว่ที่มีการแก้ไขแล้ว ระบบจะแสดงวิธีการอัปเดตการขึ้นต่อกันเพื่อแก้ไขช่องโหว่ด้วย

5. ที่เก็บเสมือนและที่เก็บระยะไกล
ในส่วนก่อนหน้า เราใช้ที่เก็บรูปภาพเดียวเพื่อพุชและดึงรูปภาพ ซึ่งเหมาะอย่างยิ่งสำหรับกรณีการใช้งานขนาดเล็ก แต่ก็เป็นความท้าทายโดยเฉพาะสำหรับองค์กรขนาดใหญ่ที่มีทีมต่างๆ ซึ่งต้องการอิสระในการควบคุมที่เก็บ โดยปกติแล้ว ทีมหรือหน่วยธุรกิจจะมีที่เก็บรูปภาพของตนเองพร้อมสิทธิ์และการกำหนดค่าของตนเอง Artifact Registry มีที่เก็บข้อมูลเสมือนที่รวบรวมทรัพยากรจากที่เก็บข้อมูลพื้นฐานหลายแห่ง เพื่อให้การใช้รูปภาพในที่เก็บข้อมูลเหล่านี้ง่ายขึ้นและเพื่อปกป้องผู้ใช้จากโครงสร้างองค์กรพื้นฐาน สถาปัตยกรรมที่เป็นไปได้อาจมีลักษณะดังนี้

ที่เก็บระยะไกลสำหรับ Docker Hub
Docker Hub เป็นรีจิสทรีอิมเมจสาธารณะที่ได้รับความนิยมและโฮสต์อิมเมจคอนเทนเนอร์โอเพนซอร์สจำนวนมาก แม้ว่าการใช้ที่เก็บข้อมูลสาธารณะโดยตรงจะทำได้ง่าย แต่ก็มีข้อจำกัดหลายอย่างในสภาพแวดล้อมการใช้งานจริง ซึ่งเราสามารถแก้ไขได้ด้วยที่เก็บข้อมูลระยะไกลใน Artifact Registry
ที่เก็บข้อมูลระยะไกลช่วยให้คุณพร็อกซีคำขอไปยังรีจิสทรีต้นทางและแคชรูปภาพได้ตลอดเส้นทาง ซึ่งไม่เพียงช่วยลดเวลาในการดาวน์โหลดรูปภาพ แต่ยังช่วยลดการพึ่งพาเวลาในการทำงานของบริการภายนอก และช่วยให้คุณใช้ความปลอดภัยและนโยบายการเข้าถึงเดียวกันกับที่ใช้กับรูปภาพของคุณเองได้
หากต้องการสร้างที่เก็บข้อมูลระยะไกลสำหรับ Docker Hub ให้เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
gcloud artifacts repositories create dockerhub \
--repository-format=docker \
--mode=remote-repository \
--remote-docker-repo=docker-hub \
--location=us-central1 \
--description="Example Remote Repo for Docker Hub"
ตอนนี้คุณควรเห็นที่เก็บอีกรายการในรายการที่เก็บของ Artifact Registry ดังนี้

หากต้องการทดสอบว่าที่เก็บระยะไกลสามารถพร็อกซีคำขอไปยังที่เก็บระยะไกลได้หรือไม่ ให้เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อดึงอิมเมจ nginx
docker pull us-central1-docker.pkg.dev/$PROJECT_ID/dockerhub/nginx:stable-alpine
เมื่อดึงข้อมูลสำเร็จแล้ว คุณยังดูที่เก็บใน Cloud Console ได้ด้วย และตอนนี้อิมเมจ nginx ที่แคชไว้จะให้การรายงานการขึ้นต่อกันและช่องโหว่แบบเดียวกันกับที่เราเห็นในอิมเมจที่คุณสร้างขึ้นเอง
การสร้างที่เก็บเสมือน
การทำตามกระบวนการที่เราใช้มาจนถึงตอนนี้จะช่วยให้คุณสร้างที่เก็บจำนวนมากสำหรับแต่ละทีมหรือธุรกิจ และกำหนดความเป็นเจ้าของและสิทธิ์ IAM สำหรับแต่ละที่เก็บได้อย่างชัดเจน นอกจากนี้ เรายังสร้างพร็อกซีสำหรับที่เก็บข้อมูลระยะไกลได้ด้วย ซึ่งจะช่วยให้การใช้รูปภาพของบุคคลที่สามง่ายและปลอดภัยยิ่งขึ้น ข้อเสียของการมีที่เก็บจำนวนมากนี้จะเห็นได้ชัดหากคุณเปลี่ยนมุมมองไปที่ผู้บริโภคของอิมเมจเหล่านี้ นักพัฒนาซอฟต์แวร์จะทราบได้อย่างไรว่าควรใช้ที่เก็บรูปภาพใดในการติดตั้งใช้งาน
หากต้องการลดความซับซ้อนในการใช้งานและซ่อนที่เก็บข้อมูลพื้นฐานไว้เบื้องหลังเลเยอร์การแยกข้อมูล คุณสามารถสร้างที่เก็บข้อมูลเสมือนใน Artifact Registry ได้โดยใช้คำสั่งต่อไปนี้ใน Cloud Shell
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-artifactregistry.iam.gserviceaccount.com \
--role roles/artifactregistry.reader
cat <<EOF > /tmp/upstream.json
[{
"id" : "hello-repo",
"repository" : "projects/$PROJECT_ID/locations/us-central1/repositories/container-example",
"priority" : 100
},{
"id" : "dockerhub",
"repository" : "projects/$PROJECT_ID/locations/us-central1/repositories/dockerhub",
"priority" : 101
}]
EOF
gcloud artifacts repositories create all-images \
--repository-format=docker \
--mode=virtual-repository \
--location=us-central1 \
--upstream-policy-file=/tmp/upstream.json \
--description="Example Virtual Repo"
ตอนนี้เราสามารถดึงรูปภาพจากที่เก็บข้อมูลเสมือนได้โดยไม่ต้องเปิดเผยโครงสร้างพื้นฐาน หากต้องการยืนยันว่าทุกอย่างทำงานได้ตามที่คาดไว้ คุณสามารถเรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
docker pull us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:tag1
docker pull us-central1-docker.pkg.dev/$PROJECT_ID/all-images/nginx:stable-alpine
6. ทำให้ใช้งานได้กับ Cloud Run
เมื่อมีที่เก็บและอิมเมจที่เกี่ยวข้องแล้ว ตอนนี้เราก็สามารถใช้ที่เก็บและอิมเมจเหล่านั้นในการติดตั้งใช้งานได้ เราจะทำให้คอนเทนเนอร์ใช้งานได้ใน Cloud Run เพื่อแสดงกรณีการใช้งานตัวอย่างและหลีกเลี่ยงการติดตั้งใช้งานโครงสร้างพื้นฐานเพิ่มเติม การทำให้ใช้งานได้ในรูปแบบที่ง่ายที่สุดทำได้โดยการเรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
gcloud run deploy hello-world \
--image us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:tag1 \
--region us-central1 \
--allow-unauthenticated
เมื่อการติดตั้งใช้งานเสร็จสิ้น ระบบจะแสดง URL ที่สร้างขึ้นโดยอัตโนมัติซึ่งคุณใช้เข้าถึงบริการได้
Deploying container to Cloud Run service [hello-world] in project [my-project] region [us-central1] OK Deploying... Done. OK Creating Revision... OK Routing traffic... OK Setting IAM Policy... Done. Service [hello-world] revision [hello-world-00001-wtc] has been deployed and is serving 100 percent of traffic. Service URL: https://hello-world-13746229022.us-central1.run.app
หากเปิด URL นั้นในแท็บเบราว์เซอร์ใหม่ คุณควรเห็นข้อความ "Hello World" ที่สำเร็จ

7. เสริมสร้างความปลอดภัยของซัพพลายเชน
ตอนนี้อิมเมจคอนเทนเนอร์ของคุณได้เข้าสู่การติดตั้งใช้งานจริงแล้ว จึงอาจเป็นเวลาที่เหมาะสมที่จะพิจารณาวิธีเสริมความแข็งแกร่งให้กับซัพพลายเชนแบบครบวงจร ในส่วนก่อนหน้า เราได้ดูวิธีที่การวิเคราะห์คอนเทนเนอร์ของ Artifact Registry ให้ข้อมูลเชิงลึกเกี่ยวกับไลบรารีและใบอนุญาตที่ใช้ในอิมเมจ อย่างไรก็ตาม ผู้ไม่ประสงค์ดีอาจยังคงนำเนื้อหาที่เป็นอันตรายมาใส่ในรูปภาพของคุณตามซัพพลายเชนได้ ในส่วนนี้ เราจะมาดูวิธีใช้เฟรมเวิร์ก SLSA เพื่อใช้การรับรองสำหรับอาร์ติแฟกต์บิลด์ และแม้แต่ใช้ประโยชน์จากลายเซ็นเข้ารหัสของอาร์ติแฟกต์เองเพื่อให้มั่นใจว่าเฉพาะอาร์ติแฟกต์ที่เชื่อถือได้เท่านั้นที่จะนำไปใช้กับรันไทม์ของ Cloud Run ได้
การรับรอง SLSA ด้วย Cloud Build
เฟรมเวิร์ก SLSA มีหลักฐานระดับต่างๆ สำหรับอาร์ติแฟกต์ในซัพพลายเชน ข้อกำหนดและการติดตั้งใช้งานอาจดูน่ากังวลในตอนแรก แต่การสร้างการรับรอง SLSA ด้วย Cloud Build นั้นง่ายเพียงแค่เพิ่มcloudbuild.yamlข้อกำหนดโดยตั้งค่าrequestedVerifyOptionเป็นVERIFIED
สำหรับแอปพลิเคชัน เราสามารถเรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อสร้างไฟล์ cloudbuild.yaml ในโฟลเดอร์ helloworld
cat <<EOF > cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', '\$_IMAGE_URI', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', '\$_IMAGE_URI']
images:
- '\$_IMAGE_URI'
options:
requestedVerifyOption: VERIFIED
substitutions:
_IMAGE_URI: us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:latest
EOF
ตอนนี้เราจะสร้างงาน Cloud Build ใหม่ซึ่งจะสร้างอิมเมจ Java Hello World เวอร์ชันใหม่โดยการเรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
gcloud builds submit --substitutions=_IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:cloud-build
เมื่อการสร้างเสร็จสมบูรณ์แล้ว เราจะไปที่ UI ของ Cloud Build ใน Google Cloud Console และดูระดับ SLSA ที่เราได้รับโดยเปิดบิลด์ แล้วดูที่อาร์ติแฟกต์ของบิลด์ในส่วนสรุปบิลด์ รูปภาพที่เห็นจะมีปุ่มสำหรับดู "ข้อมูลเชิงลึกด้านความปลอดภัย" เมื่อคลิก คุณจะเห็นการรับรอง SLSA รวมถึงรายงานช่องโหว่ที่คุ้นเคยซึ่งเราเคยเห็นใน UI ของ Artifact Registry เมื่อเราพุชบิลด์ในเครื่อง

คุณยังเรียกข้อมูลที่มาของ SLSA สำหรับอิมเมจได้โดยการเรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
gcloud artifacts docker images describe \
"us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:cloud-build" \
--show-provenance
กำหนดให้มีที่มาของ Cloud Build ด้วยการให้สิทธิ์แบบไบนารี
เมื่อมีไปป์ไลน์ Cloud Build แล้ว เราควรตรวจสอบว่าอิมเมจทั้งหมดที่เรานำไปใช้ในการผลิตสร้างขึ้นโดยใช้สภาพแวดล้อมการสร้างที่ตั้งโปรแกรมได้และทำซ้ำได้
การให้สิทธิ์แบบไบนารีจึงเข้ามามีบทบาทในจุดนี้ ซึ่งช่วยให้คุณวาง Gatekeeper ไว้หน้าเวลาเรียกใช้คอนเทนเนอร์เพื่อตรวจสอบอิมเมจคอนเทนเนอร์และยืนยันการรับรองที่เชื่อถือได้ หากไม่พบการรับรอง ระบบจะสร้างรายการบันทึกการตรวจสอบหรือบล็อกการติดตั้งใช้งานทั้งหมด ทั้งนี้ขึ้นอยู่กับการกำหนดค่า
หากต้องการเปลี่ยนการกำหนดค่าการให้สิทธิ์ไบนารีเริ่มต้นของโปรเจ็กต์ให้ต้องมีการรับรองในตัวที่ออกโดย Cloud Run ให้เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
cat << EOF > /tmp/policy.yaml
defaultAdmissionRule:
enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
evaluationMode: REQUIRE_ATTESTATION
requireAttestationsBy:
- projects/$PROJECT_ID/attestors/built-by-cloud-build
name: projects/$PROJECT_ID/policy
EOF
gcloud container binauthz policy import /tmp/policy.yaml
แน่นอนว่าคุณยังเพิ่ม Attestor ที่กำหนดเองได้ด้วย แต่จะอยู่นอกขอบเขตของ Codelab นี้และเป็นแบบฝึกหัดการบ้านเพิ่มเติมที่ไม่บังคับ
หากต้องการบังคับใช้การให้สิทธิ์ไบนารีในบริการ Cloud Run ให้เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell
gcloud run services update hello-world \
--region us-central1 \
--binary-authorization=default
มาทดสอบว่าการให้สิทธิ์แบบไบนารีของเราใช้ได้อย่างถูกต้องโดยการทำให้ใช้งานได้อีกครั้งด้วยอิมเมจที่สร้างขึ้นในเครื่องก่อน
gcloud run deploy hello-world \
--image us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:tag1 \
--region us-central1
ตามที่คาดไว้ คุณควรได้รับข้อความแสดงข้อผิดพลาดที่อธิบายว่าเหตุใดจึงไม่สามารถติดตั้งใช้งานอิมเมจได้ ซึ่งจะมีลักษณะดังนี้
Image us-central1-docker.pkg.dev/my-project/all-images/java-hello-world@sha256:71eebbf04bf7d1d023e5de5e18f786ea3b8b6411bf64c8def3301c71baca0518 denied by attestor projects/my-project/attestors/built-by-cloud-build: No attestations found that were valid and signed by a key trusted by the attestor
ดังนั้นหากต้องการทําให้เวอร์ชันใหม่ใช้งานได้ในบริการ Cloud Run เราจึงต้องระบุอิมเมจที่สร้างด้วย Cloud Build
gcloud run deploy hello-world \
--image us-central1-docker.pkg.dev/$PROJECT_ID/all-images/java-hello-world:cloud-build \
--region us-central1
การทำให้ใช้งานได้ในครั้งนี้ควรสำเร็จและแสดงข้อความการทำให้ใช้งานได้สำเร็จคล้ายกับข้อความด้านล่าง
Deploying container to Cloud Run service [hello-world] in project [my-project] region [us-central1] OK Deploying... Done. OK Creating Revision... OK Routing traffic... Done. Service [hello-world] revision [hello-world-00005-mq4] has been deployed and is serving 100 percent of traffic. Service URL: https://hello-world-13746229022.us-central1.run.app
8. การจัดการแพ็กเกจภาษา Java Maven
ในส่วนนี้ คุณจะได้ดูวิธีตั้งค่าที่เก็บ Java ของ Artifact Registry และอัปโหลดแพ็กเกจไปยังที่เก็บดังกล่าว รวมถึงวิธีใช้ประโยชน์จากแพ็กเกจในแอปพลิเคชันต่างๆ
สร้างที่เก็บแพ็กเกจ Maven
จาก Cloud Shell ให้เรียกใช้คำสั่งต่อไปนี้เพื่อสร้างที่เก็บสำหรับอาร์ติแฟกต์ Java
gcloud artifacts repositories create java-repo \
--repository-format=maven \
--location=us-central1 \
--description="Example Java Maven Repo"
คลิก "ให้สิทธิ์" หากข้อความแจ้งการให้สิทธิ์ Cloud Shell ปรากฏขึ้น
ไปที่ Google Cloud Console - Artifact Registry - ที่เก็บ แล้วสังเกตที่เก็บ Maven ที่สร้างขึ้นใหม่ชื่อ java-repo หากคลิกที่เก็บดังกล่าว คุณจะเห็นว่าที่เก็บนั้นว่างเปล่าในขณะนี้
ตั้งค่าการตรวจสอบสิทธิ์ไปยังที่เก็บ Artifact
ใช้คำสั่งต่อไปนี้เพื่ออัปเดตตำแหน่งที่รู้จักกันดีสำหรับข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน (ADC) ด้วยข้อมูลเข้าสู่ระบบบัญชีผู้ใช้ เพื่อให้โปรแกรมช่วยเหลือด้านข้อมูลเข้าสู่ระบบของ Artifact Registry สามารถตรวจสอบสิทธิ์โดยใช้ข้อมูลดังกล่าวเมื่อเชื่อมต่อกับที่เก็บ
gcloud auth login --update-adc
กำหนดค่า Maven สำหรับ Artifact Registry
เรียกใช้คำสั่งต่อไปนี้เพื่อพิมพ์การกำหนดค่าที่เก็บเพื่อเพิ่มลงในโปรเจ็กต์ Java
gcloud artifacts print-settings mvn \
--repository=java-repo \
--location=us-central1 | tee config.xml
เปิด pom.xml ใน Cloud Shell Editor โดยเรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell จากภายในไดเรกทอรี helloworld
cloudshell edit pom.xml
และเพิ่มการตั้งค่าที่ส่งคืนไปยังส่วนที่เหมาะสมในไฟล์
อัปเดตส่วน distributionManagement
<distributionManagement>
<snapshotRepository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
</snapshotRepository>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
</repository>
</distributionManagement>
อัปเดตส่วนที่เก็บ
<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
อัปเดตส่วนส่วนขยายในส่วนสร้าง
<extensions>
<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.1.0</version>
</extension>
</extensions>
ต่อไปนี้คือตัวอย่างไฟล์ที่สมบูรณ์เพื่อให้คุณใช้อ้างอิง อย่าลืมแทนที่ <PROJECT> ด้วยรหัสโปรเจ็กต์
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.run</groupId>
<artifactId>helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>com.google.cloud.samples</groupId>
<artifactId>shared-configuration</artifactId>
<version>1.2.0</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<spring-boot.version>3.2.2</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- [START Artifact Registry Config] -->
<distributionManagement>
<snapshotRepository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
</snapshotRepository>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
</repository>
</distributionManagement>
<repositories>
<repository>
<id>artifact-registry</id>
<url>artifactregistry://us-central1-maven.pkg.dev/<PROJECT>/java-repo</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<build>
<extensions>
<extension>
<groupId>com.google.cloud.artifactregistry</groupId>
<artifactId>artifactregistry-maven-wagon</artifactId>
<version>2.2.0</version>
</extension>
</extensions>
<!-- [END Artifact Registry Config] -->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<to>
<image>gcr.io/PROJECT_ID/helloworld</image>
</to>
</configuration>
</plugin>
</plugins>
</build>
</project>
อัปโหลดแพ็กเกจ Java ไปยัง Artifact Registry
เมื่อกำหนดค่า Artifact Registry ใน Maven แล้ว คุณจะใช้ Artifact Registry เพื่อจัดเก็บ Java JAR สำหรับโปรเจ็กต์อื่นๆ ในองค์กรได้
เรียกใช้คำสั่งต่อไปนี้เพื่ออัปโหลดแพ็กเกจ Java ไปยัง Artifact Registry
mvn deploy
ตรวจสอบแพ็กเกจ Java ใน Artifact Registry
ไปที่ Cloud Console - Artifact Registry - ที่เก็บ คลิก java-repo แล้วตรวจสอบว่ามีอาร์ติแฟกต์ไบนารี helloworld อยู่

9. ยินดีด้วย
ยินดีด้วย คุณทำ Codelab เสร็จแล้ว
สิ่งที่คุณได้พูดถึงไปแล้ว
- ที่เก็บที่สร้างขึ้นสำหรับคอนเทนเนอร์และแพ็กเกจภาษา
- จัดการอิมเมจคอนเทนเนอร์ด้วย Artifact Registry
- ผสานรวม Artifact Registry กับ Cloud Code
- กำหนดค่า Maven ให้ใช้ Artifact Registry สำหรับทรัพยากร Dependency ของ Java
ล้างข้อมูล
เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อลบทั้งโปรเจ็กต์
gcloud projects delete $PROJECT_ID