This text was initially revealed by Ampere Computing.

As a developer or utility administrator, when you design and handle cloud-native purposes on Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) x86 situations and you’re questioning methods to leverage the decrease value and better efficiency of OCI Ampere A1 primarily based situations and not using a full carry and shift migration to Arm64, this publish is for you.

On this publish, we are going to showcase an incremental migration of a full stack cloud-native utility to OKE Ampere A1 situations. We are going to use WordPress for instance LAMP (Linux, Apache, MySQL, PHP) stack utility. Every element on this utility stack is comparatively impartial of the others, and so redeploying anyone element β€” for instance, the MySQL database to an Ampere node β€” is simple.

We’ll take a step-by-step take a look at methods to migrate the MySQL database on OKE, with nearly no downtime, from VM.Standard3.Flex (Intel) nodes to VM.Normal.A1.Flex (Ampere) nodes. We start by deploying WordPress from a Bitnami maintained Helm chart, with one Apache/PHP WordPress pod, a major MySQL pod, and one secondary reproduction MySQL pod, all working on x86 nodes, with information being saved on OCI block quantity and file storage for persistence. This database structure makes use of MySQL asynchronous replication the place the first node is the replication supply.

We are going to then create an Arm64 node pool and add further MySQL replicas that may run on these newly created nodes, which can routinely replicate the information and be certain that all of our information is now out there on the Arm64-hosted MySQL nodes. Lastly, we are going to make one of many Arm64-hosted nodes the first node for our MySQL cluster and shut down the x86-hosted database nodes. In the long run, you now have a hybrid x86/Arm64 cluster with WordPress containers working on x86, and MySQL working on Arm64.

An architectural diagram representing the WordPress deployment

An architectural diagram representing the WordPress deployment

Deploy WordPress Software on OKE 3-Node Cluster

We begin by creating an OKE cluster utilizing the OCI net console. The cluster is about up with three nodes, utilizing the VM.Standard3.flex form. We use bitnami/wordpress and bitnami/mysql containers for deploying the appliance. Each these photographs are supported on x86 in addition to Arm64 and use helm charts for simple deployment and upgrades utilizing Kubernetes manifest information.

Step-by-step directions for deploying the appliance are offered within the Appendix part.

As soon as the cluster is created and the appliance deployed, confirm the WordPress frontend and utility pod, MySQL major pod and MySQL secondary pod are up and working on the OKE cluster:

$ kubectl get pods -o large
NAME                              READY   STATUS    RESTARTS   AGE     IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   1/1     Working   0          119s    10.244.3.134   10.0.10.217   <none>           <none>
wordpress-mysql-primary-0         1/1     Working   0          5m23s   10.244.4.2     10.0.10.78    <none>           <none>
wordpress-mysql-secondary-0       1/1     Working   0          5m23s   10.244.4.131   10.0.10.214   <none>           <none>

Migrate MySQL Secondary Database to Ampere A1 Occasion

Subsequent, we are going to add Ampere A1 situations to the OKE cluster after which prolong the WordPress utility’s MySQL database to run on the A1 situations in just a few straightforward steps. As a basic finest apply, it’s really useful to check the method in a non-production setting.

Step 1: Add an Ampere A1 node pool to your OKE cluster

Utilizing the OCI console, replace your OKE cluster and add a brand new node pool. Use the identical placement configuration as your x86 nodes.

Choose the VM.Normal.A1.Flex form. Select 2x the variety of OCPUs as your x86 nodes, for instance 2 OCPUs on VM.Normal.3.Flex occasion is equal to 4 OCPUs on VM.Normal.A1.Flex occasion. The Oracle CPU (OCPU) unit of measurement for x86 OCPUs is price two vCPUs however an Ampere OCPU is a single vCPU.

A brand new node-pool and new situations with Ampere A1 shapes might be added to your cluster. We are going to migrate the MySQL pods to the newly added Arm64 nodes.

Node details

$ kubectl get nodes -o large -l kubernetes.io/arch=amd64
NAME          STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                  CONTAINER-RUNTIME
10.0.10.214   Prepared    node    40m   v1.26.2   10.0.10.214   <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
10.0.10.217   Prepared    node    41m   v1.26.2   10.0.10.217   <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
10.0.10.78    Prepared    node    41m   v1.26.2   10.0.10.78    <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8

$ kubectl get nodes -o large -l kubernetes.io/arch=arm64
NAME          STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                   CONTAINER-RUNTIME
10.0.10.122   Prepared    node    2m38s   v1.26.2   10.0.10.122   <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8
10.0.10.82    Prepared    node    2m15s   v1.26.2   10.0.10.82    <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8

Step 2: Prolong the MySQL secondary pod to an Ampere A1 node

With the intention to migrate the MySQL secondary pod, begin by including a reproduction of the secondary pod on the Arm64 node. This step is elective. We are going to deploy a number of replicas of the MySQL secondary pod to make sure information consistency and availability on the brand new Arm64 occasion. If you do not need to create a number of replicas, you may skip to the subsequent step and migrate the MySQL secondary pod to Arm64 with out the extra validation.

You may prolong the MySQL secondary pods to the Ampere A1 nodes with none interruptions to the net utility.

Change the variety of replicas for the secondary pods in charts/bitnami-mysql/values.yaml. Additionally replace the nodeAffinityPreset values to permit the pods to be deployed on Arm64 nodes:

secondary: 
title: secondary 
replicaCount: 2 
nodeAffinityPreset: 
  sort: "onerous" 
  key: "kubernetes.io/arch" 
  values: 
    - amd64 
    - arm64

Use the helm improve command to put in the updates to your manifest file:

helm improve wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql

Examine the pod standing utilizing Kubectl. You’ll discover a brand new reproduction of the MySQL secondary pod β€œwordpress-mysql-secondary-1” working on one of many Ampere A1 nodes:

$ kubectl get pods -o large
NAME                              READY   STATUS    RESTARTS   AGE     IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   1/1     Working   0          24m     10.244.3.134   10.0.10.217   <none>           <none>
wordpress-mysql-primary-0         1/1     Working   0          27m     10.244.4.2     10.0.10.78    <none>           <none>
wordpress-mysql-secondary-0       1/1     Working   0          36s     10.244.4.133   10.0.10.214   <none>           <none>
wordpress-mysql-secondary-1       1/1     Working   0          2m13s   10.244.5.130   10.0.10.82    <none>           <none>

The MySQL BinLog (Binary Logs) is liable for dealing with the replication. Confirm the replication standing by connecting to the MySQL database:

mysql> present processlist;
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
| Id  | Consumer            | Host               | db   | Command     | Time | State                                                           | Information             |
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
|   5 | event_scheduler | localhost          | NULL | Daemon      | 1638 | Ready on empty queue                                          | NULL             |
| 617 | replicator      | 10.244.5.130:46208 | NULL | Binlog Dump |   98 | Supply has despatched all binlog to reproduction; ready for extra updates | NULL             |
| 630 | replicator      | 10.244.4.133:45986 | NULL | Binlog Dump |   68 | Supply has despatched all binlog to reproduction; ready for extra updates | NULL             |
| 653 | root            | localhost          | NULL | Question       |    0 | init                                                            | present processlist |
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
4 rows in set (0.00 sec)

Step 3: Migrate the MySQL secondary pod to an Ampere A1 node

As talked about earlier, you may straight migrate the MySQL secondary pod to the Arm64 node. The MySQL pod makes use of OCI block volumes that may be indifferent from an occasion and moved to a unique occasion with out the lack of information. This information persistence allows you to migrate information between situations and ensures that your information is safely saved, even when it isn’t related to an occasion. Any information stays intact till you reformat or delete the quantity.

With the intention to migrate the MySQL secondary pod to Ampere A1 node, replace the helm chart and set the nodeAffinityPreset to arm64 and take away amd64. On the identical time, you too can reset the replicaCount again to 1:

secondary: 
title: secondary 
replicaCount: 1 
nodeAffinityPreset: 
  sort: "onerous" 
  key: "kubernetes.io/arch" 
  values: 
    - arm64 

Use the helm improve command to put in the updates to your MySQL manifest file:

helm improve wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql

$ kubectl get pods -o large
NAME                              READY   STATUS    RESTARTS   AGE   IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   1/1     Working   0          28m   10.244.3.134   10.0.10.217   <none>           <none>
wordpress-mysql-primary-0         1/1     Working   0          31m   10.244.4.2     10.0.10.78    <none>           <none>
wordpress-mysql-secondary-0       1/1     Working   0          77s   10.244.5.131   10.0.10.82    <none>           <none>

You’ll discover the MySQL reproduction on the x86 node is deleted and a brand new reproduction created on the Arm64 node. Confirm the replication standing once more at this stage:

mysql> present processlist;
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
| Id  | Consumer            | Host               | db   | Command     | Time | State                                                           | Information             |
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
|   5 | event_scheduler | localhost          | NULL | Daemon      | 1854 | Ready on empty queue                                          | NULL             |
| 617 | replicator      | 10.244.5.130:46208 | NULL | Binlog Dump |  314 | Supply has despatched all binlog to reproduction; ready for extra updates | NULL             |
| 727 | replicator      | 10.244.5.131:45904 | NULL | Binlog Dump |   68 | Supply has despatched all binlog to reproduction; ready for extra updates | NULL             |
| 752 | root            | localhost          | NULL | Question       |    0 | init                                                            | present processlist |
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
4 rows in set (0.00 sec)

Now you can delete the x86 node that was working the previous reproduction for MySQL secondary, on this instance the node with ip handle β€œ10.0.10.214β€³. This step doesn’t require any service downtime and you’ve got now efficiently migrated your MySQL secondary pod to the Ampere A1 occasion.

Migrate MySQL Main Database to Ampere A1 Occasion

Within the earlier step, we migrated the MySQL secondary pod of the WordPress deployment to Ampere A1 node. The subsequent step is emigrate the MySQL major pod to the second Ampere A1 node in the identical OKE cluster.

Observe: it’s endorsed to check the method in a non-production setting utilizing a snapshot of your manufacturing database. When performing a failover of the MySQL major database in a manufacturing setting, please be sure you have a full backup of the database and observe all of the steps which are really useful for database failover.

With the intention to failover the MySQL major pod, reset the nodeAffinityPreset in charts/bitnami-mysql/values.yaml to make use of node with labels kubernetes.io/arch=arm64:

major:
nodeAffinityPreset:
  sort: "onerous"
  key: "kubernetes.io/arch"
  values:
    - arm64

Use the helm improve command to put in the updates to your manifest file.

Observe: this step will disrupt your utility’s connectivity to the database for couple of minutes, please plan for service downtime.

helm improve wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql

$ kubectl get pods -o large
NAME                              READY   STATUS    RESTARTS        AGE    IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   1/1     Working   1 (3m19s in the past)   37m    10.244.3.134   10.0.10.217   <none>           <none>
wordpress-mysql-primary-0         1/1     Working   0               4m2s   10.244.5.2     10.0.10.122   <none>           <none>
wordpress-mysql-secondary-0       1/1     Working   0               10m    10.244.5.131   10.0.10.82    <none>           <none>

$ kubectl get nodes -o large -l kubernetes.io/arch=arm64
NAME          STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                   CONTAINER-RUNTIME
10.0.10.122   Prepared    node    21m   v1.26.2   10.0.10.122   <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8
10.0.10.82    Prepared    node    21m   v1.26.2   10.0.10.82    <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8

$ kubectl get nodes -o large -l kubernetes.io/arch=amd64
NAME          STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                  CONTAINER-RUNTIME
10.0.10.217   Prepared    node    61m   v1.26.2   10.0.10.217   <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8

You’ll discover the MySQL major pod on the x86 node is now deleted and a brand new pod is deployed on the Arm64 node. This pod will routinely mount the first pod’s block quantity storage, guaranteeing information availability after the failover.

We have now now efficiently migrated the WordPress deployment to a heterogenous Arm64 and x86 cluster. The frontend and utility pods of WordPress proceed to run on the x86 situations, whereas the MySQL database major and secondary pods are actually migrated to the Arm64 situations in a single OKE cluster.

When you validate the performance and efficiency of your utility in a heterogenous cluster, you may then migrate the remainder of your utility elements to Arm64 situations utilizing an analogous course of and take full benefit of the worth efficiency advantages of an Ampere A1 cluster on OKE.

Appendix

Detailed directions to deploy the WordPress utility on an OKE cluster.

Step 1: Create a 3-node cluster

Create a OKE cluster utilizing VM.Standard3.Flex form. Utilizing the Cloud Shell, setup the Kubernetes configuration file (kubeconfig) for the cluster (Cloud Shell Entry). As soon as this step is full, confirm the cluster particulars utilizing kubectl instructions:

cluster details

$ kubectl get nodes -o large
NAME          STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                  CONTAINER-RUNTIME
10.0.10.214   Prepared    node    9m54s   v1.26.2   10.0.10.214   <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
10.0.10.217   Prepared    node    10m     v1.26.2   10.0.10.217   <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
10.0.10.78    Prepared    node    9m59s   v1.26.2   10.0.10.78    <none>        Oracle Linux Server 8.7   5.15.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8

Step2: Deploy the WordPress utility

Obtain the values.yaml for bitnami/wordpress and bitnami/mysql and modify it in your deployment wants:

mkdir -p oci_a1_demo/charts/bitnami-mysql
cd oci_a1_demo/charts/bitnami-mysql
wget https://uncooked.githubusercontent.com/bitnami/charts/principal/bitnami/mysql/values.yaml
cd ../../..
mkdir -p oci_a1_demo/charts/bitnami-wordpress
cd oci_a1_demo/charts/bitnami-wordpress
wget https://uncooked.githubusercontent.com/bitnami/charts/principal/bitnami/wordpress/values.yaml

Modify oci_a1_demo/charts/bitnami-mysql/values.yaml as proven under. The parameters not proven right here could be left at their default values. The nodeAffinity worth is used to pick out nodes to schedule the MySQL pods, we use the Kubernetes.io/arch label to distinguish the x86 and Arm64 nodes. This area might be up to date when migrating the MySQL deployment to Arm64 nodes:

structure: replication
auth:
  rootPassword: "your_db_password"
  database: "bitnami_wordpress"
  username: "bn_username"
  password: ""

major:
  persistence:
    enabled: true
    storageClass: "oci-bv"
    accessModes:
      - ReadWriteOnce
  nodeAffinityPreset:
    sort: "onerous"
    key: "kubernetes.io/arch"
    values:
      - amd64

secondary:
  replicaCount: 1
  persistence:
    enabled: true
  storageClass: "oci-bv"
    accessModes:
      - ReadWriteOnce
  nodeAffinityPreset:
    sort: "onerous"
    key: "kubernetes.io/arch"
    values:
      - amd64
volumePermissions:
  enabled: true

Modify charts/bitnami-wordpress/values.yaml as proven under. The parameters not proven right here could be left at their default values. Use the affinity.podAntiAffinity fields to make sure that WordPress pods are usually not deployed on the nodes which have MySQL pods working:

wordpressUsername: person
wordpressPassword: "wordpress_user_password"
replicaCount: 1
service:
  sort: LoadBalancer

persistence:
  enabled: true
  storageClass: "fss-wp-storage"
  accessModes:
    - ReadWriteMany
  accessMode: ReadWriteMany

nodeAffinityPreset:
    sort: "onerous"
    key: "kubernetes.io/arch"
    values:
      - amd64

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app.kubernetes.io/title
          operator: In
          values:
          - mysql
      topologyKey: kubernetes.io/hostname

volumePermissions:
  enabled: true

mariadb:
  enabled: false
externalDatabase:
  host: wordpress-mysql-primary
  port: 3306
  person: "root"
  password: " your_db_password"
  database: bitnami_wordpress
  existingSecret: ""
memcached:
  enabled: false

Step 3: Configure persistent volumes for MySQL containers

MySQL container makes use of persistent quantity claims to provision storage for the database. The Oracle Cloud Infrastructure Block Quantity service supplies persistent, sturdy, and high-performance block storage utilizing the CSI quantity plugin. Set the β€œstorageClass” parameter within the values.yaml file to β€œoci-bv” as proven above.

Volumes are solely accessible to situations in the identical availability area. We are going to use the identical availability area when including new Ampere A1 nodes emigrate the MySQL database:

Provisioning_PVCs_on_BlockVolume

Step 4: Configure filesystem storage for WordPress containers

The WordPress container is configured to make use of OCI’s filesystem dynamic storage to permit entry to a number of replicas throughout totally different nodes. The Oracle Cloud Infrastructure File Storage service supplies a sturdy, scalable, distributed, enterprise-grade community file system. Detailed steps to make use of the CSI quantity plugin to attach clusters to file methods within the File Storage service is documented right here:

PVCs_on_FSS-Using-CSI-Volume-Plugin

As described, create a mount goal utilizing the OCI console.

mount target information

Outline a brand new storage class that makes use of the fss.csi.oracleclould.com provisioner utilizing the OCID of the mount goal you simply created:

$ cat oci_a1_demo/oci-fs-storage-class.yaml 
---
variety: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  title: fss-wp-storage
provisioner: fss.csi.oraclecloud.com
parameters:
  availabilityDomain: MBWR:PHX-AD-1
  mountTargetOcid: <OCID of mount goal>
  compartmentOcid: <OCID of compartment>

Observe: add IAM insurance policies to allow the CSI quantity plugin.

ALLOW any-user to handle file-family in tenancy
ALLOW any-user to make use of virtual-network-family in tenancy

Create the storage class from the manifest file utilizing:

kubectl create -f oci-fs-storage-class.yaml

Step 5: Deploy the MySQL major and secondary pods utilizing the helm chart

cd oci_a1_demo
helm repo add bitnami https://charts.bitnami.com/bitnami
helm set up wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql

$ kubectl get pods -o large
NAME                          READY   STATUS    RESTARTS   AGE    IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-mysql-primary-0     1/1     Working   0          2m5s   10.244.4.2     10.0.10.78    <none>           <none>
wordpress-mysql-secondary-0   1/1     Working   0          2m5s   10.244.4.131   10.0.10.214   <none>           <none>

Step 6: Deploy the WordPress utility pods

As soon as the MySQL pods are working, use helm to deploy the WordPress frontend and utility pods:

helm set up wordpress-demo -f ./charts/bitnami-wordpress/values.yaml bitnami/wordpress

Step 7: Confirm deployment standing

Confirm that every one pods are deployed and in β€œworking” state. It will take a couple of minutes.

$ kubectl get pods -o large
NAME                              READY   STATUS    RESTARTS   AGE     IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   1/1     Working   0          119s    10.244.3.134   10.0.10.217   <none>           <none>
wordpress-mysql-primary-0         1/1     Working   0          5m23s   10.244.4.2     10.0.10.78    <none>           <none>
wordpress-mysql-secondary-0       1/1     Working   0          5m23s   10.244.4.131   10.0.10.214   <none>           <none>

$ kubectl get service
NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
kubernetes                           ClusterIP      10.96.0.1      <none>          443/TCP,12250/TCP            22d
wordpress-demo                       LoadBalancer   10.96.215.0    β€œpublic ip handle”   80:32601/TCP,443:30738/TCP   2m32s
wordpress-mysql-primary              ClusterIP      10.96.79.218   <none>          3306/TCP                     5m56s
wordpress-mysql-primary-headless     ClusterIP      None           <none>          3306/TCP                     5m56s
wordpress-mysql-secondary            ClusterIP      10.96.154.29   <none>          3306/TCP                     5m56s
wordpress-mysql-secondary-headless   ClusterIP      None           <none>          3306/TCP                     5m56s

$ kubectl get pvc
NAME                               STATUS   VOLUME                                         CAPACITY   ACCESS MODES   STORAGECLASS     AGE
data-wordpress-mysql-primary-0     Sure    csi-d6d15401-9732-4060-9391-fe07993f5f11       50Gi       RWO            oci-bv           5m31s
data-wordpress-mysql-secondary-0   Sure    csi-0cfcbf9f-9af9-4060-9063-f8d0ccb8f4f0       50Gi       RWO            oci-bv           5m48s
wordpress-demo                     Sure    csi-fss-44851833-384a-4e3e-bad6-6253d37185a1   10Gi       RWX            fss-wp-storage   2m38s

WordPress deployment is now full. You may login to the exterior IP of WordPress service and examine the weblog website. Login to the http://<external-ip>/wp-admin web page utilizing the credentials username:person and password:root, modify the WordPress configuration, add new posts, pages, customers and so on.

Constructed for sustainable cloud computing, Ampere’s first Cloud Native Processors ship predictable excessive efficiency, platform scalability, and energy effectivity unprecedented within the trade.

Discuss to our knowledgeable sales team about partnerships or to get extra info, or get trial entry to Ampere Methods by way of our Developer Access Programs.