Book "Kubernetes for DevOps"

Book "Kubernetes for DevOps" Hello Habrites! 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-native application and create the infrastructure to support it, set up a development environment and a continuous deployment pipeline that will come in handy when working on the following applications.

• Get started with containers and Kubernetes from the ground up: no special experience is required to learn the topic. • Run your own clusters or choose a managed Kubernetes service from Amazon, Google, and more. • Use Kubernetes to manage container lifecycle and resource consumption. • Optimize clusters for cost, performance, resiliency, capacity, and scalability. • Learn the best tools for developing, testing, and deploying your applications. • Use current industry practices for security and control. • Implement DevOps principles throughout your organization to make development teams more agile, faster, and more efficient.

Who is the book for?

The book is most relevant for administrative 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. Don't worry, you don't need to know how to work with Kubernetes and containers - we will teach you everything.

Experienced Kubernetes users will also find a lot of value, with in-depth coverage of topics such as RBAC, continuous deployment, sensitive data management, and observability. We hope that on the pages of the book there will definitely be something interesting for you, regardless of your skills and experience.

What questions does the book answer?

During the planning and writing of this book, we discussed cloud computing and Kubernetes with hundreds of people, from industry leaders and experts to total newbies. Below are some of the questions they would like to see answered in this edition.

  • “I'm interested in why you should spend time on this technology. What problems will it help me and my team solve?”
  • “Kubernetes seems interesting, but has a pretty high barrier to entry. Preparing a simple example is not difficult, but further administration and debugging is intimidating. We'd love some solid advice on how people manage Kubernetes clusters in the real world and what problems we're likely to run into."
  • “Subjective advice would be helpful. The Kubernetes ecosystem offers budding teams too many options to choose from. When the same thing can be done in several ways, how do you know which one is better? How to make a choice?

And perhaps the most important of all questions:

  • “How can I use Kubernetes without disrupting my company?”

Excerpt. Configuration and Secret Objects

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

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

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

In this chapter, we'll explore these objects in detail and look at some practical approaches to managing configuration and confidential data using a demo application as an example.

Update pods on configuration change

Imagine that you have a deployment in your cluster and you want to change some values ​​in its ConfigMap. If you're using the Helm chart (see "Helm: Package Manager for Kubernetes" on page 102), you can automatically detect a configuration change and reload your pods automatically with one neat trick. Add the following annotation to your deployment specification:

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

The deployment template now contains a checksum of the configuration parameters: if the parameters are changed, the sum will be updated. If you run the helm upgrade command, Helm detects that the deployment specification has changed and restarts all pods.

Sensitive data in 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, such as passwords or API keys. It can also be stored in ConfigMap, but this solution is not ideal.

Instead, Kubernetes provides a special type of object for storing sensitive data: Secret. Next, let's look at an example of how this object can be used in our demo application.

First, 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. Like a ConfigMap, you can store 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 the ConfigMap, the Secret object can be made available in the container as environment variables or as a file on its disk. In the following example, we will assign the value from Secret to the environment variable:

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 the manifests:

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

As before, forward the local port to the 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 opening an address localhost: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 located in the hello-secret-file folder of the demo repository.

To include the Secret as a file, use the following expansion:

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 "Generating configuration files from ConfigMap objects" subsection on p. 240, we create a volume (in this case demo-secret-volume) and mount it to the container in the volumeMounts specification section. The mountPath field is set to /secrets, so Kubernetes will create one file in this folder for each key/value pair defined in the Secret object.

In our example, we only defined one key/value pair named magicWord, so the manifest will create one read-only /secrets/magicWord file in the container with sensitive data.

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 list the contents of a ConfigMap. Can the same be done with Secret?

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

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

Data
====
magicWord: 5   bytes

Note that the data itself is not displayed. Secret objects in Kubernetes are of type Opaque, which means that their contents are not shown in kubectl describe output, log entries, and the terminal, making it impossible to accidentally reveal confidential information.

To view the encoded YAML version of the sensitive data, 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 this eHl6enk= that is completely different from our original value? It's actually a base64 encoded Secret object. Base64 is a scheme for encoding arbitrary binary data as a character string.

Because sensitive information can be binary and non-printable (as is the case with the TLS encryption key, for example), 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 by running the base64 --decode command in the terminal:

echo "eHl6enk=" | base64 --decode
xyzzy

Thus, while Kubernetes protects you from inadvertent output of sensitive data in the terminal or log files, if you have permission to read Secret objects in a certain namespace, this data can be obtained in base64 format and subsequently decoded.

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

echo xyzzy | base64
eHl6enkK

Accessing Secret Objects

Who can read and edit Secret objects? This is determined by RBAC, an access control mechanism (we will discuss it in detail in the "Introduction to role-based access control" subsection on page 258). If you're running a cluster that doesn't have or doesn't have RBAC enabled, all your Secrets are available to any users and containers (we'll explain later that you shouldn't have any production cluster without RBAC).

Passive data encryption

What about those who have access to the etcd database where Kubernetes stores all of its information? Can they read sensitive data without having read access to Secret objects via the API?

Since version 1.7, Kubernetes supports passive data encryption. This means that sensitive information inside etcd is stored encrypted on disk and cannot be read even by someone with direct access to the database. To decrypt it, you need a key that only the Kubernetes API server has. A properly configured cluster should have passive encryption enabled.

You can check if passive encryption works in your cluster like this:

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

If you don't see the experimental-encryption-provider-config flag, passive encryption is not enabled. When using Google Kubernetes Engine or other Kubernetes management services, your data is encrypted using a different mechanism, so the flag will not be present. Check with your Kubernetes vendor to see if etcd content is encrypted.

Storage of sensitive data

There are some Kubernetes resources that should never be removed from the cluster, such as critical Secret objects. You can keep a resource from being deleted with an annotation provided by the Helm manager:

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

Strategies for Manipulating Secret Objects

In the example in 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 sensitive information in files that are in source control. So how do you securely administer and store this information before applying it to a Kubernetes cluster?

You can choose any tools or strategies for dealing with sensitive data in your applications, but you will 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?
  • What should happen to your applications when you change or edit sensitive data?

About the authors

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

Justin Domingus is a systems administration engineer working in a DevOps environment with Kubernetes and cloud technologies. He likes to spend time outdoors, drinking coffee, catching crabs and sitting at the computer. Lives in Seattle, Washington with a wonderful cat and even more wonderful wife and best friend Adrienne.

» For more information about the book, please visit publisher's website
» Table of contents
» excerpt

For Habitants, a 25% discount on a coupon - Kubernetes

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

Source: habr.com

Add a comment