Meetup-Notes

Cloud Native Computing Foundation Bordeaux #2

🕑 Estimated reading time: 8mn

Table of Contents

CNCF News

From GitLabCI to Kubernetes

By Gaëtan Ars, Expert Lead Engineer @ Orange Business Services

With Kubernetes, resources can be shared across the same namespace and rights management exists at every level. To handle connections, the ingress controller is here for load balancing, SSL edge termination and virtual zones. A Kubernetes cluster operator will most likely use Kubeadm to administer their cluster.

What can you achieve by associating GitLab and Kubernetes?

How would you connect a Kubernetes cluster to GitLab?

  1. Create a ServiceAccount for GitLab;
  2. Retrieve the token and certificate;
  3. Configure the Role Based Access Control in your cluster with ClusterRoleBinding where you will bind the cluster-admin role to the ServiceAccount you just created;
  4. Register the cluster in GitLab using the API URL, the token and the certificate. Since GitLab 11.5, GitLab will automatically create a ServiceAccount with the edit role. This ServiceAccount will interact with the cluster during the CIs;
  5. GitLab will propose to deploy some services such as Helm, Tiller, GitLab Runner, Prometheus, NginX Ingress, CertManager, JupyterHub and Knative and add new CI variables: KUBE_URL, KUBE_TOKEN, KUBE_NAMESPACE, KUBE_CA_PEM_FILE;
  6. Write your CI, everything is ready!

Important note: GitLab Community Edition only allows the integration of one cluster. You can still manually integrate your cluster by manipulating the CI variables but you will not have access to the monitoring, the logs, the console an the other features provided by the GitLab integration.

The 12 factors of Kubernetes

By Étienne Coutaud, DevOps consultant @ OCTO Technology - Slides

  1. 1 pod can contain one or multiple containers
    Having multiple containers in a pod can be considered bad practice unless you adopted one of the following patterns:
    • Sidecar: they extend the pod function by adding monitoring or log processing for instance;
    • Ambassador: the actual application is represented by a proxy that could cache expensive computations;
    • Adapter: the application is behind an adapter that will normalize its results.
  2. Use labels everywhere
    The interface exposes more meaningful information and you will be able to manage your resources in a simpler way.

  3. Infrastructure as code leads to versioning!
    Code gets reviewed on many levels through a CI pipeline, why not configuration? You could version and test your Dockerfiles and Kubernetes resources the same way and apply the changes when ready.

  4. Use Services to expose
    Your applications and nodes can change IP. If you need to interconnect multiple applications, it is wiser to use Services rather than IPs. There are five kinds of services depending on your needs:
    • ClusterIP: Kubernetes will allocate an internal local IP for your service. This is the default.
    • NodePort: Kubernetes will allocate a random port to your service, by which it can be accessed from the outside;
    • LoadBalancer (if backed by a Cloud Provider): Will provision a configurable load balancer from your cloud provider for your service;
    • Headless: The coupling of a headless service with Kubernetes is minimal. Through configuration, the service will itself expose its endpoints and manage the registration and discovery;
    • External: Represents an external application as if it was hosted by the cluster Documentation
  5. Use config maps and secrets to manage your configuration
    Config maps can be referenced from the manifests and are mountable. Secrets have to be referenced as base64. Administrators can create a namespace-wide configuration for the resources created within that namespace.

  6. Limits and Requests for resource management
    Avoid at all costs to leave unbounded resources for any pod. The cluster health depends on the behavior of its pods. If you leave a pod unbounded, it can potentially spiral out of control and crash your cluster.
    By using Requests and Limits, Kubernetes will reserve a minimum capacity for your pods and will limit the maximum amount of resources that can be used by your application. Whenever the limit is reached for a pod, it will be killed and restarted. Kubernetes will also use your Requests and Limits to choose the nodes that will serve your application.

  7. Pod lifecycle
    To avoid losing a pod forever whenever it crashes, you can create a ReplicaSet that will keep alive a number of pods that can be defined with a min-max range. The Deployment -> ReplicaSet -> Pod architecture provides teams with rolling updates and an increased resilience.

  8. Probes
    Kubernetes has two sorts of probes for your pods:
    • Liveness: is the pod alive and well? Add a healthcheck endpoint to your application so that Kubernetes can be informed of the state of your application at any time;
    • Readiness: is the pod ready to receive traffic? Add a ping endpoint to your application so that Kubernetes knows when it can route requests to your new pod.
  9. Avoid “latest”
    Depending on your needs, you may want to properly version your application and avoid just publishing on latest. A classic way to organize your releases is the promotion system:
    • Git SHA: use the SHA to identify your feature branch and allow for tests. Do not forget to clean up the images once a feature branch has been promoted or rejected;
    • dev: stable development environment that receives accepted features;
    • release-candidate: nearing the end of a development sprint, you may want to create release candidates for your application for internal reviews by promoting the desired development state;
    • staging: nearing the end of a release cycle, you can provide a staging image for a full review by your teams by promoting the desired release candidate;
    • production, latest, v*: once a staging image has been fully tested and is ready for production, you can release it to the wild. Carefully define your version number, though. Semver is a good way to think about your release versions.
  10. Think stateless
    Unless you need your pods to be stateful, think them stateless so that you will face less scaling issues. Being stateful means that the server keeps information about your session. If your service is autoscaled, your users may end up on different servers and be disconnected frequently.

  11. Volumes and distributed storage systems
    Thanks to PersistentVolumeClaims, Kubernetes can reserve volumes on its own by negotiating with your Cloud Provider. StatefulSets can be useful whenever each pod needs its own PersistentVolumeClaim.

  12. Be 12-factors compliant
    Even though this factor looks self-evident, make sure that your code follows the 12 Factors. By respecting these factors, you will make your life as well as the ones who will monitor and maintain your application easier.

Some take aways: