Kubernetes is a large open source project with lots of code and functionality. You may have read about Kubernetes, dabbled in the field on other projects, or even used Kubernetes at work. But to understand and use Kubernetes effectively, and to put it into practice better, you need to have a deeper understanding of it. In this chapter, we will build the basic framework of Kubernetes. First, we will understand the meaning of Container Orchestration. It goes on to explain several important concepts related to Kubernetes that will be used throughout the book; After that, the architecture of Kubernetes will be introduced in depth to understand how to provide all the functions of Kubernetes to users. Next, I’ll introduce the various runtime and container engines supported by Kubernetes (Docker is one of them). Finally, the role of Kubernetes in Full Continuous Integration and Deployment Pipeline is discussed.

This chapter will focus on the following aspects: container choreography, Kubernetes conditions, Kubernetes design principles and architecture, and the different runtime environments supported by Kubernetes. The reader will become familiar with the overall structure of the open source repository and lay the groundwork for solving the remaining problems.

1.1 Understand container choreography

The main function of Kubernetes is container choreography, which is to ensure that all containers run on the physical machine or virtual machine as planned. These containers are packaged to perform large workloads within the constraints of the deployment environment and cluster configuration. In addition, Kubernetes must keep an eye on all running containers and replace containers that are aborted, unresponsive, or otherwise in an abnormal state. More features of Kubernetes will be introduced in subsequent chapters. This section focuses on containers and their choreography.

1.1.1 Dedicated Machines, VMS, and Containers

Hardware is throughout the container choreography. Running the workload requires some real hardware configuration, including a physical machine with computing power (CPU or core), memory, and some local persistent storage (mechanical hard disk or SSD). In addition, you need some shared persistent storage and use a network to connect all physical machines so that they can find each other and exchange information. In this case, you can run multiple VMS on a physical machine or keep the bare metal state. Kubernetes can be deployed on physical hardware or virtual machine clusters, and can also manage containers directly on physical hardware or virtual machines. Theoretically, a Kubernetes cluster can be a combination of physical machines and virtual machines, but this is not common.

1.1.2 Cloud Container

Containers are ideal for encapsulating microservices because they not only provide isolation for microservices, but are lightweight and do not incur the same overhead when deploying multiple microservices as when using virtual machines. This makes containers ideal for cloud deployments because the cost of assigning an entire virtual machine to each microservice is very high.

Major cloud providers like AWS, GCE and Azure now offer container-hosted services, some of which are based on Kubernetes (like Google’s GKE); Other solutions, such as Microsoft Azure container services, are based on Apache Mesos. In addition, AWS uses ECS (container services on EC2) as its own choreography solution. The power of Kubernetes is that it can be deployed on these cloud servers. Kubernetes has a cloud provider interface that allows any cloud provider to implement and seamlessly integrate Kubernetes.

1.1.3 Server Operating Mode

In the past, systems were small and each server had a name. Developers and users know exactly what software is running on each machine. Many companies I’ve worked with have had days of discussions to decide on a naming theme for their servers. Composers and Greek mythological figures, for example, are popular choices. Developers treat servers like their beloved pets. If one server fails, it’s a major crisis, and all three things need to be done with full attention: get a new server; Identify what data is still running on the failed server; How to get this data to run on a new server. If the failed server stores some important data, you can only hope for backups and data recovery.

Obviously, this approach is not appropriate, and when you have dozens or even hundreds of servers, you have to treat them like livestock, thinking collectively rather than individually. You may still need to build machines like pets, but you need to treat web servers like animals.

Kubernetes takes this approach to the extreme by taking on all the task of assigning containers to a particular machine. You don’t have to spend a lot of time interacting with individual machines (nodes). This is best for stateless workloads. For stateful applications, the situation is slightly different, but Kubernetes offers a solution called StatefulSet, which we’ll discuss next.

In this section, we introduce the concept of container choreography, discuss the relationship between a host (physical machine or virtual machine) and a container, and the advantages of running a container in the cloud. Finally, we discuss the running mode of a server using livestock and pets as an analogy. Section 1.2 will enter the world of Kubernetes and learn about the concepts and terminology associated with it.

1.2 Related concepts of Kubernetes

This section will briefly introduce many of the important concepts related to Kubernetes and provide cases to illustrate their importance and interrelationship to familiarize yourself with these terms and concepts. Next, I show you how to weave these concepts together to achieve awesome results. Readers can view many of these concepts as building blocks. Some concepts are implemented as a Kubernetes component, such as nodes and master nodes. These components are at different levels of abstraction, as discussed in more detail in Section 1.5.

Figure 1.1 is the famous Kubernetes architecture.

Figure 1.1 Kubernetes architecture

1.2.1 cluster

A cluster is a collection of host storage and network resources that Kubernetes uses to run the various workloads that make up the system. A complete system can consist of multiple clusters. Advanced use cases for cluster federation are discussed in detail later.

1.2.2 node

A node is a single host, which can be a physical machine or virtual machine, and is responsible for running a Pod. Each Kubernetes node runs multiple Kubernetes components, such as Kuberlet and Kube agent. Nodes are managed by the Kubernetes master controller. These nodes are similar to the Kubernetes worker bees and shoulder the burden. In the past, they were called subordinates (Minion). If the reader has read the previous literature, please do not be confused, subordinate refers to nodes.

1.2.3 the master node

The master node is the Kubernetes control panel, which consists of several components, including an API server, a scheduler, and a controller manager. The master node is responsible for node scheduling and event processing at the global and cluster level. Typically, all primary controller components are set up on a single host, and multiple primary nodes are preferred when considering high availability scenarios or large clusters. High availability clustering is explained in detail in Chapter 4.

1. Pod

A Pod is a unit of work for Kubernetes. Each Pod contains one or more containers, and the pods usually run on the same machine and are scheduled together. All containers in a Pod have the same IP address and port space, and they can communicate via a localhost or a standard process. In addition, all containers in the Pod have access to local shared storage on the node hosting the Pod, which exists on each container. Pod is an important feature of Kubernetes. It is possible to run multiple Docker applications in a single Docker container by acting as the super administrator of the main Docker application running on multiple processes, but this practice is discouraged for the following reasons.

  • Transparency: Making containers within pods visible to the infrastructure and enabling the infrastructure to provide services to those containers, such as process management and resource monitoring, provides a lot of convenience to users.
  • Decoupled software dependencies: Individual containers can be versioned, rebuilt, and redeployed independently. Kubernetes is even expected to support real-time updates of individual containers.
  • Ease of use: users do not need to run their own process manager, and do not need to worry about transaction propagation of signals and exit codes, etc.
  • Efficiency: Containers can be lighter because the infrastructure will take on more responsibility.

Pod provides a good solution for groups of containers that are interdependent and need to collaborate on the same host to achieve their goals. Remember, a Pod is considered a temporary, replaceable entity that can be discarded and replaced if needed, and a Pod can destroy any Pod storage. Each Pod has a unique ID (UID), so it is still possible to distinguish between them.

1.2.5 label

Tags are key-value pairs used to combine collections of objects, typically PODS. This is important for several other concepts, such as replica controllers, replica sets, and services that need to operate on dynamic groups of objects and identify group members. There is an N×N relationship between objects and labels. Each object can have multiple labels, and each label can be applied to different objects. Label design is limited. Each label on an object must have a unique key that follows a strict syntax. Its syntax consists of two parts: prefix and name. The prefix is optional, if it exists, it is separated from the name by a forward slash (/), and must be a valid DNS subdomain, with a maximum of 253 characters. The name is mandatory and contains a maximum of 63 characters. The name must start and end with letters, digits, and characters (a to Z, A to z, and 0 to 9), and contains only letters, digits, characters, periods (.), dashes (.), and underscores (_). The rules for values are the same as for names. Note that tags are only used to identify objects and do not attach any metadata to them. This is the purpose of the annotations (see Section 1.2.6).

1.2.6 annotations

Annotations allow any metadata to be associated with Kubernetes objects. Kubernetes only stores annotations and makes their metadata available. Unlike tags, there are no strict requirements on character types and sizes. Complex systems often require such metadata, and Kubernetes identifies such requirements and provides metadata out of the box so that users don’t have to extract their own separate metadata stores for mapping.

Most of the Kubernetes concepts have been covered and briefly summarized here. In Section 1.2.7, the architecture of Kubernetes will continue to be studied in terms of its design motivation, internal structure and implementation, and source code.

1.2.7 Label selectors

Label selectors select objects based on labels, specifying key names and values based on equal selectors. A value-based equality or inequality that has two operators: = (or ==) and! =, the code is as follows.

role = webserver
Copy the code

This selects all objects that have the label key and value.

Label selectors can be separated by multiple commas, as shown below.

role = webserver, application ! = fooCopy the code

Collection-based selectors extend performance and allow selection based on multiple values, as shown below.

role in (webserver, backend)
Copy the code

1.2.8 Replica Controller and Replica Set

Replica controllers and replica sets manage a set of pods identified by a label selector, ensuring that a certain number of pods are always running. The main difference between them is that replica controllers test membership through name matching, whereas replica sets test membership through collection-based selectors. Replica set updated and designated as the next generation replica controller. It is still in beta and is not supported by all tools at the time of writing. But perhaps by the time the reader reads the book, it is fully mature.

Kubernetes ensures that the same number of pods are running in the replica controller or replica set. Kubernetes will start a new use case when the number drops due to a problem with the host node or the Pod itself. Note that if the number of pods is manually started and exceeds the specified number, the replica controller will end the process of the extra pods.

Replica controllers used to be the center of many workflows, such as rolling updates and running one-off jobs. As Kubernetes evolved, it introduced direct support for many similar workflows, such as specialized objects such as Deployment, Job, and DaemonSet. These are covered in the following sections.

1.2.9 service

Services expose some functionality to users or other services. They typically contain a set of PODS, distinguished by tags. Services can provide access paths to external resources, or pods that directly control virtual IP. Local Kubernetes server via convenient endpoint exposure capabilities. Note that the service takes place at Layer 3 (TCP/UDP). Kubernetes 1.2 added entry objects that provide access to HTTP objects, more on this later. Services can be published or discovered through one of two mechanisms: DNS or environment variables. The service can be load balanced by Kubernetes. But when services use external resources or require special processing, developers can manage and balance the load themselves.

Details related to IP addresses, virtual IP addresses, and port Spaces will be discussed in more detail in later chapters.

1.2.10 storage volume

The storage on the Pod is temporary and disappears with the Pod. This is sufficient if you just exchange data between containers of nodes, but sometimes the data needs to be stored on pods for a longer period of time, or transferred between pods, which is supported by the volume concept. Note that while Docker does have the concept of a volume, it is still limited (though increasingly powerful). Kubernetes uses its own volumes and supports additional container types (such as RKT), so it is fundamentally independent of Docker volumes.

There are many types of storage volumes, and Kubernetes currently supports all of them directly. If an indirection layer could be added, an abstract storage volume plug-in might be developed. The emptyDir storage volume type installs a volume on each container, which is backed up by default on any container available on the host machine. You can request storage media if required. This store is deleted when the Pod terminates for any reason. There are many storage volume types for specific cloud environments, various networked file systems, and even Git repositories. An interesting type of storage volume is PersistentDiskClaim, which Outlines some of the details and uses the default persistent storage in the developer’s cloud provider environment.

1.2.11 Stateful Service Set

If you care about data on a Pod, you can use persistent storage. But if you need Kubernetes to manage a distributed data repository such as Kubernetes or MySQL Galera, you can’t simulate it with regular pods and services because these cluster stores distribute data on a single node. Back to stateful service sets, we discussed the relationship between pets and livestock and how livestock are managed and enforced. The stateful service set is somewhere in between. A stateful service set ensures that a given number of pets with unique identifiers are running at any given time (similar to a replication controller). Pets have the following characteristics.

  • Stable host name available in DNS.
  • Ordinal index.
  • Stable storage attached to ordinal and host names.

Stateful service sets help peers discover, add, or remove pets.

1.2.12 Key Object

Key objects are small objects that contain sensitive information, such as credentials and tokens. They are stored in etCD as clear text, accessible through the Kubernetes API server, and loaded into Pod as files when needed (using the private key object capacity loaded on the regular capacity). The same key object can be installed in multiple pods. Kubernetes itself encrypts its components, and developers can create their own key objects. Another approach is to use key objects as environment variables. Note that, for better security, in the case of prefabricated key objects, the key objects in Pod are generally stored in TMPFS memory.

1.2.13 name

Each object in Kubernetes is identified by its UID and name, which is used to refer to the object in the API call. The name should contain no more than 253 characters and use lowercase alphanumeric characters, underscores (_), and dots (.). . If you delete an object, you can create another object with the same name as the deleted object, but the UID must be unique throughout the life of the cluster. The UID is generated by Kubernetes, so you don’t have to worry about its duplication.

1.2.14 Namespaces

A namespace is a virtual cluster. Multiple virtual clusters separated by namespaces can form a single physical cluster. Each virtual cluster is completely isolated from other virtual clusters and can exchange information only through a common interface. Note that node objects and persistent volumes do not exist in the namespace. Kubernetes can schedule pods from different namespaces to run on the same node. Similarly, pods from different namespaces can use the same persistent storage.

When using namespaces, network policies and resource quotas must be considered to ensure proper access and allocation of resources in the physical cluster.

1.3 In-depth understanding of Kubernetes architecture

Kubernetes has very ambitious goals to manage and simplify the orchestration, deployment, and management of distributed systems across environments and cloud providers. It provides many features and services that should be adapted to a variety of situations, evolve and remain simple enough to be used by most users. This is a tall order. Kubernetes achieves this through clear layout, high-level design, and a mature architecture that promotes both scalability and flexibility. Many parts of Kubernetes are still hard-coded or context-sensitive, but they will be gradually decomposed into plug-ins, keeping the kernel generic and general. In this section, Kubernetes will be dissected layer by layer. First, various distributed system design patterns and how Kubernetes support them are introduced. Then we introduce the outer layer of Kubernetes, its SET of apis. The actual components that make up Kubernetes will be introduced next; Finally, the source code tree is briefly introduced to further understand the structure of Kubernetes.

At the end of this section, the reader will have an in-depth understanding of Kubernetes’ architecture, implementation, and some of its design decisions.

Distributed system design patterns

Happy families (distributed systems of work) are similar to Tolstoy’s Anna Karenina. This means that all well-designed distributed systems must follow best practices and principles in order to function properly. Kubernetes is more than just a management system, it also applies these best practices to provide developers and administrators with a high level of service. Several design patterns are described below.

1. Side car model

Sidecar mode co-locates another container in the Pod in addition to the main application container. The application container is unaware of the sidecar container and simply performs its task. A good example is the Central Logging Agent. The main container only logs to STDout, but the sidecar container sends all logs to a central logging service where the logs are aggregated for the entire system. Use side car container compared to add the log to the main application container has great advantages, application is no longer the burden of the central log, if you want to upgrade or change the central logging policy or switch to the new provider, only need to update and deploy side car container, container and do not have any change, so will not be damaged due to the unexpected.

2. Diplomat model

The diplomat pattern refers to treating remote services as local services and having them enforce partial policies. A good example of the diplomat pattern is if you have a Cluster of Redis in which one host is used for authoring and the remaining copies are used for reading, the local diplomat container can act as a proxy and expose Redis to the main application container on the local host. The main application container simply connects to Redis on localHost :6379 (the default port of Redis), but it really only connects to the diplomat container running in the same Pod, which filters requests, sends write requests to the real Redis host, and randomly sends read requests to one of the read copies. Similar to sidecar mode, the main application does not know what is going on during this time. This will be of great help when testing a real native Redis cluster. In addition, if the Redis cluster configuration changes, only the diplomat container needs to be modified, and the main application is also unaware of this operation.

3. Adapter mode

The adapter pattern is the standardized output of the main application container. Progressively rolled out services may face the following problems: Services may generate reports in formats that do not conform to previous versions, and other services and applications that use this output have not been upgraded. The adapter container can be co-deployed with the new application container on the same Pod and match its output to the old version until all users have been upgraded. The adapter container shares the file system with the main application container to monitor the local file system and ADAPTS as soon as a new application writes to a file.

4. Multi-node mode

Single-node modes are supported directly by Kubernetes via Pod. While the multi-node mode is not directly supported, such as director election, work queue, and decentralized collection, Kubernetes support can be achieved using the standard interface combination Pod.

1.4 Kubernetes API

To understand the capabilities of a system and the services it provides, you need to look at its apis. The API provides a global map for users of the system. Kubernetes provides developers with multiple sets of REST apis from multiple perspectives. Some apis need to be used by tools, while others can be used directly by developers. An important aspect of the apis is that they are also constantly evolving, and Kubernetes developers keep them manageable by trying to extend (adding new objects and fields to existing objects) and avoiding renaming or deleting existing objects and fields. In addition, all API endpoints are versioned and usually contain Alpha or Beta notation as well. Here’s the code.

/api/v1
/api/v2alpha1
Copy the code

The API can be accessed through kubectl CLI based on the client library, or by calling the REST API directly. The following sections describe authentication and authorization mechanisms in detail. This gives the reader a sense of the API.

1.4.1 Kubernetes API

This is the main API of Kubernetes, and it’s huge. All of the concepts discussed above, and many of the auxiliary concepts, have corresponding API objects and operations. If you have the right permissions, you can list, get, create, and update objects. Below is a detailed documentation of a common operation to get a list of all the PODS.

GET /api/v1/pods
Copy the code

It supports various optional parameters.

  • Pretty: If true, the output is printed with pretty.
  • LabelSelector: A selector expression used to restrict the result.
  • Watch: If true, the change is observed and the event stream is returned.
  • ResourceVersion: With Watch, only events that happened after this version are returned.
  • TimeoutSeconds: Specifies the timeout period for the list or monitor.

1.4.2 Automatic Scaling API

The autoscaling API is very focused, allowing control of the Pod autoscaling at the same level. The autozoomer manages a set of pods based on CPU utilization and even application-specific metrics. It can list, query, create, update and destroy autoscaler objects with /apis/autoscaling/v1 endpoints.

Batch API

The batch API is used to manage jobs. A job is a Pod that executes and terminates some activity. Unlike regular pods managed by replica controllers, they should terminate when the job completes. The batch API uses Pod templates to specify jobs and then, in most cases, allows jobs to be listed, queried, created, and deleted via /apis/ Batch /v1 endpoints.

1.5 Kubernetes components

A Kubernetes cluster has several main components that control the cluster, as well as node components that run on each cluster node. This section introduces these components and explains how they work together.

1.5.1 primary component

The main components typically run on a single node, but in a high availability cluster or large cluster, they can be distributed across multiple nodes.

1. API server

Kube API Server (KuBE-API Server) provides the Kubernetes REST API. Because of its stateless nature, it can easily scale horizontally. All of its data is stored in an ETCD cluster. The API server is the embodiment of the Kubernetes control plane.

2. Etcd

Etcd is a very reliable distributed data store. Kubernetes uses it to store the entire cluster state. In a small transient cluster, a single ETCD can run on the same node as all other main components. But for redundancy and high availability, larger clusters often contain three or even five ETCD clusters.

3. Controller manager

The controller manager is a collection of managers packaged into a binary file. It contains replica controller, Pod controller, service controller, endpoint controller, and so on. All of these controllers monitor the cluster state through apis, and their job is to control the cluster to a target state.

4. The scheduler

The Kube scheduler is responsible for scheduling pods into nodes. This is a very complex task, as it requires consideration of multiple interacting factors, such as the following.

  • Resource requirements.
  • Service requirements.
  • Hard/software policy constraints.
  • Affinity and anti-affinity specifications.
  • Data locality.
  • Deadline.

5. The DNS

The DNS service has been part of the standard Kubernetes cluster since Kubernetes 1.3. It is scheduled as a normal Pod. Every service except Headless receives DNS names, and Pod can also receive DNS names, which is useful for automated exploration.

1.5.2 Node Components

Nodes in a cluster require several components to interact with the cluster main component, receive workloads to be executed, and update the cluster based on their status.

1. The agent

The Kube proxy performs low-level network maintenance on each node. It is used to render local Kubernetes services, perform TCP and UDP forwarding, and find cluster IP through environment variables or DNS.

2. Kubelet

Kubelet represents Kubernetes on a node. It is responsible for monitoring the communication with the main component and managing the RUNNING Pod, including the following aspects.

  • Download Pod secrets from the API server.
  • Loading volume.
  • The container that runs Pod (Docker or Rkt).
  • Reports the status of nodes and each Pod.
  • Run the container active probe.

In this section, we take an in-depth look at the architecture of Kubernetes and the design patterns it supports from a macro perspective through the API of Kubernetes and the components used to control and manage clusters. Section 1.6 covers the runtime supported by Kubernetes.

1.6 Kubernetes runtime

Kubernetes originally only supported Docker as a container runtime engine, but things have changed now, Rkt is another supported runtime engine, and there are some interesting attempts with Hypernet and Hyper-.sh container work. An important design strategy is that Kubernetes itself should be completely isolated from a particular runtime. Kubernetes interacts with the runtime through a relatively generic interface that the runtime engine must execute. Most of the information exchange is implemented through pods, container concepts, and operations that can be performed on containers, and each runtime engine is responsible for ensuring that the Kubernetes runtime interface is compatible.

In this section, you’ll delve into the run-time interface and refine it to a single run-time engine. By the end of this section, the reader will be able to select a run-time engine that is appropriate for the actual use case and will be aware of specific practical scenarios for switching or combining multiple runtimes within the same system.

1.6.1 Runtime Interface

The runtime interface for containers is described in detail in GitHub’s Kubernetes project. Kubernetes is open source and can be found on the website.

The following code shows a portion of the file that is not commented in detail. Even entry-level programmers with no knowledge of the Go language can grasp the scope of the run-time engine from Kubernetes’ perspective.

type Runtime interface {
  Type() string
  Version() (Version, error)
  APIVersion() (Version, error)
  Status() error
  GetPods(all bool) ([]*Pod, error)
}
Copy the code

 

Here’s a brief introduction to the Go language to help you better parse your code — first the method name, then the method parameters in parentheses. Each parameter is a pair, consisting of a name and a name type. Finally, specify the return value. The Go language allows for multiple return types. In addition to returning the actual result, it is also common to return an error object, which will be nil if all goes well.

In fact, this is an interface that means Kubernetes does nothing. The first set of methods provides basic information about the runtime: type, version, API version, and status. You can get all the PODS with the following code.

SyncPod(pod *api.Pod, apiPodStatus api.PodStatus, podStatus
*PodStatus, pullSecrets []api.Secret, backOff
*flowcontrol.Backoff) PodSyncResult

KillPod(pod *api.Pod, runningPod Pod, gracePeriodOverride *int64)
error 

GetPodStatus(uid types.UID, name, namespace string) (*PodStatus,
error)

GetNetNS(containerID ContainerID) (string, error)

GetPodContainerID(*Pod) (ContainerID, error)

GetContainerLogs(pod *api.Pod, containerID ContainerID, logOptions
*api.PodLogOptions, stdout, stderr io.Writer) (err error)

DeleteContainer(containerID ContainerID) error
Copy the code

The next set of methods deals primarily with Pod, as this is the main conceptual framework in the Kubernetes conceptual model. Then there’s GetPodContainerID (), which transfers data from the container to the Pod. There are a few more container-related methods below.

  • ContainerCommandRunner
  • ContainerAttacher
  • ImageService

ContainerCommandRunner, ContainerAttacher, and ImageService are interfaces inherited from run-time interfaces. This means that anyone who needs to execute a run-time interface needs to execute these interface methods. The definition of an interface is stored in the same file. The interface name provides a lot of information about the interface function. Obviously, Kubernets need to execute commands in the container to attach the container to the Pod and extract the container image. Readers are advised to search this file and familiarize themselves with the code.

Now that the reader has a glimpse of Kubernetes as a runtime engine at the code level, it’s time to take a look at the individual run-time engines.

1.6.2 Docker

Of course, Docker is an important container. Kubernetes was originally designed for Docker containers only, and the multi-runtime feature was first added in Kubernetes 1.3. Prior to this, Kubernetes could only manage Docker containers.

It is assumed that readers are very familiar with Docker and understand its functions when reading this book. As we know, Docker has been praised and developed, but also received some criticism, which mainly focuses on the following aspects.

  • Security.
  • It is difficult to build multi-container applications (especially networks).
  • Development, monitoring, and logging.
  • Limitations of the Docker container executing a single command.
  • Releasing half-based features is too fast.

In response to the above problems, Docker has made some improvements, especially for Docker Swarm products. Docker Swarm is a Docker native choreography solution to Kubernetes. It is simpler to use than Kubernetes, but not as powerful and mature as Kubernetes.

 

Since Docker 1.12, Docker daemons have built in swarm mode, but bloat and scope creep have frustrated some users. That, in turn, has led more people to switch to CoreOS Rkt as an alternative.

Since Docker 1.11, released in April 2016, Docker has changed the way it runs containers. The runtime now runs the Open Container Initiative (OCI) image in the container with Containerd and Runc, as shown in Figure 1.2.

Figure 1.2 Running an Open Container Initiative (OCI) image in a container

1.6.3 Rkt

Rkt is a new container manager from CoreOS (CoreOS Linux distribution, ETCD, Flannel, etc.). Rkt runtime benefits from its simplicity, security, and isolation. Instead of daemons like the Docker engine, it relies on OS Init systems like Systemd to start Rkt executables. Rkt has a much simpler architecture for downloading images (whether App Container (APPC) images or OCI images), validating images, and running images in containers.

1. App container

CoreOS began standardization work in December 2014, called APPC, including standard image formats (such as ACI), runtime, signature, and discovery. A few months later, Docker began its own OCI standardization effort. It follows that all gains will converge. This is a great thing because tools, mirrors, and runtimes can all execute freely with each other, however, this vision is not yet realized.

2. Rkrnetes

Rktnetes introduces Rkt as a runtime engine in Kubernetes. Kubernetes is still abstracted from the run-time engine process. Rktnetes is not a stand-alone product. Externally, you only need to run Kubelet with a few command line switches on each node. However, due to the fundamental differences between Docker and Rkt, various problems may be encountered in practice.

3. Whether Rkt is ready for production and use

The integration of Rkt and Kubernetes is not perfect, and there are still some flaws. At this stage (end of 2016), unless there is a clear and specific reason for using Rkt, readers are still advised to choose Docker. If there are significant use cases that require Rkt, it is best to build on CoreOS to find the best integration with the CoreOS cluster, as well as the best documentation and online support.

1.6.4 the Hyper Container

Hyper Container is another option. Hyper Container has a lightweight VM (its own guest kernel) that runs on bare metal and relies on the hypervisor for isolation rather than the Linux Cgroup. This approach provides a more interesting combination than standard bare metal clusters, which are laborious to set up, and public cloud containers can be deployed on heavyweight VMS.

Hypernetes

Hypernetes is a multi-tenant Kubernetes distribution that uses Hyper Container along with some OpenStack components for authentication, persistent storage, and networking, as shown in Figure 1.3. Since containers do not share host kernels, it is safe to run containers with different tenants on the same physical host.

This section describes the various runtime engines supported by Kubernetes and the trend towards standardization and convergence. Section 1.7 takes a look at the big picture and how Kubernetes fits into the CI/CD pipeline.

Figure 1.3 Hypernetes

1.7 Continuous Integration and Deployment

Kubernetes is a great platform for microservices-based applications. Typically, most developers may not know that the system is deployed on Kubernetes, but Kubernetes can make tasks that previously seemed very difficult possible.

This section explores CI/CD pipelining and what Kubernetes can bring to it. After reading this section, you will be able to design your own CI/CD pipeline that takes advantage of Kubernetes features such as ease of scaling and development production parity to improve efficiency and stability in daily development and deployment.

An assembly line 1.7.1 CI/CD

A CI/CD pipeline is a series of steps by a developer or operator to modify system code, data, or configuration, test it, and deploy it into production. Some lines are fully automated, while others are semi-automated with manual verification. In large companies, test and rehearsal environments may be deployed automatically, but release to production still requires human intervention.

It is worth noting that developers can be completely removed from the production infrastructure. Their interface is just a Git workflow, and a good example is the Deis workflow (PaaS on Kubernetes, similar to Heroku), shown in Figure 1.4, which describes a typical transport process.

Figure 1.4Deis workflow

1.7.2 Design CI/CD pipeline for Kubernetes

When deploying to a Kubernetes cluster, some traditional practices should be rethought. First, the packaging is different, and the image needs to be packaged for the container, so it’s easy and quick to undo code changes by using smart tags. If a bad change passes testing but is immediately reverted to the previous version, this gives users a lot of confidence. It is important to note, however, that schema changes and data migrations cannot be rolled back automatically. Another unique aspect of Kubernetes is that developers can run the entire cluster locally. This takes some effort to design the cluster, but is still feasible because the micro services that make up the system run in containers that interact through apis. Typically, if the system is data-driven, you need to provide snapshots of the data and synthetic data available to the developer to accommodate this situation.

1.8 summarize

This chapter introduces a lot of the basics and knowledge that allows the reader to understand the design and architecture of Kubernetes. Kubernetes is a microservice-based application choreography platform running in a container. The Kubernetes cluster has a master node and a working node. Containers run inside pods, and each Pod runs on a single physical machine or virtual machine. Kubernetes directly supports many concepts, such as services, labels, and persistent storage. Various distributed system design patterns can be implemented on Kubernetes. The Container itself can be Docker, Rkt, or Hyper Container.

This article is excerpted from a new book: Mastering Kubernetes

  • K8s Beginner’s Guide
  • For K8s1.10, there are plenty of practical cases
  • Helps readers develop the skills to design and deploy large clusters on a variety of cloud platforms

This book introduces Kubernetes, the ideal tool for container orchestration, from all aspects by combining theory with practice. The book has 14 chapters covering topics including understanding the Kubernetes architecture, creating a Kubernetes cluster, monitoring, logging, and troubleshooting, high availability and reliability, configuring Kubernetes security, restrictions, and accounts, using critical Kubernetes resources, managing Kubernetes storage, Running stateful applications with Kubernetes, rolling updates, scalability and quotas, advanced Kubernetes networking, running Kubernetes in cloud platforms and cluster federation, custom Kubernetes apis and plug-ins, Operate Kubernetes package manager and the future of Kubernetes. A comprehensive consideration of different environments and use cases gives readers an understanding of how to create large systems and deploy them on Kubernetes. In each chapter theme, readers provide a wealth of practical case analysis, narrated, fascinating. This book can be used as a practical reference manual for Kubernetes, focusing on the design and management of Kubernetes clusters, detailing the functions and services provided by Kubernetes for developers, operations and maintenance engineers.