Kubernetes OSS for modern cloud native architecture (gRpc)

Kubernetes OSS for modern cloud native architecture (gRpc)

Kubernetes CRD and Operator

Kubernetes has a mechanism called CRD (Custom Resource Definition) and Operator. CRD is a feature that allows Kubernetes to define unique resources other than the resources that it can handle by default. For example, you can create something like the MysqlCluster resource below.

apiVersion: mysql.presslabs.org/v1alpha1
kind: MysqlCluster
metadata:
  name: product-db
  namespace: product
spec:
  replicas: 2
  secretName: product-db
  mysqlVersion: "5.7"
  backupSchedule: "0 0 */2 * *"
  backupURL: s3://product-db/

Operator is a program that actually processes resources created from this CRD. In the example above, the MySQL cluster will be created and operated automatically after the manifest is registered. A lot of systems based on Kubernetes now run in this way.

In the recent community, we have come to see the word “Kubernetes-native”, and we recognize that this phrase is broadly “built on the assumption of Kubernetes” and narrowly “definable and settable all in manifests using Kubernetes CRD,” as in the example above. This time, we designed the Kubernetes-native testbed in the narrow sense.

Kubernetes-native infrastructure

In this testbed, an e-commerce website will be provided as an example to incorporate all of the middleware described above. The website is easy for everyone to understand and has many components, so it is also intended to be used as microservices. Please look at the architecture diagram.

GitOps

When we started this project, the first thing we thought we should prepare was the CI/CD environment. It is also described in the CNCF TrailMap. Modifying application deployments and infrastructure configurations are very challenging even in environments using Kubernetes. Build the container image and rewrite the manifest tag every time you modify the application. This is a very monotonous and boring task. By eliminating the work from the beginning, you can spend more time developing applications.

The following OSSs were selected for the Kubernetes-native CI/CD environment.

OSSCATEGORY
Tekton(Pipeline、Triggers)Kubernetes-native CI tool
ArgoCDKubernetes-native CD tool
HarborContainer registry for storing container images
(CNCF Incubating project)
ClairVulnerability scanner for container image
KanikoBuild container images on Kubernetes pods

GitOps is known as the best practice of all CI/CD patterns in the Kubernetes environment so we have built a GitOps environment with the OSS described above.

Kubernetes-native local development

The testbed is too large, so we cannot run the whole system on your local machine. For local development, we provide the way by using Skaffold and Telepresence.

Kubernetes-native stateful middleware

Container technology is generally considered unsuitable for stateful applications, but it is expected that this perception will gradually change in the future with the help of operators. In addition, depending on the status of database failures, the operator can change the members of the endpoints or obtain a backup automatically, so we can entrust operation to the operator as instead of human. In other words, the Kubernetes Operator system can be used to program operational knowledge and delegate management to Kubernetes in accordance with their lifecycle. In this testbed, we are using Database, KVS, MessageQueue and Block/Shared/Object Storage with Kubernetes Operator.

gRPC and gRPC-web

This testbed uses gRPC for communication of each microservice. gRPC can describe APIs using IDL, so the specifications are very clear. This has the advantage of making it easier to implement server-side and client-side. So it’s a great match for microservices which are developed by some split teams.

In addition, communication between browsers and microservices uses gRPC, too! This is strictly called gRPC-Web. The browser cannot issue gRPC requests due to some functions required for gRPC is not implemented. Therefore, gRPC-Web was proposed, this protocol close to gRPC.

gRPC-Web requires a proxy that converts gRPC and gRPC-Web to each other for a browser to communicate with the backend. Envoy, L7 Load Balancer, has this proxy feature and we use it in our testbed. Additionally, to make Envoy more Kubernetes-native, we use Contour as Envoy controller.

How gRPC works

gRPC is a high-performance, open-source, feature-rich RPC framework, originally developed by Google, and now is a part of the cloud native computing foundation (or CNCF), just like Kubernetes or Prometheus.

OK, so what g in gRPC stands for? At first I thought it’s Google (yeah, you know why). But in fact, it stands for different things in each gRPC release, such as “good”, “green”, “glorious”, and even “gRPC” itself.

You can check out the full list in this link.

How about RPC? RPC stands for Remote Procedure Calls. It is a protocol that allows a program to execute a procedure of another program located in other computer.

And what’s awesome about it is that developers don’t have to explicitly coding the details of the network interaction. It’s automatically handled by the underlying framework.

So, in the client code, it looks like we’re just calling a function of the server code directly. And it works even if the codes on client and server are written in different programming languages. Like in this example, the client code is written in Go, and the server code is written in Rust.

So how can gRPC do that? Basically, the client has a stub that provides the same method (or function) as the server. That stub is automatically generated for you by gRPC.

The stub will call gRPC framework under the hood to exchange information with the server over the network.

And voila, magically everything just works. Thanks to the stubs, the client and server now only need to care about implementing their core service logic.

How gRPC works

Next, we will see how the gRPC stubs are generated with the help of protocol buffer.

How gRPC generates codes

Code generation is one of the most important features of gRPC.

In order to generate stubs for the server and client, we first need to write the API contract, which includes a description of the services and their payload messages in a protocol buffer file that looks something like this:

Define protocol buffer message

In this file, a Hello method is defined, which takes a HelloRequest as input and returns a HelloResponse. The HelloRequest only contains a string name, and the HelloResponse has a string greet.

Very simple, right? We will learn much more detail about this later in the hands-on with protobuf lectures.

From this proto file, the server and client stub codes are generated by the protocol buffer compiler (or protoc). Depending on the programming language, we will have to tell the compiler to use the correct gRPC plugin for it.

The generated codes for Rust and Go will look something like this:

How stubs are generated

OK, so you may wonder why gRPC uses protocol buffer? Well, there are many reasons.

First, it’s super easy to read and understand.

Second, it’s language interoperable with automatic code generation for many languages

Third, It represents data in binary format, which is smaller size, faster to transport, and more efficient to serialize than some text-based format like JSON or XML.

It provides a strongly typed API contract between client and server, which is super safe to work with.

And it has a great set of rules for API evolution to ensure backward and forward compatibility.

Why protocol buffer

Sounds pretty amazing, right? But is protocol-buffer required to work with gRPC?

The answer is NO. You can use Google flatbuffers or Microsoft bond instead. But in my opinion, protocol buffer is already a great choice.

It supports a lot of popular programming languages, with 10 officially supported, where Go, Java, NodeJS are purely implemented, and 7 others are wrappers of the gRPC core C, namely, C++, C#, Objective-C, Python, Ruby, Dart, and PHP.

Besides, there are many other unofficial libraries for other languages such as Swift, Rust, TypeScript, Haskell and so on.

Supported programming languages

Alright, now we know how gRPC generates codes for us. I hope you find it interesting.

In the next lecture, we will explore another secret weapon of gRPC: HTTP/2. See you then.

GitOps

When we started this project, the first thing we thought we should prepare was the CI/CD environment. It is also described in the CNCF TrailMap. Modifying application deployments and infrastructure configurations are very challenging even in environments using Kubernetes. Build the container image and rewrite the manifest tag every time you modify the application. This is a very monotonous and boring task. By eliminating the work from the beginning, you can spend more time developing applications.

The following OSSs were selected for the Kubernetes-native CI/CD environment.

OSSCATEGORY
Tekton(Pipeline、Triggers)Kubernetes-native CI tool
ArgoCDKubernetes-native CD tool
HarborContainer registry for storing container images
(CNCF Incubating project)
ClairVulnerability scanner for container image
KanikoBuild container images on Kubernetes pods

GitOps is known as the best practice of all CI/CD patterns in the Kubernetes environment so we have built a GitOps environment with the OSS described above.

Kubernetes-native local development

The testbed is too large, so we cannot run the whole system on your local machine. For local development, we provide the way by using Skaffold and Telepresence.

Kubernetes-native stateful middleware

Container technology is generally considered unsuitable for stateful applications, but it is expected that this perception will gradually change in the future with the help of operators. In addition, depending on the status of database failures, the operator can change the members of the endpoints or obtain a backup automatically, so we can entrust operation to the operator as instead of human. In other words, the Kubernetes Operator system can be used to program operational knowledge and delegate management to Kubernetes in accordance with their lifecycle. In this testbed, we are using Database, KVS, MessageQueue and Block/Shared/Object Storage with Kubernetes Operator.

gRPC and gRPC-web

This testbed uses gRPC for communication of each microservice. gRPC can describe APIs using IDL, so the specifications are very clear. This has the advantage of making it easier to implement server-side and client-side. So it’s a great match for microservices which are developed by some split teams.

In addition, communication between browsers and microservices uses gRPC, too! This is strictly called gRPC-Web. The browser cannot issue gRPC requests due to some functions required for gRPC is not implemented. Therefore, gRPC-Web was proposed, this protocol close to gRPC.

gRPC-Web requires a proxy that converts gRPC and gRPC-Web to each other for a browser to communicate with the backend. Envoy, L7 Load Balancer, has this proxy feature and we use it in our testbed. Additionally, to make Envoy more Kubernetes-native, we use Contour as Envoy controller.

For cloud providers

For Cloud Providers, we are looking for a sponsor to provide cloud environment. If you can help, please email us (kubernetes-native-testbed@googlegroups.com).

Summarize: One answer to realizing cloud native

In this testbed, we introduced the following three points, mainly using the Kubernetes-native ecosystem.

  • CI/CD and development environment that can be released stably immediately after application development

  • Automated stateful middleware by Kubernetes Operator

  • High-Performance Interservice Communication with Full gRPC

By using these functions, we can continue to create services and provide new functions in a stable manner with minimal effort. We think this is one answer to the realization of cloud native.

Although some parts are still under development at this point, we believe that the Cloud Native world will be more popular in the future. I’d like you to experience the great world.

Repository:

https://github.com/redhabayuanggara21/pcbook-java

https://github.com/redhabayuanggara21/pcbook-go

https://github.com/redhabayuanggara21/go-grpc-microservices

https://github.com/redhabayuanggara21/simplebank

References:

https://www.youtube.com/watch?v=f6KG5eqOPFw

https://www.youtube.com/watch?v=rx6CPDK_5mU&list=PLy_6D98if3ULEtXtNSY_2qN21VCKgoQAE

https://dev.to/svengau/when-graphql-meets-grpc-5aah