How to externally check Kubernetes readiness on deployment? - deployment

Our goal is to make sure the deployment was successful and the service is available
We already encountered a situation where the Ingress role was not correctly configured and the API's were down
We thought about deploying to a staging namespace, do a readiness call from outside the cluster and if everything checks out, move the deployment to its production namespace if not, delete the staging and declare the deployment as failed.
Is there a better way to handle this scenario?

Using kubernetes namespaces for staging and production is a nice idea.
Another way is to:
Create a staging kubernetes cluster and install the deployment, service and ingress in it.
Test readiness of deployment, service and ingress in the staging cluster from outside the staging cluster.
Move deployment to production cluster if everything is working fine as expected.
Use kubectl's config and context to switch between staging cluster and production cluster:
apiVersion: v1
kind: Config
preferences: {}
clusters:
- cluster:
name: staging
- cluster:
name: production
...

Related

Miinikube. Secrets not included in (only) one pod

I am testing a deployment on minikube.
It requires two pods, one is a webapp deloyment and one a chronjob
For ChronJob:
I start minikube and use
minikube addons configure registry-creds
minikube addons enable registry-creds
I use helm to deploy the the chronjob, the image pulls, the pod starts and I see the awssecr-cred in the pod
Everything works!
For the web app:
Rinse and repeat. Both are in default namespace, both deployed by helm to the same minikube deployment.
However, all secrets are missing from the webapp pod and, not surprisingly, cannot pull the image.
Can someone give me a pointer as to why the secrets are missing from this pod?

Kubernetes test environment

I have a hosted VPS and I would like to use this machine as a single node Kubernetes test environment. Is it possible to create a single-node Kubernetes cluster on the VPS, deploy pods to it using, for example, GitLab and test the application from outside the machine? I would like to locally develop, push to git and then deploy on this testing/staging environment.
Thank you
Answering the part of whole question:
I have a hosted VPS and I would like to use this machine as a single node kubernetes test environment.
A good starting point could be to cite the parts of my own answer from Serverfault:
There are a lot of options to choose from. Each solution will have it's advantages and disadvantages. It will also depend on the operating system your VM is deployed with.
Some of the options are the following:
MicroK8S - as pointed by user #Sekru
Minikube
Kind
Kubeadm
Kubespray
Kelsey Hightower: Kubernetes the hard way
Each of the solutions linked above have a link to it's respective homepage. You can find there installation steps/tips. Each solution is different and I encourage you to check if selected option suits your needs.
You'll need to review the networking part of each of above solutions as some of them will have easier/more difficult process to expose your workload outside of the environment (make it accessible from the Internet).
It all boils down to what are your requirements/expectations and what are the requirements for each of the solutions.
MicroK8S setup:
I do agree with an answer provided by community member #Sekru but I also think it could be beneficiary to add an example for such setup. Assuming that you have a microk8s compatible OS:
sudo snap install microk8s --classic
sudo microk8s enable ingress
sudo microk8s kubectl create deployment nginx --image=nginx
sudo microk8s kubectl expose deployment nginx --port=80 --type=NodePort
sudo microk8s kubectl apply -f ingress.yaml where ingress.yaml is a file with following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
ingressClassName: public # <-- IMPORTANT
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
After above steps you should be able to contact your Deployment from the place outside of your host by:
curl http://IP-ADDRESS
Side notes!
A setup like that will allow expose your workload on a NodePort (allocated port on each node from 30000 to 32767).
From the security perspective I would consider using your VPS provider firewalls to limit the traffic coming to your instance to allow only subnets that you are connecting from.
From the perspective of Gitlab integration with Kubernetes, I'd reckon you could find useful information by following it's page:
About.gitlab.com
Additional resources about Kubernetes:
Kubernetes.io: Docs: Home
Yes, use microk8s. For access from outside, use ingress addon

Does kubernetes Deployment automatically create the service like openshift DeploymentConfig does?

I created a deployment using kubernetes Deployment in openshift cluster. i expected it to create the service for all the container ports like openshift DeploymentConfig does.
but i did not find any service created by the kubernetes Deployment.
does kubernetes Deployment not create the service automatically like openshift DeploymentConfig does ?
My openshift version is 3.11
Both Deployment and DeploymentConfig does not create the Service component in OpenShift. These component are used for creation of Replication Control of the Pod.
Service has to be configured separately with the selector parameter to point to the specific Pods.
selector:
name: as in the deployment or in deploymentConfig.
This link would help you on the same.
https://docs.openshift.com/container-platform/3.3/dev_guide/deployments/how_deployments_work.html#creating-a-deployment-configuration
Deployment and service are different kubernetes objects. Deployment doesnt automatically create service object. you need to define service definition in a YAML targeting the ports from the pod definition inside deployment manifests. You need to deploy both deployment and service objects. you can deploy then separately or bundle them together in a single YAML and deploy.
Further details follow the link --> https://kubernetes.io/docs/concepts/services-networking/service/

How do I un-expose (undo expose) service?

In Kubernetes, it is possible to make a service running in cluster externally accessible by running kubectl expose deployment. Why deployment as opposed to service is beyond my simpleton's comprehension. That aside, I would like to also be able to undo this operation afterwards. Think of a scenario, where I need to get access to the service that normally is only accessible inside the cluster for debugging purposes and then to restore original situation.
Is there any way of doing this short of deleting the deployment and creating it afresh?
PS. Actually deleting service and deployment doesn't help. Re-creating service and deployment with the same name will result in service being exposed.
Assuming you have a deployment called hello-world, and do a kubectl expose as follows:
kubectl expose deployment hello-world --type=ClusterIP --name=my-service
this will create a service called my-service, which makes your deployment accessible for debugging, as you described.
To display information about the Service:
kubectl get services my-service
To delete this service when you are done debugging:
kubectl delete service my-service
Now your deployment is un-exposed.

What is the difference between a pod and a deployment?

I have been creating pods with type:deployment but I see that some documentation uses type:pod, more specifically the documentation for multi-container pods:
apiVersion: v1
kind: Pod
metadata:
name: ""
labels:
name: ""
namespace: ""
annotations: []
generateName: ""
spec:
? "// See 'The spec schema' for details."
: ~
But to create pods I can just use a deployment type:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ""
spec:
replicas: 3
template:
metadata:
labels:
app: ""
spec:
containers:
etc
I noticed the pod documentation says:
The create command can be used to create a pod directly, or it can
create a pod or pods through a Deployment. It is highly recommended
that you use a Deployment to create your pods. It watches for failed
pods and will start up new pods as required to maintain the specified
number. If you don’t want a Deployment to monitor your pod (e.g. your
pod is writing non-persistent data which won’t survive a restart, or
your pod is intended to be very short-lived), you can create a pod
directly with the create command.
Note: We recommend using a Deployment to create pods. You should use
the instructions below only if you don’t want to create a Deployment.
But this raises the question of what kind:pod is good for? Can you somehow reference pods in a deployment? I didn't see a way. It looks like what you get with pods is some extra metadata but none of the deployment options such as replica or a restart policy. What good is a pod that doesn't persist data, survives a restart? I think I'd be able to create a multi-container pod with a deployment as well.
Radek's answer is very good, but I would like to pitch in from my experience, you will almost never use an object with the kind pod, because that doesn't make any sense in practice.
Because you need a deployment object - or other Kubernetes API objects like a replication controller or replicaset - that needs to keep the replicas (pods) alive (that's kind of the point of using kubernetes).
What you will use in practice for a typical application are:
Deployment object (where you will specify your apps container/containers) that will host your app's container with some other specifications.
Service object (that is like a grouping object and gives it a so-called virtual IP (cluster IP) for the pods that have a certain label - and those pods are basically the app containers that you deployed with the former deployment object).
You need to have the service object because the pods from the deployment object can be killed, scaled up and down, and you can't rely on their IP addresses because they will not be persistent.
So you need an object like a service, that gives those pods a stable IP.
Just wanted to give you some context around pods, so you know how things work together.
Hope that clears a few things for you, not long ago I was in your shoes :)
Both Pod and Deployment are full-fledged objects in the Kubernetes API. Deployment manages creating Pods by means of ReplicaSets. What it boils down to is that Deployment will create Pods with spec taken from the template. It is rather unlikely that you will ever need to create Pods directly for a production use-case.
Kubernetes has three Object Types you should know about:
Pods - runs one or more closely related containers
Services - sets up networking in a Kubernetes cluster
Deployment - Maintains a set of identical pods, ensuring that they have the correct config and that the right number of them exist.
Pods:
Runs a single set of containers
Good for one-off dev purposes
Rarely used directly in production
Deployment:
Runs a set of identical pods
Monitors the state of each pod, updating as necessary
Good for dev
Good for production
And I would agree with other answers, forget about Pods and just use Deployment. Why? Look at the second bullet point, it monitors the state of each pod, updating as necessary.
So, instead of struggling with error messages such as this one:
Forbidden: pod updates may not change fields other than spec.containers[*].image
So just refactor or completely recreate your Pod into a Deployment that creates a pod to do what you need done. With Deployment you can change any piece of configuration you want to and you need not worry about seeing that error message.
Pod is container instance.
That is the output of replicas: 3
Think of one deployment can have many running instances(replica).
//deployment.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: tomcat-deployment222
spec:
selector:
matchLabels:
app: tomcat
replicas: 3
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:9.0
ports:
- containerPort: 8080
I want to add some informations from Kubernetes In Action book, so you can see all picture and connect relation between Kubernetes resources like Pod, Deployment and ReplicationController(ReplicaSet)
Pods
are the basic deployable unit in Kubernetes. But in real-world use cases, you want your deployments to stay up and running automatically and remain healthy without any manual intervention. For this the recommended approach is to use a Deployment, which under the hood create a ReplicaSet.
A ReplicaSet, as the name implies, is a set of replicas (Pods) maintained with their Revision history.
(ReplicaSet extends an older object called ReplicationController -- which is exactly the same but without the Revision history.)
A ReplicaSet constantly monitors the list of running pods and makes sure the running number of pods matching a certain specification always matches the desired number.
Removing a pod from the scope of the ReplicationController comes in handy
when you want to perform actions on a specific pod. For example, you might
have a bug that causes your pod to start behaving badly after a specific amount
of time or a specific event.
A Deployment
is a higher-level resource meant for deploying applications and updating them declaratively.
When you create a Deployment, a ReplicaSet resource is created underneath (eventually more of them). ReplicaSets replicate and manage pods, as well. When using a Deployment, the actual pods are created and managed by the Deployment’s ReplicaSets, not by the Deployment directly
Let’s think about what has happened. By changing the pod template in your Deployment resource, you’ve updated your app to a newer version—by changing a single field!
Finally, Roll back a Deployment either to the previous revision or to any earlier revision so easy with Deployment resource.
These images are from Kubernetes In Action book, too.
Pod is a collection of containers and basic object of Kuberntes. All containers of pod lie in same node.
Not suitable for production
No rolling updates
Deployment is a kind of controller in Kubernetes.
Controllers use a Pod Template that you provide to create the Pods for which it is responsible.
Deployment creates a ReplicaSet which in turn make sure that,
CurrentReplicas is always same as desiredReplicas .
Advantages :
You can rollout and rollback your changes using deployment
Monitors the state of each pod
Best suitable for production
Supports rolling updates
In Kubernetes we can deploy our workloads using different type of API objects like Pods, Deployment, ReplicaSet, ReplicationController and StatefulSets.
Out of those Pods are the smallest deployable unit in Kubernetes. Any workload/application that runs in Kubernetes, has to run inside a container part of a Pod. A Pod could run multiple containers (meaning multiple applications) within it. A Pod is a wrapper on top of one/many running containers. Using a Pod, kubernetes could control, monitor, operate the containers.
Now using stand alone Pods we can't do lot of things. We can't change configurations, volumes inside Pods. We can't restart the Pod if one is down.
So there is another API Object called Deployment comes into picture which maintains the desired state (how many instances, how much compute resource application uses) of the application. The Deployment maintaines multiple instances of same application by running multiple Pods. Deployments unlike Pods are mutable. Deployments uses another API Object called ReplicaSet to maintain the desired state. Deployments through ReplicaSet spawns another Pod if one is down.
So Pod runs applications in containers. Deployments run Pods and maintains desired state of the application.
Try to avoid Pods and implement Deployments instead for managing containers as objects of kind Pod will not be rescheduled (or self healed) in the event of a node failure or pod termination.
A Deployment is generally preferable because it defines a ReplicaSet to ensure that the desired number of Pods is always available and specifies a strategy to replace Pods, such as RollingUpdate.
May be this example will be helpful for beginners !!
1) Listing PODs
controlplane $ kubectl -n my-namespace get pods
NAME READY STATUS RESTARTS AGE
mysql 1/1 Running 0 92s
webapp-mysql-75dfdf859f-9c54j 1/1 Running 0 92s
2) Deleting web-app pode - which is created using deployment
controlplane $ kubectl -n my-namespace delete pod webapp-mysql-75dfdf859f-9c54j
pod "webapp-mysql-75dfdf859f-9c54j" deleted
3) Listing PODs ( You can see, it is recreated automatically)
controlplane $ kubectl -n my-namespace get pods
NAME READY STATUS RESTARTS AGE
mysql 1/1 Running 0 2m42s
webapp-mysql-75dfdf859f-mqrcx 1/1 Running 0 45s
4) Deleting mysql POD whcih is created directly ( with out deployment)
controlplane $ kubectl -n my-namespace delete pod mysql
pod "mysql" deleted
5) Listing PODs ( You can see mysql POD is lost for ever )
controlplane $ kubectl -n my-namespace get pods
NAME READY STATUS RESTARTS AGE
webapp-mysql-75dfdf859f-mqrcx 1/1 Running 0 76s
In kubernetes Pods are the smallest deployable units. Every time when we create a kubernetes object like Deployments, replica-sets, statefulsets, daemonsets it creates pod.
As mentioned above deployments create pods based on desired state mentioned in your deployment object. So for example you want 5 replicas of a application, you mentioned replicas: 5 in your deployment manifest. Now deployment controller is responsible to create 5 identical replicas (no less, no more) of given application with all metadata like RBAC policy, networks policy, labels, annotations, health check, resource quotas, taint/tolerations and others and associate with each pods it creates.
There are some cases when you wants to create pod, for example if you are running a test sidecar where you don't need to run application forever, you don't need multiple replicas, and you run application when you wants to execute in that case pod is suitable. For example helm test, which is a pod definition that specifies a container with a given command to run.
I am also a beginner in k8s so correct me if I am wrong.
We know that a pod is created when we create a deployment. What I observed is that if you see the YAML file of the deployment, you can see its kind:deployment. But if you see the YAML file of the pod, you see its kind:pod.