Kubernetes deployment practice tutorial

The original




























































































































  • API Server: The entry point for all REST commands and the only component of the master node that users can access.
  • Datastore: A powerful, consistent, and highly available key-value store used by Kubernetes clusters.
  • Scheduler: Monitors newly created pods and assigns them to nodes. The deployment of pods and services to nodes is primarily controlled by scheduler.
  • Controller Manager: Manages all controllers that handle routine tasks in the cluster.
  • Worker Node: Main Node agent, also known as minion(old version kubernetes). Pod runs here. The working node contains all the necessary services such as managing the network between containers, communicating with the master node, and allocating resources to the scheduled containers.
  • Docker: Runs on each working node to download images and start containers.
  • Kubelet: Monitors the pod status and ensures that the container is up and running. It also communicates with the data store to get information about the service and record details of the newly created service.
  • Kube-proxy: a network proxy and load balancer for services on a single working node. It is responsible for traffic routing.
  • Kubectl: A CLI tool for users to communicate with Kubernetes API Server.























A simple deployment example








Setup – Kubernetes






GitHub – d-kononov/simple-rails-app-in-k8s












shell

rails new blog







config/database.yml






yaml

production:

adapter: mysql2

encoding: utf8

pool: 5

port: 3306

database: < %= ENV['DATABASE_NAME'] %>

Host: 127.0.0.1

username: < %= ENV['DATABASE_USERNAME'] %>

password: < %= ENV['DATABASE_PASSWORD'] %>













shell

rails g scaffold Article title:string description:text













gem 'mysql2', '< 0.6.0 'and' > = 0.4.4 '

gem 'health_check'







Dockerfile






shell

docker build -t REPO_NAME/IMAGE_NAME:TAG . & & docker push REPO_NAME/IMAGE_NAME:TAG







gCloud CLI
How to
kubectl cluster-info












Apis and services
service account
here
service-account.json






secret
service-account.json






shell

kubectl create secret generic mysql-instance-credentials \

--from-file=credentials.json=service-account.json













shell

kubectl create secret generic simple-app-secrets \

--from-literal=username=$MYSQL_PASSWORD \

--from-literal=password=$MYSQL_PASSWORD \

--from-literal=database-name=$MYSQL_DB_NAME \

--from-literal=secretkey=$SECRET_RAILS_KEY













deployment.yaml
























rake-tasks-job.yaml






shell

kubectl apply -f rake-tasks-job.yaml










shell

kubectl apply -f deployment.yaml










kubectl get pods -w






NAME READY STATUS RESTARTS AGE

sample-799bf9fd9c-86cqf 2/2 Running 0 1m

sample-799bf9fd9c-887vv 2/2 Running 0 1m

sample-799bf9fd9c-pkscp 2/2 Running 0 1m









  1. Create a static IP:gcloud compute addresses create sample-ip --global
  2. Create Ingress:kubectl apply -f ingress.yaml
  3. Check whether the Ingress was created successfully and check its IP address:kubectl get ingress -w
  4. Create a domain name or subdomain for your application





CI/CD






config.yml


  1. The main branch is used for development, for new code. When someone pushes new code to the main branch, CircleCI initiates the main branch’s workflow of building and testing the code.
  2. The production branch is used to deploy new releases to the production environment. The production branch works as follows: push new code (preferably open PR from the main branch to production) to trigger a new build and deployment process; During the build process, CircleCI creates new Docker images, pushes them to GCR and creates new deployments; If it fails, CircleCI will trigger the rollback process.


















kubectl patch deployment sample -p '{" spec" :{" template" :{" spec" :{" containers" :[{"name":"sample","image":"gcr.io/test-d6bf8/simple:'"$CIRCLE_SHA1"'" }}}}}] '

if ! kubectl rollout status deploy/sample; then

echo " DEPLOY FAILED, ROLLING BACK TO PREVIOUS"

kubectl rollout undo deploy/sample

# Deploy failed -> notify slack

else

echo " Deploy succeeded, current version: ${CIRCLE_SHA1}"

# Deploy succeeded -> notify slack

fi

deployment.extensions/sample patched

Waiting for deployment " sample" rollout to finish: 2 out of 3 new replicas have been updated...

Waiting for deployment " sample" rollout to finish: 2 out of 3 new replicas have been updated...

Waiting for deployment " sample" rollout to finish: 2 out of 3 new replicas have been updated...

Waiting for deployment " sample" rollout to finish: 1 old replicas are pending termination...

Waiting for deployment " sample" rollout to finish: 1 old replicas are pending termination...

Waiting for deployment " sample" rollout to finish: 1 old replicas are pending termination...

Waiting for deployment " sample" rollout to finish: 2 of 3 updated replicas are available...

Waiting for deployment " sample" rollout to finish: 2 of 3 updated replicas are available...

deployment " sample" successfully rolled out

Deploy succeeded, current version: 512eabb11c463c5431a1af4ed0b9ebd23597edd9






conclusion


















CI/CD: How do I deploy an effective initial deployment pipeline