Skip to content

otammato/3_Kubernetes_FullStackApp_Deployment_on_AWS_EKS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

66 Commits
 
 

Repository files navigation

Kubernetes, a FullStackApp (Node.js / MySQL) Deployment

Technologies used

  • Kubernetes
  • Docker
  • DockerHub
  • NodeJS
  • MySQL
  • AWS Cloud

Pre-requisites

Launch a Kubernetes cluster. I am using AWS EKS. Please be aware it's a paid service.

Launch a Kubernetes cluster on AWS EKS (use a Terraform template)

  1. Clone this official hashicorp repository with terraform templates:

    git clone https://github.com/hashicorp/learn-terraform-provision-eks-cluster
    

This example repository contains configuration to provision a VPC, security groups, and an EKS cluster with the following architecture: Screenshot 2023-05-28 at 17 53 54



  1. Launch the terraform templates to create infrastructure and a Kubernetes cluster on AWS EKS.

    terraform init
    terraform validate
    terraform apply
    
    Screenshot 2023-05-28 at 17 53 54


If you use AWS Cloud9 as an IDE you also have to disallow AWS Managed Temporary Credentials. Go to Cloud9 > Preferences > AWS Settings > AWS Managed Temporary Credentials and turn it off. Store your permanent AWS access credentials in the environment. Use aws configure command.

Screenshot 2023-05-28 at 14 14 28
Screenshot 2023-05-28 at 18 30 32


Launch and configure a master node to manage the Kubernetes cluster

  1. Launch a new EC2 instance or use the current Cloud9 instance. Here is the example of AWS CLI command to launch a t3.small EC2 instance:

    aws ec2 run-instances --image-id ami-xxxxxxxx --count 1 --instance-type t3.small --key-name MyKeyPair --security-group-ids sg-903004f8 --subnet-id subnet-6e7f829e
    
  2. Configure it as a master node to work with a cluster named education-eks-hCIH6McB:

    aws eks update-kubeconfig --name education-eks-hCIH6McB
    
    Screenshot 2023-05-28 at 19 42 24


  1. Install kubectl

    curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.27.1/2023-04-19/bin/linux/amd64/kubectl
    chmod +x ./kubectl
    mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
    echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
    kubectl version --short --client
    
    Screenshot 2023-05-28 at 19 47 36
  2. Make sure the master node can access the cluster kubectl get svc

    Screenshot 2023-05-28 at 19 54 05


Create a deployment



Screenshot 2023-01-31 at 19 23 50



  1. For the deployment I will be pulling images from DockerHub which I created in the preceding project located here: https://github.com/otammato/FullStack_NodeJS_MySql_Docker.git



Screenshot 2023-01-31 at 19 23 50



  1. Create a Kubernetes manifest and save it as deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: node-app
          image: montcarotte/fullstack_nodejs_mysql_demo:node_app
          ports:
            - containerPort: 3000
          env:
            - name: APP_DB_HOST
              value: mysql-service
            - name: APP_DB_USER
              value: "admin"
        - name: mysql-server
          image: montcarotte/fullstack_nodejs_mysql_demo:mysql_server_new
          ports:
            - containerPort: 3306
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "12345678" # the standard security practice for Kubernetes is to manage passwords through a separate secrets.yaml file. For the simplicity and demo purposes I am not doing it here.
---
apiVersion: v1
kind: Service
metadata:
  name: node-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancer
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

This is a Kubernetes manifest file written in YAML. It defines a Deployment, two Services, and their associated configurations.

The Deployment named "my-deployment" specifies the desired state for running two replicas of a containerized application. It uses a selector to match the pods with the label "app: my-app." The template section defines the pod template for the Deployment. Inside the template, there are two containers defined. The first container is named "node-app" and uses the image "montcarotte/fullstack_nodejs_mysql_demo:node_app." It exposes port 3000 and sets environment variables for the application's database host and user. The second container is named "mysql-server" and uses the image "montcarotte/fullstack_nodejs_mysql_demo:mysql_server_new." It exposes port 3306 and sets the root password for the MySQL server.

Please note that this manifest file provides a simplified example, and in a real-world scenario, it is recommended to use secrets or other secure methods to manage sensitive information like passwords.

Following the Deployment, there are two Service definitions. The first one is named "node-app-service" and exposes port 80. It selects the pods with the label "app: my-app" and forwards traffic to port 3000 of those pods. The type of this Service is LoadBalancer, indicating that it will be externally accessible through a load balancer.

The second Service is named "mysql-service" and exposes port 3306. It also selects the pods with the label "app: my-app" and forwards traffic to port 3306 of those pods. This Service allows communication with the MySQL server container.

The manifest involves environment variables as the Node.js script suggests using ether the default variables or the provided ones for connecting to the database.

Screenshot 2023-01-31 at 19 23 50



Apply the deployment

kubectl apply -f deployment.yaml

Screenshot 2023-06-05 at 20 18 35

Test the app

  1. Retrieve the information about all the Kubernetes resources in the cluster and note the LoadBalancer's external address

kubectl get all

Screenshot 2023-06-05 at 20 44 44

  1. Insert the DNS address into a web browser
Screenshot 2023-06-05 at 20 56 54

Screenshot 2023-06-05 at 20 59 12

To troubleshoot:

Check the container status:

kubectl get pods

To get the logs of a pod named "my-pod" in a specific namespace named "my-namespace":

kubectl logs <mysql-pod-name> -n <my-namespace-name>

If the pod has multiple containers, you can specify the container name using the -c flag.

kubectl logs <mysql-pod-name> -c mysql-server

Check connectivity: Validate the connectivity to the MySQL server from within the cluster. You can create a temporary pod to access the MySQL server container and test the connection.

kubectl run -it --rm --image=mysql:latest mysql-client -- mysql -h <mysql-service-name> -u root -p

To open an interactive shell (such as bash) inside a container,

kubectl exec -it my-pod -c my-container -- /bin/bash

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published