<?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 Sayed Imran on Medium]]></title>
        <description><![CDATA[Stories by Sayed Imran on Medium]]></description>
        <link>https://medium.com/@sayed-imran?source=rss-d0f6f318bd08------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*sMY0iPz7FTzgoCP_hhsyQQ.png</url>
            <title>Stories by Sayed Imran on Medium</title>
            <link>https://medium.com/@sayed-imran?source=rss-d0f6f318bd08------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 27 May 2026 03:59:33 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@sayed-imran/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[Traffic Management with Istio | Istio + Flagger | Part-4]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://sayed-imran.medium.com/traffic-management-with-istio-istio-flagger-part-4-d783f8b12a3b?source=rss-d0f6f318bd08------2"><img src="https://cdn-images-1.medium.com/max/1603/1*dEmPf0lEq6uf1x6kPLIxhQ.gif" width="1603"></a></p><p class="medium-feed-snippet">Welcome to the final part of the Traffic Management with Istio series. So far, we&#x2019;ve manually deployed application versions and configured&#x2026;</p><p class="medium-feed-link"><a href="https://sayed-imran.medium.com/traffic-management-with-istio-istio-flagger-part-4-d783f8b12a3b?source=rss-d0f6f318bd08------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://sayed-imran.medium.com/traffic-management-with-istio-istio-flagger-part-4-d783f8b12a3b?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/d783f8b12a3b</guid>
            <category><![CDATA[traffic-management]]></category>
            <category><![CDATA[flagger]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[istio]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Sun, 29 Jun 2025 18:46:33 GMT</pubDate>
            <atom:updated>2025-06-29T18:46:33.283Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Traffic Management using Istio | Traffic Shifting | Part-3]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://sayed-imran.medium.com/traffic-management-using-istio-traffic-shifting-part-3-37e37138a08d?source=rss-d0f6f318bd08------2"><img src="https://cdn-images-1.medium.com/max/911/1*nYkZj1X5LwTYXxdQJQyAcA.png" width="911"></a></p><p class="medium-feed-snippet">In this third part of our traffic management series with Istio, we will dive into deploying a canary release for a sample application and&#x2026;</p><p class="medium-feed-link"><a href="https://sayed-imran.medium.com/traffic-management-using-istio-traffic-shifting-part-3-37e37138a08d?source=rss-d0f6f318bd08------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://sayed-imran.medium.com/traffic-management-using-istio-traffic-shifting-part-3-37e37138a08d?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/37e37138a08d</guid>
            <category><![CDATA[service-mesh]]></category>
            <category><![CDATA[istio]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[traffic-management]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Mon, 23 Jun 2025 07:00:57 GMT</pubDate>
            <atom:updated>2025-06-23T07:00:57.904Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Traffic Management using Istio | Mirroring | Part-2]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://sayed-imran.medium.com/traffic-management-using-istio-mirroring-part-2-8551b8c9d475?source=rss-d0f6f318bd08------2"><img src="https://cdn-images-1.medium.com/max/2502/1*3Dh1jXUhRTi8wnFtWGtT2A.png" width="2502"></a></p><p class="medium-feed-snippet">In the world of microservices and Kubernetes, releasing new versions of applications with confidence requires more than just solid CI/CD&#x2026;</p><p class="medium-feed-link"><a href="https://sayed-imran.medium.com/traffic-management-using-istio-mirroring-part-2-8551b8c9d475?source=rss-d0f6f318bd08------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://sayed-imran.medium.com/traffic-management-using-istio-mirroring-part-2-8551b8c9d475?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/8551b8c9d475</guid>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[traffic-management]]></category>
            <category><![CDATA[istio]]></category>
            <category><![CDATA[service-mesh]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Thu, 29 May 2025 08:54:52 GMT</pubDate>
            <atom:updated>2025-05-29T08:54:52.749Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Traffic Management using Istio | Request Routing | Part-1]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://sayed-imran.medium.com/traffic-management-using-istio-request-routing-part-1-d04f63d8cbbd?source=rss-d0f6f318bd08------2"><img src="https://cdn-images-1.medium.com/max/2600/1*xo5qMis_G7o-T_cMqgyLCg.png" width="2829"></a></p><p class="medium-feed-snippet">Managing traffic in a microservices architecture is no longer just about sending requests from point A to point B&#x200A;&#x2014;&#x200A;it&#x2019;s about doing so&#x2026;</p><p class="medium-feed-link"><a href="https://sayed-imran.medium.com/traffic-management-using-istio-request-routing-part-1-d04f63d8cbbd?source=rss-d0f6f318bd08------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://sayed-imran.medium.com/traffic-management-using-istio-request-routing-part-1-d04f63d8cbbd?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/d04f63d8cbbd</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[istio]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[traffic-management]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Thu, 22 May 2025 05:03:00 GMT</pubDate>
            <atom:updated>2025-05-22T05:03:00.633Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Multi-Cluster Networking with Multi-Cloud : Migrating to Google Kubernetes Engine with Istio]]></title>
            <link>https://sayed-imran.medium.com/multi-cluster-networking-with-multi-cloud-migrating-to-google-kubernetes-engine-with-istio-2e1715dcd3e5?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/2e1715dcd3e5</guid>
            <category><![CDATA[migration]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[multi-cloud]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[istio]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Mon, 21 Apr 2025 03:39:25 GMT</pubDate>
            <atom:updated>2025-06-09T11:59:38.676Z</atom:updated>
            <content:encoded><![CDATA[<h3>Multi-Cluster Networking with Multi-Cloud Environments: Migrating to Google Kubernetes Engine with Istio</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kMXuMvaxKpU13WlbMcMoXQ.png" /><figcaption>Multi Cluster Multi Cloud Setup</figcaption></figure><p>As organizations expand their cloud strategy, they often manage workloads across multiple Kubernetes clusters, sometimes spanning different cloud providers. Migrating workloads between clouds — especially to <strong>Google Kubernetes Engine (GKE)</strong> — requires careful planning to ensure seamless networking, security, and service availability.</p><p>This article explores how <strong>Istio Service Mesh</strong> can be leveraged to connect two Kubernetes clusters — one running in another cloud provider and the other in <strong>Google Cloud (GKE)</strong>.</p><p>We will cover the following:</p><ul><li><strong>Challenges of Multi-Cloud Networking</strong> — Managing inter-cluster traffic, security, service discovery, and latency.</li><li><strong>Why Istio?</strong> — How Istio facilitates <strong>secure, observable, and controlled traffic routing</strong> between clusters.</li><li><strong>Setting Up Istio Across Multi-Cloud Clusters</strong> — Deploying Istio to enable cross-cluster networking between an external cloud and GKE.</li><li><strong>Service-to-Service Communication Between Clouds</strong> — Enabling seamless connectivity between workloads across both clusters.</li><li><strong>Live Migration to GKE</strong> — gradually migrate services from another cloud provider to Google Cloud <strong>without downtime</strong>.</li><li><strong>Testing &amp; Validating Migration</strong> — Ensuring smooth traffic flow and validating the migration success.</li></ul><p>By the end of this guide, you’ll have a <strong>multi-cloud Istio service mesh</strong> that connects an external cloud provider to <strong>Google Kubernetes Engine (GKE)</strong>. More importantly, you’ll learn how to <strong>gradually shift traffic and migrate workloads to GKE</strong> without service disruption.</p><p>Before getting started with the setup, Istio offers the following types of connectivity setups:</p><ul><li><a href="https://istio.io/latest/docs/setup/install/multicluster/multi-primary/">Install Multi-Primary on same network</a></li><li><a href="https://istio.io/latest/docs/setup/install/multicluster/primary-remote/">Install Primary-Remote on same network</a></li><li><a href="https://istio.io/latest/docs/setup/install/multicluster/multi-primary_multi-network/">Install Multi-Primary on different networks</a></li><li><a href="https://istio.io/latest/docs/setup/install/multicluster/primary-remote_multi-network/">Install Primary-Remote on different networks</a></li></ul><p>For our use-case we shall be using multi primary setup on different networks, as there are two completely different cloud and networks in place.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*e_QH47-r8W7SKVKRiZ4sBA.png" /><figcaption><a href="https://istio.io/latest/docs/setup/install/multicluster/multi-primary_multi-network/">Install Multi-Primary on different networks</a></figcaption></figure><p>To demonstrate this setup, I’ll be using EKS as the remote cluster, from where the workloads will be migrated to the GKE. Supposedly can be done for Azure as well!</p><p>Here’s the command used to create the AWS EKS Cluster:</p><pre>eksctl create cluster --name eks-cluster --region ap-south-1 --nodegroup-name nodegroup-1 --node-type t3.medium --nodes 3 --nodes-min 1 --nodes-max 5 --managed</pre><h4>3 node EKS cluster up and running</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GocTXqJar64dZPlqwAOvHA.png" /></figure><p>For the GKE cluster to be up and running, I’ve used the following gcloud command to spin up a 3 node cluster:</p><pre>gcloud container  clusters create &quot;gke-cluster&quot; --zone &quot;asia-south1-a&quot; --tier &quot;standard&quot;  --machine-type &quot;n2-standard-2&quot; --disk-type &quot;pd-balanced&quot; --disk-size &quot;50&quot;</pre><h4>3 node GKE Cluster Up and Running</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Jmdkz6QOBqMFfe-uV5TEGQ.png" /></figure><p>We already have workloads running in EKS which are required to be replicated in GKE, and then eventually the traffic shall be shifted completely to GKE.</p><p>Here’s the overview of the sample application which happens to be a <a href="https://github.com/Sayed-Imran/DevOps-and-Cloud">Animal Album</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eo5Ev0cRRKnfCarozIC6Jw.gif" /><figcaption>Animal Album App Architecture</figcaption></figure><p>This happens to be a very simple application with the following workload services:</p><ul><li><strong>ui-service</strong>: Built with React, responsible for the user interface.</li><li><strong>data-service</strong>: Built with FastAPI, responsible for retrieving data from the database.</li><li><strong>image-service</strong>: Built with FastAPI, responsible for retrieving images from the object storage.</li><li><strong>mongo</strong>: NoSQL database to store the metadata of the objects.</li><li><strong>minio</strong>: Object storage to store images of the animals.</li></ul><p>As per the current setup, the complete application is served from EKS. once we connect both the cluster, we’ll start to migrate the workloads.</p><h4>Deployed workloads on EKS</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/834/1*M7q-nS0QujQl1n9SPli_DA.png" /></figure><h3>Preparing the clusters</h3><p>Configuring the cluster include assigning the cluster with their unique name for cluster and network, and setting up east-west gateway which will act as the entry point of traffic from/to the respective cluster’s traffic.</p><h4>🛠️Configuring Istio in EKS Cluster</h4><p>We’ll start the preparation for migration from EKS, by configuring istio to consider EKS cluster as cluster1 in network1 as part of the mesh1. I’ll be using istioctl command line tool to configure the clusters, the YAML for the same here:</p><pre>apiVersion: install.istio.io/v1alpha1<br>kind: IstioOperator<br>spec:<br>  values:<br>    global:<br>      meshID: mesh1<br>      multiCluster:<br>        clusterName: cluster1<br>      network: network1</pre><pre># Command to install istio control plane component (istiod &amp; ingressgateway)<br>istioctl install --context=&quot;${CTX_CLUSTER1}&quot; -f cluster1.yaml</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/941/1*zQ2OKCRYhQ09LMnREcgBgA.png" /></figure><h4>🌐Installing East-West Gateway in EKS</h4><p>To enable <strong>cross-cluster communication</strong>, install the <strong>east-west gateway</strong>:</p><pre># Have used the istio scripts that come as part of installing istioctl<br>cd istio-&lt;version&gt;<br>samples/multicluster/gen-eastwest-gateway.sh \<br>    --network network1 | \<br>    istioctl --context=&quot;${CTX_CLUSTER1}&quot; install -y -f -</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7cYbTm8Epcth_lMy-KMB5A.png" /></figure><h4>📡Exposing the services in EKS cluster</h4><p>Since the clusters are on separate networks, we need to expose all services (*.local) on the east-west gateway in both clusters.</p><p>While this gateway is public on the Internet, services behind it can only be accessed by services with a trusted mTLS certificate and workload ID, just as if they were on the same network.</p><pre>kubectl --context=&quot;${CTX_CLUSTER1}&quot; apply -n istio-system -f \<br>    samples/multicluster/expose-services.yaml</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/837/1*5FXNzI3Bw-y7bMcz210E9w.png" /></figure><h4>🔐 Building Trust Between GKE and EKS Istio Meshes</h4><p>With Istio successfully configured in our <strong>EKS cluster</strong>, we now move on to setting it up in the <strong>GKE cluster</strong>. But before diving in, there’s one important prerequisite: <strong>establishing mutual trust</strong> between the two service meshes.</p><h4>🔑 Sharing the CA (Certificate Authority) Between Clusters</h4><p>To enable <strong>secure cross-cluster communication</strong> and <strong>DNS-based service discovery</strong>, both clusters must trust the <strong>same root certificate authority (CA)</strong>. While a production setup should use a secure and automated method for certificate management, for the purpose of this demo, we’ll manually reuse the <strong>CA secrets from the EKS cluster</strong> in the GKE cluster.</p><p><strong>📥 Step 1: Export CA Secret from EKS</strong></p><pre># Getting ca secrets from EKS cluster to copy to GKE<br>kubectl get secrets --context=&quot;${CTX_CLUSTER1}&quot;  -n istio-system \<br>istio-ca-secret -oyaml &gt; istio-ca-secrets.yaml</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sXn5_-NCeHlgIDGVarHwOQ.png" /><figcaption>Getting secrets from EKS cluster</figcaption></figure><blockquote>⚠️ Important Note</blockquote><blockquote>Copying Kubernetes <strong>Service Account (SA) secrets</strong> or CA secrets across clusters is <strong>not recommended in production environments</strong>. This approach is acceptable only in experimental or demo scenarios.</blockquote><blockquote>For production use cases, it is highly recommended to use <strong>cert-manager</strong> or <strong>Istio’s integration with external CAs</strong> to <strong>securely and automatically manage certificates across clusters</strong>.</blockquote><h4>🛠️ Configuring Istio in the GKE Cluster</h4><p>Now, let’s set up Istio in GKE. First, we’ll pre-create the namespace and apply the copied CA secret:</p><pre>kubectl create ns istio-system --context $CTX_CLUSTER2<br>kubectl apply -f istio-ca-secrets.yaml --context $CTX_CLUSTER2</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/753/1*Vvn2MsMLI3ET2AtFlBHFMw.png" /></figure><p>Then configure Istio with a shared mesh ID, and unique cluster/network identifiers:</p><pre>apiVersion: install.istio.io/v1alpha1<br>kind: IstioOperator<br>spec:<br>  values:<br>    global:<br>      meshID: mesh1<br>      multiCluster:<br>        clusterName: cluster2<br>      network: network2</pre><p>Install Istio in the GKE cluster:</p><pre>istioctl install --context=&quot;${CTX_CLUSTER2}&quot; -f cluster2.yaml</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1006/1*9QFmzdoTczPxfJkxgXTaXQ.png" /></figure><h4>🌐Installing East-West Gateway in GKE</h4><p>To enable <strong>cross-cluster communication</strong>, install the <strong>east-west gateway</strong>:</p><pre>samples/multicluster/gen-eastwest-gateway.sh \<br>    --network network2 | \<br>    istioctl --context=&quot;${CTX_CLUSTER2}&quot; install --set components.cni.enabled=false -y -f -</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/876/1*43_oTAxgvKeNCowZItVG1Q.png" /></figure><h4>📡Exposing the services in GKE cluster</h4><pre>kubectl --context=&quot;${CTX_CLUSTER2}&quot; apply -n istio-system -f \<br>    samples/multicluster/expose-services.yaml</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/864/1*Vxrj9AteOtgYsCG6yOPJaA.png" /></figure><h3>🔐Enable Endpoint Discovery</h3><p>Install a remote secret in cluster2 that provides access to cluster1’s API server.</p><pre>istioctl create-remote-secret \<br>  --context=&quot;${CTX_CLUSTER1}&quot; \<br>  --name=cluster1 | \<br>  kubectl apply -f - --context=&quot;${CTX_CLUSTER2}&quot;</pre><p>Install a remote secret in cluster1 that provides access to cluster2’s API server.</p><pre>istioctl create-remote-secret \<br>  --context=&quot;${CTX_CLUSTER2}&quot; \<br>  --name=cluster2 | \<br>  kubectl apply -f - --context=&quot;${CTX_CLUSTER1}&quot;</pre><h3>✅ Verifying the Multicluster Istio Setup</h3><p>To validate that Istiod can successfully communicate with the Kubernetes control plane of the remote cluster:</p><p><strong>For EKS run:</strong></p><pre>istioctl remote-clusters --context=&quot;${CTX_CLUSTER1}&quot;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/862/1*KmhzN7nLheJTKdGnk-AYrA.png" /></figure><p><strong>For GKE run:</strong></p><pre>istioctl remote-clusters --context=&quot;${CTX_CLUSTER2}&quot;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/864/1*V1SJcnc2SM3ob16LO39Uvg.png" /></figure><p>Both clusters are connected using the east-west gateway, and this connectivity has been verified via the previously shared snapshots.</p><p>Next, we deploy the image-service component in the <strong>GKE</strong> cluster. Once deployed, we access it via the <strong>web UI</strong>.</p><pre># Creating and labeling namespace<br>kubectl create ns animal-album --context $CTX_CLUSTER2<br>kubectl label ns animal-album istio-injection=enabled --context $CTX_CLUSTER2<br><br># Deploying the image service<br>kubectl apply -k image-service/ --context $CTX_CLUSTER2</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SSBw0zUlcCEKPZtwwu7BCQ.png" /></figure><p>Here’s the web-ui of the sample application that I’ve used for the demo purpose.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k0fzxDvbmdaABqziWAEjMw.png" /><figcaption>Web UI of the Animal Album App</figcaption></figure><h4>📈 Observing Cross-Cluster Traffic</h4><p>If the configuration is correct (and it absolutely is 😉), we’ll observe traffic reaching the image-service pods running in the GKE cluster.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*095io7jqFW7y5cBby001Bw.png" /><figcaption>(Left)Logs streaming from EKS— — — — — — — — — — — — — — — -(Right) Logs streaming from GKE</figcaption></figure><p>As expected, the traffic is flowing seamlessly across both image-service workloads deployed in <strong>GKE</strong> and <strong>EKS</strong> clusters — confirming that our multi-cluster Istio setup is working flawlessly.</p><h3>🎉 Success!</h3><p>Now, we can scale down the image-service in the EKS cluster completely and eventually migrating all the</p><p>With this setup in place, we can now <strong>migrate and run any application — stateless or stateful — between clusters</strong> with zero downtime. This significantly boosts our flexibility and resilience as we shift our workloads toward <strong>Google Kubernetes Engine</strong>. From unified traffic management to robust observability and secure service-to-service communication, Istio continues to prove its value in modern, distributed cloud-native applications.</p><p>By integrating <strong>Istio with Google Kubernetes Engine (GKE)</strong>, we’ve unlocked the ability to manage service-to-service communication with <strong>fine-grained control, built-in security, and powerful observability</strong> — all while spanning multiple clusters across cloud providers like GKE and EKS.</p><p>This multicluster setup demonstrates how Istio can <strong>extend a single service mesh across environments</strong>, giving us the flexibility to deploy, scale, and migrate workloads without disruption. GKE’s seamless integration with Istio further simplifies the management of complex architectures, making it easier to adopt <strong>zero-trust security</strong>, <strong>advanced traffic routing</strong>, and <strong>multi-cloud resilience</strong>.</p><p>This is just the beginning — I’m looking forward to <strong>leveraging more of Istio’s capabilities</strong> to enhance reliability, observability, and security across our distributed applications running on <strong>GKE and beyond</strong>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2e1715dcd3e5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Conversing with GKE Clusters: Google’s Agent Development Kit in Action]]></title>
            <link>https://sayed-imran.medium.com/conversing-with-gke-clusters-googles-agent-development-kit-in-action-d45a15393886?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/d45a15393886</guid>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[agent-development-kit]]></category>
            <category><![CDATA[agentic-ai]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Sat, 12 Apr 2025 00:42:34 GMT</pubDate>
            <atom:updated>2025-04-21T05:48:57.705Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fQQls7n7pK1n5OOVl-ZW-g.png" /></figure><p>When Google Cloud Next 2025 dropped the curtain on the <a href="https://github.com/google/adk-python"><strong>Agent SDK (a.k.a. ADK)</strong></a> — their shiny new toolset for building conversational agents — I knew two things instantly:</p><ol><li>I had to try it <em>immediately</em>.</li><li>I was going to make it talk to my <strong>GKE cluster</strong>.</li></ol><p>Fast forward a few coffees and command-line sessions later, and I now have a working conversational agent that can talk to, analyze, and interact with my Kubernetes workloads — all wrapped with a clean API, thanks to none other than <a href="https://fastapi.tiangolo.com/"><strong>FastAPI</strong></a>, my favorite framework (and the one Google used under the hood of ADK!).</p><p>Let’s dive into how I built it, what this SDK actually does, and why this might just be the future of cloud-native operations.</p><h3>🚀 What Is Google’s Agent SDK (ADK)?</h3><p>In short: <strong>a framework for building AI-powered agents</strong> that can understand user intents, execute tools, and hold context-aware conversations.</p><p>It combines the power of Google Cloud’s Gemini models, vector memory, and native tool-calling via <strong>FastAPI </strong>— all packaged in a dev-friendly kit.</p><p><strong>What’s inside ADK?</strong></p><ul><li>Built-in Gemini Pro support (via Vertex AI)</li><li>FastAPI-based tool integration</li><li>Natural multi-turn conversation support</li><li>Easy-to-deploy agent runtimes</li></ul><p>And yes — <strong>FastAPI</strong> is baked into the SDK as the underlying server tech. Google knows what’s up 😎.</p><h3>🛠️ Why Make a GKE Chatbot?</h3><p>Because <strong>kubectl is great, but natural language is better</strong>.</p><p>Imagine asking:</p><blockquote><em>“How many pods are in my production namespace?”<br> or<br> “Scale the frontend deployment to 5 replicas.”</em></blockquote><p>…and getting instant results. No context switching, no syntax memorization. Just chat.</p><p>I’ve uploaded a <strong>simple yet powerful implementation</strong> of this GKE chatbot to <a href="https://github.com/Sayed-Imran/google-adk-kubernetes-bot">GitHub</a>, designed to showcase just the <strong>tip of the iceberg</strong> of what Google’s ADK is capable of. It uses a handful of straightforward tools and functions — but even with this minimal setup, the possibilities are already exciting.</p><p>This is just the beginning. I’m looking forward to expanding the bot’s capabilities — adding more advanced tools, deeper GKE integrations, and perhaps even multi-cluster or policy-driven workflows. With the ADK’s flexibility and FastAPI’s developer-friendliness, the sky’s the limit. 🚀</p><p>Here’s a quick look at how the agent is declared along with the tool functions I’ve registered.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/644/1*mUh6OiHDdmouzhvPp9kpow.png" /></figure><p>Honestly, it’s <strong>just so damn fabulous</strong> how the ADK abstracts away <em>almost all the complexity</em> involved in building a conversational agent. And the cherry on top? The <strong>built-in web UI</strong> — powered by none other than <strong>FastAPI</strong> — is <em>chef’s kiss</em>. Here’s the snap of the same:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cofYzEIHtuM0-sr9Lgy3UA.png" /></figure><p>The UI is <strong>phenomenal</strong>. It not only allows you to experiment with different inputs but also provides <strong>rich, step-by-step details</strong> for each action the agent performs. You can visually trace every decision, every tool execution, and every intermediate step the model takes — it’s like watching the brain of your agent in action.</p><p>For this demo, I kept it simple with two tools:</p><ul><li>One to <strong>list all namespaces</strong></li><li>Another to <strong>list all pods and deployments</strong> within a given namespace</li></ul><p>Asked the agent for listing all the pods in all the namespaces.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jX7A_o2e9I_aZiyTI1ShcA.png" /></figure><p>What’s truly impressive is how the agent <strong>chains the tools intelligently</strong>. In the example below, you can see how it:</p><ol><li>First calls the list_namespaces() function.</li><li>Parses the result and picks a namespace.</li><li>Then calls list_pods(namespace) using that result—all without me hardcoding a workflow!</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dvqO6Xf0W34nNcSFQsl8-w.png" /></figure><p>The tool execution graph visualizes this beautifully, showing the flow of information and how one tool’s output becomes another tool’s input. Every action is logged in detail, making it incredibly easy to debug or improve the logic.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/626/1*gZC6syop6bDJvJcumsQLAw.png" /></figure><p>🛠️ <strong>Want to Try It Yourself?</strong><br> I’ve published the full implementation of the Kubernetes Assistant Agent on GitHub:<br> 👉 <a href="https://github.com/sayed-imran/google-adk-kubernetes-bot"><strong>sayed-imran/google-adk-kubernetes-bot</strong></a></p><p>This project is a <strong>lightweight yet powerful example</strong> of using Google’s new Agent Development Kit (ADK) to interact with Kubernetes clusters via natural language. Here’s what’s inside:</p><h3>🔍 Overview</h3><p>A conversational agent built with <strong>FastAPI</strong> (via ADK) and backed by <strong>Gemini models</strong>, designed to understand your prompts and perform Kubernetes operations accordingly.</p><h3>⚙️ Features</h3><p>The assistant currently supports:</p><ul><li>Listing all <strong>namespaces</strong> in your cluster</li><li>Viewing <strong>deployments, pods, and services</strong> within any namespace</li><li>Retrieving <strong>all resources</strong> in a given namespace with a single query</li></ul><h3>📦 Installation</h3><p>It’s super easy to set up. You’ll need Python 3.10+, an API key for Gemini, and a working kubeconfig. Just clone the repo, install dependencies with pip, set your API key, and you’re good to go.</p><h3>🚀 Usage</h3><p>Run the assistant locally with:</p><pre>adk run</pre><p>This spins up an interactive web UI where you can start chatting with your cluster right away.</p><p>Feel free to fork it, extend it with more tools, or plug it into your own DevOps workflows. Let’s explore how conversational agents can become a part of our daily ops toolkit. 💬⚙️</p><p>This, again, is just a minimal implementation, but it already feels like magic. Imagine what we could do with a few more tools — triggering rollouts, managing autoscaling, debugging failing pods, or even syncing with GitOps pipelines!</p><p>If you’re reading this and already thinking of ideas — you’re my kind of person.<br>Let’s build this out together. Fork the repo, add a new tool, or connect it to your DevOps workflows. The possibilities with Google’s ADK are nearly endless.</p><p>Let’s give our clusters a voice — because DevOps should be more than just YAML and kubectl. 🧠💬</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d45a15393886" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Seamless TLS for Istio on GKE: Auto-Provisioning Certificates with a Custom Admission Controller]]></title>
            <link>https://medium.com/google-cloud/seamless-tls-for-istio-on-gke-auto-provisioning-certificates-with-a-custom-admission-controller-b7968053d226?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/b7968053d226</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[istio]]></category>
            <category><![CDATA[cert-manager]]></category>
            <category><![CDATA[automation]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Mon, 07 Apr 2025 10:33:20 GMT</pubDate>
            <atom:updated>2025-04-07T10:33:20.309Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G8jMxx1Gh91VHGBRl4AYQA.png" /></figure><p>Istio has become the de facto standard for managing service-to-service communication in Kubernetes, offering powerful features like traffic management, security, and observability. However, when it comes to securing external traffic using Istio Gateway on <strong>Google Kubernetes Engine (GKE)</strong>, managing TLS certificates can be a challenge. While <strong>cert-manager</strong> simplifies certificate issuance in Kubernetes, it currently does not support auto-provisioning certificates based on annotations for Istio Gateway.</p><p>This limitation leaves teams with the manual task of creating <strong>Certificate</strong> and <strong>Issuer</strong> resources, which can lead to inconsistencies, misconfigurations, and increased operational overhead. To address this gap, we can leverage a <strong>Kubernetes Admission Controller</strong> to automate certificate provisioning seamlessly.</p><h3>Why This Matters for GKE Users ?</h3><p>For teams running <strong>Istio on GKE</strong>, managing certificates manually is inefficient, especially in large-scale environments with multiple microservices. Google Kubernetes Engine provides built-in integrations with <strong>Google-managed certificates</strong>, but many teams prefer <strong>cert-manager</strong> for its flexibility and support for different Certificate Authorities (CAs). This article will provide a solution that ensures <strong>cert-manager works seamlessly with Istio Gateway on GKE</strong>, automating certificate provisioning while maintaining security and reliability.</p><h3>Tech Stack</h3><p>To build the admission controller, we will be leveraging the following technologies:</p><ul><li><strong>FastAPI</strong> — A high-performance web framework for building asynchronous, HTTP-based service APIs in Python. This will serve as the backbone of our webhook service.</li><li><strong>Uvicorn</strong> — A minimal and lightning-fast ASGI server, perfect for running FastAPI applications in production.</li><li><strong>Kubernetes Python SDK</strong> — Enables interaction with Kubernetes API resources, allowing our webhook to automatically create certificates upon request.</li><li><strong>Docker</strong> — Used to containerize our webhook service, making deployment seamless across environments.</li><li><strong>Google Kubernetes Engine (GKE)</strong> — Our target Kubernetes cluster where we will deploy and test the admission controller in action.</li></ul><p>Here’s the link to the github repo: <a href="https://github.com/Sayed-Imran/istio-cert-manager-webhook">Istio-Cert Admission Controller</a></p><p>Before diving into implementation, let’s first understand <strong>Kubernetes webhooks</strong> and their role in automating resource management.</p><h3>Kubernetes Webhooks: Validating vs. Mutating</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iQlWS0scZjp5JD4ji4O3yg.png" /></figure><p>Admission webhooks in Kubernetes allow us to modify or validate resources <strong>before</strong> they are persisted to the cluster. They provide an efficient way to enforce policies, modify objects dynamically, and automate resource management. Kubernetes supports two main types of webhooks:</p><h3>1. Validating Webhook</h3><p>A <strong>validating webhook</strong> intercepts API requests and ensures they meet specific requirements <strong>before</strong> the resource is created or modified. If the request does not comply with defined rules, the webhook can reject it.</p><p>💡 <strong>Use Case Example:</strong> Ensuring that every Istio Gateway resource contains a valid host field before it is admitted into the cluster.</p><h3>2. Mutating Webhook</h3><p>A <strong>mutating webhook</strong> goes a step further by <strong>modifying</strong> the request <strong>before</strong> it is persisted in the cluster. This is particularly useful for injecting default values or adding annotations dynamically.</p><p>💡 <strong>Use Case Example:</strong> Automatically adding cert-manager.io/issuer annotations to Istio Gateway resources so that certificates are provisioned without manual intervention.</p><p>For our admission controller, we will be building a <strong>validating webhook</strong> that dynamically creates a certificate from the mentioned issuer/cluster-issuer in the annotation of the Istio Gateway, also, if the same doesn’t exist will respond with the same message that the mentioned issuer/cluster-issuer doesn’t exist.</p><p>Going into the details about the code can make things lengthy and become complex, I’ll just brief about what concept and the implementation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hfeQ57gx00vq65DEekcxoQ.png" /></figure><p>As the above diagram shows, there are three primary layers of this admission controller as follows:</p><h3><strong>API Layer</strong></h3><p>The API layer serves as the entry point to the admission controller. It receives the intercepted Kubernetes API requests related to the admission of Istio Gateway resources. Once a request is received, it is parsed and the JSON payload is forwarded to the handler layer for validation and further processing.</p><p>This modular design keeps the controller clean and extensible. Below is a snapshot of the API layer in action:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pjdAHloNtjnRXPx5plbw5g.png" /></figure><h3><strong>Handler Layer</strong></h3><p>The handler layer is responsible for validating the presence and correctness of specific annotations within the intercepted Istio Gateway resource. It primarily checks for the following annotations:</p><ul><li>cert-manager.io/issuer: &lt;issuer-name&gt;</li><li>cert-manager.io/cluster-issuer: &lt;clusterissuer-name&gt;</li></ul><p>Based on the presence or absence of these annotations, it follows one of two paths:</p><h4>Case 1: Annotations Not Present</h4><p>If neither of the required annotations is found in the request, the handler bypasses further validation and immediately returns an <strong>AdmissionReview</strong> response indicating the request is allowed. The response looks like this:</p><pre>{<br>    &quot;apiVersion&quot;: &quot;admission.k8s.io/v1&quot;, <br>    &quot;kind&quot;: &quot;AdmissionReview&quot;, <br>    &quot;response&quot;: {<br>        &quot;allowed&quot;: true, <br>        &quot;uid&quot;: &quot;c51f1429-48e9-47b7-bd3b-659b025b74b9&quot;,<br>        &quot;status&quot;:{<br>            &quot;message&quot;: &quot;Validation passed&quot;<br>        }<br>    }<br>}</pre><blockquote>NOTE: The response <strong>must</strong> strictly adhere to this format for Kubernetes to accept the result. The uid field in the response must exactly match the uid from the intercepted request to ensure that the response maps correctly to the original AdmissionReview.</blockquote><h4>Sample Intercepted Request</h4><p>Below is an example of an incoming <strong>AdmissionReview</strong> request received by the admission controller. It includes metadata and annotations related to the creation of an Istio Gateway:</p><pre>{<br>    &quot;kind&quot;: &quot;AdmissionReview&quot;,<br>    &quot;apiVersion&quot;: &quot;admission.k8s.io/v1&quot;,<br>    &quot;request&quot;: {<br>        &quot;uid&quot;: &quot;c51f1429-48e9-47b7-bd3b-659b025b74b9&quot;,<br>        &quot;kind&quot;: {<br>            &quot;group&quot;: &quot;networking.istio.io&quot;,<br>            &quot;version&quot;: &quot;v1&quot;,<br>            &quot;kind&quot;: &quot;Gateway&quot;<br>        },<br>        &quot;resource&quot;: {<br>            &quot;group&quot;: &quot;networking.istio.io&quot;,<br>            &quot;version&quot;: &quot;v1&quot;,<br>            &quot;resource&quot;: &quot;gateways&quot;<br>        },<br>        &quot;requestKind&quot;: {<br>            &quot;group&quot;: &quot;networking.istio.io&quot;,<br>            &quot;version&quot;: &quot;v1&quot;,<br>            &quot;kind&quot;: &quot;Gateway&quot;<br>        },<br>        &quot;requestResource&quot;: {<br>            &quot;group&quot;: &quot;networking.istio.io&quot;,<br>            &quot;version&quot;: &quot;v1&quot;,<br>            &quot;resource&quot;: &quot;gateways&quot;<br>        },<br>        &quot;name&quot;: &quot;istio-gateway&quot;,<br>        &quot;namespace&quot;: &quot;istio-system&quot;,<br>        &quot;operation&quot;: &quot;CREATE&quot;,<br>        &quot;userInfo&quot;: {<br>            &quot;username&quot;: &quot;&quot;,<br>            &quot;uid&quot;: &quot;&quot;,<br>            &quot;groups&quot;: [<br>                &quot;system:masters&quot;,<br>                &quot;system:authenticated&quot;<br>            ],<br>            &quot;extra&quot;: {}<br>        },<br>        &quot;object&quot;: {<br>            &quot;apiVersion&quot;: &quot;networking.istio.io/v1&quot;,<br>            &quot;kind&quot;: &quot;Gateway&quot;,<br>            &quot;metadata&quot;: {<br>                &quot;annotations&quot;: {<br>                    &quot;cert-manager.io/cluster-issuer&quot;: &quot;istio-cluster-issuer&quot;,<br>                },<br>                &quot;creationTimestamp&quot;: &quot;2025-04-05T07:25:12Z&quot;,<br>                &quot;generation&quot;: 1,<br>                &quot;managedFields&quot;: [<br>                    {<br>                        &quot;apiVersion&quot;: &quot;networking.istio.io/v1&quot;,<br>                        &quot;fieldsType&quot;: &quot;FieldsV1&quot;,<br>                        &quot;fieldsV1&quot;: {<br>                            &quot;f:metadata&quot;: {<br>                                &quot;f:annotations&quot;: {<br>                                    &quot;.&quot;: {},<br>                                    &quot;f:cert-manager.io/cluster-issuer&quot;: {},<br>                                    &quot;f:kubectl.kubernetes.io/last-applied-configuration&quot;: {}<br>                                }<br>                            },<br>                            &quot;f:spec&quot;: {<br>                                &quot;.&quot;: {},<br>                                &quot;f:selector&quot;: {<br>                                    &quot;.&quot;: {},<br>                                    &quot;f:istio&quot;: {}<br>                                },<br>                                &quot;f:servers&quot;: {}<br>                            }<br>                        },<br>                        &quot;manager&quot;: &quot;kubectl-client-side-apply&quot;,<br>                        &quot;operation&quot;: &quot;Update&quot;,<br>                        &quot;time&quot;: &quot;2025-04-05T07:25:12Z&quot;<br>                    }<br>                ],<br>                &quot;name&quot;: &quot;istio-gateway&quot;,<br>                &quot;namespace&quot;: &quot;istio-system&quot;,<br>                &quot;uid&quot;: &quot;b658440c-9eff-4579-bbdc-81a137129981&quot;<br>            },<br>            &quot;spec&quot;: {<br>                &quot;selector&quot;: {<br>                    &quot;istio&quot;: &quot;ingressgateway&quot;<br>                },<br>                &quot;servers&quot;: [<br>                    {<br>                        &quot;hosts&quot;: [<br>                            &quot;grpc-test.example.com&quot;<br>                        ],<br>                        &quot;port&quot;: {<br>                            &quot;name&quot;: &quot;https&quot;,<br>                            &quot;number&quot;: 443,<br>                            &quot;protocol&quot;: &quot;HTTPS&quot;<br>                        },<br>                        &quot;tls&quot;: {<br>                            &quot;credentialName&quot;: &quot;istio-ingress-tls&quot;,<br>                            &quot;mode&quot;: &quot;SIMPLE&quot;<br>                        }<br>                    }<br>                ]<br>            }<br>        },<br>        &quot;oldObject&quot;: null,<br>        &quot;dryRun&quot;: false,<br>        &quot;options&quot;: {<br>            &quot;kind&quot;: &quot;CreateOptions&quot;,<br>            &quot;apiVersion&quot;: &quot;meta.k8s.io/v1&quot;,<br>            &quot;fieldManager&quot;: &quot;kubectl-client-side-apply&quot;,<br>            &quot;fieldValidation&quot;: &quot;Strict&quot;<br>        }<br>    }<br>}</pre><blockquote>NOTE: The uid inside the request block (c51f1429-48e9-47b7-bd3b-659b025b74b9) is the one that must be returned in the admission controller&#39;s response to ensure accurate validation of the original request.</blockquote><h4>Case 2: Annotations Are Present</h4><p>If the required annotations are present, the handler proceeds to verify whether the specified Issuer or ClusterIssuer exists within the cluster:</p><ul><li><strong>If the Issuer/ClusterIssuer is found:</strong> The request is allowed to proceed as usual.</li><li><strong>If the Issuer/ClusterIssuer is not found:</strong> The request is <strong>denied</strong>, and the admission controller returns a response with allowed: false, along with an error message stating that the referenced issuer does not exist.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G7la8NXCWm2XvXTkfeRQSw.png" /></figure><p>This safeguards the cluster from deploying gateways referencing non-existent certificate managers, which could result in misconfigurations or failures in TLS termination.</p><h3>Kubernetes Utility Layer</h3><p>Once all validations are successfully passed, control is handed over to the <strong>Kubernetes Utility Layer</strong>. Unlike standard validation webhooks that only accept or reject requests, this layer goes a step further — it actively creates Kubernetes resources. This is essential to our core goal: <strong>auto-provisioning TLS certificates</strong> for Istio Gateway resources.</p><p>This layer interacts directly with the Kubernetes API server to create the required Certificate resources based on metadata and annotations extracted from the intercepted Gateway object.</p><h4>Certificate Creation and Ownership</h4><p>A central task of this layer is the creation of a Certificate resource when the referenced Issuer or ClusterIssuer exists in the cluster.</p><p>The certificate is initialized with default values for fields such as duration and renewBefore. However, these can be customized via annotations on the Gateway resource, giving users granular control without modifying the controller itself.</p><p>Another key aspect is the automatic injection of an ownerReference into the generated Certificate. This reference links the Certificate to its parent Gateway resource, ensuring that when the Gateway is deleted, the associated Certificate is also cleaned up by Kubernetes&#39; garbage collector.</p><p>This automation replaces what would otherwise be a manual and error-prone process:</p><ol><li>Manually creating the Gateway.</li><li>Retrieving its metadata.</li><li>Manually crafting a matching Certificate resource with correct references.</li></ol><p>By handling all of this internally, the admission controller drastically reduces operational complexity and ensures <strong>seamless, lifecycle-aware certificate management</strong>.</p><h3>Wiring It All Together: ValidatingWebhookConfiguration</h3><p>Once the admission controller is deployed and running, the final step is to <strong>ensure that relevant API requests are intercepted</strong> and routed through it. This is achieved by creating a ValidatingWebhookConfiguration.</p><p>This Kubernetes resource registers the webhook with the API server, specifying what kind of resources and operations should trigger the admission controller. In our case, it’s configured to intercept CREATE and UPDATE operations on Istio Gateway resources.</p><p>Here’s the manifest for the ValidatingWebhookConfiguration that ties everything together:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/906/1*G1qgJ3GGL1DaXmLltBPkqA.png" /></figure><blockquote>🛡️ <strong>NOTE:</strong> Admission controllers <strong>must be served over HTTPS</strong>, as the Kubernetes API server only communicates with webhooks via secure channels. While the details of setting up TLS for the controller are outside the scope of this article, it’s an essential step to ensure the controller functions properly in a production environment.</blockquote><h3>Conclusion</h3><p>By extending the functionality of a standard admission controller to include resource creation, we’ve built a streamlined and automated solution for certificate provisioning tied to Istio Gateways. This not only eliminates manual overhead but also ensures lifecycle-aware cleanup using owner references — all while integrating seamlessly into the Kubernetes admission workflow.</p><p>While this approach is tailored for Istio and cert-manager, the underlying pattern can be extended to other dynamic resource scenarios as well. With the right validations, ownership models, and security considerations in place, admission controllers can go beyond validation to become powerful automation tools within your Kubernetes ecosystem.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b7968053d226" width="1" height="1" alt=""><hr><p><a href="https://medium.com/google-cloud/seamless-tls-for-istio-on-gke-auto-provisioning-certificates-with-a-custom-admission-controller-b7968053d226">Seamless TLS for Istio on GKE: Auto-Provisioning Certificates with a Custom Admission Controller</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[Leveraging Istio to connect External VM to Kubernetes (GKE)]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/google-cloud/leveraging-istio-to-connect-external-vm-to-kubernetes-gke-0e0e33bac5d3?source=rss-d0f6f318bd08------2"><img src="https://cdn-images-1.medium.com/max/1048/1*kBFs7PKGhJlFPASrQR_HyQ.gif" width="1048"></a></p><p class="medium-feed-snippet">This article explores how to extend Kubernetes service mesh capabilities beyond the cluster by leveraging Istio to seamlessly connect an&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/google-cloud/leveraging-istio-to-connect-external-vm-to-kubernetes-gke-0e0e33bac5d3?source=rss-d0f6f318bd08------2">Continue reading on Google Cloud - Community »</a></p></div>]]></description>
            <link>https://medium.com/google-cloud/leveraging-istio-to-connect-external-vm-to-kubernetes-gke-0e0e33bac5d3?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/0e0e33bac5d3</guid>
            <category><![CDATA[gcp-security-operations]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[service-mesh]]></category>
            <category><![CDATA[istio]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Fri, 04 Oct 2024 08:01:20 GMT</pubDate>
            <atom:updated>2024-10-04T08:01:20.257Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Empowering Kubernetes Operator Development with Kopf: Deploying to Kubernetes EKS(Part-3)]]></title>
            <link>https://sayed-imran.medium.com/empowering-kubernetes-operator-development-with-kopf-deploying-to-kubernetes-eks-part-3-ce101db2947c?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/ce101db2947c</guid>
            <category><![CDATA[kubernetes-operator]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[automation]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Sun, 03 Mar 2024 15:34:43 GMT</pubDate>
            <atom:updated>2024-03-03T15:34:43.760Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yjxyr2yVxvFgKvtJIOE62Q.png" /></figure><p>In my previous article on <a href="https://sayed-imran.medium.com/empowering-kubernetes-operator-development-with-kopf-getting-started-with-writing-operator-f66864374852">Getting Started with Writing Operator</a>, I built a simple operator which launched a Kubernetes Deployment and exposed it via Kubernetes Service for the custom resource Microservice.</p><p>In this part of the article, I’ll be moving on from development mode to deployment, and will be running the operator as a Kubernetes Deployment in the Kubernetes itself. I’ll be using AWS EKS as the Kubernetes environment.</p><blockquote>Kubernetes Operator operates in the same method irrespective of the Kubernetes Environment.</blockquote><p>The following steps will be involved to deploy the operator to Kubernetes:</p><ol><li>Adding authentication logic for Operator</li><li>Creating Dockerfile for the Operator.</li><li>Building and pushing the image to Docker Hub.</li><li>Launching an EKS Cluster.</li><li>Creating necessary resources, CRD and the Operator.</li><li>Deploying Microservice to test the operator.</li></ol><h4>Authentication Logic for Operator</h4><pre>@kopf.on.login()<br>def custom_login_fn(**kwargs):<br>    if EnvConfig.ENV == &quot;dev&quot;:<br>        return kopf.login_with_kubeconfig(**kwargs)<br>    else:<br>        return kopf.login_with_service_account(**kwargs)</pre><p>I’ve modified the code and folder structures to make it more readable, you may find the code here: <a href="https://github.com/Sayed-Imran/microservice-operator/tree/v1.0.0">Microservice Operator</a>.</p><p>Every time the operator starts, it performs an initial authentication process with the Kubernetes API server, to determine the whereabouts of the Kubernetes to be used. This above function overrides the default authentication flow, which in my case is environment driven.</p><p>Depending upon the value passed for the environment variable, operator will be able to authenticate from either using kubeconfig (for development purpose) or from the service account (for production).</p><h4>Dockerfile for Operator</h4><p>The following <em>Dockerfile </em>is used for creating the image of the operator.</p><pre>FROM python:3.11-slim-buster<br><br>WORKDIR /app<br><br>COPY requirements.txt .<br><br>RUN pip install --no-cache-dir -r requirements.txt<br><br>COPY . .<br><br>ENTRYPOINT [&quot;kopf&quot;, &quot;run&quot;, &quot;main.py&quot;]</pre><p>The <a href="https://github.com/Sayed-Imran/microservice-operator/blob/v1.0.0/requirements.txt">requiremets.txt</a> file contains the python packages used for the operator.</p><h4>Building and Pushing Image</h4><p>I’ve used my personal docker image registry to push the image.</p><p>Command to build the image:</p><pre>docker build -t sayedimran/microservice-operator:v1.0.0 .</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/702/1*TNA6aZI0KHoT0xcdIhlC7Q.png" /><figcaption>Image Build Output</figcaption></figure><p>Command to push the image to the registry:</p><pre>docker push sayedimran/microservice-operator:v1.0.0</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yr7HntWpjOuyxC2Jm4iUyQ.png" /><figcaption>Pushing image to the registry</figcaption></figure><h4>Launching an EKS Cluster</h4><p>I’ve created an EKS cluster with all the default options as shown in the below image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/982/1*_l_OQUxeHsyKnGM4C29w9A.png" /><figcaption>Default EKS configuration</figcaption></figure><p>Created a Node Group with all default options with Amazon Linux 2 Image with 2 nodes of type t2.medium and 20 GiB of storage for each:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xZZSPbskZZgJyhcHE02aMA.png" /><figcaption>Default Node Group Configuration</figcaption></figure><p>Once the cluster is ready, to access the EKS via kubectl, I’ll be the using the aws CLI in AWS CloudShell.</p><p>Command to generate kubeconfig:</p><pre>aws eks --region ap-south-1 update-kubeconfig --name aws-cluster-1</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/913/1*5OcsSsvBkpGN9KpRExNG1A.png" /><figcaption>Generating Kubeconfig for the created cluster</figcaption></figure><p>Checking for the kube-system namespace pods</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/647/1*2Yn43Z-hCYe9QoyTWO04wQ.png" /><figcaption>Pods of kube-system</figcaption></figure><p>Cluster is now ready for the operator to be deployed.</p><h4>Creating resources &amp; CRD for Operator</h4><p>As of now the operator has been bundled as image and pushed to the registry which now can be pulled into the Kubernetes when deployed.</p><p>Before deploying the operator, the following resources are the pre-requisites for the operator to function in the cluster:</p><ul><li>ClusterRole</li><li>ClusterRoleBinding</li><li>Role</li><li>RoleBinding</li><li>ServiceAccount</li></ul><p>All the above resources are basically the RBAC permissions to be provided to the operator so as to provision resources on launch of the custom resources.</p><p>Link of the CRD, resources &amp; operator deployment can be found here:</p><ul><li>Microservice CRD [<a href="https://raw.githubusercontent.com/sayed-imran/microservice-operator/v1.0.0/crd.yml">crd.yaml</a>]</li><li>Microservice Operator Resources and Deployment [<a href="https://raw.githubusercontent.com/sayed-imran/microservice-operator/v1.0.0/deploy.yml">deploy.yaml</a>]</li></ul><p>Command to deploy the CRD, resources and operator:</p><pre>kubectl apply -f https://raw.githubusercontent.com/sayed-imran/microservice-operator/v1.0.0/crd.yml<br>kubectl apply -f https://raw.githubusercontent.com/sayed-imran/microservice-operator/v1.0.0/deploy.yml</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PPYWXiqmZjX-GpEZ4V4Cjw.png" /><figcaption>CRD, resources &amp; Operator deployed</figcaption></figure><h4>Testing the Microservice Resource</h4><p>Once the pod for operator goes to running state, we can deploy our custom resource i.e. Microservice.</p><p>Deploying a sample microservice application, link for the same can be found here: [<a href="https://raw.githubusercontent.com/Sayed-Imran/microservice-operator/v1.0.0/cr.yml">sample-microservice.yaml</a>]</p><p>Command to deploy the custom resource:</p><pre>kubectl apply -f https://raw.githubusercontent.com/sayed-imran/microservice-operator/v1.0.0/cr.yml</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tqWO4UzsW9EZZY8Fj-XsPA.png" /><figcaption>Deploying the custom resouce microservice</figcaption></figure><p>As we can see the resource has been deployed successfully, we can also check for the child resources i.e., pods of the deployment and the service.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/731/1*fQYlYMu5s0OG2EbZ8ue96A.png" /><figcaption>Child resources for the custom resource</figcaption></figure><p>This marks the completion of the deployment of the Kubernetes Operator in the EKS.</p><p>Looking forward to add further more advanced logic to the Operator, do let me know if you want me to add anything relevant and please do give your feedbacks in the comment, would love to hear from you.</p><p>#kubernetes #operator #aws #eks #automation #python #kopf #docker #devops #cloud #containerization #sdk #python #go #community #learning #dev</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ce101db2947c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Empowering Kubernetes Operator Development with Kopf: Getting Started with writing Operator…]]></title>
            <link>https://sayed-imran.medium.com/empowering-kubernetes-operator-development-with-kopf-getting-started-with-writing-operator-f66864374852?source=rss-d0f6f318bd08------2</link>
            <guid isPermaLink="false">https://medium.com/p/f66864374852</guid>
            <category><![CDATA[kubernetes-operator]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[automation]]></category>
            <dc:creator><![CDATA[Sayed Imran]]></dc:creator>
            <pubDate>Sat, 24 Feb 2024 15:33:03 GMT</pubDate>
            <atom:updated>2024-02-24T15:33:03.847Z</atom:updated>
            <content:encoded><![CDATA[<h3>Empowering Kubernetes Operator Development with Kopf: Getting Started with writing Operator (Part-2)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oCeObxW3_e861L6syxg6mQ.png" /></figure><p>In my previous article, <a href="https://sayed-imran.medium.com/empowering-kubernetes-operator-development-with-kopf-introduction-to-operators-part-1-c0970a349b6b">Introduction to Operators (Part-1)</a> I briefed about the various aspects of a Kubernetes Operator. This part of the series will be getting started with writing a basic operator.</p><p>As mentioned earlier, we’ll be using <a href="https://github.com/nolar/kopf">Kopf</a> (Kubernetes Operator Pythonic Framework), for building our first basic operator.</p><p>Apart from that, we need the following things to get started:</p><ul><li><strong><em>pykube-ng </em></strong>( a lightweight Python client library for Kubernetes which is preferred when developing a Operator.)</li><li><a href="https://minikube.sigs.k8s.io/docs/start/"><strong><em>minikube</em></strong></a> or any running<strong><em> kubernetes</em></strong> <strong><em>cluster </em></strong>with accessible <strong><em>kubeconfig </em></strong>file. (I’ll be using minikube)</li></ul><p>We’ll be creating a operator for a custom resource called Microservice, which basically will launch a deployment as a child resource for the same.</p><h4>Custom Resource Definition for the Operator and Resource</h4><p>Any Custom Resource (CR) comes with a Custom Resource Definition (CRD), which defines the schema of the CR and other necessary fields. Here’s the CRD to be used for the resource that we will be creating.</p><pre>apiVersion: apiextensions.k8s.io/v1<br>kind: CustomResourceDefinition<br>metadata:<br>  name: microservices.imran.dev.io<br>spec:<br>  group: imran.dev.io<br>  scope: Namespaced<br>  names:<br>    plural: microservices<br>    singular: microservice<br>    kind: Microservice<br>    shortNames:<br>    - ms<br>  versions:<br>  - name: v1alpha<br>    served: true<br>    storage: true<br>    schema:<br>      openAPIV3Schema:<br>        type: object<br>        properties:<br>          spec:<br>            type: object<br>            properties:<br>              replicas:<br>                type: integer<br>                minimum: 1<br>              image:<br>                type: string<br>              labels:<br>                type: object<br>                additionalProperties:<br>                  type: string<br>              env:<br>                type: array<br>                items:<br>                  type: object<br>                  properties:<br>                    name:<br>                      type: string<br>                    value:<br>                      type: string<br>            required:<br>            - replicas<br>            - image<br>          status:<br>            type: object<br>            properties:<br>              ready:<br>                type: string<br>    additionalPrinterColumns:<br>    - name: Replicas<br>      type: integer<br>      description: Number of replicas for the microservice<br>      jsonPath: .spec.replicas<br>    - name: Image<br>      type: string<br>      description: Image used for the microservice<br>      jsonPath: .spec.image</pre><p>The metadata field contains the name of the CRD in the format &lt;plural&gt;.&lt;group&gt;. Here, it&#39;s microservices.imran.dev.io.</p><p>The spec field contains the details of the custom resource:</p><ul><li>group is the name of the API group that this CRD belongs to. In this case, the group is imran.dev.io. API groups are a way of organizing related kinds in the Kubernetes API.</li><li>scope defines whether the custom resource is cluster-wide or namespace-specific. Here, the scope is Namespaced, meaning instances of this custom resource can be created within specific namespaces in the Kubernetes cluster.</li><li>names defines the naming conventions for the custom resource. The plural and singular fields are used in the URL of the API endpoint and in command-line interactions, respectively. The kind field is the name of the custom resource that you&#39;re defining with this CRD. The shortNames field provides a shorter alias for the resource, which can be used in command-line interactions.</li></ul><p>The versions field is an array that defines one or more versions for the custom resource. Each version can have its own schema and additional printer columns. Here, we have one version named v1alpha which is both served and stored.</p><p>The schema of the custom resource is defined under properties. Here, the custom resource has properties replicas, image, labels, and env.</p><ul><li>replicas is a required field that specifies the number of instances of a microservice that should be running.</li><li>image is another required field that specifies the Docker image to use for the microservice.</li><li>labels is another required field that is an object with additional properties of type string. This is typically used for specifying metadata.</li><li>env is an array of objects, each having name and value properties. This is used for setting environment variables for the microservice.</li></ul><p>The additionalPrinterColumns field is used to customize the output when using kubectl to list these resources. Here, two additional columns are defined: Replicas and Image, which display the number of replicas and the image used for the microservice, respectively. The jsonPath specifies the path to the field in the custom resource&#39;s Spec that should be used for the column&#39;s value.</p><p>Now, applying the CRD to the Kubernetes:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BYBbYV26lbQ0BEyjUQR2Sw.png" /><figcaption>Applying the Custom Resource Definition</figcaption></figure><h4>Kubernetes Operator Code Snippet</h4><p>Here’s the code snippet to the operator that will drive the CR lifecycle:</p><pre>import kopf<br>import pykube<br><br><br>@kopf.on.create(&quot;imran.dev.io&quot;, &quot;v1alpha1&quot;, &quot;microservices&quot;)<br>def create_fn(spec, **kwargs):<br>    kube_api = pykube.HTTPClient(pykube.KubeConfig.from_file())<br>    deployment = pykube.Deployment(kube_api,{<br>        &#39;apiVersion&#39;: &#39;apps/v1&#39;,<br>        &#39;kind&#39;: &#39;Deployment&#39;,<br>        &#39;spec&#39;: {<br>            &#39;replicas&#39;: spec[&#39;replicas&#39;],<br>            &#39;selector&#39;: {<br>                &#39;matchLabels&#39;: spec[&#39;labels&#39;],<br>            },<br>            &#39;template&#39;: {<br>                &#39;metadata&#39;: {<br>                    &#39;labels&#39;: spec[&#39;labels&#39;],<br>                },<br>                &#39;spec&#39;: {<br>                    &#39;containers&#39;: [<br>                        {<br>                            &#39;name&#39;: kwargs[&#39;body&#39;][&#39;metadata&#39;][&#39;name&#39;],<br>                            &#39;image&#39;: spec[&#39;image&#39;],<br>                            &#39;env&#39;: spec.get(&#39;env&#39;, []),<br>                        },<br>                    ],<br>                },<br>            },<br>        },<br>    })<br>    kopf.adopt(deployment)<br>    deployment.create()<br>    return {&#39;message&#39;: &#39;Deployment created&#39;}<br></pre><p>The Operator listens for the creation of custom resources of type microservices in the imran.dev.io group and v1alpha1 version, and creates a corresponding Kubernetes Deployment.</p><p>The @kopf.on.create decorator registers a function to be called whenever a microservices custom resource is created. The function parameters spec and kwargs contain the details of the custom resource.</p><p>Inside the function, a pykube.HTTPClient is created to interact with the Kubernetes API. The pykube.KubeConfig.from_file() function reads the kubeconfig file from its default location and uses it to authenticate with the Kubernetes API.</p><p>A pykube.Deployment object is then created. The deployment specification is built using the spec from the custom resource. The number of replicas, the labels, the container image, and the environment variables are all taken from the custom resource&#39;s spec.</p><p>The kopf.adopt(deployment) function is called to set the owner references of the Deployment to the custom resource. This means that when the custom resource is deleted, the Deployment will be automatically deleted as well.</p><p>Command to run the Operator: kopf run main.py --verbose</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zW9f-gITLbzQudyDZbtu7A.png" /><figcaption>Logs from Operator</figcaption></figure><h4>YAML for the CR:</h4><pre>apiVersion: imran.dev.io/v1alpha1<br>kind: Microservice<br>metadata:<br>  name: micron<br>spec:<br>  labels:<br>    app: microservice-sample<br>    env: dev<br>  replicas: 3<br>  image: sayedimran/fastapi-sample-app:v4<br>  env:<br>    - name: ENV<br>      value: test<br>    - name: LOG_LEVEL<br>      value: debug</pre><p>Now, applying the YAML to the Cluster</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1017/1*NIpcJMQ3GZhkvlVeOR1m-g.png" /><figcaption>Applying the Custom Resource</figcaption></figure><p>So, now if check for the resource:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/904/1*JmwSJC2-JrRcMUTFuZRS4A.png" /><figcaption>Details of the Custom Resource via kubectl</figcaption></figure><p>Our custom resource has been created, and the deployment &amp; pods for the same has been created as well, which can be verified:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*c4SLQleHkonpqhDbKLs7ww.png" /><figcaption>Child resources for the Custom Resource</figcaption></figure><p>This marks the end of part-2 of the series, where we created a simple operator to get an overall understanding of the concepts, we can definitely add more functionality to it such as: support for having secretKeyRef, configMapKey, volumes and volumeMounts, etc.</p><p>I’ve been adding more and more logic to the operator, you may find the GitHub Repo Link: <a href="https://github.com/Sayed-Imran/microservice-operator">microservice-operator</a> for the same.</p><p>Currently I’ve added support for service creation, which is helpful in exposing the deployment, that gets deployed as a child resource as well.</p><p>In the next part of series, we’ll work on deploying this operator to the Kubernetes Operator as a deployment.</p><p>Do let me know if you’ve got any doubts or any type of feedbacks in the comments.</p><p>#kubernetes #operator #crd #devops #automation #containerization #cloud #aws #googlecloud #azure #containers #automation #sdk #python #go #community #learning #dev</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f66864374852" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>