Professional Documents
Culture Documents
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
9. Install Kubernetes.
yum install -y kubelet kubeadm kubectl
10. Reboot.
14. Reload systemd for the changes to take effect, and then restart Kubernetes.
systemctl daemon-reload
systemctl restart kubelet
$ 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.
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.
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
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.
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
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.
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.
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/
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.
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.
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).
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.
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>
# Not in a namespace
$kubectl api-resources --namespaced=false
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.
"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
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
Examples:
Create the objects defined in a configuration file:
$kubectl create -f nginx.yaml
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:
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
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.
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
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
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========================================================
$ 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
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.
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.
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
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).
$
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
1 deployment running a single instance of your app. The instance is running inside a Docker container on your node
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:
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
$
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
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:
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:/#
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:
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
$
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
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
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
$
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
$
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
$
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
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
scenario is to update a deployed application with kubectl set image and to rollback with the rollout undo command:
To view the current image version of the app, run a describe command against the Pods (look at the Image field):
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
$
We hit a different Pod with every request and we see that all Pods are running the latest version (v2).
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
$
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
$
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/