Book Kubernetes for DevOps

imageHello, habrozhiteli! Kubernetes is one of the key elements of the modern cloud ecosystem. This technology provides the reliability, scalability, and resiliency of container virtualization. John Arundel and Justin Domingus talk about the Kubernetes ecosystem and introduce proven solutions to everyday problems. Step by step, you will build your own cloud-based application and create the infrastructure to support it, configure the development environment and the continuous deployment pipeline, which will be useful to you when working on the following applications.

• Get started with containers and Kubernetes from scratch: no special experience is required to learn the topic. • Start your own clusters or choose a managed Kubernetes service from Amazon, Google, etc. • Use Kubernetes to manage container lifecycle and resource consumption. • Optimize clusters for cost, performance, resilience, power, and scalability. • Learn the best tools for developing, testing, and deploying your applications. • Take advantage of current industry practices for safety and control. • Implement DevOps principles in your company so that development teams become more flexible, fast and efficient.

Who is the book for?


The book is most relevant for employees of the administration departments responsible for servers, applications and services, as well as for developers involved in either building new cloud services or migrating existing applications to Kubernetes and the cloud. Do not worry, knowing how to work with Kubernetes and containers is not required - we will teach you everything.

Experienced Kubernetes users will also find a lot to discover: topics such as RBAC, continuous deployment, sensitive data management, and observability are covered in depth. We hope that the pages of the book will surely have something interesting for you, regardless of your skills and experience.

What questions does the book answer


During the planning and writing of the book, we discussed cloud technologies and Kubernetes with hundreds of people, talked with leaders and experts in the industry, as well as with absolute beginners. The following are individual questions that they would like to see answers to in this publication.

  • “I'm interested in why time should be spent on this technology. What problems will she help me and my team solve? ”
  • “Kubernetes seems interesting, but has a pretty high entry threshold. Preparing a simple example is not difficult, but further administration and debugging is scary. We would like to get reliable advice on how people manage Kubernetes clusters in real life and what problems we are likely to encounter. ”
  • “Subjective advice would be helpful. The Kubernetes ecosystem offers novice teams too many options to choose from. When the same thing can be done in several ways, how to understand which one is better? How to make a choice? ”

And, probably, the most important of all questions:

  • “How to use Kubernetes without disrupting my company?”

Excerpt. Configuration and Secret objects


The ability to separate the logic of the Kubernetes application from its configuration (that is, from any values ​​or settings that may change over time) is very useful. Configuration values ​​typically include settings for a specific environment, DNS addresses of third-party services, and credentials for authentication.

Of course, all this can be placed directly in the code, but this approach is not flexible enough. For example, to change the configuration value, then you will have to reassemble and deploy your code. A much better solution would be to separate the configuration from the code and read it from the file or environment variables.

Kubernetes provides several different ways to manage your configuration. First, you can pass values ​​to the application through the environment variables specified in the specification of the pod shell (see the section "Environment Variables" on page 192). Secondly, configuration data can be stored directly in Kubernetes using the ConfigMap and Secret objects.

In this chapter, we will examine these objects in detail and consider some practical approaches to managing configuration and sensitive data using an example demo application.

Updating pod shells when changing configurations


Imagine that your cluster has a deployment and you want to change some values ​​in its ConfigMap. If you use the Helm chart (see the “Helm: Package Manager for Kubernetes” section on page 102), you can detect a configuration change and reboot your pod shells automatically with one elegant trick. Add the following annotation to your deployment specification:

checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") .
       | sha256sum }}

Now the deployment template contains the checksum of the configuration parameters: when the parameters are changed, the sum is updated. If you run the helm upgrade command, Helm will find that the deployment specification has changed and restart all pod shells.

Confidential Data at Kubernetes


We already know that the ConfigMap object provides a flexible mechanism for storing and accessing configuration data in a cluster. However, most applications have information that is secret and confidential: for example, passwords or API keys. It can also be stored in ConfigMap, but such a solution is not ideal.

Instead, Kubernetes offers a special type of object designed to store sensitive data: Secret. Next, we consider an example of how this object can be applied in our demo application.

To get started, take a look at the Kubernetes manifest for the Secret object (see hello-secret-env / k8s / secret.yaml):

apiVersion: v1
kind: Secret
metadata:
    name: demo-secret
stringData:
    magicWord: xyzzy

In this example, the magicWord private key is xyzzy (en.wikipedia.org/wiki/Xyzzy_(computing)). The word xyzzy is generally very useful in the world of computers. Similar to ConfigMap, you can place many keys and values ​​in a Secret object. Here, for simplicity, we use only one key-value pair.

Using Secret objects as environment variables


Like ConfigMap, the Secret object can be made available in the container as environment variables or a file on its disk. In the following example, we will assign the environment variable the value from Secret:

spec:
   containers:
       - name: demo
          image: cloudnatived/demo:hello-secret-env
          ports:
             - containerPort: 8888
          env:
             - name: GREETING
               valueFrom:
               secretKeyRef:
                  name: demo-secret
                  key: magicWord


Run the following command in the demo repository to apply manifests:

kubectl apply -f hello-secret-env/k8s/
deployment.extensions "demo" configured
secret "demo-secret" created

As before, redirect the local port to deployment to see the result in your browser:

kubectl port-forward deploy/demo 9999:8888
Forwarding from 127.0.0.1:9999 -> 8888
Forwarding from [::1]:9999 -> 8888

When you open the localhost address : 9999 / you should see the following:

The magic word is "xyzzy"

Writing Secret objects to files


In this example, we will attach the Secret object to the container as a file. The code is in the hello-secret-file folder of the demo repository.

To connect Secret as a file, we will use the following deployment:

spec:
   containers:
       - name: demo
          image: cloudnatived/demo:hello-secret-file
          ports:
              - containerPort: 8888
          volumeMounts:
              - name: demo-secret-volume
                mountPath: "/secrets/"
                readOnly: true
   volumes:
      - name: demo-secret-volume
        secret:
           secretName: demo-secret

As in the subsection “Creating configuration files from ConfigMap objects” on p. 240, we create a volume (in this case, demo-secret-volume) and connect it to the container in the volumeMounts specification section. MountPath is / secrets, so Kubernetes will create one file for each key-value pair defined in the Secret object in this folder.

In our example, we defined only one key-value pair called magicWord, so the manifest will create a single / secrets / magicWord file with confidential data in the container that is read-only.

If you apply this manifest in the same way as in the previous example, you should get the same result:

The magic word is "xyzzy"

Reading Secret Objects


In the previous section, we used the kubectl describe command to display the contents of ConfigMap. Can you do the same with Secret?

kubectl describe secret/demo-secret
Name:          demo-secret

Namespace:      default
Labels:             <none>
Annotations:
Type:               Opaque

Data
====
magicWord: 5   bytes

Please note that the data itself is not displayed. Secret objects in Kubernetes are of type Opaque: this means that their contents are not shown in the output of kubectl describe, journal entries and the terminal, making it impossible to accidentally reveal sensitive information.

To view the encoded version of sensitive data in YAML format, use the kubectl get command:

kubectl get secret/demo-secret -o yaml
apiVersion: v1
data:
   magicWord: eHl6enk=
kind: Secret
metadata:
...
type: Opaque

base64


What is eHl6enk =, which is completely different from our original value? This is actually a Secret object, represented in base64 encoding. Base64 is an encoding scheme for arbitrary binary data as a string of characters.

Since confidential information may be binary and inaccessible for output (as, for example, in the case of the TLS encryption key), Secret objects are always stored in base64 format.

The text beHl6enk = is the base64 encoded version of our secret word xyzzy. You can verify this if you execute the base64 --decode command in the terminal:

echo "eHl6enk=" | base64 --decode
xyzzy

Thus, despite the fact that Kubernetes protects you from accidentally displaying confidential data in the terminal or log files, if you have permissions to read Secret objects in a specific namespace, this data can be received in base64 format and subsequently decoded.

If you need to encode some text in base64 (for example, to put it in Secret), use the base64 command with no arguments:

echo xyzzy | base64
eHl6enkK

Access to Secret objects


Who can read and edit Secret objects? This is determined by RBAC, the access control mechanism (we will discuss it in detail in the section “Introduction to Role Based Access Control” on page 258). If you use a cluster in which the RBAC system is absent or not enabled, all your Secret objects are accessible to any users and containers (we will explain later that you should not have any industrial cluster without RBAC).

Passive data encryption


What about those who have access to the etcd database, in which Kubernetes stores all its information? Can they read sensitive data without the right to read Secret objects through the API?

Starting with version 1.7, Kubernetes supports passive data encryption. This means that the confidential information inside etcd is stored on the disk in encrypted form and cannot be read even by those who have direct access to the database. To decrypt it, you need a key that only the Kubernetes API server has. In a properly configured cluster, passive encryption must be enabled.

Check if passive encryption works in your cluster by doing this:

kubectl describe pod -n kube-system -l component=kube-apiserver |grep encryption
        --experimental-encryption-provider-config=...

If you do not see the experimental-encryption-provider-config flag, passive encryption is not enabled. When using the Google Kubernetes Engine or other Kubernetes management services, your data is encrypted using a different mechanism, so the flag will be absent. Check with your Kubernetes provider to see if the contents of etcd are encrypted.

Confidential Data Storage


There are Kubernetes resources that should never be removed from a cluster: for example, especially important Secret objects. You can protect the resource from being deleted using the annotation provided by Helm Manager:

kind: Secret
metadata:
    annotations:
        "helm.sh/resource-policy": keep

Secret Object Management Strategies


In the example from the previous section, sensitive data was protected from unauthorized access immediately after being stored in the cluster. But in the manifest files, they were stored in plain text.

You should never place confidential information in files that are in the version control system. How to safely administer and store this information before applying it to a Kubernetes cluster?

You can choose any tools or strategies for working with sensitive data in your applications, but you still need to answer at least the following questions.

  • Where to store sensitive data so that it is highly accessible?
  • How to make sensitive data available to your active applications?
  • , ?


John Arundel is a consultant with 30 years of experience in the computer industry. He has written several books and works with many companies from different countries, advising them on cloud-based infrastructure and Kubernetes. In his free time he enjoys surfing, shoots a good pistol and plays the piano amateurly. Lives in a fabulous cottage in Cornwall, England.

Justin Domingus is a system administration engineer working in a DevOps environment with Kubernetes and cloud technologies. He likes to spend time outdoors, drink coffee, catch crabs and sit at the computer. Lives in Seattle, Washington, along with a wonderful cat and an even more wonderful wife and part-time best friend Adrienne.

»More information about the book can be found on the publisher’s website
» Contents
» Excerpt

For Khabrozhiteley 25% coupon discount - Kubernetes

Upon payment of the paper version of the book, an electronic book is sent by e-mail.

All Articles