<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Archives des cilium - dbi Blog</title>
	<atom:link href="https://www.dbi-services.com/blog/tag/cilium/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.dbi-services.com/blog/tag/cilium/</link>
	<description></description>
	<lastBuildDate>Tue, 03 Sep 2024 15:04:07 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2025/05/cropped-favicon_512x512px-min-32x32.png</url>
	<title>Archives des cilium - dbi Blog</title>
	<link>https://www.dbi-services.com/blog/tag/cilium/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Kubernetes Traffic Control: Ingress vs. Gateway API</title>
		<link>https://www.dbi-services.com/blog/kubernetes-traffic-control-ingress-vs-gateway-api/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-traffic-control-ingress-vs-gateway-api/#respond</comments>
		
		<dc:creator><![CDATA[Donovan Winter]]></dc:creator>
		<pubDate>Tue, 03 Sep 2024 15:04:04 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[cni]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[gateway api]]></category>
		<category><![CDATA[httproute]]></category>
		<category><![CDATA[Ingress]]></category>
		<category><![CDATA[ingress controller]]></category>
		<category><![CDATA[isovalent]]></category>
		<category><![CDATA[kubernetes]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=34635</guid>

					<description><![CDATA[<p>In the evolving landscape of Kubernetes, efficient and flexible management of network traffic is essential for deploying, scaling, and securing modern applications. As organizations adopt more complex microservices architectures, the need for robust traffic control mechanisms becomes increasingly critical. This is where the Gateway API comes into play. Gateway API is a relatively new and [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-traffic-control-ingress-vs-gateway-api/">Kubernetes Traffic Control: Ingress vs. Gateway API</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the evolving landscape of Kubernetes, efficient and flexible management of network traffic is essential for deploying, scaling, and securing modern applications. As organizations adopt more complex microservices architectures, the need for robust traffic control mechanisms becomes increasingly critical. This is where the Gateway API comes into play.</p>



<p class="wp-block-paragraph">Gateway API is a relatively new and powerful extension to Kubernetes designed to improve how traffic routing and network policies are managed. It is a set of resources that provides more expressive and extensible tools for controlling network traffic. Unlike the traditional Ingress resource, which focuses primarily on HTTP and HTTPS routing, Gateway API offers a more modular approach, supporting multiple protocols and providing advanced capabilities that address the limitations of Ingress.</p>



<p class="wp-block-paragraph">The Gateway API introduces concepts like Gateways, Routes, and GatewayClasses, which allow for a clearer separation of concerns, enabling both infrastructure administrators and application developers to work more efficiently. By supporting features such as traffic splitting, path-based routing, and more granular control over traffic policies, Gateway API offers a significant step forward in Kubernetes traffic management.</p>



<p class="wp-block-paragraph">As organizations increasingly demand more advanced networking features and greater flexibility in their deployments, the Gateway API is positioned as a future-proof solution, providing a standardized and consistent way to manage traffic across a wide range of use cases. Whether you are dealing with complex microservices architectures, multi-tenant environments, or simply need more control over your traffic routing, Gateway API offers the tools to meet these needs effectively.</p>



<h2 class="wp-block-heading" id="h-ingress-and-gateway-api-comparison">Ingress and Gateway API comparison</h2>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="900" height="250" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/ing-vs-ga.png" alt="" class="wp-image-34639" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/ing-vs-ga.png 900w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/ing-vs-ga-300x83.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/ing-vs-ga-768x213.png 768w" sizes="(max-width: 900px) 100vw, 900px" /></figure>
</div>


<p class="wp-block-paragraph">In Kubernetes, managing and directing traffic to applications is a critical aspect of deploying and maintaining services. Two primary methods for achieving this are the Ingress resource and the Gateway API. Both serve the purpose of handling inbound traffic, but they differ significantly in their design, functionality, and intended use cases. Understanding these differences is crucial for choosing the right approach for your specific needs.</p>



<h3 class="wp-block-heading" id="h-ingress">Ingress</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="256" height="249" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/ing-256.png" alt="" class="wp-image-34640" /></figure>
</div>


<p class="wp-block-paragraph">Ingress is one of the older and more established methods for managing external access to services within a Kubernetes cluster. It defines a set of rules for routing external HTTP and HTTPS traffic to backend services. An Ingress resource is used in conjunction with an Ingress Controller, which implements the routing rules defined in the Ingress resource.</p>



<p class="wp-block-paragraph">Key features of ingress:</p>



<ol class="wp-block-list">
<li>Simplicity and ease of use
<ul class="wp-block-list">
<li>Ingress provides a straightforward way to define routing rules using a single Kubernetes resource.</li>



<li>It is suitable for basic to moderately complex routing scenarios.</li>
</ul>
</li>



<li>Support for HTTP and HTTPS
<ul class="wp-block-list">
<li>Ingress is primarily designed to handle HTTP and HTTPS traffic.</li>



<li>It allows for features like SSL/TLS termination, name-based virtual hosting, and URL path-based routing.</li>
</ul>
</li>



<li>Integration with Ingress Controllers
<ul class="wp-block-list">
<li>Various Ingress Controllers such as NGINX, Traefik, and HAProxy can be used to implement the routing rules.</li>



<li>Each Ingress Controller may offer additional features and customizations, often managed via annotations.</li>
</ul>
</li>



<li>Annotations for extended features
<ul class="wp-block-list">
<li>Ingress relies heavily on annotations to extend its functionality, which can lead to inconsistencies and complexity.</li>



<li>Different controllers may interpret annotations differently, affecting portability.</li>
</ul>
</li>



<li>Common use cases:
<ul class="wp-block-list">
<li>Ideal for simple to moderately complex HTTP/HTTPS routing needs.</li>



<li>Suitable for scenarios where ease of use and quick setup are prioritized.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading" id="h-gateway-api">Gateway API</h3>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="900" height="250" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/gateway-api-logo.png" alt="" class="wp-image-34641" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/gateway-api-logo.png 900w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/gateway-api-logo-300x83.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/09/gateway-api-logo-768x213.png 768w" sizes="(max-width: 900px) 100vw, 900px" /></figure>
</div>


<p class="wp-block-paragraph">Gateway API is a more modern and flexible approach to traffic management in Kubernetes. It addresses some of the limitations of Ingress by providing a more powerful and extensible framework. Gateway API introduces a set of new resources designed to offer greater flexibility and control over traffic routing and management.</p>



<p class="wp-block-paragraph">Key features of gateway API:</p>



<ol class="wp-block-list">
<li>Modular and extensible design
<ul class="wp-block-list">
<li>Gateway API introduces multiple resources such as GatewayClass, Gateway, HTTPRoute, TCPRoute, and TLSRoute.</li>



<li>This modular design allows for more granular and precise control over traffic management.</li>
</ul>
</li>



<li>Support for multiple protocols
<ul class="wp-block-list">
<li>In addition to HTTP and HTTPS, Gateway API supports other protocols like TCP and TLS.</li>



<li>This makes it suitable for a broader range of use cases beyond simple web traffic.</li>
</ul>
</li>



<li>Separation of responsibilities
<ul class="wp-block-list">
<li>Gateway API separates the concerns of infrastructure management and application development.</li>



<li>Administrators can manage Gateways, while developers can define routing rules using Route resources.</li>
</ul>
</li>



<li>Advanced features and flexibility
<ul class="wp-block-list">
<li>Gateway API supports advanced features such as weighted traffic splitting, traffic mirroring, and more complex routing rules.</li>



<li>It provides a more consistent and standardized way to define and manage these features.</li>
</ul>
</li>



<li>Improved consistency and portability
<ul class="wp-block-list">
<li>Gateway API aims to reduce the reliance on annotations and provide a more consistent API surface.</li>



<li>This enhances portability across different environments and implementations.</li>
</ul>
</li>



<li>Common use cases
<ul class="wp-block-list">
<li>Ideal for complex traffic management scenarios requiring advanced routing capabilities.</li>



<li>Suitable for multi-tenant environments and architectures with microservices requiring fine-grained control over traffic routing.</li>
</ul>
</li>
</ol>



<h2 class="wp-block-heading" id="h-example-use-gateway-api-with-cilium">Example: Use Gateway API with Cilium</h2>



<p class="wp-block-paragraph">At dbi services, we follow the best practice of using Cilium as our Kubernetes CNI (Container Network Interface). If you are not familiar with Cilium you can follow these articles from my colleagues:</p>



<ul class="wp-block-list">
<li><a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/" target="_blank" rel="noreferrer noopener">Kubernetes Networking by Using Cilium – Beginner Level</a></li>



<li><a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/" target="_blank" rel="noreferrer noopener">Kubernetes Networking by Using Cilium – Intermediate Level – Network Interface</a><a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/">s</a></li>



<li><a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/" target="_blank" rel="noreferrer noopener">Kubernetes Networking by Using Cilium – Intermediate Level – Traditional Linux Routing</a></li>



<li><a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-advanced-level-ebpf-routing/" target="_blank" rel="noreferrer noopener">Kubernetes Networking by Using Cilium – Advanced Level – eBPF Routing</a></li>
</ul>



<p class="wp-block-paragraph">Cilium not only provides powerful networking and security capabilities but also implements several Gateway API features, such as:</p>



<ul class="wp-block-list">
<li><strong>GatewayClass and Gateway support:</strong> Allowing for flexible and scalable traffic management.</li>



<li><strong>L4 and L7 traffic filtering:</strong> Enabling more granular control over traffic routing.</li>



<li><strong>Native integration with HTTPRoute, GRPCRoute, and TLSRoute:</strong> Facilitating advanced protocol support and routing capabilities.</li>
</ul>



<p class="wp-block-paragraph">In this example, we will demonstrate how to install Cilium with Gateway API support and set up a simple HTTPRoute to route traffic to a backend service.</p>



<p class="wp-block-paragraph">Other Gateway API solutions exist, so if you&#8217;re familiar with other network tools (Traefik, Istio, Contour, …) or need to implement TCPRoute and/or UDPRoute resources, you&#8217;ll find a <a href="https://gateway-api.sigs.k8s.io/implementations/" target="_blank" rel="noreferrer noopener">list of implementations</a> in the official Gateway API documentation.</p>



<h3 class="wp-block-heading" id="h-prerequisites">Prerequisites</h3>



<p class="wp-block-paragraph">According to the <a href="https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/" target="_blank" rel="noreferrer noopener">Cilium&#8217;s documentation</a>, we need to add the necessary CRDs then deploy the Cilium&#8217;s Helm chart with the right options:</p>



<ul class="wp-block-list">
<li>Add Gateway API CRDs</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/v1.1.0/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml
</pre></div>


<ul class="wp-block-list">
<li>Deploy cilium on your Kubernetes with Gateway API feature</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
# Cilium install using Helm:
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium \
    --version 1.16.1 \
    --namespace kube-system \
    --set kubeProxyReplacement=true \
    --set gatewayAPI.enabled=true

# Wait for Cilium to be healthy
cilium status --wait
    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK
 /¯¯\__/¯¯\    Envoy DaemonSet:    disabled (using embedded mode)
 \__/¯¯\__/    Hubble Relay:       disabled
    \__/       ClusterMesh:        disabled

DaemonSet              cilium             Desired: 1, Ready: 1/1, Available: 1/1
Deployment             cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1
Containers:            cilium             Running: 1
                       cilium-operator    Running: 1
Cluster Pods:          14/15 managed by Cilium
</pre></div>


<h3 class="wp-block-heading" id="h-httproute-example">HTTPRoute example:</h3>



<ul class="wp-block-list">
<li>Create YAML definition file for the HTTP server deployment and service (http-server.yaml): </li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: testgw-backend
    example: http-routing
  name: testgw-backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: testgw-backend
  template:
    metadata:
      labels:
        app: testgw-backend
    spec:
      containers:
      - env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        image: gcr.io/k8s-staging-ingressconformance/echoserver:v20221109-7ee2f3e
        imagePullPolicy: IfNotPresent
        name: testgw-backend
        resources:
          requests:
            cpu: 10m
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    example: http-routing
  name: testgw-svc
spec:
  ports:
  - name: http
    port: 8080
    protocol: TCP
    targetPort: 3000
  selector:
    app: testgw-backend
  type: ClusterIP
</pre></div>


<ul class="wp-block-list">
<li>Create YAML definition file for the Gateway (gateway.yaml):</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: cilium-gateway
spec:
  gatewayClassName: cilium
# Depending on your Loadbalancer strategy, precise the IP address to use
  addresses:
  - type: IPAddress
    value: 172.22.14.96
  listeners:
  - allowedRoutes:
      namespaces:
        from: Same
    name: web-gw
    port: 80
    protocol: HTTP
</pre></div>


<ul class="wp-block-list">
<li>Create YAML definition file for the HTTPRoute (httproute.yaml):</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  labels:
    example: http-routing
  name: testgw-route
  namespace: default
spec:
  hostnames:
  - testgw.dbi-services.com
  parentRefs:
  - kind: Gateway
    name: cilium-gateway
  rules:
  - backendRefs:
    - group: &quot;&quot;
      kind: Service
      name: testgw-svc
      port: 8080
      weight: 1
    matches:
    - path:
        type: PathPrefix
        value: /get
</pre></div>


<ul class="wp-block-list">
<li>Apply the resources:</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
kubectl apply -f http-server.yaml
kubectl apply -f gateway.yaml 
kubectl apply -f httproute.yaml
</pre></div>


<ul class="wp-block-list">
<li>Check your Gateway API resources</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
kubectl get gateway
NAME             CLASS    ADDRESS         PROGRAMMED   AGE
cilium-gateway   cilium   172.22.14.96    True         9m31s

kubectl get httproute
NAME        HOSTNAMES             AGE
testgw-route   &#x5B;&quot;testgw.dbi-services.com&quot;]   11m
</pre></div>


<ul class="wp-block-list">
<li>Test an HTTP request</li>
</ul>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
curl http://testgw.dbi-services.com/get
{
 &quot;path&quot;: &quot;/get&quot;,
 &quot;host&quot;: &quot;testgw.dbi-services.com&quot;,
 &quot;method&quot;: &quot;GET&quot;,
 &quot;proto&quot;: &quot;HTTP/1.1&quot;,
 &quot;headers&quot;: {
  &quot;Accept&quot;: &#x5B;
   &quot;*/*&quot;
  ],
  &quot;User-Agent&quot;: &#x5B;
   &quot;curl/8.9.1&quot;
  ]
 },
 &quot;namespace&quot;: &quot;default&quot;,
 &quot;ingress&quot;: &quot;&quot;,
 &quot;service&quot;: &quot;&quot;,
 &quot;pod&quot;: &quot;testgw-backend-67d4f66b9b-jtj9s&quot;
}
</pre></div>


<p class="wp-block-paragraph">Well done ! Your Gateway API HTTPRouting is working ! 🎉</p>



<h2 class="wp-block-heading" id="h-conclusion">Conclusion</h2>



<p class="wp-block-paragraph">While both Ingress and Gateway API serve to manage external traffic in Kubernetes, they cater to different needs and use cases. Ingress is simpler and quicker to set up, making it ideal for straightforward HTTP/HTTPS routing scenarios. On the other hand, Gateway API offers a more powerful, flexible, and extensible framework suitable for advanced traffic management requirements, including support for multiple protocols and more complex routing configurations. Understanding these differences can help you make an informed decision on which approach to use for your Kubernetes deployments.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-traffic-control-ingress-vs-gateway-api/">Kubernetes Traffic Control: Ingress vs. Gateway API</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-traffic-control-ingress-vs-gateway-api/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kubernetes Network Policy by using Cilium &#8211; Beginner Level</title>
		<link>https://www.dbi-services.com/blog/kubernetes-network-policy-by-using-cilium-beginner-level/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-network-policy-by-using-cilium-beginner-level/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 19 Mar 2024 07:20:28 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[network policy]]></category>
		<category><![CDATA[networking]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=31754</guid>

					<description><![CDATA[<p>Kubernetes network policies explained for the beginners. We review the basics of Kubernetes network policies.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-network-policy-by-using-cilium-beginner-level/">Kubernetes Network Policy by using Cilium &#8211; Beginner Level</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In my blog post series about Kubernetes networking, I wrote <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/" target="_blank" rel="noreferrer noopener">here</a> that by default, all pods can communicate together in a “vanilla” Kubernetes. Whatever they belong to the same namespace or not. To provide network separation, we need to implement Kubernetes Network Policy.</p>



<p class="wp-block-paragraph">If your Kubernetes cluster is <a href="https://kubernetes.io/docs/concepts/security/multi-tenancy/" target="_blank" rel="noreferrer noopener">multi-tenant</a> this is going to be a requirement. Multi-tenant means the same Kubernetes cluster host several applications. Each of them is in their own namespace. However the product owners are different for each application. In this case you&#8217;ll need to isolate each application from each other. It would be very bad if from a pod of your application you could reach and connect to a pod of another application and the other way around. To provide this networking isolation we need to configure and deploy Network Policy. They are often the pet peeve of many Kubernetes Administrator that are not familiar with networking. If it is your case, this blog post is for you. I&#8217;ll give you all the basics to understand it completely.</p>



<h2 class="wp-block-heading" id="h-ingress-and-egress">Ingress and Egress</h2>



<p class="wp-block-paragraph">Kubernetes Network Policy is like a police officer in front of your pods. It allows or denies traffic entering or exiting the pod. This is the first concept to grasp, the traffic can flow in 2 directions: entering or exiting. In traditional networking we call it incoming and outgoing (sometimes it is inbound and outbound) traffic. In Kubernetes we are talking about ingress and egress but they are the same thing.</p>



<p class="wp-block-paragraph">Ingress or egress traffic depends on the point of reference. We basically apply a Network Policy to a pod. Cilium calls it an endpoint but it is the same. For this pod, the direction of traffic is egress when it comes from the pod to the outside. An ingress traffic is for traffic coming from outside and entering into this pod. The drawing below illustrates that concept:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="619" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-Egress-1024x619.png" alt="Network Policies ingress egress definition" class="wp-image-31763" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-Egress-1024x619.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-Egress-300x181.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-Egress-768x464.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-Egress.png 1446w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">On the left, the police officer looks to the pod so she will stop and filter any traffic coming from that pod before it goes outside. On the right, he looks to the outside with his back to the pod. He will then filter and stop any traffic from outside before it enters that pod.</p>



<h2 class="wp-block-heading" id="h-labels">Labels</h2>



<p class="wp-block-paragraph">As you may know, pods get their IP Address from Cilium when they start. A pod by design can be deleted and recreated which means its IP Address will change. In traditional networking, we filter traffic with firewalls or Access Control List (ACL). This layer 3 filtering is based on the IP Address. In Kubernetes we then have to use another way than IP Addresses and so we use labels instead. We set a label to each pod and if pods use the same label then they belong to the same group. It is the case for the replicas of a front end or a back end pod that will share the same label. We apply a Network Policy to a group of pods based on this label. Let&#8217;s look at this on a drawing:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="596" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Labels-1-1024x596.png" alt="Network Policies labels definition" class="wp-image-31816" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Labels-1-1024x596.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Labels-1-300x175.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Labels-1-768x447.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Labels-1-1536x894.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Labels-1.png 1946w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">In our example we have 2 applications in 2 separate namespaces. Each application has 2 Front End (FE) and 2 Back End (BE). In the namespace app1, the FE have the same label &#8220;<strong>app: frontend1&#8243;</strong> and the BE have the label &#8220;<strong>app:backend1&#8243;</strong>. We apply the same to the namespace app2.</p>



<h2 class="wp-block-heading" id="h-cilium-network-policy">Cilium Network Policy</h2>



<p class="wp-block-paragraph">Kubernetes provides an object called <strong>NetworkPolicy</strong> that is implemented by the Container Network Interface (CNI). Cilium is using its own object called <strong>CiliumNetworkPolicy</strong> that extends the capabilities of that standard Network Policy object. You can learn more about it from this <a href="https://isovalent.com/blog/post/intro-to-cilium-network-policies/" target="_blank" rel="noreferrer noopener">Isovalent blog post</a>.</p>



<p class="wp-block-paragraph">A Network Policy is a yaml file where we configure to which pod labels it applies as well as the ingress and/or egress rules we apply to them. When we apply that yaml file in our cluster, we set the police officer in front of the pods door.</p>



<h3 class="wp-block-heading" id="h-kubernetes-network-policy-ingress-rule">Kubernetes Network Policy ingress rule</h3>



<p class="wp-block-paragraph">Let&#8217;s look at an example and start with an ingress rule. We will use the simple CiliumNetworkPolicy below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [5,7,10]; title: ; notranslate">
apiVersion: &quot;cilium.io/v2&quot;
kind: CiliumNetworkPolicy
metadata:
  name: &quot;ingress-backend-rule&quot;
  namespace: app1
spec:
  endpointSelector:
    matchLabels:
      app: backend1
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend1
</pre></div>


<p class="wp-block-paragraph">This CiliumNetworkPolicy applies to any pod in the namespace <strong>app1</strong> that has the label &#8220;<strong>app: backend1</strong>&#8220;. Only one ingress rule is applied here where traffic from all pods with the label &#8220;<strong>app: frontend1</strong>&#8221; is allowed. Any other ingress traffic will be discarded. Below is the drawing showing it in a visual way:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="543" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-3-1024x543.png" alt="Network Policies ingress rules definition" class="wp-image-31817" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-3-1024x543.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-3-300x159.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-3-768x407.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-3-1536x814.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Ingress-3-2048x1086.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">When any traffic in this Kubernetes cluster reach the pods BE 1 or BE 2 in the namespace app1, the ingress rules of our Network Policy applies. Only traffic coming from the pods FE 1 or FE 2 in the namespace app1 will be allowed to enter because they have the authorized label.</p>



<h3 class="wp-block-heading" id="h-kubernetes-network-policy-egress-rule">Kubernetes Network Policy egress rule</h3>



<p class="wp-block-paragraph">Let&#8217;s continue with a simple egress rule. We will use the CiliumNetworkPolicy below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [5,7,10]; title: ; notranslate">
apiVersion: &quot;cilium.io/v2&quot;
kind: CiliumNetworkPolicy
metadata:
  name: &quot;egress-frontend-rule&quot;
  namespace: app1
spec:
  endpointSelector:
    matchLabels:
      app: frontend1
  egress:
  - toEndpoints:
    - matchLabels:
        app: backend1
</pre></div>


<p class="wp-block-paragraph">This CiliumNetworkPolicy applies to any pod in the namespace <strong>app1</strong> that has the label &#8220;<strong>app: frontend1</strong>&#8220;. Only one egress rule is applied here where traffic to pods with the label &#8220;<strong>app: backend1</strong>&#8221; is allowed. Any other egress traffic from there pods will be discarded. Below is the drawing showing it in a visual way:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="552" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Egress-1024x552.png" alt="Network Policies egress rules definition" class="wp-image-31841" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Egress-1024x552.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Egress-300x162.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Egress-768x414.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Egress-1536x829.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/03/CNP-Egress-2048x1105.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">When traffic from the pods FE 1 or FE 2 in the namespace app1 is going out, the egress rule of our Network Policy applies. Only traffic to pods BE 1 and BE 2 will be allowed as they have the authorized label.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">We&#8217;ve covered the basics of Kubernetes Network Policy by explaining what are its key components: Ingress, egress, labels and the CiliumNetworkPolicy object. Then we&#8217;ve seen a simple example of ingress and egress rules and illustrated them with a drawing. These basics should get you started in the world of Kubernetes Network Policy.</p>



<p class="wp-block-paragraph">With the simple ingress and egress rules above did we completely isolate the traffic flow between FE and BE in app1? The answer is no because from BE 1 or BE 2 I can still reach any pods in the cluster. There is only an ingress rule but no egress rule. The same, any traffic can reach FE 1 or FE 2 because there is only an egress rule but no ingress rule. I would then need to configure an ingress rule and an egress rule (the same as above) into the same CiliumNetworkPolicy. Congratulations, you&#8217;ve just entered into the complex world of Kubernetes Network Policy!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-network-policy-by-using-cilium-beginner-level/">Kubernetes Network Policy by using Cilium &#8211; Beginner Level</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-network-policy-by-using-cilium-beginner-level/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kubernetes Networking by Using Cilium – Advanced Level – eBPF Routing</title>
		<link>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-advanced-level-ebpf-routing/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-advanced-level-ebpf-routing/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 05 Mar 2024 07:18:54 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[ebpf]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[networking]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=31435</guid>

					<description><![CDATA[<p>The DevOps technology Kubernetes uses a complex networking process when using Cilium. Cilium leverage eBPF for a fast and efficient routing in Kubernetes.</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-advanced-level-ebpf-routing/">Kubernetes Networking by Using Cilium – Advanced Level – eBPF Routing</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">We have come a long way regarding networking in Kubernetes using Cilium. From a high level picture in this <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/" target="_blank" rel="noreferrer noopener">post</a>, we moved to discovering the Kubernetes networking interfaces in this <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/" target="_blank" rel="noreferrer noopener">post</a> and dived into linux routing in Kubernetes in this <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/" target="_blank" rel="noreferrer noopener">post</a>.</p>



<p class="wp-block-paragraph">If you still want to know more, then you are in the right place. Fasten your seat belt because in this blog post we will dive deep into the eBPF routing. When using Cilium for networking in your Kubernetes cluster, you will automatically use eBPF for routing between pods. I&#8217;ll stick to the same 2 examples of routing between pods on the same node and on different nodes. You&#8217;ll then see the continuity on the same drawing that will hopefully help you understand this routing topic completely.</p>



<h2 class="wp-block-heading" id="h-discovering-ebpf">Discovering eBPF</h2>



<h3 class="wp-block-heading" id="h-ebpf-routing">eBPF Routing</h3>



<p class="wp-block-paragraph">In my high level blog and in the previous one about routing, I&#8217;ve talked about servants that are waiting at some network interfaces to help and direct you in the Kubernetes cluster. I&#8217;ve told you they were using a magical eBPF map to guide you through a secret passage toward your destination. Let&#8217;s now see what these servants are exactly in our Kubernetes cluster.</p>



<p class="wp-block-paragraph">A servant is actually an eBPF program attached to a network interface at the kernel level. That is what eBPF allows you to do, modify the kernel dynamically. The advantage is that you can attach your own program (that is C code transformed to machine code) to some events and network interfaces in the kernel and trigger any action you have programmed. An action could be routing a packet or report and act on any interaction with the kernel. This is why eBPF fits nicely for observability because anything happening in a node interact with the kernel. It could be running a process, opening a file, routing a packet,&#8230; Regarding routing, it is very fast because it shortcuts the traditional Linux routing process. That is the reason why we couldn&#8217;t see all the routing steps in the previous post by using our traditional networking tools. We now need eBPF tools to inspect this routing in more details.</p>



<h3 class="wp-block-heading" id="h-cilium-agent-and-ebpf-routing">Cilium Agent and eBPF routing</h3>



<p class="wp-block-paragraph">You know from the previous posts that there is a Cilium agent pod on each node in the cluster. This agent takes care of everything about networking on that node and so also eBPF routing. It comes with some eBPF tools packed with it that will allow us to explore it more deeply.</p>



<p class="wp-block-paragraph">Let&#8217;s now see what these servants really look like in our cluster. As a reminder and to gather all the information here, below are all our Cilium agents in our cluster:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [3,4]; title: ; notranslate">
$ kubectl get po -n kube-system -owide|grep cilium
cilium-9zh9s                                      1/1     Running   5 (65m ago)   113d   172.18.0.3    mycluster-control-plane   &lt;none&gt;           &lt;none&gt;
cilium-czffc                                      1/1     Running   5 (65m ago)   113d   172.18.0.4    mycluster-worker2         &lt;none&gt;           &lt;none&gt;
cilium-dprvh                                      1/1     Running   5 (65m ago)   113d   172.18.0.2    mycluster-worker          &lt;none&gt;           &lt;none&gt;
cilium-operator-6b865946df-24ljf                  1/1     Running   5 (65m ago)   113d   172.18.0.2    mycluster-worker          &lt;none&gt;           &lt;none&gt;
</pre></div>


<p class="wp-block-paragraph">As before in this series, we will trace the routing from a pod on the node <strong>mycluster-worker</strong> and so we will need to interact with the Cilium agent of that node: cilium-dprvh. We use into that agent pod the tool <strong>bpftool</strong> to list all the network interfaces and the eBPF programs attached to them:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [13]; title: ; notranslate">
$ kubectl exec -it -n kube-system cilium-dprvh -- bpftool net show
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
xdp:

tc:
cilium_net(2) clsact/ingress cil_to_host-cilium_net id 1209
cilium_host(3) clsact/ingress cil_to_host-cilium_host id 1184
cilium_host(3) clsact/egress cil_from_host-cilium_host id 1197
cilium_vxlan(4) clsact/ingress cil_from_overlay-cilium_vxlan id 1154
cilium_vxlan(4) clsact/egress cil_to_overlay-cilium_vxlan id 1155
lxc_health(6) clsact/ingress cil_from_container-lxc_health id 1295
eth0(7) clsact/ingress cil_from_netdev-eth0 id 1223
lxc4a891387ff1a(9) clsact/ingress cil_from_container-lxc4a891387ff1a id 1285
lxc5b7b34955e61(11) clsact/ingress cil_from_container-lxc5b7b34955e61 id 1303
lxc73d2e1d7cf4(13) clsact/ingress cil_from_container-lxc73d2e1d7cf4 id 1294
</pre></div>


<p class="wp-block-paragraph">Yes these programs are our servants! Armed with the knowledge of the network interfaces in a previous <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/" target="_blank" rel="noreferrer noopener">post</a> you should recognize their names. The one that will be used at the starting point of our travel is lxc4a891387ff1a. In parenthesis you have the interface id 9 that is on the node side of this link to this container. The Cilium agent assigned to this interface the id 1285. The name of the program attached to this interface is called <strong>cil_from_container</strong>. From this name, you know for which direction the program will operate. Here it is for the traffic coming from the container to the node, in the other direction there is no processing. As the Cilium community edition is open source, you can read its code directly <a href="https://github.com/cilium/cilium/tree/main/bpf" target="_blank" rel="noreferrer noopener">here</a>. In the file <strong>bpf_lxc.c</strong> just search for the program name and you will see all the details. Yes, this is advanced but don&#8217;t worry, I did the hard work for you, so you just have to read along!</p>



<p class="wp-block-paragraph">Before we move on to trace the eBPF routing, let&#8217;s update our drawing to show these eBPF servants:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="462" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-5-1024x462.png" alt="Kubernetes networking routing with Cilium using eBPF" class="wp-image-31465" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-5-1024x462.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-5-300x135.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-5-768x346.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-5-1536x693.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-5.png 2044w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Kubernetes networking routing with Cilium using eBPF</figcaption></figure>
</div>


<p class="wp-block-paragraph">Don&#8217;t be confused about the lxc network interface id. For example lxc4a891387ff1a(9) from the command output above. It means it is linked to id 9 which is on the node side, on the interface called lxc&#8230;.@if8. Id 8 being the id inside of the container (you will see in it 8: eth0@if9).</p>



<h2 class="wp-block-heading" id="h-pod-to-pod-routing-on-the-same-node">Pod to pod routing on the same node</h2>



<p class="wp-block-paragraph">I don&#8217;t want to lose you with all the details so I&#8217;ll give you only the key information to follow along this eBPF routing. Yes, from here it is becoming more complicated but I&#8217;ll try to make it smooth for you to enjoy it anyway.</p>



<p class="wp-block-paragraph">As we did in the previous post, let&#8217;s now see how eBPF routes the traffic thanks to its servants from 10.10.2.117 to 10.10.2.121. The Cilium agent gives information to the eBPF program and receives information from them. For exchanging information, it uses what is called <strong>maps</strong> (yes these are our magic maps!) in the eBPF terminology. There are several of them that are used for different purposes. These maps are stored in the folder <strong>/sys/fs/bpf/tc/globals</strong> into the Cilium agent pod and we can manually interact with them by using the <strong>bpftool</strong>. We can then trace the eBPF routing that way. When the packet leaves the container, it reaches the lxc interface on the node and the program <strong>cil_from_container</strong> is triggered to route that packet. The program sees the destination IP Address is in the same subnet as the source and will then just forward the traffic to the destination lxc network interface by using the map called <strong>cilium_lxc</strong>.</p>



<p class="wp-block-paragraph">Below is how we can trace that eBPF routing:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [7,8]; title: ; notranslate">
$ kubectl exec -it -n kube-system cilium-dprvh -- bpftool map lookup pinned /sys/fs/bpf/tc/globals/cilium_lxc key hex 0a 0a 02 79 00 00 00 00  00 00 00 00 00 00 00 00 01 00 00 00
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
key:
0a 0a 02 79 00 00 00 00  00 00 00 00 00 00 00 00
01 00 00 00
value:
0b 00 00 00 00 00 33 06  00 00 00 00 00 00 00 00
ea c4 71 d6 4f a0 00 00  f6 87 b6 c3 a6 45 00 00
2c 0d 00 00 00 00 00 00  00 00 00 00 00 00 00 00
</pre></div>


<p class="wp-block-paragraph">We have to give to the <strong>bpftool</strong> an hexadecimal string that it expects (the details of this format can be found in the source code). The destination IP Address we want to trace is 10.10.2.121 which is 0a 0a 02 79 in hexadecimal. This information is at the beginning of the string in our command.</p>



<p class="wp-block-paragraph">In the output of this command you can see the key section, which is the hexadecimal string we have provided as well as the result in the value section.</p>



<p class="wp-block-paragraph">In this result we get the MAC Address of the destination lxc interface on the pod side which is ea c4 71 d6 4f a0. We also get the MAC Address of the destination lxc interface on the node side which is f6 87 b6 c3 a6 45. Finally we get the lxc id of the destination pod which is 33 06. A little trick here is that this value is stored in reverse order (you can do a search about big endian and little endian if you want to know more on this) so we have to read 06 33 which converted to decimal gives 1587. This value is the endpoint ID used by Cilium to identify the pods. You can get this general information in the cluster with the following command:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [5]; title: ; notranslate">
$ kubectl get ciliumendpoint -n networking101
NAME                        ENDPOINT ID   IDENTITY ID   INGRESS ENFORCEMENT   EGRESS ENFORCEMENT   VISIBILITY POLICY   ENDPOINT STATE   IPV4          IPV6
busybox-c8bbbbb84-fmhwc     897           3372          &lt;status disabled&gt;     &lt;status disabled&gt;    &lt;status disabled&gt;   ready            10.10.1.164
busybox-c8bbbbb84-t6ggh     715           3372          &lt;status disabled&gt;     &lt;status disabled&gt;    &lt;status disabled&gt;   ready            10.10.2.117
netshoot-7d996d7884-fwt8z   1587          10388         &lt;status disabled&gt;     &lt;status disabled&gt;    &lt;status disabled&gt;   ready            10.10.2.121
netshoot-7d996d7884-gcxrm   3564          10388         &lt;status disabled&gt;     &lt;status disabled&gt;    &lt;status disabled&gt;   ready            10.10.1.155
</pre></div>


<p class="wp-block-paragraph">So the destination pod is netshoot-7d996d7884-fwt8z and it is reached directly through its lxc interface. And that&#8217;s it! Of course the routing occurs much faster than me explaining it but more importantly it is faster than the traditional Linux routing.</p>



<h2 class="wp-block-heading" id="h-pod-to-pod-routing-on-a-different-node">Pod to pod routing on a different node</h2>



<p class="wp-block-paragraph">Let&#8217;s now check the eBPF routing from 10.10.2.117 to 10.10.1.155 which is then on a different node. The packet is also intercepted by the program <strong>cil_from_container</strong> but this time the destination IP Address belongs to another subnet so it is going to use another map called <strong>cilium_ipcache</strong> to route that packet.</p>



<p class="wp-block-paragraph">As before, we have to provide an hexadecimal string in the expected format to trace the routing of this packet. Here, our destination IP Address is 10.10.1.155 so 0a 0a 01 9b in hexadecimal.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [7]; title: ; notranslate">
$ kubectl exec -it -n kube-system cilium-dprvh -- bpftool map lookup pinned /sys/fs/bpf/tc/globals/cilium_ipcache key hex 40 00 00 00 00 00 00 01 0a 0a 01 9b 00 00 00 00 00 00 00 00 00 00 00 00
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
key:
40 00 00 00 00 00 00 01  0a 0a 01 9b 00 00 00 00
00 00 00 00 00 00 00 00
value:
94 28 00 00 ac 12 00 04  00 00 00 00
</pre></div>


<p class="wp-block-paragraph">In the value section we can see the destination IP Address of the node mycluster-worker2 which is ac 12 00 04 (172.18.0.4). From there, the packet is encapsulated and goes straight to the egress VXLAN interface to reach that node. Once there, it is now the eBPF programs of the Cilium agent pod on this node that will be used. Let&#8217;s check them as we did before for the other node:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [9,15]; title: ; notranslate">
$ kubectl exec -it -n kube-system cilium-czffc -- bpftool net show
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
xdp:

tc:
cilium_net(2) clsact/ingress cil_to_host-cilium_net id 1254
cilium_host(3) clsact/ingress cil_to_host-cilium_host id 1242
cilium_host(3) clsact/egress cil_from_host-cilium_host id 1246
cilium_vxlan(4) clsact/ingress cil_from_overlay-cilium_vxlan id 1163
cilium_vxlan(4) clsact/egress cil_to_overlay-cilium_vxlan id 1164
lxc_health(6) clsact/ingress cil_from_container-lxc_health id 1414
lxc0a97661d8043(8) clsact/ingress cil_from_container-lxc0a97661d8043 id 1387
eth0(9) clsact/ingress cil_from_netdev-eth0 id 1261
lxc174c023046ff(11) clsact/ingress cil_from_container-lxc174c023046ff id 1391
lxce84a702bb02c(13) clsact/ingress cil_from_container-lxce84a702bb02c id 1419
</pre></div>


<p class="wp-block-paragraph">The output is similar to the other node. So, once the packet exits the VXLAN tunnel, it is caught by another program on the ingress VXLAN interface called <strong>cil_from_overlay-cilium_vxlan</strong>. This program sees the destination IP Address belongs to this node. It will then use the map <strong>cilium_lxc</strong> to forward the traffic to the lxc interface of the destination pod as we have seen before. Note that there is no programs in the list above called to_container so the packet in not processed further. We can then trace that eBPF routing part as before by using the hexadecimal value of our destination IP Address 10.10.1.155:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [7,8]; title: ; notranslate">
$ kubectl exec -it -n kube-system cilium-dprvh -- bpftool map lookup pinned /sys/fs/bpf/tc/globals/cilium_lxc key hex 0a 0a 01 9b 00 00 00 00  00 00 00 00 00 00 00 00 01 00 00 00
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
key:
0a 0a 01 9b 00 00 00 00  00 00 00 00 00 00 00 00
01 00 00 00
value:
0b 00 00 00 00 00 ec 0d  00 00 00 00 00 00 00 00
be 57 3d 54 40 f1 00 00  92 65 df 09 dd 28 00 00
2c 0d 00 00 00 00 00 00  00 00 00 00 00 00 00 00
</pre></div>


<p class="wp-block-paragraph">The result gives us the following information:</p>



<ul class="wp-block-list">
<li>92 65 df 09 dd 28: This is the MAC Address of the destination lxc interface on the node side</li>



<li>be 57 3d 54 40 f1: This is the MAC Address of the destination lxc interface on the pod side</li>



<li>ec 0d: We reverse it to 0d ec which we convert to 3564. This is the Cilium endpoint of the destination pod netshoot-7d996d7884-gcxrm as we have seen previously (you can check the output of the command above and find that pod).</li>
</ul>



<p class="wp-block-paragraph">As before, from here the packet is directly forwarded to this destination pod. This is how an eBPF routing plan comes up together!</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">Wow! Congratulations if you&#8217;ve reached that point! You are champions! You now have the complete and detailed picture of how the basic networking between pods is working with Cilium in a Kubernetes cluster. There is more to cover as I&#8217;ve mentioned network policies in a previous post but we didn&#8217;t talk about services, ingress or name resolution. Also in addition to these basic Kubernetes networking topics, Cilium provides a lot of other features that enrich what can be done in a cluster. So stay tuned!</p>



<p class="wp-block-paragraph"> </p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-advanced-level-ebpf-routing/">Kubernetes Networking by Using Cilium – Advanced Level – eBPF Routing</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-advanced-level-ebpf-routing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kubernetes Networking by Using Cilium – Intermediate Level – Traditional Linux Routing</title>
		<link>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Mon, 26 Feb 2024 08:34:41 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[ebpf]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[networking]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=31207</guid>

					<description><![CDATA[<p>Discover a DevOps technology that is about Kubernetes Networking by using Cilium. </p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/">Kubernetes Networking by Using Cilium – Intermediate Level – Traditional Linux Routing</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Welcome back in this blog post series about Kubernetes Networking by using Cilium. In the <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/" target="_blank" rel="noreferrer noopener">previous post</a> about network interfaces, we&#8217;ve looked at how we can identify all the interfaces that will be involved in the routing between pods. I&#8217;ve also explained the routing in a Kubernetes cluster with Cilium in a non technical language in this <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/" target="_blank" rel="noreferrer noopener">blog post</a>. Let&#8217;s now see it into actions for the techies!</p>



<p class="wp-block-paragraph">Below is the drawing of where we left off:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="503" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-6-1024x503.png" alt="Kubernetes networking interfaces with Cilium." class="wp-image-31307" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-6-1024x503.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-6-300x148.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-6-768x378.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-6-1536x755.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-6.png 1924w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">We will continue to use the same method, you are the packet that will travel from your apartment (pod) 10.10.2.117 on the top left to other pods in this Kubernetes cluster. But first, let&#8217;s take this opportunity to talk about namespace and enrich our drawing with a new analogy.</p>



<h2 class="wp-block-heading" id="h-routing-between-namespaces">Routing between namespaces</h2>



<p class="wp-block-paragraph">A namespace is a logical group of objects that provide isolation in the cluster. However, by default, all pods can communicate together in a &#8220;vanilla&#8221; Kubernetes. Whatever they belong to the same namespace or not. So this isolation provided by namespace doesn&#8217;t mean the pods can&#8217;t communicate together. To allow or deny such communication, you will need to create network policies. That could be the topic for another blog post!</p>



<p class="wp-block-paragraph">We can use the analogy of a namespace being the same floor number of all building of our cluster. All apartments on the same floor in each building will be logically grouped into the same namespace. This is what we can see below in our namespace called <strong>networking101</strong>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl get po -n networking101 -owide
NAME                        READY   STATUS    RESTARTS       AGE    IP            NODE                NOMINATED NODE   READINESS GATES
busybox-c8bbbbb84-fmhwc     1/1     Running   1 (125m ago)   4d1h   10.10.1.164   mycluster-worker2   &lt;none&gt;           &lt;none&gt;
busybox-c8bbbbb84-t6ggh     1/1     Running   1 (125m ago)   4d1h   10.10.2.117   mycluster-worker    &lt;none&gt;           &lt;none&gt;
netshoot-7d996d7884-fwt8z   1/1     Running   0              103m   10.10.2.121   mycluster-worker    &lt;none&gt;           &lt;none&gt;
netshoot-7d996d7884-gcxrm   1/1     Running   0              103m   10.10.1.155   mycluster-worker2   &lt;none&gt;           &lt;none&gt;
</pre></div>


<p class="wp-block-paragraph">That&#8217;s our 4 apartments / pods on the same floor, grouped together in one namespace:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="496" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-4-2-1024x496.png" alt="Kubernetes networking interfaces and namespace with Cilium." class="wp-image-31310" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-4-2-1024x496.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-4-2-300x145.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-4-2-768x372.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-4-2-1536x744.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-4-2.png 1978w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The routing process doesn&#8217;t care about the pod&#8217;s namespace, only its destination IP Address will be used. Let&#8217;s now see how we can go from the apartment 10.10.2.117 to the apartment 10.10.2.121 in the same building (node).</p>



<h2 class="wp-block-heading" id="h-pod-to-pod-routing-on-the-same-node">Pod to pod routing on the same node</h2>



<p class="wp-block-paragraph">From the pod 10.10.2.117, you&#8217;ve then decided to go to pay a visit to 10.10.2.121. You first look at the routing table in order to know how to reach this destination. But you can&#8217;t go out if you don&#8217;t also have the MAC Address of your destination. You need both destination information (IP Address and MAC Address) before you can start to travel. You then look at the ARP table to find out this information. The ARP table contains the known mapping of a MAC Address to an IP Address in your IP subnet. If it is not there, you send first a scout to knock at the door of each apartment in your community until you find the MAC Address of your destination. This is called the ARP request. When the scout comes back with that information, you write it into the ARP table. You thank the scout for his help and are now ready to start your travel by exiting the pod.</p>



<p class="wp-block-paragraph">Let&#8217;s see how we can trace this in our source pod 10.10.2.117</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n networking101 busybox-c8bbbbb84-t6ggh -- ip route
default via 10.10.2.205 dev eth0
10.10.2.205 dev eth0 scope link
</pre></div>


<p class="wp-block-paragraph">Very simple routing instruction! For every destination, you go through 10.10.2.205 by using your only network interface eth0 in the pod. You can see from the drawing above that 10.10.2.205 is the IP Address of the cilium_host. You then check your ARP table:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n networking101 busybox-c8bbbbb84-t6ggh -- arp -a
</pre></div>


<p class="wp-block-paragraph">The arp -a command list the content of the ARP table and we can see there is nothing in there.</p>



<p class="wp-block-paragraph">A way to send a scout out is by using the <strong>arping</strong> tool toward our destination. You may have noticed that for my pods I&#8217;m using busybox and netshoot images. Both provide networking tools that are useful for troubleshooting:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n networking101 busybox-c8bbbbb84-t6ggh -- arping 10.10.2.121
ARPING 10.10.2.121 from 10.10.2.117 eth0
Unicast reply from 10.10.2.121 &#x5B;d6:21:74:eb:67:6b] 0.028ms
Unicast reply from 10.10.2.121 &#x5B;d6:21:74:eb:67:6b] 0.092ms
Unicast reply from 10.10.2.121 &#x5B;d6:21:74:eb:67:6b] 0.123ms
^CSent 3 probe(s) (1 broadcast(s))
Received 3 response(s) (0 request(s), 0 broadcast(s))
</pre></div>


<p class="wp-block-paragraph">We now have the piece of information that was missing, the MAC address of our destination. We can then just check it is written into our ARP table of our source pod:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n networking101 busybox-c8bbbbb84-t6ggh -- arp -a
? (10.10.2.205) at d6:21:74:eb:67:6b &#x5B;ether]  on eth0
</pre></div>


<p class="wp-block-paragraph">Here it is! However you may wonder why we don&#8217;t see here the IP Address of our destination 10.10.2.121 right? In traditional networking this is what you will see but here we are in a Kubernetes cluster and we are using Cilium that is taking care of the networking in it. Also we have seen above from the routing table of the source pod that for every destination we go to this cilium_host interface.</p>



<p class="wp-block-paragraph">So the cilium_host on that node is attracting all the traffic even for communication between pods in the same IP subnet. </p>



<p class="wp-block-paragraph">As a side note, below is a command where you can quickly display all the IP Addresses of the cilium_host and the nodes in your cluster in one shot:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [4,5]; title: ; notranslate">
$ kubectl get ciliumnodes
NAME                      CILIUMINTERNALIP   INTERNALIP   AGE
mycluster-control-plane   10.10.0.54         172.18.0.3   122d
mycluster-worker          10.10.2.205        172.18.0.2   122d
mycluster-worker2         10.10.1.55        172.18.0.4   122d
</pre></div>


<p class="wp-block-paragraph">In traditional networking, doing L2 switching, the MAC Address of the destination is the one related to the destination IP Address. That is not the case here in Kubernetes networking. So which interface has the MAC Address d6:21:74:eb:67:6b ? Let&#8217;s respond to that question immediately:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [4]; title: ; notranslate">
$ sudo docker exec -it mycluster-worker ip a | grep -iB1 d6:21:74:eb:67:6b
9: lxc4a891387ff1a@if8: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d6:21:74:eb:67:6b brd ff:ff:ff:ff:ff:ff link-netns cni-67a5da05-a221-ade5-08dc-64808339ad05
</pre></div>


<p class="wp-block-paragraph">That is the LXC interface of the node as it is indeed our next step from the source pod to reach our destination. You&#8217;ve learned from my first <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/" target="_blank" rel="noreferrer noopener">post blog</a> of this networking series that there is a servant waiting here at the LXC interface to direct us toward our destination.</p>



<p class="wp-block-paragraph">From there, we don&#8217;t see much of the travel to the destination from the traditional Linux routing point of view. This is because the routing is done by the Cilium agent using eBPF. As the destination is in the same IP subnet as the source, the Cilium agent just switch it directly to the destination LXC interface and then reach the destination pod.</p>



<p class="wp-block-paragraph">When the destination pod responds to the source, the same process occurs and for the sake of completeness let&#8217;s look at the routing table and ARP table in the destination pod:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n networking101 netshoot-7d996d7884-fwt8z -- ip route
default via 10.10.2.205 dev eth0 mtu 1450
10.10.2.205 dev eth0 scope link

$ kubectl exec -it -n networking101 netshoot-7d996d7884-fwt8z -- arp -a
? (10.10.2.205) at 92:65:df:09:dd:28 &#x5B;ether]  on eth0

$ sudo docker exec -it mycluster-worker ip a | grep -iB1 92:65:df:09:dd:28
13: lxce84a702bb02c@if12: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 92:65:df:09:dd:28 brd ff:ff:ff:ff:ff:ff link-netns cni-d259ef79-a81c-eba6-1255-6e46b8d1c779
</pre></div>


<p class="wp-block-paragraph">So from the traditional Linux routing point of view, everything goes to the cilium_host and the destination MAC address is the LXC interface of the node that is linked to our pod. This is exactly the same we have seen with our source pod.</p>



<h2 class="wp-block-heading" id="h-pod-to-pod-routing-on-a-different-node">Pod to pod routing on a different node</h2>



<p class="wp-block-paragraph">Let&#8217;s now have a look at how we could reach the pod 10.10.1.155 from the source pod 10.10.2.117 which is hosted in another node. The routing is the same at the beginning but when talking to the servant at the LXC interface, he sees that the destination IP Address doesn&#8217;t belong to the same IP subnet and so directs us to the cilium_host in the Lobby. From there we are routed to the cilium_vxlan interface to reach the node that host our destination pod.</p>



<p class="wp-block-paragraph">Let&#8217;s now have a look at the routing table of the host:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [4]; title: ; notranslate">
$ sudo docker exec -it mycluster-worker ip route
default via 172.18.0.1 dev eth0
10.10.0.0/24 via 10.10.2.205 dev cilium_host proto kernel src 10.10.2.205 mtu 1450
10.10.1.0/24 via 10.10.2.205 dev cilium_host proto kernel src 10.10.2.205 mtu 1450
10.10.2.0/24 via 10.10.2.205 dev cilium_host proto kernel src 10.10.2.205
10.10.2.205 dev cilium_host proto kernel scope link
172.18.0.0/16 dev eth0 proto kernel scope link src 172.18.0.2
</pre></div>


<p class="wp-block-paragraph">We don&#8217;t see much here as the routing is using eBPF and is managed by the Cilium agent as we&#8217;ve seen before.</p>



<p class="wp-block-paragraph">As a side note and to share everything with you, the output of the network interfaces as well as the ip route in the Cilium agent pod is identical to the one of the node. This is because at startup the Cilium agent provides these information to the node. You can check the Cilium agent with the following commands:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n kube-system cilium-dprvh -- ip a
$ kubectl exec -it -n kube-system cilium-dprvh -- ip route
</pre></div>


<p class="wp-block-paragraph">So you go through the VXLAN tunnel and you reach the node mycluster-worker2. Here is the routing table of this node:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [4]; title: ; notranslate">
$ sudo docker exec -it mycluster-worker2 ip route
default via 172.18.0.1 dev eth0
10.10.0.0/24 via 10.10.1.55 dev cilium_host proto kernel src 10.10.1.55 mtu 1450
10.10.1.0/24 via 10.10.1.55 dev cilium_host proto kernel src 10.10.1.55
10.10.1.55 dev cilium_host proto kernel scope link
10.10.2.0/24 via 10.10.1.55 dev cilium_host proto kernel src 10.10.1.55 mtu 1450
172.18.0.0/16 dev eth0 proto kernel scope link src 172.18.0.4
</pre></div>


<p class="wp-block-paragraph">Again from the traditional Linux routing point of view there isn&#8217;t much to see, except that all the traffic for the pods subnet are going to the cilium_host that is managed by the Cilium agent. This is identical as what we&#8217;ve learned in the other node. When we reach the cilium_vxlan interface, a servant is waiting for us with his magical eBPF map and directs us through a secret passage to the LXC corridor interface of the top left pod where we can reach our destination.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">We&#8217;ve explored all that can be seen in routing from the traditional Linux point of view by using the common networking tools.</p>



<p class="wp-block-paragraph">Maybe you feel frustrated to not understand it completely because there are some gaps in this step-by-step packet routing? Cilium uses eBPF for routing the packets so it adds some complexity to the routing understanding. However it is much faster than the traditional Linux routing due to the secret passages opened by the eBPF servants.</p>



<p class="wp-block-paragraph">If you want to know more about this, don&#8217;t miss my next <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-advanced-level-ebpf-routing/" target="_blank" rel="noreferrer noopener">blog post</a> where I&#8217;ll dive deep into the meanders of eBPF routing. See you there!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/">Kubernetes Networking by Using Cilium – Intermediate Level – Traditional Linux Routing</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kubernetes Networking by Using Cilium &#8211; Intermediate Level &#8211; Network Interfaces</title>
		<link>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Tue, 20 Feb 2024 07:36:39 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[networking]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=30953</guid>

					<description><![CDATA[<p>If you are new or uneasy with networking in Kubernetes, you may benefit from my previous blog for beginner level. In this blog post I will show you in a Kubernetes cluster what a building and its networking components look like. As a reminder, below is the picture I drew in my previous blog to [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/">Kubernetes Networking by Using Cilium &#8211; Intermediate Level &#8211; Network Interfaces</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">If you are new or uneasy with networking in Kubernetes, you may benefit from my <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/" target="_blank" rel="noreferrer noopener">previous blog for beginner level</a>. In this blog post I will show you in a Kubernetes cluster what a building and its networking components look like. As a reminder, below is the picture I drew in my previous blog to illustrate the networking in a Kubernetes cluster with Cilium:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="586" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-1024x586.png" alt="Kubernetes networking with Cilium" class="wp-image-30956" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-1024x586.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-300x172.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-768x440.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3.png 1334w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">If you want to understand this networking in Kubernetes in more details, read on, this blog post is for you! I&#8217;ll consider you know the basics about Kubernetes and how to interact with it, otherwise you may find our <a href="https://www.dbi-services.com/courses/docker-and-kubernetes-essential-skills/" target="_blank" rel="noreferrer noopener">training course</a> on it very interesting (in English or in French)!</p>



<h2 class="wp-block-heading" id="h-diving-into-the-ip-addresses-configuration">Diving into the IP Addresses configuration</h2>



<p class="wp-block-paragraph">Let&#8217;s start by checking our environment and update our picture with real information from our Kubernetes cluster:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl get no -owide
NAME                      STATUS   ROLES           AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION      CONTAINER-RUNTIME
mycluster-control-plane   Ready    control-plane   113d   v1.27.3   172.18.0.3    &lt;none&gt;        Debian GNU/Linux 11 (bullseye)   5.15.0-94-generic   containerd://1.7.1
mycluster-worker          Ready    &lt;none&gt;          113d   v1.27.3   172.18.0.2    &lt;none&gt;        Debian GNU/Linux 11 (bullseye)   5.15.0-94-generic   containerd://1.7.1
mycluster-worker2         Ready    &lt;none&gt;          113d   v1.27.3   172.18.0.4    &lt;none&gt;        Debian GNU/Linux 11 (bullseye)   5.15.0-94-generic   containerd://1.7.1

$ kubectl get po -n networking101 -owide
NAME                        READY   STATUS    RESTARTS      AGE     IP            NODE                NOMINATED NODE   READINESS GATES
busybox-c8bbbbb84-fmhwc     1/1     Running   1 (24m ago)   3d23h   10.10.1.164   mycluster-worker2   &lt;none&gt;           &lt;none&gt;
busybox-c8bbbbb84-t6ggh     1/1     Running   1 (24m ago)   3d23h   10.10.2.117   mycluster-worker    &lt;none&gt;           &lt;none&gt;
netshoot-7d996d7884-fwt8z   1/1     Running   0             79s     10.10.2.121   mycluster-worker    &lt;none&gt;           &lt;none&gt;
netshoot-7d996d7884-gcxrm   1/1     Running   0             80s     10.10.1.155   mycluster-worker2   &lt;none&gt;           &lt;none&gt;
</pre></div>


<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="497" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-3-1024x497.png" alt="Kubernetes networking interfaces with Cilium" class="wp-image-31003" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-3-1024x497.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-3-300x146.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-3-768x373.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-3-1536x745.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-3.png 1884w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">You can now see for real that the IP subnets of the pods are different than the one of the nodes. Also the IP subnet of pods on each node is different from each other. If you are not sure why, you are perfectly right because it is not so clear at this stage. So let&#8217;s clarify it by checking our Cilium configuration.</p>



<p class="wp-block-paragraph">I&#8217;ve told you in my previous blog that there is one Cilium Agent per building. This Agent is a pod itself and he takes care about networking in the node. This is what they look like in our cluster:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl get po -n kube-system -owide|grep cilium
cilium-9zh9s                                      1/1     Running   5 (65m ago)   113d   172.18.0.3    mycluster-control-plane   &lt;none&gt;           &lt;none&gt;
cilium-czffc                                      1/1     Running   5 (65m ago)   113d   172.18.0.4    mycluster-worker2         &lt;none&gt;           &lt;none&gt;
cilium-dprvh                                      1/1     Running   5 (65m ago)   113d   172.18.0.2    mycluster-worker          &lt;none&gt;           &lt;none&gt;
cilium-operator-6b865946df-24ljf                  1/1     Running   5 (65m ago)   113d   172.18.0.2    mycluster-worker          &lt;none&gt;           &lt;none&gt;
</pre></div>


<p class="wp-block-paragraph">There is two things to notice here:</p>



<ul class="wp-block-list">
<li>The Cilium Agent is a Daemonset so that is how you make sure to always have one on each node of our cluster. As it is a pod, it also gets an IP Address&#8230; but wait a minute&#8230; this is the same IP Address as the node! Exactly! This is a special case for pods IP Address assignation, usually for system pods that need direct access to the node (host) network. If you look at the pods in the kube-system namespace, you&#8217;ll see most of them uses the node IP Address.</li>



<li>The Cilium Operator pod is responsible for IP address management in the cluster and so it gives to each Cilium Agent its range to use.</li>
</ul>



<p class="wp-block-paragraph">Now you want to see which IP range is used by each node right? Let&#8217;s just check that Cilium Agent on each node as we have found their name above:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [3,7]; title: ; notranslate">
$ kubectl exec -it -n kube-system cilium-dprvh -- cilium debuginfo | grep IPAM
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
IPAM:                   IPv4: 5/254 allocated from 10.10.2.0/24,

$ kubectl exec -it -n kube-system cilium-czffc -- cilium debuginfo | grep IPAM
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
IPAM:                   IPv4: 5/254 allocated from 10.10.1.0/24,
</pre></div>


<p class="wp-block-paragraph">You can now see the different IP subnet on each node. In my previous blog I told you that an IP Address belong to a group and it uses the subnet mask. This subnet mask is here /24 which means for the first node that any address starting with 10.10.2 belongs to the same group. For the second node it is 10.10.1 and so they are both in a separate group or IP subnet.</p>



<p class="wp-block-paragraph">What now about checking the interfaces that are the doors of our drawing?</p>



<h2 class="wp-block-heading" id="h-diving-into-the-interfaces-configuration">Diving into the interfaces configuration</h2>



<p class="wp-block-paragraph">Let&#8217;s explore our buildings and see what we could find out! We are going to start with our four pods:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [15,17,29,31,43,45,57,59]; title: ; notranslate">
$ kubectl get po -n networking101 -owide
NAME                        READY   STATUS    RESTARTS       AGE    IP            NODE                NOMINATED NODE   READINESS GATES
busybox-c8bbbbb84-fmhwc     1/1     Running   1 (125m ago)   4d1h   10.10.1.164   mycluster-worker2   &lt;none&gt;           &lt;none&gt;
busybox-c8bbbbb84-t6ggh     1/1     Running   1 (125m ago)   4d1h   10.10.2.117   mycluster-worker    &lt;none&gt;           &lt;none&gt;
netshoot-7d996d7884-fwt8z   1/1     Running   0              103m   10.10.2.121   mycluster-worker    &lt;none&gt;           &lt;none&gt;
netshoot-7d996d7884-gcxrm   1/1     Running   0              103m   10.10.1.155   mycluster-worker2   &lt;none&gt;           &lt;none&gt;

$ kubectl exec -it -n networking101 busybox-c8bbbbb84-t6ggh -- ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
8: eth0@if9: &lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&gt; mtu 1500 qdisc noqueue qlen 1000
    link/ether 9e:80:70:0d:d9:37 brd ff:ff:ff:ff:ff:ff
    inet 10.10.2.117/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::9c80:70ff:fe0d:d937/64 scope link
       valid_lft forever preferred_lft forever

$ kubectl exec -it -n networking101 netshoot-7d996d7884-fwt8z -- ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
12: eth0@if13: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether ea:c4:71:d6:4f:a0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.10.2.121/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e8c4:71ff:fed6:4fa0/64 scope link
       valid_lft forever preferred_lft forever

$ kubectl exec -it -n networking101 netshoot-7d996d7884-gcxrm -- ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
12: eth0@if13: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:57:3d:54:40:f1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.10.1.155/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::bc57:3dff:fe54:40f1/64 scope link
       valid_lft forever preferred_lft forever

$ kubectl exec -it -n networking101 busybox-c8bbbbb84-fmhwc -- ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
10: eth0@if11: &lt;BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN&gt; mtu 1500 qdisc noqueue qlen 1000
    link/ether 2a:7f:05:a0:69:db brd ff:ff:ff:ff:ff:ff
    inet 10.10.1.164/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::287f:5ff:fea0:69db/64 scope link
       valid_lft forever preferred_lft forever
</pre></div>


<p class="wp-block-paragraph">You can see that each container has only one network interface in addition to its local loopback. The format is for example <strong>8: eth0@if9</strong> which means the interface in the container has the number 9 and is linked to its pair interface number 8 of the node it is hosted on. These are the 2 doors connected by a corridor in my drawing.</p>



<p class="wp-block-paragraph">Then check the nodes network interfaces:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [10,12,14,16,18,26,30,42,44,46,52,54,60,62]; title: ; notranslate">
$ sudo docker exec -it mycluster-worker ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: cilium_net@cilium_host: &lt;BROADCAST,MULTICAST,NOARP,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 5e:84:64:22:90:7f brd ff:ff:ff:ff:ff:ff
3: cilium_host@cilium_net: &lt;BROADCAST,MULTICAST,NOARP,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether ca:7e:e1:cc:4e:74 brd ff:ff:ff:ff:ff:ff
    inet 10.10.2.205/32 scope global cilium_host
       valid_lft forever preferred_lft forever
4: cilium_vxlan: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether f6:bf:81:9b:e2:c5 brd ff:ff:ff:ff:ff:ff
5: eth0@if6: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fc00:f853:ccd:e793::2/64 scope global nodad
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:2/64 scope link
       valid_lft forever preferred_lft forever
7: lxc_health@if6: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 8a:de:c1:2c:f5:83 brd ff:ff:ff:ff:ff:ff link-netnsid 1
9: lxc4a891387ff1a@if8: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d6:21:74:eb:67:6b brd ff:ff:ff:ff:ff:ff link-netns cni-67a5da05-a221-ade5-08dc-64808339ad05
11: lxc5b7b34955e61@if10: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether f2:80:da:a5:17:74 brd ff:ff:ff:ff:ff:ff link-netns cni-0b438679-e5d3-d429-85c0-b6e3c8914250
13: lxc73d2e1d7cf4f@if12: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether f6:87:b6:c3:a6:45 brd ff:ff:ff:ff:ff:ff link-netns cni-f608f13c-1869-6134-3d6b-a0f76fd6d483

$ sudo docker exec -it mycluster-worker2 ip a
1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: cilium_net@cilium_host: &lt;BROADCAST,MULTICAST,NOARP,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether f2:91:2b:31:1f:47 brd ff:ff:ff:ff:ff:ff
3: cilium_host@cilium_net: &lt;BROADCAST,MULTICAST,NOARP,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:7f:e0:2b:d6:b1 brd ff:ff:ff:ff:ff:ff
    inet 10.10.1.55/32 scope global cilium_host
       valid_lft forever preferred_lft forever
4: cilium_vxlan: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether e6:c8:8d:5d:1e:2d brd ff:ff:ff:ff:ff:ff
6: lxc_health@if5: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d2:cf:ec:4c:51:b6 brd ff:ff:ff:ff:ff:ff link-netnsid 1
8: lxcdc5fb9751595@if7: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fe:b4:3a:e0:67:a3 brd ff:ff:ff:ff:ff:ff link-netns cni-c0d4bea2-92fd-03fb-ba61-3656864d8bd7
9: eth0@if10: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.4/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fc00:f853:ccd:e793::4/64 scope global nodad
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe12:4/64 scope link
       valid_lft forever preferred_lft forever
11: lxc174c023046ff@if10: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether ae:7a:b9:6b:b3:c1 brd ff:ff:ff:ff:ff:ff link-netns cni-4172177b-df75-61a8-884c-f9d556165df2
13: lxce84a702bb02c@if12: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 92:65:df:09:dd:28 brd ff:ff:ff:ff:ff:ff link-netns cni-d259ef79-a81c-eba6-1255-6e46b8d1c779
</pre></div>


<p class="wp-block-paragraph">On each node there are several interfaces to notice. I&#8217;ll take the first node for example:</p>



<ul class="wp-block-list">
<li><strong>eth0@if6</strong>: As our Kubernetes cluster is created with Kind, a node is actually a container (and this interface open a corridor to its pair interface on my laptop). If it feels like the movie Inception, well, it is a perfectly correct comparison! This interface is the main door of the building.</li>



<li><strong>lxc4a891387ff1a@if8</strong>: This is the pair interface number 8 that is linked to the left container above.</li>



<li><strong>lxc73d2e1d7cf4f@if12</strong>: This is the pair interface number 12 that is linked to the right container above.</li>



<li><strong>cilium_host@cilium_net</strong>: This is the circle interface in my drawing that allows the routing to/from other nodes in our cluster.</li>



<li><strong>cilium_vxlan</strong>: This is the rectangle in my drawing and is the tunnel interface that will transport you to/from the other nodes in our cluster.</li>
</ul>



<p class="wp-block-paragraph">Let&#8217;s now get the complete picture by updating our drawing with these information:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="503" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-8-1024x503.png" alt="Kubernetes networking with Cilium" class="wp-image-31312" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-8-1024x503.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-8-300x148.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-8-768x378.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-8-1536x755.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-3-8.png 1924w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">With this foundation knowledge, you now have all the key elements to understand the communication between pods on the same node or on different nodes. This is what we will look at in my <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-linux-routing/" target="_blank" rel="noreferrer noopener">next blog post</a>. Stay tuned!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/">Kubernetes Networking by Using Cilium &#8211; Intermediate Level &#8211; Network Interfaces</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kubernetes Networking by Using Cilium &#8211; Beginner Level</title>
		<link>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/#comments</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Wed, 14 Feb 2024 09:37:11 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[ebpf]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[networking]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=30875</guid>

					<description><![CDATA[<p>There seems to be a strong interest these days about understanding better networking in Kubernetes. This blog post is my contribution on this topic. I&#8217;ll do my best to explain it in a visual way and translate the techie part to an understandable language so that anybody can actually enjoy it. The best way to [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/">Kubernetes Networking by Using Cilium &#8211; Beginner Level</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">There seems to be a strong interest these days about understanding better networking in Kubernetes. This blog post is my contribution on this topic. I&#8217;ll do my best to explain it in a visual way and translate the techie part to an understandable language so that anybody can actually enjoy it.</p>



<p class="wp-block-paragraph">The best way to learn networking is by doing what is called &#8220;Follow the packet&#8221; or &#8220;The life of a packet&#8221;. Basically, you follow the packet from the sender to the receiver by stopping at each step of this journey. I did that a while ago with a <a href="https://www.dbi-services.com/blog/exploration-of-calico-in-minikube/" target="_blank" rel="noreferrer noopener">communication from a Pod to another Pod by using Calico</a>. This time I&#8217;ll use another Container Network Interface (CNI) called <a href="https://cilium.io" target="_blank" rel="noreferrer noopener">Cilium</a> which is based on eBPF (understand fast and flexible routing) and comes with a lot of powerful features and tools. Let&#8217;s hit that packet road!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="573" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-Roads-1024x573.png" alt="" class="wp-image-30877" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-Roads-1024x573.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-Roads-300x168.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-Roads-768x430.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-Roads-1536x859.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-Roads.png 2034w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading" id="h-traditional-networking-without-kubernetes">Traditional Networking without Kubernetes</h2>



<p class="wp-block-paragraph">We are going to start from the beginning. I&#8217;ll consider you know nothing about networking. Maybe you already know what an IP Address is? The IP Address is the numerical Address of a network interface in a computer. This is how your computer can connect for example to your Wi-Fi network and give you access to the Internet. If you are using a laptop, your Wi-Fi network interface has one IP Address. This network interface also has another address that is unique and burnt on it by the hardware provider. This address is called the Medium Access Control (MAC) Address.</p>



<p class="wp-block-paragraph">The IP Address belongs to a group (the IP Subnet). To know to which group it belongs to, it uses something called the Subnet Mask. This mask when applied to the IP Address gives a result and this result is identical for every IP Address that belong to the same group. This is like your community.</p>



<p class="wp-block-paragraph">Let&#8217;s use the drawing below to make analogies:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="488" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-TraditionalNetwork-1-1024x488.png" alt="Traditional networking" class="wp-image-30879" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-TraditionalNetwork-1-1024x488.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-TraditionalNetwork-1-300x143.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-TraditionalNetwork-1-768x366.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-TraditionalNetwork-1.png 1382w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">The house is a computer, a server or a virtual machine. It could be of different sizes according to its CPU and memory but let use the same one for simplicity sake. A house has a door that is your network interface. The serial number of that door is your MAC Address and the number on your house (which is usually nailed on the door) is your IP Address. It is only if you change your door that your serial number will change. However, your house number has been assigned to you by the architect of your community and could change if there is a reassignment or a change in the design.</p>



<p class="wp-block-paragraph">The community 10th (using numbers from 10 to 19) in blue belong to the same group (same IP subnet) and the community 20th in green is another group. In each group there are five houses so there is space for the community to grow. In each community the door has a direct link to a fountain which represents a Switch. At the fountain, there is a sign for each path to indicate which door you can reach. Yes, the fountain doesn&#8217;t know the house number but only the serial number of the door. For humans it is not very practical so we use a map (called the ARP table) that gives the translation between the house number and the serial number of its door.</p>



<p class="wp-block-paragraph">If you live in house 14 and want to visit house 15, you&#8217;ll use the path (there is only one and it is yours so no traffic jams!) to the fountain first and then look at the signs. You know from your map which serial number correspond to which house and so you use the path to house 15. In this star topology you always go to the fountain first and not directly to the house you want to visit because there is no direct path. A path inside your community represents a Layer 2 link. You can&#8217;t reach another community by using these paths.</p>



<h3 class="wp-block-heading" id="h-traveling-between-communities">Traveling between communities</h3>



<p class="wp-block-paragraph">What now if from your house 14, you want to pay a visit to house 24? This is another community which means the couple IP Address / Subnet mask for 14 doesn&#8217;t produce the same result as for 24. Indeed the 10th and the 20th communities are different. So you know the destination is another community and in that case you have to go first to your gatekeeper (but always through the fountain as we have seen). He is the default gateway of your community and he lives in house 11. The rule is to go to him for any destinations that is outside of your community.</p>



<p class="wp-block-paragraph">Only he has a map (the Routing Table) to reach community 20th and know which road to take (This is called Layer 3 routing because you are traveling outside of your community). This map shows that to reach 24 in the 20th community you have to use another door. Wait a minute, if a door is a network interface, does it mean that the gatekeeper house has another door? Absolutely correct! The house 11 has another door with another number on it (101) and of course this door has another serial number (MAC Address).</p>



<p class="wp-block-paragraph">By exiting this door you can now take the path to reach community 20th which has its own gatekeeper in house 21. The map (Routing Table) of this gatekeeper directs you to the proper door to reach your destination. This door gives you access to community 20th as your destination 24 belongs to it. The gatekeeper also give you the map (ARP table) so you can orientate yourself at the fountain. You can now walk on the path to the green fountain. From there, you just have to follow the sign and the path to house 24. When you want to get back home, you travel back using the same path in the opposite direction.</p>



<h2 class="wp-block-heading" id="h-networking-in-kubernetes">Networking in Kubernetes</h2>



<p class="wp-block-paragraph">Now you know the basics about networking, let&#8217;s see how it works in comparison in Kubernetes. Yes it is slightly more complicated but let&#8217;s go step by step and use the picture below to understand it better:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="586" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-1024x586.png" alt="Kubernetes networking with Cilium" class="wp-image-30937" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-1024x586.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-300x172.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2-768x440.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2024/02/KubernetesNetworking101-KubernetesNetwork-2.png 1334w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Instead of houses, we now have buildings. The networking between the buildings is still the same as the traditional one with a Switch/fountain in the middle. The entrance of the building has a door with the building number on it (its IP Address) that is part of a 1000th community. One building will represent one node of our Kubernetes cluster.</p>



<p class="wp-block-paragraph">You know Kubernetes is a container orchestrator. A container is wrapped into a pod. For simplicity sake, let&#8217;s consider a pod has only one container and so both terms are here equivalent. This pod will be one appartement in our building and so is like a private part of it. The apartment could be of different size in the building as it could have 2, 3 or 4 bedrooms for example. This will be the CPU and memory capacities your container will need on the node. Some appartement are empty so the building still has some capacity. However in Kubernetes, pods are created and deleted as needed. So in our building that would mean sometimes a 2 bedrooms appartement is created and when not used anymore, it could be removed from the building. Then a 5 bedrooms appartement could be created next if the building has enough space for it. Imagine then that it is a LEGO building and inside it you can build and demolish apartments of various size according to your need! Isn&#8217;t it awesome?</p>



<p class="wp-block-paragraph">In each building, the containers/pods have their own community (IP subnet). The function of a CNI in Kubernetes is basically to assign numbers (IP Addresses) to pods so they can communicate together. By default Cilium uses different community for each building. When an apartment is created, Cilium assigns a number to it. When an apartment is deleted an recreated, it will get another number so it is ephemeral. Here the blue community uses the 10th range and the green one uses the 20th. You can notice that the number ranges of the blue and green communities are different than the range of the buildings. Just for you to know, this design is called an Overlay network. There are other ones possible but that is a commonly used. It is a network of pods on top of the network of nodes.</p>



<h3 class="wp-block-heading" id="h-traveling-between-apartments-in-the-same-building">Traveling between apartments in the same building</h3>



<p class="wp-block-paragraph">Now, you live in the apartment 12, how are you going to pay a visit to apartment 14? Like we did with the traditional networking example, you are the packet we are going to follow! Of course you leave the apartment (container) through its door (its network interface). The difference with our previous example is that you are now not out of the house, you are just out of your apartment but still inside of the building. You then follow a private corridor and reach another door (this is the LXC interface).</p>



<p class="wp-block-paragraph">This door gives you access to a common space of the building where the routing and dispatching occurs. We call it the Cilium Lobby (the blue rectangle). This Lobby has been installed by the Cilium Agent of this building when Cilium was selected to provide communications in this Kubernetes cluster. There is one Cilium Agent per building and he is taking care of everything related to networking. In this Lobby there is a gatekeeper that doesn&#8217;t live in an apartment but waits at a deck in the Lobby. He has a team of servants that wait at different doors in the building to provide directions. This is because Cilium is using a magic routing map called eBPF that efficiently helps the travellers.</p>



<p class="wp-block-paragraph">So when you reach the door at the end of the corridor,  you show the servant who is waiting here you want to go to number 14. He finds a match in his magic eBPF map with number 14 and shows you directly the corridor door on the top right. You don&#8217;t have to go to the Lobby, he shows you a secret passage to go straight to it. You then open that door, follow the corridor and reach apartment number 14. You would go back to apartment number 12 following the same path and process but in the opposite direction. </p>



<p class="wp-block-paragraph">So this dispatching is different from traditional switching and it is very fast thanks to the magic eBPF map!</p>



<h3 class="wp-block-heading" id="h-traveling-between-apartments-in-different-buildings">Traveling between apartments in different buildings</h3>



<p class="wp-block-paragraph">Now from apartment 12 you want to pay a visit to the apartment number 22 which is in another building. The beginning of your travel is the same as previously, you exit your apartment, follow the corridor and ask the servant waiting here for directions. As the destination number 22 belongs to another community, he directs you to the Lobby this time. Here and as with traditional networking, you need the help of the gatekeeper in the Lobby. The gatekeeper looks at his map (the Routing table) for direction to number 22 and shows you the door number 11 to use (the cilium_host).</p>



<p class="wp-block-paragraph">When you open that door, you see another door behind it: It is the blue triangle and it is called the VXLAN interface. This door open to a nice transparent tunnel that goes through the main door of the building. You are protected from the rain and can enjoy the landscape while walking to the other building. You even spot the outdoor fountain! When you reach the green building you exit the tunnel and go meet the servant that is waiting for you at the green triangle (VXLAN interface). You give him your destination, he finds a match in his magic eBPF map with number 22 and shows you a secret passage to the corridor door on the top left. From there you follow the corridor and reach your destination. As before, your way back will follow the same journey in the opposite direction.</p>



<p class="wp-block-paragraph">This is Layer 3 routing as the destination community is different than yours. You can see it is a bit more complex in Kubernetes than in traditional routing.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">I hope this helped you understand the difference between the traditional networking and Kubernetes networking and also that the latter is clearer now for you. If that is all you needed, then I&#8217;m glad you&#8217;ve read this blog post, I hope you&#8217;ve enjoyed it. If you now want to learn more about Kubernetes Networking, stay tuned because I&#8217;ll write an <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-intermediate-level-part-1/" target="_blank" rel="noreferrer noopener">intermediate level</a> where you&#8217;ll see what a building really looks like on a real cluster!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/">Kubernetes Networking by Using Cilium &#8211; Beginner Level</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-networking-by-using-cilium-beginner-level/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Combining Powerful Cilium Features Together In Kubernetes</title>
		<link>https://www.dbi-services.com/blog/combining-powerful-cilium-features-together-in-kubernetes/</link>
					<comments>https://www.dbi-services.com/blog/combining-powerful-cilium-features-together-in-kubernetes/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Wed, 01 Nov 2023 13:23:43 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[ingress controller]]></category>
		<category><![CDATA[isovalent]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[L2 service announcement]]></category>
		<category><![CDATA[loadbalancer IPAM]]></category>
		<category><![CDATA[metallb]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=28913</guid>

					<description><![CDATA[<p>My colleagues and I have played with Cilium from Isovalent for a while now and we have successfully deployed it as simple CNI (Container Network Interface) along with Hubble on several production Kubernetes cluster of our customers. However, over the past year there has been several very interesting new features being released. Smartly, Isovalent gives [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/combining-powerful-cilium-features-together-in-kubernetes/">Combining Powerful Cilium Features Together In Kubernetes</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">My colleagues and I have played with <a href="https://cilium.io">Cilium</a> from <a href="https://isovalent.com">Isovalent</a> for a while now and we have successfully deployed it as simple CNI (Container Network Interface) along with Hubble on several production Kubernetes cluster of our customers. </p>



<p class="wp-block-paragraph">However, over the past year there has been several very interesting new features being released. Smartly, Isovalent gives you the opportunity to play with each new feature in their excellent labs they have now put together in this original <a href="https://labs-map.isovalent.com">map quest</a>. You follow the instructions to learn how the feature works and earn a badge (for the main features) if you solve the final challenge. Be careful it is very addictive, as soon as you earn your first badge you will then want to collect all of them!</p>



<h2 class="wp-block-heading" id="h-simplifying-a-kubernetes-cluster-architecture">Simplifying a Kubernetes cluster architecture</h2>



<p class="wp-block-paragraph">Cilium just became a <a href="https://isovalent.com/blog/post/cilium-graduates-cncf/">Graduated CNCF project</a> and I wanted to try to combine several of its features together to simplify our traditional Kubernetes cluster architecture for future projects.</p>



<p class="wp-block-paragraph">If you are using a Kubernetes on-premise cluster that hosts applications reachable from outside of this cluster then you are using an Ingress Controller and a load balancer (probably <a href="https://metallb.org">MetalLB</a> using Layer 2 configuration). This is the traditional architecture we deploy and with Cilium it is now possible to replace these two components by using a combination of the following features: Ingress Controller, LoadBalancer IPAM and L2 Service Announcement.</p>



<p class="wp-block-paragraph">I&#8217;ve done my tests with Minikube as at this stage I just wanted to see how the combining configuration would work. I didn&#8217;t see yet some examples of those 3 features together so if you are also interested to optimize the architecture of your Kubernetes cluster with Cilium then read on!</p>



<h2 class="wp-block-heading" id="h-overview-of-the-configuration">Overview of the configuration</h2>



<p class="wp-block-paragraph">If you are like me, you like to have some visuals about what we are doing. So I start by giving the summary of my configuration that combine the 3 Cilium features (with their name in bold in the diagram below). The colored rectangle boxes show the important parameters of the objects and when they are of the same color, it is how the link is made between the objects.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="581" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium-combining-features-4-1024x581.png" alt="" class="wp-image-28942" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium-combining-features-4-1024x581.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium-combining-features-4-300x170.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium-combining-features-4-768x436.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium-combining-features-4-1536x872.png 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium-combining-features-4-2048x1163.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">I&#8217;ve used the application &#8220;testcontainers/helloworld&#8221; that I want to expose outside of my cluster. So from my laptop I should be able to reach it and this is my goal for this first stage of testing.</p>



<p class="wp-block-paragraph">Each feature brings its customized object (CRD) and you can see in the diagram above the configuration of the object for each of the 3 features. The service object with the type LoadBalancer is automatically created when the feature Ingress Controller is enabled. We then just associate a deployment for our &#8220;testcontainers/helloworld&#8221; application to this service by using the selector/labels association.</p>



<h2 class="wp-block-heading" id="h-minikube-configuration">Minikube configuration</h2>



<p class="wp-block-paragraph">Let&#8217;s start from the beginning, here is my Minikube configuration for testing these features. I&#8217;ve started a new Minikube cluster with 3 nodes, no cni and I like to create a separate profile called here <strong>cluster-cilium</strong> to separate that cluster from the other cluster tests I&#8217;m doing.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ minikube start --nodes 3 --network-plugin=cni --cni=false --memory=4096 -p cluster-cilium
</pre></div>


<p class="wp-block-paragraph">When my cluster is up and running, I install Cilium 1.14.2 and activate all the features and parameters I need for my testing. I also like to install Cilium in a separate namespace called here <strong>cilium</strong>:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl create ns cilium
$ cilium install --version 1.14.2 --set kubeProxyReplacement=strict --set ingressController.enabled=true --set ingressController.loadbalancerMode=dedicated --set kubeProxyReplacement=true --set l2announcements.enabled=true --set l2announcements.leaseDuration=&quot;3s&quot; --set l2announcements.leaseRenewDeadline=&quot;1s&quot; --set l2announcements.leaseRetryPeriod=&quot;500ms&quot; --set l2podAnnouncements.enabled=true --set l2podAnnouncements.interface=&quot;eth0&quot; --set externalIPs.enabled=true -n cilium
</pre></div>


<h2 class="wp-block-heading" id="h-combined-features-configuration">Combined features configuration</h2>



<p class="wp-block-paragraph">When my cluster is ready, I can check the LoadBalancer service is automatically created with an http and https nodePort. For this example I&#8217;ve edited this service and removed the https port to avoid any confusion. The http nodePort 31814 was automatically created but that value could be changed. For my testing I&#8217;ll not use it:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl get svc -n cilium
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
cilium-ingress-basic-ingress   LoadBalancer   10.107.176.240   &lt;pending&gt;      80:31814/TCP   16h
</pre></div>


<p class="wp-block-paragraph">You can see that this service doesn&#8217;t have any external IP address yet (the status shows pending). To provide one, we need to create an object CiliumLoadBalancerIPPool and define a cidr range of IP to use as external IP Address. Note that /30 (so 2 IP Addresses) is the minimum range you can use. It is not possible to use just 1 IP Address in a pool. We then set a serviceSelector to match the label blue (in this example) so each LoadBalancer service that have that label will take an IP Address from this pool if there is one available. If all IP Addresses are already taken then the EXTERNAL-IP field of the service will stay in the pending state. Below is the CiliumLoadBalancerIPPool configuration:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [8,9,10]; title: ; notranslate">
apiVersion: &quot;cilium.io/v2alpha1&quot;
kind: CiliumLoadBalancerIPPool
metadata:
  name: &quot;pool-blue&quot;
spec:
  cidrs:
  - cidr: &quot;10.0.0.0/30&quot;
  serviceSelector:
    matchLabels:
      color: blue
</pre></div>


<p class="wp-block-paragraph">You&#8217;ll then need to add the blue label to the LoadBalancer service </p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl edit svc -n cilium cilium-ingress-basic-ingress
</pre></div>


<p class="wp-block-paragraph">Just add the label color: blue and you&#8217;ll then see the following:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl get svc -n cilium
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
cilium-ingress-basic-ingress   LoadBalancer   10.107.176.240   10.0.0.1      80:31814/TCP   16h
</pre></div>


<p class="wp-block-paragraph">Now our service has an external IP Address that comes from the pool-blue we have defined previously.</p>



<p class="wp-block-paragraph">We can create our deployment by applying the following yaml file:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [13,14]; title: ; notranslate">
apiVersion: apps/v1
kind: Deployment
metadata:
  name: testciliuml2
  namespace: cilium
spec:
  replicas: 2
  selector:
    matchLabels:
      name: testcontainers
  template:
    metadata:
      labels:
        name: testcontainers
    spec:
      containers:
      - name: testciliuml2
        image: testcontainers/helloworld
        env:
        - name: DELAY_START_MSEC
          value: &quot;2000&quot;
</pre></div>


<p class="wp-block-paragraph">You can see we use the label name: testcontainers for this deployment. We will then need to edit again our LoadBalancer service to associate it with that deployment label (you can also see it in the diagram above if you want to check):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; title: ; notranslate">
  selector:
    name: testcontainers
</pre></div>


<p class="wp-block-paragraph">Finally we can configure an ingress object to link it to our LoadBalancer service by using the yaml file below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [7,12,13]; title: ; notranslate">
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: basic-ingress
  namespace: cilium
spec:
  ingressClassName: cilium
  rules:
  - http:
      paths:
      - backend:
          service:
            name: cilium-ingress-basic-ingress
            port:
              number: 80
        path: /
        pathType: Prefix
</pre></div>


<p class="wp-block-paragraph">Note that the&nbsp;ingressClassName&nbsp;field uses the value&nbsp;cilium. This instructs Kubernetes to use Cilium as the Ingress controller for this resource. We can check the state of our ingress:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
 kubectl get ing -n cilium
NAME            CLASS    HOSTS   ADDRESS    PORTS   AGE
basic-ingress   cilium   *       10.0.0.1   80      30d
</pre></div>


<p class="wp-block-paragraph">You can recognize the external IP Address of our LoadBalancer service.</p>



<h2 class="wp-block-heading" id="h-test-of-connection-to-the-loadbalancer-service">Test of connection to the LoadBalancer service</h2>



<p class="wp-block-paragraph">To fully test the flow from our laptop through the ingress and down to the pod, we would need the external IP Address to be reachable from my laptop. In production you will not use this external IP Address directly but use a URL with a domain name that will be resolved by a DNS to this external IP Address.</p>



<p class="wp-block-paragraph">Here I will just test the connection to the LoadBalancer service with <strong>kubectl port-forward</strong> to reach port 80 of this service as it would be by our ingress rule:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl port-forward svc/cilium-ingress-basic-ingress -n cilium 8080:80 &amp;
</pre></div>


<p class="wp-block-paragraph">I can then reach my application from my laptop by using the URL <strong>http://localhost:8080</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="876" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium_HelloWord-1024x876.png" alt="" class="wp-image-28970" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium_HelloWord-1024x876.png 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium_HelloWord-300x257.png 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium_HelloWord-768x657.png 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/10/Cilium_HelloWord.png 1258w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">As a conclusion, I&#8217;ve found the configuration of all these features pretty easy to bound together. It is then very simple to provide a complete Kubernetes architecture with only Cilium features to reach my application from outside of this cluster.</p>



<p class="wp-block-paragraph">The next step will be to test it in a real Kubernetes cluster with some failover scenarii but that all look very promising to me!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/combining-powerful-cilium-features-together-in-kubernetes/">Combining Powerful Cilium Features Together In Kubernetes</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/combining-powerful-cilium-features-together-in-kubernetes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kubernetes CoreDNS in depth</title>
		<link>https://www.dbi-services.com/blog/kubernetes-coredns-in-depth/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-coredns-in-depth/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Wed, 27 Sep 2023 07:34:08 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[coredns]]></category>
		<category><![CDATA[devops]]></category>
		<category><![CDATA[kubernetes]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=28263</guid>

					<description><![CDATA[<p>You know that CoreDNS is one of the core component of Kubernetes. You may also know that the CoreDNS pod is up and running only after the Container Network Interface (CNI) has been installed in your Kubernetes cluster. Of course you know what CoreDNS is about, it converts names to IP Addresses for objects in [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-coredns-in-depth/">Kubernetes CoreDNS in depth</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">You know that <a href="https://coredns.io" target="_blank" rel="noreferrer noopener">CoreDNS</a> is one of the core component of Kubernetes. You may also know that the CoreDNS pod is up and running only after the Container Network Interface (CNI) has been installed in your Kubernetes cluster. Of course you know what CoreDNS is about, it converts names to IP Addresses for objects in the Kubernetes cluster. If you are interested to learn a bit more about how it works under the hood then keep reading. I&#8217;ll share with you some information that will help you understand CoreDNS in more depth. We will use Cilium as CNI to easily monitor DNS traffic in our cluster. Take a deep breath and let&#8217;s dive in.</p>



<h2 class="wp-block-heading" id="h-the-basics">The basics</h2>



<p class="wp-block-paragraph">CoreDNS is then a core component of a Kubernetes cluster and is operating as a Pod running on one of the node of your cluster. This node could be a master or a worker node. There are 2 CoreDNS Pods by default hosted on 2 separate nodes. That provides redundancy and load balancing in the cluster for this name to IP function. CoreDNS is deployed through a deployments object and so it can be scaled out or in according to your needs. The CoreDNS pods are reached through a service that holds a virtual IP Address to load balance traffic between these Pods.</p>



<p class="wp-block-paragraph">The CoreDNS Pods belong to the kube-system namespace and its configuration is stored in a configmaps called coredns in that same namespace. This default configuration is something like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [7]; title: ; notranslate">
$ kubectl get cm coredns -n kube-system -o yaml

apiVersion: v1
data:
  Corefile: |
    .:53 {
        log
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: &quot;2023-09-26T15:40:53Z&quot;
  name: coredns
  namespace: kube-system
</pre></div>


<p class="wp-block-paragraph">We advise to use <strong>log</strong> as in the example above in order to record all the resolution CoreDNS will do in its logs. This will ease the understanding and the troubleshooting around CoreDNS.</p>



<h2 class="wp-block-heading" id="h-the-dns-traffic-to-an-object-name-inside-the-kubernetes-cluster">The DNS traffic to an object name inside the Kubernetes cluster</h2>



<p class="wp-block-paragraph">CoreDNS acts as a DNS resolver for our Kubernetes cluster so it listen on UDP port 53 as expected for a DNS. If you need to capture traffic to and from a CoreDNS Pod I would recommend to scale in the deployments to 1 Pod to be sure that all the traffic will go through it.</p>



<p class="wp-block-paragraph">Let&#8217;s have a look at an example of a Pod sending a DNS Request and capture that traffic with cilium to better understand it. We will use a netshoot Pod that contains several networking tools for us to play with (here we will just use nslookup):</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl run netshoot --image=nicolaka/netshoot -it -- bash
netshoot:~# nslookup myservice.mynamespace.svc.cluster.local
Server:         172.21.0.10
Address:        172.21.0.10#53

Name:    myservice.mynamespace.svc.cluster.local
Address: 172.21.0.100
</pre></div>


<p class="wp-block-paragraph">From the netshoot Pod we have resolved the name of one of our service (myservice) in the cluster to its IP Address 172.21.0.100. The CoreDNS service has the IP Address of 172.21.0.10.</p>



<p class="wp-block-paragraph">At the same time in another shell we captured that traffic with Cilium. To monitor this traffic we have to use the Cilium agent that is running on the same node as our CoreDNS Pod. The result is as follows:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n cilium cilium-4zs7z -- cilium monitor|grep &quot;:53 &quot;
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
-&gt; endpoint 907 flow 0x0 , identity 5812-&gt;21815 state new ifindex lxcb2c39c2042dc orig-ip 172.20.1.46: 172.20.1.46:51450 -&gt; 172.20.3.34:53 udp
-&gt; overlay flow 0x0 , identity 21815-&gt;5812 state reply ifindex cilium_vxlan orig-ip 0.0.0.0: 172.20.3.34:53 -&gt; 172.20.1.46:51450 udp
</pre></div>


<p class="wp-block-paragraph">Our netshoot Pod has the IP Address of 172.20.1.46 and our CoreDNS Pod has the IP Address of 172.20.3.34. We can see that the request goes to the CoreDNS Pod on port 53 and then it responds back to the netshoot Pod. Not that if that service name didn&#8217;t exist, the flow would be identical, CoreDNS will not try to resolve this DNS request further because CoreDNS has authority on the domain svc.cluster.local. So if it doesn&#8217;t know, then nobody does and it will not ask another DNS resolver. Also note that I could do <strong>nslookup myservice.mynamespace</strong> and CoreDNS will automatically try a few suffix he has authority on and try to resolve it.</p>



<p class="wp-block-paragraph">To give you the complete picture, here are the CoreDNS logs associated with this DNS traffic:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl logs --namespace=kube-system -l k8s-app=kube-dns
...
&#x5B;INFO] 172.20.1.46:36694 - 8284 &quot;A IN myservice.mynamespace.svc.cluster.local. udp 60 false 512&quot; NOERROR qr,aa,rd 118 0.000289493s
...
</pre></div>


<p class="wp-block-paragraph">We can see the IP Address of our netshoot Pod, the name to be resolved as well as its result. NOERROR means that the resolution has been done successfully and at the end we also have the time this resolution took. If the resolution had failed you would have seen NXDOMAIN instead of NOERROR.</p>



<h2 class="wp-block-heading" id="h-the-dns-traffic-to-a-name-outside-of-the-kubernetes-cluster">The DNS traffic to a name outside of the Kubernetes cluster</h2>



<p class="wp-block-paragraph">Now let&#8217;s see what is happening when a Pod tries to resolve a name on which CoreDNS doesn&#8217;t have the authority. It could be any of the URL in your ingress rules or the API server name of your cluster. Those names are supposed to be resolved from a DNS that is outside of the Kubernetes cluster before the traffic can enter into your cluster. Also you may have an architecture where a Pod tries to connect to an Oracle database that is outside of the Kubernetes cluster and so the name resolution of this database will be done by a DNS in your local network that is outside of the cluster. Let&#8217;s use our netshoot Pod again to learn more about it:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
netshoot:~# nslookup myoracledatabase.mydomain.com
Server:         172.21.0.10
Address:        172.21.0.10#53

Name:   myoracledatabase.mydomain.com
Address: 10.0.0.10
</pre></div>


<p class="wp-block-paragraph">The name has been resolved but from the Pod we don&#8217;t see much about this resolution process. The Pod only knows the CoreDNS service IP Address which is 172.21.0.10. If you look at the DNS configuration inside this netshoot Pod you&#8217;ll see the following:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
netshoot:~# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 172.21.0.10
options ndots:5
</pre></div>


<p class="wp-block-paragraph">You see the domains on which CoreDNS has authority on and the CoreDNS service IP Address. And that&#8217;s it! So let&#8217;s have a look as previously what cilium can see about this traffic:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl exec -it -n cilium cilium-4zs7z -- cilium monitor|grep &quot;:53 &quot;
Defaulted container &quot;cilium-agent&quot; out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
-&gt; endpoint 907 flow 0x0 , identity 5812-&gt;21815 state new ifindex lxcb2c39c2042dc orig-ip 172.20.1.46: 172.20.1.46:52794 -&gt; 172.20.3.34:53 udp
-&gt; stack flow 0x8414f33b , identity 21815-&gt;world state new ifindex 0 orig-ip 0.0.0.0: 172.20.3.34:46263 -&gt; 8.8.8.8:53 udp
-&gt; endpoint 907 flow 0xd6863373 , identity world-&gt;21815 state reply ifindex lxcb2c39c2042dc orig-ip 8.8.8.8: 8.8.8.8:53 -&gt; 172.20.3.34:46263 udp
-&gt; overlay flow 0x0 , identity 21815-&gt;5812 state reply ifindex cilium_vxlan orig-ip 0.0.0.0: 172.20.3.34:53 -&gt; 172.20.1.46:52794 udp
</pre></div>


<p class="wp-block-paragraph">You can see that in this case as CoreDNS doesn&#8217;t have authority on <strong>mydomain.com</strong> it asks the DNS he knows to do the resolution for him. Here it is 8.8.8.8 that is a google public DNS for this example and to anonymize the real DNS IP Address in our local network. So the DNS traffic goes that way:</p>



<p class="wp-block-paragraph">Netshoot Pod (172.20.1.46) -&gt;  CoreDNS Pod (172.20.3.34) -&gt; Local DNS (8.8.8.8) and back on the same path. Note that this is what is seen by the Cilium agent in our Kubernetes cluster but that our local DNS may also asks other DNS to do some resolution for him (this is the standard DNS recursive mechanics).</p>



<p class="wp-block-paragraph">In the CoreDNS logs you can see this name resolution has been successful and that the time it took was slightly longer than for a resolution inside of the cluster. This is because it had to go through the local DNS so there were more steps in the process.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl logs --namespace=kube-system -l k8s-app=kube-dns
...
&#x5B;INFO] 172.20.1.46:52167 - 21729 &quot;A IN myoracledatabase.mydomain.com. udp 60 false 512&quot; NOERROR qr,aa,rd 118 0.001330359s
...
</pre></div>


<h2 class="wp-block-heading" id="h-how-coredns-knows-which-local-dns-to-ask">How CoreDNS knows which local DNS to ask?</h2>



<p class="wp-block-paragraph">That is a very good question! This comes from the coredns configmaps plugin <strong>forward . /etc/resolv.conf</strong> we have seen at the beginning of this blog. OK that looks like an answer given by ChatGPT but can you see what is inside this file and where does it come from? I didn&#8217;t try ChatGPT on it but I guess it may have a hard time with these two questions. I&#8217;ve promised to explore CoreDNS in depth in this blog so I have to provide you the answers! Let&#8217;s see how we can learn this. The Pods are designed to provide a function and so the container inside it uses an image built with only the minimum of tools required for this function. That means it doesn&#8217;t always contain a shell for example. That also reduce the attack surface for the naughty guys and gals out there. The CoreDNS image doesn&#8217;t contain a shell but this is how you could kind of have one anyway to explore files in its container:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; title: ; notranslate">
$ kubectl debug -it coredns-d669857b7-d4wqb -n kube-system --image=nicolaka/netshoot --target=coredns

coredns-d669857b7-hknvf  ~ cat /proc/1/root/etc/resolv.conf
search localdomain.com
nameserver 8.8.8.8
</pre></div>


<p class="wp-block-paragraph">With <strong>kubectl debug</strong> you can jump into the Pod by using another image of your choice but still have access to the content of the original CoreDNS container (crazy stuff isn&#8217;t it?). <strong>coredns</strong> of <strong>target=coredns</strong> is the name of the container into the pod <strong>coredns-d669857b7-d4wqb</strong>. You can then look at the content of /proc/1/root/etc/resolv.conf which is what we were looking for.</p>



<p class="wp-block-paragraph">To tell you everything, the coredns configmaps is also stored as a file in this container with the path /proc/1/root/etc/coredns/Corefile.</p>



<p class="wp-block-paragraph">That answers the first question. The second one was where he gets this resolv.conf file from? Well the response is easy when you know it: It just comes from the /etc/resolv.conf file of the node that hosts this CoreDNS Pod! I did the test to add a record into /etc/resolv.conf of the node and I&#8217;ve redeployed CoreDNS and sure enough, the added record was also into /etc/resolv.conf of the coredns container! Remember that the CoreDNS Pod can be hosted on any node of your cluster. So if you want to do this test, you can either force this Pod Scheduling to a specific node or change the /etc/resolv.conf file of all the nodes. Testing it in a lab with a few nodes should then be pretty easy.</p>



<h2 class="wp-block-heading" id="h-modify-the-configuration-of-the-coredns">Modify the configuration of the CoreDNS</h2>



<p class="wp-block-paragraph">So you know by now how CoreDNS works but is there some way you could control this name resolution from inside of the cluster? You may have an architecture where your Pods need to use an URL that is managed by the Ingress Controllers of your cluster. In that case the name resolution will not be done by the CoreDNS but by your local DNS as we have seen previously. In your organization these local DNS (there are usually two of them) may be managed by another team and you don&#8217;t have the control over them. If for some reason these local DNS become unreachable then the applications in your cluster will not work anymore. If you want the Pods in your cluster to independently resolve these URL names, then you could map them statically in your CoreDNS by using the <strong>hosts</strong> plugin. </p>



<p class="wp-block-paragraph">You just edit the coredns configmaps and add the <strong>hosts</strong> plugin before the <strong>forward</strong> plugin (Those blocks or instructions are called plugin in the CoreDNS terminology) as shown below:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: yaml; highlight: [19,20,21,22]; title: ; notranslate">
$ kubectl get cm coredns -n kube-system -o yaml

apiVersion: v1
data:
  Corefile: |
    .:53 {
        log
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        hosts {
           1.2.3.4 myoracledatabase.mydomain.com
           fallthrough
        }
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: &quot;2023-09-26T15:40:53Z&quot;
  name: coredns
  namespace: kube-system
</pre></div>


<p class="wp-block-paragraph">After a few seconds, if you try again a name resolution for <strong>myoracledatabase.mydomain.com</strong> from the netshoot Pod, you&#8217;ll see it gives the IP Address you have set in the <strong>hosts</strong> plugin.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: bash; highlight: [6]; title: ; notranslate">
netshoot:~# nslookup myoracledatabase.mydomain.com
Server:         172.21.0.10
Address:        172.21.0.10#53

Name:   myoracledatabase.mydomain.com
Address: 1.2.3.4
</pre></div>


<p class="wp-block-paragraph">So CoreDNS is able to do the resolution itself for this URL and doesn&#8217;t need to ask for the local DNS configured in /etc/resolv.conf. The parameter <strong>fallthrough</strong> means that if he doesn&#8217;t have a static mapping in <strong>hosts</strong>, then it will forward the DNS request to the local DNS for resolution just as before.</p>



<p class="wp-block-paragraph">So this change is dynamic (there is nothing to restart) and with the <strong>fallthrough</strong>, the resolution continues to be done by the local DNS for external names or URLs if there is no mapping. That way you can add at your own pace these mappings that will be done by CoreDNS. By doing this, the name resolution will be faster and you keep the control over it. Of course the drawback is that you&#8217;ll have to keep that mapping up to date when new applications, using ingress rules for example, will be hosted in your cluster.</p>



<p class="wp-block-paragraph">Note that it is useless to insert the <strong>hosts</strong> plugin after the <strong>forward</strong> plugin because the later doesn&#8217;t have the <strong>fallthrough</strong> parameter and so the hosts mapping will never be reached.</p>



<h2 class="wp-block-heading" id="h-wrap-up">Wrap up</h2>



<p class="wp-block-paragraph">I hope that by now you are pretty solid about CoreDNS! I believe that understanding the details of how a component works is a great advantage when it comes to troubleshoot issues around it. Go deep and keep learning!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-coredns-in-depth/">Kubernetes CoreDNS in depth</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-coredns-in-depth/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Swiss Cloud Native day landed at the Gurten!</title>
		<link>https://www.dbi-services.com/blog/swiss-cloud-native-day-landed-at-the-gurten/</link>
					<comments>https://www.dbi-services.com/blog/swiss-cloud-native-day-landed-at-the-gurten/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Mon, 25 Sep 2023 12:26:43 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[autoscaling]]></category>
		<category><![CDATA[bern]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[climate]]></category>
		<category><![CDATA[cloudnative]]></category>
		<category><![CDATA[cncf]]></category>
		<category><![CDATA[container]]></category>
		<category><![CDATA[ebpf]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[HorizontalPodAutoscaler]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[sustainablility]]></category>
		<category><![CDATA[swiss]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=28047</guid>

					<description><![CDATA[<p>On the 21st of September this year, we attended the Swiss Cloud Native Day. I was accompanied by two of my colleagues, Arnaud Berbier and Christoph Bernhard. This event took place for the third time, and this year, it landed in Bern at the Gurten. Surrounding the capital, Mount Gurten is reachable after 11 minutes [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/swiss-cloud-native-day-landed-at-the-gurten/">Swiss Cloud Native day landed at the Gurten!</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">On the 21st of September this year, we attended the <a href="https://cloudnativeday.ch/">Swiss Cloud Native Day</a>. I was accompanied by two of my colleagues, Arnaud Berbier and Christoph Bernhard. This event took place for the third time, and this year, it landed in Bern at the Gurten. Surrounding the capital, <a href="https://www.bern.com/en/detail/gurten-berns-local-mountain">Mount Gurten</a> is reachable after 11 minutes of funicular. It&#8217;s definitely a great spot to discuss, share, and learn new things!&nbsp;</p>



<p class="wp-block-paragraph">And learning sessions were organised; the day before was dedicated to workshops, provided on three different subjects</p>



<ul class="wp-block-list">
<li>GitOps with ArgoCD</li>



<li>Platform Engineering with Backstage</li>



<li>Kubernetes Basics</li>
</ul>



<p class="wp-block-paragraph">Jumping on the tramway, spending a bit of time on the Gurtenbahn, we were right on time to start our journey. All was well organised. At the time specified in their email communication, staff was waiting for all the attendees. Badges were alphabetically sorted, so we didn&#8217;t suffer from any waiting queues!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="1024" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_060811437.MP-crop-960x1024.jpg" alt="" class="wp-image-28049" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_060811437.MP-crop-960x1024.jpg 960w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_060811437.MP-crop-281x300.jpg 281w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_060811437.MP-crop-768x820.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_060811437.MP-crop-1439x1536.jpg 1439w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_060811437.MP-crop-1919x2048.jpg 1919w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p class="wp-block-paragraph">After wandering across the site, we took a seat in the main pavillon, where the welcome session and keynote were going to start.</p>



<p class="wp-block-paragraph">Anais Urlichs, from <a href="https://www.aquasec.com/">Aqua Security</a>, introduced the day by talking about, naturally, security and cloud native. Her title, &#8220;Back to the future in the space of cloud native security&#8221; definitely ended up with a picture of a sports car, which became popular after a 1985 movie <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> She started to flashback five years ago and came back to some security events. Codecov in 2021, SolarWinds in 2020, and MGM Resorts early this month: here are some breaches publicly reported.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="516" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_073319840.MP-crop-1024x516.jpg" alt="" class="wp-image-28053" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_073319840.MP-crop-1024x516.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_073319840.MP-crop-300x151.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_073319840.MP-crop-768x387.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_073319840.MP-crop-1536x774.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_073319840.MP-crop-2048x1032.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">What do they have in common? They were undetected by the security measures in place, which obviously failed. But staying positive, she closed her session by pushing the public to look at open-source and cloud native solutions, mentioning <a href="https://www.sigstore.dev/">Sigstore</a> for signing digital artefacts, <a href="https://kyverno.io/">Kyverno</a> for policies, and <a href="https://github.com/aquasecurity/tracee">Tracee</a> using eBPF for monitoring.</p>



<p class="wp-block-paragraph">A short break, we moved on, and the next session we chose was from Kunal Kushwaha &#8220;Embarking on a Kubernetes Odyssey: A Tale of Building, Deploying, and Scaling&#8221;. It was very worthwhile; his session was easy to follow with always a hint of humour. He was embarking us on a K8s journey as he promised, using his virtual assistant, Alex, and was tagging some questions and quotes: &#8220;Why should I go cloud native?&#8221;, &#8220;Benefits of a multi-cloud approach&#8221;. The most interesting was maybe this one: &#8220;Understanding the hype cycle&#8221;. From the &#8220;initial hype&#8221; to the &#8220;plateau of productivity&#8221;, he explained each step we would be faced with.</p>



<p class="wp-block-paragraph">As a huge fan of <a href="https://cilium.io/">Cilium</a> from <a href="https://isovalent.com/">Isovalent</a>, I stayed there to listen to Marga Manterola. She has been appointed Director of Engineering. We, at dbi services, use Cilium in Kubernetes deployments, running in a kube-proxy free setup. Even if I&#8217;m familiar with the concept of <a href="https://ebpf.io/">eBPF</a>, it is always a great pleasure and an opportunity to learn new functionalities around the use of eBPF in the Cilium stack.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="560" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_093248130.MP-crop-1024x560.jpg" alt="" class="wp-image-28052" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_093248130.MP-crop-1024x560.jpg 1024w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_093248130.MP-crop-300x164.jpg 300w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_093248130.MP-crop-768x420.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_093248130.MP-crop-1536x840.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/09/PXL_20230921_093248130.MP-crop-2048x1120.jpg 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">A few slides after the start of her session, she announced the great news, following a <a href="https://github.com/cncf/toc/pull/952">GitHub PR opened in Oct 2022</a>! Cilium is finally upgraded to Graduated Project at the <a href="https://www.cncf.io/">CNCF</a>. Unfortunately, the <a href="https://www.cncf.io/projects/cilium/">Cilium page</a> does not seem to reflect this change. This marks the maturity of the project, proving its stability and wide adoption.</p>



<p class="wp-block-paragraph">Security on Kubernetes, using Cilium, involves the following points</p>



<ul class="wp-block-list">
<li>network policies (facilitated by the <a href="https://editor.networkpolicy.io/">online editor</a>),</li>



<li>transparent encryption across nodes (either powered by the <a href="https://www.wireguard.com/">Wireguard</a> or <a href="https://en.wikipedia.org/wiki/IPsec">IPSec</a> protocols),</li>



<li>observability using <a href="https://github.com/cilium/hubble">Hubble</a> (either the UI, the CLI, or the metrics for Prometheus and Grafana),&nbsp;</li>



<li>and runtime security using <a href="https://github.com/cilium/tetragon">Tetragon</a>, Cilium&#8217;s sister project.</li>
</ul>



<p class="wp-block-paragraph">Annie Talvasto, during the afternoon, provided us with an interesting overview of an unfortunately popular subject. Working at VSHN, Annie&#8217;s goal was to show us &#8220;How Kubernetes Optimisation Can Combat Climate Change&#8221;. Ambitious topic, I naively thought fighting against global warming would simply require some <code>kubectl scale sts mylittle_voracious_statefulset --replicas=0</code>. I was wrong. She went through the principles of green software, location shifting (moving workload across different locations), time shifting (scaling up and down accordingly to the time of the day), and demand shaping. She displayed the website of the <a href="https://branch.climateaction.tech/issues/">Branch Magazine</a>. Based on the demand, the website is showing more or less components, from full monochrome-text-only, to a color-flavored-with-nice-pictures web site.</p>



<p class="wp-block-paragraph">Informative, <a href="https://keda.sh/">KEDA </a>was also mentioned at the end of the talk. I would definitely look at this tool, as it provides much more functionalities for automatic scaling on Kubernetes. At least much more than the &#8220;traditional&#8221; <a href="https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/">HPA</a>.</p>



<p class="wp-block-paragraph">I&#8217;ve probably forgotten to tell you about the other sessions, but all were, even if not as technical as initially expected, very informative. This was the first year we joined this event, and we&#8217;ll definitely be back next year! See you soon,<a href="https://cloudnativeday.ch/"> Swiss Cloud Native Day </a>!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/swiss-cloud-native-day-landed-at-the-gurten/">Swiss Cloud Native day landed at the Gurten!</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/swiss-cloud-native-day-landed-at-the-gurten/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Kubernetes Community Days 2023 in Zürich</title>
		<link>https://www.dbi-services.com/blog/kubernetes-community-days-2023-in-zurich/</link>
					<comments>https://www.dbi-services.com/blog/kubernetes-community-days-2023-in-zurich/#respond</comments>
		
		<dc:creator><![CDATA[DevOps]]></dc:creator>
		<pubDate>Mon, 19 Jun 2023 16:58:11 +0000</pubDate>
				<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[cilium]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[cncf]]></category>
		<category><![CDATA[ebpf]]></category>
		<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://www.dbi-services.com/blog/?p=25999</guid>

					<description><![CDATA[<p>I attended for the first time the KCD (Kubernetes Community Days) in Zürich with my colleagues Jean-Philippe and Arjen. I can say I was pretty eager to know more about topics around Kubernetes and eBPF stuff as Isovalent was well represented.This event is a two day conference with 2 streams at some slots, first day [&#8230;]</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-community-days-2023-in-zurich/">Kubernetes Community Days 2023 in Zürich</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="672" height="378" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/KCD.gif" alt="" class="wp-image-26089" /></figure>
</div>


<p class="wp-block-paragraph">I attended for the first time the KCD (Kubernetes Community Days) in Zürich with my colleagues Jean-Philippe and Arjen.</p>



<p class="wp-block-paragraph">I can say I was pretty eager to know more about topics around Kubernetes and eBPF stuff as Isovalent was well represented.<br>This event is a two day conference with 2 streams at some slots, first day is dedicated to technical workshops and day 2 (the one I attended) is dedicated to talk sessions.</p>



<p class="wp-block-paragraph">It started very well in a beautiful place at Google Swiss headquarter.</p>



<p class="wp-block-paragraph"><br>As we were at the opening, we had some time to do networking and it was funny to find Sacha Dubois a Senior solution specialist from VMware with who I had worked to implement a Managed Kubernetes with Tanzu last year.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="480" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_4999.jpeg" alt="" class="wp-image-26090" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_4999.jpeg 640w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_4999-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
</div>


<p class="wp-block-paragraph">The event started exactly on time at 8:45 AM in a crowdy sold out main conference room with a funny welcome message with many remarkable numbers starting with 2014 which is the initial release date of Kubernetes and ended with the number 10^100 which represent &#8220;one Googol&#8221; to thanks Google for their support.</p>



<h2 class="wp-block-heading">Cilium Mesh</h2>



<p class="wp-block-paragraph">The first talk was with Thomas Graf from Isovalent and gave us an overview of what can be done with Cilium Mesh to manage our infrastructure with a minimal effort by just only adding annotations to mention if a service should be reachable from another Kubernetes cluster with Cluster Mesh.<br><br>The innovation, here, is that our workloads and machines can be managed easily whether they are in the cloud, on-prem or on the edge by creating an universal networking layer.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="480" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5028.jpeg" alt="" class="wp-image-26091" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5028.jpeg 640w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5028-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
</div>


<h2 class="wp-block-heading">State of Green Washing</h2>



<p class="wp-block-paragraph">Then Max Körbächer talked about concrete sustainability with power consumption when using cloud resources for your Kubernetes cluster, to resume the idea, the best way to reduce your carbon emission is to be able to calculate it and then start by reducing non required tasks like multiple checks in your pipeline that are not required, change to &#8220;green regions&#8221;, and so on…</p>



<h2 class="wp-block-heading">Scale at another level</h2>



<p class="wp-block-paragraph">After that, I followed a talk at the extreme opposite from Ricardo Rocha a computing Engineer at the CERN who explain us how they manage to handle billions of data in a short time with Kubernetes and before his talk I was wondering what concrete applications can require that much nodes, now I know!</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="480" src="http://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5083.jpeg" alt="" class="wp-image-26092" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5083.jpeg 640w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5083-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
</div>


<p class="wp-block-paragraph">He also explain his other challenge to succeed on computing efficiently data gathered. The software that compute should be able to scale rapidly, but its image is about 24 GB!!!<br>This is where they start to use <strong>stargz snapshotter</strong>, this project leverage on the fact that pulling an image before the container can start take around 76% of the startup time and optimize the container start by rearranging image layers and allowing lazy pulling, in his demo we saw the pod starting in less than 7s compared to 1 minute for the standard image, very impressive!</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="640" height="480" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5108.jpeg" alt="" class="wp-image-26093" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5108.jpeg 640w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5108-300x225.jpeg 300w" sizes="auto, (max-width: 640px) 100vw, 640px" /></figure>
</div>


<h2 class="wp-block-heading">Anime and Kubernetes</h2>



<p class="wp-block-paragraph">Before the lunch I went to a more lightweight talk around Kubernetes but nevertheless very creative. Annie Talvasto has one of her passions which is Japanese animation, she talked about the analogy you can find in Anime and Kubernetes or tech careers.<br>With for example Naruto Multicloning and Kubernetes replicaset or the different evolution of Goku (Dragon Ball Z) from a kid to a Super Saiyan compared to when you started you career and when you start gaining badge from technical certificates, I loved that!<br>Thanks Annie for keeping fun in our job!</p>


<div class="wp-block-image">
<figure class="alignright size-medium"><img loading="lazy" decoding="async" width="225" height="300" src="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5314-225x300.jpg" alt="" class="wp-image-26094" srcset="https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5314-225x300.jpg 225w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5314-768x1024.jpg 768w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5314-1152x1536.jpg 1152w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5314-1536x2048.jpg 1536w, https://www.dbi-services.com/blog/wp-content/uploads/sites/2/2023/06/IMG_5314-scaled.jpg 1920w" sizes="auto, (max-width: 225px) 100vw, 225px" /></figure>
</div>


<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>



<p class="has-text-align-left wp-block-paragraph">During the lunch break, I had the opportunity to talk to Liz Rice and got her book &#8220;What is eBPF&#8221; signed.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">In the afternoon, I joined Lena Fuhrimann&#8217;s talk about how to troubleshoot efficiently our Kubernetes cluster with their project livelint.</p>



<p class="wp-block-paragraph">After that, I choose to ear Julius Volz, co-founder of Prometheus.io, talking about enhancement done is prometheus metrics for histograms with native histograms, never think all is carved in marble when you use open-source project, enhancement can be done everywhere.</p>



<h2 class="wp-block-heading">Extend observability with eBPF</h2>



<p class="wp-block-paragraph">Before the last talk, I followed Raphaël Pinson&#8217;s talk an other Isovalent talented member on removing the bridge between Dev and Ops when talking about monitoring by bringing observability to a new level with eBPF.<br>A fact is, eBPF is not a new thing, it&#8217;s everywhere since 10 years now, it allows Linux Kernel to be programmable without any additional configuration at application layer.</p>



<p class="wp-block-paragraph">You can find <a href="https://ebpf.io/applications/">here</a> the list of eBPF applications.</p>



<p class="wp-block-paragraph">The conference ended with Liz Rice talk in the main room touting about eBPF possibilities and coupled with Kubernetes Tetragon CRDs to bring your security to another level, the less we can say is, if you consider security, <strong>think with eBPF capabilities</strong>.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">This day was full of good talks and I hope you learned something from reading this resume.<br>I encourage you also to read Jean-Philippe&#8217;s blog <a href="https://www.dbi-services.com/blog/kubernetes-community-days-landed-in-zurich/">here</a> for the other talks of this event.</p>



<p class="wp-block-paragraph">Thanks dbi services for giving the opportunity to make your employees growing up!</p>
<p>L’article <a href="https://www.dbi-services.com/blog/kubernetes-community-days-2023-in-zurich/">Kubernetes Community Days 2023 in Zürich</a> est apparu en premier sur <a href="https://www.dbi-services.com/blog">dbi Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.dbi-services.com/blog/kubernetes-community-days-2023-in-zurich/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)

Served from: www.dbi-services.com @ 2026-06-17 18:33:40 by W3 Total Cache
-->