You are on page 1of 59

Install Kubernetes on a CentOS 7 server

1. The first thing that we are going to do is use SSH to log in to all machines. Once we have logged in, we need to
elevate privileges using sudo.
sudo su

2. Disable SELinux.
setenforce 0
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

3. Enable the br_netfilter module for cluster communication.


modprobe br_netfilter
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

4. Disable swap to prevent memory allocation issues.


swapoff -a
vim /etc/fstab. -> Comment out the swap line
5. Install Docker CE.

6. Install the Docker prerequisites.


yum install -y yum-utils device-mapper-persistent-data lvm2

7. Add the Docker repo and install Docker.


yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce

8. Add the Kubernetes repo.


cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

9. Install Kubernetes.
yum install -y kubelet kubeadm kubectl

10. Reboot.

11. Enable and start Docker and Kubernetes.


systemctl enable docker
systemctl enable kubelet
systemctl start docker
systemctl start kubelet
12.Check the group Docker is running in.
docker info | grep -i cgroup

13. Set Kubernetes to run in the same group.


sed -i 's/cgroup-driver=systemd/cgroup-driver=cgroupfs/g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

14. Reload systemd for the changes to take effect, and then restart Kubernetes.
systemctl daemon-reload
systemctl restart kubelet

*Note: Complete the following section on the MASTER ONLY!


15. Initialize the cluster using the IP range for Flannel.
kubeadm init --pod-network-cidr=10.244.0.0/16

16. Copy the kubeadmin join command.

17. Exit sudo and run the following:


mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

18. Deploy Flannel.


kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

19. Check the cluster state.


kubectl get pods —all-namespaces
Note: Complete the following steps on the NODES ONLY!
20.Run the join command that you copied earlier (this command needs to be run as sudo), then check your nodes
from the master.
kubectl get nodes

$ vi pod-example.yaml

Networking in kubernetes:
Network installed in kubernetes is flannel.
DNS in kubernetes:
ReplicaSets:
ReplicaSets is set of pods that all share the same labels.
Deployments: Deployments are used to manage ReplicaSets.

Deployment instructs Kubernetes how to create and update instances of your application. Once a Deployment is cre-
ated, the Kubernetes master schedules mentioned application instances onto individual Nodes in the cluster.

Once the application instances are created, a Kubernetes Deployment Controller continuously monitors those in-
stances. If the Node hosting an instance goes down or is deleted, the Deployment controller replaces the instance
with an instance on another Node in the cluster. This provides a self-healing mechanism to address machine failure
or maintenance.

When we create a Deployment, we need to specify the container image for application and the number of replicas
that we want to run.
Below demonstrates versioning our Deployments and how a Deployment will gracefully roll out those new versions
Services: Provides high availability. Labels are used to connect pods to services. DNS using a service allow to resolve
name to access groups of pods.

From description we need labels


==============================Essential===================================
https://interactive.linuxacademy.com/diagrams/KubernetesEssentialsInteractiveDiagram.html

Kubernetes: Open-source container Management tool which automates container deployment, container (de)scaling
and container load balancing.

Container wrap software in independent packages, portable packages, making it easy to quickly run software in a vari-
ety of environments.
Warping software in container, can quickly and easily run it anywhere. That’s makes containers great for automation.
Container are bit like VMs, But are smaller and start up faster. This means that automation can move quickly and effi-
ciently with containers.

Kubernetes is container orchestration tool and is all about managing containers.

"Manage Containers with Kubernetes"


After spinning up of few Docker containers, you’ll realize that something is missing. If you want to run multiple con-
tainers across multiple machines - which you’ll need to do if you’re using microservices - there is still a lot of work left
to do.

You need to start the right containers at the right time, figure out how they can talk to each other, handle storage
considerations, and deal with failed containers or hardware. Doing all of this manually would be a nightmare. Luckily,
that’s where Kubernetes comes in.

Kubernetes is an open source container orchestration platform, allowing large numbers of containers to work togeth-
er in harmony, reducing operational burden. It helps with things like:
 Running containers across many different machines
 Scaling up or down by adding or removing containers when demand changes
 Keeping storage consistent with multiple instances of an application
 Distributing load between the containers
 Launching new containers on different machines if something fails

Doesn’t Docker do Container Management?


Kubernetes isn’t the only container management tool around. Docker also has its own native container management
tool called Docker Swarm. It lets you deploy containers as Swarms that you can interact with as a single unit, with all
the container management taken care of. To be clear, Kubernetes does not interact with Docker Swarm in any fash-
ion, only the Docker engine itself.

Using Docker with Kubernetes:


Docker and Kubernetes work at different levels. Under the hood, Kubernetes can integrate with the Docker engine to
coordinate the scheduling and execution of Docker containers on Kubelets. The Docker engine itself is responsible for
running the actual container image built by running ‘docker build’.

Kubernetes and Docker are two different things that are related to each other.
After getting used to Docker, you realize that there should be ‘Docker run’ commands or something like that to run
many containers across heterogeneous hosts. Here is when Kubernetes or k8s comes in. It solved many problems that
Docker had.

Kubernetes is a Container Orchestration tool for Docker containers. The function of container orchesteration tool is to
make it sure that application is launched and running properly. If in case a container fails, Kubernetes will spin up an-
other container. It provides a complete system for running so many containers across multiple hosts. It has load bal-
ancer integrated and uses etcd (distributed key value store that stores and replicates all Kubernetes cluster state) for
service discovery.

Docker CLI can’t be used as Kubernetes has its own CLI and API (both are used to create and manage Kubernetes clus-
ters).
Kubernetes tools allow and deploy container over a cluster. It is necessary to have Docker service first as k8s works
with Docker only.

Docker is a run time engine running on your computer. It’s a daemon that is in charge of containers start, stop on that
single computer. So Docker is about managing works within a single machine. When people talk about ‘Docker’, it is
(normally) about individual machine.

Kubernetes is kind of a cluster management software. It is a group of daemons that is in charge of a cluster of ma-
chines. Though there is a single daemon (kubelet) running on an individual machine, the kubelet by itself does not
have much value on the table; it is these group of kubelets (along with kubernetes controllers that control them) make
decisions about the whole cluster. So k8s is about managing works for a cluster of machines. When people talk about
‘k8s’, it’s almost about a cluster of machines.

Features of kubernetes:

1. Automatic Binpacking: Kubernetes packages application and it automatically places containers based on
their requirement and resources that are available.
2. Service discovery & Load balancing: No worries about networking and communication because kubernetes
automatically assign containers their own IP and single DNS name for a set of container. And there will be
load balancing across them.

3. Storage Orchestration: Kubernetes automatically mount storage system.


4. Self-healing- Whenever kubernetes realizes that one of container has failed then it will restart that container
on its own and create a new container in place of crashed one and in case node itself fails then whatever con-
tainer were running in that failed node those containers would be started in another node.

5. Batch Execution: Along with services kubernetes manages batch and CI workload which is more Devops role.
As part of CI workloads Kubernetes can replace container which fails and it can restart and restore the origi-
nal state.

6. Secret and Configuration management: It’s a concept where we can deploy and update secrets. And applica-
tion configuration without having to rebuild your entire image and without having to expose your secrets in
you stack configuration.(Don’t have to restart everything and rebuild your entire container)

7. scaling: Scale application up and down with simple command or GUI or automatically based on CPU usage

8. Automatic Rollbacks and Rollout: Whenever there’s an update to update application which we want to re-
lease kubernetes rolls out these changes and updates to the application or its configurations by this ensuring
that one instance after the other is sent these updates and it makes sure that not all instance are updated at
the same time thus ensuring high availability. Even if something goes wrong then the kubernetes will rollback
that changes.

Kubernetes cannot be compared with Docker. Docker is containerization platform and Kubernetes is container man-
agement platform which meant that once you have containerized your application with the help of docker container
and when scaling up these container to big number like 50 100 that’s where kubernetes would come in when you
have like multiple containers which need to be managed that’s where kubernetes come in and effectively do it.

https://www.youtube.com/watch?v=ahAhOlO3o90
https://github.com/nithyanantha/kubex/

Concept:
1. Cluster: A cluster is a set of physical or VMs and other infrastructure resources used by kubernetes to run ap-
plications.
2. Node[Minion]: A node is physical or VM running kubernetes, onto which pods can be scheduled. This place
where application pods or container are running.
3. Pod: A pod is group of container and volumes
4. Label: A label is a key/value pair that is attached to a resource such as pod to convey a user-defined identify-
ing attribute. Labels can be used to organize and to select subsets of resources.
5. Selector: A selector is an expression that matches labels in order to identify related resources such as which
pods are targeted by a load-balanced service.
6. Replication Controller: A replication controller ensures that a specified number of pods replicas are running
at any one time. It both allows for easy scaling of replicated systems and handles recreation of a pod when
the machine it is on reboots or otherwise fails.
7. Service: A service defines a set of pods and means by which to access them, such as single stable IP address
and corresponding DNS name.
8. Volume: A volume is directory, possibly with some data in it, which is accessible to a container as part of its
file system. Kubernetes volume build upon docker volumes, adding provisioning of the volume directory
and/or device.
9. Namespace: A namespace is like a prefix to the name of resource(products.mypod, sales.mypod). Namespace
help different projects, teams or customer to share a cluster, such as by preventing name collisions between
unrelated teams.
10. Secret: A secrets stores sensitive data such as authentication tokens, which can be made available to con-
tainers upon request. It’s like vault

Master Component: Master is responsible for managing the cluster.


1. Kube-apiserver: Front-end for kubernetes control panel. Validated the configuration data stores in etcd and
the details of deployed container that are in agreement. It processes REST operations, validates them and
updates the corresponding objects in etcd
2. etcd: Store the configuration data accessed by all the nodes(minions and master) in the cluster.
Example of data stored by Kubernetes in etcd are jobs being scheduled, created and deployed pod/services
details and state, namespaces and replication information’s etc.
3. kube-controller-manager: A binary that runs controllers. All controller are compiled into single binary and
run in a single process (Node controller- Responsible for noticing & responding when nodes go down, Repli-
cation controller- Responsible for maintaining correct number of pods for every replications controller ob-
jects in system, Endpoints Controller- Populates endpoint objects i.e joins object & services and Service Ac-
count & Token controller- Create default accounts and API access tokens for new namespaces.)
4. kube-schedular: Watches newly created pod that have no node assigned and select a node for them to run
on.
5. Kubeadm: Used to install and setup kubernetes.
Kubeadm init command is used to master node and kubeadm join to initialize worker node.
Kubeadm token is used to create token,kubeadm version print the version of kubeadm.
Kubeadm upgrade command is used to upgrade Kubernetes and downgrade cluster.

6. DNS: KubeDNS provide DNS name for services to access in simple manner.
Every service defined in cluster is assigned a DNS name. By default, a client Pod’s DNS search list will include
the pod’s own namespace and the cluster’s default domain.
Running Kubernetes DNS pod hold 3 containers-
kubedns- Watches kubernetes master for changes in services and endpoints and maintains in-memory lookup
structure to service DNS request.
dnsmasq container- Add DNS caching to improve performance
healthz container- provide single health check endpoint while performing dual healthchecks.
Example: Assume a service named customerSvc in kubernetes namespace sales. Then we can look up this
service by simply doing a DNS query for customerSvc. Or CustomerSvc.sales or custom-
erSvc.sales.svc.cluster.local
7. User interface:
8. Container resource monitoring:

Node Component:
1. Kubelet: Primary node agent that runs on each node in cluster. Kubeletes manages pods and their contain-
ers,their images and their volumes etc. Kubectl uses Kubernetes API to interect with the cluster. It is available
in each node.
 Watches for pods that have been assigned to its node
 Mounts the pod’s required volumes
 Run the pod’s container via docke

2. Kube-proxy: Enables kubernetes service abstraction by maintaining network rules on the host and perform-
ing connection forwarding. Every node in the cluster runs a simple network proxy. Using proxy node in clus-
ter route request to correct container in node.
3. Container runtime: Container runtime is software that is responsible for running containers. Kubernetes sup-
ports several runtimes: Docker, contained,cri-o,rktlet and any implementation of kubernetes container
runtime interface.
4. Docker: One of basic requirement of nodes is Docker. Docker is responsible for pulling down and running
container from docker images.
5. Flannel: It is an overlay network that works on assigning a range of subnets address. It is used to assign IPs to
each pods running in the cluster and to make the pod to pod and pod to services communications.

Addons:
Addons are pods and services that implements cluster features. The pods may be managed by deploy-
ments,ReplicationControllers, and so on.Namespaced addon objects are created in the kube-system space.

Few addons are below:


DNS: While the other addons are not strictly required, all Kubernetes clusters should have cluster DNS.
Cluster DNS is a DNS server, in addition to the other DNS server(s) in your environment, which serves DNS records for
Kubernetes services.
Containers started by Kubernetes automatically include this DNS server in their DNS searches.

Web UI (Dashboard):
Dashboard is a general purpose, web-based UI for Kubernetes clusters. It allows users to manage and troubleshoot
applications running in the cluster, as well as the cluster itself.

Container Resource Monitoring:


Container Resource Monitoring records generic time-series metrics about containers in a central database, and pro-
vides a UI for browsing that data.

Cluster-level Logging:
A Cluster-level logging mechanism is responsible for saving container logs to a central log store with search/browsing
interface

==========================Kubernetes concept=====================================================
https://kubernetes.io/docs/concepts/

Understanding Kubernetes Objects


Object Spec and Status:
Every Kubernetes object includes two nested object fields that govern the object’s configuration: the object spec and
the object status. The spec, which you must provide, describes your desired state for the object–the characteristics
that you want the object to have. The status describes the actual state of the object, and is supplied and updated by
the Kubernetes system. At any given time, the Kubernetes Control Plane actively manages an object’s actual state to
match the desired state you supplied.

For example, a Kubernetes Deployment is an object that can represent an application running on your cluster. When
you create the Deployment, you might set the Deployment spec to specify that you want three replicas of the applica-
tion to be running. The Kubernetes system reads the Deployment spec and starts three instances of your desired ap-
plication–updating the status to match your spec. If any of those instances should fail (a status change), the Kuber-
netes system responds to the difference between spec and status by making a correction–in this case, starting a re-
placement instance.
Describing a Kubernetes Object:
When you create an object in Kubernetes, you must provide the object spec that describes its desired state, as well as
some basic information about the object (such as a name). When you use the Kubernetes API to create the object (ei-
ther directly or via kubectl), that API request must include that information as JSON in the request body. Most often,
you provide the information to kubectl in a .yaml file. kubectl converts the information to JSON when making the API
request.
Here’s an example .yaml file that shows the required fields and object spec for a Kubernetes Deployment:
application/deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

One way to create a Deployment using a .yaml file like the one above is to use the kubectl apply command in the ku-
bectl command-line interface, passing the .yaml file as an argument. Here’s an example:
$kubectl apply -f https://k8s.io/examples/application/deployment.yaml --record
The output is similar to this:
deployment.apps/nginx-deployment created

Required Fields:
In the .yaml file for the Kubernetes object you want to create, you’ll need to set values for the following fields:

apiVersion - Which version of the Kubernetes API you’re using to create this object
kind - What kind of object you want to create
metadata - Data that helps uniquely identify the object, including a name string, UID, and optional namespace
Also need to provide the object spec field. The precise format of the object spec is different for every Kubernetes ob-
ject, and contains nested fields specific to that object. The Kubernetes API Reference can help you find the spec for-
mat for all of the objects you can create using Kubernetes.

Names:
All objects in the Kubernetes REST API are unambiguously identified by a Name and a UID.
For non-unique user-provided attributes, Kubernetes provides labels and annotations.

A client-provided string that refers to an object in a resource URL, such as /api/v1/pods/some-name.


Only one object of a given kind can have a given name at a time. However, if you delete the object, you can make a
new object with the same name.

By convention, the names of Kubernetes resources should be up to maximum length of 253 characters and consist of
lower case alphanumeric characters, -, and ., but certain resources have more specific restrictions.

UIDs:
A Kubernetes systems-generated string to uniquely identify objects.
Every object created over the whole lifetime of a Kubernetes cluster has a distinct UID. It is intended to distinguish
between historical occurrences of similar entities.

Namespaces:
Kubernetes supports multiple virtual clusters backed by the same physical cluster. These virtual clusters are called
namespaces.

When to Use Multiple Namespaces ?


Namespaces are intended for use in environments with many users spread across multiple teams, or projects. For
clusters with a few to tens of users, you should not need to create or think about namespaces at all. Start using
namespaces when you need the features they provide.

Namespaces provide a scope for names. Names of resources need to be unique within a namespace, but not across
namespaces. Namespaces can not be nested inside one another and each Kubernetes resources can only be in one
namespace.

Namespaces are a way to divide cluster resources between multiple users (via resource quota).

Working with Namespaces:


1. List the current namespaces in a cluster using:
$kubectl get namespaces

NAME STATUS AGE


default Active 11d
kube-system Active 11d
kube-public Active 11d

Kubernetes starts with three initial namespaces:

 default: The default namespace for objects with no other namespace


 kube-system: The namespace for objects created by the Kubernetes system
 kube-public: This namespace is created automatically and is readable by all users (including those not au-
thenticated). This namespace is mostly reserved for cluster usage, in case that some resources should be visi-
ble and readable publicly throughout the whole cluster. The public aspect of this namespace is only a conven-
tion, not a requirement

2. Get the summary of a specific namespace using:


$kubectl get namespaces <name>

3. Get detailed information with:


$kubectl describe namespaces <name>

Name: default
Labels: <none>
Annotations: <none>
Status: Active

No resource quota.

Resource Limits
Type Resource Min Max Default
---- -------- --- --- ---
Container cpu - - 100m

Above details show both resource quota (if present) as well as resource limit ranges.

A namespace can be in one of two phases:


Active the namespace is in use
Terminating the namespace is being deleted, and cannot be used for new objects

Creating a new namespace:


1. Create a new YAML file called my-namespace.yaml with the contents:

apiVersion: v1
kind: Namespace
metadata:
name: <insert-namespace-name-here>
Then run:
$kubectl create -f ./my-namespace.yaml

Note that the name of your namespace must be a DNS compatible label.
There’s an optional field finalizers, which allows observables to purge resources whenever the namespace is deleted.
Keep in mind that if you specify a nonexistent finalizer, the namespace will be created but will get stuck in the Termi-
nating state if the user tries to delete it.

Deleting a namespace:
$kubectl delete namespaces <insert-some-namespace-name>

Setting the namespace for a request:


To temporarily set the namespace for a request, use the --namespace flag.

$kubectl --namespace=<insert-namespace-name-here> run nginx --image=nginx


$kubectl --namespace=<insert-namespace-name-here> get pods

Setting the namespace preference:


Permanently save the namespace for all subsequent kubectl commands in that context.
$kubectl config set-context $(kubectl config current-context) --namespace=<insert-namespace-name-here>
# Validate it
$kubectl config view | grep namespace:
Namespaces and DNS:
When you create a Service, it creates a corresponding DNS entry.
This entry is of the form <service-name>.<namespace-name>.svc.cluster.local, which means that if a container just
uses <service-name>, it will resolve to the service which is local to a namespace. This is useful for using the same con-
figuration across multiple namespaces such as Development, Staging and Production. If you want to reach across
namespaces, you need to use the fully qualified domain name (FQDN).

Not All Objects are in a Namespace:


Most Kubernetes resources (e.g. pods, services, replication controllers, and others) are in some namespaces. However
namespace resources are not themselves in a namespace. And low-level resources, such as nodes and persistentVol-
umes, are not in any namespace.

To see which Kubernetes resources are and aren’t in a namespace:


# In a namespace
$kubectl api-resources --namespaced=true

# Not in a namespace
$kubectl api-resources --namespaced=false

Labels and Selectors:

Labels:
Labels are key/value pairs that are attached to objects, such as pods.
Labels can be used to organize and to select subsets of objects. Labels can be attached to objects at creation time and
subsequently added and modified at any time. Each object can have a set of key/value labels defined. Each Key must
be unique for a given object.
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}

Example labels:
 "release" : "stable", "release" : "canary"
 "environment" : "dev", "environment" : "qa", "environment" : "production"
 "tier" : "frontend", "tier" : "backend", "tier" : "cache"
 "partition" : "customerA", "partition" : "customerB"
 "track" : "daily", "track" : "weekly"

Label selectors:
Unlike names and UIDs, labels do not provide uniqueness. In general, we expect many objects to carry the same la-
bel(s).
Via a label selector, the client/user can identify a set of objects. The label selector is the core grouping primitive in
Kubernetes.

Two types of selectors: equality-based and set-based.A label selector can be made of multiple requirements which are
comma-separated. In the case of multiple requirements, all must be satisfied so the comma separator acts as a logical
AND (&&) operator.

Annotations:
Annotations allow to attach arbitrary non-identifying metadata to objects.
Annotations are key/value pairs.

Attaching metadata to objects:


You can use either labels or annotations to attach metadata to Kubernetes objects.
Labels can be used to select objects and to find collections of objects that satisfy certain conditions. In contrast, anno-
tations are not used to identify and select objects. The metadata in an annotation can be small or large, structured or
unstructured, and can include characters not permitted by labels.
Annotations, like labels, are key/value maps:

"metadata": {
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
}

Field Selectors:
Field selectors let you select Kubernetes resources based on the value of one or more resource fields. Here are some
example field selector queries:
 metadata.name=my-service
 metadata.namespace!=default
 status.phase=Pending

This kubectl command selects all Pods for which the value of the status.phase field is Running:
$kubectl get pods --field-selector status.phase=Running

Chained selectors:
As with label and other selectors, field selectors can be chained together as a comma-separated list. This kubectl
command selects all Pods for which the status.phase does not equal Running and the spec.restartPolicy field equals
Always:
$kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always

kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always


$kubectl get statefulsets,services --field-selector metadata.namespace!=default

Kubernetes Object Management:


kubectl command-line tool supports several different ways to create and manage Kubernetes objects.
kubectl tool supports three kinds of object management:
 Imperative commands
 Imperative object configuration
 Declarative object configuration

Management techniques:
A Kubernetes object should be managed using only one technique. Mixing and matching techniques for the same ob-
ject results in undefined behavior

Imperative commands:
When using imperative commands, a user operates directly on live objects in a cluster. The user provides operations
to the kubectl command as arguments or flags.

Examples:
Run an instance of the nginx container by creating a Deployment object:
$kubectl run nginx --image nginx

Do the same thing using a different syntax:


$kubectl create deployment nginx --image nginx
Imperative object configuration:
In imperative object configuration, the kubectl command specifies the operation (create, replace, etc.), optional flags
and at least one file name. The file specified must contain a full definition of the object in YAML or JSON format.

Examples:
Create the objects defined in a configuration file:
$kubectl create -f nginx.yaml

Delete the objects defined in two configuration files:


$kubectl replace -f nginx.yaml

Declarative object configuration:


When using declarative object configuration, a user operates on object configuration files stored locally, however the
user does not define the operations to be taken on the files. Create, update, and delete operations are automatically
detected per-object by kubectl. This enables working on directories, where different operations might be needed for
different objects.

Examples:
Process all object configuration files in the configs directory, and create or patch the live objects. You can first diff to
see what changes are going to be made, and then apply:

$kubectl diff -f configs/


$kubectl apply -f configs/

Recursively process directories:


$kubectl diff -R -f configs/
$kubectl apply -R -f configs/

Managing Kubernetes Objects Using Imperative Commands:


Kubernetes objects can quickly be created, updated, and deleted directly using imperative commands built into the
kubectl command-line tool.

How to create objects:


The kubectl tool supports verb-driven commands for creating some of the most common object types. The commands
are named to be recognizable to users unfamiliar with the Kubernetes object types.
run: Create a new Deployment object to run Containers in one or more Pods.
expose: Create a new Service object to load balance traffic across Pods.
autoscale: Create a new Autoscaler object to automatically horizontally scale a controller, such as a Deployment.

create <objecttype> [<subtype>] <instancename>


Some objects types have subtypes that you can specify in the create command. For example, the Service object has
several subtypes including ClusterIP, LoadBalancer, and NodePort. Here’s an example that creates a Service with sub-
type NodePort:
$kubectl create service nodeport <myservicename>

How to update objects:


some common update operations. These commands are named to enable users unfamiliar with Kubernetes objects to
perform updates without knowing the specific fields that must be set:
scale: Horizontally scale a controller to add or remove Pods by updating the replica count of the controller.
annotate: Add or remove an annotation from an object.
label: Add or remove a label from an object.
edit: Directly edit the raw configuration of a live object by opening its configuration in an editor.
patch: Directly modify specific fields of a live object by using a patch string.

How to delete objects:


$kubectl delete deployment/nginx

How to view an object:


There are several commands for printing information about an object:
get: Prints basic information about matching objects. Use get -h to see a list of options.
describe: Prints aggregated detailed information about matching objects.
logs: Prints the stdout and stderr for a container running in a Pod.

Using set commands to modify objects before creation:


$kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run | kubectl set selector --local -f - 'envi-
ronment=qa' -o yaml | kubectl create -f -

1. The kubectl create service -o yaml --dry-run command creates the configuration for the Service, but prints it
to stdout as YAML instead of sending it to the Kubernetes API server.
2. The kubectl set selector --local -f - -o yaml command reads the configuration from stdin, and writes the up-
dated configuration to stdout as YAML.
3. The kubectl create -f - command creates the object using the configuration provided via stdin

Using --edit to modify objects before creation:


$kubectl create service clusterip my-svc --clusterip="None" -o yaml --dry-run > /tmp/srv.yaml
$kubectl create --edit -f /tmp/srv.yaml

1. The kubectl create service command creates the configuration for the Service and saves it to /tmp/srv.yaml.
2. The kubectl create --edit command opens the configuration file for editing before it creates the object.

Imperative Management of Kubernetes Objects Using Configuration Files:


Kubernetes objects can be created, updated, and deleted by using the kubectl command-line tool along with an object
configuration file written in YAML or JSON.

How to create objects:


$kubectl create -f <filename|url>

How to update objects:


use kubectl replace -f to update a live object according to a configuration file
$kubectl replace -f <filename|url>

How to delete objects:


delete an object that is described in a configuration file
$kubectl delete -f <filename|url>

How to view an object:


To view information about an object that is described in a configuration file.
$kubectl get -f <filename|url> -o yaml

-o yaml flag specifies that the full object configuration is printed

Limitations:
The create, replace, and delete commands work well when each object’s configuration is fully defined and recorded in
its configuration file. However when a live object is updated, and the updates are not merged into its configuration
file, the updates will be lost the next time a replace is executed. This can happen if a controller, such as a Horizon-
talPodAutoscaler, makes updates directly to a live object. Here’s an example:
1. You create an object from a configuration file.
2. Another source updates the object by changing some field.
3. You replace the object from the configuration file. Changes made by the other source in step 2 are lost.

If you need to support multiple writers to the same object, you can use kubectl apply to manage the object

Creating and editing an object from a URL without saving the configuration:
Suppose you have the URL of an object configuration file. You can use kubectl create --edit to make changes to the
configuration before the object is created. This is particularly useful for tutorials and tasks that point to a configura-
tion file that could be modified by the reader.
$kubectl create -f <url> --edit

Migrating from imperative commands to imperative object configuration:


Migrating from imperative commands to imperative object configuration involves several manual steps.
1. Export the live object to a local object configuration file:
$kubectl get <kind>/<name> -o yaml --export > <kind>_<name>.yaml

2. Manually remove the status field from the object configuration file.
3. For subsequent object management, use replace exclusively.
$kubectl replace -f <kind>_<name>.yaml

Declarative Management of Kubernetes Objects Using Configuration Files:


Kubernetes objects can be created, updated, and deleted by storing multiple object configuration files in a directory
and using kubectl apply to recursively create and update those objects as needed.

How to create objects:


$kubectl apply -f <directory>/

kubectl apply -f <directory>/


apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

Run kubectl diff to print the object that will be created:


$kubectl diff -f https://k8s.io/examples/application/simple_deployment.yaml

Create the object using kubectl apply:


$kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml

Print the live configuration using kubectl get:


$kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml

Read completely for details,Not included here much


https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/

Nodes:
A node is a worker machine in Kubernetes, previously known as a minion. A node may be a VM or physical machine,
depending on the cluster. Each node contains the services necessary to run pods and is managed by the master com-
ponents. The services on a node include the container runtime, kubelet and kube-proxy.
Node Status:
A node’s status contains the following information:
1. Addresses:
The usage of these fields varies depending on your cloud provider or bare metal configuration.
 HostName: The hostname as reported by the node’s kernel. Can be overridden via the kubelet --hostname-
override parameter.
 ExternalIP: Typically the IP address of the node that is externally routable (available from outside the cluster).
 InternalIP: Typically the IP address of the node that is routable only within the cluster
2. Condition:
The conditions field describes the status of all Running nodes.

The node condition is represented as a JSON object. For example, the following response describes a healthy node.

If the Status of the Ready condition remains Unknown or False for longer than the pod-eviction-timeout, an argument
is passed to the kube-controller-manager and all the Pods on the node are scheduled for deletion by the Node Con-
troller. The default eviction timeout duration is five minutes.
3. Capacity:
Describes the resources available on the node: CPU, memory and the maximum number of pods that can be sched-
uled onto the node.

4. Info:
General information about the node, such as kernel version, Kubernetes version (kubelet and kube-proxy version),
Docker version (if used), OS name. The information is gathered by Kubelet from the node.

Management:
Unlike pods and services, a node is not inherently created by Kubernetes: it is created externally by cloud providers
like Google Compute Engine, or it exists in your pool of physical or virtual machines. So when Kubernetes creates a
node, it creates an object that represents the node. After creation, Kubernetes checks whether the node is valid or
not. For example, if you try to create a node from the following content:
There are three components that interact with the Kubernetes node interface: node controller, kubelet, and kubectl.

Node Controller:
The node controller is a Kubernetes master component which manages various aspects of nodes.
The node controller has multiple roles in a node’s life. The first is assigning a CIDR block to the node when it is regis-
tered (if CIDR assignment is turned on).

The second is keeping the node controller’s internal list of nodes up to date with the cloud provider’s list of available
machines. When running in a cloud environment, whenever a node is unhealthy, the node controller asks the cloud
provider if the VM for that node is still available. If not, the node controller deletes the node from its list of nodes.

The third is monitoring the nodes’ health. The node controller is responsible for updating the NodeReady condition of
NodeStatus to ConditionUnknown when a node becomes unreachable (i.e. the node controller stops receiving heart-
beats for some reason, e.g. due to the node being down), and then later evicting all the pods from the node (using
graceful termination) if the node continues to be unreachable. (The default timeouts are 40s to start reporting Condi-
tionUnknown and 5m after that to start evicting pods.) The node controller checks the state of each node every --
node-monitor-period seconds.

Master-Node communication:
Communication paths between the master (really the apiserver) and the Kubernetes cluster.
Cluster to Master:
All communication paths from the cluster to the master terminate at the apiserver.
Apiserver is configured to listen for remote connections on a secure HTTPS port (443).
Master to Cluster:
There are two primary communication paths from the master (apiserver) to the cluster.
1. Apiserver to the kubelet process which runs on each node in the cluster.
2. Apiserver to any node, pod, or service through the apiserver’s proxy functionality.

Not continued

========================================================================================
https://hackr.io/tutorials/learn-kubernetes

==========================Kubernetes Basics========================================================

Kubernetes Command and Outputs:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.3", GitCom-
mit:"721bfa751924da8d1680787490c54b9179b1fed0", GitTreeState:"clean", BuildDate:"2019-02-
01T20:08:12Z",GoVersion:"go1.11.5", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.3", GitCom-
mit:"721bfa751924da8d1680787490c54b9179b1fed0", GitTreeState:"clean", BuildDate:"2019-02-
01T20:00:57Z",GoVersion:"go1.11.5", Compiler:"gc", Platform:"linux/amd64"}

client version is the kubectl version; the server version is the Kubernetes version installed on the master.

$ kubectl cluster-info
Kubernetes master is running at https://172.17.0.57:8443
KubeDNS is running at https://172.17.0.57:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
$

have a running master and a dashboard. The Kubernetes dashboard allows to view your applications in a UI.

$ kubectl get nodes -->shows all nodes that can be used to host our applications
NAME STATUS ROLES AGE VERSION
minikube Ready master 13m v1.13.3
$
Create a Deployment:
A Kubernetes Deployment checks on the health of your Pod and restarts the Pod’s Container if it terminates.
Deployments are the recommended way to manage the creation and scaling of Pods.

1. Use the kubectl create command to create a Deployment that manages a Pod. The Pod runs a Container based on
the provided Docker image.
$ kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node

2. View the Deployment:


$kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1 1 1 1 1m

3. View the Pod:


$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m

4. View cluster events:


$ kubectl get events

5. View the kubectl configuration


$ kubectl config view

Kubectl overview https://kubernetes.io/docs/reference/kubectl/overview/

Create a Service:
By default, the Pod is only accessible by its internal IP address within the Kubernetes cluster. To make the hello-node
Container accessible from outside the Kubernetes virtual network, you have to expose the Pod as a Kubernetes
Service

1. Expose the Pod to the public internet using the kubectl expose command:
$kubectl expose deployment hello-node --type=LoadBalancer --port=8080

--type=LoadBalancer flag indicates that you want to expose your Service outside of the cluster.

2. View the Service you just created:


$kubectl get services

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE


hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m

Clean up:
clean up the resources created in your cluster:
$kubectl delete service hello-node
$kubectl delete deployment hello-node

Kubectl basics:
Type kubectl in the terminal to see its usage.

$ kubectl
kubectl controls the Kubernetes cluster manager.

Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/

Basic Commands (Beginner):


create Create a resource from a file or from stdin.
expose Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service
run Run a particular image on the cluster
set Set specific features on objects

Basic Commands (Intermediate):


explain Documentation of resources
get Display one or many resources
edit Edit a resource on the server
delete Delete resources by filenames, stdin, resources and names, or by resources and label selector

Deploy Commands:
rollout Manage the rollout of a resource
scale Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job
autoscale Auto-scale a Deployment, ReplicaSet, or ReplicationController

Cluster Management Commands:


certificate Modify certificate resources.
cluster-info Display cluster info
top Display Resource (CPU/Memory/Storage) usage.
cordon Mark node as unschedulable
uncordon Mark node as schedulable
drain Drain node in preparation for maintenance
taint Update the taints on one or more nodes

Troubleshooting and Debugging Commands:


describe Show details of a specific resource or group of resources
logs Print the logs for a container in a pod
attach Attach to a running container
exec Execute a command in a container
port-forward Forward one or more local ports to a pod
proxy Run a proxy to the Kubernetes API server
cp Copy files and directories to and from containers.
auth Inspect authorization

Advanced Commands:
diff Diff live version against would-be applied version
apply Apply a configuration to a resource by filename or stdin
patch Update field(s) of a resource using strategic merge patch
replace Replace a resource by filename or stdin
wait Experimental: Wait for a specific condition on one or many
resources.
convert Convert config files between different API versions

Settings Commands:
label Update the labels on a resource
annotate Update the annotations on a resource
completion Output shell completion code for the specified shell (bash or
zsh)

Other Commands:
api-resources Print the supported API resources on the server
api-versions Print the supported API versions on the server, in the form of
"group/version"
config Modify kubeconfig files
plugin Provides utilities for interacting with plugins.
version Print the client and server version information

Usage:
kubectl [flags] [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all
commands).
$

Deploy our app:


Run first app on Kubernetes with the kubectl run command. The run command creates a new deployment. We need to
provide the deployment name and app image location (include the full repository url for images hosted outside Docker
hub). We want to run the app on a specific port so we add the --port parameter.

$kubectl run kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=8080

Deployed first application by creating a deployment. This performed a few things:

searched for a suitable node where an instance of the application could be run (we have only 1 available node)
scheduled the application to run on that Node
configured the cluster to reschedule the instance on a new Node when needed

$ kubectl get deployments


NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 1/1 1 1 3m28s
$

1 deployment running a single instance of your app. The instance is running inside a Docker container on your node

View our app:


$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6bf84cb898-hlb9j 1/1 Running 0 90s

Pods that are running inside Kubernetes are running on a private, isolated network. By default they are visible from
other pods and services within the same kubernetes cluster, but not outside that network. When we use kubectl, we're
interacting through an API endpoint to communicate with our application.

kubectl command can create a proxy that will forward communications into the cluster-wide, private network. The
proxy can be terminated by pressing control-C and won't show any output while its running.
We will open a second terminal window to run the proxy
$ kubectl proxy
Starting to serve on 127.0.0.1:8001

now have a connection between our host (the online terminal) and the Kubernetes cluster. The proxy enables direct
access to the API from these terminals
see all those APIs hosted through the proxy endpoint, now available at through http://localhost:8001. For example, we
can query the version directly through the API using the curl command:

$ curl http://localhost:8001/version

{
"major": "1",
"minor": "13",
"gitVersion": "v1.13.3",
"gitCommit": "721bfa751924da8d1680787490c54b9179b1fed0",
"gitTreeState": "clean",
"buildDate": "2019-02-01T20:00:57Z",
"goVersion": "go1.11.5",
"compiler": "gc",
"platform": "linux/amd64"
}$
The API server will automatically create an endpoint for each pod, based on the pod name, that is also accessible
through the proxy.
First we need to get the Pod name, and we'll store in the environment variable POD_NAME:

$ export POD_NAME=$(kubectl get pods -o go-template --template '{{range


.items}}{{.metadata.name}}{{"\n"}}{{end}}')
$ echo Name of the Pod: $POD_NAME
Name of the Pod: kubernetes-bootcamp-6bf84cb898-hlb9j

Now we can make an HTTP request to the application running in that pod:
$ curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-hlb9j | v=1
$

The url is the route to the API of the Pod.

Kubernetes Pods:
When created a Deployment, Kubernetes created a Pod to host application instance.
A Pod is a Kubernetes abstraction that represents a group of one or more application containers (such as Docker), and
some shared resources for those containers.
Those resources include:
 Shared storage, as Volumes
 Networking, as a unique cluster IP address
 Information about how to run each container, such as the container image version or specific ports to use

A Pod models an application-specific "logical host" and can contain different application containers which are relatively
tightly coupled. For example, a Pod might include both the container with your Node.js app as well as a different
container that feeds the data to be published by the Node.js webserver. The containers in a Pod share an IP Address and
port space, are always co-located and co-scheduled, and run in a shared context on the same Node

Pods are the atomic unit on the Kubernetes platform. When we create a Deployment on Kubernetes, that Deployment
creates Pods with containers inside them (as opposed to creating containers directly). Each Pod is tied to the Node
where it is scheduled, and remains there until termination (according to restart policy) or deletion. In case of a Node
failure, identical Pods are scheduled on other available Nodes in the cluster.

Most common operations can be done with the following kubectl commands:
 kubectl get - list resources
 kubectl describe - show detailed information about a resource
 kubectl logs - print the logs from a container in a pod
 kubectl exec - execute a command on a container in a pod

$ kubectl get pods


NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6bf84cb898-8gqdj 1/1 Running 0 5s

To view what containers are inside that Pod and what images are used to build those containers we run the describe
pods command:
$ kubectl describe pods
Name: kubernetes-bootcamp-6bf84cb898-8gqdj
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.6
Start Time: Sun, 07 Apr 2019 17:31:46 +0000
Labels: pod-template-hash=6bf84cb898
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.2
Controlled By: ReplicaSet/kubernetes-bootcamp-6bf84cb898
Containers:
kubernetes-bootcamp:
Container ID: docker://37c0eee8652d903e282e7168835f002e6af9fc5a990ae865fc12ba4ca553824a
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 07 Apr 2019 17:31:47 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-7npqp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-7npqp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-7npqp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 25s default-scheduler Successfully assigned default/kubernetes-bootcamp-6bf84cb898-8gqdj to
minikube
Normal Pulled 24s kubelet, minikube Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already
present on machine
Normal Created 24s kubelet, minikube Created container
Normal Started 24s kubelet, minikube Started container
$

Pods are running in an isolated, private network - so we need to proxy access to them so we can debug and interact with
them. To do this, we'll use the kubectl proxy command to run a proxy in a second terminal window. Click on the
command below to automatically open a new terminal and run the proxy:
$ kubectl proxy
Starting to serve on 127.0.0.1:8001

get the Pod name and query that pod directly through the proxy. To get the Pod name and store it in the POD_NAME
environment variable:

$ echo Name of the Pod: $POD_NAME


Name of the Pod: kubernetes-bootcamp-6bf84cb898-8gqdj

To see the output of our application, run a curl request.


$ curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-8gqdj | v=1
$

View the container logs


Anything that the application would normally send to STDOUT becomes logs for the container within the Pod. We can
retrieve these logs using the kubectl logs command:
$ kubectl logs $POD_NAME
Kubernetes Bootcamp App Started At: 2019-04-07T17:31:47.598Z | Running On: kubernetes-bootcamp-6bf84cb898-
8gqdj
Running On: kubernetes-bootcamp-6bf84cb898-8gqdj | Total Requests: 1 | App Uptime: 302.001 seconds | Log Time:
2019-04-07T17:36:49.599Z
$

Executing command on the container:


Execute commands directly on the container once the Pod is up and running. For this, we use the exec command and
use the name of the Pod as a parameter. Let’s list the environment variables:
$ kubectl exec $POD_NAME env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=kubernetes-bootcamp-6bf84cb898-8gqdj
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
NPM_CONFIG_LOGLEVEL=info
NODE_VERSION=6.3.1
HOME=/root
$

start a bash session in the Pod’s container:


$ kubectl exec -ti $POD_NAME bash
root@kubernetes-bootcamp-6bf84cb898-8gqdj:/#

now an open console on the container where we run our NodeJS application. The source code of the app is in the
server.js file:
root@kubernetes-bootcamp-6bf84cb898-8gqdj:/# cat server.js
var http = require('http');
var requests=0;
var podname= process.env.HOSTNAME;
var startTime;
var host;
var handleRequest = function(request, response) {
response.setHeader('Content-Type', 'text/plain');
response.writeHead(200);
response.write("Hello Kubernetes bootcamp! | Running on: ");
response.write(host);
response.end(" | v=1\n");
console.log("Running On:" ,host, "| Total Requests:", ++requests,"| App Uptime:", (new Date() - startTime)/1000 ,
"seconds", "| Log Time:",new Date());
}
var www = http.createServer(handleRequest);
www.listen(8080,function () {
startTime = new Date();;
host = process.env.HOSTNAME;
console.log ("Kubernetes Bootcamp App Started At:",startTime, "| Running On: " ,host, "\n" );
});
root@kubernetes-bootcamp-6bf84cb898-8gqdj:/#

You can check that the application is up by running a curl command:


root@kubernetes-bootcamp-6bf84cb898-8gqdj:/# curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-8gqdj | v=1
root@kubernetes-bootcamp-6bf84cb898-8gqdj:/#

To close your container connection type exit.


root@kubernetes-bootcamp-6bf84cb898-8gqdj:/# exit
exit
$

Using a service to expose you App:


Overview of Kubernetes Services
When a worker node dies, the Pods running on the Node are also lost. A ReplicaSet might then dynamically drive the
cluster back to desired state via creation of new Pods to keep your application running.
A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them.
Services enable a loose coupling between dependent Pods.

A Service is defined using YAML (preferred) or JSON, like all Kubernetes objects.
set of Pods targeted by a Service is usually determined by a LabelSelector.

Although each Pod has a unique IP address, those IPs are not exposed outside the cluster without a Service.
Services allow your applications to receive traffic. Services can be exposed in different ways by specifying a type in the
ServiceSpec:

 ClusterIP (default) - Exposes the Service on an internal IP in the cluster. This type makes the Service only
reachable from within the cluster.
 NodePort - Exposes the Service on the same port of each selected Node in the cluster using NAT. Makes a
Service accessible from outside the cluster using <NodeIP>:<NodePort>. Superset of ClusterIP.
 LoadBalancer - Creates an external load balancer in the current cloud (if supported) and assigns a fixed,
external IP to the Service. Superset of NodePort.
 ExternalName - Exposes the Service using an arbitrary name (specified by externalName in the spec) by
returning a CNAME record with the name. No proxy is used. This type requires v1.7 or higher of kube-dns

Note that there are some use cases with Services that involve not defining selector in the spec. A Service created
without selector will also not create the corresponding Endpoints object. This allows users to manually map a Service
to specific endpoints. Another possibility why there may be no selector is you are strictly using type: ExternalName
A Service routes traffic across a set of Pods. Services are the abstraction that allows pods to die and replicate in
Kubernetes without impacting your application. Discovery and routing among dependent Pods (such as the frontend and
backend components in an application) is handled by Kubernetes Services.
Services match a set of Pods using labels and selectors, a grouping primitive that allows logical operation on objects in
Kubernetes. Labels are key/value pairs attached to objects and can be used in any number of ways:

 Designate objects for development, test, and production


 Embed version tags
 Classify an object using tags
Labels can be attached to objects at creation time or later on. They can be modified at any time.

In this scenario will learn how to expose Kubernetes applications outside the cluster using the kubectl expose
command. You will also learn how to view and apply labels to objects with the kubectl label command
Step 1 Create a new service:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6bf84cb898-wffdg 1/1 Running 0 23m
$

create a new service and expose it to external traffic we’ll use the expose command with NodePort as parameter
(minikube does not support the LoadBalancer option yet)
$ kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
service/kubernetes-bootcamp exposed
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 28m
kubernetes-bootcamp NodePort 10.108.195.3 <none> 8080:32359/TCP 44s
$

We have now a running Service called kubernetes-bootcamp. Here we see that the Service received a unique cluster-IP,
an internal port and an external-IP (the IP of the Node).
To find out what port was opened externally (by the NodePort option) we’ll run the describe service command:
$ kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations: <none>
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.108.195.3
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 32359/TCP
Endpoints: 172.18.0.4:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
$

Create an environment variable called NODE_PORT that has the value of the Node port assigned:
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports
0).nodePort}}')
$ echo NODE_PORT=$NODE_PORT
NODE_PORT=32359
$

Now we can test that the app is exposed outside of the cluster using curl, the IP of the Node and the externally exposed
port:
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-wffdg | v=1
$

And we get a response from the server. The Service is exposed

Step 2: Using labels

Deployment created automatically a label for our Pod. With describe deployment command you can see the name of the
label:
$ kubectl describe deployment
Name: kubernetes-bootcamp
Namespace: default
CreationTimestamp: Mon, 08 Apr 2019 03:07:24 +0000
Labels: run=kubernetes-bootcamp
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=kubernetes-bootcamp
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=kubernetes-bootcamp
Containers:
kubernetes-bootcamp:
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: kubernetes-bootcamp-6bf84cb898 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 36m deployment-controller Scaled up replica set kubernetes-bootcamp-6bf84cb898 to 1
$
use this label to query our list of Pods. We’ll use the kubectl get pods command with -l as a parameter, followed by the
label values:
$ kubectl get pods -l run=kubernetes-bootcamp
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6bf84cb898-7tzxg 1/1 Running 0 59s

same to list the existing services:


$ kubectl get services -l run=kubernetes-bootcamp
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-bootcamp NodePort 10.105.54.3 <none> 8080:32626/TCP 48s
$

Get the name of the Pod and store it in the POD_NAME environment variable:
$ export POD_NAME=$(kubectl get pods -o go-template --template '{{range
.items}}{{.metadata.name}}{{"\n"}}{{end}}')
$ echo Name of the Pod: $POD_NAME
Name of the Pod: kubernetes-bootcamp-6bf84cb898-7tzxg
$

To apply a new label we use the label command followed by the object type, object name and the new label:
$ kubectl label pod $POD_NAME app=v1
pod/kubernetes-bootcamp-6bf84cb898-7tzxg labeled
$

This will apply a new label to our Pod (we pinned the application version to the Pod), and we can check it with the
describe pod command:
$ kubectl describe pods $POD_NAME
Name: kubernetes-bootcamp-6bf84cb898-7tzxg
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.48
Start Time: Mon, 08 Apr 2019 03:53:57 +0000
Labels: app=v1
pod-template-hash=6bf84cb898
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.2
Controlled By: ReplicaSet/kubernetes-bootcamp-6bf84cb898
Containers:
kubernetes-bootcamp:
Container ID: docker://7559c75615079831d550b87cc718861427daa2d9a4469c0f923c55ec1e79ad36
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 08 Apr 2019 03:53:59 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-jjkgx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-jjkgx:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-jjkgx
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 108s default-scheduler 0/1 nodes are available: 1 node(s) had taints that the pod didn't
tolerate.
Normal Scheduled 108s default-scheduler Successfully assigned default/kubernetes-bootcamp-6bf84cb898-
7tzxg to minikube
Warning FailedMount 107s kubelet, minikube MountVolume.SetUp failed for volume "default-token-jjkgx" :
couldn't propagate object cache: timed out waiting for the condition
Normal Pulled 106s kubelet, minikube Container image "gcr.io/google-samples/kubernetes-bootcamp:v1"
already present on machine
Normal Created 106s kubelet, minikube Created container
Normal Started 106s kubelet, minikube Started container

$ kubectl get pods -l app=v1


NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6bf84cb898-7tzxg 1/1 Running 0 2m6s

Step 3 Deleting a service:


delete Services you can use the delete service command. Labels can be used also here:
$ kubectl delete service -l run=kubernetes-bootcamp
service "kubernetes-bootcamp" deleted
$

Confirm that the service is gone:


$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11m

This confirms that our Service was removed. To confirm that route is not exposed anymore you can curl the previously
exposed IP and port:
$ curl $(minikube ip):$NODE_PORT
curl: (7) Failed to connect to 172.17.0.48 port 32626: Connection refused
$

This proves that the app is not reachable anymore from outside of the cluster. You can confirm that the app is still
running with a curl inside the pod:
$ kubectl exec -ti $POD_NAME curl localhost:8080
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-7tzxg | v=1
$

Running Multiple Instances of Your App:


Scaling an application
Scaling is accomplished by changing the number of replicas in a Deployment.
Running multiple instances of an application will require a way to distribute the traffic to all of them. Services have an
integrated load-balancer that will distribute network traffic to all Pods of an exposed Deployment. Services will monitor
continuously the running Pods using endpoints, to ensure the traffic is sent only to available Pods.

To scale a deployment with kubectl scale and to see the load balancing in action
Step 1: Scaling a deployment
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 1/1 1 1 31s
$
scale the Deployment to 4 replicas. We’ll use the kubectl scale command, followed by the deployment type, name and
desired number of instances:
$ kubectl scale deployments/kubernetes-bootcamp --replicas=4
deployment.extensions/kubernetes-bootcamp scaled
$

$ kubectl get deployments


NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 4/4 4 4 3m17s
$

change was applied, and we have 4 instances of the application available. Next, let’s check if the number of Pods
changed:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
READINESS GATES
kubernetes-bootcamp-6bf84cb898-5hjbz 1/1 Running 0 3m55s 172.18.0.2 minikube <none>
<none>
kubernetes-bootcamp-6bf84cb898-62fcv 1/1 Running 0 65s 172.18.0.7 minikube <none> <none>
kubernetes-bootcamp-6bf84cb898-jnzkx 1/1 Running 0 65s 172.18.0.5 minikube <none> <none>
kubernetes-bootcamp-6bf84cb898-tplgs 1/1 Running 0 65s 172.18.0.6 minikube <none> <none>
$

There are 4 Pods now, with different IP addresses. The change was registered in the Deployment events log. To check
that, use the describe command:
$ kubectl describe deployments/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
CreationTimestamp: Mon, 08 Apr 2019 04:38:30 +0000
Labels: run=kubernetes-bootcamp
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=kubernetes-bootcamp
Replicas: 4 desired | 4 updated | 4 total | 4 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=kubernetes-bootcamp
Containers:
kubernetes-bootcamp:
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: kubernetes-bootcamp-6bf84cb898 (4/4 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 4m39s deployment-controller Scaled up replica set kubernetes-bootcamp-6bf84cb898 to
1
Normal ScalingReplicaSet 109s deployment-controller Scaled up replica set kubernetes-bootcamp-6bf84cb898 to 4
$

Step 2: Load Balancing


Let’s check that the Service is load-balancing the traffic. To find out the exposed IP and Port
$ kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations: <none>
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.104.183.222
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30866/TCP
Endpoints: 172.18.0.2:8080,172.18.0.5:8080,172.18.0.6:8080 + 1 more...
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
$

Create an environment variable called NODE_PORT that has a value as the Node port:
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports
0).nodePort}}')
$ echo NODE_PORT=$NODE_PORT
NODE_PORT=30866
$

we’ll do a curl to the exposed IP and port. Execute the command multiple times:
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-5hjbz | v=1
$
$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-jnzkx | v=1

We hit a different Pod with every request. This demonstrates that the load-balancing is working

Step 3: Scale Down


To scale down the Service to 2 replicas, run again the scale command:
$ kubectl scale deployments/kubernetes-bootcamp --replicas=2
deployment.extensions/kubernetes-bootcamp scaled
$

List the Deployments to check if the change was applied with the get deployments command:
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 2/2 2 2 9m39s
$

The number of replicas decreased to 2. List the number of Pods, with get pods:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
READINESS GATES
kubernetes-bootcamp-6bf84cb898-5hjbz 1/1 Running 0 9m56s 172.18.0.2 minikube <none>
<none>
kubernetes-bootcamp-6bf84cb898-jnzkx 1/1 Running 0 7m6s 172.18.0.5 minikube <none>
<none>
$
Performing a Rolling Update:
Updating an application
Users expect applications to be available all the time and developers are expected to deploy new versions of them
several times a day. In Kubernetes this is done with rolling updates. Rolling updates allow Deployments' update to take
place with zero downtime by incrementally updating Pods instances with new ones. The new Pods will be scheduled on
Nodes with available resources

Rolling updates allow the following actions:


 Promote an application from one environment to another (via container image updates)
 Rollback to previous versions
 Continuous Integration and Continuous Delivery of applications with zero downtime

scenario is to update a deployed application with kubectl set image and to rollback with the rollout undo command:

$ kubectl get deployments


NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 4/4 4 4 42s

$ kubectl get pods


NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-6bf84cb898-cdfcf 1/1 Running 0 38s
kubernetes-bootcamp-6bf84cb898-q7pl9 1/1 Running 0 38s
kubernetes-bootcamp-6bf84cb898-v6hh6 1/1 Running 0 38s
kubernetes-bootcamp-6bf84cb898-z8kvk 1/1 Running 0 38s
$
$

To view the current image version of the app, run a describe command against the Pods (look at the Image field):

$ kubectl describe pods


Name: kubernetes-bootcamp-6bf84cb898-cdfcf
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:54:31 +0000
Labels: pod-template-hash=6bf84cb898
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.6
Controlled By: ReplicaSet/kubernetes-bootcamp-6bf84cb898
Containers:
kubernetes-bootcamp:
Container ID: docker://212f9ac40cb5cc20b1ddaabf905da17eb4a845965aa91b5077426a222f031747
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:54:33 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 49s default-scheduler Successfully assigned default/kubernetes-bootcamp-6bf84cb898-cdfcf to
minikube
Normal Pulled 48s kubelet, minikube Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already
present on machine
Normal Created 47s kubelet, minikube Created container
Normal Started 47s kubelet, minikube Started container

Name: kubernetes-bootcamp-6bf84cb898-q7pl9
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:54:31 +0000
Labels: pod-template-hash=6bf84cb898
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.7
Controlled By: ReplicaSet/kubernetes-bootcamp-6bf84cb898
Containers:
kubernetes-bootcamp:
Container ID: docker://630555b58bab987e88a086d6d75d9414f0b537bb95d3706224ae7c7faf74da68
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:54:33 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 49s default-scheduler Successfully assigned default/kubernetes-bootcamp-6bf84cb898-q7pl9 to
minikube
Normal Pulled 47s kubelet, minikube Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already
present on machine
Normal Created 47s kubelet, minikube Created container
Normal Started 47s kubelet, minikube Started container

Name: kubernetes-bootcamp-6bf84cb898-v6hh6
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:54:31 +0000
Labels: pod-template-hash=6bf84cb898
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.5
Controlled By: ReplicaSet/kubernetes-bootcamp-6bf84cb898
Containers:
kubernetes-bootcamp:
Container ID: docker://3ea7f634915ed2089def2dcf92271f2ff5b14605e719015dfacbca021474f074
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:54:33 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 49s default-scheduler Successfully assigned default/kubernetes-bootcamp-6bf84cb898-v6hh6 to
minikube
Normal Pulled 48s kubelet, minikube Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already
present on machine
Normal Created 48s kubelet, minikube Created container
Normal Started 47s kubelet, minikube Started container

Name: kubernetes-bootcamp-6bf84cb898-z8kvk
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:54:31 +0000
Labels: pod-template-hash=6bf84cb898
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.4
Controlled By: ReplicaSet/kubernetes-bootcamp-6bf84cb898
Containers:
kubernetes-bootcamp:
Container ID: docker://68f49124f7dc744bc8c645fbca3f8d177421fb5eedfdea596d42f3e273259d31
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:54:33 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 49s default-scheduler Successfully assigned default/kubernetes-bootcamp-6bf84cb898-z8kvk to
minikube
Normal Pulled 48s kubelet, minikube Container image "gcr.io/google-samples/kubernetes-bootcamp:v1" already
present on machine
Normal Created 48s kubelet, minikube Created container
Normal Started 47s kubelet, minikube Started container
$

To update the image of the application to version 2, use the set image command, followed by the deployment name and
the new image version:
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
deployment.extensions/kubernetes-bootcamp image updated
$

The command notified the Deployment to use a different image for your app and initiated a rolling update. Check the
status of the new Pods, and view the old one terminating with the get pods command:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-5bf4d5689b-6v7bh 1/1 Running 0 97s
kubernetes-bootcamp-5bf4d5689b-8v24c 1/1 Running 0 99s
kubernetes-bootcamp-5bf4d5689b-gkh6t 1/1 Running 0 99s
kubernetes-bootcamp-5bf4d5689b-ztcwr 1/1 Running 0 97s
$
Step 2: Verify an update:
let’s check that the App is running. To find out the exposed IP and Port we can use describe service:
$ kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: run=kubernetes-bootcamp
Annotations: <none>
Selector: run=kubernetes-bootcamp
Type: NodePort
IP: 10.99.10.244
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 32665/TCP
Endpoints: 172.18.0.10:8080,172.18.0.11:8080,172.18.0.8:8080 + 1 more...
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
$

Create an environment variable called NODE_PORT that has the value of the Node port assigned:
$ export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports
0).nodePort}}')
$ echo NODE_PORT=$NODE_PORT
NODE_PORT=32665
$

Next, we’ll do a curl to the the exposed IP and port:


$ curl $(minikube ip):$NODE_PORT
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-5bf4d5689b-8v24c | v=2
$

We hit a different Pod with every request and we see that all Pods are running the latest version (v2).

The update can be confirmed also by running a rollout status command:


$ kubectl rollout status deployments/kubernetes-bootcamp
deployment "kubernetes-bootcamp" successfully rolled out
$

To view the current image version of the app, run a describe command against the Pods:
$ kubectl describe pods
Name: kubernetes-bootcamp-5bf4d5689b-6v7bh
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:49 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.10
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://ce27779618b55277178059819cfeb84063eedfae6d4a95107e91c20882b4ed5a
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:50 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m57s default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-6v7bh
to minikube
Normal Pulled 5m56s kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 5m56s kubelet, minikube Created container
Normal Started 5m56s kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-8v24c
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:47 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.9
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://61ae4e10f2f03a58203ed7d77669123488dd33dfbdf85d0cef864c0891dcf859
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m59s default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-8v24c
to minikube
Normal Pulled 5m58s kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 5m58s kubelet, minikube Created container
Normal Started 5m58s kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-gkh6t
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:47 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.8
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://2e473aefd5502d4aaf29168c3c690e2cdfdd859d1ea0781c12c374b31c19ba0e
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m59s default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-gkh6t
to minikube
Normal Pulled 5m58s kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 5m58s kubelet, minikube Created container
Normal Started 5m58s kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-ztcwr
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:49 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.11
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://fe8692ed80172e7acba09eaacc7a0671bebdc0deea8268462a3ccca1920c0f19
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:50 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m57s default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-ztcwr
to minikube
Normal Pulled 5m56s kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 5m56s kubelet, minikube Created container
Normal Started 5m56s kubelet, minikube Started container
$

We run now version 2 of the app (look at the Image field)

Step 3: Rollback an update


Let’s perform another update, and deploy image tagged as v10 :
$ kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-
bootcamp:v10
deployment.extensions/kubernetes-bootcamp image updated
$

Use get deployments to see the status of the deployment:


$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 3/4 2 3 13m
$

And something is wrong… We do not have the desired number of Pods available. List the Pods again:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-597cfc5b76-mlctm 0/1 ImagePullBackOff 0 2m15s
kubernetes-bootcamp-597cfc5b76-np42w 0/1 ImagePullBackOff 0 2m15s
kubernetes-bootcamp-5bf4d5689b-6v7bh 1/1 Running 0 9m55s
kubernetes-bootcamp-5bf4d5689b-8v24c 1/1 Running 0 9m57s
kubernetes-bootcamp-5bf4d5689b-gkh6t 1/1 Running 0 9m57s
$

A describe command on the Pods should give more insights:


$ kubectl describe pods
Name: kubernetes-bootcamp-597cfc5b76-mlctm
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 03:06:29 +0000
Labels: pod-template-hash=597cfc5b76
run=kubernetes-bootcamp
Annotations: <none>
Status: Pending
IP: 172.18.0.5
Controlled By: ReplicaSet/kubernetes-bootcamp-597cfc5b76
Containers:
kubernetes-bootcamp:
Container ID:
Image: gcr.io/google-samples/kubernetes-bootcamp:v10
Image ID:
Port: 8080/TCP
Host Port: 0/TCP
State: Waiting
Reason: ImagePullBackOff
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m52s default-scheduler Successfully assigned default/kubernetes-bootcamp-
597cfc5b76-mlctm to minikube
Normal Pulling 79s (x4 over 2m52s) kubelet, minikube pulling image "gcr.io/google-samples/kubernetes-
bootcamp:v10"
Warning Failed 78s (x4 over 2m51s) kubelet, minikube Failed to pull image "gcr.io/google-samples/kubernetes-
bootcamp:v10": rpc error: code = Unknown desc = Error response from daemon: manifest for gcr.io/google-
samples/kubernetes-bootcamp:v10 not found
Warning Failed 78s (x4 over 2m51s) kubelet, minikube Error: ErrImagePull
Normal BackOff 65s (x6 over 2m51s) kubelet, minikube Back-off pulling image "gcr.io/google-
samples/kubernetes-bootcamp:v10"
Warning Failed 52s (x7 over 2m51s) kubelet, minikube Error: ImagePullBackOff

Name: kubernetes-bootcamp-597cfc5b76-np42w
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 03:06:29 +0000
Labels: pod-template-hash=597cfc5b76
run=kubernetes-bootcamp
Annotations: <none>
Status: Pending
IP: 172.18.0.4
Controlled By: ReplicaSet/kubernetes-bootcamp-597cfc5b76
Containers:
kubernetes-bootcamp:
Container ID:
Image: gcr.io/google-samples/kubernetes-bootcamp:v10
Image ID:
Port: 8080/TCP
Host Port: 0/TCP
State: Waiting
Reason: ImagePullBackOff
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m52s default-scheduler Successfully assigned default/kubernetes-bootcamp-
597cfc5b76-np42w to minikube
Normal Pulling 78s (x4 over 2m52s) kubelet, minikube pulling image "gcr.io/google-samples/kubernetes-
bootcamp:v10"
Warning Failed 77s (x4 over 2m50s) kubelet, minikube Failed to pull image "gcr.io/google-samples/kubernetes-
bootcamp:v10": rpc error: code = Unknown desc = Error response from daemon: manifest for gcr.io/google-
samples/kubernetes-bootcamp:v10 not found
Warning Failed 77s (x4 over 2m50s) kubelet, minikube Error: ErrImagePull
Normal BackOff 66s (x6 over 2m50s) kubelet, minikube Back-off pulling image "gcr.io/google-
samples/kubernetes-bootcamp:v10"
Warning Failed 51s (x7 over 2m50s) kubelet, minikube Error: ImagePullBackOff

Name: kubernetes-bootcamp-5bf4d5689b-6v7bh
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:49 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.10
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://ce27779618b55277178059819cfeb84063eedfae6d4a95107e91c20882b4ed5a
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:50 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-6v7bh
to minikube
Normal Pulled 10m kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 10m kubelet, minikube Created container
Normal Started 10m kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-8v24c
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:47 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.9
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://61ae4e10f2f03a58203ed7d77669123488dd33dfbdf85d0cef864c0891dcf859
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-8v24c
to minikube
Normal Pulled 10m kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 10m kubelet, minikube Created container
Normal Started 10m kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-gkh6t
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:47 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.8
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://2e473aefd5502d4aaf29168c3c690e2cdfdd859d1ea0781c12c374b31c19ba0e
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-gkh6t to
minikube
Normal Pulled 10m kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 10m kubelet, minikube Created container
Normal Started 10m kubelet, minikube Started container
$

There is no image called v10 in the repository. Let’s roll back to our previously working version. We’ll use the rollout
undo command:
$ kubectl rollout undo deployments/kubernetes-bootcamp
deployment.extensions/kubernetes-bootcamp rolled back
$

The rollout command reverted the deployment to the previous known state (v2 of the image). Updates are versioned and
you can revert to any previously know state of a Deployment. List again the Pods
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-5bf4d5689b-6v7bh 1/1 Running 0 12m
kubernetes-bootcamp-5bf4d5689b-8v24c 1/1 Running 0 12m
kubernetes-bootcamp-5bf4d5689b-gkh6t 1/1 Running 0 12m
kubernetes-bootcamp-5bf4d5689b-wcr5h 1/1 Running 0 51s

Four Pods are running. Check again the image deployed on the them:
$ kubectl describe pods
Name: kubernetes-bootcamp-5bf4d5689b-6v7bh
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:49 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.10
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://ce27779618b55277178059819cfeb84063eedfae6d4a95107e91c20882b4ed5a
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:50 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 12m default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-6v7bh
to minikube
Normal Pulled 12m kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 12m kubelet, minikube Created container
Normal Started 12m kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-8v24c
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:47 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.9
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://61ae4e10f2f03a58203ed7d77669123488dd33dfbdf85d0cef864c0891dcf859
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 12m default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-8v24c
to minikube
Normal Pulled 12m kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 12m kubelet, minikube Created container
Normal Started 12m kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-gkh6t
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 02:58:47 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.8
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://2e473aefd5502d4aaf29168c3c690e2cdfdd859d1ea0781c12c374b31c19ba0e
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 02:58:48 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 12m default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-gkh6t to
minikube
Normal Pulled 12m kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 12m kubelet, minikube Created container
Normal Started 12m kubelet, minikube Started container

Name: kubernetes-bootcamp-5bf4d5689b-wcr5h
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: minikube/172.17.0.50
Start Time: Tue, 09 Apr 2019 03:10:31 +0000
Labels: pod-template-hash=5bf4d5689b
run=kubernetes-bootcamp
Annotations: <none>
Status: Running
IP: 172.18.0.6
Controlled By: ReplicaSet/kubernetes-bootcamp-5bf4d5689b
Containers:
kubernetes-bootcamp:
Container ID: docker://c41a1e63822c9d383ceceb69a96f247ca45e3fd8f3a1625ee667feb142d63e0c
Image: jocatalin/kubernetes-bootcamp:v2
Image ID: docker-pullable://jocatalin/kubernetes-
bootcamp@sha256:fb1a3ced00cecfc1f83f18ab5cd14199e30adc1b49aa4244f5d65ad3f5feb2a5
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 09 Apr 2019 03:10:32 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-vmwzp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-vmwzp:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-vmwzp
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 56s default-scheduler Successfully assigned default/kubernetes-bootcamp-5bf4d5689b-wcr5h to
minikube
Normal Pulled 55s kubelet, minikube Container image "jocatalin/kubernetes-bootcamp:v2" already present on
machine
Normal Created 55s kubelet, minikube Created container
Normal Started 55s kubelet, minikube Started container
$

We see that the deployment is using a stable version of the app (v2). The Rollback was successful.

https://kubernetes.io/docs/concepts/services-networking/service/
https://kubernetes.io/docs/concepts/

====================Srinath Challa youtube================================================


https://www.youtube.com/watch?v=jgmdY73RF6w&list=PLMPZQTftRCS8Pp4wiiUruly5ODScvA
wcQ

You might also like