Skip to content

Commit 822d0d9

Browse files
Merge pull request #2073 from jeffdyoung/ocpblog
Multi-Architecture Applications with Red Hat OpenShift
2 parents 533d2bd + 75e955b commit 822d0d9

File tree

4 files changed

+328
-0
lines changed

4 files changed

+328
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
title: Building Multi-Architecture Applications with Red Hat OpenShift Pipelines on Red Hat OpenShift 4.18 on AWS
3+
4+
minutes_to_complete: 30
5+
6+
who_is_this_for: This learning path is for Openshift administrators interested in migrating their applications to Arm.
7+
8+
9+
learning_objectives:
10+
- Migrate existing applications to Arm.
11+
12+
prerequisites:
13+
- An AWS account with an OpenShift 4.18 cluster with x86 nodes installed and configured.
14+
- Red Hat OpenShift Pipelines (Tekton) operator installed in your cluster.
15+
- Familiarity with Red Hat OpenShift (oc CLI), container concepts, and basic Tekton principles (Task, Pipeline, PipelineRun).
16+
- Access to your Red Hat OpenShift cluster with cluster-admin or equivalent privileges for node configuration and pipeline setup.
17+
- Your application source code in a Git repository. In this example we assume that you have [pipelines-tutorial](https://www.google.com/url?q=https://github.com/openshift/pipelines-tutorial&sa=D&source=editors&ust=1749822472437927&usg=AOvVaw2P4wUOL5KUV-ePkRiv3jJx) built and running on x86.
18+
- Ensure that the Red Hat OpenShift cluster is using the multi-arch release payload.
19+
20+
author: Jeff Young
21+
22+
### Tags
23+
skilllevels: Advanced
24+
subjects: CI-CD
25+
armips:
26+
- Aarch64
27+
tools_software_languages:
28+
- Tekton
29+
- OpenShift
30+
operatingsystems:
31+
- Linux
32+
33+
### FIXED, DO NOT MODIFY
34+
# ================================================================================
35+
weight: 1 # _index.md always has weight of 1 to order correctly
36+
layout: "learningpathall" # All files under learning paths have this same wrapper
37+
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
38+
---
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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
title: Conclusion
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
### Conclusion
9+
10+
Automating native builds for different architectures using Red Hat OpenShift Pipelines on Red Hat OpenShift 4.18 on AWS streamlines the development and deployment of versatile applications. By setting up distinct pipelines that leverage nodeSelector to build on x86\_64 and Arm64 nodes, you ensure that your application components are optimized for their target environments. This approach provides a clear and manageable way to embrace multi-architecture computing in the cloud.
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
---
2+
title: How to Migrate an x86 Workload to Arm64 on AWS
3+
weight: 2
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
### 1. Assess Workload Compatibility
10+
11+
Before migrating, determine whether your applications can run on 64-bit Arm architecture. Most modern applications built with portable runtimes (e.g., Java, Go, Python, Node.js) can run seamlessly on 64-bit Arm with little or no modifications. Check your container images and dependencies for 64-bit Arm compatibility. Fortunately, our [pipelines-tutorial](https://www.google.com/url?q=https://github.com/openshift/pipelines-tutorial&sa=D&source=editors&ust=1749822472442265&usg=AOvVaw1m8Dc2XNThwRLw9jJ9AX-L) doesn't have these restrictions.
12+
13+
### 2. Enable Multi-Arch Support in Red Hat OpenShift
14+
15+
Red Hat OpenShift supports multi-architecture workloads, allowing you to run both 64-bit x86 and 64-bit Arm based nodes in the same cluster. Red Hat OpenShift's [documentation](https://www.google.com/url?q=https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/postinstallation_configuration/configuring-multi-architecture-compute-machines-on-an-openshift-cluster%23multi-architecture-verifying-cluster-compatibility_creating-multi-arch-compute-nodes-aws&sa=D&source=editors&ust=1749822472444182&usg=AOvVaw3zaXidSPcmXJdpHXRLF8jq) will be your guide for this process.
16+
17+
### 3. Add 64-bit Arm MachineSets
18+
19+
To migrate to Graviton-based EC2 instances:
20+
21+
Ensure that the Red Hat Openshift cluster is using the multi-arch release payload.
22+
23+
```
24+
$oc adm release info -o jsonpath="{ .metadata.metadata}"
25+
{"release.openshift.io/architecture":"multi","url":"https://access.redhat.com/errata/xxx"}$
26+
27+
```
28+
29+
* Decide on a scheduling strategy. Manual with Taints/Tolerations, or [Multiarch Tuning O](https://www.google.com/url?q=https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/postinstallation_configuration/configuring-multi-architecture-compute-machines-on-an-openshift-cluster%23multiarch-tuning-operator&sa=D&source=editors&ust=1749822472450131&usg=AOvVaw1zslJ0RW8K9Lq_t6bf9Jrt)[perator](https://www.google.com/url?q=https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/postinstallation_configuration/configuring-multi-architecture-compute-machines-on-an-openshift-cluster%23multiarch-tuning-operator&sa=D&source=editors&ust=1749822472450917&usg=AOvVaw1QxXa3syc7ziLPLvut2YZv).
30+
Since we have 1 workload (our build pipeline) we'll go the Taint and Toleration routes. We've added this taint to our new Arm machine sets:
31+
32+
```
33+
taints:
34+
35+
- effect: NoSchedule
36+
37+
key: newarch
38+
39+
value: arm64
40+
```
41+
This prevents existing x86 workloads from being scheduled to the Arm nodes.
42+
43+
* Reimport needed imagestreams with import-mode set to 'PreserveOriginal'
44+
45+
```
46+
oc import-image php -n openshift --all --confirm --import-mode='PreserveOriginal'
47+
oc import-image python -n openshift --all --confirm --import-mode='PreserveOriginal'
48+
```
49+
50+
### 4. Rebuild and Verify Container Images
51+
52+
Note: Red Hat OpenShift only supports native architecture container builds. Cross-architecture container builds are not supported.
53+
54+
To build 64-bit Arm compatible images, we've modified the openshift-pipelines tutorial to patch deployments with the Tekton Task's podTemplate information. This will allow us to pass a podTemplate for building and deploying our newly built application on the target architecture. It also makes it easy to revert back to 64-bit x86 by re-running the pipeline without the template.
55+
56+
Create a podTemplate defining a toleration and a node affinity to make the builds deploy on arm machines:
57+
58+
arm64.yaml
59+
```
60+
tolerations:
61+
62+
- key: "newarch"
63+
64+
value: "arm64"
65+
66+
operator: "Equal"
67+
68+
effect: "NoSchedule"
69+
70+
affinity:
71+
72+
nodeAffinity:
73+
74+
requiredDuringSchedulingIgnoredDuringExecution:
75+
76+
nodeSelectorTerms:
77+
78+
- matchExpressions:
79+
80+
- key: "kubernetes.io/arch"
81+
82+
operator: "In"
83+
84+
values:
85+
86+
* "arm64"
87+
88+
- key: "kubernetes.io/os"
89+
90+
operator: "In"
91+
92+
values:
93+
94+
- "linux"
95+
```
96+
97+
Next we update 02\_update\_deployment\_task.yaml
98+
This includes extract patching to include the podTemplate's nodeAffinity/tolerations.
99+
100+
02\_update\_deployment\_task.yaml
101+
```
102+
apiVersion: tekton.dev/v1
103+
104+
kind: Task
105+
106+
metadata:
107+
108+
name: update-deployment
109+
110+
spec:
111+
112+
params:
113+
114+
- name: deployment
115+
116+
description: The name of the deployment patch the image
117+
118+
type: string
119+
120+
- name: IMAGE
121+
122+
description: Location of image to be patched with
123+
124+
type: string
125+
126+
- name: taskrun-name
127+
128+
type: string
129+
130+
description: Name of the current TaskRun (injected from context)
131+
132+
steps:
133+
134+
- name: patch
135+
136+
image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest
137+
138+
command: \["/bin/bash", "-c"\]
139+
140+
args:
141+
142+
- |-
143+
144+
oc patch deployment $(inputs.params.deployment) --patch='{"spec":{"template":{"spec":{
145+
146+
"containers":\[{
147+
148+
"name": "$(inputs.params.deployment)",
149+
150+
"image":"$(inputs.params.IMAGE)"
151+
152+
}\]
153+
154+
}}}}'
155+
156+
\# Find my own TaskRun name
157+
158+
MY\_TASKRUN\_NAME="$(params.taskrun-name)"
159+
160+
echo "TaskRun name: $MY\_TASKRUN\_NAME"
161+
162+
\# Fetch the podTemplate
163+
164+
PODTEMPLATE\_JSON=$(kubectl get taskrun "$MY\_TASKRUN\_NAME" -o jsonpath='{.spec.podTemplate}')
165+
166+
if \[ -z "$PODTEMPLATE\_JSON" \]; then
167+
168+
echo "No podTemplate found in TaskRun...Remove tolerations and affinity."
169+
170+
oc patch deployment "$(inputs.params.deployment)" \\\\
171+
172+
--type merge \\\\
173+
174+
-p "{\\"spec\\": {\\"template\\": {\\"spec\\": {\\"tolerations\\": null, \\"affinity\\": null}}}}"
175+
176+
else
177+
178+
echo "Found podTemplate:"
179+
180+
echo "$PODTEMPLATE\_JSON"
181+
182+
oc patch deployment "$(inputs.params.deployment)" \\\\
183+
184+
--type merge \\\\
185+
186+
-p "{\\"spec\\": {\\"template\\": {\\"spec\\": $PODTEMPLATE\_JSON }}}"
187+
188+
fi
189+
190+
\# issue: https://issues.redhat.com/browse/SRVKP-2387
191+
192+
\# images are deployed with tag. on rebuild of the image tags are not updated, hence redeploy is not happening
193+
194+
\# as a workaround update a label in template, which triggers redeploy pods
195+
196+
\# target label: "spec.template.metadata.labels.patched\_at"
197+
198+
\# NOTE: this workaround works only if the pod spec has imagePullPolicy: Always
199+
200+
patched\_at\_timestamp=\`date +%s\`
201+
202+
oc patch deployment $(inputs.params.deployment) --patch='{"spec":{"template":{"metadata":{
203+
204+
"labels":{
205+
206+
"patched\_at": '\\"$patched\_at\_timestamp\\"'
207+
208+
}
209+
210+
}}}}'
211+
```
212+
And we need to update 04\_pipeline.yaml to pass the taskrun-name to the update-deployment task:
213+
214+
```
215+
- name: update-deployment
216+
217+
taskRef:
218+
219+
name: update-deployment
220+
221+
params:
222+
223+
- name: deployment
224+
225+
value: $(params.deployment-name)
226+
227+
- name: IMAGE
228+
229+
value: $(params.IMAGE)
230+
231+
- name: taskrun-name //add these
232+
233+
value: $(context.taskRun.name) //lines
234+
```
235+
236+
Now we can redeploy the UI and API using the arm64.yaml podTemplate. This will force all parts of the build pipeline and deployment to our tainted 64-bit Arm nodes.
237+
```
238+
tkn pipeline start build-and-deploy \\\\
239+
240+
--prefix-name build-deploy-api-pipelinerun-arm64 \\\\
241+
242+
-w name=shared-workspace,volumeClaimTemplateFile=https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/01\_pipeline/03\_persistent\_volume\_claim.yaml \\\\
243+
244+
-p deployment-name=pipelines-vote-api \\\\
245+
246+
-p git-url=https://github.com/openshift/pipelines-vote-api.git \\\\
247+
248+
-p IMAGE=image-registry.openshift-image-registry.svc:5000/pipelines-tutorial/pipelines-vote-api-arm64
249+
250+
--use-param-defaults \\\\
251+
--pod-template arm64.yaml
252+
```
253+
```
254+
tkn pipeline start build-and-deploy \\\\
255+
256+
--prefix-name build-deploy-ui-pipelinerun-arm64 \\\\
257+
258+
-w name=shared-workspace,volumeClaimTemplateFile=https://raw.githubusercontent.com/openshift/pipelines-tutorial/master/01\_pipeline/03\_persistent\_volume\_claim.yaml \\\\
259+
260+
-p deployment-name=pipelines-vote-ui \\\\
261+
262+
-p git-url=https://github.com/openshift/pipelines-vote-ui.git \\\\
263+
264+
-p IMAGE=image-registry.openshift-image-registry.svc:5000/pipelines-tutorial/pipelines-vote-ui-arm64 \\\\
265+
266+
--use-param-defaults \\\\
267+
--pod-template arm64.yaml
268+
```
269+
270+
Once the pods are up and running, you can safely remove the x86 worker nodes from the cluster, and remove the taints from the Arm worker nodes (if you choose to do so).
271+
272+

0 commit comments

Comments
 (0)