Saturday 31 August, the first Cloud Native Meetup was held at the SWAN Head Office in Port-Louis. We are very grateful for this sponsorship and collaboration between SWAN and the Cloud Native Chapter of Mauritius.
Since this is the first post about the Cloud Native (chapter) on my blog, let me add a little bit of background information.
Cloud Native refers to an approach to building and running applications that fully leverage the advantages of technologies like containers, microservices, and orchestration tools such as Kubernetes. The Cloud Native Computing Foundation (CNCF) is an open-source software foundation that promotes the development and adoption of cloud native technologies. CNCF supports projects that enable cloud native development, such as Kubernetes, Prometheus, Helm, Argo and many more (See the CNCF landscape). By fostering collaboration and innovation within the cloud native ecosystem, CNCF helps developers and companies build modern, scalable applications.
CNCF fosters a global community through its community groups or chapters, which are local groups that bring together developers, practitioners, and enthusiasts to share knowledge and collaborate on cloud native technologies. These chapters host meetups, workshops, and events, providing a space for individuals to learn, network, and contribute to the cloud native ecosystem at a local level.
We announced the creation of the Cloud Native Mauritius Chapter in July at the Developers Conference. Great enough, we were able to host our first meetup right a month after that thanks to the sponsorship by SWAN — providing a venue and snacks/beverages for the attendees.
Alex published a nice sum-up of the event on his blog. I invite you to read it to see how the day unfolded.
In this post, however, I would to shed more light over a tool that I used for the demo during my presentation — Rancher Desktop.
The theme of my presentation was "Cloud Native for the Monolith User". It was themed so, because I wanted to demo a use case, referring to lexpress.mu, on how it's built as a monolith application using Laravel, and yet we can deploy the same on Kubernetes without changing a single line of code.
The basic idea is to be able to identify services that make the application stateful — such as MySQL and Redis.
For the actual demo on that day I used a simple Laravel application that I wrote quickly only for the demo. I called it "Random Persons". It portrays the basic use of MySQL and Redis to fetch and cache records from a database. I use Laravel's Eloquent Factory to generate random names and countries for testing the application. You can have a look at the demo app, "Random Persons" on GitHub.
I create a simple Laravel application that uses the Eloquent Factory class to generate random names and countries for testing the application.
# database/factories/PersonFactory.php
class PersonFactory extends Factory
{
public function definition(): array
{
return [
'firstname' => $this->faker->firstName,
'lastname' => $this->faker->lastName,
'country' => $this->faker->country,
];
}
}
# database/seeders/PersonSeeder.php
class PersonSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Person::factory()->count(50)->create();
}
}
The application uses the above Factory class and faker()
helper to generate 50 random names and countries.
When the application runs it produces a nice data table that pulls the names and countries from a MySQL database, thus letting us test the APP -> DB connection. In order to test Redis part, I cache the database results to Redis, when fetching the records.
public function index()
{
$persons = Cache::remember('persons_page_' . request('page', 1), 60, function () {
return Person::paginate(5);
});
return view('index', compact('persons'));
}
Now, that we have a functional Laravel application fetching records from MySQL and caching them using Redis, the next step is to deploy it using a container.
I used the FrankenPHP container to build the application.
FROM dunglas/frankenphp
RUN install-php-extensions \
pcntl \
pdo_mysql \
redis \
opcache \
xdebug \
zip \
bcmath \
sockets \
intl \
gd \
imagick \
exif \
gmp \
soap \
xml \
zip \
bz2 \
calendar \
tokenizer
COPY . /app
ENTRYPOINT ["php", "artisan", "octane:frankenphp"]
Next comes Rancher Desktop.
Rancher Desktop is an open-source application that provides a seamless way to run Kubernetes on a laptop or desktop for development and testing. With features like easy cluster management, port forwarding, and support for multiple Kubernetes versions, it allows developers to iterate rapidly and ensures that applications behave consistently across development and production environments.
Rancher Desktop comes with a tool called nerdctl
that can be used to build containers. I ran the below command from the directory that contains the Dockerfile
to build the container image.
nerdctl -n k8s.io build -t random-persons:1.0 .
It builds the container image within the k8s.io
namespace which is a containerd
namespace that contains all the containers started from the CRI plugin by kubelet.
I used the Rancher Desktop to create a ConfigMap
that will provide all the .env
variables for "Random Persons".
I was already running Redis and MySQL as separate deployments. However, in the presentation the assumption was that these services would be running on Virtual Machines which the "kubernetes cluster" could access.
apiVersion: apps/v1
kind: Deployment
metadata:
name: random-persons
labels:
app: random-persons
spec:
replicas: 3
selector:
matchLabels:
app: random-persons
template:
metadata:
labels:
app: random-persons
spec:
containers:
- name: random-persons
image: random-persons:1.0
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: random-persons
I used the above deployment manifest file to deploy three replicas of the "Random Persons" application. Then, I used the below service manifest to create a service that will make application available on port 8000 on the cluster.
apiVersion: v1
kind: Service
metadata:
name: random-persons
spec:
selector:
app: random-persons
ports:
- protocol: TCP
port: 8000
targetPort: 8000
It's faster to apply both manifests using kubectl
that doing it through the interface.
kubectl apply -f .
Finally, create a port forward on the laptop to allow requests on port 8000 be forwarded to the cluster.
kubectl port-forward service/random-persons 8000:8000
Like that, using Rancher Desktop, we can do cloud native application development on any notebook or desktop computer.