kubectl: Manually updating Kubernetes workloads and deployments
Understanding Kubernetes Workloads
Before you can manually update your applications running in Kubernetes, you need to understand the different types of Kubernetes objects and their collective workloads that require deploying and updating.
At a high level, updating apps in your cluster is done with deployment templates that can be applied with the Kubernetes API or alternatively can be controlled by Kubernetes command line tool, ‘kubectl’. Here are the Kubernetes objects, each of these has its own YAML definition or manifest.
- Stateless applications – refers to an application that does not maintain its history or state in a persistent database, but rather all user state is kept with the client. Examples of these types of applications include: NGINX, and a TomCat application server.
- Stateful applications – need to store their state information in a persistent storage so that other applications can access it. Examples are MongoDB and message queues like RabbitMQ.
- Batch jobs – these are parallel tasks that are finite and that need to run to completion. Examples include video rendering and email processing.
- Daemons – perform background tasks on their assigned node without the need for human interaction.
What are Deployments?
Deployments give you fine grain control over how Pods are updated and rolled back. A kubernetes update deployment runs multiple replicas of your application and replaces any instances that have failed or are unresponsive. In this way, deployments ensure that one or more instances of your application are always available to serve requests to your users.
Deployments use a Pod or deployment template, written in YAML, that contains the specification for its Pods. The Pod specification defines its desired state, and it identifies what applications run inside its containers, which volumes, if any, the Pods it should mount, its labels, and any annotations that have been defined for it.
When a Deployment Pod template is changed, new ReplicaSets are created that will create new Pods one at a time in real-time with zero application downtime. This is what’s referred to as a rolling update.
Example Deployment Template
Deployment templates are defined in a YAML file. The following snippet is taken from the Kubernetes documentation and it shows an example manifest for deploying NGINX:
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
The template field contains the following instructions:
- The Pods are labeled app: nginx
- Create one container and name it nginx
- Run the nginx image at version 1.7.9
- Open port 80 so that the container can send and accept traffic
Managing Pod Configurations
Depending on how you are working and the types of applications you are deploying, you will want to ensure that the container image and its deployment configuration are decoupled. This not only ensures that your app is more portable between environments, but in some cases it is necessary to keep your data secure.
Type of Data
How it's mounted or referred to
Environment variable OR local file
Environment variable OR local file
Choose Your Object Management Method
Once the deployment template is defined and you’re ready to do some rolling updates, you will need to choose how you’re going to do those updates. Kubernetes updates to your application/deployment can be managed using one of these three methods:
These are raw `kubectl` commands.
These are used directly on Live objects in the cluster. It saves no history and isn’t very useful on a daily basis with a large team of developers. Generally used for ‘one off’ tasks.
Imperative object definition
‘kubectl` commands applied to at least one file.
The file generally is generally in YAML format. Allows some rollback and can be stored in source control, but users still need to understand the schema in order to update it.
Declarative object configuration
Applies the ‘kubectl’ to directories of files.
Allows you to work on different object types at the same time.
Steps for a Manual Update
These are the steps that you’ll need to do, if you want to manually update an app in Kubernetes:
- Unit test code in a CI system.
- Build an updated Docker image (with a new tag).
- Upload the image to a repository.
- Update your deployment definition YAMLs for your app: deployment, service and Kubernetes secret and ingress.
- Apply or ‘set image’ to the changes in your Kubernetes cluster.
- Scale your deployment appropriately (if necessary).
- If all went well, and you don’t have to rollback, clean up and remove the deployment.
- If you’re using the declarative method you can check your deployment definitions into Git so that you have a history of it.