reCAPTCHA WAF Session Token
Programming Languages

Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters — SitePoint

This article was originally published by Ampere Computing.

As a developer or application administrator, if you design and manage cloud-native applications on Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) x86 instances and you are wondering how to leverage the lower cost and higher performance of OCI Ampere A1 based instances without a full lift and shift migration to Arm64, this post is for you.

In this post, we will showcase an incremental migration of a full stack cloud-native application to OKE Ampere A1 instances. We will use WordPress as an example LAMP (Linux, Apache, MySQL, PHP) stack application. Each component in this application stack is relatively independent of the others, and so redeploying any one component — for example, the MySQL database to an Ampere node — is straightforward.

We’ll take a step-by-step look at how to migrate the MySQL database on OKE, with almost no downtime, from VM.Standard3.Flex (Intel) nodes to VM.Standard.A1.Flex (Ampere) nodes. We begin by deploying WordPress from a Bitnami maintained Helm chart, with one Apache/PHP WordPress pod, a primary MySQL pod, and one secondary replica MySQL pod, all running on x86 nodes, with data being stored on OCI block volume and file storage for persistence. This database architecture uses MySQL asynchronous replication where the primary node is the replication source.

We will then create an Arm64 node pool and add additional MySQL replicas that will run on these newly created nodes, which will automatically replicate the data and ensure that all of our data is now available on the Arm64-hosted MySQL nodes. Finally, we will make one of the Arm64-hosted nodes the primary node for our MySQL cluster and shut down the x86-hosted database nodes. In the end, you now have a hybrid x86/Arm64 cluster with WordPress containers running on x86, and MySQL running on Arm64.

An architectural diagram representing the WordPress deployment

Deploy WordPress Application on OKE 3-Node Cluster

We start by creating an OKE cluster using the OCI web console. The cluster is set up with three nodes, using the VM.Standard3.flex shape. We use bitnami/wordpress and bitnami/mysql containers for deploying the application. Both these images are supported on x86 as well as Arm64 and use helm charts for easy deployment and upgrades using Kubernetes manifest files.

Step-by-step instructions for deploying the application are provided in the Appendix section.

Once the cluster is created and the application deployed, verify the WordPress frontend and application pod, MySQL primary pod and MySQL secondary pod are up and running on the OKE cluster:

<code class="bash language-bash">$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   <span class="token number">1</span>/1     Running   <span class="token number">0</span>          119s    <span class="token number">10.244</span>.3.134   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-primary-0         <span class="token number">1</span>/1     Running   <span class="token number">0</span>          5m23s   <span class="token number">10.244</span>.4.2     <span class="token number">10.0</span>.10.78    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-secondary-0       <span class="token number">1</span>/1     Running   <span class="token number">0</span>          5m23s   <span class="token number">10.244</span>.4.131   <span class="token number">10.0</span>.10.214   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
</code>

Migrate MySQL Secondary Database to Ampere A1 Instance

Next, we will add Ampere A1 instances to the OKE cluster and then extend the WordPress application’s MySQL database to run on the A1 instances in a few easy steps. As a general best practice, it’s recommended to test the process in a non-production environment.

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

Using the OCI console, update your OKE cluster and add a new node pool. Use the same placement configuration as your x86 nodes.

Select the VM.Standard.A1.Flex shape. Choose 2x the number of OCPUs as your x86 nodes, for example 2 OCPUs on VM.Standard.3.Flex instance is equivalent to 4 OCPUs on VM.Standard.A1.Flex instance. The Oracle CPU (OCPU) unit of measurement for x86 OCPUs is worth two vCPUs but an Ampere OCPU is a single vCPU.

A new node-pool and new instances with Ampere A1 shapes will be added to your cluster. We will migrate the MySQL pods to the newly added Arm64 nodes.

Node details

<code class="bash language-bash">$ kubectl get nodes -o wide -l kubernetes.io/arch<span class="token operator">=</span>amd64
NAME          STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                  CONTAINER-RUNTIME
<span class="token number">10.0</span>.10.214   Ready    node    40m   v1.26.2   <span class="token number">10.0</span>.10.214   <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
<span class="token number">10.0</span>.10.217   Ready    node    41m   v1.26.2   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
<span class="token number">10.0</span>.10.78    Ready    node    41m   v1.26.2   <span class="token number">10.0</span>.10.78    <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8

$ kubectl get nodes -o wide -l kubernetes.io/arch<span class="token operator">=</span>arm64
NAME          STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                   CONTAINER-RUNTIME
<span class="token number">10.0</span>.10.122   Ready    node    2m38s   v1.26.2   <span class="token number">10.0</span>.10.122   <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8
<span class="token number">10.0</span>.10.82    Ready    node    2m15s   v1.26.2   <span class="token number">10.0</span>.10.82    <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8
</code>

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

In order to migrate the MySQL secondary pod, start by adding a replica of the secondary pod on the Arm64 node. This step is optional. We will deploy multiple replicas of the MySQL secondary pod to ensure data consistency and availability on the new Arm64 instance. If you do not want to create multiple replicas, you can skip to the next step and migrate the MySQL secondary pod to Arm64 without the additional validation.

You can extend the MySQL secondary pods to the Ampere A1 nodes without any interruptions to the web application.

Change the number of replicas for the secondary pods in charts/bitnami-mysql/values.yaml. Also update the nodeAffinityPreset values to allow the pods to be deployed on Arm64 nodes:

<code class="bash language-bash">secondary: 
name: secondary 
replicaCount: <span class="token number">2</span> 
nodeAffinityPreset: 
  type: <span class="token string">"hard"</span> 
  key: <span class="token string">"kubernetes.io/arch"</span> 
  values: 
    - amd64 
    - arm64
</code>

Use the helm upgrade command to install the updates to your manifest file:

<code class="bash language-bash">helm upgrade wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql
</code>

Check the pod status using Kubectl. You will notice a new replica of the MySQL secondary pod “wordpress-mysql-secondary-1” running on one of the Ampere A1 nodes:

<code class="bash language-bash">$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   <span class="token number">1</span>/1     Running   <span class="token number">0</span>          24m     <span class="token number">10.244</span>.3.134   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-primary-0         <span class="token number">1</span>/1     Running   <span class="token number">0</span>          27m     <span class="token number">10.244</span>.4.2     <span class="token number">10.0</span>.10.78    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-secondary-0       <span class="token number">1</span>/1     Running   <span class="token number">0</span>          36s     <span class="token number">10.244</span>.4.133   <span class="token number">10.0</span>.10.214   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-secondary-1       <span class="token number">1</span>/1     Running   <span class="token number">0</span>          2m13s   <span class="token number">10.244</span>.5.130   <span class="token number">10.0</span>.10.82    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
</code>

The MySQL BinLog (Binary Logs) is responsible for handling the replication. Verify the replication status by connecting to the MySQL database:

<code class="bash language-bash">mysql<span class="token operator">></span> show processlist<span class="token punctuation">;</span>
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
<span class="token operator">|</span> Id  <span class="token operator">|</span> User            <span class="token operator">|</span> Host               <span class="token operator">|</span> db   <span class="token operator">|</span> Command     <span class="token operator">|</span> Time <span class="token operator">|</span> State                                                           <span class="token operator">|</span> Info             <span class="token operator">|</span>
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
<span class="token operator">|</span>   <span class="token number">5</span> <span class="token operator">|</span> event_scheduler <span class="token operator">|</span> localhost          <span class="token operator">|</span> NULL <span class="token operator">|</span> Daemon      <span class="token operator">|</span> <span class="token number">1638</span> <span class="token operator">|</span> Waiting on empty queue                                          <span class="token operator">|</span> NULL             <span class="token operator">|</span>
<span class="token operator">|</span> <span class="token number">617</span> <span class="token operator">|</span> replicator      <span class="token operator">|</span> <span class="token number">10.244</span>.5.130:46208 <span class="token operator">|</span> NULL <span class="token operator">|</span> Binlog Dump <span class="token operator">|</span>   <span class="token number">98</span> <span class="token operator">|</span> Source has sent all binlog to replica<span class="token punctuation">;</span> waiting <span class="token keyword">for</span> <span class="token function">more</span> updates <span class="token operator">|</span> NULL             <span class="token operator">|</span>
<span class="token operator">|</span> <span class="token number">630</span> <span class="token operator">|</span> replicator      <span class="token operator">|</span> <span class="token number">10.244</span>.4.133:45986 <span class="token operator">|</span> NULL <span class="token operator">|</span> Binlog Dump <span class="token operator">|</span>   <span class="token number">68</span> <span class="token operator">|</span> Source has sent all binlog to replica<span class="token punctuation">;</span> waiting <span class="token keyword">for</span> <span class="token function">more</span> updates <span class="token operator">|</span> NULL             <span class="token operator">|</span>
<span class="token operator">|</span> <span class="token number">653</span> <span class="token operator">|</span> root            <span class="token operator">|</span> localhost          <span class="token operator">|</span> NULL <span class="token operator">|</span> Query       <span class="token operator">|</span>    <span class="token number">0</span> <span class="token operator">|</span> init                                                            <span class="token operator">|</span> show processlist <span class="token operator">|</span>
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
<span class="token number">4</span> rows <span class="token keyword">in</span> <span class="token builtin class-name">set</span> <span class="token punctuation">(</span><span class="token number">0.00</span> sec<span class="token punctuation">)</span>
</code>

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

As mentioned earlier, you can directly migrate the MySQL secondary pod to the Arm64 node. The MySQL pod uses OCI block volumes that can be detached from an instance and moved to a different instance without the loss of data. This data persistence enables you to migrate data between instances and ensures that your data is safely stored, even when it is not connected to an instance. Any data remains intact until you reformat or delete the volume.

In order to migrate the MySQL secondary pod to Ampere A1 node, update the helm chart and set the nodeAffinityPreset to arm64 and remove amd64. At the same time, you can also reset the replicaCount back to 1:

<code class="bash language-bash">secondary: 
name: secondary 
replicaCount: <span class="token number">1</span> 
nodeAffinityPreset: 
  type: <span class="token string">"hard"</span> 
  key: <span class="token string">"kubernetes.io/arch"</span> 
  values: 
    - arm64 
</code>

Use the helm upgrade command to install the updates to your MySQL manifest file:

<code class="bash language-bash">helm upgrade wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql

$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   <span class="token number">1</span>/1     Running   <span class="token number">0</span>          28m   <span class="token number">10.244</span>.3.134   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-primary-0         <span class="token number">1</span>/1     Running   <span class="token number">0</span>          31m   <span class="token number">10.244</span>.4.2     <span class="token number">10.0</span>.10.78    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-secondary-0       <span class="token number">1</span>/1     Running   <span class="token number">0</span>          77s   <span class="token number">10.244</span>.5.131   <span class="token number">10.0</span>.10.82    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
</code>

You will notice the MySQL replica on the x86 node is deleted and a new replica created on the Arm64 node. Verify the replication status again at this stage:

<code class="bash language-bash">mysql<span class="token operator">></span> show processlist<span class="token punctuation">;</span>
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
<span class="token operator">|</span> Id  <span class="token operator">|</span> User            <span class="token operator">|</span> Host               <span class="token operator">|</span> db   <span class="token operator">|</span> Command     <span class="token operator">|</span> Time <span class="token operator">|</span> State                                                           <span class="token operator">|</span> Info             <span class="token operator">|</span>
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
<span class="token operator">|</span>   <span class="token number">5</span> <span class="token operator">|</span> event_scheduler <span class="token operator">|</span> localhost          <span class="token operator">|</span> NULL <span class="token operator">|</span> Daemon      <span class="token operator">|</span> <span class="token number">1854</span> <span class="token operator">|</span> Waiting on empty queue                                          <span class="token operator">|</span> NULL             <span class="token operator">|</span>
<span class="token operator">|</span> <span class="token number">617</span> <span class="token operator">|</span> replicator      <span class="token operator">|</span> <span class="token number">10.244</span>.5.130:46208 <span class="token operator">|</span> NULL <span class="token operator">|</span> Binlog Dump <span class="token operator">|</span>  <span class="token number">314</span> <span class="token operator">|</span> Source has sent all binlog to replica<span class="token punctuation">;</span> waiting <span class="token keyword">for</span> <span class="token function">more</span> updates <span class="token operator">|</span> NULL             <span class="token operator">|</span>
<span class="token operator">|</span> <span class="token number">727</span> <span class="token operator">|</span> replicator      <span class="token operator">|</span> <span class="token number">10.244</span>.5.131:45904 <span class="token operator">|</span> NULL <span class="token operator">|</span> Binlog Dump <span class="token operator">|</span>   <span class="token number">68</span> <span class="token operator">|</span> Source has sent all binlog to replica<span class="token punctuation">;</span> waiting <span class="token keyword">for</span> <span class="token function">more</span> updates <span class="token operator">|</span> NULL             <span class="token operator">|</span>
<span class="token operator">|</span> <span class="token number">752</span> <span class="token operator">|</span> root            <span class="token operator">|</span> localhost          <span class="token operator">|</span> NULL <span class="token operator">|</span> Query       <span class="token operator">|</span>    <span class="token number">0</span> <span class="token operator">|</span> init                                                            <span class="token operator">|</span> show processlist <span class="token operator">|</span>
+-----+-----------------+--------------------+------+-------------+------+-----------------------------------------------------------------+------------------+
<span class="token number">4</span> rows <span class="token keyword">in</span> <span class="token builtin class-name">set</span> <span class="token punctuation">(</span><span class="token number">0.00</span> sec<span class="token punctuation">)</span>
</code>

You can now delete the x86 node that was running the old replica for MySQL secondary, in this example the node with ip address “10.0.10.214″. This step does not require any service downtime and you have now successfully migrated your MySQL secondary pod to the Ampere A1 instance.

Migrate MySQL Primary Database to Ampere A1 Instance

In the previous step, we migrated the MySQL secondary pod of the WordPress deployment to Ampere A1 node. The next step is to migrate the MySQL primary pod to the second Ampere A1 node in the same OKE cluster.

Note: it is recommended to test the process in a non-production environment using a snapshot of your production database. When performing a failover of the MySQL primary database in a production environment, please make sure you have a full backup of the database and follow all the steps that are recommended for database failover.

In order to failover the MySQL primary pod, reset the nodeAffinityPreset in charts/bitnami-mysql/values.yaml to use node with labels kubernetes.io/arch=arm64:

<code class="bash language-bash">primary:
nodeAffinityPreset:
  type: <span class="token string">"hard"</span>
  key: <span class="token string">"kubernetes.io/arch"</span>
  values:
    - arm64
</code>

Use the helm upgrade command to install the updates to your manifest file.

Note: this step will disrupt your application’s connectivity to the database for few minutes, please plan for service downtime.

<code class="bash language-bash">helm upgrade wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql

$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS        AGE    IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   <span class="token number">1</span>/1     Running   <span class="token number">1</span> <span class="token punctuation">(</span>3m19s ago<span class="token punctuation">)</span>   37m    <span class="token number">10.244</span>.3.134   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-primary-0         <span class="token number">1</span>/1     Running   <span class="token number">0</span>               4m2s   <span class="token number">10.244</span>.5.2     <span class="token number">10.0</span>.10.122   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-secondary-0       <span class="token number">1</span>/1     Running   <span class="token number">0</span>               10m    <span class="token number">10.244</span>.5.131   <span class="token number">10.0</span>.10.82    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>

$ kubectl get nodes -o wide -l kubernetes.io/arch<span class="token operator">=</span>arm64
NAME          STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                   CONTAINER-RUNTIME
<span class="token number">10.0</span>.10.122   Ready    node    21m   v1.26.2   <span class="token number">10.0</span>.10.122   <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8
<span class="token number">10.0</span>.10.82    Ready    node    21m   v1.26.2   <span class="token number">10.0</span>.10.82    <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.aarch64   cri-o://1.26.2-142.el8

$ kubectl get nodes -o wide -l kubernetes.io/arch<span class="token operator">=</span>amd64
NAME          STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                  CONTAINER-RUNTIME
<span class="token number">10.0</span>.10.217   Ready    node    61m   v1.26.2   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
</code>

You will notice the MySQL primary pod on the x86 node is now deleted and a new pod is deployed on the Arm64 node. This pod will automatically mount the primary pod’s block volume storage, ensuring data availability after the failover.

We have now successfully migrated the WordPress deployment to a heterogenous Arm64 and x86 cluster. The frontend and application pods of WordPress continue to run on the x86 instances, while the MySQL database primary and secondary pods are now migrated to the Arm64 instances in one OKE cluster.

Once you validate the functionality and performance of your application in a heterogenous cluster, you can then migrate the rest of your application components to Arm64 instances using a similar process and take full advantage of the price performance benefits of an Ampere A1 cluster on OKE.

Appendix

Detailed instructions to deploy the WordPress application on an OKE cluster.

Step 1: Create a 3-node cluster

Create a OKE cluster using VM.Standard3.Flex shape. Using the Cloud Shell, setup the Kubernetes configuration file (kubeconfig) for the cluster (Cloud Shell Access). Once this step is complete, verify the cluster details using kubectl commands:

cluster details

<code class="bash language-bash">$ kubectl get nodes -o wide
NAME          STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                  KERNEL-VERSION                  CONTAINER-RUNTIME
<span class="token number">10.0</span>.10.214   Ready    node    9m54s   v1.26.2   <span class="token number">10.0</span>.10.214   <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
<span class="token number">10.0</span>.10.217   Ready    node    10m     v1.26.2   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
<span class="token number">10.0</span>.10.78    Ready    node    9m59s   v1.26.2   <span class="token number">10.0</span>.10.78    <span class="token operator"><</span>none<span class="token operator">></span>        Oracle Linux Server <span class="token number">8.7</span>   <span class="token number">5.15</span>.0-6.80.3.1.el8uek.x86_64   cri-o://1.26.2-142.el8
</code>

Step2: Deploy the WordPress application

Download the values.yaml for bitnami/wordpress and bitnami/mysql and modify it for your deployment needs:

<code class="bash language-bash"><span class="token function">mkdir</span> -p oci_a1_demo/charts/bitnami-mysql
<span class="token builtin class-name">cd</span> oci_a1_demo/charts/bitnami-mysql
<span class="token function">wget</span> 
<span class="token builtin class-name">cd</span> <span class="token punctuation">..</span>/<span class="token punctuation">..</span>/<span class="token punctuation">..</span>
<span class="token function">mkdir</span> -p oci_a1_demo/charts/bitnami-wordpress
<span class="token builtin class-name">cd</span> oci_a1_demo/charts/bitnami-wordpress
<span class="token function">wget</span> 
</code>

Modify oci_a1_demo/charts/bitnami-mysql/values.yaml as shown below. The parameters not shown here can be left at their default values. The nodeAffinity value is used to select nodes to schedule the MySQL pods, we use the Kubernetes.io/arch label to differentiate the x86 and Arm64 nodes. This field will be updated when migrating the MySQL deployment to Arm64 nodes:

<code class="bash language-bash">architecture: replication
auth:
  rootPassword: <span class="token string">"your_db_password"</span>
  database: <span class="token string">"bitnami_wordpress"</span>
  username: <span class="token string">"bn_username"</span>
  password: <span class="token string">""</span>

primary:
  persistence:
    enabled: <span class="token boolean">true</span>
    storageClass: <span class="token string">"oci-bv"</span>
    accessModes:
      - ReadWriteOnce
  nodeAffinityPreset:
    type: <span class="token string">"hard"</span>
    key: <span class="token string">"kubernetes.io/arch"</span>
    values:
      - amd64

secondary:
  replicaCount: <span class="token number">1</span>
  persistence:
    enabled: <span class="token boolean">true</span>
  storageClass: <span class="token string">"oci-bv"</span>
    accessModes:
      - ReadWriteOnce
  nodeAffinityPreset:
    type: <span class="token string">"hard"</span>
    key: <span class="token string">"kubernetes.io/arch"</span>
    values:
      - amd64
volumePermissions:
  enabled: <span class="token boolean">true</span>
</code>

Modify charts/bitnami-wordpress/values.yaml as shown below. The parameters not shown here can be left at their default values. Use the affinity.podAntiAffinity fields to ensure that WordPress pods are not deployed on the nodes that have MySQL pods running:

<code class="bash language-bash">wordpressUsername: user
wordpressPassword: <span class="token string">"wordpress_user_password"</span>
replicaCount: <span class="token number">1</span>
service:
  type: LoadBalancer

persistence:
  enabled: <span class="token boolean">true</span>
  storageClass: <span class="token string">"fss-wp-storage"</span>
  accessModes:
    - ReadWriteMany
  accessMode: ReadWriteMany

nodeAffinityPreset:
    type: <span class="token string">"hard"</span>
    key: <span class="token string">"kubernetes.io/arch"</span>
    values:
      - amd64

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

volumePermissions:
  enabled: <span class="token boolean">true</span>

mariadb:
  enabled: <span class="token boolean">false</span>
externalDatabase:
  host: wordpress-mysql-primary
  port: <span class="token number">3306</span>
  user: <span class="token string">"root"</span>
  password: <span class="token string">" your_db_password"</span>
  database: bitnami_wordpress
  existingSecret: <span class="token string">""</span>
memcached:
  enabled: <span class="token boolean">false</span>
</code>

Step 3: Configure persistent volumes for MySQL containers

MySQL container uses persistent volume claims to provision storage for the database. The Oracle Cloud Infrastructure Block Volume service provides persistent, durable, and high-performance block storage using the CSI volume plugin. Set the “storageClass” parameter in the values.yaml file to “oci-bv” as shown above.

Volumes are only accessible to instances in the same availability domain. We will use the same availability domain when adding new Ampere A1 nodes to migrate the MySQL database:

Provisioning_PVCs_on_BlockVolume

Step 4: Configure filesystem storage for WordPress containers

The WordPress container is configured to use OCI’s filesystem dynamic storage to allow access to multiple replicas across different nodes. The Oracle Cloud Infrastructure File Storage service provides a durable, scalable, distributed, enterprise-grade network file system. Detailed steps to use the CSI volume plugin to connect clusters to file systems in the File Storage service is documented here:

PVCs_on_FSS-Using-CSI-Volume-Plugin

As described, create a mount target using the OCI console.

mount target information

Define a new storage class that uses the fss.csi.oracleclould.com provisioner using the OCID of the mount target you just created:

<code class="bash language-bash">$ <span class="token function">cat</span> oci_a1_demo/oci-fs-storage-class.yaml 
---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fss-wp-storage
provisioner: fss.csi.oraclecloud.com
parameters:
  availabilityDomain: MBWR:PHX-AD-1
  mountTargetOcid: <span class="token operator"><</span>OCID of <span class="token function">mount</span> target<span class="token operator">></span>
  compartmentOcid: <span class="token operator"><</span>OCID of compartment<span class="token operator">></span>
</code>

Note: add IAM policies to enable the CSI volume plugin.

<code class="bash language-bash">ALLOW any-user to manage file-family <span class="token keyword">in</span> tenancy
ALLOW any-user to use virtual-network-family <span class="token keyword">in</span> tenancy
</code>

Create the storage class from the manifest file using:

<code class="bash language-bash">kubectl create -f oci-fs-storage-class.yaml
</code>

Step 5: Deploy the MySQL primary and secondary pods using the helm chart

<code class="bash language-bash"><span class="token builtin class-name">cd</span> oci_a1_demo
helm repo <span class="token function">add</span> bitnami 
helm <span class="token function">install</span> wordpress-mysql -f ./charts/bitnami-mysql/values.yaml bitnami/mysql

$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE    IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-mysql-primary-0     <span class="token number">1</span>/1     Running   <span class="token number">0</span>          2m5s   <span class="token number">10.244</span>.4.2     <span class="token number">10.0</span>.10.78    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-secondary-0   <span class="token number">1</span>/1     Running   <span class="token number">0</span>          2m5s   <span class="token number">10.244</span>.4.131   <span class="token number">10.0</span>.10.214   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
</code>

Step 6: Deploy the WordPress application pods

Once the MySQL pods are running, use helm to deploy the WordPress frontend and application pods:

<code class="bash language-bash">helm <span class="token function">install</span> wordpress-demo -f ./charts/bitnami-wordpress/values.yaml bitnami/wordpress
</code>

Step 7: Verify deployment status

Verify that all pods are deployed and in “running” state. This will take a few minutes.

<code class="bash language-bash">$ kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE     IP             NODE          NOMINATED NODE   READINESS GATES
wordpress-demo-5d8d554d8d-gg2wd   <span class="token number">1</span>/1     Running   <span class="token number">0</span>          119s    <span class="token number">10.244</span>.3.134   <span class="token number">10.0</span>.10.217   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-primary-0         <span class="token number">1</span>/1     Running   <span class="token number">0</span>          5m23s   <span class="token number">10.244</span>.4.2     <span class="token number">10.0</span>.10.78    <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>
wordpress-mysql-secondary-0       <span class="token number">1</span>/1     Running   <span class="token number">0</span>          5m23s   <span class="token number">10.244</span>.4.131   <span class="token number">10.0</span>.10.214   <span class="token operator"><</span>none<span class="token operator">></span>           <span class="token operator"><</span>none<span class="token operator">></span>

$ kubectl get <span class="token function">service</span>
NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP     PORT<span class="token punctuation">(</span>S<span class="token punctuation">)</span>                      AGE
kubernetes                           ClusterIP      <span class="token number">10.96</span>.0.1      <span class="token operator"><</span>none<span class="token operator">></span>          <span class="token number">443</span>/TCP,12250/TCP            22d
wordpress-demo                       LoadBalancer   <span class="token number">10.96</span>.215.0    “public <span class="token function">ip</span> address”   <span class="token number">80</span>:32601/TCP,443:30738/TCP   2m32s
wordpress-mysql-primary              ClusterIP      <span class="token number">10.96</span>.79.218   <span class="token operator"><</span>none<span class="token operator">></span>          <span class="token number">3306</span>/TCP                     5m56s
wordpress-mysql-primary-headless     ClusterIP      None           <span class="token operator"><</span>none<span class="token operator">></span>          <span class="token number">3306</span>/TCP                     5m56s
wordpress-mysql-secondary            ClusterIP      <span class="token number">10.96</span>.154.29   <span class="token operator"><</span>none<span class="token operator">></span>          <span class="token number">3306</span>/TCP                     5m56s
wordpress-mysql-secondary-headless   ClusterIP      None           <span class="token operator"><</span>none<span class="token operator">></span>          <span class="token number">3306</span>/TCP                     5m56s

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

WordPress deployment is now complete. You can login to the external IP of WordPress service and view the blog site. Login to the page using the credentials username:user and password:root, modify the WordPress configuration, add new posts, pages, users etc.

Built for sustainable cloud computing, Ampere’s first Cloud Native Processors deliver predictable high performance, platform scalability, and power efficiency unprecedented in the industry.

Talk to our expert sales team about partnerships or to get more information, or get trial access to Ampere Systems through our Developer Access Programs.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button
WP Twitter Auto Publish Powered By : XYZScripts.com
SiteLock