Skip to content

Instantly share code, notes, and snippets.

@ross-humphrey
Last active February 17, 2020 14:14
Show Gist options
  • Save ross-humphrey/52d898f922a692b4ea4c5ea6c235672e to your computer and use it in GitHub Desktop.
Save ross-humphrey/52d898f922a692b4ea4c5ea6c235672e to your computer and use it in GitHub Desktop.
∛ Kubernetes Notes
Collection of notes on Kubernetes
🔗 Links:
https://www.freecodecamp.org/news/learn-kubernetes-in-under-3-hours-a-detailed-guide-to-orchestrating-containers-114ff420e882/
https://github.com/kelseyhightower/kubernetes-the-hard-way
[IN PROGRESS]
Learn Kubernetes in Under 3 Hours: A Detailed Guide to Orchestrating Containers
https://www.freecodecamp.org/news/learn-kubernetes-in-under-3-hours-a-detailed-guide-to-orchestrating-containers-114ff420e882/
React app commands: sa-frontend
(see https://gist.github.com/candyflossuk/b3a933432a949dd364c80f13c6fcc229)
sudo npm install -g npm-check-updates
npm-check-updates -u
npm install
npm start
npm run build
Install nginx - See https://gist.github.com/candyflossuk/f3b79c3901ba5f6655a9e57bcc7a69c5
cp -a /<path_to_project/sa-frontend/build/. /usr/local/Cellar/nginx/<version_number/html
# Check sentiment analyzer is running
Web application - (Java)
# Install Java (if needed)
# Install Maven - see https://gist.github.com/candyflossuk/bbf676588def6e2f7fd692ac859e0067
# Navigate to sa-webapp diretory
mvn install
# We decide to run the python application being outlined here on port 5000
java -jar sentiment-analysis-web-0.0.1-SNAPSHOT.jar --sa.logic.api.url=http://localhost:5000
Logic - (Python)
# Install Python and PIP and set up environment variables
python -m pip install -r requirements.txt
python -m textblob.download_corpora
# This annoyingly puts a crap folder in your home directory instead you want to move the library to: /usr/local/share
cd /usr/local/share
cp -R /Users/<home_dir_name>/nltk_data . # In mac osx behaviour is as follows: -R will copy the symbolic link which is what it is intended most of the times - in this case this is what we want - as updates and future calls to python -m textblob.download_corpora will then point to this directory 👍🏼
# Delete /Users/<home_dir_name>/nltk_data should you so wish
python sentiment_analysis.py
# Now it all works together.... it's time to containerize it all!
Building the Docker image: React App
Dockerfile = base container image + sequence of instructions on how to build new container image
that does what the app needs
Steps to replicate (from manual steps above) for the React container
> Build static files (npm run build)
> Start nginx
> Copy contents of build from sa-frontend project to nginx/html
Within the tutorial - Dockerhub is used - however for these purposes I am using
'Github Packages'
1. docker login docker.pkg.github.com --username candyflossuk
2. docker build -t docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-frontend:0.1 .
3. docker push docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-frontend:0.1
Running a container: (Using Github Packages)
1. docker pull docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-frontend:0.1
2. docker run -d -p 80:80 docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-frontend:0.1
Docker container specifies two ports (80:80)
> First is the port of the host (laptop)
> Second 80 is the container port to which the calls should be forwarded
Webapp dockerfile:
> ENV declares and environment variable inside the docker container - provides URL for Sentitment analyis API
> EXPOSE exposes a port that we want to access later
Then build the webapp:
1. docker build -t docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-webapp:0.1 .
2. docker push docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-webapp:0.1
And finall the logic:
1. docker build -t docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-logic:0.1 .
2. docker push docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-logic:0.1
TEST
Run Logic:
docker run -d -p 5050:5000 docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-logic:0.1
Get the container ip:
docker container list
# Copy the id of sa-logic container and execute:
docker inspect <container_id>
# containers IP is under property NetworkSettings.IPAddress
Run Webapp:
docker run -d -p 8080:8080 -e SA_LOGIC_API_URL='http://172.17.0.3:5000' docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-webapp:0.1
Run Frontend:
docker run -d -p 80:80 docker.pkg.github.com/candyflossuk/k8s-mastery/sentiment-analysis-frontend:0.1
There was a problem with the flask version - where Werkzeug and Flask had a clash (where Werkzeug had version had moved on, by updating flask to latest 1.1.1 all is fixed)
# Creating a pod
kubectl create -f file_name.yaml
Output: pod "pod_name" created
# Checking pods running
kubectl get pods
# To watch
kubectl get pods --watch
# Port forwarding (the port must be higher than 1024 or it will require special permissions)
kubectl port-forward sa-frontend 8888:80
Services in Kubernetes:
> Kubernetes Service resource acts as an entry point to a set of pods that provide the same functional service.
> Labels are used to differentiate between pods - from a service
Labels - are a two step process:
> Applying a label to all the pods that we want services to target
> Appling a selector to our service so that defines which labeled pods to target.
Editing and applying a kubernetes file change:
> kubectl apply -f sa-frontend-pod.yaml
Get all pods by label name
> kubectl get pod -l app=sa-frontend
- to show said labels use:
> kubectl get pod -l app=sa-frontend --show-labels
====== Service Definition =============
Service definition for a load balancer (terminology)
> Kind: A service
> Type: Specification type (LoadBalancer)
> Port: Specifiees the port in which the service gets requests
> Protocol: Defines communication
> TargetPort: The port at which incoming requests are forwarded
> Selector: Object that contains properties for selecting pods
> app - Defines which pods to target, only pods that are labelled with the labels specified.
Command to create the service:
kubectl create -f service-sa-frontend-lb.yaml
Command to view services
kubectl get svc
View Services using:
kubectl get svc
====== Kubernetes Deployments =======
> Deployment resource automates the process of moving from one version of the application to the next,
zero downtime - in case of failures - you can rollback.
Some terminology from a Kubernetes deploymnet file:
Kind: A deployment
Selector: Pods matching the selctor will be taken under the management of this deployment
Replicas: property of deployments Spec defines how many pods we want to run
Type: Specifies the strategy used in the the deploymnet when moving versions 'RollingUpdate' ensures Zero Downtime
MaxUnavailable - property of 'RollingUpdate' object that specifies the maximum unavailable pods allowed.
MaxSurge - property of 'RollingUpdate' defines the maximum amount of pods added to a deployment
Template - specifies the pod template that the deployment will use
app: sa-frontend - label to use for the pods created by template
ImagePullPolicy - when set to Always - it will pull the container images on each redeployment
Create deployment:
kubectl apply -f sa-frontend-deployment.yaml
Delete old pods:
kubectl get pods # view pods
kubectl delete pod <pod-name>
=== Benefit #1 - Rolling a Zero Downtime deployment: ===
Applying a new deployment image configuration
- kubectl apply -f sa-frontend-deployment-green.yaml --record
Check the status:
- kubectl rollout status deployment sa-frontend
How does 'TheRollingUpdate' works behind the scenes
> After the application of the deployment - Kubernetes compares the new state with the old.
> The RollingUpdate then kicks in
> The RollingUpdate acts according to the rules specified in the deployment file - i.e adheres to the maxSurge and
maxUnavailable.
==== Benefit #2 Rolling back to a previous state ===
Get History of Previous States:
- kubectl rollout history deployment sa-frontend
Rollback to previous version:
- kubectl rollout undo deployment sa-frontend --to-revision=1
--record flag - will ensure the 'CHANGE-CLAUSE' is included in the revision history.
=== KUBE-DNS===
> Kubernetes has a special pod - kube-dns
> By default Kubernetes uses it as the DNS service
> kube-dns cretes a dns record for each created service.
======================== A pause for some more notes (non implementation specific) ====================================
What is Kubernetes?
> Kubernetes is a container orchestrator, that abstracts the underlying infrastructure (Where the containers run)
Abstracting underlying infrastructure
> K8s abstracts the underlying infra by providing a simple API to which we can send requests.
> Requests prompt K8s to meet them to the best of its abilities
> As a developer you don't have to care about the number of nodes, where containers are started and how they communicate
> You do not have to deal with hardware optimization or about nodes going down (because new nodes are added to the cluster)
> K8s will spin up the containers in other nodes that are still running
== SOME TERMINOLOGY ==
API SERVER: The only way to interact with the cluster. Start, stop, check state, logs etc
KUBELET: Monitors the containers(pods) inside a node and communicates with master node
PODS: For now a POD = Container
KUBERNETES STANDARDIZES THE CLOUD PROVIDERS - Kubernetes abstracts away the cloud provider
Kubernetes in Practice - PODS
- Use Minikube for debugging locally...
Main Properties of Pods are as follows:
> Each pod has a unique IP in the K8 cluster
> Pod can have multiple containers, containers can share the same port space.
Communicate via localhost, and communicating with containers of the other
containers of the other pods has to be done in conjunction with the pod ip
> Containers in a pod share the same volume*, port, ip and IPC namespace.
> Each container has their own isolated filesystem - can share via Kubernetes volumes.
A POD Definition has the following:
> Kind: Specifies kind of K8 resource that we want to create
> Name: defines name of resource
> Spec - object that defines desired state for the resource
> Image - container image we want to start in this pod
> Name: is the unique name for a container in a pod
> Container port: port at which the container is listening.
[DONE]
K8s in 5 Minutes Notes
https://www.youtube.com/watch?v=PH-2FfFD2PU
2 main architectural components
> K8 cluster services
> We can enforce "desired state management".
> Feed the cluster services configuration
> Up to the cluster services to run that configuration in my infrastructure
> The cluster services are fronted with an API
> Worker
> A container host
> Kubelet process runs on the worker - to communicate with K8 cluster services
"Desired State Management"
> Sits in an application configuration YAML file
> POD Configuration ( a pod is the smallest unit of configuration in K8s - can have multiple PODs)
> In a POD you can have 1 or more running containers ( a container image )
> Replicas can be specified
> The POD configuration is fed to the 'Cluster Services' which will work out how to schedule the PODs
in the environment and the right number of PODs running.
> If a worker is lost - the running configuration does not match the 'Desired State' and therefore
the scheduler will make sure if a worker goes down for example the POD is re assigned a new worker
to match the 'Desired State' set out in the file
What are containers?
A container image is:
> Lightweight
> Standalone
> Executable package of a piece of software
> It includes everything needed to run it:
> Code
> Runtime
> System tools
> System libraries
> Settings
> Containerized software will always run the same, regardless of environment
> Containers run the same on any server - even production with no differences
Hosting a react application - Virtual Machine vs Container
Cons of a virtual machine:
> Resource inefficient, each VM has overhead of a full OS
> Platform dependant (local vs prod might not work (or not) the same
> Heavyweight and slow scaling when compared to containers
Pros of a container
> Resource efficient - use Host OS with help of docker
> Platform independant - runs anywhere
> Lightweight using image layers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment