Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
February 18, 2021 02:00 pm GMT

How to deploy an API to a Kubernetes Cluster with a Github Actions CI/CD Workflow

With single page applications becoming the standard of web development, many of us write APIs with which they communicate to display information for the end user.

One can either manually push the API code to a server, build it and serve it, or automate these steps using modern tools like Github Actions.
Moreover, it is easier to build a Docker image of the project and deploy it to an orchestration system like Kubernetes, something that will allow the API to scale and be more resilient.

In this article we will see how you can navigate all these tools to automate your deployment to a Kubernetes Cluster using Github Actions, and we will assume that your project has a Dockerfile in the root directory that expose the API to Port 8080, here is an example:

FROM node:12# Create app directoryWORKDIR /usr/src/app# Install app dependencies# A wildcard is used to ensure both package.json AND package-lock.json are copied# where available (npm@5+)COPY package*.json ./RUN npm install# If you are building your code for production# RUN npm ci --only=production# Bundle app sourceCOPY . .EXPOSE 8080CMD [ "node", "server.js" ]
Enter fullscreen mode Exit fullscreen mode

Kubernetes Deployment File

For this article, let's imagine we have a nodejs API called tutorial-api, this API needs a couple of environment variables to run, like PORT, DB_NAME, etc.

apiVersion: v1kind: Servicemetadata:  name: tutorial-apispec:  type: ClusterIP  ports:    - port: 80      targetPort: 8080  selector:    app: tutorial-api---apiVersion: apps/v1kind: Deploymentmetadata:  name: tutorial-apispec:  replicas: 1  selector:    matchLabels:      app: tutorial-api  template:    metadata:      labels:        app: tutorial-api    spec:      containers:        - name: tutorial-api          image: <IMAGE>          resources:            requests:              memory: "256Mi"              cpu: "300m"            limits:              memory: "512Mi"              cpu: "500m"          ports:            - containerPort: 8080          env:            - name: NODE_ENV              value: "production"            - name: PORT              value: "$PORT"            - name: DB_NAME              value: "$DB_NAME"            - name: DB_USERNAME              value: "$DB_USERNAME"            - name: DB_PASSWORD              value: "$DB_PASSWORD"            - name: DB_HOST              value: "$DB_HOST"            - name: DB_PORT              value: "$DB_PORT"
Enter fullscreen mode Exit fullscreen mode

This file should be located in the root of the project too.

Github Actions

Github Actions allows you to execute a list of actions, once a GitHub event is triggered.
For example, you may want to create a workflow for greeting a new contributor to your repository, or building a Docker image and pushing it to your favorite Docker container registry once you push code to the master branch, you can find a list of triggers here : Events that trigger workflows

CI/CD happens to be one of many types of workflow that you can create on GitHub Actions, and this is what we're going to do in this section.

First, create a new file called ci.yaml inside .github/workflows

For the purpose of this article, we will deploy the Docker container to a Kubernetes Cluster hosted on DigitalOcean, that's why you will find a reference to DigitalOcean's CLI tool doctl, nonetheless, the steps shouldn't change much with other cloud providers.

Here is an example of a Github Actions workflow:

on:  push:    branches:      - masterjobs:  build:    name: Build, push, and deploy    runs-on: ubuntu-latest    steps:      - name: Checkout master        uses: actions/checkout@master      - name: Update SHA        run: echo $GITHUB_SHA > $GITHUB_WORKSPACE/_meta      - name: Install doctl        uses: digitalocean/action-doctl@v2        with:          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}      - name: Build container image        run: docker build -t docker_fake_repo/tutorial-api:$(echo $GITHUB_SHA | head -c7) .      - name: Docker Login        env:          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}        run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD      - name: Push image to Docker Hub        run: docker push docker_fake_repo/tutorial-api      - name: Update deployment file        run: TAG=$(echo $GITHUB_SHA | head -c7) && sed -i 's|<IMAGE>|docker_fake_repo/tutorial-api:'${TAG}'|' $GITHUB_WORKSPACE/deployment.yml      - name: Replace Environment Variables        uses: danielr1996/[email protected]        env:          PORT: ${{ secrets.PORT }}          DB_HOST: ${{ secrets.DB_HOST }}          DB_USERNAME: ${{ secrets.DB_USERNAME }}          DB_PORT: ${{ secrets.DB_PORT }}          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}          DB_NAME: ${{ secrets.DB_NAME }}        with:          input: deployment.yml          output: deploy.yml      - name: Save DigitalOcean kubeconfig        run: doctl kubernetes cluster kubeconfig save $CLUSTER_NAME        env:           CLUSTER_NAME: ${{ secrets.CLUSTER_NAME }}      - name: Deploy to Kubernetes        run: kubectl apply -f deploy.yml      - name: Verify deployment        run: kubectl rollout status deployment/geerd-drive
Enter fullscreen mode Exit fullscreen mode

Let's start with the first block of this file :

on:  push:    branches:      - master
Enter fullscreen mode Exit fullscreen mode

It means that we want to execute the jobs present in this file once code is pushed to the master branch.

In our case, we will run only one job, that we will call build, push, and deploy, this job will run on ubuntu, and will execute couple of steps, each step either uses actions provided for by the community on GitHub's Marketplace, or you can run commands yourself.

  1. Checkout master: the first action checks-out your repository under $GITHUB_WORKSPACE, so our workflow can access it

  2. *Update SHA: We store the value of the SHA of the commit that triggered the workflow in the variable $GITHUB_SHA

  3. Install doctl: Optional step, because in this example we need to connect to the DigitalOcean API to execute commands on the Kubernetes Cluster

  4. Build container image: Building the Docker image, the tag name of the image is the first 7 characters of $GITHUB_SHA

  5. Docker Login: In this example, we will log in to Docker Hub to push our image. The secrets are created under the settings tab of your repository on GitHub, you can add secrets that GitHub will make accessible to the workflow, you should store environment variables and sensitive values there.

  6. Push image to Docker Hub

  7. Update deployment file: Previously, in the deployment.yml file, the image key image: <IMAGE> had the value , we will replace this latter with the tag we just pushed to our container registry.

  8. Replace Environment Variables: If your deployment.yml has environment variables that you Docker container needs, you can use this step to inject the values stored in the repository secrets, which will output a new file deploy.yml

  9. Save DigitalOcean kubeconfig: Choose the cluster we will deploy to.

  10. Deploy to Kubernetes

  11. Verify Deployment

Now that you deployed your project, you need to add an ingress to Kubernetes, NGINX for example, then set up a let's encrypt ssl certificate using cert-manager, so that your API is securely exposed online.


Original Link: https://dev.to/othpwn/how-to-deploy-an-api-to-a-kubernetes-cluster-with-a-github-actions-ci-cd-workflow-km

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To