Professional Documents
Culture Documents
Getting Started With GKE
Getting Started With GKE
Getting Started With GKE
Abstract: This paper describes step by step approach on how to deploy Jenkins and use Jenkins
pipeline to deploy a simple hello world microservice on GKE cluster on Google Cloud.
Category: Modernization
General Terms: GKE
Additional Keywords and Phrases: Microservices, DevOps , Modernization, Jenkins
Technology used: GCP (Google Cloud Platform), GCloud SDK, Helm, Jenkins, Kubernetes plugin
INTRODUCTION
Google Kubernetes Engine provides a managed environment for deploying, managing, and scaling
enterprise containerized applications using Google infrastructure. GKE environment consists of
multiple machines (specifically, Google Compute Engine instances) grouped together to form a
cluster.
GKE clusters are powered by the Kubernetes open source cluster management system. Kubernetes
provides the mechanisms through which we interact with our GKE cluster. We use Kubernetes
commands and resources to deploy and manage our enterprise containerized applications, perform
administration tasks, set relevant policies, and monitor the health of our deployed workloads.
Using Gcloud:
To work with GCP resources using command line you have option to use cloud shell or google cloud
SDK. Which can be downloaded from following URL:
https://cloud.google.com/appengine/docs/standard/go/download
CD extends CI because it adds another layer after integration and testing of software are
complete.
Source - https://cloud.google.com/blog/products/gcp/google-kubernetes-engine-1-10-is-generally-
available-and-ready-for-the-enterprise
Cluster
A cluster is the foundation of GKE: the Kubernetes objects that represent containerized applications
all run on top of a cluster. In Google Kubernetes Engine, a cluster consists of at least one cluster
master and multiple worker machines called nodes. These master and node machines run the
Kubernetes cluster orchestration system.
Cluster master
The cluster master runs the Kubernetes control plane processes, including the Kubernetes API
server, scheduler, and core resource controllers. The master's lifecycle is managed by GKE when we
create or delete a cluster. This includes upgrades to the Kubernetes version running on the cluster
Nodes: A cluster typically has one or more nodes, which are the worker machines that run our
containerized applications and other workloads. The individual machines are Compute Engine VM
instances that GKE creates on our behalf when we create a cluster.
Each node is managed from the master, which receives updates on each node's self-reported status.
A node runs the services necessary to support the Docker containers that make up your cluster's
workloads. These include the Docker runtime and the Kubernetes node agent (kubelet) which
communicates with the master and is responsible for starting and running Docker containers
scheduled on that node.
In GKE, there are also a number of special containers that run as per-node agents to provide
functionality such as log collection and intra-cluster network connectivity.
Steps:
Contents of namespace.yaml:
kind: Namespace
apiVersion: v1
metadata:
name: devopsgcpnamespace
labels:
name: devopsgcpnamespace
GKE Workloads: GKE works with containerized applications: applications packaged into hardware
independent, isolated user-space instances, for example by using Docker. In GKE and Kubernetes,
these containers, whether for applications or batch jobs, are collectively called workloads. Before
we deploy a workload on a GKE cluster, we must first package the workload into a container.
Pods: A pod is smallest deployment unit in the kubernetes world. It is a group of one or more
containers for eg, docker, with shared network/storage. To verify the pods deployed on Kubernetes
: Kubectl get pods
Deployments: Deployments are used to declare and manage the state of the pods and ReplicaSet.
Deployments is responsible for creating and updating instances of our containerized application.
Both Pod and Deployment are full-fledged objects in the Kubernetes API. Deployment manages
creating Pods by means of ReplicaSets. What it boils down to is that Deployment will create Pods
with spec taken from the template. It is rather unlikely that you will ever need to create Pods
directly for a production use-case.
Services: A service is an abstraction that defines logical group of pods and a policy for accessing
them. .
Exposing a service: kubectl expose deployment test --target-port=80 -type=NodePort
To verify the services: kubectl get svc --namespace jenkinsgcp
Services Types determines how the service will available outside cluster, service type can be on of
the following :
ClusterIP: service is reachable within Kubernetes Cluster (services that are not to be
exposed to external world should be configured as ClusterIP.
NodePort: Service is reachable through NodeIP:NodeportAddress
LoadBalancer: Service is reachable though an external load balancer mapped to
<NODEIP>:NodePort Adress
Quotas: Quotas are a way to limit the usage of resources across the kubernetes cluster. A quota is
defined using object ResourceQuata : CPU, MEMORY<Storage>
To start using google cloud repository you need to enable the source repository, follow the below
steps to enable and start using google cloud source repository:
login to gcp
From the projects list, select a project or create a new one
Go to api library page and enable google cloud source repository
gcloud init
gcloud source repos clone TestApp --project=mystical-runway-247816
cd TestApp
git add .
git –m commit “base version”
git push -u origin master
13) After that command completes, ensure the Jenkins pod goes to the Running state and the
container is in the READY state: kubectl get pods
16) Retrieve the admin password that was automatically created by the Jenkins Helm chart:
The sample application exposes sayHello service which prints hello message and take employee
name from config maps(for config maps refer to page 31 onwards)
The Demo app checked in contains k8 folder which has two manifest files : …/k8s/dev/frontend-
dev.yaml : which contains deployment
…/k8s/services/ frontend.yaml , which exposes deployment as a service
In Jenkins, a pipeline is a group of events or jobs which are interlinked with one another in a
sequence. In simple words, Jenkins Pipeline is a combination of plugins that support the integration
and implementation of continuous delivery pipelines using Jenkins
The Jenkins file explained in next few sections is enclosed below :
You execute the docker build command to create a Docker image based on the Dockerfile
select add credentials from left menu and you will get below screen , and in the kind drop
down select google Service Account from metadata
Login to Jenkins
Select New Item from top left corner, you will get screen like below screenshot, enter the
name of your pipeline and select multibranch pipeline , and click Ok.
The Jenkins will connect to Google source repository, look for branches configured and scan the
Jenkins pipeline and build the code and then deploy. Giving access to Jenkins id to deploy and scale
the pods. Jenkins will deploy the artifacts on GCP using default Jenkins id (incase the deployment
fails with access issue, you can use define role based access to default user , by creating yaml file as
below and execute the same using
kubectl command : kubectl apply -f <your yaml file>
The following manifest file defines an Ingress resource that directs traffic to your web Service
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: basic-ingress
annotations:
spec:
backend:
serviceName: web
servicePort: 8080
Once you have created the configuration for load balance you verify using following command:
Kubectl get ingress
Kubectl describe ingress basic-ingress
Setting up Ingress with Static IP (load balancer)
Configuring a static IP address (optional)
Commands
To create static IP : gcloud compute addresses create jenkins-static-ip --global
To verify the IPs configured: gcloud compute addresses list
Once the static ip is configured you can specify the same in the yaml and update it
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: basic-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: " jenkins-static-ip"
spec:
backend:
serviceName: web
servicePort: 8080
To create a secret, you can either by using yaml file or using from-literal option in the kubectl
command
apiVersion: v1
kind: Secret
metadata:
labels:
application: test
name: ftpserver-credentials
namespace: test-prod
stringData:
username: test
password: testpassword
type: kubernetes.io/basic-auth
apiVersion: v1
Kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: cmVudQo=
Using Secret in the pod
In the deployment.yaml , add following entry
env:
One can verify the environment details of a pod using following command: kubectl exec -ti
<podname> env
volumes:
- name: secret
secret:
secretName: secret-config
Cluster autoscaler
Overview
GKE's cluster autoscaler automatically resizes clusters based on the demands of the workloads.
With autoscaling enabled, GKE automatically adds a new node to your cluster if you've created new
Pods that don't have enough capacity to run; conversely, if a node in your cluster is underutilized
and its Pods can be run on other nodes, GKE can delete the node.
Cluster autoscaling allows you to pay only for resources that are needed at any given moment, and
to automatically get additional resources when demand increases.
Keep in mind that when resources are deleted or moved in the course of autoscaling your cluster,
your services can experience some disruption. For example, if your service consists of a controller
with a single replica, that replica's Pod might be restarted on a different node if its current node is
deleted. Before enabling autoscaling, ensure that your services can tolerate potential disruption or
that they are designed and configured so that downscaling does not disrupt Pods that cannot be
interrupted.
How cluster autoscaler works
The cluster autoscaler works on a per-node pool basis. For each node pool, the autoscaler
periodically checks whether there are any Pods that are not being scheduled and are waiting for a
node with available resources. If such Pods exist, and the autoscaler determines that resizing a node
pool would allow the waiting Pods to be scheduled, then the autoscaler expands that node pool.
Cluster autoscaler also measures the usage of each node against the node pool's total demand for
capacity. If a node has had no new Pods scheduled on it for a set period of time, and all Pods
running on that node can be scheduled onto other nodes in the pool, the autoscaler moves the Pods
and deletes the node. If the node is not able to be drained gracefully after a timeout period
(currently 10 minutes), the node is forcibly terminated. The grace period is not configurable for
GKE clusters.
Cluster autoscaler works based on Pod resource requests, based on how many resources your Pods
have requested. Cluster autoscaler does not take into account the resources your Pods are actively
using. Essentially, cluster autoscaler trusts that the Pod resource requests you've provided are
accurate and schedules Pods on nodes based on that assumption.
If your Pods have requested too few resources (or haven't changed the defaults, which might be
insufficient) and your nodes are experiencing shortages, cluster autoscaler does not correct the
situation. You can help ensure cluster autoscaler works as accurately as possible by making explicit
resource requests for all of your workloads.
The following command creates a node pool of size 3 (default), with node autoscaling based on
cluster load that scales the node pool to a maximum of 5 nodes and a minimum of 1 node:
Autoscaling PODS/Deployments
Vertical Scaling: Vertical scaling refers to adding more resources (CPU/RAM/DISK) to your server
(database or application server is still remaining one) as on demand.
Horizontal Scaling: Horizontal Scaling is a must use technology – whenever a high availability of
(server) services are required. Scaling horizontally involves adding more processing units or
phyiscal machines to your server or database. It involves growing the number of nodes in the
cluster, reducing the responsibilities of each member node by spreading the key space wider and
providing additional end-points for client connections.
Horizontal Scaling has been historically much more used for high level of computing and for
application and services.
Autoscaling in Kubernetes has two dimensions
Cluster Autoscaling: which deals with node scaling operations
Horizontal Pod Autoscaler: which automatically scales the number of pods in a deployment or
replica set
Cluster Autoscaling, together with the Horizontal Pod Autoscaler, can be used to dynamically adjust
computing power, as well as the level of parallelism that your system needs to meet SLAs. While
Cluster Autoscaling is highly dependent on the underlying capabilities of the cloud provider that’s
hosting your cluster, the HPA operates independently of your IaaS/PaaS provider.
The HPA is included in Kubernetes by default, and is implemented as a control loop, with a period
controlled by the controller manager’s --horizontal-pod-autoscaler-sync-period flag, whose default
value is 30 seconds. The controller manager queries resource utilization against the metrics
specified in each HorizontalPodAutoscaler definition.
Prometheus is an open-source software application used for event monitoring and alerting. It
records real-time metrics in a time series database (allowing for high dimensionality) built using a
HTTP pull model, with flexible queries and real-time alerting.
A Pipeline deployment will automatically install and dynamically configure Prometheus to collect
metrics in a centralized (or federated Prometheus) cluster
Vertical Autoscaling
You can use the VerticalPodAutoscaler custom resource to analyze and adjust your containers' CPU
requests and memory requests. You can configure a VerticalPodAutoscaler to make
recommendations for CPU and memory requests, or you can configure it to make automatic
changes to your CPU and memory requests.
Enabling vertical pod autoscaling for a cluster:
gcloud beta container clusters create [CLUSTER_NAME] --enable-vertical-pod-autoscaling --cluster-
version=1.11.8
Vertical Autoscaling
Git hub link for reference code used in this document : https://github.ibm.com/gcp-assets/gke-
jenkins-pipeline