<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Fatima Silveira on Medium]]></title>
        <description><![CDATA[Stories by Fatima Silveira on Medium]]></description>
        <link>https://medium.com/@mfsilv?source=rss-d7ea4b9845fe------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*C974eIQCY1Fx2XhIWaSpZg.jpeg</url>
            <title>Stories by Fatima Silveira on Medium</title>
            <link>https://medium.com/@mfsilv?source=rss-d7ea4b9845fe------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 06:43:29 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@mfsilv/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Kubernetes for dummies: Deployment auto-scaling]]></title>
            <link>https://itnext.io/kubernetes-for-dummies-deployment-auto-scaling-28ad0f9da1df?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/28ad0f9da1df</guid>
            <category><![CDATA[learning]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[containers]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Wed, 12 Jan 2022 17:00:35 GMT</pubDate>
            <atom:updated>2022-02-22T21:11:32.760Z</atom:updated>
            <content:encoded><![CDATA[<h4>KUBERNETES | CLOUD CONCEPTS</h4><h4>Part 5 — Using Horizontal Pod AutoScaler</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*8uNFXIsxwGCSEcCk" /></figure><p>Welcome back, my fellow Jedi apprentice! Now we have a pretty good grasp on the basics of using the Force. Let’s start making our way into some interesting adjacent concepts. In case you need a refresher, here are the links for what we discussed so far:</p><ul><li><a href="https://bit.ly/fawix-k8s-p1">Part 1 — What is kubernetes after all?</a></li><li><a href="https://bit.ly/fawix-k8s-p2">Part 2 — A Look under the hood</a></li><li><a href="https://bit.ly/fawix-k8s-p3">Part 3 — Life of a Pod</a></li><li><a href="https://bit.ly/fawix-k8s-p4">Part 4 — Deployments and Services</a></li></ul><p>Now we can start exploring how you can use deployments to implement cool stuff like auto-scaling, auto-healing and graceful degradation; this part will build upon the concepts we learned in part 4. This post is all about auto-scaling using deployments!</p><h3>Auto-scaling #WTF</h3><p>This is a simple concept: your workloads can scale up or down according to the load in the cluster or workload resources.</p><p>By scale up, I literally mean deploying new pods and scaling down destroying them. To make this possible, Kubernetes has an Object called “Horizontal Pod AutoScaler” (aka HPA) that must be referencing a Deployment with a ReplicaSet (part 4). Fortunately, once you define HPA in the deployment the ReplicaSet becomes implied. Also, there is an HPA controller; it monitors resources and changes the replicas value in the ReplicaSet object. The HPA object tells k8s that we want to auto-scale the deployment so the controller knows it should monitor the Pod and its resources ( Aha! “building blocks” 😉 ).</p><p>Now, that is basically how scaling works in k8s, but remember that we need a reference point… the workload scales in reference to something. That something is a Pod Resource. The most basic Pod Resources are CPU and Memory. The cluster automatically monitors their utilization and keeps the related Pod Resource objects up to date; It does this using a Metric Server that aggregates metrics across the nodes by querying the kubelet of each node. The diagram below is for illustrative purposes — but gives you a good sense of how this fits into the picture.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qP2ztGvHIgNQn9YG" /></figure><p>Also, resources can be other parameters too. Anything that can be imported as a Pod Resource can be used as a scaling reference. Kubernetes has a few mechanisms that allow this. Most commonly “Custom metrics” in the Metric Server. It’s also possible to use an object called “Extended Resources”. This effectively allows you to declare resources from outside the cluster that might affect your workload scale (useful for event-driven architecture). Let me know if you want a post on this specifically, we can venture further into it!</p><h3>Avoid Noise Neighbours #BestPractice</h3><p>A quick thing we should discuss, yes, neighbours! Essentially, noise neighbours are Pods that consume too many resources to the detriment of other pods in the cluster. So, it’s a good practice to define at least Memory and CPU consumption for your pods (even if you are not using HPA) to avoid the risk of overcrowding your node. Another benefit of doing this is that kubelet will keep track of CPU and Memory utilization in the node, so the control plane can select nodes with enough capacity available for the pod. Also, when you define a minimum and maximum it allows the pod to start warm by having a dedicated amount of resources from the beginning and you prevent rogue workloads from consuming all available resources in case of issues or compromised containers.</p><p>Ideally, you should measure your workload resource consumption profile for one Pod. A load test is the best tool to help you understand that. Simply monitor CPU and Memory usage of the Pod while ensuring that the application remains stable and within your reliability parameters (latency, availability, error rate, etc).</p><p>There are a few things you should consider; think of this exercise as a Gaussian curve, what you select depends on your traffic pattern.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*UxB0qkmVG86wc_NK" /></figure><p>The graphic above means to illustrate this:</p><ul><li>Minimum load (Yellow): the lowest load you get (this can be idle or with trickle traffic)</li><li>Nominal load (Blue): a chosen percentile in a cycle that represents the most common load for your application (think 99th or 95th in a day for example)</li><li>Peak load (Red): maximum load the application can reliably serve.</li></ul><p>You want to configure your Pod Resources to request either your nominal or minimum load at startup and scale-up before reaching the peak load. Which one you pick depends on where your application spends the most time. Of course, this changes over time so make sure to revisit this frequently. Major versions or traffic pattern changes are good indicators that your values need a review.</p><p>Now you ask me, this is so much work… can’t I just guesstimate? Well, young Jedi apprentice… no one will stop you! However, be aware of what it means. You may end up scaling too soon or too late, or you may also block more resources than you need or less than you need. So, measuring is better (even if it’s a partial measurement to allow you to make an informed guesstimate approximation). If you can, eliminate the guesswork!!</p><p>Ok, back to our deployment! Let’s start by defining our resources in the deployment. Remember our friendly <a href="https://gist.github.com/fawix/8e7b3ddf52db83eab46659b828828afb">NGINX deployment</a> from part 4? Here is what that object looks like with resources defined for memory and CPU:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/32ea6d46ee7d8d1846bd1bdc1183b66c/href">https://medium.com/media/32ea6d46ee7d8d1846bd1bdc1183b66c/href</a></iframe><p>As you can see we no longer need to tell the deployment the number of replicas we need (HPA will take care of that), so we remove spec.replicas. We also set the spec.containers.resources fields with the limits of how much CPU and Memory we want. This is where you would reference a custom metric as well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/620/0*SJ-4r4zShzpWITVd.jpg" /><figcaption>Credit: imgflip.com</figcaption></figure><p>Sidebar on reading the values of CPU and Memory. They are rather confusing at first sight ! (</p><ul><li>Memory — measured in bytes, it can be represented using <em>binary prefixes</em> (Ki, Mi, Gi) or <em>decimal prefixes</em> (K, M, G).</li><li>CPU — measured in CPU units (which depends on where you are running), for bare-metal it’s 1 hyperthread, but in GCP it’s 1 Core. This metric allows fractions so we can actually request half a CPU (0.5 — read this as 50%). Most workloads won’t actually occupy that much, so kubernetes has the “m” prefix that indicates milli (in <em>decimal prefixes</em>) — so requesting 200m is equivalent to requesting 0.2 units of the CPU (a.k.a.: 20% CPU utilization).</li></ul><p>I highly recommend you choose either binary or decimal prefixes. Maintain consistency across all your deployment files, especially for large scale workloads.</p><p>I hope this was useful ! )</p><p>Now adding HPA is simple…. kind of. The HPA object is still evolving. Pay special attention to the apiVersion you choose (autoscaling/v1 vs autoscaling/v2beta2). On the v2 you can scale in multiple metrics while v1 can’t. Here we are using the v2 flavour.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/caa44dd41d1ed73ff5fc5432b26b82c1/href">https://medium.com/media/caa44dd41d1ed73ff5fc5432b26b82c1/href</a></iframe><p>For auto-scaling purposes, we define the Pod resources. We also define the consumption threshold in which the upscaling should happen. The HPA controller will query the resources every 15s (default) and make adjustments based on the thresholds vs actual consumption. As you can see on the object above that is the spec.metrics[].resource.target field; the way it links back to the deployment is via the spec.scaleTargetRef field.</p><p>Let’s see this action — grab the YAML above and follow along! By now you are very familiar with kubectl apply so I’ll skip that step. Let’s focus on the cool stuff!</p><p>Time to inspect the deployment! You can see the resource parameters and the replica set; notice it starts with a single pod.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*qSRjJJAlqEk9UKbP" /></figure><p>Let’s inspect the actual HPA object, notice the metrics section:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KGUM4bvFU0MHpqJU" /></figure><p>As you can see, it references our nginx-deployment and the current number of pods deployed is one. Now, as a quick test, we can generate some load and see the auto-scaling in action:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*2GSgEEXzWZ09tHjj" /></figure><p>Several things go into making an auto-scaling configuration. However, start with what you have. If you can’t do a forecast or don’t have all the required data (new applications I see you), it should not prevent you from starting with good enough numbers. You can fine-tune it over time.</p><p>This is a very cool concept that can be explored further, I recommend spending some time playing with this configuration; as an exercise try to forecast what is the TPS you’ll hit 3, 5 and 10 pods with and see if you got it right. Notice the period it takes to scale down after the load is gone? How would that behave in different traffic patterns?</p><p>As usual, if you don’t have your cluster yet <a href="https://www.katacoda.com/courses/kubernetes/playground">Katacoda Playground</a> is still an option. You can also use the <a href="https://cloud.google.com/free">free tier and credits on GCP</a> to create a GKE cluster that you can play with!</p><p>In this post, we reviewed how to implement auto-scaling with deployments, in the next post we will look at auto-healing, graceful degradation which enables us to create more resilient workloads in kubernetes.</p><p>Do you like the series so far? Let me know! Also, feel free to follow me on<a href="https://twitter.com/fawix"> Twitter (@fawix)</a> or<a href="https://www.linkedin.com/in/fatimasilv/"> LinkedIn</a> so you won’t miss the update! May the Containers be with you!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=28ad0f9da1df" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/kubernetes-for-dummies-deployment-auto-scaling-28ad0f9da1df">Kubernetes for dummies: Deployment auto-scaling</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kubernetes for dummies: deployments and services]]></title>
            <link>https://itnext.io/kubernetes-for-dummies-deployments-and-services-7403f30d30ba?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/7403f30d30ba</guid>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[cloud]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Sat, 04 Dec 2021 02:01:29 GMT</pubDate>
            <atom:updated>2022-02-22T19:23:09.037Z</atom:updated>
            <content:encoded><![CDATA[<h4>KUBERNETES | CLOUD CONCEPTS</h4><h4>Part 4 — Making Pods more useful</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*29KQ5Si1w9Z90uKa" /></figure><p>Welcome back, young Padawan! Now that you have a pretty good idea of the inner workings of the cluster and how a Pod works, let’s check how to use those things more effectively.</p><p>As we saw in the <a href="https://bit.ly/fawix-k8s-p3">last post</a>, a Pod provides our basic building block, but it’s not necessarily production-friendly. We can only access the application from inside the Pod. It would be really inconvenient and risky to expose it to the internet that way. Besides, it’s not permanent. If a Pod dies, it stays dead. There are different ways to solve those two items. We’ll cover the basics and add as we go.</p><p>Let’s discover Service and Deployment objects 😎</p><h3>Deployment #WTF</h3><p>Deployment adds several goodies to Pods and enables several important adjacent use-cases. In essence, deployments allow k8s to have <strong>desired state rules</strong> on a Pod or group of Pods. These are things like version rollout, rollback, pause at a basic level.</p><p>Kubernetes Deployment also makes use of other k8s objects to further enhance functionality. One super common construct is the “ReplicaSet”, which defines how many copies of the same Pod should be created by this deployment. A copy of a Pod is called a replica. If we say a deployment contains 3 replicas it means it will be running 3 copies of the same Pod. This means that, at any given time, k8s will ensure that the desired amount of Pods are running as part of this deployment! If a pod dies, k8s will start a new one to replace it and match our desired state.</p><p>Remember our <a href="https://gist.github.com/fawix/d50d9bb3510f41e2c3f347a1e44ccba9#file-k8s_pod_example-yaml">nginx Pod</a>? What if we wanted to make it a Deployment so in case our Pod dies k8s restarts it automatically?</p><p>Here is what that object will look like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ad73d5d78b8f70aaee6be8c198eeeea7/href">https://medium.com/media/ad73d5d78b8f70aaee6be8c198eeeea7/href</a></iframe><p>Notice that the object kind is now Deployment. Also, see the spec.template? It contains the definition of the actual Pod. If you compare that with the Pod we created in part 3 you’ll see that it’s the same. Also, take special note of the spec.replicas field. This is part of the ReplicaSet and defines how many copies we want.</p><p>Remember we talked about labels in part 3? This is one of its applications. The ReplicaSet Controller selects all the Pods which matches the spec.selector.matchLabels and compare them to the desired state. Those labels should match the information on the actual Pod labels in spec.template.metadata.labels. This concept is used in several places in k8s and groups related objects to build the functionality around them.</p><p>Labels are fundamental to organizing large deployments. You can also perform kubectl operations filtering via labels making this construct really powerful. These are also called selector labels and, sometimes, filters (although less common).</p><p>Let’s see this in action:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/846/0*7uCUI_aSIO0k0XDw" /></figure><p>Ok, now that we solved the permanency problem, let’s talk about accessing the application.</p><h3>Services #WTF</h3><p>There are multiple ways to expose your application using k8s. Services are one of the simple ways we can do it.</p><p>Think of the Service object as a networking abstraction. It provides a way to expose an application running in one or more pods via a single IP. Remember Pods have their own IP. For example, if your deployment has 3 replicas, you don’t want to manage that in your application; you need a consolidated way to access it. Services object will take care of handling that bit.</p><p>Here is what a Service object looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/396eba4a1bf0d2b22d93e643a03e0bf3/href">https://medium.com/media/396eba4a1bf0d2b22d93e643a03e0bf3/href</a></iframe><p>One handy feature of services is that it can map any incoming port to a target port on the container as you can see in the example above. The incoming traffic (into the Service) is on spec.ports.port and traffic going from the service to the container is mapped in the spec.ports.targetPort.</p><p>At a lower level, a service contains a collection of endpoints. An endpoint is a simple object with the IP of a Pod. Remember labels? That is what k8s uses to group Endpoints as part of a service. Normally, you don’t need to worry about creating endpoints since that is done behind the scene, but you can actually see it in action:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/851/0*Mft6ghT0Ooum5V6-" /></figure><p>With the labels, k8s will automatically create the endpoints. The endpoint object also allows you to point services to IPs outside the cluster; by manually provisioning the endpoint object. This is useful especially for testing environments or external dependencies that are not deployed in the cluster but needs to be accessed by the pods.</p><p>The service object will provide us with an IP and a DNS entry on the cluster DNS server to facilitate service-to-service communications.</p><p>Speaking of DNS… kube-dns is a component that is often deployed in the cluster. Although not a mandatory nor a core component, it’s essential to clusters running multiple services. It can be replaced with other DNS services if desired. A popular alternative is coreDNS. It provides name resolution within the cluster, including services domain names.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/818/0*nPornwI1zYG606ud" /></figure><p>There are many types of services, each has things they are better for:</p><ul><li><strong>NodePort:</strong> this actually blocks a specific port in the node and lets traffic reach the service through the node IP directly.</li><li><strong>ClusterIP:</strong> this lets the cluster assign an IP to the service from its services IP pool (more about it in a future post)</li><li><strong>LoadBalancer:</strong> this will actually use the cloud controller manager to create a load balancer on the infrastructure provided by the cloud provider (assuming you are running in a hyperscaler environment).</li></ul><p>Let’s put it all together!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/846/0*q8lHHL5uefaae-Pk" /></figure><p>As you can see, we can access the workload from outside the cluster. The Service object is quite simple and does not allow for complex traffic rules. There are other objects that we can use for that purpose. A popular option is the Ingress object. As the name implies, it offers desired state rules around ingress traffic and routes incoming traffic into the deployment/service. We will talk more about it in a later post.</p><p>We just scratched the surface! There is a lot more to explore; grab the sample deployment and service objects from this blog post and fire up your Kubernetes Cluster! If you still don’t have an installation, feel free to use <a href="https://www.katacoda.com/courses/kubernetes/playground">O’Reilly’s Katacoda interactive playground</a>. Be curious! Change the service type. How does it behave? Change the desired number of replicas of an existing deployment. Modify the NGINX welcome page and see if you can route into two different versions of the application. Use the force, my fellow Jedi apprentice!</p><p>Now we have a much more robust workload, but we can still make it a lot better! In the <a href="https://bit.ly/fawix-k8s-pt5">next post</a>, we will look at some of the key use-cases this enables. We will look at adjacent concepts, like auto-healing, auto-scaling; and how they play a part in creating resilient workloads in kubernetes.</p><p>Follow me on<a href="https://twitter.com/fawix"> Twitter (@fawix)</a> or<a href="https://www.linkedin.com/in/fatimasilv/"> LinkedIn</a> so you won’t miss the update! May the Containers be with you!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7403f30d30ba" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/kubernetes-for-dummies-deployments-and-services-7403f30d30ba">Kubernetes for dummies: deployments and services</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kubernetes for dummies: Life of a Pod]]></title>
            <link>https://itnext.io/kubernetes-for-dummies-life-of-a-pod-fc8158e27aa?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/fc8158e27aa</guid>
            <category><![CDATA[kubernetes-cluster]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Wed, 17 Nov 2021 14:19:08 GMT</pubDate>
            <atom:updated>2022-02-22T19:21:53.562Z</atom:updated>
            <content:encoded><![CDATA[<h4>KUBERNETES | CLOUD CONCEPTS</h4><h4>Part 3 — Pods, and that other thing?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jdBWDI2n38l5YT0pm3WMsg.png" /></figure><p>Welcome back, young Padawan! You now understand the components in a k8s cluster (<a href="http://bit.ly/fawix-k8s-p2">part 2</a>). Today we take a look at one of our most basic constructs: PODs. We will see how they are involved when we are running our applications.</p><h3>Pod #WTF</h3><p>Pods are one of the most fundamental building blocks within Kubernetes. They are the smallest deployable object. Their goal is to provide a runtime environment for your containers. Although Pods need other Objects to make them truly useful, they are the piece that represents your application within Kubernetes. Several other Objects will build upon the capabilities offered by the Pod. Today we will focus on how they run our workloads. In the next post, we will look at those other objects that interact with PODs to make them more robust and versatile.</p><p>Maybe you were expecting me to say that the smallest Kubernetes object is the container? Not so, young Padawan! Every running container in a k8s cluster is inside a Pod. Effectively you will never have containers running by themselves.</p><p>The Pod provides a running environment for the containers, including networking and storage. A Pod can have multiple containers if necessary. Containers in the same Pod are tightly coupled and share resources (networking and storage, security rules, etc. ).</p><p>Conceptually, a Pod looks like the following:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*GYlS2shkBs8-yvk_" /></figure><p>There is only one IP assigned to a Pod, regardless of the number of containers it has. Meaning, inside a Pod, the containers share the same network namespace (IP and Ports). The consequence is that containers within a Pod can communicate through localhost (127.0.0.1). Optionally a Pod can also specify one or more storage methods, referred to as Volumes. All containers in the Pod can access mounted volumes. Pods can share storage as well, but that is for another post.</p><p>Fun fact, the name Pod comes from the collective for whales. It alludes to the containers inside it, which predominantly ran with dockerd (Docker logo is a whale!).</p><p>Of course, now we’ll look at what an actual object looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ba8701f10930dd47723d617f13a87b5/href">https://medium.com/media/1ba8701f10930dd47723d617f13a87b5/href</a></iframe><p>These are the mandatory fields required to stand up a Pod. As we advance, we will look at other Objects that use the Pods to build more capabilities and then expand on other fields.</p><p>One important thing to notice above is the field spec.containers, which is an array of containers that you can define. The image field is the name of the actual container with its repository (when omitted, it defaults to DockerHub) and a tag. Container tagging is simply a way to manage your versions and releases. With this, you can target a specific version of the container. In the example above, we’re using the <a href="https://hub.docker.com/layers/nginx/library/nginx/stable-alpine/images/sha256-415f060bbd6fbabb39d19b604247204b5429f340fa571bfdd12f724dbff2839a?context=explore">nginx container with the stable-alpine tag</a> in DockerHub (because we omitted the repository bit).</p><h3>Not all containers are created equal</h3><p>When we talk about containers, the first thing that comes to mind is the containers running our applications. Typically a long-running process that will stay up until we kill it or something goes wrong. However, I quickly want to mention two other types of container in a Pod and what you should use them for:</p><p><strong>Init Containers:</strong> as the name suggests, init containers are good for initialization and setup. They run before the regular containers in the pod get started. Unlike the regular containers, these should always run to completion and exit successfully or the Pod will enter the Failed state (more on that below).</p><p><strong>Ephemeral Containers:</strong> it’s a fairly new (alpha in 1.22) type of container. It makes no guarantees for resources or execution, and they are never automatically restarted (don’t use these to build applications). These are useful for troubleshooting and interactive shells for short-lived operations.</p><p>For consistency, anytime I talk about “containers” that is your regular workload container. I’ll specifically call out the other two types when we are talking about them.</p><h3>Life of a Pod</h3><p>As you can see, Pods provides that fundamental piece we need to run our containers. Now let us look at how a Pod comes to life and eventually dies: The pod Lifecycle.</p><p>It’s simple to conceptualize at a high level:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*_IEYpJCoURZm_pkO" /></figure><p>First, we create the Pod. In this stage, Kubernetes fetches the container from the registry. Then k8s ask a node to run the Pod; which causes the creation of necessary constructs around networking and storage. Then it runs the container in that space. If fetching the container fails, the Pod will assume the “UNKNOWN” state.</p><p>The process in the container will be in the foreground until completion or until an external command terminates it. This is the Running state. If the Pod fails the state is set to FAILED. If it runs successfully, it assumes the status of TERMINATED.</p><p>Ok, let’s create a POD! Grab that example object above and save it as pod.yaml if you want to follow along, young Padawan! PS: if you don’t have a k8s installation yet, feel free to use <a href="https://www.katacoda.com/courses/kubernetes/playground">O’Reilly’s Katacoda interactive playground</a>.</p><p>For this, we’ll simply run kubectl create -f pod.yaml</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pDmR86rrOwiBYWEH" /></figure><p>Remember the components we described in part two? You can already yield the force, young Padawan. What do you think is happening under the hood? Think a bit about it before you continue reading for maximum experience points!</p><p>Ok, ready!?<br> <br>Let’s check the details of what is happening under the hood when we ran that command:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*EiGASjd_UXLJJeL8" /></figure><ol><li>The user runs a kubectl create command to create the object</li><li>kubectl makes a call to the API Server to create the object</li><li>API Server saves the Object in etcd</li><li>Scheduler detects a new Pod was created and is not assigned to a node</li><li>The scheduler then updates the Pod object with the chosen node. It takes into account several constraints to define which node gets the Pod. These are labels and taints that define affinity (run groups of pods together) or anti-affinity (avoid scheduling pods together) rules.</li><li>kube-controller-manager then detects that the Pod desired state doesn’t match the current state and makes the necessary calls to the API Server (it’s a bi-directional flow); at this point, the correct controller will respond to do these changes</li><li>Which in turn triggers an API call from the API Server to kubelet, in the selected node, to create the actual Pod</li><li>As part of setting up the Pod, networking kube-proxy does the required changes to the OS via the package filtering layer</li></ol><p>With that, your pod is created! Any object creation works like this involving different controllers as needed.</p><p>At this point, you can only access the workload via local networking. This means, you need to be connected to the Pod:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*XNLwMfnLvUKBbsla" /></figure><p>If you created our Pod, you should spend some time playing with it. Check what happens when you run kubectl describe pod nginx, or try sending a SIGKILL to the nginx process from inside the Pod. See what happens! Be curious!</p><p>Now, you may be thinking: I can’t run my apps with localhost only access!? Correct you are! This is less than ideal for workloads, and we will see how to solve that in part 4 using services. However, at this moment, you effectively have your workload running in kubernetes! One thing to be aware of, once the Pod gets killed, or runs into a failure, it will simply sit in the terminated or failed state and will not be restarted. That is something deployments solves, and we will see that in the <a href="https://bit.ly/fawix-k8s-p4">next post</a>.</p><p>Follow me on<a href="https://twitter.com/fawix"> Twitter (@fawix)</a> or<a href="https://www.linkedin.com/in/fatimasilv/"> LinkedIn</a> so you won’t miss the update! May the Containers be with you!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fc8158e27aa" width="1" height="1" alt=""><hr><p><a href="https://itnext.io/kubernetes-for-dummies-life-of-a-pod-fc8158e27aa">Kubernetes for dummies: Life of a Pod</a> was originally published in <a href="https://itnext.io/">ITNEXT</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kubernetes for dummies: the cluster]]></title>
            <link>https://medium.com/@mfsilv/kubernetes-for-dummies-the-cluster-7cf6a7b5532?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/7cf6a7b5532</guid>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[kubernetes]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Tue, 02 Nov 2021 17:32:30 GMT</pubDate>
            <atom:updated>2022-02-22T19:20:03.794Z</atom:updated>
            <content:encoded><![CDATA[<h4>KUBERNETES | CLOUD CONCEPTS</h4><h4>Part 2 — A look under the hood</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*BmiZd-b1jQ_tSuOG" /></figure><p>As promised today we’ll be deep-diving into the architecture of a Kubernetes cluster and see how it all comes together! This is foundational to understanding how k8s runs workloads.</p><p>Let’s look inside the Control Plane first! As we <a href="https://medium.com/@mfsilv/kubernetes-a-gentle-introduction-9d23de7f00e0?source=friends_link&amp;sk=9c67d80b8d121d04fcd7c023054fb42f">already established</a> this is the brain of our cluster. A robust cluster will have multiple Control Plane nodes, preferably in different geographical locations. This is usually taken care of by the cloud provider if you are running in the cloud. For example, In GCP a GKE regional cluster has three control plane nodes in distinct zones to guarantee high availability. The Control Plane is also the entry point when “<em>Interact with the cluster you have”</em> as foretold by the Jedi Master.</p><h3>Control Plane — Under the Hood</h3><p>Let’s peek inside! The control plane runs five major components as shown in the diagram below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*NS9EDteJgC5JtYs1" /><figcaption>Control Plane</figcaption></figure><p><strong>API Server:</strong> is a process running the Kubernetes API, which follows the REST design pattern. It’s well thought out and implemented. It lets you query and modify the state of objects within Kubernetes. Think of objects as things with a state (normally); entities such as Pods, Nodes, etc (more below). The user documentation is <a href="https://kubernetes.io/docs/reference/kubernetes-api/">here</a> and is also fully <a href="https://github.com/kubernetes/kubernetes/blob/master/api/openapi-spec/swagger.json">documented using OpenAPI</a>! <em>~The source, Luke!~</em></p><p><strong>Controller Manager:</strong> several things within Kubernetes require comparing the current state with the desired state. If there are any deviations the controller manager will execute a set of actions to correct them. Kubernetes employs the control-loop pattern for various “Controller” implementations (more below). Essentially, this means that the process is running an infinite loop and executing the checks. Pretty much everything in Kubernetes that requires an action is a controller. Kubernetes also supports custom controllers, so you could even write your own if you need to. Important examples of controllers are the Deployment Controller, Job Controller and others.</p><p><strong>Cloud Controller Manager: </strong>based on the above, you can pretty much guess this one. It’s a controller manager for cloud provider-specific implementations. There are actions in Kubernetes that depend on the environment k8s is running in. For example, say you want to expose your application to the internet. Typically, this requires a Load Balancer which is very platform-dependent and will change whether you are running on GCP, AWS or Azure. Each cloud provider that wants to enable Kubernetes to consume their cloud resources has to provide a basic set of controllers that teach Kubernetes how to use their resources.</p><p><strong>Scheduler:</strong> also called kube-scheduler and, it has a super important duty: assign Pods to worker nodes. More about it when we talk about Pods, but essentially this is the piece that will guarantee your pods have a home.</p><p><strong>etcd:</strong> the cluster storage/database — this is where Kubernetes objects are stored. etcd is a distributed key-value store that prioritizes consistency and availability (from CAP theorem). Initially designed by the CoreOS team and then adopted into the broader community, and is currently part of the CNCF landscape.</p><p>These five components enable k8s to interact with the system resources and provide a solid platform for your containers. We will explore the new terms and concepts in future posts — for now, focus on understanding each component and its role within the Control Plane.</p><h3>Kubernetes Objects #WTF</h3><p>Kubernetes represents its state using objects. It usually describes entities within the cluster (like the worker nodes, pods, etc). Objects contain the entity’s basic information and its <strong>desired state</strong>. There are several “kinds” of objects and, most objects have a basic set of keys that are always present. That help us Jedi apprentices to navigate the ways of the Containers more easily!</p><p>We can interact with the cluster using a handy CLI called kubectl. It mainly talks to the API Server and allows us to do several tasks within the cluster. The API Server accepts JSON only, but kubectl also understands YAML. Ideally, it allows for a simplified human interface (YMMV).</p><p>Here is what a basic structure looks like in YAML:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cc647e210c52443eac70a72d6226aa7e/href">https://medium.com/media/cc647e210c52443eac70a72d6226aa7e/href</a></iframe><p>The structure above is pretty much self-explanatory and, we will expand more on these concepts as we advance. The one thing I want to mention is the difference between labels and annotations. Labels are used for organisation and grouping. Annotations add functionality to the object. Typically the latter is provided by applications or tools deployed in the cluster. If you are familiar with the idea of decoration functions this is a very similar concept.</p><h3>Control Loop #WTF</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/0*Zu6in_g44wJi2wF_" /><figcaption>Credit: imgflip.com</figcaption></figure><p>I like to think of Kubernetes as a framework with a set of actions needed to run workloads in containers. When we create an object, we are using that framework to achieve that goal. For example, we can add a worker node in the cluster to run our containers.</p><p>Kubernetes will then use the information about the entity to verify its <strong>current state </strong>(status)<strong> </strong>against the<strong> desired state</strong> (spec) and take corrective action if needed. Something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/948/0*5-7OHlLe75Owh2Al" /><figcaption>Control Loop</figcaption></figure><p>This construct is called a control loop and is a fundamental principle in how kubernetes operate.</p><h3>Node — Under the Hood</h3><p>Now we need a place to run our applications and workloads — that is the main job of the Worker Nodes. It isn’t a good idea to run workloads in the control plane node. In fact, k8s prevents that from happening by default using a mechanism called taint. Fear not padawan, we will explore that later. For now, this means that we need worker nodes in the cluster to run your application.</p><p>A worker node is essentially a VM (compute) that has two Kubernetes processes (kubelet and kube-proxy), and a container runtime (see part 1). Before anything can happen, the node has to join the cluster so the control plane knows it can run your workloads. Kubernetes control plane will then manage it and give it instructions using the Kubernetes processes (such as running a workload).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ieSGRCnSk6EHlYTo" /><figcaption>The worker node</figcaption></figure><p>When a node joins the cluster (kubelet says hi to the API Server) their state is tracked by an object that represents the node. The Nodes objects look a bit like the below:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/290b9ae0a2c299d84aecb92892e50847/href">https://medium.com/media/290b9ae0a2c299d84aecb92892e50847/href</a></iframe><p>I redacted values for readability, but you get the idea. All the metadata regarding the node and its health is in that object.</p><p>Typically new nodes will self-register with the cluster. This communication happens between kubelet in the node and the API Server in the control plane. You also have the option to register nodes manually if necessary, which you might need to do when you are creating your cluster outside of cloud providers. A neat utility for that purpose is the <a href="https://github.com/kubernetes/kubeadm">kubeadm</a>. It facilitates the creation and exchange of bootstrap tokens, used by the API Server to know that the call comes from a legit node trying to join the cluster (oversimplification). <a href="https://twitter.com/fawix">Let me know</a> if you are interested in a deep dive into the actual bootstrap process!</p><p>Using kubectl we can ask the cluster for the state of our nodes. We can do some basic manipulations like drain traffic from a node, make it unschedulable (so scheduler won’t assign workloads to it), get its details etc. Here is what listing the nodes in a cluster looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/942/0*EekkoL_BMuSAhdbP" /></figure><p>The more you know… the more there is to learn!</p><p>Want to get some hands-on-keyboard time? There are two really easy ways you can get started:</p><ol><li>Use the free tier and credits on GCP and create a GKE cluster that you can play with: <a href="https://cloud.google.com/free">https://cloud.google.com/free</a></li><li>Play with the <a href="https://www.katacoda.com/courses/kubernetes">O’Reilly Katacoda</a> platform.</li></ol><p>A benefit of option 1 is that you can re-use the same cluster to follow along on future posts. If you choose option 2, I recommend checking out the <a href="https://www.katacoda.com/courses/kubernetes/getting-started-with-kubeadm">“Getting Started with Kubeadm”</a> course. If you want something faster check out <a href="https://www.katacoda.com/courses/kubernetes/launch-single-node-cluster">“Launch a Single Node with Minikube”</a> instead. Spend some time querying the nodes and checking its spec and status. Run a kubectl drain &lt;node name&gt; and see how it’s reflected on the node details. Be curious!</p><p>So now you know the inner pieces of a cluster, but how does it work together? The <a href="https://bit.ly/fawix-k8s-p3">next post</a> will deploy a very simple workload to understand that. We will check what a pod consists of, its lifecycle, how it relates to containers and all that good stuff. Follow me on<a href="https://twitter.com/fawix"> Twitter (@fawix)</a> or<a href="https://www.linkedin.com/in/fatimasilv/"> LinkedIn</a> so you won’t miss the update! May the Containers be with you!</p><p>PS: Optional hands-on time coming up in next post!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7cf6a7b5532" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Kubernetes: a gentle introduction]]></title>
            <link>https://medium.com/@mfsilv/kubernetes-a-gentle-introduction-9d23de7f00e0?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/9d23de7f00e0</guid>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[kubernetes]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Sun, 17 Oct 2021 01:09:43 GMT</pubDate>
            <atom:updated>2022-02-22T19:18:48.117Z</atom:updated>
            <content:encoded><![CDATA[<h4>kubernetes | cloud concepts</h4><h3>Kubernetes for dummies: introduction</h3><h4>Part 1 — What is kubernetes after all?</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*58POF3bGS9YsSgjs1l8zIw.png" /></figure><p>Cheers to another successful Kubecon! As I celebrated how far this community has come, I started thinking about when I first met Mr k8s (Kubernetes).</p><p>I have been playing with Kubernetes for a while (since 2016) — minikube was in its baby steps. Back then and there weren’t a lot of good resources out there. Today learners are in a much better place with several good resources at hand — even so, I realized that we still have things we could improve after giving a few talks last year.</p><p>Fear not, young padawan! With this blog series, I am to give you enough information to start wielding the force. So you can make your way to a Jedi Master by deepening your understanding of the unseen. (Disclaimer: as a fellow disciple, I will share what I know).</p><p>Here we will start from zero. In this series, I plan to touch on key concepts for understanding Kubernetes. We will also talk about some of the adjacent technologies and patterns. First, let’s talk about what Kubernetes is and what it’s not.</p><p>Kubernetes is:</p><ul><li>Platform (or as people like to say: “it’s an Orchestration Layer”)</li><li>Distributed system framework (when done right)</li><li>Extensible &amp; Resilient</li><li>Declarative</li><li><a href="https://github.com/kubernetes/kubernetes">Open Source</a></li></ul><p>Kubernetes is not:</p><ul><li>Simple ( … goes without swaying … *pun intended*)</li><li>Hypervisor (but it will use them)</li><li>Containers (it allows you to run them)</li></ul><p>Also, note that there are several cool things that Kubernetes enables you to do. For example, when combined with the correct adjacent tools and processes using canary releases, auto-scaling, auto-healing, becomes possible. We will talk about these in future posts.</p><p>In the realm of IaaS, PaaS, SaaS, Kubernetes classifies as a hybrid. This is because when you are using Kubernetes from hyperscalers (aka “the cloud”) there are some responsibilities that fall under the cloud provider (infrastructure) and others that fall under the customer (workloads). Running a Kubernetes cluster well is difficult since it’s a complex platform with security and operational concerns. If there is interest to explore this topic further let <a href="https://twitter.com/fawix">me know</a>.</p><h3>Containers #WTF</h3><p>We can’t talk about Kubernetes without talking about containers. Back in the day, we used to run stuff on servers directly. You usually installed the Operating System (OS) then added your libraries and your software et voila. Today we call that running your applications on bare-metal. Sometimes the business needed to cut costs, so multiple applications had to share the same server — wasn’t pretty.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/742/0*IF8orwUJw3XphBbC" /></figure><p>Applications would often clash and compete for resources, to solve that problem (among other things) someone thought about sharing the hardware but enforcing isolation with multiple operating systems. Thus hypervisors became a thing giving rise to virtual machines. Further down the road, we ran into dependency management issues. “But it runs on my machine” was the slogan Docker used to come out into the world making containers more mainstream. These would share the kernel but package their dependencies and application runtime creating a little <em>~container~</em> inside the machine. These can be deployed in a VM or Bare-metal, the container won’t know the difference.</p><p>Alas, sometimes a picture is worth a thousand words:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/767/0*5qg0q6TehDT9JYcG" /></figure><p>Containers use Linux features such as namespaces and cgroups to achieve a certain level of separation in compute, storage and network and to limit resource usage. To run a container you need to build them as defined by the <a href="https://opencontainers.org/">OCI Specification</a>. Then you need a container runtime — this is where dockerd and containerd fit into the picture.</p><p>When you build the containers you have to tell the packaging software what to include and any configurations to perform. Normally that is done via a Dockerfile and the image utility that can package and push it to a registry — recently alternatives such as buildpacks are also available but Dockerfiles remain the most widely used option. A Registry is a sort of online catalogue for containers like DockerHub.</p><p>After your container is packaged and ready to roll Kubernetes get into the scene.</p><h3>Microservices #WTF</h3><p>At the same time that this was all happening with the way we run our applications, people started realizing that separations of concerns are a great thing to have! Heck, in 2008 I was designing systems that would be considered “microservices”, however that wasn’t a term back then.</p><p>Conceptually both Monoliths and Microservices are valid systems design patterns and both have their place with pros/cons. The Monolith’s served the bare-metal / VM era well since it was all packaged as a unit and meant to run in the same machine. Microservices on the other hand segment all the logical services into actual packages achieving a certain degree of separation of concerns which serves the container era pretty well. Nonetheless, don’t be fooled, everything can be misused — as monoliths have been historically abused so can microservices… on the other hand microservices solve many of the monoliths issues, but it comes with its own bundle of challenges. Remember, both patterns are equally valid but we will focus on Microservices here.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PQZPOQLEGFcuvAPl" /></figure><p>One such challenge is how do you efficiently and reliably run several containers in a large-scale production environment? Things like resiliency, observability, upgradability are top concerns. Those are the problems Kubernetes set out to solve.</p><h3>Kubernetes #WTF</h3><p>If you are thinking of Kubernetes (or k8s for short) it’s likely because you want to provide a production-grade runtime for your containers as we just talked about above. To simplify maintenance and operational responsibilities, etc.</p><p>Kubernetes will take care of the shared infrastructure for your containers. For a very high-level view think of a k8s cluster as composed of control plane nodes and worker nodes. For high availability, the control plane runs on multiple nodes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2VA16PertCOD0f4ZQxMxqA.png" /><figcaption>High level view of k8s cluster</figcaption></figure><p>A control plane is the brain of the cluster and it will manage the worker nodes accordingly; there are key components within the control plane that are responsible for different aspects of the lifecycle of a node and we will talk more about those in a future post.</p><p>The nodes are typically responsible for running the workloads and there are several constructs around a container to enable Kubernetes to run it. One such construct is a POD which we will deep dive into soon.</p><p>Stay tuned for the <a href="https://bit.ly/fawix-k8s-p2">next post</a> where we will look under the hood for the control plane and nodes and see how that works. Follow me on <a href="https://twitter.com/fawix">Twitter (@fawix)</a> or <a href="https://www.linkedin.com/in/fatimasilv/">LinkedIn</a> so you won’t miss the update! May the containers be with you!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9d23de7f00e0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SAP on Google Cloud (pt. 4): Secrets in your pipes]]></title>
            <link>https://medium.com/google-cloud/sap-on-google-cloud-pt-4-secrets-in-your-pipes-70232071aab7?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/70232071aab7</guid>
            <category><![CDATA[sap-hana]]></category>
            <category><![CDATA[infrastructure]]></category>
            <category><![CDATA[cloud-native]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[microservices]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Mon, 02 Aug 2021 19:14:09 GMT</pubDate>
            <atom:updated>2021-08-04T18:43:25.759Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1014/0*mBNbyTNBlbKOqjxQ" /></figure><p>Sometime ago we published a few posts about creating a CICD — today we decided to show a bit more about how you make that config more secure by hiding your secrets. If you seen our previous posts on this topic you know how to <a href="https://blogs.sap.com/2020/07/02/sap-on-google-cloud-when-sap-developers-join-the-cloud-pt.-1/">use HDI to deploy changes to your HANA</a>, and how it can <a href="https://blogs.sap.com/2020/07/27/sap-on-google-cloud-hana-hdi-containers-and-ci-cd-pipelines-pt.2/">integrate with an existing cloud native workflow</a> all the while <a href="https://blogs.sap.com/2020/08/31/sap-on-google-cloud-creating-the-ci-cd-pipeline-pt.-3/">ensuring that your changes are properly tested</a> using a CICD pipeline; this is all really cool and will speed up our development cycle, but something is still missing for us to be able to put that beauty into prod!</p><h3>Hiding sensitive information</h3><p>If you have been wondering how you can protect your pipeline now that VCAP is right there with all the juicy information to do things to your HDI containers then I have good news for you. We can protect that information while retaining the same functionality.</p><p>Secrets … who doesn’t have them? Certainly not HANA (and many other applications for that matter); in the software world secrets are any information you want to keep private — if leaked or obtained by unauthorized parties it could offer them access that can potentially be used to compromise or damage your system.</p><p>If in doubt whether something should be a secret or not ask yourself, what would happen if a malicious entity got this information? Well, if that happened to VCAP … you’ll get the idea!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*O3IqCwbnGWxX02N5" /><figcaption>Created with imgflip</figcaption></figure><p>We will use <strong>Google Secret Manager</strong> to secure the VCAP variable, and then we will change our <strong>Cloud Build</strong> pipeline to securely consume that secret. The Google Secret Manager is a managed solution that allows us to easily create and consume secrets; but this method would work with other secret engines too.</p><h3>Creating the secret</h3><p>First make sure you have the correct information for VCAP services with the details for the user that is dedicated to the CI/CD pipeline, which is the same you created previously using the hanacli tool (<a href="https://medium.com/google-cloud/sap-on-google-cloud-hana-hdi-containers-and-ci-cd-pipelines-60cedaddfbc8#0972">“Creating the HDI container”</a>).</p><p>If you no longer have the json file with the contents of VCAP services we can recover it from the trigger — it’s there in plain text after all… and that is the problem we are going to solve.</p><pre>gcloud config set project ${PROJECT_ID} # make sure to use the correct PROJECT ID<br>cd app_hana/db<br>touch credentials.json<br>edit credentials.json</pre><p>Now, navigate to Cloud Build triggers page, where you have populated the environment variables and recover the value in the _CREDS and then paste it on the file we just created:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*vpWWF_ZJQs5zHomB" /></figure><p>If you rather obtain that value from the comfort of your command line do the following:</p><pre>gcloud components install alpha<br>gcloud alpha builds triggers describe deploy-app-hana-db --format=&quot;value(substitutions)&quot;</pre><p>This will print the value of _CREDS environment variable so you can just copy and paste in the file (making sure to only get the value) as shown in the screenshot above, if you changed the name of the triggers when you created them make sure to use the correct name above.</p><p>Our next step is to create the secret (you’ll need roles/secretmanager.admin IAM permission):</p><pre>gcloud services enable secretmanager.googleapis.com<br>gcloud secrets create app-hana-dev-vcap --data-file=./credentials.json --labels env=dev,app=app-hana-db,usage=cicd --replication-policy automatic<br>gcloud secrets list</pre><p>Each environment should have a different database and therefore a different VCAP value, for that reason we are not only appending the environment in the name but also adding a few labels to help us catalog and retrieve data in the future. Labels are really useful, so be sure to think about the relevant labels for your use-case.</p><p>With that … our secret is born!</p><h3>Updating the Cloud Build Pipeline</h3><p>Time to modify our CI/CD pipeline to use our app-hana-dev-vcap secret!</p><pre>edit cloudbuild.yaml</pre><p>This change is fairly straightforward, we will add a new step in our YAML file that tells Cloud Build how to get the secret and make it available to other steps as a file and once the pipeline is destroyed the file is destroyed with it.</p><p>We will accomplish that using the following gcloud command:</p><pre>gcloud secrets versions access latest --secret &quot;${_CREDS}&quot; --format=&#39;get(payload.data)&#39; | base64 -d &gt;&gt; credentials.json &amp;&amp; exit $?</pre><p>We also need to modify the next step to waitFor the secret step to finish before it starts and to use the file we just created instead to obtain the credentials to connect to the HDI container. Here is what the final <strong>cloudbuild.yaml</strong> looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a8473cc61b3791a4b65fe2fa7622c65c/href">https://medium.com/media/a8473cc61b3791a4b65fe2fa7622c65c/href</a></iframe><p>Now we need to update the trigger, head to the trigger page on cloud build and edit it, now replace the value on _CREDS with the name of our secret (in this case app-hana-dev-vcap).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/759/0*3bu867FLqJw9M9Ei" /></figure><p>Before this can work, however, we still need to tell GCP that the Cloud Build pipeline can access this secret, for that navigate to the IAM &amp; Admin page then find the service account that ends with @cloudbuild.gserviceaccount.com and give it the Secret Manager Secret Accessor role.</p><p>Now let’s test our pipeline! Push a change and see the magic happen:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*UVs-8MLfyjdnE-zN" /></figure><p>You are done! Enjoy!</p><p>If this was useful to you let <a href="https://twitter.com/fawix">me</a> or <a href="https://twitter.com/LuciaBlick">Lucia Subatin</a> know!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=70232071aab7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/google-cloud/sap-on-google-cloud-pt-4-secrets-in-your-pipes-70232071aab7">SAP on Google Cloud (pt. 4): Secrets in your pipes</a> was originally published in <a href="https://medium.com/google-cloud">Google Cloud - Community</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SAP on Google Cloud: Creating the CI/CD Pipeline (pt. 3)]]></title>
            <link>https://medium.com/google-cloud/sap-on-google-cloud-creating-the-ci-cd-pipeline-pt-3-22aa6c64123?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/22aa6c64123</guid>
            <category><![CDATA[cloud-build]]></category>
            <category><![CDATA[continuous-integration]]></category>
            <category><![CDATA[sap]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Sun, 30 Aug 2020 01:11:55 GMT</pubDate>
            <atom:updated>2020-09-08T17:13:43.511Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*---1Mb6D5X04Dr_W" /></figure><p>In this post, we will continue into our CI/CD journey. We have already explored the main concepts (<a href="https://medium.com/@lucia.subatin/sap-on-google-cloud-when-sap-developers-join-the-cloud-pt-1-5b4e24bf24e8">part 1</a> — including what is CI/CD) and ideas behind our sample application and the design principles for the pipeline when HANA is involved (<a href="https://medium.com/@lucia.subatin/sap-on-google-cloud-hana-hdi-containers-and-ci-cd-pipelines-60cedaddfbc8">part 2</a>). Now we will show you what the plumbing looks like for one of the microservices pipelines.</p><p>The image above shows the CI/CD flow we will implement. When the app developer commits the code, it will be picked up by a trigger in Cloud Build. It will then build, test and deploy our application. Let’s focus initially on a single environment pipeline since expanding it to multiple environments later is quite simple.</p><h3>Demo app recap</h3><p>Before we dive into the pipeline, let’s quickly recap what our application looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/659/0*hrzUzZHYejA2B9S3" /></figure><p>As <a href="https://twitter.com/LuciaBlick">Lucia Subatin</a> explained in part 2, the application has four major components:</p><ol><li>Frontend: web interface, allows the user access to the application.</li><li>Backend: translation service</li><li>DAL: the data access layer</li><li>Database: SAP HANA — stores our data.</li></ol><p>The diagram above shows how these components interact with each other. For more details, check out part 2 of this series.</p><h3>Where do I even start?</h3><p>Now you might be thinking: That is great! Where do we start? How do I pick the first microservice to become <em>CI/CD’ed</em>? (yes, I just invented a word… Poetic License FTW!!!)</p><p>When first starting a CI/CD pipeline for an existing application, it might be a challenge to know how to begin dissecting the beast. Look for the following traits in a service:</p><ul><li>Fairly independent, meaning it doesn’t have to call a lot of other services within the same application (it’s ok to be a dependency for other services)</li><li>A service that has good test coverage for the unit, functional and integration tests (yes — they are all important)</li><li>Has a relatively low overall complexity</li></ul><p>Take a peek at the diagram above again, which service do you think is the most adequate to be the first? Take a guess!</p><p>We are starting with the backend service since it’s quite isolated and well tested. When automating deployments, always try to improve your tests to ensure the reliability of your application — your future self will thank you.</p><h3>Build Containers</h3><p>The backend depends on the Google Translate API SDK for Golang; this means we would always need to install that SDK with a go get before can build. We also want to run go test and go vet as part of our test process.</p><p>Pipeline steps in Cloud Build run inside containers; this means we can simplify our build by creating a custom container with all the tools we need. Let’s go ahead and create a build container for the backend and store it in the container registry for later use within the pipeline.</p><p>Why bother, you ask? Eventually, you will want to run 10’s or even 100’s of builds a day — so those few seconds get magnified. This drives the needs to make builds as fast as possible. A build container allows us to skip the download and install step for build dependencies — saving time.</p><p>Here is what our backend build container Dockerfile looks like:</p><pre># build stage<br>FROM golang:alpine<br>RUN apk — no-cache add build-base git bzr gcc<br>RUN go get -u cloud.google.com/<a href="https://goto.google.com/translate">go/translate</a></pre><pre>ENTRYPOINT [ “/bin/ash” ]</pre><p>Bonus tip: you may decrease the build time even further by implementing <a href="https://cloud.google.com/cloud-build/docs/kaniko-cache">Kaniko Cache</a>.</p><h3>The Pipeline Configuration</h3><p>Now that we have the environment, let’s check what the pipeline looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/916/0*_mtogi642wW-jHpJ" /></figure><p>For master branch we will:</p><ol><li>Run static tests using go vet</li><li>Run unit tests go test</li><li>Run functional tests (also go test)</li><li>Build container (docker)</li><li>Push container to the registry (docker)</li><li>Deploy Container to the environment (gcloud)</li><li>Run integration tests (go test)</li></ol><p>The Cloud Build pipeline is configured via a YAML file called cloudbuild.yaml as follows:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c94f26323d59fb3691edad41eec1023a/href">https://medium.com/media/c94f26323d59fb3691edad41eec1023a/href</a></iframe><p>Of course, to implement the pipeline for other technologies the details will change, however, the overall flow will remain the same. For example, when testing the DAL layer using NodeJS the command will be npm test instead of go test and so on.</p><p>Some important considerations here are:</p><ol><li>Each microservice has an individual pipeline (cloudbuild.yaml)</li><li>Each microservice will generate its artefacts independently</li><li>Each microservice should test the integration with its dependencies.</li></ol><p>Remember this image Lucia explained in part 2?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*fGU2Ts08zvoA5CYE" /></figure><p>Look at the cloudbuild.yaml closely and you will see a dir: translate on each step that points to the backend microservice and thus this will only run when we make changes in that folder. There are many ways of doing this so pick the version that best suits your release and development needs. Also, notice how the cloudbuild.yaml file sits inside the folder for its relevant microservice.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/754/0*pbl9Jtz5M-QD1Mpq" /></figure><h3>Creating the Trigger</h3><p>It’s very straightforward to create a trigger in Cloud Build, once we have the YAML file created:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/0*La8mLNbyDC-kNa8v" /></figure><p>Notice that we configured the glob pattern to match only changes applied inside our microservice folder in the case of our backend it’s translate/**. This prevents this trigger from going off if we commit in other folders in the repo.</p><p>Also see how our regex is matching a branch named master, for non-master branches you can check the “Invert Regex” checkbox. Finally the Cloud Build configuration file also points specifically for our microservice pipeline definition with translate/cloudbuild.yaml</p><p>By now you can pretty much visualize how you would create the pipeline for the other microservices too!</p><p>To run your pipeline commit to your repository in the correct folder, you also have the option to run it manually. The build logs can be viewed by going to the Console and looking at the build execution like so:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*d5ictjVUtZy9fABX" /></figure><h3>The pipeline for HANA artefacts</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/559/1*lyRCTGSKY-yjhPz11iEaRQ.png" /><figcaption>Credit / Source: <a href="https://icanhas.cheezburger.com/">icanhas.cheezburger.com</a></figcaption></figure><p>The pipeline for deploying the HANA artefacts is mostly the same, but different … but still mostly the same.</p><p>As you saw in part 2, this pipeline relies on an HDI container and a special build container with the correct tooling to allow us to connect and deploy to the instance. The actual cloudbuild.yaml file is rather simple:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*htdbBkcNMYAejhSM" /></figure><p>Notice how it has a single step (for now). It mostly relies on the prepared build environment and tools likehana-cli and HDI connection context via the environment. All that is accomplished by creating a specific build container (much like our backend build container).</p><p>This is what the build container Dockerfile looks like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cd6f6cfb2942b4add9ed25457835d8d1/href">https://medium.com/media/cd6f6cfb2942b4add9ed25457835d8d1/href</a></iframe><p>As a side note, this Dockerfile is not optimized and you may want to tweak it a bit before using.</p><p>Notice how we set up the container with the required tooling to connect to HANA via HDI. You can build this container in the same way we created our backend build container. This step is important because it essentially allows us to be ready to connect and deploy our db-things via HDI.</p><p>Another important difference is how the npm start command is configured. We added the exit flag, so it won’t wait for a human to press Ctrl+C, without that the pipeline would hang and timeout.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Qh_jgrJb8iUMhdVi" /></figure><p>These are the main differences between a regular microservice pipeline and the HANA deployment pipeline using HDI containers.</p><p>Now you should be able to build your very own pipeline for your microservices and your HANA artefacts! Enjoy!</p><p><a href="https://twitter.com/LuciaBlick">Lucia Subatin</a> and <a href="https://www.linkedin.com/in/fatimasilv/">Fatima Silveira</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=22aa6c64123" width="1" height="1" alt=""><hr><p><a href="https://medium.com/google-cloud/sap-on-google-cloud-creating-the-ci-cd-pipeline-pt-3-22aa6c64123">SAP on Google Cloud: Creating the CI/CD Pipeline (pt. 3)</a> was originally published in <a href="https://medium.com/google-cloud">Google Cloud - Community</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to use multiple accounts with gcloud]]></title>
            <link>https://medium.com/google-cloud/how-to-use-multiple-accounts-with-gcloud-848fdb53a39a?source=rss-d7ea4b9845fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/848fdb53a39a</guid>
            <category><![CDATA[gcp]]></category>
            <category><![CDATA[terminal]]></category>
            <category><![CDATA[gcloud-commands]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Fatima Silveira]]></dc:creator>
            <pubDate>Fri, 17 Apr 2020 02:39:45 GMT</pubDate>
            <atom:updated>2020-04-23T23:40:01.129Z</atom:updated>
            <content:encoded><![CDATA[<h4>GCP TIPS</h4><h4>Learn how to easily switch contexts with gcloud.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*r-81XZzfTZCe1Is2s2JA7A.png" /></figure><p>Do you want to know how to work with multiple accounts and organizations in <em>gcloud</em> while keeping your sanity? Let me share with you a little known feature in <em>gcloud</em> that does just that.</p><h3>gcloud config configurations</h3><p>There is a sub-module in <em>gcloud config </em>that allows you to group a set of <em>configurations</em> and give it a name. You can then activate it on-demand! This means it becomes super easy to switch between different accounts or organizations whenever you need. In other words, context switching.</p><p>This is how you use it:</p><pre>gcloud config configurations activate config-name</pre><p>Switching between configurations is very simple and it carries all the information you set when you created it — this means that you don’t have to login again even if you are using different credentials. Simply type the command above <em>et voilà.</em></p><p>Before we get into details on how to create them, let me give you a few examples when this is useful:</p><ul><li>Switching between environments with distinct regions and zones.</li><li>Switching between different credentials, especially for testing.</li><li>Switching between completely different organizations.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5HD9BrDFGx846sLDL7wtAg.png" /><figcaption>gcloud configurations example. Source: my terminal</figcaption></figure><p>Notice on the screenshot above that I have accounts for different organizations, projects, compute zone, and compute region — and these are only a subset of <a href="https://cloud.google.com/sdk/gcloud/reference/config/set">possible settings</a>.</p><p>Of course to use a <em>configuration</em> you must first create it. This step requires a bit of typing but it’s a one-time effort, and will save a lot of time in the long run. This is how you create a new configuration:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1e2eadef1ce64fdb0ca1793092c5e2d4/href">https://medium.com/media/1e2eadef1ce64fdb0ca1793092c5e2d4/href</a></iframe><p>Give the config a memorable name, then add the <em>project id</em> and the <em>account </em>at a minimum. I typically also set the compute region and zone since I work with these a lot. For development, you may also want to add a service account.</p><p>By the way, did you notice I didn’t have to log in when creating the config above? That is because that account was already in use by another configuration. Yes, that easy!</p><p>If you do need to add a new account just invoke the following:</p><pre>gcloud auth login</pre><p>Using this trick will save you a lot of time and make your experience in <em>gcloud</em> better! It’s well worth to learn and configure if you work with multiple contexts;</p><p>Ready to create your first configuration? <a href="https://twitter.com/fawix">Let me know how it goes!</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=848fdb53a39a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/google-cloud/how-to-use-multiple-accounts-with-gcloud-848fdb53a39a">How to use multiple accounts with gcloud</a> was originally published in <a href="https://medium.com/google-cloud">Google Cloud - Community</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>