Skip to content

Commit 91457c5

Browse files
authored
Add files via upload
1 parent 6a61af8 commit 91457c5

File tree

8 files changed

+319
-0
lines changed

8 files changed

+319
-0
lines changed
69.7 KB
Loading
19.9 KB
Loading
111 KB
Loading
31 KB
Loading
68.6 KB
Loading
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# ================================================================================
3+
# FIXED, DO NOT MODIFY THIS FILE
4+
# ================================================================================
5+
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
6+
title: "Next Steps" # Always the same, html page title.
7+
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
8+
---
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
title: "Background"
3+
4+
weight: 2
5+
6+
layout: "learningpathall"
7+
---
8+
9+
## What is the Axion Arm-based processor?
10+
11+
Axion is Google's first custom-designed Arm-based CPU, specifically built for data center workloads. It leverages the Armv9 architecture to deliver high performance and energy efficiency, targeting a wide range of applications, including web serving, data analytics, and machine learning.
12+
13+
The Google Axion VM instances are of below serie:
14+
15+
* The general-purpose `C4A` virtual machine series.
16+
17+
To learn more about Google Axion, refer to the blog ["Introducing Google Axion Processors, our new Arm-based CPUs"](https://cloud.google.com/blog/products/compute/introducing-googles-new-arm-based-cpu).
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
---
2+
title: "Build and deploy a .NET application"
3+
4+
weight: 3
5+
6+
layout: "learningpathall"
7+
---
8+
9+
In this Learning Path, you will build a .NET 6-based web application using a self-hosted GitHub Actions Arm64 runner. You will deploy the application in a GKE Cluster, running on Google Axion based VMs. Self-hosted runners offer increased control and flexibility in terms of infrastructure, operating systems, and tools, in comparison to GitHub-hosted runners.
10+
11+
{{% notice Note %}}
12+
* GitHub-hosted Arm64 runners have now reached General Availability. If your GitHub account is part of a Team or an Enterprise Cloud plan, you can use GitHub-hosted Arm64 runners.
13+
14+
* To learn how you can configure a GitHub-managed runner, see the Learning Path [*Build multi-architecture container images with GitHub Arm-hosted runners*](/learning-paths/cross-platform/github-arm-runners/).
15+
{{% /notice %}}
16+
17+
## How do I create a Virtual Machine in GCP?
18+
Creating a virtual machine based on Google Axion is no different from creating any other VM in GCP. To create a Google Axion virtual machine, launch the GCP portal and navigate to Virtual Machines.
19+
Please refer to "Create an Arm-based VM instance with Google Axion CPU" in [*Create an Axion instance*](/learning-paths/servers-and-cloud-computing/java-on-axion/1-create-instance) for creating Axion based VM instance.
20+
21+
## How do I configure the GitHub repository?
22+
23+
The source code for the application and configuration files that you require to follow this Learning Path are hosted in this [SampleDotNetApp github repository](https://github.com/odidev/SampleDotNetApp). This repository also contains the Dockerfile and Kubernetes deployment manifests that you require to deploy the .NET 6 based application.
24+
25+
Follow these steps:
26+
27+
* Start by forking the repository.
28+
29+
* Once the GitHub repository is forked, navigate to the `Settings` tab, and click on `Actions` in the left navigation pane.
30+
31+
* In `Runners`, select `New self-hosted runner`, which opens up a new page to configure the runner.
32+
33+
* For `Runner image`, select `Linux`, and for `Architecture`, select `ARM64`.
34+
35+
* Using the commands shown, execute them on the `c4a-standard-2` VM you created in the previous step.
36+
37+
* Once you have configured the runner successfully, you will see a self-hosted runner appear on the same page in GitHub.
38+
39+
{{% notice Note %}}
40+
To learn more about creating an Arm-based self-hosted runner, see this Learning Path [*Use Self-Hosted Arm64-based runners in GitHub Actions for CI/CD*](/learning-paths/laptops-and-desktops/self_hosted_cicd_github/).
41+
{{% /notice %}}
42+
43+
## How do I create an GKE cluster with Arm-based Axion nodes using Terraform?
44+
45+
You can create an Arm-based GKE cluster by following the steps in this Learning Path [*Deploy an Arm-based GKE Cluster of Axion VMs using Terraform*](/learning-paths/servers-and-cloud-computing/gke/cluster_deploymen/).
46+
47+
Make sure to update the `main.tf` file with the correct VM as shown below:
48+
49+
```console
50+
`machine_type ` = `c4a-standard-2`
51+
`disk_type` = `hyperdisk-balanced`
52+
```
53+
Once you have successfully created the cluster, you can proceed to the next section.
54+
55+
## How do I create a container registry with Artifact Registry?
56+
57+
Creating a Container Registry in Google Cloud Platform (GCP) is a straightforward process. Google Container Registry (GCR) is a private registry for storing and managing Docker container images. Here's a step-by-step guide to creating and using a container registry in GCP:
58+
1. Enable Required APIs
59+
- Enable the Container Registry API:
60+
- Navigate to the **API & Services** section in the Cloud Console.
61+
- Click on "**Enable APIs and Services**"
62+
- Search for "**Google Container Registry API**" and enable it.
63+
64+
- Enable the Google Cloud Storage API (if not already enabled):
65+
- Container Registry uses Google Cloud Storage to store container images, so this API must be enabled.
66+
67+
2. Generate a Service Account Key
68+
- In the Service Accounts list, click on the service account you just created.
69+
- Go to the "Keys" tab.
70+
- Click "Add Key" and select "Create New Key".
71+
- Choose the key type as JSON and click "Create"
72+
Download the Key File:
73+
- A JSON key file will be downloaded to your computer. This file contains the credentials for the service account.
74+
75+
3. Authenticate gcloud with the Service Account in self-hosted runner VM
76+
- upload json file in self-hosted runner VM and set the GOOGLE_APPLICATION_CREDENTIALS environment variable to point to the JSON key file:
77+
```console
78+
export GOOGLE_APPLICATION_CREDENTIALS="PATH_TO_JSON_KEY_FILE"
79+
```
80+
- Use the following command to authenticate gcloud with the service account:
81+
```console
82+
gcloud auth activate-service-account SERVICE_ACCOUNT_EMAIL --key-file=PATH_TO_JSON_KEY_FILE
83+
```
84+
Replace:
85+
SERVICE_ACCOUNT_EMAIL with the email address of the service account (e.g., [email protected]).
86+
PATH_TO_JSON_KEY_FILE with the full path to the JSON key file.
87+
4. Run the following command to verify that gcloud is authenticated with the service account:
88+
```console
89+
gcloud auth list
90+
```
91+
You should see the service account email listed as the active account.
92+
5. Set Your Project:
93+
- Set the default project for the SDK:
94+
```console
95+
gcloud config set project PROJECT_ID
96+
```
97+
Replace PROJECT_ID with your actual GCP project ID.
98+
99+
6. Choose a Registry Location:
100+
- GCR supports multiple regions. Choose a location as 'us-central1' to your deployment.
101+
102+
## How do I set up GitHub Secrets?
103+
104+
The next step allows GitHub Actions to access the google Container Registry to push application docker images and GKE to deploy application pods.
105+
106+
Create the following secrets in your GitHub repository:
107+
108+
- Populate `GCP_PROJECT_ID` with the name of your Project ID.
109+
- Populate `GCP_SA_KEY` with json key of a Service account you have downloaded in above steps.
110+
- Populate `GKE_CLUSTER_NAME` with the name of your GKE cluster.
111+
- Populate `GKE_REGION` with the name of your region.
112+
113+
## Deploy a .NET-based application
114+
115+
.NET added support for Arm64 applications starting with version 6. Several performance enhancements have been made in later versions. The latest version that supports Arm64 targets is .NET 9. In this Learning Path, you will use the .NET 6 SDK for application development.
116+
117+
Follow these steps:
118+
119+
* In your fork of the GitHub repository, inspect the `SampleDotNetApp.csproj` file.
120+
121+
* Verify that the `TargetFramework` field has `net6.0` as the value.
122+
123+
The contents of the file are shown below:
124+
125+
```console
126+
<Project Sdk="Microsoft.NET.Sdk.Web">
127+
<PropertyGroup>
128+
<TargetFramework>net6.0</TargetFramework>
129+
<Nullable>enable</Nullable>
130+
<ImplicitUsings>enable</ImplicitUsings>
131+
</PropertyGroup>
132+
</Project>
133+
```
134+
135+
You can inspect the contents of the `Dockerfile` within your repository as well. This is a multi-stage Dockerfile with the following stages:
136+
137+
1. `base` stage - prepares the base environment with the `.NET 6 SDK` and exposes ports 80 and 443.
138+
139+
2. `build` stage - restores dependencies and builds the application.
140+
141+
3. `publish` stage - publishes the application making it ready for deployment.
142+
143+
4. `final` stage - copies the published application into the final image and sets the entry point to run the application.
144+
145+
```console
146+
# Use the .NET SDK image for building
147+
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
148+
WORKDIR /src
149+
150+
# Copy the project file and restore dependencies
151+
COPY ["SampleDotNetApp.csproj", "./"]
152+
RUN dotnet restore
153+
154+
# Copy the rest of the application code
155+
COPY . .
156+
157+
# Build the application
158+
RUN dotnet build -c Release -o /app/build
159+
160+
# Publish the application
161+
RUN dotnet publish -c Release -o /app/publish
162+
163+
# Use the .NET runtime image for running the application
164+
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS runtime
165+
WORKDIR /app
166+
167+
# Copy the published application from the build stage
168+
COPY --from=build /app/publish .
169+
170+
# Expose ports
171+
EXPOSE 80
172+
EXPOSE 443
173+
EXPOSE 5000
174+
EXPOSE 8080
175+
176+
# Define the entry point for the container
177+
ENTRYPOINT ["dotnet", "SampleDotNetApp.dll"]
178+
```
179+
Next, navigate to the k8s folder and check the Kubernetes yaml files. The deployment.yml file defines a deployment for the application. It specifies the container image to use from gcr.io and exposes port 80 for the application. The deployment ensures that the application runs with the defined resource constraints and is accessible on the specified port.
180+
```yaml
181+
apiVersion: apps/v1
182+
kind: Deployment
183+
metadata:
184+
name: githubactions-gke-demo
185+
spec:
186+
selector:
187+
matchLabels:
188+
app: githubactions-gke-demo
189+
replicas: 3 # Adjust the number of replicas as needed
190+
template:
191+
metadata:
192+
labels:
193+
app: githubactions-gke-demo
194+
spec:
195+
containers:
196+
- name: githubactions-gke-demo
197+
image: gcr.io/<PROJECT_ID>/test:latest # Replace with your GCR image path
198+
resources:
199+
limits:
200+
memory: "128Mi"
201+
cpu: "250m"
202+
ports:
203+
- containerPort: 80
204+
imagePullSecrets:
205+
- name: gcr-json-key
206+
tolerations:
207+
- key: "kubernetes.io/arch"
208+
operator: "Equal"
209+
value: "arm64"
210+
effect: "NoSchedule"
211+
```
212+
The `service.yml` file defines a `Service` and uses `LoadBalancer` to expose the service externally on port 8080, directing traffic to the application’s container on port 80.
213+
214+
```yaml
215+
apiVersion: v1
216+
kind: Service
217+
metadata:
218+
name: githubactions-gke-demo-service
219+
spec:
220+
selector:
221+
app: githubactions-gke-demo # Matches the app label in the Deployment
222+
type: LoadBalancer # Creates a GCP Load Balancer
223+
ports:
224+
- port: 8080 # External port exposed by the Load Balancer
225+
targetPort: 80 # Internal port the container is listening on
226+
```
227+
228+
Finally, have a look at the GitHub Actions file located at `.github/workflows/deploytoAKS.yml`
229+
230+
```yaml
231+
name: Deploy .NET app to GCP
232+
233+
on:
234+
workflow_dispatch:
235+
push:
236+
237+
jobs:
238+
deploy:
239+
name: Deploy application to GKE
240+
runs-on: self-hosted # Use GCP-hosted runner or self-hosted if preferred
241+
242+
steps:
243+
- name: Checkout repo
244+
uses: actions/checkout@v3
245+
246+
- name: Set up Google Cloud SDK
247+
uses: google-github-actions/setup-gcloud@v1
248+
with:
249+
project_id: ${{ secrets.GCP_PROJECT_ID }}
250+
service_account_key: ${{ secrets.GCP_SA_KEY }}
251+
export_default_credentials: true
252+
253+
- name: Build Docker image
254+
run: docker buildx build --platform linux/arm64 -t githubactions-gke-demo:'${{ github.sha }}' .
255+
256+
- name: Tag and push Docker image to GCR
257+
run: |
258+
docker tag githubactions-gke-demo:'${{ github.sha }}' gcr.io/${{ secrets.GCP_PROJECT_ID }}/githubactions-gke-demo:'${{ github.sha }}'
259+
docker push gcr.io/${{ secrets.GCP_PROJECT_ID }}/githubactions-gke-demo:'${{ github.sha }}'
260+
261+
- name: Get GKE credentials
262+
run: |
263+
gcloud container clusters get-credentials ${{ secrets.GKE_CLUSTER_NAME }} \
264+
--region ${{ secrets.GKE_REGION }} \
265+
--project ${{ secrets.GCP_PROJECT_ID }}
266+
267+
- name: Deploy application to GKE
268+
run: kubectl apply -f k8s/deployment.yml -f k8s/service.yml
269+
```
270+
271+
This GitHub Actions yaml file defines a workflow to deploy a .NET application to Google Kubernetes Engine (GKE). This workflow runs on the self-hosted GitHub Actions runner that you configured in a previous step. This workflow can be triggered manually, or on a push to the repository.
272+
273+
It has the following main steps:
274+
275+
1. `Checkout repo` - checks out the repository code.
276+
2. `Build image` - builds a Docker image of the application.
277+
3. `Tag and push image` - tags and pushes the Docker image to Artifact Registry.
278+
4. `Get GKE credentials` - retrieves Google Kubernetes Cluster credentials.
279+
7. `Deploy application` - deploys the application to GKE using specified Kubernetes manifests.
280+
281+
## How do I run the CI/CD pipeline?
282+
283+
The next step is to trigger the pipeline manually by navigating to `Actions` tab in the GitHub repository. Select `Deploy .NET app`, and click on `Run Workflow`. You can also execute the pipeline by making a commit to the repository. Once the pipeline executes successfully, you will see the Actions output in a format similar to what is shown below:
284+
285+
![google-axion-vm #center](_images/workflow.png)
286+
287+
You can check your kubernetes cluster and see new application pods deployed on the cluster as shown below:
288+
![google-axion-vm #center](_images/nodes_and_pods.png)
289+
290+
You can also check the running application in browser with http://load_balancer_IP:8080 as shown below:
291+
![google-axion-vm #center](_images/website.png)
292+
293+
294+

0 commit comments

Comments
 (0)