Cloud Native First Cloud Native Chapter Meetup at SWAN

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.

Ish Sookun

4 min read
Rancher Desktop running on macOS Sequoia / MacBook Pro M1
Rancher Desktop running on macOS Sequoia / MacBook Pro M1

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.

Screenshot of the 'Random Persons' Laravel application
Screenshot of the 'Random Persons' Laravel application

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.