Article note: #good2read

At the time of this article, Kubernetes is about six years old, and over the last two years, it has risen in popularity to consistently be one of the most loved platforms. This year, it comes in as the number three most loved platform. If you haven’t heard about Kubernetes yet, it’s a platform that allows you to run and orchestrate container workloads.

Containers began as a Linux kernel process isolation construct that encompasses cgroups from 2007 and namespaces from 2002. Containers became more of a thing when LXC became available in 2008, and Google developed its own internal ‘run everything in containers mechanism’ called Borg. Fast forward to 2013, and Docker was released and completely popularized containers for the masses. At the time, Mesos was the primary tool for orchestrating containers, however, it wasn’t as widely adopted. Kubernetes was released in 2015 and quickly became the de facto container orchestration standard.

To try to understand the popularity of Kubernetes, let’s consider some questions. When was the last time developers could agree on the way to deploy production applications? How many developers do you know who run tools as is out of the box? How many cloud operations engineers today don’t understand how applications work? We’ll explore the answers in this article.

Infrastructure as YAML

Coming from the world of Puppet and Chef, one of the big shifts with Kubernetes has been the move from infrastructure as code towards infrastructure as data—specifically, as YAML. All the resources in Kubernetes that include Pods, Configurations, Deployments, Volumes, etc., can simply be expressed in a YAML file. For example:

apiVersion: v1
kind: Pod
metadata:
  name: site
  labels:
    app: web
spec:
  containers:
    - name: front-end
      image: nginx
      ports:
        - containerPort: 80

This representation makes it easier for DevOps or site reliability engineers to fully express their workloads without the need to write code in a programming language like Python, Ruby, or Javascript.

Other benefits from having your infrastructure as data include:

  • GitOps or Git Operations Version Control. With this approach, you can keep all your Kubernetes YAML files under git repositories, which allows you to know precisely when a change was made, who made the change, and what exactly changed. This leads to more transparency across the organization and improves efficiency by avoiding ambiguity as to where members need to go to find what they need. At the same time, it can make it easier to automatically make changes to Kubernetes resources by just merging a pull request.
  • Scalability. Having resources defined as YAML makes it super easy for cluster operators to change one or two numbers in a Kubernetes resource to change the scaling behavior. Kubernetes has Horizontal Pod Autoscalers to help you identify a minimum and a maximum number of pods a specific deployment would need to have to be able to handle low and high traffic times. For example, if you are running a deployment that may need more capacity because traffic suddenly increases, you could change maxReplicas from 10 to 20:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp-deployment
  minReplicas: 1
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50
  • Security and Controls. YAML is a great way to validate what and how things get deployed in Kubernetes. For example, one of the significant concerns when it comes to security is whether your workloads are running as a non-root user. We can make use of tools like conftest, a YAML/JSON validator, together with the Open Policy Agent, a policy validator to check that the SecurityContext of your workloads doesn’t allow a container to run as a root. For that, users can use a simple Open Policy Agent rego policy like this:
package main

deny[msg] {
  input.kind = "Deployment"
  not input.spec.template.spec.securityContext.runAsNonRoot = true
  msg = "Containers must not run as root"
}
  • Cloud Provider Integrations. One of the major trends in the tech industry is to run workloads in the public cloud providers. With the help of the cloud-provider component, Kubernetes allows every cluster to integrate with the cloud provider it’s running on. For example, if a user is running an application in Kubernetes in AWS and wants that application to be accessible through a service, the cloud provider helps automatically create a LoadBalancer service that will automatically provision an Amazon Elastic Load Balancer to forward the traffic to the application pods.

Extensibility

Kubernetes is very extensible, and developers love that. There are a set of existing resources like Pods, Deployments, StatefulSets, Secrets, ConfigMaps, etc. However, users and developers can add more resources in the form of Custom Resource Definitions. For example, if we’d like to define a CronTab resource, we could do it with something like this:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: crontabs.my.org
spec:
  group: my.org
  versions:
    - name: v1
      served: true
      storage: true
      Schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                  pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
                replicas:
                  type: integer
                  minimum: 1
                  maximum: 10
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab
    shortNames:
    - ct

We can create a CronTab resource later with something like this:

apiVersion: "my.org/v1"
kind: CronTab
metadata:
  name: my-cron-object
spec:
  cronSpec: "* * * * */5"
  image: my-cron-image
  replicas: 5

Another form of Kubernetes extensibility is its ability for developers to write their own Operators, a specific process running in a Kubernetes cluster that follows the control loop pattern. An Operator allows users to automate the management of CRDs (custom resource definitions) by talking to the Kubernetes API. 

The community has several tools that allow developers to create their own Operators. One of those tools is the Operator Framework and its Operator SDK. The SDK provides a skeleton for developers to get started creating an operator very quickly. For example, you can get started on its command line with something like this:

$ operator-sdk new my-operator --repo github.com/myuser/my-operator

Which creates the whole boilerplate for your operator including YAML files and Golang code:

.
|____cmd
| |____manager
| | |____main.go
|____go.mod
|____deploy
| |____role.yaml
| |____role_binding.yaml
| |____service_account.yaml
| |____operator.yaml
|____tools.go
|____go.sum
|____.gitignore
|____version
| |____version.go
|____build
| |____bin
| | |____user_setup
| | |____entrypoint
| |____Dockerfile
|____pkg
| |____apis
| | |____apis.go
| |____controller
| | |____controller.go

Then you can add APIs and a controller like this:

$ operator-sdk add api --api-version=myapp.com/v1alpha1 --kind=MyAppService

$ operator-sdk add controller --api-version=myapp.com/v1alpha1 --kind=MyAppService

And finally build and push the operator to your container registry:

$ operator-sdk build your.container.registry/youruser/myapp-operator

If developers need to have even more control, they can modify the boilerplate code in the Golang files. For example, to modify the specifics of the controller, they can make changes to the controller.go file.

Another project, KUDO, allows you to create operators by just using declarative YAML files . For example, an operator for Apache Kafka would be defined with something like this, and it allows users to install a Kafka cluster on top of Kubernetes with a couple of commands:

$ kubectl kudo install zookeeper
$ kubectl kudo install kafka

Then tune it also with another command:

$ kubectl kudo install kafka --instance=my-kafka-name \
            -p ZOOKEEPER_URI=zk-zookeeper-0.zk-hs:2181 \
            -p ZOOKEEPER_PATH=/my-path -p BROKER_CPUS=3000m \
            -p BROKER_COUNT=5 -p BROKER_MEM=4096m \
            -p DISK_SIZE=40Gi -p MIN_INSYNC_REPLICAS=3 \
            -p NUM_NETWORK_THREADS=10 -p NUM_IO_THREADS=20

Innovation

Over the last few years, Kubernetes has had major releases every three or four months, which means that every year there are three or four major releases. The number of new features being introduced hasn’t slowed, evidenced by over 30 different additions and changes in its last release. Furthermore, the contributions don’t show signs of slowing down even during these difficult times as indicated by the Kubernetes project Github activity.

The new features allow cluster operators more flexibility when running a variety of different workloads. Software engineers also love to have more controls to deploy their applications directly to production environments.

Community

Another big aspect of Kubernetes popularity is its strong community. For starters, Kubernetes was donated to a vendor-neutral home in 2015 as it hit version 1.0: the Cloud Native Computing Foundation.

There is also a wide range of community SIGs (special interest groups) that target different areas in Kubernetes as the project moves forwards. They continuously add new features and make it even more user friendly.

The Cloud Native Foundation also organizes CloudNativeCon/KubeCon, which as of this writing, is the largest ever open-source event in the world. The event, which is normally held up to three times a year, gathers thousands of technologists and professionals who want to improve Kubernetes and its ecosystem as well as make use of some of the new features released every three months.

Furthermore, the Cloud Native Foundation has a Technical Oversight Committee that, together with its SIGs, look at the foundations’ new and existing projects in the cloud-native ecosystem. Most of the projects help enhance the value proposition of Kubernetes.

Finally, I believe that Kubernetes would not would not have the success that it does without the conscious effort by the community to be inclusive to each other and to be welcoming to any newcomers.

Future

One of the main challenges developers face in the future is how to focus more on the details of the code rather than the infrastructure where that code runs on. For that, serverless is emerging as one of the leading architectural paradigms to address that challenge. There are already very advanced frameworks such as Knative and OpenFaas that use Kubernetes to abstract the infrastructure from the developer.

We’ve shown a brief peek at Kubernetes in this article, but this is just the tip of the iceberg. There are many more resources, features, and configurations users can leverage. We will continue to see new open-source projects and technologies that enhance or evolve Kubernetes, and as we mentioned, the contributions and the community aren’t going anywhere.

The post Why Kubernetes getting so popular? appeared first on Stack Overflow Blog.

Article note: #good2know

Bild von Joshua Golde auf Unsplash

Das Ranking einer Webseite ist für viele Betreiber im Internet eine der wichtigsten Auszeichnungen, immerhin sorgt eine besonders gute Bewertung dafür, dass die eigene Webseite entsprechend weit oben in den Google-Suchergebnissen auftaucht und somit noch mehr Leser anzieht. Wie Google in einem neuen Beitrag informiert, werden die Algorithmen, die jenes Ranking beeinflussen, zukünftig modernisiert, sodass dann ab sofort die sogenannte „Page Experience“ als Wert herangezogen wird.

Diese Page Experience hängt dabei natürlich auch wieder von allerhand Faktoren ab, die dieses Mal aber deutlich über das Messen der Ladegeschwindigkeit einer einzelnen Webseite hinausgehen. So sind dann auch Dinge wie Pop-ups, auf der Seite „herumspringende“ Inhalte oder aber auch Verzögerungen beim Anzeigen einzelner Seiteninhalte relevant. Vor allem ändert sich aber auch etwas an den Anforderungen für Beiträge, die in den Google-Schlagzeilen auftauchen können. Bisher mussten diese immer noch zwingend im AMP-Format verfasst sein, jene Anforderung fällt zukünftig weg – jeder Beitrag hat die Chance, in den Schlagzeilen angezeigt zu werden, sofern er die Page-Experience-Kriterien einhält.

Die hier gezeigten Kriterien zeigen, wie sich der Faktor „Page Experience“ eigentlich zusammensetzt.

  • Largest Contentful Paint (LCP) misst, wie schnell der „Hauptinhalt“ der Seite geladen wird
  • First Input Delay (FID) misst, wie schnell die Seite reagiert, wenn der Nutzer erstmalig auf der Seite etwas anklickt
  • Cumulative Layout Shift (CLS) misst, wenn Dinge auf der Seite „herumspringen“ – zum Beispiel, wenn Anzeigen den darzustellenden Text immer wieder neu anordnen

Laut The Verge brauchen Betreiber von Webseiten nun aber nicht in Panik verfallen und ihre Seiten sofort entsprechend anpassen. Frühestens in einem halben Jahr wolle Google laut einiger Entwickler damit beginnen, Seiten nach deren Page Experience zu bewerten und anzuzeigen.

-> Zum Beitrag Google: Ranking von Webseiten wird zukünftig von anderen Kriterien abhängen

-> Zum Blog Caschys Blog

Unser Feedsponsor:

Article note: #good2know #good2read #goodluck!

Android device vendors are known for their short support periods. They only provide updates for a limited time or even ship devices with old Android versions. Developers then have to deal with a fragmented distribution of Android versions. Android 4.x is still used by around 2% of the active devices on Google Play. Old phones usually still have decent performance and updating them with Custom ROMs makes them well-suited even until today. Unfortunately, not all devices support Custom ROMs and not all users want to deal with the trouble of installing one.

AntennaPod is an open-source podcast manager for Android that I maintain. AntennaPod does not rely on a centralized server but fetches the podcast feeds directly using the device. This is pretty nice for user’s privacy because nobody gets a full list of your subscriptions. Unfortunately, more and more users with old Android versions experience problems with some podcast feeds. The reason is that servers are updated to more recent TLS versions that are not available on those devices. Upgrading the TLS version of servers is definitely a good thing because it makes the communication more secure. That’s why most browsers ship their own stack that they can update independently of the device vendors. Unfortunately, all other apps that are dependent on connections to many servers out of their control, like AntennaPod, still experience issues. Users then see download errors like the following: Failure in SSL Library, usually a protocol error. This is pretty bad because it prevents users from listening to podcasts. While this is basically the device vendor’s fault, it ultimately backfires on app developers.

TLSv1.1 and TLSv1.2 are supported starting with Android 4.1 and were enabled by default in Android 5.0. There also is a number of Cipher suites and certificates that are not supported in Android 4.x. While this problem currently only affects Android 4.x users, more will follow in the future as servers are upgraded to TLSv1.3. TLSv1.3 was first shipped with Android 10, which runs on about 8% of the active devices on Google Play. You can find more details about the SSL support in Android on the SSLSocket reference page. Developers now have to deal with the fact that vendors neglect software updates.

This is a known problem, so Google published a library called ProviderInstaller. It’s pretty easy to use (ProviderInstaller.installIfNeeded(context);) and fixes all those problems instantly. Because the provider is kept up-to-date independently of the app using Google Play Services, app developers do not need to worry about this anymore.

This sounds too good to be true, doesn’t it? Well, Google’s ProviderInstaller has a pretty big drawback. The library is closed-source, so it can not be used for apps published on F-Droid. AntennaPod currently builds with two different flavors: one that is 100% free software for F-Droid and one with the ProviderInstaller library for the Google Play Store. This means that the F-Droid users are left behind. They still experience connection problems to some servers and consider this a bug in AntennaPod.

An alternative that works with F-Droid is to include the open-source library Conscrypt. Bundling Conscrypt with an app is just as easy as using Google’s ProviderInstaller but it has two major disadvantages:

  • App developers are forced to update the provider regularly. This is additional work for the maintainers and might cause trouble with apps that have a slow development cycle.
  • Bundling Conscrypt increases the apk size. In case of AntennaPod, this means that the app gets around 4 MB bigger, which is a 40% increase just for this mostly invisible change. Now consider that every app would have to do that in order to get an updated TLS stack. If every app on F-Droid that deals with networking needs to bundle additional 4 MB of TLS libraries, this would increase storage usage noticeably.

Fortunately, there is a solution for this! The idea is to write an open-source provider application (just like Google’s provider) that does nothing but bundling Conscrypt and providing a stable API that allows other apps to load it. It can then be updated independently of apps like AntennaPod or F-Droid. The provider app could simply have a class with something like this:

public static void install() {
    Security.insertProviderAt(Conscrypt.newProvider(), 1);
    Log.d(TAG, "Provider installed.");
}

We could then develop an open-source library that uses the ClassLoader to include the Conscrypt library from the provider app.

Context targetContext = context.createPackageContext("com.bytehamster.providerinstaller",
        Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
ClassLoader classLoader = targetContext.getClassLoader();
Class installClass = classLoader.loadClass("com.bytehamster.providerinstaller.ProviderInstallerImpl");
Method installMethod = installClass.getMethod("install", new Class[]{ });
installMethod.invoke(null);
installed = true;

Code samples are also available (and a bit more detailed) on GitHub Gist.

Obviously, just including code from another app is a security risk. By including the provider, you execute foreign code in the context of your application. How do you verify that the provider is not malicious? There are some ways to verify that the provider can be trusted:

  • Let a trusted application be the provider. The F-Droid application itself could bundle the provider, keep it updated and provide the stable API. Apps could then hard-code the F-Droid package name and verify its signature. The problem with this approach is that users who build F-Droid themselves or use alternatives like G-Droid could not use the updated libraries.
  • The library could query the Android system for compatible Conscrypt provider apps and include one of them. To make sure that this is secure, it would be possible to only include the provider if it is a system app. Then the F-Droid privileged extension could bundle and provide Conscrypt. Many F-Droid users probably do not use the privileged extension though, so we could still not reach all users.
  • To me, the best solution seems to have a standalone app (like org.fdroid.securityprovider) that provides Conscrypt. This was also discussed on the F-Droid Forum and originally suggested by @bubu. A trusted entity like F-Droid could build the provider and sign it with their keys. Those could then be verified by the calling apps that want to include Conscrypt.

I would love to see some movement in this direction. We should definitely explore the possibilities of a fully open-source security provider app. Unfortunately, I am pretty busy with maintaining AntennaPod. I am therefore not able to maintain the library and installer app. There is a proof-of-concept available on GitHub Gist but it misses security checks. Also, it would probably be good to add some simple ways to prompt users to install the provider on TLS failures. If you are interested in making an open-source provider possible, have a look at the F-Droid Forum.

Some notes:

  • This post was written from an app developer’s perspective. I try to make AntennaPod work best for all users, including those with Android 4.x. From a user’s perspective, you should think about whether you still want to use old Android versions like 4.x. Android 4.4 was released in 2014, which is 6 years ago. Many critical security issues have been fixed since then. Exposing such an old device to the Internet might be a pretty big security risk, independently of the TLS libraries that are included in apps.
  • Before looking into this, I did not know that you can use ClassLoader to execute other app’s code. This is pretty nice and can be used for things like plugins. I would love to see what other developers build with that.