Google Cloud Account Purchase: Building a Docker Deployment Instance Based on GCP Artifact Registry and GKE
Anyone who’s dabbled in cloud-native technologies or tinkered with Kubernetes has likely experienced the frustration of being bogged down by container image distribution and cluster deployments.
A typical on-premises workflow goes like this: after writing the code locally, you package it into a Docker image and push it to an open-source private registry such as Harbor or Docker Hub. Next, you’ll need to manage the pull‑stream credentials (Secrets) for your Kubernetes nodes yourself; once those credentials expire, the GKE (Google Kubernetes Engine) cluster will start generating a flood of error messages.
ImagePullBackOff
An inexplicable error (image pull failed). Not to mention that because the mirror warehouse and the computing cluster are not in the same computer room, when pulling large mirrors of several GB across regions, the high public network traffic fee and the maddening delay in pulling streams are too slow.
In Google Cloud’s (GCP) modern ecosystem, there is a textbook‑perfect enterprise‑grade golden combination:
Use Artifact Registry to manage container assets and cooperate with GKE for fully automatic container scheduling.
The invincibility of both of them lies in
The underlying permissions are naturally opened (based on IAM)
. You don't need to configure any cumbersome K8s Secret,GKE nodes can pull images and complete rolling updates in seconds with extremely high secure intranet bandwidth.
Today we do not pull the complicated distributed theory and reject any official black language. Starting directly from scratch, take you to package a Web application and deploy it to the GKE production cluster with the production standards of large factories.
The first stage: deep dismantling, cloud native delivery of the "three-dimensional world model"
Before you start typing commands, you must clear up the complete life cycle from code to public network. The whole enterprise-level assembly line consists of the following three core positions:
Container Terminal (Artifact Registry):GCP's new generation of specialized product warehouses (replacing the old GCR). It is responsible for storing your packaged Docker image version and comes with Google's large factory-level vulnerability scanning function.
Compute Engine (GKE cluster): Google‑managed Kubernetes service. You don't need to manage the underlying Master node, you just need to tell it through a declarative YAML file: "I want to run 3 copies of the Web container", and it will automatically help you stabilize in the background.
Security gateway (IAM role): This is the key to get through without key. We will attach a dedicated identity (Service Account) to GKE nodes, granting them the privilege to read images from Artifact Registry by default.
Phase 2: Environmental Preparedness-Opening the Infrastructure Territory on GCP
Please ensure that it is already installed and configured on your local machine.
Alright
Google Cloud CLI
CLI (Google Cloud Command-Line Interface) and the Docker Engine.
1. Activate the Core API (First Step in Starting Out)
In the terminal, enter this command to fully activate the Google Cloud infrastructure we need:
Bash
gcloud services enable container.googleapis.com artifactregistry.googleapis.com
2. Create a private image repository (Artifact Registry)
We are in the Taiwan region of China.
asia-east1
, with extremely low latency for domestic access) Set up a Docker‑specific registry; let’s assume the project ID is called
my-gke-project
:
Bash
gcloud artifacts repositories create gke-repo
--repository-format=docker
--location=asia-east1
--description="GKE Production Images Repository"
3. Create a Managed GKE Cluster (Autopilot Mode)
For small and medium-sized enterprises or teams that don’t want to be bogged down by the complexities of Kubernetes tuning,
We strongly recommend selecting Autopilot mode.
. You don’t need to worry about CPU and memory allocation on the nodes; Google automatically scales resources elastically based on your Pod specifications, and you’re billed only for the actual resources consumed by the Pods you run.
Bash
gcloud container clusters create-auto prod-gke-cluster
--location=asia-east1
(Creating the cluster will take approximately 3 to 5 minutes. Please grab a coffee and wait patiently.)
Phase 3: Hands-on Exercise 1 – Containerizing On-Premises Code and Pushing Streams to the Cloud
We assume you have a very simple web application running locally—whether it’s built with Node.js or Python—that listens on the local machine.
8080
Port.
1. Writing a Production-Ready Dockerfile
In the project root directory, create a new
Dockerfile
:
Dockerfile
# Use the official lightweight base image
FROM alpine:3.18
# Install runtime dependencies (using Python as an example)
RUN apk add --no-cache python3 py3-pip
WORKDIR /app
Carbon monoxide
PY . /app
# Expose business ports
EXPOSE 8080
# Start the Web service
CMD ["python3", "-m", "http.server", "8080"]
2. Binding secret: Configuring identity authentication between the local Docker and GCP
Many people encounter errors when pushing images here, because Docker does not recognize GCP’s container registry by default. We need to let
Google Cloud CLI
Inject the security credentials directly into the local Docker configuration file:
Bash
gcloud auth configure-docker asia-east1-docker.pkg.dev
3. Compile, tag, and force stream the content
According to Artifact Registry’s standard conventions, give the image a standardized name that includes a cloud-based path, then push it:
Bash
# Compile and package into version 1.0
docker build -t asia-east1-docker.pkg.dev/my-gke-project/gke-repo/my-web-app:v1.0.
# Fully Accelerate Cloud Migration of Traffic
docker push asia-east1-docker.pkg.dev/my-gke-project/gke-repo/my-web-app:v1.0
Once the progress bar completes, navigate to the Artifact Registry page in the GCP Console, and you’ll find that the image is securely stored in the cloud, with Google already performing automated OS vulnerability scans in the background.
Phase 4: Practical Exercise 2 – Deploying a GKE Cluster Using Declarative YAML
The image has been uploaded to the cloud—how do we get GKE to pull it and turn it into a real, service‑providing container (Pod)? In the Kubernetes world, we don’t run start commands; we write…
YAML configuration file
.
Connect locally to the newly created GKE cluster and retrieve the authentication credentials:
Bash
gcloud container clusters get-credentials prod-gke-cluster --location=asia-east1
Create a new one locally called
deployment.yaml
the file, paste the following declarative code that conforms to the multinational architecture standards of major companies:
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
labels:
app: web-se
service
spec:
replicas: 3# welding dead high available defense line: resident 3 container copies, broken one automatically pull up the new one
selector:
matchLabels:
app: web-service
template:
metadata:
labels:
app: web-service
spec:
containers:
-name: web-container
# Precisely point to the mirror path you just pushed to the Artifact Registry
image: asia-east1-docker.pkg.dev/my-gke-project/gke-repo/my-web-app:v1.0
ports:
-containerPort: 8080
resources:# Strictly limit resource specifications to prevent rogue code from draining the cluster.
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "200m"
memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
name: web-app-lb-service
spec:
Type: LoadBalancer# Let GKE automatically apply for a high-security global public network load balancing IP at the bottom of Google network
selector:
app: web-service
ports:
-protocol: TCP
port: 80# front-end public network gate port
targetPort: 8080# The actual port inside the container
In the terminal, run the one-click deployment command to submit this design blueprint to GKE:
Bash
kubectl apply -f deployment.yaml
The fifth stage: the moment to witness the miracle-on-line verification and fault fuse drill
After the deployment is complete, we use Kubernetes’ “Tianyan command” to monitor the infrastructure as it comes online:
Bash
kubectl get p
ODS
You will see three green lights illuminate on the screen.
Running
A Pod in a certain state.
Here’s the key point: throughout this process, we didn’t configure any image pull secrets (ImagePullSecrets). Thanks to its native IAM permissions, GKE securely pulled the private images from Artifact Registry directly!
Next, look at the public network load balancing external network gate allocated by Google for us:
Bash
kubectl get service web-app-lb-service
You will see
EXTERNAL-IP
A golden public static IP address has appeared in the field (for example,
34.120.x.x
). Enter this IP address in your browser, and the page will load instantly—your cloud-native web service is now officially accessible to the public!
"Body Melting Exercise" to Simulate Production Environment"
To test GKE’s self-healing capabilities, we deliberately introduced faults in the backend. Manually delete one of the running containers (Pods):
Bash
kubectl delete pod web-app-deployment-xxxxxx-xxxxx
The moment you delete it, you go to refresh the page again, the website
Absolutely no lag or interruptions.
(Because the other 2 copies are carrying traffic). Even more remarkable, when you run it again…
kubectl get pods
At that moment, you’ll find that a brand-new Pod has been automatically brought up within seconds and has transitioned to a healthy state. This is the power of GKE’s automated management of declarative ReplicaSets.
Stage Six: A Painful, Lessons-Learned Journey Avoiding Pitfalls in Global Cloud-Native Business
Once this solution is successfully implemented, you will have already overcome the most formidable hurdle in cloud-native adoption. However, to survive in a true enterprise‑level, high‑concurrency environment, as an architect you must immediately implement a second layer of configuration hardening to guard against the following two hidden pitfalls:
1. Never use
latest
Tag (the root of all evil in release management)
Many teams take the easy way out and tag each locally built image every time.
my-web-app:latest
The label is pushed up. It's also written in YAML.
image: ...:latest
.
Disaster: When a bug occurs in the online code and needs to be rolled back urgently, you will find that all historical versions have been washed away by latest. Moreover, K8s has a mirror cache mechanism at the bottom. If it finds that there is already a latest mirror locally, even if you push new code, it may be lazy to directly reuse the old mirror locally, resulting in your new version not being released at all.
Big factory standard solution: resolutely cut off the use of latest. Each time you push a stream, you must use a version number with semantic meaning (such as v1.0, v1.1), or
Use Git's Commit ID directly. When releasing a new version, modify the version number in YAML to allow GKE to perform perfect rolling updates (Rolling Update) to achieve zero business downtime.
2. Automatic disconnection of stuck Artifact Registry (life cycle management)
If the development team has set up a CI/CD automation pipeline (such as GitHub Actions or GitLab CI), each code merge will automatically produce a multi-gigabyte image that gets pushed to Artifact Registry. If left unchecked, the warehouse will soon be piled high with tens of thousands of outdated historical images, and the end-of-month Google Cloud Storage bill could really make the boss wince.
A hardcore cost-saving tip: In the Artifact Registry repository settings, enable “Cleanup Policies.”
Cold asset automatic purging rule: Configure a rule as follows: “For temporary intermediate images that have no tags (Untagged), if they are older than 7 days, they shall be physically destroyed immediately”; or “For images with version tags, retain only the 20 most recent versions, and automatically purge older ones.” Let the system automatically declutter for you, helping your company’s cloud assets save on costly idle storage fees.
Summary
By leveraging GCP Artifact Registry and GKE to build a cloud-native deployment, the core industrial-grade essence can be summarized in sixteen characters:
Image version locking, secure pull without credentials, replica declaration for stability, automatic repository cleanup.
.
With this closed-loop golden combination, you’ve been completely freed from the tedious chore of server environment configuration, the complexity of setting up network load balancing, and the grueling task of manually monitoring for outages. Return all the energy to the code and the business itself. On top of Google's world-class cloud native infrastructure, your application will have unlimited flexibility and automatic disaster tolerance.
gcloud services enable container.googleapis.com artifactregistry.googleapis.com
2. Create a private image repository (Artifact Registry)
We are in the Taiwan region of China.
asia-east1
, with extremely low latency for domestic access) Set up a Docker‑specific registry; let’s assume the project ID is called
my-gke-project
:
Bash
gcloud artifacts repositories create gke-repo
--repository-format=docker
--location=asia-east1
--description
option="GKE Production Images Repository"
3. Create a Managed GKE Cluster (Autopilot Mode)
For small and medium-sized enterprises or teams that don’t want to be bogged down by the complexities of Kubernetes tuning,
We strongly recommend selecting Autopilot mode.
. You don’t need to worry about CPU and memory allocation on the nodes; Google automatically scales resources elastically based on your Pod specifications, and you’re billed only for the actual resources consumed by the Pods you run.
Bash
gcloud container clusters create-auto prod-gke-cluster
--location=asia-east1
(Creating the cluster will take approximately 3 to 5 minutes. Please grab a coffee and wait patiently.)
Phase 3: Hands-on Exercise 1 – Containerizing On-Premises Code and Pushing Streams to the Cloud
We assume you have a very simple web application running locally—whether it’s built with Node.js or Python—that listens on the local machine.
8080
Port.
1. Writing a Production-Ready Dockerfile
In the project root directory, create a new
Dockerfile
:
# Use the official lightweight base image
FROM alpine:3.18
# Install runtime dependencies (using Python as an example)
RUN apk add --no-cache python3 py3-pip
WORKDIR /app
COPY . /app
# Expose business ports
EXPOSE 8080
# Start the Web service
CMD ["python3", "-m", "http.server", "8080"]
2. Binding secret: Configuring identity authentication between the local Docker and GCP
Many people encounter errors when pushing images here, because Docker does not recognize GCP’s container registry by default. We need to let
Google Cloud CLI
Inject the security credentials directly into the local Docker configuration file:
Bash
gcloud auth configure-docker asia-east1-docker.pkg.dev
3. Compile, tag, and force stream the content
According to Artifact Registry’s standard conventions, give the image a standardized name that includes a cloud-based path, then push it:
Bash
# Compile and package into version 1.0
docker build -t asia-east1-docker.pkg.dev/my-gke-project/gke-repo/my-web-app:
v1.0.
# Fully Accelerate Cloud Migration of Traffic
docker push asia-east1-docker.pkg.dev/my-gke-project/gke-repo/my-web-app:v1.0
Once the progress bar completes, navigate to the Artifact Registry page in the GCP Console, and you’ll find that the image is securely stored in the cloud, with Google already performing automated OS vulnerability scans in the background.
Phase 4: Practical Exercise 2 – Deploying a GKE Cluster Using Declarative YAML
The image has been uploaded to the cloud—how do we get GKE to pull it and turn it into a real, service‑providing container (Pod)? In the Kubernetes world, we don’t run start commands; we write…
YAML configuration file
.
Connect locally to the newly created GKE cluster and retrieve the authentication credentials:
Bash
gcloud container clusters get-credentials prod-gke-cluster --location=asia-east1
Create a new one locally called
deployment.yaml
the file, paste the following declarative code that conforms to the multinational architecture standards of major companies:
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
labels:
app: web-service
spec:
replicas: 3# Hard-coded high-availability defense: maintain 3 container replicas; if one fails, a new one is automatically brought up.
selector:
matchLabels:
app: web-service
template:
metadata:
labels:
app: web-service
spec:
containers:
-name: web-container
# Precisely specify the image path you just pushed to Artifact Registry
image: asia-east1-docker.pkg.dev/my-gke-project/gke-repo/my-web-app:v1.0
sports:
-containerPort: 8080
resources:# Strictly limit resource specifications to prevent being squeezed by rogue code
dry cluster
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "200m"
memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
name: web-app-lb-service
spec:
type: LoadBalancer# Have GKE automatically request a globally accessible, DDoS‑protected load balancer IP from Google’s underlying network infrastructure
selector:
app: web-service
sports:
-protocol: TCP
port: 80# Frontend public gateway port
targetPort: 8080# The actual port inside the container
In the terminal, run the one-click deployment command to submit this design blueprint to GKE:
Bash
kubectl apply -f deployment.yaml
Phase 5: The Moment of Truth—Go-Live Validation and Fault-Cutting Drills
After the deployment is complete, we use Kubernetes’ “Tianyan command” to monitor the infrastructure as it comes online:
Bash
kubectl get pods
You will see three green lights illuminate on the screen.
Running
A Pod in a certain state.
Here’s the key point: throughout this process, we didn’t configure any image pull secrets (ImagePullSecrets). Thanks to its native IAM permissions, GKE securely pulled the private images from Artifact Registry directly!
Next, check the public-facing gateway of the Google‑assigned external load balancer:
Bash
kubectl get service web-app-lb-service
You will see
EXTERNAL-IP
A golden public static IP address has appeared in the field (for example,
34.120.x.x
). Enter this IP address in your browser, and the page will load instantly—your cloud-native web service is now officially accessible to the public!
“Meltdown drills” simulating the production environment
To test GKE’s self-healing capabilities, we deliberately introduced faults in the backend. Manually delete one of the running containers (Pods):
Bash
kubectl delete pod web-app-deployment-xxxxxx-xxxxx
The moment you delete it, you brush it again.
New pages, websites
Absolutely no lag or interruptions.
(Because the other two replicas are handling the traffic). Even more remarkable, when you run it again…
kubectl get pods
At that moment, you’ll find that a brand-new Pod has been automatically brought up within seconds and has transitioned to a healthy state. This is the power of GKE’s automated management of declarative ReplicaSets.
Stage Six: A Painful, Lessons-Learned Journey Avoiding Pitfalls in Global Cloud-Native Business
Once this solution is successfully implemented, you will have already overcome the most formidable hurdle in cloud-native adoption. However, to survive in a true enterprise‑level, high‑concurrency environment, as an architect you must immediately implement a second layer of configuration hardening to guard against the following two hidden pitfalls:
1. Never use
latest
Tag (the root of all evil in release management)
Many teams take the easy way out and tag each locally built image every time.
my-web-app:latest
Push the tag up. It’s also written in YAML.
image: ...:latest
.
When disaster strikes—say, a bug in your production code forces an urgent rollback—you’ll find that all previous versions have been overwritten by the `latest` tag. Moreover, Kubernetes has an image‑caching mechanism at the lower level. If it detects that a `latest` image is already present locally, even after you’ve pushed new code, it may skip pulling the updated image and simply reuse the old one, preventing your new version from being deployed.
Standard practice at major companies: firmly eliminate the use of `latest`. For each stream push, you must use the version number with semantics (such as v1.0 and v1.1) or directly use Git's Commit ID. When releasing a new version, update the version number in the YAML file to enable GKE’s seamless rolling update, ensuring zero downtime during deployments.
2. Prevent Artifact Registry’s automatic cleanup (lifecycle management) from getting stuck
If the development team has set up a CI/CD automation pipeline (such as GitHub Actions or GitLab CI), each code merge will automatically produce a multi-gigabyte image that gets pushed to Artifact Registry. If left unchecked, the warehouse will soon be piled high with tens of thousands of outdated historical images, and the end-of-month Google Cloud Storage bill could really make the boss wince.
A hardcore cost-saving tip: In the Artifact Registry repository settings, enable “Cleanup Policies.”
Cold asset automatic purging rule: Configure a rule as follows: “For temporary intermediate images that have no tags (Untagged), if they are older than 7 days, they shall be physically destroyed immediately”; or “For images with version tags, retain only the 20 most recent versions, and automatically purge older ones.” Let the system help you automatically cut off, can help the company's cloud assets save
high idle storage fees.
Summary
By leveraging GCP Artifact Registry and GKE to build a cloud-native deployment, the core industrial-grade essence can be summarized in sixteen characters:
Image version locking, secure pull without credentials, replica declaration for stability, automatic repository cleanup.
.
With this closed-loop golden combination, you’ve been completely freed from the tedious chore of server environment configuration, the complexity of setting up network load balancing, and the grueling task of manually monitoring for outages. Focus all your energy on the code and the business itself. Built on Google’s world‑class cloud‑native infrastructure, your applications will benefit from limitless scalability and automated disaster recovery—backed by the confidence of a leading global tech giant.
