Reader small image

You're reading from  Kubernetes for Developers

Product typeBook
Published inApr 2018
Reading LevelIntermediate
PublisherPackt
ISBN-139781788834759
Edition1st Edition
Languages
Right arrow
Author (1)
Joseph Heck
Joseph Heck
author image
Joseph Heck

Joseph Heck has broad development and management experience across start-ups and large companies. He has architected, developed, and deployed a wide variety of solutions, ranging from mobile and desktop applications to cloud-based distributed systems. He builds and directs teams and mentors individuals to improve the way they build, validate, deploy, and run software. He also works extensively with and in open source, collaborating across many projects, including Kubernetes.
Read more about Joseph Heck

Right arrow

Chapter 4. Declarative Infrastructure

Kubernetes is inherently a declarative system. In prior chapters, we have explored Kubernetes and some of its key concepts using commands such as kubectl run and kubectl expose. These commands are all imperative: do this thing now. Kubernetes does this by managing these resources as objects themselves. kubectl and the API server translate these requests into resource representations, and then store them, and it is the job of the various controllers to understand the current state and make it as requested.

We can take advantage of the declarative structures directly—all the Services, Pods, and more can be represented by either JSON or YAML files. In this chapter, we will move to define your applications as a declarative infrastructure. We will take the existing simple Kubernetes Pods and put them into declarations that you can manage alongside your code; stored in source control and deployed to run your software. We will also introduce ConfigMaps and Secrets...

Imperative versus declarative commands


Our examples thus far have focused on quick and imperative commands such as kubectl run to create a deployment that in turn runs our software. This is convenient for something quick, but does not easily expose the full flexibility of the API. To leverage all the options available via Kubernetes, it is often more effective to manage files that describe the deployment you want.

When using these files, you can use commands such as kubectl create, kubectl delete, and kubectl replace along with the -f option to specify the file to use. The imperative commands are easy and effective for simple setups, but you quickly need a sequence of commands that you repeat again and again to take full advantage of all the capabilities. You might be storing sets of these commands in a cheatsheet, but that can get cumbersome and isn't always clear.

Kubernetes offers a declarative mechanism as well, leveraging the kubectl apply command, which takes in files, reviews the current...

Declaring your first application


Go ahead and pick one of the examples and create a deployment declaration, and try creating one using the declaration.

I recommend making a directory called deploy, and putting your declaration file within that. This is using the flask example:

flask.yml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: flask
  labels:
    run: flask
spec:
  template:
    metadata:
      labels:
         app: flask
    spec:
      containers:
      - name: flask
        image: quay.io/kubernetes-for-developers/flask:0.1.1
        ports: 
        - containerPort: 5000

Remove the existing deployment before you try out your file:

kubectl delete deployment flask

It is a good practice to use the --validate option to have kubectl check the files, and you can use it with --dry-run to compare the file to anything existing in Kubernetes to let you know specifically what it will be doing.  YAML is easy to read, and unfortunately even easier to make formatting mistakes due to its...

Kubernetes resource – Annotations


Where labels and selectors are used for grouping and selecting sets of Kubernetes resources, Annotations provide a means of adding resource-specific metadata that can be accessed by either Kubernetes or in the containers it runs.

As you just saw, kubectl apply automatically applies an annotation to track the last applied configuration state of a resource when it is invoked. In the last chapter, you might have noticed the annotation that the deployment controllers used to track revision, deployment.kubernetes.io/revision, and we spoke of the kubernetes.io/change-cause annotation that was used by kubectl to display the change history of deployment rollouts.

Annotations can be simple values or complex blocks (as in the case of kubectl.kubernetes.io/last-applied-configuration). The examples so far are Kubernetes tools using annotations to share information, although annotations are also used to share information in a container for an application to use.

You might...

Kubernetes resource – ConfigMap


When you create containers as read-only instances of your code, you quickly want a means to provide small changes in the form of flags or configuration. Perhaps, more importantly, you do not want to include private details such as API keys, passwords, or authentication tokens in your container images.

Kubernetes supports two resources to help and link in exactly this kind of information. The first is a ConfigMap, which can be used individually or across Pods for your application deployment, providing a single place to update and propagate configuration for your application. Kubernetes also supports the concept of a Secret, a far more locked down type of configuration that is more tightly controlled and exposed only where you need it.

For example, one might use a ConfigMap to control basic configuration of the example Redis deployment, and a Secret to distribute sensitive authentication credentials for clients to connect.

Creating a ConfigMap

You can create a ConfigMap...

Kubernetes resource – Secrets


ConfigMaps are great for general configuration, but are easily visible—which may not be desired. For some configuration, such as passwords, authorization tokens, or API keys, you often want a more controlled mechanism to protect those values. That’s what the resource Secrets are designed to solve.

Secrets are generally created (and managed) individually, and internally Kubernetes stores this data using base64 encoding.

You can create a secret on the command line by first writing the values into one or more files, and then specifying those files in the create command. Kubernetes will take care of doing all the relevant base64 encoding and storing them away. For example, if you wanted to store a database username and password, you might do the following:

echo -n “admin” > username.txt
echo -n “sdgp63lkhsgd” > password.txt
kubectl create secret generic database-creds --from-file=username.txt --from-file=password.txt

Note that in naming the secret's name, you...

Example – Python/Flask deployment with ConfigMap


This example builds on our earlier Python/Flask example. This extension will add a ConfigMap that uses both environment variables and structured files, as well as code updates to consume and use those values.

To start, add a ConfigMap with both top-level values and a deeper configuration. The top values will be exposed as environment variables, and the multiline YAML will be exposed as a file inside the container:

# CONFIGURATION FOR THE FLASK APP
kind: ConfigMap
apiVersion: v1
metadata:
  name: flask-config
data:
  CONFIG_FILE: “/etc/flask-config/feature.flags“
  feature.flags: |
    [features]
    greeting=hello
    debug=true

This ConfigMap is mapped with updates to the Pod specification of the deployment with the envFrom key and as a volume to provide the file mapping:

    spec:
      containers:
      - name: flask
        image: quay.io/kubernetes-for-developers/flask:latest
        ports:
        - containerPort: 5000
        envFrom:
...

Summary


In this chapter, we looked at how to take advantage of the declarative nature of Kubernetes in detail and managing our application through specification files. We also looked at Annotations, ConfigMap, and Secrets and how those can be created and then used from within Pods. We closed the chapter with updating our Python and Node.js applications to use ConfigMaps to run the example code we set up previously, and looked briefly at how to leverage the built-in JSONPATH within kubectl to make that tool more immediately powerful at providing the specific information you want.

 

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Kubernetes for Developers
Published in: Apr 2018Publisher: PacktISBN-13: 9781788834759
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Joseph Heck

Joseph Heck has broad development and management experience across start-ups and large companies. He has architected, developed, and deployed a wide variety of solutions, ranging from mobile and desktop applications to cloud-based distributed systems. He builds and directs teams and mentors individuals to improve the way they build, validate, deploy, and run software. He also works extensively with and in open source, collaborating across many projects, including Kubernetes.
Read more about Joseph Heck