আর্টিফ্যাক্ট রেজিস্ট্রি গভীর ডুব

১. সংক্ষিপ্ত বিবরণ

আর্টিফ্যাক্ট রেজিস্ট্রি হলো একটি সম্পূর্ণভাবে পরিচালিত প্যাকেজ ম্যানেজার এবং এটি আপনার OCI কন্টেইনার ইমেজ ও ল্যাঙ্গুয়েজ প্যাকেজ (যেমন Maven এবং npm) ব্যবস্থাপনার জন্য একটি সমন্বিত টুল প্রদান করে।

আর্টিফ্যাক্ট রেজিস্ট্রি নিম্নলিখিত উদাহরণগুলির মতো গুগল ক্লাউডের অন্যান্য বিস্তৃত পরিষেবাগুলির সাথে সম্পূর্ণরূপে সমন্বিত:

  • Cloud Build can directly upload image artifacts to Artifact Registry.
  • ক্লাউড ডিপ্লয় আর্টিফ্যাক্ট রেজিস্ট্রি ইমেজগুলোকে সরাসরি বিভিন্ন রানটাইম এনভায়রনমেন্টে ডিপ্লয় করতে পারে।
  • এটি ক্লাউড রান এবং জিকেই-এর মতো কন্টেইনার রানটাইমগুলিতে ইমেজ সরবরাহ করে এবং ইমেজ স্ট্রিমিং-এর মতো উন্নত পারফরম্যান্স অপ্টিমাইজেশন সক্ষমতা প্রদান করে।
  • আর্টিফ্যাক্ট রেজিস্ট্রি, আর্টিফ্যাক্ট অ্যানালাইসিসের জন্য একটি শনাক্তকরণ বিন্দু হিসেবে কাজ করতে পারে, যা জ্ঞাত দুর্বলতাগুলোর উপর ক্রমাগত নজরদারি করে।
  • ক্লাউড আইএএম আর্টিফ্যাক্ট অ্যাক্সেস এবং পারমিশনের উপর সুসংগত ও সূক্ষ্ম নিয়ন্ত্রণ প্রদান করে।

এই ল্যাবটি একটি হাতে-কলমে টিউটোরিয়ালের মাধ্যমে আপনাকে এই বৈশিষ্ট্যগুলির অনেকগুলো সম্পর্কে ধাপে ধাপে শিখিয়ে দেবে।

আপনি যা শিখবেন

এই ল্যাবের শিক্ষণ উদ্দেশ্যগুলো কী কী?

  • কন্টেইনার এবং ল্যাঙ্গুয়েজ প্যাকেজের জন্য আলাদা রিপোজিটরি তৈরি করুন
  • আর্টিফ্যাক্ট রেজিস্ট্রি দিয়ে কন্টেইনার ইমেজ তৈরি ও ব্যবহার করুন
  • আপনার আর্টিফ্যাক্টগুলোর নিরাপত্তা পরিস্থিতি ও বিষয়বস্তু বিশ্লেষণ করতে আর্টিফ্যাক্ট রেজিস্ট্রি ব্যবহার করুন।
  • জাভা মেভেন ডিপেন্ডেন্সির জন্য আর্টিফ্যাক্ট রেজিস্ট্রি কনফিগার এবং ব্যবহার করুন

২. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিতে পরিবেশ সেটআপ

  1. Google Cloud Console- এ সাইন-ইন করুন এবং একটি নতুন প্রজেক্ট তৈরি করুন অথবা বিদ্যমান কোনো প্রজেক্ট পুনরায় ব্যবহার করুন। যদি আপনার আগে থেকে Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তবে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • প্রজেক্টের নামটি হলো এই প্রজেক্টের অংশগ্রহণকারীদের প্রদর্শিত নাম। এটি একটি ক্যারেক্টার স্ট্রিং যা গুগল এপিআই ব্যবহার করে না। আপনি যেকোনো সময় এটি আপডেট করতে পারেন।
  • প্রজেক্ট আইডি সমস্ত গুগল ক্লাউড প্রজেক্ট জুড়ে অনন্য এবং অপরিবর্তনীয় (একবার সেট করার পর এটি পরিবর্তন করা যায় না)। ক্লাউড কনসোল স্বয়ংক্রিয়ভাবে একটি অনন্য স্ট্রিং তৈরি করে; সাধারণত এটি কী তা নিয়ে আপনার মাথা ঘামানোর দরকার নেই। বেশিরভাগ কোডল্যাবে, আপনাকে আপনার প্রজেক্ট আইডি উল্লেখ করতে হবে (যা সাধারণত PROJECT_ID হিসাবে চিহ্নিত করা হয়)। তৈরি করা আইডিটি আপনার পছন্দ না হলে, আপনি এলোমেলোভাবে আরেকটি তৈরি করতে পারেন। বিকল্পভাবে, আপনি আপনার নিজের আইডি দিয়ে চেষ্টা করে দেখতে পারেন যে সেটি উপলব্ধ আছে কিনা। এই ধাপের পরে এটি পরিবর্তন করা যাবে না এবং প্রজেক্টের পুরো সময়কাল জুড়ে এটি অপরিবর্তিত থাকবে।
  • আপনার অবগতির জন্য জানাচ্ছি যে, তৃতীয় একটি ভ্যালু রয়েছে, যা হলো প্রজেক্ট নম্বর , এবং কিছু এপিআই এটি ব্যবহার করে থাকে। ডকুমেন্টেশনে এই তিনটি ভ্যালু সম্পর্কে আরও বিস্তারিত জানুন।
  1. এরপর, ক্লাউড রিসোর্স/এপিআই ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং চালু করতে হবে। এই কোডল্যাবটি সম্পন্ন করতে খুব বেশি খরচ হবে না, এমনকি আদৌ কোনো খরচ নাও হতে পারে। এই টিউটোরিয়ালের পর বিলিং এড়াতে রিসোর্সগুলো বন্ধ করার জন্য, আপনি আপনার তৈরি করা রিসোর্সগুলো অথবা প্রজেক্টটি ডিলিট করে দিতে পারেন। নতুন গুগল ক্লাউড ব্যবহারকারীরা ৩০০ মার্কিন ডলারের ফ্রি ট্রায়াল প্রোগ্রামের জন্য যোগ্য।

gcloud সেট আপ করুন

ক্লাউড শেলে আপনার প্রজেক্ট আইডি এবং প্রজেক্ট নম্বর সেট করুন। এগুলোকে PROJECT_ID এবং PROJECT_NUMBER ভেরিয়েবল হিসেবে সংরক্ষণ করুন।

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

গুগল পরিষেবাগুলি সক্ষম করুন

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 অর্গানাইজেশনে রয়েছে। নিচের কমান্ডটি ব্যবহার করে এটি ক্লোন করুন।

git clone https://github.com/GoogleCloudPlatform/java-docs-samples

৩. কন্টেইনার ইমেজ পুশ করা

আর্টিফ্যাক্ট রেজিস্ট্রিতে একটি ডকার রিপোজিটরি তৈরি করুন

পূর্বে যেমন উল্লেখ করা হয়েছে, আর্টিফ্যাক্ট রেজিস্ট্রি বিভিন্ন রিপোজিটরি ফরম্যাট সমর্থন করে যা আপনাকে কন্টেইনার ইমেজ এবং ল্যাঙ্গুয়েজ প্যাকেজ পরিচালনা করতে দেয়। বিভিন্ন ধরণের আর্টিফ্যাক্ট রিপোজিটরির সাথে মিথস্ক্রিয়া স্পেসিফিকেশনে সংজ্ঞায়িত করা আছে এবং এগুলো বহুল গৃহীত স্ট্যান্ডার্ড। উদাহরণস্বরূপ, Maven ডিপেন্ডেন্সির জন্য অনুরোধগুলো Node ডিপেন্ডেন্সির জন্য অনুরোধ থেকে ভিন্ন।

একটি নির্দিষ্ট আর্টিফ্যাক্ট এপিআই স্পেসিফিকেশন সমর্থন করার জন্য, আর্টিফ্যাক্ট রেজিস্ট্রিকে আপনার আর্টিফ্যাক্টগুলিকে সংশ্লিষ্ট রিপোজিটরি টাইপগুলিতে পরিচালনা করতে হয়। যখন আপনি একটি নতুন রিপোজিটরি তৈরি করেন, তখন রিপোজিটরির ধরন নির্দেশ করার জন্য আপনাকে --repository-format ফ্ল্যাগটি ব্যবহার করতে হয়।

ডকার ইমেজের জন্য প্রথম রিপোজিটরি তৈরি করতে ক্লাউড শেল থেকে নিম্নলিখিত কমান্ডটি চালান:

gcloud artifacts repositories create container-example --repository-format=docker \
--location=us-central1 --description="Example Docker repository"

ক্লাউড শেল অথরাইজেশন প্রম্পট দেখা গেলে অথরাইজ-এ ক্লিক করুন।

Google Cloud Console - Artifact Registry - Repositories-এ যান এবং আপনার সদ্য তৈরি করা ` container-example নামের ডকার রিপোজিটরিটি দেখুন, সেটিতে ক্লিক করলে দেখতে পাবেন যে এই মুহূর্তে এটি খালি আছে।

5b854eb010e891c2.png

আর্টিফ্যাক্ট রেজিস্ট্রিতে ডকার অথেনটিকেশন কনফিগার করুন

আর্টিফ্যাক্ট রেজিস্ট্রি-তে সংযোগ করার সময় অ্যাক্সেস দেওয়ার জন্য ক্রেডেনশিয়াল প্রয়োজন হয়। আলাদা ক্রেডেনশিয়াল সেট আপ করার পরিবর্তে, আপনার gcloud ক্রেডেনশিয়াল নির্বিঘ্নে ব্যবহার করার জন্য ডকার কনফিগার করা যেতে পারে।

us-central1 অঞ্চলের আর্টিফ্যাক্ট রেজিস্ট্রিতে অনুরোধ প্রমাণীকরণের জন্য ডকার যাতে গুগল ক্লাউড সিএলআই ব্যবহার করে, তা কনফিগার করতে ক্লাউড শেল থেকে নিম্নলিখিত কমান্ডটি চালান।

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

ক্লাউড শেল ডকার কনফিগারেশন পরিবর্তন করার জন্য যদি কমান্ডটি নিশ্চিতকরণের জন্য অনুরোধ করে, তাহলে এন্টার চাপুন।

নমুনা অ্যাপ্লিকেশনটি অন্বেষণ করুন

পূর্ববর্তী ধাপে আপনার ক্লোন করা গিট রিপোজিটরিতে একটি নমুনা অ্যাপ্লিকেশন দেওয়া আছে। java ডিরেক্টরিতে প্রবেশ করুন এবং অ্যাপ্লিকেশন কোডটি পর্যালোচনা করুন।

cd java-docs-samples/run/helloworld/
ls

ফোল্ডারটিতে একটি উদাহরণ জাভা অ্যাপ্লিকেশন রয়েছে যা একটি সাধারণ ওয়েব পেজ রেন্ডার করে। এই নির্দিষ্ট ল্যাবের জন্য অপ্রাসঙ্গিক বিভিন্ন ফাইল ছাড়াও, এতে src ফোল্ডারের অধীনে সোর্স কোড এবং একটি ডকারফাইল রয়েছে যা আমরা একটি কন্টেইনার ইমেজ তৈরি করতে ব্যবহার করব।

কন্টেইনার ইমেজ তৈরি করুন

আর্টিফ্যাক্ট রেজিস্ট্রি-তে কন্টেইনার ইমেজ সংরক্ষণ করার আগে আপনাকে একটি তৈরি করতে হবে।

কন্টেইনার ইমেজটি তৈরি করতে এবং সম্পূর্ণ আর্টিফ্যাক্ট রেজিস্ট্রি পাথ দিয়ে এটিকে ট্যাগ করতে নিম্নলিখিত কমান্ডটি চালান:

docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:tag1 .

কন্টেইনার ইমেজটি আর্টিফ্যাক্ট রেজিস্ট্রি-তে পুশ করুন

পূর্বে তৈরি করা রিপোজিটরিতে কন্টেইনার ইমেজটি পুশ করতে নিম্নলিখিত কমান্ডটি চালান:

docker push us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:tag1

আর্টিফ্যাক্ট রেজিস্ট্রিতে ছবিটি পর্যালোচনা করুন।

Google Cloud Console - Artifact Registry - Repositories- এ যান . container-example রিপোজিটরিটি খুলুন এবং যাচাই করুন যে java-hello-world ইমেজটি সেখানে আছে।

88e4b26e8536afb2.png

ছবিতে ক্লিক করুন এবং tag1 ট্যাগযুক্ত ছবিটি লক্ষ্য করুন। যেহেতু আমরা containerscanning.googleapis.com পরিষেবার মাধ্যমে ছবিগুলোর স্বয়ংক্রিয় স্ক্যানিং চালু করেছি, আপনি দেখতে পাবেন যে `Vulnerability Scanning` হয় চলছে অথবা ইতিমধ্যে সম্পন্ন হয়েছে। এটি সম্পন্ন হয়ে গেলে, আপনি এই ইমেজ রিভিশনের জন্য শনাক্ত হওয়া দুর্বলতার সংখ্যা দেখতে পাবেন। আমরা পরবর্তী বিভাগে দুর্বলতা এবং অন্যান্য আর্টিফ্যাক্ট সম্পর্কিত তথ্য নিয়ে আলোচনা করব।

55406d03cf0c96b8.png

৪. কন্টেইনার ইমেজ পরিদর্শন

এখন যেহেতু আপনি আপনার প্রথম ইমেজটি container-example রিপোজিটরিতে পুশ করেছেন, আমরা এটি আরও বিস্তারিতভাবে দেখতে পারি। `versions` ট্যাবে, আমরা এইমাত্র যে ভার্সনটি তৈরি করেছি সেটিতে ক্লিক করুন। ইমেজটি আরও বিস্তারিতভাবে দেখতে:

44c3f28dd457ed1d.png

উপরের কপি বাটনটি বিশেষভাবে উপযোগী, কারণ এটি SHA-হ্যাশ সহ সেই ইমেজ ভার্সনের সম্পূর্ণ ইমেজ URI সহজে অ্যাক্সেস করার সুযোগ দেয়। এই URI-টি পরবর্তীতে একটি নির্দিষ্ট ইমেজ ভার্সন পুল করতে অথবা Kubernetes Deployment বা Cloud Run Service-এ ইমেজ রেফারেন্স হিসেবে ব্যবহার করা যেতে পারে। ইমেজ URI-টি পরীক্ষা করার জন্য আপনি Cloud Shell-এ নিম্নলিখিত কমান্ডটি চালাতে পারেন:

docker pull $IMAGE_URI

নির্ভরশীলতা বোঝা

উপরে থাকা "ডিপেন্ডেন্সি" ট্যাবে গেলে আপনি আপনার ইমেজে শনাক্ত হওয়া সমস্ত ডিপেন্ডেন্সি দেখতে পাবেন। লক্ষ্য করুন যে, এটি ল্যাঙ্গুয়েজ ডিপেন্ডেন্সি এবং ওএস লেভেল উভয়েরই তালিকা দেখায়। এছাড়াও, আপনি প্রতিটি ডিপেন্ডেন্সির সাথে সংযুক্ত সফটওয়্যার লাইসেন্সগুলোও দেখতে পারবেন।

af03348529575dbc.png

ভালোভাবে দেখলে আপনি দেখতে পাবেন যে SBOM তথ্য এখনও পূরণ করা হয়নি। আপনার আর্টিফ্যাক্টের জন্য SOM পূরণ করতে, আপনি উপরের ব্রেডক্রাম্ব বার থেকে কপি করা সম্পূর্ণ ইমেজ URI ব্যবহার করে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালাতে পারেন।

gcloud artifacts sbom export --uri $IMAGE_URI

পৃষ্ঠাটি রিফ্রেশ করলে, এতে ক্লাউড স্টোরেজে সংরক্ষিত স্বয়ংক্রিয়ভাবে তৈরি SBOM-এর একটি লিঙ্ক দেখা যাবে। আপনি যদি আপনার ইমেজের জন্য SBOM-এর উপর নির্ভর করেন, তবে আপনি আপনার আর্টিফ্যাক্টগুলোর জন্যও স্বয়ংক্রিয়ভাবে SBOM তৈরি করতে এবং এই তৈরির প্রক্রিয়াটিকে আপনার CI/CD পাইপলাইনের অংশ করে নিতে পারেন।

ছবির দুর্বলতা অন্বেষণ

ভিউ-এর উপরের "Vulnerabilities" ট্যাবে ক্লিক করলে আপনি আপনার ইমেজে শনাক্ত হওয়া সমস্ত দুর্বলতা দেখতে পাবেন। উপরের দুর্বলতাগুলোর সারাংশের পাশাপাশি, আপনি নীচের টেবিলে দুর্বলতাগুলোর সম্পূর্ণ তালিকা দেখতে পাবেন। প্রতিটি সারি CVE বুলেটিনের সাথে লিঙ্ক করা থাকে, যা এর তীব্রতা এবং যে প্যাকেজ থেকে এটি এসেছে তা নির্দেশ করে। যেসব দুর্বলতার জন্য সমাধান (fix) পাওয়া যায়, সেগুলোর ক্ষেত্রে দুর্বলতাটি ঠিক করার জন্য ডিপেন্ডেন্সিগুলো কীভাবে আপডেট করতে হবে তার নির্দেশাবলীও দেওয়া থাকে।

fda03e6fd758ddef.png

৫. ভার্চুয়াল এবং রিমোট রিপোজিটরি

পূর্ববর্তী বিভাগে আমরা আমাদের ইমেজ পুশ এবং পুল করার জন্য একটি একক ইমেজ রিপোজিটরি ব্যবহার করেছি। এটি ছোট পরিসরের ব্যবহারের ক্ষেত্রে দারুণ কাজ করে, কিন্তু বিশেষ করে বড় সংস্থাগুলির জন্য এটি চ্যালেঞ্জ তৈরি করে, যেখানে বিভিন্ন দল তাদের রিপোজিটরিগুলির উপর স্বায়ত্তশাসন চায়। দল বা ব্যবসায়িক ইউনিটগুলির নিজস্ব অনুমতি এবং কনফিগারেশন সহ তাদের নিজস্ব ইমেজ রিপোজিটরি থাকাটা সাধারণ ব্যাপার। এই রিপোজিটরিগুলিতে থাকা ইমেজগুলির ব্যবহার সহজ করতে এবং ব্যবহারকারীকে অন্তর্নিহিত সাংগঠনিক কাঠামো থেকে আড়াল করতে, আর্টিফ্যাক্ট রেজিস্ট্রি ভার্চুয়াল রিপোজিটরি সরবরাহ করে যা একাধিক অন্তর্নিহিত রিপোজিটরি থেকে রিসোর্স একত্রিত করতে পারে। একটি সম্ভাব্য আর্কিটেকচার দেখতে এইরকম হতে পারে:

c6488dc5a6bfac3.png

ডকার হাবের জন্য রিমোট রিপোজিটরি

ডকার হাব একটি জনপ্রিয় পাবলিক ইমেজ রেজিস্ট্রি এবং এটি অনেক ওপেন-সোর্স কন্টেইনার ইমেজ হোস্ট করে। যদিও সরাসরি পাবলিক রিপোজিটরি ব্যবহার করা সহজ, প্রোডাকশন পরিবেশে এর সাথে বেশ কিছু চ্যালেঞ্জ রয়েছে যা আমরা আর্টিফ্যাক্ট রেজিস্ট্রি-এর রিমোট রিপোজিটরি ব্যবহার করে কাটিয়ে উঠতে পারি।

রিমোট রিপোজিটরি আপনাকে আপস্ট্রিম রেজিস্ট্রিতে পাঠানো অনুরোধগুলোকে প্রক্সি করার এবং সেই সাথে ইমেজগুলো ক্যাশ করার সুবিধা দেয়। এটি কেবল ইমেজ ডাউনলোডের সময়ই কমায় না, বরং বাহ্যিক পরিষেবার আপটাইমের উপর নির্ভরতাও দূর করে এবং আপনাকে আপনার নিজের ইমেজে প্রয়োগ করা একই নিরাপত্তা ও অ্যাক্সেস নীতিগুলো প্রয়োগ করার সুযোগ দেয়।

ডকার হাবের জন্য একটি রিমোট রিপোজিটরি তৈরি করতে আপনি ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালাতে পারেন:

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"

আপনি এখন আপনার আর্টিফ্যাক্ট রেজিস্ট্রি রিপোজিটরি তালিকায় একটি অতিরিক্ত রিপোজিটরি দেখতে পাবেন:

7e174a9944c5f34c.png

আপনার রিমোট রিপোজিটরি অনুরোধ প্রক্সি করতে সক্ষম কিনা তা পরীক্ষা করতে, ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালিয়ে এনজিনএক্স (nginx) ইমেজটি পুল করুন:

docker pull us-central1-docker.pkg.dev/$PROJECT_ID/dockerhub/nginx:stable-alpine

পুল সফল হলে আপনি ক্লাউড কনসোলে রিপোজিটরিটি দেখতে পারেন এবং সেখানে দেখতে পাবেন যে ক্যাশ করা এনজিনএক্স (nginx) ইমেজটি এখন সেই একই ডিপেন্ডেন্সি ও ভালনারেবিলিটি রিপোর্টিং প্রদান করছে, যা আমরা আপনার নিজের তৈরি করা ইমেজটির ক্ষেত্রে দেখেছিলাম।

একটি ভার্চুয়াল রিপোজিটরি তৈরি করা

এখন পর্যন্ত আমরা যে পদ্ধতিগুলো ব্যবহার করেছি তা অনুসরণ করে আপনি প্রতিটি টিম বা ব্যবসার জন্য একাধিক রিপোজিটরি তৈরি করতে পারেন এবং প্রতিটির জন্য মালিকানা ও IAM পারমিশন স্পষ্টভাবে নির্ধারণ করতে পারেন। আমরা রিমোট রিপোজিটরিগুলোর জন্য প্রক্সিও তৈরি করতে পারি, যা থার্ড-পার্টি ইমেজ ব্যবহার করাকে আরও সহজ ও নিরাপদ করে তোলে। এই বিপুল সংখ্যক রিপোজিটরির অসুবিধাটি স্পষ্ট হয়ে ওঠে যদি আপনি এই ইমেজগুলোর ব্যবহারকারীর দৃষ্টিকোণ থেকে বিষয়টি দেখেন। একজন ডেভেলপার কীভাবে জানবেন যে তার ডেপ্লয়মেন্টের জন্য কোন ইমেজ রিপোজিটরিটি ব্যবহার করা উচিত?

ব্যবহার সহজ করতে এবং অন্তর্নিহিত রিপোজিটরিগুলোকে একটি অ্যাবস্ট্রাকশন লেয়ারের আড়ালে রাখতে, আপনি ক্লাউড শেলে নিম্নলিখিত কমান্ডের মাধ্যমে আর্টিফ্যাক্ট রেজিস্ট্রি-তে একটি ভার্চুয়াল রিপোজিটরি তৈরি করতে পারেন:

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"

এখন আমরা অন্তর্নিহিত কাঠামো প্রকাশ না করেই ভার্চুয়াল রিপোজিটরি থেকে ইমেজগুলো পুল করতে পারি। সবকিছু প্রত্যাশা অনুযায়ী কাজ করছে কিনা তা যাচাই করতে, আপনি ক্লাউড শেলে নিম্নলিখিত কমান্ডগুলো চালাতে পারেন:

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

৬. ক্লাউড রানে স্থাপন করুন

সংশ্লিষ্ট রিপোজিটরি এবং ইমেজগুলো প্রস্তুত হয়ে গেলে, আমরা এখন একটি ডিপ্লয়মেন্টে সেগুলো ব্যবহার করার দিকে এগোতে পারি। একটি উদাহরণমূলক ব্যবহার দেখানোর জন্য এবং অতিরিক্ত পরিকাঠামো স্থাপন এড়ানোর জন্য, আমরা আমাদের কন্টেইনারটি ক্লাউড রান-এ ডিপ্লয় করব। এর সবচেয়ে সহজ রূপে, ক্লাউড শেল-এ নিম্নলিখিত কমান্ডটি চালানোর মাধ্যমে ডিপ্লয়মেন্টটি সম্পন্ন করা যায়:

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

আপনি যদি ওই ইউআরএলটি একটি নতুন ব্রাউজার ট্যাবে খোলেন, তাহলে সফল "হ্যালো ওয়ার্ল্ড" বার্তাটি দেখতে পাবেন।

852a8748c1543736.png

৭. সরবরাহ শৃঙ্খলের নিরাপত্তা জোরদার করা

এখন যেহেতু আপনার কন্টেইনার ইমেজটি লাইভ ডেপ্লয়মেন্টে পৌঁছে গেছে, তাই আমাদের এন্ড-টু-এন্ড সাপ্লাই চেইনকে কীভাবে আরও শক্তিশালী করা যায়, তা খতিয়ে দেখার এটাই উপযুক্ত সময় হতে পারে। আগের অংশে আমরা দেখেছি, আর্টিফ্যাক্ট রেজিস্ট্রির কন্টেইনার অ্যানালাইসিস কীভাবে ইমেজে ব্যবহৃত লাইব্রেরি এবং লাইসেন্সগুলো সম্পর্কে ধারণা দেয়। তবে, সাপ্লাই চেইন বরাবর ক্ষতিকারক ব্যক্তিদের পক্ষে আপনার ইমেজে ক্ষতিকর কন্টেন্ট প্রবেশ করানো এখনও সম্ভব। এই অংশে আমরা দেখব, কীভাবে আমরা SLSA ফ্রেমওয়ার্ক ব্যবহার করে বিল্ড আর্টিফ্যাক্টগুলোর জন্য অ্যাটেস্টেশন চালু করতে পারি এবং এমনকি আর্টিফ্যাক্টগুলোর ক্রিপ্টোগ্রাফিক সিগনেচার কাজে লাগিয়ে এটা নিশ্চিত করতে পারি যে, শুধুমাত্র বিশ্বস্ত আর্টিফ্যাক্টগুলোই আমাদের ক্লাউড রান রানটাইমে ডেপ্লয় করা যাবে।

ক্লাউড বিল্ডের সাথে এসএলএসএ অ্যাটেস্টেশন

SLSA ফ্রেমওয়ার্ক সাপ্লাই চেইন আর্টিফ্যাক্টগুলোর জন্য বিভিন্ন স্তরের প্রমাণ সরবরাহ করে। এর স্পেসিফিকেশন এবং বাস্তবায়ন প্রথম দর্শনে কঠিন মনে হতে পারে, কিন্তু ক্লাউড বিল্ডের সাহায্যে SLSA অ্যাটেস্টেশন তৈরি করা খুবই সহজ। এর জন্য শুধু একটি cloudbuild.yaml স্পেসিফিকেশন তৈরি করে requestedVerifyOption VERIFIED এ সেট করতে হয়।

আমাদের অ্যাপ্লিকেশনের জন্য, helloworld ফোল্ডারে একটি cloudbuild.yaml ফাইল তৈরি করতে আমরা ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালাতে পারি।

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

এখন আমরা ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালিয়ে একটি নতুন ক্লাউড বিল্ড জব তৈরি করব, যা আমাদের জাভা হ্যালো ওয়ার্ল্ড ইমেজের একটি নতুন সংস্করণ বিল্ড করবে।

gcloud builds submit --substitutions=_IMAGE_URI=us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:cloud-build

বিল্ডটি সম্পন্ন হয়ে গেলে, আমরা গুগল ক্লাউড কনসোলের ক্লাউড বিল্ড UI-তে গিয়ে আমাদের বিল্ডটি খুলে এবং তারপর বিল্ড সামারির অধীনে থাকা বিল্ড আর্টিফ্যাক্টস দেখে আমাদের অর্জিত SLSA লেভেলটি দেখতে পারি। সেখানে দেখা ছবিতে "সিকিউরিটি ইনসাইটস" দেখার জন্য একটি বাটন রয়েছে। এটিতে ক্লিক করলে আপনি SLSA অ্যাটেস্টেশনের পাশাপাশি সেই পরিচিত ভালনারেবিলিটি রিপোর্টগুলোও দেখতে পাবেন, যেগুলো আমরা আমাদের লোকাল বিল্ড পুশ করার সময় আর্টিফ্যাক্ট রেজিস্ট্রি UI-তে আগে দেখেছিলাম।

f6154004bfcddc16.png

ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালিয়ে আমাদের ইমেজের SLSA প্রোভেনেন্সও পুনরুদ্ধার করা যেতে পারে:

gcloud artifacts docker images describe \
"us-central1-docker.pkg.dev/$PROJECT_ID/container-example/java-hello-world:cloud-build" \
 --show-provenance 

বাইনারি অনুমোদনের সাথে ক্লাউড বিল্ড প্রোভেনেন্স প্রয়োজন

ক্লাউড বিল্ড পাইপলাইন চালু থাকলে, আমরা প্রোডাকশনে যে সমস্ত ইমেজ ডেপ্লয় করি, সেগুলো যেন সেই প্রোগ্রামযোগ্য ও পুনরুৎপাদনযোগ্য বিল্ড এনভায়রনমেন্ট ব্যবহার করে তৈরি করা হয়, তা নিশ্চিত করতে পারলে কি দারুণ হতো না?

এইখানেই বাইনারি অথরাইজেশন কাজে আসে। এটি আপনাকে আপনার কন্টেইনার রানটাইমগুলোর সামনে একজন গেটকিপার রাখার সুযোগ দেয়, যে কন্টেইনার ইমেজটি পরিদর্শন করে এবং একটি বিশ্বস্ত অ্যাটেস্টেশনের অস্তিত্ব যাচাই করে। যদি কোনো অ্যাটেস্টেশন খুঁজে না পাওয়া যায়, তবে কনফিগারেশনের উপর নির্ভর করে এটি হয় অডিট লগ এন্ট্রি তৈরি করে অথবা ডেপ্লয়মেন্টটি সম্পূর্ণরূপে ব্লক করে দেয়।

আমাদের প্রোজেক্টের ডিফল্ট বাইনারি অথরাইজেশন কনফিগারেশন পরিবর্তন করে ক্লাউড রান দ্বারা ইস্যু করা বিল্ট-ইন অ্যাটেস্টেশন বাধ্যতামূলক করতে, আমরা ক্লাউড শেলে নিম্নলিখিত কমান্ডটি রান করি:

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

এখানে আপনি অবশ্যই আপনার নিজস্ব অ্যাটেস্টরও যোগ করতে পারেন, কিন্তু তা এই কোডল্যাবের আওতার বাইরে এবং একটি ঐচ্ছিক পাঠ্যক্রম-বহির্ভূত বাড়ির কাজ হিসেবে রাখা হয়েছে।

আমাদের ক্লাউড রান সার্ভিসে বাইনারি অথরাইজেশন কার্যকর করতে আমরা ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালাই:

gcloud run services update hello-world \
  --region us-central1 \
  --binary-authorization=default

Let's test our Binary Authorization is applied correctly by re-deploying the locally built image first

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

সুতরাং, আমাদের ক্লাউড রান পরিষেবাতে একটি নতুন সংস্করণ স্থাপন করার জন্য ক্লাউড বিল্ড দিয়ে তৈরি একটি ইমেজ সরবরাহ করতে হবে।

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

৮. জাভা মেভেন ল্যাঙ্গুয়েজ প্যাকেজ পরিচালনা করা

এই অংশে আপনি দেখতে পাবেন কীভাবে একটি আর্টিফ্যাক্ট রেজিস্ট্রি জাভা রিপোজিটরি সেট আপ করতে হয়, এতে প্যাকেজ আপলোড করতে হয় এবং বিভিন্ন অ্যাপ্লিকেশনে সেগুলোকে কাজে লাগাতে হয়।

একটি Maven প্যাকেজ রিপোজিটরি তৈরি করুন

ক্লাউড শেল থেকে জাভা আর্টিফ্যাক্টের জন্য একটি রিপোজিটরি তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:

gcloud artifacts repositories create java-repo \
    --repository-format=maven \
    --location=us-central1 \
    --description="Example Java Maven Repo"

ক্লাউড শেল অথরাইজেশন প্রম্পট দেখা গেলে অথরাইজ-এ ক্লিক করুন।

Google Cloud Console - Artifact Registry - Repositories- এ যান এবং আপনার সদ্য তৈরি করা java-repo নামের Maven রিপোজিটরিটি লক্ষ্য করুন, সেটিতে ক্লিক করলে দেখতে পাবেন যে এই মুহূর্তে এটি খালি আছে।

আর্টিফ্যাক্ট রিপোজিটরিতে প্রমাণীকরণ সেট আপ করুন

অ্যাপ্লিকেশন ডিফল্ট ক্রেডেনশিয়ালস (ADC)-এর সুপরিচিত অবস্থানটি আপনার ব্যবহারকারী অ্যাকাউন্টের ক্রেডেনশিয়াল দিয়ে আপডেট করতে নিম্নলিখিত কমান্ডটি ব্যবহার করুন, যাতে আর্টিফ্যাক্ট রেজিস্ট্রি ক্রেডেনশিয়াল হেল্পার রিপোজিটরিগুলির সাথে সংযোগ করার সময় সেগুলি ব্যবহার করে প্রমাণীকরণ করতে পারে:

gcloud auth login --update-adc

আর্টিফ্যাক্ট রেজিস্ট্রির জন্য মেভেন কনফিগার করুন

আপনার জাভা প্রজেক্টে যোগ করার জন্য রিপোজিটরি কনফিগারেশন প্রিন্ট করতে নিম্নলিখিত কমান্ডটি চালান:

gcloud artifacts print-settings mvn \
    --repository=java-repo \
    --location=us-central1 | tee config.xml

helloworld ডিরেক্টরির ভেতর থেকে Cloud Shell-এ নিম্নলিখিত কমান্ডটি চালিয়ে pom.xml ফাইলটি Cloud Shell Editor-এ খুলুন:

cloudshell edit pom.xml

এবং প্রাপ্ত সেটিংসগুলো ফাইলের উপযুক্ত বিভাগগুলোতে যোগ করুন,

ডিস্ট্রিবিউশনম্যানেজমেন্ট বিভাগটি আপডেট করুন

<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>

আপনার জাভা প্যাকেজটি আর্টিফ্যাক্ট রেজিস্ট্রি-তে আপলোড করুন

Maven-এ Artifact Registry কনফিগার করা থাকলে, আপনি এখন আপনার প্রতিষ্ঠানের অন্যান্য প্রোজেক্টে ব্যবহারের জন্য Java Jar ফাইল সংরক্ষণ করতে এটি ব্যবহার করতে পারবেন।

আপনার জাভা প্যাকেজটি আর্টিফ্যাক্ট রেজিস্ট্রি-তে আপলোড করতে নিম্নলিখিত কমান্ডটি চালান:

mvn deploy

আর্টিফ্যাক্ট রেজিস্ট্রি-তে জাভা প্যাকেজটি পরীক্ষা করুন

ক্লাউড কনসোল - আর্টিফ্যাক্ট রেজিস্ট্রি - রিপোজিটরি- তে যান। java-repo এর ভিতরে ক্লিক করুন এবং পরীক্ষা করে দেখুন যে helloworld বাইনারি আর্টিফ্যাক্টটি সেখানে আছে কিনা:

a95d370ee0fd9af0.png

৯. অভিনন্দন!

অভিনন্দন, আপনি কোডল্যাবটি সম্পন্ন করেছেন!

আপনি যা যা আলোচনা করেছেন

  • কন্টেইনার এবং ল্যাঙ্গুয়েজ প্যাকেজের জন্য রিপোজিটরি তৈরি করা হয়েছে
  • আর্টিফ্যাক্ট রেজিস্ট্রি দিয়ে পরিচালিত কন্টেইনার ইমেজ
  • ক্লাউড কোডের সাথে সমন্বিত আর্টিফ্যাক্ট রেজিস্ট্রি
  • জাভা ডিপেন্ডেন্সিগুলির জন্য আর্টিফ্যাক্ট রেজিস্ট্রি ব্যবহার করতে মেভেন কনফিগার করা হয়েছে।

পরিষ্কার-পরিচ্ছন্নতা

সম্পূর্ণ প্রজেক্টটি মুছে ফেলার জন্য ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান।

gcloud projects delete $PROJECT_ID