<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:hashnode="https://hashnode.com/rss"><channel><title><![CDATA[Karim El Jamali]]></title><description><![CDATA[Continuous Learner, Solutions Architect, Technical Account Manager, Technical Education Lead, &amp; Product Owner
]]></description><link>https://jamali.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 03 Dec 2024 09:19:21 GMT</lastBuildDate><atom:link href="https://jamali.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><atom:link rel="next" href="https://jamali.hashnode.dev/rss.xml?page=2"/><atom:link rel="previous" href="https://jamali.hashnode.dev/rss.xml"/><item><title><![CDATA[Dynamic Credentials with Hashicorp Vault]]></title><description><![CDATA[Need for secrets management focusing on dynamic secrets.We explain Secret Engines, Auth Methods ,roles,policies & audit capabilities with examples & code]]></description><link>https://jamali.hashnode.dev/dynamic-credentials-with-hashicorp-vault</link><guid isPermaLink="true">https://jamali.hashnode.dev/dynamic-credentials-with-hashicorp-vault</guid><category><![CDATA[secrets management]]></category><category><![CDATA[multicloud]]></category><category><![CDATA[hashicorp]]></category><category><![CDATA[hashicorp-vault]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[GCP]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Sat, 17 Aug 2024 16:47:01 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h1 id=&quot;heading-the-hassle-of-managing-secrets&quot;&gt;The Hassle of Managing Secrets&lt;/h1&gt;&lt;p&gt;It was around 3:15 AM when my pager buzzed for the first time ever, jolting me awake from sleep. At that time, I was working as a Technical Account Manager at AWS, and the situation was urgenta developer had mistakenly checked in AWS credentials to GitHub. Recently, I started going through an excellent course by Bryan Krausen on HashiCorp Vault, which connects directly to that issue and inspired me to write this post.&lt;/p&gt;&lt;p&gt;You can think of Hashicorp Vault as a super secret safe for your digital secrets. At a high level it can store your secrets safely, and request dynamic secrets which will be the focus of today&apos;s post, with granular levels of access control and a detailed audit trail. You can think about it as your one stop shop for all things credentials and secrets or even a front-end or a service by which all clients (users/developers/machines) can request access to those secrets.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723752632421/8074c261-ee60-4095-b41f-3f9c030a2d73.jpeg&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 1. Hassle of Managing Secrets&lt;/em&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-dynamic-secrets&quot;&gt;Dynamic Secrets&lt;/h1&gt;&lt;p&gt;You can think of Vault as an API Gateway servicing all your credential and secret requests, bringing a unified experience &amp;amp; a common methodology on secrets management. But what are Dynamic Secrets?&lt;/p&gt;&lt;p&gt;Dynamic secrets are short-lived keys or credentials. Instead of giving out a permanent password or API key, Vault generates or requests a new one whenever you need it, and it expires automatically after a set period. A few reasons this might be very beneficial:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Better Security: This means that if someone gets hold of the key, it won&apos;t be useful for long, keeping your data safer. You can have credentials that last for a few minutes which in case leaked will have a much more limited damage as most likely they wouldn&apos;t be usable shortly. When employees leave the company, you don&apos;t have to worry about any static long lived credentials that they might still have to access your systems. In addition, all secrets are safely encrypted via multiple chains of encryption keys.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;On Demand Credentials: Credentials are only there when you need them. You need to assume a particular AWS role, you ask Vault to generate dynamic short lived credentials to AWS to do a particular task.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;heading-high-level-overview&quot;&gt;High Level Overview&lt;/h1&gt;&lt;p&gt;At a high level Vault works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Clients (Machines/Users) first need to authenticate to Vault. This is a critical step as it determines what the secrets the client can access or request. This authentication can happen via multiple methods some of which are shown in Figure 2. In addition, this authentication process can happen via CLI or UI. In this example, we will use Okta as our authentication method.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;When Okta successfully authenticates the client, it returns back the Okta Group in which the user resides (e.g IT, SecOps..etc). Vault will make use of this group information and assign this user a policy. This policy basically authorizes the user or machine to authenticate for instance to AWS (simplified example here).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that Vault has identified the group and policy the user belongs to, it returns back a Token that is mapped to a policy that we discussed in step 2. &lt;em&gt;The whole objective of this whole authentication process is to be able to get a token that is constrained by an associated policy.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Finally, the client can request credentials against a particular AWS Role i.e. AssumeRole will be requested by Vault against the particular AWS Role to receive Dynamic or time-bound AWS credentials (AWS Access Key, Secret Key, Session Token). AWS is just an example here, it could be a full Multi-Cloud environment, local secrets, Kubernetes, databases and much more. The full list of supported secret engines can be found &lt;a target=&quot;_blank&quot; href=&quot;https://developer.hashicorp.com/vault/docs/secrets&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723863989716/7f16e44d-086a-41f2-a059-2d67e597eccd.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 2. Vault High Level Architecture&lt;/em&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-lets-dive-deeper&quot;&gt;Let&apos;s Dive Deeper&lt;/h1&gt;&lt;h2 id=&quot;heading-setup-configuration&quot;&gt;Setup Configuration&lt;/h2&gt;&lt;p&gt;The objective of this section is to explain the setup from a configuration &amp;amp; object standpoint. In this section we are assuming the following:&lt;/p&gt;&lt;p&gt;Prerequisites:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;There are two AWS Accounts Prod &amp;amp; Dev that users need access to.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For simplification purposes, within the Prod as well as Dev accounts there are two IAM roles. S3:readonly provides read only access to S3 storage and S3:readwrite allows full S3 access. This configuration is fully done within AWS. Enterprise setups would have a way larger number of accounts &amp;amp; roles but the same logic and object relationships continues to hold true.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These are the configuration steps:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;First and foremost, Vault needs to have access to the AWS accounts to be able to request dynamic credentials from within these accounts. This can be done via credentials (Access Key, Secret Key) or via an instance Profile if the Vault server itself runs within AWS. The IAM permissions used by Vault are documented &lt;a target=&quot;_blank&quot; href=&quot;https://developer.hashicorp.com/vault/docs/secrets/aws#iam-permissions-policy-for-vault&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Customers will generally have an Identity Provider (IdP) which in our case is Okta. Within Okta, most customers would group users depending on the role or function within the organization. It is important that the groups within Okta that would require Vault interaction be mapped to groups within Vault.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Each group within Vault (1:1 mapping of Okta/IdP group) has an associated Vault Policy. This Policy for instance would allow a particular group to access particular paths (Yes, everything in Vault is a path) and eventually assume particular Vault roles. Our policy in Figure3, allows access to prod/s3-readonly &amp;amp; dev/s3-readonly roles.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Vault roles are indeed a 1:1 mapping of the roles within the different AWS accounts.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723864034450/15f331f7-f7c4-4bb8-b3e8-178dae44f4a7.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 3. Setup Configuration&lt;/em&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-object-relationships&quot;&gt;Object Relationships&lt;/h2&gt;&lt;p&gt;Figure 4 tries to simplify the object relationships.&lt;/p&gt;&lt;p&gt;A Vault Group needs to have an associated Vault Policy. Recall that in our setup configuration, these Vault groups within the Vault Server are a one to one mapping of the external IdP groups (Okta). The vault policy can in turn provide access to one or more paths (roles) where these roles are again a one to one mapping of the roles configured within AWS.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723864050866/3790d593-895e-46fc-af9f-83b6e9ab1205.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 4. Object Relationships&lt;/em&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-putting-it-all-together&quot;&gt;Putting it All Together&lt;/h2&gt;&lt;p&gt;In this section, we will tackle it end-to-end from the user&apos;s perspective again touching on some of the concepts we explained for an end-to-end understanding.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Adam is a user belonging to Group: s3-readonly in Okta.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Adam tries to authenticate to Vault by using the Okta authentication method supplying his credentials (CLI/UI). Okta authenticates Adam successfully and returns back the group name Group: s3-readonly.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;As mentioned the groups in the IdP that need Vault access should have corresponding vault roles (Group: s3-readonly).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The vault group s3-readonly is associated with a policy that provides access to multiple paths (roles) in our example prod/s3-readonly &amp;amp; dev/s3-readonly. Note that each of those roles within Vault have corresponding IAM roles in the prod and dev accounts.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that authentication is complete and Vault maps the user to a particular policy, Vault issues a token and provides it to Adam.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;With the token &amp;amp; correct permissions, Adam goes ahead and requests credentials against the Vault group prod/s3-readonly.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Since the vault policy allows Adam to access the Vault role prod/s3-readonly, Vault with its own credentials requests AWS STS for temporary credentials against the IAM role s3-readonly within the Prod account.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Vault will return the credentials to Adam consisting of Access Key, Secret Key and Session token.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Adam can now issue the command &quot;aws s3 ls&quot; to list the buckets within S3 with the received credentials.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723869872571/d6d9a030-bada-4bbb-9b60-f76c3333e38c.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 5. Putting it All Together&lt;/em&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-lab-setup&quot;&gt;Lab Setup&lt;/h1&gt;&lt;p&gt;This is the lab setup we will use for demonstration. For Vault to be able to communicate with the AWS Account Prod, I associated the Vault EC2 instance with an IAM role via an Instance Profile.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723765767077/1c079328-4729-4036-a38f-da06fe671d9a.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 6. Lab Setup&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The below code snippet shows the Vault group within Okta &quot;s3-ro-group-role&quot; that maps to an Okta group name mapping it to a Vault Policy &quot;s3-ro-access-role-policy&quot;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Creating the group within Vault and mapping it to a policy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;auth/okta/groups/s3-ro-group-role&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;policies=&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Creating the policy s3-ro-access-role-policy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-role-policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-policy.hcl&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 7. Creating Auth Group within Vault &amp;amp; mapping it to a Vault Policy&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The below figure shows the details of the Vault policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Contents of the Policy&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-role-policy&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#The below path allows access to request credentials (read capability in &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Vault) for the role s3-ro-access-sts. Note the path has creds&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;aws/creds/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;read&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;#The below path allows access to read the configuration of the role s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;aws/roles/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;read&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;# If you want to allow users to renew the leases for the same role&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Renew leases means rotating the credentials&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;sys/leases/lookup/aws/creds/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;read&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;#Ability to revoke the lease&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;sys/leases/revoke/aws/creds/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;update&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;#Ability to list all available roles, note this doesn&apos;t allow issuing credentials&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# towards these roles&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;aws/roles/*&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;list&quot;&lt;/span&gt;]}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 8. Vault Policy&lt;/em&gt; s3-ro-access-role-policy&lt;/p&gt;&lt;p&gt;The code snippet in Figure 9 shows the mapping between the Vault role &quot;s3-ro-access-sts&quot; and the IAM role of the same name. Note that the ttl (default_sts_ttl) is set to 15 min and the max_sts_ttl (max ttl) is 24 hours. This means that that credentials generated against this rule will live for 15 minutes but can be renewed or rotated where applicable until the max_sts_ttl is reached. Once max_sts_ttl is reached, there is no possibility to renew the credential.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Finally this is a mapping between the Vault role s3-ro-access-sts &amp;amp;&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# the IAM Role ARN. Account number details are hidden &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# default_sts_ttl is 15 min means that credentials will live for a period of 15 min&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# max_sts_ttl=24h means you can request credential renewal where applicable&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/roles/s3-ro-access-sts&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;role_arns=&quot;arn:aws:iam::XXXXXXXXXXXX:role/s3-ro-access-sts&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;credential_type=assumed_role&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;default_sts_ttl=15m&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;max_sts_ttl=24h&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#reading the configuration of the role with the same details&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/roles/s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;                         &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;                         &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;credential_type&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;assumed_role&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;default_sts_ttl&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;15m&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;external_id&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;iam_groups&lt;/span&gt;                  &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;iam_tags&lt;/span&gt;                    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;max_sts_ttl&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;24h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;mfa_serial_number&lt;/span&gt;           &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;permissions_boundary_arn&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;policy_arns&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;policy_document&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;role_arns&lt;/span&gt;                   [&lt;span class=&quot;hljs-string&quot;&gt;arn:aws:iam::871253670082:role/s3-ro-access-sts&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;session_tags&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;user_path&lt;/span&gt;                   &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 9. Mapping Vault Roles to IAM Roles in AWS&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Now let&apos;s try to have a client authenticate.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Login with user credentials and receive the Vault token. &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# At this stage you only logged into to Vault successfully and have a token&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# with an associated policy (s3-ro-access-role-policy)&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;login&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-method=okta&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;username=&quot;david@gmail.com&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;password=&quot;XXXXXXXXXX&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Success!&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;You&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;are&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;authenticated.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;information&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;displayed&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;below&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;already&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;stored&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;helper.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;You&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;need&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;vault login&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;again.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Future&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;requests&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;will&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;automatically&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token.&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;                    &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;                    &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt;                  &lt;span class=&quot;hljs-string&quot;&gt;hvs.CAESIMniUaK0hhXKCGQaCQMkIR-P8K4UkKdQDAybYTWPQRLKGh4KHGh2cy5CcHRid01ETFhENmk5bWlCZGFoUk43ZTE&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_accessor&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;jEUNtHfL7PGTFxIAOzxyJgNy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_duration&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;768h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_renewable&lt;/span&gt;        &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_policies&lt;/span&gt;         [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;identity_policies&lt;/span&gt;      []&lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt;               [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;] &lt;span class=&quot;hljs-comment&quot;&gt;#policy associated with the vault token&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_meta_policies&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-role-policy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_meta_username&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;david@gmail.com&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Now david our user has requested credentials against the role s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Since the Vault policy allows it the request is successful&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#david receives short-lived credentials (access key, secret key and session_token)&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#note that there is no need for me to remove the credentials from the output because&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#their lifetime is 15 min&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;lease_id&lt;/span&gt;           &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;lease_duration&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;15m&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;lease_renewable&lt;/span&gt;    &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;access_key&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;ASIA4VWWD7DBJJFME3HO&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;arn&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;arn:aws:sts::871253670082:assumed-role/s3-ro-access-sts/vault-root-s3-ro-access-sts-1723777259-eAMrdCkR95w7Bv38YBbc&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;secret_key&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;ch3xhCWqtz5rO2S5nnuj505Rjajy0WYxg9kDZrGq&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;security_token&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;FwoGZXIvYXdzEPz//////////wEaDH3IMV5gEXgYudFS9iLfAfytgc1Ajloy83I+nyqFP92v++K60uGInLXQsWtztYEyCdRtNsGXfaumjU/Fuea2ZB6x3mLq7u/D8T5WQqU4/AHmecy0Gl2lGdsP6EFivLCVejJDVbgprDEVTZzDsBwIPpXsoMDmB9+9bxAxsVTEtifpqnrcG5WkuSne2OfrYEu6AwvDxp7HdhpgqXgabsxfT7zfO3WFyzEFutmM3N8yjyc001kROOxFxJojzDBAvo7PejN5tf2wjlWXdi8ZnxqjhSGaIcAn1rVCjpWM3DGn7wTUhzW97GMT2eaUsiBrw1so64H7tQYyLXiVIc3xZ3j1HbueByMKVUqDkuy885fM6CeIuVfW+KcLjsPahfngTb8O52Wbfg==&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;session_token&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;FwoGZXIvYXdzEPz//////////wEaDH3IMV5gEXgYudFS9iLfAfytgc1Ajloy83I+nyqFP92v++K60uGInLXQsWtztYEyCdRtNsGXfaumjU/Fuea2ZB6x3mLq7u/D8T5WQqU4/AHmecy0Gl2lGdsP6EFivLCVejJDVbgprDEVTZzDsBwIPpXsoMDmB9+9bxAxsVTEtifpqnrcG5WkuSne2OfrYEu6AwvDxp7HdhpgqXgabsxfT7zfO3WFyzEFutmM3N8yjyc001kROOxFxJojzDBAvo7PejN5tf2wjlWXdi8ZnxqjhSGaIcAn1rVCjpWM3DGn7wTUhzW97GMT2eaUsiBrw1so64H7tQYyLXiVIc3xZ3j1HbueByMKVUqDkuy885fM6CeIuVfW+KcLjsPahfngTb8O52Wbfg==&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ttl&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;14m59s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 10. Client authenticates to Vault, receives token &amp;amp; requests AWS credentials&lt;/em&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Prior to getting credentials failing to list the buckets in S3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;An&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;occurred&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(InvalidAccessKeyId)&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;when calling the ListBuckets operation:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Access&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;you&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;provided&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;does&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;exist&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;our&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;records.&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Inputting the credentials&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS_ACCESS_KEY_ID=&quot;ASIA4VWWD7DBJJFME3HO&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS_SECRET_ACCESS_KEY=&quot;ch3xhCWqtz5rO2S5nnuj505Rjajy0WYxg9kDZrGq&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS_SESSION_TOKEN=&quot;FwoGZXIvYXdzEPz//////////wEaDH3IMV5gEXgYudFS9iLfAfytgc1Ajloy83I+nyqFP92v++K60uGInLXQsWtztYEyCdRtNsGXfaumjU/Fuea2ZB6x3mLq7u/D8T5WQqU4/AHmecy0Gl2lGdsP6EFivLCVejJDVbgprDEVTZzDsBwIPpXsoMDmB9+9bxAxsVTEtifpqnrcG5WkuSne2OfrYEu6AwvDxp7HdhpgqXgabsxfT7zfO3WFyzEFutmM3N8yjyc001kROOxFxJojzDBAvo7PejN5tf2wjlWXdi8ZnxqjhSGaIcAn1rVCjpWM3DGn7wTUhzW97GMT2eaUsiBrw1so64H7tQYyLXiVIc3xZ3j1HbueByMKVUqDkuy885fM6CeIuVfW+KcLjsPahfngTb8O52Wbfg==&quot;&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Succeeded in listing the buckets in S3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;2023-11-01 13:57:10 &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kops-configuration-test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 11. Checking Credentials&lt;/em&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Here you can see the leases (credentials requested via Vault) &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Notice we only requested credentials for the role s3-ro-access-sts&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;sys/leases/lookup/aws/creds/&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-sts/&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Here you can see the lease id sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;sys/leases/lookup/aws/creds/s3-ro-access-sts/&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Here you can see details of the lease. Just want to show the ttl 6m57s &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#this is the time after which these credentials will expire&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;expire_time&lt;/span&gt;     &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:15:59.000032318Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;id&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;issue_time&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:00:59.177372978Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;last_renewal&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;renewable&lt;/span&gt;       &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ttl&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;6m57s&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Another run of the same command now showing the ttl is now 28s&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;expire_time&lt;/span&gt;     &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:15:59.000032318Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;id&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;issue_time&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:00:59.177372978Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;last_renewal&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;renewable&lt;/span&gt;       &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ttl&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;28s&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#We can no longer find the lease (ttl is expired)&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;error looking up lease id aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;making&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;API&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;request.&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;URL:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PUT&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;http://127.0.0.1:8200/v1/sys/leases/lookup&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Code: 400. Errors:&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;invalid&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Trying again to list the buckets in S3 and getting an ExpiredToken error&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;An&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;occurred&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ExpiredToken)&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;when calling the ListBuckets operation:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;provided&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;expired.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Figure12. Details of the lease &amp;amp; TTL&lt;/p&gt;&lt;h2 id=&quot;heading-audit-logs&quot;&gt;Audit Logs&lt;/h2&gt;&lt;p&gt;Audit logs are a necessity especially when it comes to your critical assets and attempts to access them.&lt;/p&gt;&lt;p&gt;This is how you can enable Audit Logs for Vault in a lab environment.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;audit&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;file_path=/var/log/vault_audit.log&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a sample log message that shows the user david authenticating and getting a token (client_token field) which is redacted in this output that is associated with the policy s3-ro-access-role-policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;{  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;auth&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;client_token&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;display_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;okta-david@gmail.com&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;metadata&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;username&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;david@gmail.com&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;],    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_ttl&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2764800&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;service&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;request&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;id&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;mount_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;auth/okta/&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;operation&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;update&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;path&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;auth/okta/login/david@gmail.com&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;response&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;auth&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;client_token&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;display_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;okta-david@gmail.com&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;metadata&quot;:&lt;/span&gt; {        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;username&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;david@gmail.com&quot;&lt;/span&gt;      },      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_ttl&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2764800&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;service&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;mount_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;auth/okta/&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;response&quot;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h1 id=&quot;heading-the-hassle-of-managing-secrets&quot;&gt;The Hassle of Managing Secrets&lt;/h1&gt;&lt;p&gt;It was around 3:15 AM when my pager buzzed for the first time ever, jolting me awake from sleep. At that time, I was working as a Technical Account Manager at AWS, and the situation was urgenta developer had mistakenly checked in AWS credentials to GitHub. Recently, I started going through an excellent course by Bryan Krausen on HashiCorp Vault, which connects directly to that issue and inspired me to write this post.&lt;/p&gt;&lt;p&gt;You can think of Hashicorp Vault as a super secret safe for your digital secrets. At a high level it can store your secrets safely, and request dynamic secrets which will be the focus of today&apos;s post, with granular levels of access control and a detailed audit trail. You can think about it as your one stop shop for all things credentials and secrets or even a front-end or a service by which all clients (users/developers/machines) can request access to those secrets.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723752632421/8074c261-ee60-4095-b41f-3f9c030a2d73.jpeg&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 1. Hassle of Managing Secrets&lt;/em&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-dynamic-secrets&quot;&gt;Dynamic Secrets&lt;/h1&gt;&lt;p&gt;You can think of Vault as an API Gateway servicing all your credential and secret requests, bringing a unified experience &amp;amp; a common methodology on secrets management. But what are Dynamic Secrets?&lt;/p&gt;&lt;p&gt;Dynamic secrets are short-lived keys or credentials. Instead of giving out a permanent password or API key, Vault generates or requests a new one whenever you need it, and it expires automatically after a set period. A few reasons this might be very beneficial:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Better Security: This means that if someone gets hold of the key, it won&apos;t be useful for long, keeping your data safer. You can have credentials that last for a few minutes which in case leaked will have a much more limited damage as most likely they wouldn&apos;t be usable shortly. When employees leave the company, you don&apos;t have to worry about any static long lived credentials that they might still have to access your systems. In addition, all secrets are safely encrypted via multiple chains of encryption keys.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;On Demand Credentials: Credentials are only there when you need them. You need to assume a particular AWS role, you ask Vault to generate dynamic short lived credentials to AWS to do a particular task.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;heading-high-level-overview&quot;&gt;High Level Overview&lt;/h1&gt;&lt;p&gt;At a high level Vault works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Clients (Machines/Users) first need to authenticate to Vault. This is a critical step as it determines what the secrets the client can access or request. This authentication can happen via multiple methods some of which are shown in Figure 2. In addition, this authentication process can happen via CLI or UI. In this example, we will use Okta as our authentication method.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;When Okta successfully authenticates the client, it returns back the Okta Group in which the user resides (e.g IT, SecOps..etc). Vault will make use of this group information and assign this user a policy. This policy basically authorizes the user or machine to authenticate for instance to AWS (simplified example here).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that Vault has identified the group and policy the user belongs to, it returns back a Token that is mapped to a policy that we discussed in step 2. &lt;em&gt;The whole objective of this whole authentication process is to be able to get a token that is constrained by an associated policy.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Finally, the client can request credentials against a particular AWS Role i.e. AssumeRole will be requested by Vault against the particular AWS Role to receive Dynamic or time-bound AWS credentials (AWS Access Key, Secret Key, Session Token). AWS is just an example here, it could be a full Multi-Cloud environment, local secrets, Kubernetes, databases and much more. The full list of supported secret engines can be found &lt;a target=&quot;_blank&quot; href=&quot;https://developer.hashicorp.com/vault/docs/secrets&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723863989716/7f16e44d-086a-41f2-a059-2d67e597eccd.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 2. Vault High Level Architecture&lt;/em&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-lets-dive-deeper&quot;&gt;Let&apos;s Dive Deeper&lt;/h1&gt;&lt;h2 id=&quot;heading-setup-configuration&quot;&gt;Setup Configuration&lt;/h2&gt;&lt;p&gt;The objective of this section is to explain the setup from a configuration &amp;amp; object standpoint. In this section we are assuming the following:&lt;/p&gt;&lt;p&gt;Prerequisites:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;There are two AWS Accounts Prod &amp;amp; Dev that users need access to.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For simplification purposes, within the Prod as well as Dev accounts there are two IAM roles. S3:readonly provides read only access to S3 storage and S3:readwrite allows full S3 access. This configuration is fully done within AWS. Enterprise setups would have a way larger number of accounts &amp;amp; roles but the same logic and object relationships continues to hold true.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These are the configuration steps:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;First and foremost, Vault needs to have access to the AWS accounts to be able to request dynamic credentials from within these accounts. This can be done via credentials (Access Key, Secret Key) or via an instance Profile if the Vault server itself runs within AWS. The IAM permissions used by Vault are documented &lt;a target=&quot;_blank&quot; href=&quot;https://developer.hashicorp.com/vault/docs/secrets/aws#iam-permissions-policy-for-vault&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Customers will generally have an Identity Provider (IdP) which in our case is Okta. Within Okta, most customers would group users depending on the role or function within the organization. It is important that the groups within Okta that would require Vault interaction be mapped to groups within Vault.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Each group within Vault (1:1 mapping of Okta/IdP group) has an associated Vault Policy. This Policy for instance would allow a particular group to access particular paths (Yes, everything in Vault is a path) and eventually assume particular Vault roles. Our policy in Figure3, allows access to prod/s3-readonly &amp;amp; dev/s3-readonly roles.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Vault roles are indeed a 1:1 mapping of the roles within the different AWS accounts.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723864034450/15f331f7-f7c4-4bb8-b3e8-178dae44f4a7.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 3. Setup Configuration&lt;/em&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-object-relationships&quot;&gt;Object Relationships&lt;/h2&gt;&lt;p&gt;Figure 4 tries to simplify the object relationships.&lt;/p&gt;&lt;p&gt;A Vault Group needs to have an associated Vault Policy. Recall that in our setup configuration, these Vault groups within the Vault Server are a one to one mapping of the external IdP groups (Okta). The vault policy can in turn provide access to one or more paths (roles) where these roles are again a one to one mapping of the roles configured within AWS.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723864050866/3790d593-895e-46fc-af9f-83b6e9ab1205.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 4. Object Relationships&lt;/em&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-putting-it-all-together&quot;&gt;Putting it All Together&lt;/h2&gt;&lt;p&gt;In this section, we will tackle it end-to-end from the user&apos;s perspective again touching on some of the concepts we explained for an end-to-end understanding.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Adam is a user belonging to Group: s3-readonly in Okta.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Adam tries to authenticate to Vault by using the Okta authentication method supplying his credentials (CLI/UI). Okta authenticates Adam successfully and returns back the group name Group: s3-readonly.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;As mentioned the groups in the IdP that need Vault access should have corresponding vault roles (Group: s3-readonly).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The vault group s3-readonly is associated with a policy that provides access to multiple paths (roles) in our example prod/s3-readonly &amp;amp; dev/s3-readonly. Note that each of those roles within Vault have corresponding IAM roles in the prod and dev accounts.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that authentication is complete and Vault maps the user to a particular policy, Vault issues a token and provides it to Adam.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;With the token &amp;amp; correct permissions, Adam goes ahead and requests credentials against the Vault group prod/s3-readonly.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Since the vault policy allows Adam to access the Vault role prod/s3-readonly, Vault with its own credentials requests AWS STS for temporary credentials against the IAM role s3-readonly within the Prod account.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Vault will return the credentials to Adam consisting of Access Key, Secret Key and Session token.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Adam can now issue the command &quot;aws s3 ls&quot; to list the buckets within S3 with the received credentials.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723869872571/d6d9a030-bada-4bbb-9b60-f76c3333e38c.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 5. Putting it All Together&lt;/em&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-lab-setup&quot;&gt;Lab Setup&lt;/h1&gt;&lt;p&gt;This is the lab setup we will use for demonstration. For Vault to be able to communicate with the AWS Account Prod, I associated the Vault EC2 instance with an IAM role via an Instance Profile.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1723765767077/1c079328-4729-4036-a38f-da06fe671d9a.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Figure 6. Lab Setup&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The below code snippet shows the Vault group within Okta &quot;s3-ro-group-role&quot; that maps to an Okta group name mapping it to a Vault Policy &quot;s3-ro-access-role-policy&quot;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Creating the group within Vault and mapping it to a policy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;auth/okta/groups/s3-ro-group-role&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;policies=&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Creating the policy s3-ro-access-role-policy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-role-policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-policy.hcl&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 7. Creating Auth Group within Vault &amp;amp; mapping it to a Vault Policy&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The below figure shows the details of the Vault policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Contents of the Policy&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-role-policy&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#The below path allows access to request credentials (read capability in &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Vault) for the role s3-ro-access-sts. Note the path has creds&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;aws/creds/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;read&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;#The below path allows access to read the configuration of the role s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;aws/roles/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;read&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;# If you want to allow users to renew the leases for the same role&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Renew leases means rotating the credentials&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;sys/leases/lookup/aws/creds/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;read&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;#Ability to revoke the lease&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;sys/leases/revoke/aws/creds/s3-ro-access-sts&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;update&quot;&lt;/span&gt;]}&lt;span class=&quot;hljs-comment&quot;&gt;#Ability to list all available roles, note this doesn&apos;t allow issuing credentials&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# towards these roles&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;aws/roles/*&quot;&lt;/span&gt; {  &lt;span class=&quot;hljs-string&quot;&gt;capabilities&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;=&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;list&quot;&lt;/span&gt;]}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 8. Vault Policy&lt;/em&gt; s3-ro-access-role-policy&lt;/p&gt;&lt;p&gt;The code snippet in Figure 9 shows the mapping between the Vault role &quot;s3-ro-access-sts&quot; and the IAM role of the same name. Note that the ttl (default_sts_ttl) is set to 15 min and the max_sts_ttl (max ttl) is 24 hours. This means that that credentials generated against this rule will live for 15 minutes but can be renewed or rotated where applicable until the max_sts_ttl is reached. Once max_sts_ttl is reached, there is no possibility to renew the credential.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Finally this is a mapping between the Vault role s3-ro-access-sts &amp;amp;&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# the IAM Role ARN. Account number details are hidden &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# default_sts_ttl is 15 min means that credentials will live for a period of 15 min&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# max_sts_ttl=24h means you can request credential renewal where applicable&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;write&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/roles/s3-ro-access-sts&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;role_arns=&quot;arn:aws:iam::XXXXXXXXXXXX:role/s3-ro-access-sts&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;credential_type=assumed_role&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;default_sts_ttl=15m&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;max_sts_ttl=24h&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#reading the configuration of the role with the same details&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/roles/s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;                         &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;                         &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;credential_type&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;assumed_role&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;default_sts_ttl&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;15m&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;external_id&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;iam_groups&lt;/span&gt;                  &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;iam_tags&lt;/span&gt;                    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;max_sts_ttl&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;24h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;mfa_serial_number&lt;/span&gt;           &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;permissions_boundary_arn&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;policy_arns&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;policy_document&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;role_arns&lt;/span&gt;                   [&lt;span class=&quot;hljs-string&quot;&gt;arn:aws:iam::871253670082:role/s3-ro-access-sts&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;session_tags&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;user_path&lt;/span&gt;                   &lt;span class=&quot;hljs-string&quot;&gt;n/a&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 9. Mapping Vault Roles to IAM Roles in AWS&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Now let&apos;s try to have a client authenticate.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Login with user credentials and receive the Vault token. &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# At this stage you only logged into to Vault successfully and have a token&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# with an associated policy (s3-ro-access-role-policy)&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;login&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-method=okta&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;username=&quot;david@gmail.com&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;password=&quot;XXXXXXXXXX&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Success!&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;You&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;are&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;authenticated.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;information&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;displayed&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;below&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;already&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;stored&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;helper.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;You&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;need&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;vault login&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;again.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Future&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;requests&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;will&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;automatically&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token.&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;                    &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;                    &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt;                  &lt;span class=&quot;hljs-string&quot;&gt;hvs.CAESIMniUaK0hhXKCGQaCQMkIR-P8K4UkKdQDAybYTWPQRLKGh4KHGh2cy5CcHRid01ETFhENmk5bWlCZGFoUk43ZTE&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_accessor&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;jEUNtHfL7PGTFxIAOzxyJgNy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_duration&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;768h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_renewable&lt;/span&gt;        &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_policies&lt;/span&gt;         [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;identity_policies&lt;/span&gt;      []&lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt;               [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;] &lt;span class=&quot;hljs-comment&quot;&gt;#policy associated with the vault token&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_meta_policies&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-role-policy&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;token_meta_username&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;david@gmail.com&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Now david our user has requested credentials against the role s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Since the Vault policy allows it the request is successful&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#david receives short-lived credentials (access key, secret key and session_token)&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#note that there is no need for me to remove the credentials from the output because&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#their lifetime is 15 min&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;lease_id&lt;/span&gt;           &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;lease_duration&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;15m&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;lease_renewable&lt;/span&gt;    &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;access_key&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;ASIA4VWWD7DBJJFME3HO&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;arn&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;arn:aws:sts::871253670082:assumed-role/s3-ro-access-sts/vault-root-s3-ro-access-sts-1723777259-eAMrdCkR95w7Bv38YBbc&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;secret_key&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;ch3xhCWqtz5rO2S5nnuj505Rjajy0WYxg9kDZrGq&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;security_token&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;FwoGZXIvYXdzEPz//////////wEaDH3IMV5gEXgYudFS9iLfAfytgc1Ajloy83I+nyqFP92v++K60uGInLXQsWtztYEyCdRtNsGXfaumjU/Fuea2ZB6x3mLq7u/D8T5WQqU4/AHmecy0Gl2lGdsP6EFivLCVejJDVbgprDEVTZzDsBwIPpXsoMDmB9+9bxAxsVTEtifpqnrcG5WkuSne2OfrYEu6AwvDxp7HdhpgqXgabsxfT7zfO3WFyzEFutmM3N8yjyc001kROOxFxJojzDBAvo7PejN5tf2wjlWXdi8ZnxqjhSGaIcAn1rVCjpWM3DGn7wTUhzW97GMT2eaUsiBrw1so64H7tQYyLXiVIc3xZ3j1HbueByMKVUqDkuy885fM6CeIuVfW+KcLjsPahfngTb8O52Wbfg==&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;session_token&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;FwoGZXIvYXdzEPz//////////wEaDH3IMV5gEXgYudFS9iLfAfytgc1Ajloy83I+nyqFP92v++K60uGInLXQsWtztYEyCdRtNsGXfaumjU/Fuea2ZB6x3mLq7u/D8T5WQqU4/AHmecy0Gl2lGdsP6EFivLCVejJDVbgprDEVTZzDsBwIPpXsoMDmB9+9bxAxsVTEtifpqnrcG5WkuSne2OfrYEu6AwvDxp7HdhpgqXgabsxfT7zfO3WFyzEFutmM3N8yjyc001kROOxFxJojzDBAvo7PejN5tf2wjlWXdi8ZnxqjhSGaIcAn1rVCjpWM3DGn7wTUhzW97GMT2eaUsiBrw1so64H7tQYyLXiVIc3xZ3j1HbueByMKVUqDkuy885fM6CeIuVfW+KcLjsPahfngTb8O52Wbfg==&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ttl&lt;/span&gt;                &lt;span class=&quot;hljs-string&quot;&gt;14m59s&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 10. Client authenticates to Vault, receives token &amp;amp; requests AWS credentials&lt;/em&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Prior to getting credentials failing to list the buckets in S3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;An&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;occurred&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(InvalidAccessKeyId)&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;when calling the ListBuckets operation:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Access&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;you&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;provided&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;does&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;exist&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;our&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;records.&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Inputting the credentials&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS_ACCESS_KEY_ID=&quot;ASIA4VWWD7DBJJFME3HO&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS_SECRET_ACCESS_KEY=&quot;ch3xhCWqtz5rO2S5nnuj505Rjajy0WYxg9kDZrGq&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AWS_SESSION_TOKEN=&quot;FwoGZXIvYXdzEPz//////////wEaDH3IMV5gEXgYudFS9iLfAfytgc1Ajloy83I+nyqFP92v++K60uGInLXQsWtztYEyCdRtNsGXfaumjU/Fuea2ZB6x3mLq7u/D8T5WQqU4/AHmecy0Gl2lGdsP6EFivLCVejJDVbgprDEVTZzDsBwIPpXsoMDmB9+9bxAxsVTEtifpqnrcG5WkuSne2OfrYEu6AwvDxp7HdhpgqXgabsxfT7zfO3WFyzEFutmM3N8yjyc001kROOxFxJojzDBAvo7PejN5tf2wjlWXdi8ZnxqjhSGaIcAn1rVCjpWM3DGn7wTUhzW97GMT2eaUsiBrw1so64H7tQYyLXiVIc3xZ3j1HbueByMKVUqDkuy885fM6CeIuVfW+KcLjsPahfngTb8O52Wbfg==&quot;&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Succeeded in listing the buckets in S3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;2023-11-01 13:57:10 &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kops-configuration-test&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Figure 11. Checking Credentials&lt;/em&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Here you can see the leases (credentials requested via Vault) &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;# Notice we only requested credentials for the role s3-ro-access-sts&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;sys/leases/lookup/aws/creds/&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;s3-ro-access-sts/&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Here you can see the lease id sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;sys/leases/lookup/aws/creds/s3-ro-access-sts/&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Keys&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Here you can see details of the lease. Just want to show the ttl 6m57s &lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#this is the time after which these credentials will expire&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;expire_time&lt;/span&gt;     &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:15:59.000032318Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;id&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;issue_time&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:00:59.177372978Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;last_renewal&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;renewable&lt;/span&gt;       &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ttl&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;6m57s&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Another run of the same command now showing the ttl is now 28s&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;Key&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;---&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;-----&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;expire_time&lt;/span&gt;     &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:15:59.000032318Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;id&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;issue_time&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;2024-08-16T03:00:59.177372978Z&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;last_renewal&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;nil&amp;gt;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;renewable&lt;/span&gt;       &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ttl&lt;/span&gt;             &lt;span class=&quot;hljs-string&quot;&gt;28s&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#We can no longer find the lease (ttl is expired)&lt;/span&gt;[&lt;span class=&quot;hljs-string&quot;&gt;ec2-user@ip-10-0-5-142&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;~&lt;/span&gt;]&lt;span class=&quot;hljs-string&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lookup&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;error looking up lease id aws/creds/s3-ro-access-sts/sfB1tR8zvGSLqlxyxS6UATFx:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;making&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;API&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;request.&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;URL:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PUT&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;http://127.0.0.1:8200/v1/sys/leases/lookup&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Code: 400. Errors:&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;invalid&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;lease&lt;/span&gt;&lt;span class=&quot;hljs-comment&quot;&gt;#Trying again to list the buckets in S3 and getting an ExpiredToken error&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;aws&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;s3&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;An&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;occurred&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ExpiredToken)&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;when calling the ListBuckets operation:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;provided&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;expired.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Figure12. Details of the lease &amp;amp; TTL&lt;/p&gt;&lt;h2 id=&quot;heading-audit-logs&quot;&gt;Audit Logs&lt;/h2&gt;&lt;p&gt;Audit logs are a necessity especially when it comes to your critical assets and attempts to access them.&lt;/p&gt;&lt;p&gt;This is how you can enable Audit Logs for Vault in a lab environment.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;vault&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;audit&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;file_path=/var/log/vault_audit.log&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a sample log message that shows the user david authenticating and getting a token (client_token field) which is redacted in this output that is associated with the policy s3-ro-access-role-policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;{  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;auth&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;client_token&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;display_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;okta-david@gmail.com&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;metadata&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;username&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;david@gmail.com&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;],    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_ttl&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2764800&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;service&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;request&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;id&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;mount_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;auth/okta/&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;operation&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;update&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;path&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;auth/okta/login/david@gmail.com&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;response&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;auth&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;client_token&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;REDACTED&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;display_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;okta-david@gmail.com&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;metadata&quot;:&lt;/span&gt; {        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;username&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;david@gmail.com&quot;&lt;/span&gt;      },      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;policies&quot;:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;s3-ro-access-role-policy&quot;&lt;/span&gt;],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_ttl&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2764800&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;token_type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;service&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;mount_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;auth/okta/&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;response&quot;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1723912446414/f4311811-9654-48fa-80cc-c64484ba992b.jpeg</hashnode:coverImage></item><item><title><![CDATA[Intro to Kyverno]]></title><description><![CDATA[This article focuses on Kyverno an admission controller tailored for Kubernetes. It explains the use-cases, how it works and tries a few common policies.]]></description><link>https://jamali.hashnode.dev/intro-to-kyverno</link><guid isPermaLink="true">https://jamali.hashnode.dev/intro-to-kyverno</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[Security]]></category><category><![CDATA[#kubernetes #container ]]></category><category><![CDATA[kyverno]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[GCP]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Fri, 31 May 2024 02:43:16 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;Last week, a new tool called Kyverno captured my interest. I spent some time diving into their documentation to understand the benefits and use cases it addresses.&lt;/p&gt;&lt;p&gt;Kyverno is a policy engine designed specifically for Kubernetes. But what exactly is a policy engine? Simply put, it sets acceptable configuration standards for Kubernetes objects and resources. When these standards are deviated from, the engine can block the deployment, send alerts, or even mutate the configurations to comply with the policies. The main use cases for a policy engine like Kyverno revolve around enhancing security, ensuring compliance, automating tasks, and improving governance within Kubernetes clusters.&lt;/p&gt;&lt;h1 id=&quot;heading-basics-of-admission-controllers&quot;&gt;Basics of Admission Controllers&lt;/h1&gt;&lt;p&gt;An admission controller is a component within Kubernetes that intercepts requests to the Kubernetes API server before the object is persisted, but after the request has been authenticated and authorized. As shown in the figure below, when a request to create a deployment is sent to the API server, it first undergoes authentication and authorization. Afterward, it is passed to the Admission Controller, depicted as a police officer in the diagram. In this scenario, the Admission Controller is configured to ensure that any deployment must have a minimum of two replicas to maintain high availability (HA).&lt;/p&gt;&lt;p&gt;Thus, the best way to think about an admission controller is as a police officer that examines requests sent to the API server to ensure they align with the organization&apos;s intent. It acts as a controller or watchdog, persistently ensuring conformance to organizational policies and intents.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1716916216207/2591c303-1907-4f80-8986-7a3a594c2ec9.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-built-in-admission-controllers&quot;&gt;Built in Admission Controllers&lt;/h1&gt;&lt;p&gt;It&apos;s worth noting that Kubernetes includes several built-in admission controllers.. You can find a list of these controllers &lt;a target=&quot;_blank&quot; href=&quot;link&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Before delving further, it&apos;s important to differentiate between the two general types of admission controllers:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Validating Admission Controllers: These controllers simply allow or reject requests.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Mutating Admission Controllers: These controllers have the ability to modify objects related to the requests they receive.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Let&apos;s take the example of LimitRanger, an in-built admission controller or plugin. A LimitRange defines policies to govern resource allocations for pods or other applicable resources. More details can be found &lt;a target=&quot;_blank&quot; href=&quot;link&quot;&gt;here&lt;/a&gt;. It&apos;s important to note that LimitRange functions as both a validating and a mutating admission controller.&lt;/p&gt;&lt;p&gt;To try it out, the first step is to add it to the list of admission controllers or plugins using the &quot;--enable-admission-plugins&quot; flag.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;annotations:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;172.18&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:6443&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;creationTimestamp:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;null&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;component:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-apiserver&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;tier:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;control-plane&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-apiserver&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;containers:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;command:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-apiserver&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--advertise-address=172.18.0.3&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--allow-privileged=true&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--authorization-mode=Node,RBAC&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--client-ca-file=/etc/kubernetes/pki/ca.crt&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--enable-admission-plugins=NodeRestriction,LimitRanger&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, let&apos;s define the LimitRange object where we configure:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Minimum and maximum CPUs for all pods within the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Default limits applied when a user doesn&apos;t explicitly configure the resources for a pod.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This configuration ensures that all pods adhere to the specified CPU limits, promoting efficient resource utilization across the cluster. Additionally, it provides a safety net by automatically assigning default limits when users do not specify resource constraints for their pods.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;LimitRange&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cpu-resource-constraint&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;limits:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;default:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# this section defines default limits&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;defaultRequest:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# this section defines default requests&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;max:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# max and min define the limit range&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;600m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;min:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;100m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Container&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Below is an example of a Pod configuration that requests 700m of CPU resources, which exceeds the defined limit of 500m. When attempting to apply this configuration, you&apos;ll immediately encounter an error, showcasing the validating behavior of the admission controller.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;example-conflict-with-limitrange-cpu&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;containers:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;demo&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;image:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;registry.k8s.io/pause:2.0&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;requests:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;700m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;example-conflict-with-limitrange-cpu&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;is invalid:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;spec.containers[0].resources.requests:&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Invalid value:&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;&quot;700m&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;must&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;less&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;than&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cpu&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, let&apos;s attempt to create another pod without specifying any resource requests or limits.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can observe that the default requests and limits have been automatically applied to the pod, courtesy of the admission controller. This exemplifies a mutating behavior, wherein the original request has been modified to include the necessary resource requests and limits.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;pods&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;containers:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;image:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;imagePullPolicy:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Always&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;limits:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;requests:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-external-admission-controllers&quot;&gt;External Admission Controllers&lt;/h1&gt;&lt;p&gt;In the previous section, we delved into the inherent admission controllers within Kubernetes. However, these built-in controllers often lack the configurability or flexibility needed to accommodate diverse organizational requirements.&lt;/p&gt;&lt;p&gt;Below is a diagram (Source: Kyverno documentation) illustrating the stages of an API request to a Kubernetes API Server, highlighting the crucial steps involving Mutating and Validating admissions.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://kyverno.io/images/kyverno-architecture.png&quot; alt=&quot;Kyverno Architecture&quot; /&gt;&lt;/p&gt;&lt;p&gt;Here&apos;s a concise overview of the mentioned components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Webhook Controller&lt;/strong&gt;: This controller is responsible for managing webhooks, which play a pivotal role in programming the Kubernetes API server to forward API requests to Kyverno. Webhooks are essential building blocks that enable seamless integration between Kubernetes and Kyverno, facilitating the enforcement of policies and configurations.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Policy Engine&lt;/strong&gt;: Kyverno&apos;s policy engine serves as the cornerstone component tasked with evaluating and enforcing policies on Kubernetes resources. It empowers administrators to define policies as Kubernetes resources within Kyverno, enabling them to manage, validate, and mutate other Kubernetes resources effectively. By processing these policies, the policy engine ensures that the cluster complies with desired configurations and standards, fostering consistency and adherence to organizational policies.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cert Renewer&lt;/strong&gt;: This component focuses on managing TLS (Transport Layer Security) communications between the Kubernetes API Server and the Kyverno webhook service. By handling TLS certificates, the Cert Renewer ensures secure transmission of data between these components, safeguarding the integrity and confidentiality of communications.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The ValidatingWebhookConfiguration plays a crucial role in configuring the Kubernetes API server to route requests to Kyverno. Here&apos;s how it works:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Webhooks Section&lt;/strong&gt;: This section defines where to redirect matching API requests. It typically references a Kubernetes Service and specifies a particular path to send the requests for validation.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rules Section&lt;/strong&gt;: The rules section allows you to specify the resources and operations that you want to send to the admission controller for validation. This granularity enables precise control over which requests are subject to validation.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Namespace Selector&lt;/strong&gt;: This field enables you to focus admission control on specific namespaces where stricter governance is required or where you want to apply policies gradually. It provides flexibility in applying policies across different parts of the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Failure Policy&lt;/strong&gt;: This field determines how the Kubernetes API server responds when it receives a negative admission response from the admission controller. The options are &quot;Fail&quot; and &quot;Ignore&quot;. &quot;Fail&quot; immediately rejects the intended operation upon receiving a negative admission response, ensuring strict enforcement of policies. On the other hand, &quot;Ignore&quot; provides more leniency by allowing the operation to proceed despite policy violations. This can be useful when you want to identify and understand gaps before fully enforcing policies.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admissionregistration.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;ValidatingWebhookConfiguration&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno-validating-webhook&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;webhooks:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;validate.kyverno.svc&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;clientConfig:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;service:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno-svc&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;/validate&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;caBundle:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;ca-bundle&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# Base64 encoded CA certificate&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;operations:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;CREATE&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;UPDATE&quot;&lt;/span&gt;]        &lt;span class=&quot;hljs-attr&quot;&gt;apiGroups:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;]        &lt;span class=&quot;hljs-attr&quot;&gt;apiVersions:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;]        &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;]    &lt;span class=&quot;hljs-attr&quot;&gt;failurePolicy:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Fail&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchPolicy:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Equivalent&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;namespaceSelector:&lt;/span&gt; {}    &lt;span class=&quot;hljs-attr&quot;&gt;objectSelector:&lt;/span&gt; {}    &lt;span class=&quot;hljs-attr&quot;&gt;sideEffects:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;None&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;timeoutSeconds:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;10&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;admissionReviewVersions:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;v1&quot;&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-sample-policies&quot;&gt;Sample Policies&lt;/h1&gt;&lt;p&gt;This example policy ensures that each configured pod must have the &quot;app&quot; label.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-label-app&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Audit&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureActionOverrides:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;action:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Enforce&lt;/span&gt;     &lt;span class=&quot;hljs-comment&quot;&gt;# Action to apply&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;       &lt;span class=&quot;hljs-comment&quot;&gt;# List of affected namespaces&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-label-app&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;            &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;The label `app` is required.&quot;&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;?*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Explanation:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;ClusterPolicy:&lt;/strong&gt; as the name suggests is a policy that applies Cluster wide vs policy which is scoped to the namespace.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;background&lt;/strong&gt;: When set to true, this field ensures that the policy is applied retroactively to existing resources upon creation or update. This means that the policy will be evaluated against resources that were created before the policy was implemented.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;validationFailureAction&lt;/strong&gt;: This field determines the default action to take when a validation rule fails. In this case, it is set to &quot;audit&quot;, meaning that failed validations will be recorded, but resource creation will continue.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;validationFailureActionOverrides&lt;/strong&gt;: This section allows you to override the default validation failure action for specific namespaces. In the example, validation failures in the default namespace will be enforced, overriding the default action set in validationFailureAction.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;rules&lt;/strong&gt;: This section defines the rules of the policy. In this example, there is one rule named &quot;check-app-label&quot; that applies to Pods. The rule specifies that Pods must have an &apos;app&apos; label.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Attempting to create an nginx pod within the blue namespace succeeds with a warning as per the policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image=nginx&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Warning: policy check-label-app.check-label-app: validation error:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;`app`&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;required.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-label-app&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;failed&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/metadata/labels/app/&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;pod/nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;created&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attempting the same operation within the default namespace is denied again as per policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image=nginx&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Error from server:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;webhook&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;validate.kyverno.svc-fail&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;denied the request:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod/default/nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blocked&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;due&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;following&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;check-label-app:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;check-label-app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&apos;validation error: The label `app` is required. rule check-label-app    failed at path /metadata/labels/app/&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here&apos;s the example policy enforcing a minimum level of high availability for deployments:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;validate-replica-count&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;            &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Replica count for a Deployment must be greater than or equal to 2.&quot;&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;replicas:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;gt;=2&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-cilium-policies&quot;&gt;Cilium Policies&lt;/h1&gt;&lt;p&gt;After reviewing several examples, I&apos;ve considered implementing Kyverno for admission control of Cilium Network Policies. For that matter I found an interesting repository &lt;a target=&quot;_blank&quot; href=&quot;https://github.com/adobeSlash/cilium-kyverno&quot;&gt;here&lt;/a&gt; that helped me get started.&lt;/p&gt;&lt;p&gt;After making little modifications to various examples on GitHub, I crafted a policy aimed at whitelisting specific namespaces where Cilium policies can be configured. Any attempts to create Cilium policies in namespaces not included in the whitelist will be denied. I think this is pretty useful to ensure no mishaps can happen as part of Network Policy configuration and helps with locking things down one namespace at a time.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;limit-ciliumnetworkpolicy-scope&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;limit-scope&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;          &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;CiliumNetworkPolicy can only be applied to specific namespaces&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;anyPattern:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I attempt to use the below Network Policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;isolate-ns1&quot;&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;green&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      {}  &lt;span class=&quot;hljs-attr&quot;&gt;ingress:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;fromEndpoints:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;        {}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As expected, the request is blocked by the admission controller.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mypolicy.yaml&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Error from server:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;creating&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;&quot;mypolicy.yaml&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;webhook&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;validate.kyverno.svc-fail&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;denied the request:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy/green/isolate-ns1&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blocked&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;due&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;following&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;limit-ciliumnetworkpolicy-scope:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;limit-scope:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&apos;validation error: CiliumNetworkPolicy can only be applied to specific    namespaces. rule limit-scope[0] failed at path /metadata/namespace/ rule limit-scope[1]    failed at path /metadata/namespace/&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The example below provides more insight on Kyverno&apos;s capabilities whereby we leverage a ClusterPolicy whose objective is to ensure that pods to be created need to have the label &quot;app.kubernetes.io/name&quot;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;require-labels&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;annotations:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/title:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Labels&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/category:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Best&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Practices&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/minversion:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1.6&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/severity:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;medium&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/subject:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Label&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/description:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;gt;-      Define and use labels that identify semantic attributes of your application or Deployment.      A common set of labels allows tools to work collaboratively, describing objects in a common manner that      all tools can understand. The recommended labels describe applications in a way that can be      queried. This policy validates that the label `app.kubernetes.io/name` is specified with some value.&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-for-labels&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;          &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;The label `app.kubernetes.io/name` is required.&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;?*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, I try to create a deployment (not a Pod) &amp;amp; interestingly enough the admission controller reacts in the right manner not allowing the deployment to happen.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;deployment&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kubernetes-bootcamp&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image=gcr.io/google-samples/kubernetes-bootcamp:v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;error: failed to create deployment:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;webhook&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;validate.kyverno.svc-fail&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;denied the request:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Deployment/default/kubernetes-bootcamp&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blocked&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;due&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;following&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;require-labels:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;autogen-check-for-labels:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&apos;validation error: The label `app.kubernetes.io/name`    is required. rule autogen-check-for-labels failed at path /spec/template/metadata/labels/app.kubernetes.io/name/&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-conclusion&quot;&gt;Conclusion&lt;/h1&gt;&lt;p&gt;Kyverno and more generally admission controllers can help ensure better security, compliance and governance of Kubernetes Clusters. On top of this, there is a good number of &lt;a target=&quot;_blank&quot; href=&quot;https://kyverno.io/policies/?policytypes=Best%2520Practices%2BEKS%2520Best%2520Practices%2Bvalidate&quot;&gt;readily available policies&lt;/a&gt; making it easier to consume. I even tried asking ChatGPT to generate a Kyverno policy:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;please craft a kyverno policy that would allow cilium network policies to only touch pods that have environment: dev as not to disrupt production&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;restrict-cilium-policy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;restrict-cilium-network-policy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Cilium Network Policies can only target pods with the label &apos;environment: dev&apos;.&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;environment:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dev&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It might be worthwhile if you are getting started to deploy it to have the validationFailureAction as Audit as this would provide context on how objects being created deviate from the norm and have the background set to true as this will ensure that your existing resources are scanned in terms of adherence to organizational policies.ValidateActionOverride will be useful to enforce policies on namespaces one by one to ensure a smooth adoption.&lt;/p&gt;&lt;p&gt;Finally, a good one to mention is Policy Reports that provide insights into the compliance status of resources in the Kubernetes cluster. Though I have noticed that some resources don&apos;t show up in the reports, it is still very useful when background is set to true as this will give an indication of the compliance state of all resources within Kubernetes.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policyreports.wgpolicyk8s.io&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-A&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;NAMESPACE&lt;/span&gt;            &lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                                   &lt;span class=&quot;hljs-string&quot;&gt;KIND&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                                             &lt;span class=&quot;hljs-string&quot;&gt;PASS&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;FAIL&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;WARN&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ERROR&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;SKIP&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;AGE&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;6228a955-195b-4795-83ee-5c1a662bf532&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;prometheus&lt;/span&gt;                                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-number&quot;&gt;81242176&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;-f6ac-4331-8be3-bdedccc32f67&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;grafana-6f4755f98c-4cxzx&lt;/span&gt;                         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;bbe6c1f9-a91f-4628-b524-bf04c2603c0a&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;grafana-6f4755f98c&lt;/span&gt;                               &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;c70e65cc-800a-4986-90ab-c52078189f29&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;prometheus-67fdcf4796&lt;/span&gt;                            &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;d7006776-21e2-4b86-a684-d6cf173f2f2e&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;prometheus-67fdcf4796-gj4kb&lt;/span&gt;                      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;dd37f6a5-0bd7-43f8-a7d5-337f089df95f&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;grafana&lt;/span&gt;                                          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;0064fbf9-80ce-4517-934e-5b34d98e88c5&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;DaemonSet&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;cilium&lt;/span&gt;                                           &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;0be0cbb5-25b0-448e-922c-074e510d269c&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-zx692&lt;/span&gt;                                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;0d9c47b0-2b55-4752-ae1f-1d22ab63e9c9&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator-5d64788c99-g2f48&lt;/span&gt;                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;14ae51f5-ba2f-4942-aa35-d93e94d2d76f&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-scheduler-kind-control-plane&lt;/span&gt;                &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;23a370a8-ef0e-4d1c-aa19-ffab703b5f0d&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;DaemonSet&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy&lt;/span&gt;                                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;35e9706f-7a88-4932-a78c-37745a397abe&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;coredns-76f75df574-xvxns&lt;/span&gt;                         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-number&quot;&gt;501429e0&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;-4f00-4f30-9cc8-9eb633d9a0e5&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;coredns-76f75df574&lt;/span&gt;                               &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;6911c7d8-4128-470d-89ef-6fc969e62b05&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-controller-manager-kind-control-plane&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;69a7f09e-a753-4dd9-8fe2-e5eb70e3691d&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-jvllh&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;8c6c30a5-1ef6-4bd1-9978-381b0aeca611&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator&lt;/span&gt;                                  &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;9cd0150a-34fd-49df-837b-d2f19ea575dd&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator-5d64788c99&lt;/span&gt;                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;9ecef8f0-c9b1-4989-9fa6-15b07f8de581&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;coredns&lt;/span&gt;                                          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;a8482fb9-10bc-4819-8230-17a776d1079f&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-kfrnt&lt;/span&gt;                                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;be23c6c2-8ad5-4a86-adc1-de4180dc8d81&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-g4gnt&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cc4021e0-2360-403b-b013-fad70807f04b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;coredns-76f75df574-7zdjj&lt;/span&gt;                         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;dba5f38a-e8e5-46d0-9e4a-ec269ae9ddb4&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-bztgh&lt;/span&gt;                                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;e0146bde-f48c-4663-997f-019e24402bcd&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator-5d64788c99-hdlsz&lt;/span&gt;                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;eadc9e7d-90dd-42c1-9dbe-62b3822d668a&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-fn567&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;f3d97e60-2a0f-4985-9644-a98e98541103&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;etcd-kind-control-plane&lt;/span&gt;                          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;ff45c31d-ca5d-43c5-90da-bb0f113b03b3&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-6jfqw&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;0840b270-f6a2-499c-b1d7-a37a716ef440&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-background-controller-84b5ff7875-fkd2x&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;13f74dc4-4e27-4a78-b34c-cc9ae3e7b57c&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;CronJob&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-admission-reports&lt;/span&gt;                &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;27bf13f4-2bc8-4dae-8e0c-2a29d57438c0&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-reports-controller&lt;/span&gt;                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;29bcbffc-d253-4d8e-97d6-98043bf9600b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;CronJob&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-cluster-admission-reports&lt;/span&gt;        &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;532c51d8-843e-42ae-82d2-d5a8f6f9b62e&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-controller-574fc8c6b6-kpbbg&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;6fea3745-3b96-46c9-9c62-59cc22f75722&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-admission-controller&lt;/span&gt;                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;80e5c9d7-9677-4a71-a4c3-89370afd665e&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-controller-574fc8c6b6&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;94048b9d-8a52-4f70-bbc4-cb814b8ee671&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-reports-controller-5557c85bb4-8jpm6&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;a0948eaa-9332-488c-a7a9-cb9c3ee4b045&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-admission-controller-6797d4bd6b&lt;/span&gt;          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;ab1c5601-072a-4782-b08a-d9c2e9ae3d92&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-controller&lt;/span&gt;                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;ead76fa0-bfec-4385-9a00-4b26293c069b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-admission-controller-6797d4bd6b-l2kwf&lt;/span&gt;    &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;f47b4093-46fd-4eb7-abe3-0e431a98d23a&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-background-controller-84b5ff7875&lt;/span&gt;         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;local-path-storage&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;13e4514a-18e1-484d-aa39-c591f34c4d56&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;local-path-provisioner-7577fdbbfb-6hb2v&lt;/span&gt;          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;local-path-storage&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;45119b4b-a214-4d6c-b06a-7c8a2c4af402&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;local-path-provisioner-7577fdbbfb&lt;/span&gt;                &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;local-path-storage&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;adc91343-2e69-4059-aebb-1e4a50f80a2b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;local-path-provisioner&lt;/span&gt;                           &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;p&gt;Last week, a new tool called Kyverno captured my interest. I spent some time diving into their documentation to understand the benefits and use cases it addresses.&lt;/p&gt;&lt;p&gt;Kyverno is a policy engine designed specifically for Kubernetes. But what exactly is a policy engine? Simply put, it sets acceptable configuration standards for Kubernetes objects and resources. When these standards are deviated from, the engine can block the deployment, send alerts, or even mutate the configurations to comply with the policies. The main use cases for a policy engine like Kyverno revolve around enhancing security, ensuring compliance, automating tasks, and improving governance within Kubernetes clusters.&lt;/p&gt;&lt;h1 id=&quot;heading-basics-of-admission-controllers&quot;&gt;Basics of Admission Controllers&lt;/h1&gt;&lt;p&gt;An admission controller is a component within Kubernetes that intercepts requests to the Kubernetes API server before the object is persisted, but after the request has been authenticated and authorized. As shown in the figure below, when a request to create a deployment is sent to the API server, it first undergoes authentication and authorization. Afterward, it is passed to the Admission Controller, depicted as a police officer in the diagram. In this scenario, the Admission Controller is configured to ensure that any deployment must have a minimum of two replicas to maintain high availability (HA).&lt;/p&gt;&lt;p&gt;Thus, the best way to think about an admission controller is as a police officer that examines requests sent to the API server to ensure they align with the organization&apos;s intent. It acts as a controller or watchdog, persistently ensuring conformance to organizational policies and intents.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1716916216207/2591c303-1907-4f80-8986-7a3a594c2ec9.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-built-in-admission-controllers&quot;&gt;Built in Admission Controllers&lt;/h1&gt;&lt;p&gt;It&apos;s worth noting that Kubernetes includes several built-in admission controllers.. You can find a list of these controllers &lt;a target=&quot;_blank&quot; href=&quot;link&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Before delving further, it&apos;s important to differentiate between the two general types of admission controllers:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Validating Admission Controllers: These controllers simply allow or reject requests.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Mutating Admission Controllers: These controllers have the ability to modify objects related to the requests they receive.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Let&apos;s take the example of LimitRanger, an in-built admission controller or plugin. A LimitRange defines policies to govern resource allocations for pods or other applicable resources. More details can be found &lt;a target=&quot;_blank&quot; href=&quot;link&quot;&gt;here&lt;/a&gt;. It&apos;s important to note that LimitRange functions as both a validating and a mutating admission controller.&lt;/p&gt;&lt;p&gt;To try it out, the first step is to add it to the list of admission controllers or plugins using the &quot;--enable-admission-plugins&quot; flag.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;annotations:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;172.18&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:6443&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;creationTimestamp:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;null&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;component:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-apiserver&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;tier:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;control-plane&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-apiserver&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;containers:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;command:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-apiserver&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--advertise-address=172.18.0.3&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--allow-privileged=true&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--authorization-mode=Node,RBAC&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--client-ca-file=/etc/kubernetes/pki/ca.crt&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--enable-admission-plugins=NodeRestriction,LimitRanger&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, let&apos;s define the LimitRange object where we configure:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Minimum and maximum CPUs for all pods within the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Default limits applied when a user doesn&apos;t explicitly configure the resources for a pod.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This configuration ensures that all pods adhere to the specified CPU limits, promoting efficient resource utilization across the cluster. Additionally, it provides a safety net by automatically assigning default limits when users do not specify resource constraints for their pods.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;LimitRange&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cpu-resource-constraint&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;limits:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;default:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# this section defines default limits&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;defaultRequest:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# this section defines default requests&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;max:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# max and min define the limit range&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;600m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;min:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;100m&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Container&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Below is an example of a Pod configuration that requests 700m of CPU resources, which exceeds the defined limit of 500m. When attempting to apply this configuration, you&apos;ll immediately encounter an error, showcasing the validating behavior of the admission controller.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;example-conflict-with-limitrange-cpu&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;containers:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;demo&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;image:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;registry.k8s.io/pause:2.0&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;requests:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;700m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;example-conflict-with-limitrange-cpu&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;is invalid:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;spec.containers[0].resources.requests:&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Invalid value:&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;&quot;700m&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;must&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;less&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;than&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;equal&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cpu&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;limit&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, let&apos;s attempt to create another pod without specifying any resource requests or limits.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can observe that the default requests and limits have been automatically applied to the pod, courtesy of the admission controller. This exemplifies a mutating behavior, wherein the original request has been modified to include the necessary resource requests and limits.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;pods&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;yaml&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;containers:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;image:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;imagePullPolicy:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Always&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;limits:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;requests:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;500m&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-external-admission-controllers&quot;&gt;External Admission Controllers&lt;/h1&gt;&lt;p&gt;In the previous section, we delved into the inherent admission controllers within Kubernetes. However, these built-in controllers often lack the configurability or flexibility needed to accommodate diverse organizational requirements.&lt;/p&gt;&lt;p&gt;Below is a diagram (Source: Kyverno documentation) illustrating the stages of an API request to a Kubernetes API Server, highlighting the crucial steps involving Mutating and Validating admissions.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://kyverno.io/images/kyverno-architecture.png&quot; alt=&quot;Kyverno Architecture&quot; /&gt;&lt;/p&gt;&lt;p&gt;Here&apos;s a concise overview of the mentioned components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Webhook Controller&lt;/strong&gt;: This controller is responsible for managing webhooks, which play a pivotal role in programming the Kubernetes API server to forward API requests to Kyverno. Webhooks are essential building blocks that enable seamless integration between Kubernetes and Kyverno, facilitating the enforcement of policies and configurations.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Policy Engine&lt;/strong&gt;: Kyverno&apos;s policy engine serves as the cornerstone component tasked with evaluating and enforcing policies on Kubernetes resources. It empowers administrators to define policies as Kubernetes resources within Kyverno, enabling them to manage, validate, and mutate other Kubernetes resources effectively. By processing these policies, the policy engine ensures that the cluster complies with desired configurations and standards, fostering consistency and adherence to organizational policies.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cert Renewer&lt;/strong&gt;: This component focuses on managing TLS (Transport Layer Security) communications between the Kubernetes API Server and the Kyverno webhook service. By handling TLS certificates, the Cert Renewer ensures secure transmission of data between these components, safeguarding the integrity and confidentiality of communications.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The ValidatingWebhookConfiguration plays a crucial role in configuring the Kubernetes API server to route requests to Kyverno. Here&apos;s how it works:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Webhooks Section&lt;/strong&gt;: This section defines where to redirect matching API requests. It typically references a Kubernetes Service and specifies a particular path to send the requests for validation.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rules Section&lt;/strong&gt;: The rules section allows you to specify the resources and operations that you want to send to the admission controller for validation. This granularity enables precise control over which requests are subject to validation.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Namespace Selector&lt;/strong&gt;: This field enables you to focus admission control on specific namespaces where stricter governance is required or where you want to apply policies gradually. It provides flexibility in applying policies across different parts of the cluster.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Failure Policy&lt;/strong&gt;: This field determines how the Kubernetes API server responds when it receives a negative admission response from the admission controller. The options are &quot;Fail&quot; and &quot;Ignore&quot;. &quot;Fail&quot; immediately rejects the intended operation upon receiving a negative admission response, ensuring strict enforcement of policies. On the other hand, &quot;Ignore&quot; provides more leniency by allowing the operation to proceed despite policy violations. This can be useful when you want to identify and understand gaps before fully enforcing policies.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admissionregistration.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;ValidatingWebhookConfiguration&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno-validating-webhook&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;webhooks:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;validate.kyverno.svc&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;clientConfig:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;service:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno-svc&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;/validate&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;caBundle:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;ca-bundle&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;# Base64 encoded CA certificate&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;operations:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;CREATE&quot;&lt;/span&gt;, &lt;span class=&quot;hljs-string&quot;&gt;&quot;UPDATE&quot;&lt;/span&gt;]        &lt;span class=&quot;hljs-attr&quot;&gt;apiGroups:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;]        &lt;span class=&quot;hljs-attr&quot;&gt;apiVersions:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;]        &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;]    &lt;span class=&quot;hljs-attr&quot;&gt;failurePolicy:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Fail&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchPolicy:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Equivalent&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;namespaceSelector:&lt;/span&gt; {}    &lt;span class=&quot;hljs-attr&quot;&gt;objectSelector:&lt;/span&gt; {}    &lt;span class=&quot;hljs-attr&quot;&gt;sideEffects:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;None&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;timeoutSeconds:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;10&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;admissionReviewVersions:&lt;/span&gt; [&lt;span class=&quot;hljs-string&quot;&gt;&quot;v1&quot;&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-sample-policies&quot;&gt;Sample Policies&lt;/h1&gt;&lt;p&gt;This example policy ensures that each configured pod must have the &quot;app&quot; label.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-label-app&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Audit&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureActionOverrides:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;action:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Enforce&lt;/span&gt;     &lt;span class=&quot;hljs-comment&quot;&gt;# Action to apply&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;       &lt;span class=&quot;hljs-comment&quot;&gt;# List of affected namespaces&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-label-app&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;            &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;The label `app` is required.&quot;&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;?*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Explanation:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;ClusterPolicy:&lt;/strong&gt; as the name suggests is a policy that applies Cluster wide vs policy which is scoped to the namespace.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;background&lt;/strong&gt;: When set to true, this field ensures that the policy is applied retroactively to existing resources upon creation or update. This means that the policy will be evaluated against resources that were created before the policy was implemented.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;validationFailureAction&lt;/strong&gt;: This field determines the default action to take when a validation rule fails. In this case, it is set to &quot;audit&quot;, meaning that failed validations will be recorded, but resource creation will continue.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;validationFailureActionOverrides&lt;/strong&gt;: This section allows you to override the default validation failure action for specific namespaces. In the example, validation failures in the default namespace will be enforced, overriding the default action set in validationFailureAction.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;rules&lt;/strong&gt;: This section defines the rules of the policy. In this example, there is one rule named &quot;check-app-label&quot; that applies to Pods. The rule specifies that Pods must have an &apos;app&apos; label.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Attempting to create an nginx pod within the blue namespace succeeds with a warning as per the policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image=nginx&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Warning: policy check-label-app.check-label-app: validation error:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;`app`&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;required.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;rule&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-label-app&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;failed&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;at&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/metadata/labels/app/&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;pod/nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;created&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attempting the same operation within the default namespace is denied again as per policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image=nginx&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Error from server:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;webhook&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;validate.kyverno.svc-fail&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;denied the request:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod/default/nginx&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blocked&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;due&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;following&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;check-label-app:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;check-label-app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&apos;validation error: The label `app` is required. rule check-label-app    failed at path /metadata/labels/app/&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here&apos;s the example policy enforcing a minimum level of high availability for deployments:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;validate-replica-count&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;            &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Replica count for a Deployment must be greater than or equal to 2.&quot;&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;replicas:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&amp;gt;=2&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-cilium-policies&quot;&gt;Cilium Policies&lt;/h1&gt;&lt;p&gt;After reviewing several examples, I&apos;ve considered implementing Kyverno for admission control of Cilium Network Policies. For that matter I found an interesting repository &lt;a target=&quot;_blank&quot; href=&quot;https://github.com/adobeSlash/cilium-kyverno&quot;&gt;here&lt;/a&gt; that helped me get started.&lt;/p&gt;&lt;p&gt;After making little modifications to various examples on GitHub, I crafted a policy aimed at whitelisting specific namespaces where Cilium policies can be configured. Any attempts to create Cilium policies in namespaces not included in the whitelist will be denied. I think this is pretty useful to ensure no mishaps can happen as part of Network Policy configuration and helps with locking things down one namespace at a time.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;limit-ciliumnetworkpolicy-scope&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;limit-scope&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;          &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;CiliumNetworkPolicy can only be applied to specific namespaces&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;anyPattern:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I attempt to use the below Network Policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;isolate-ns1&quot;&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;green&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      {}  &lt;span class=&quot;hljs-attr&quot;&gt;ingress:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;fromEndpoints:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;        {}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As expected, the request is blocked by the admission controller.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mypolicy.yaml&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Error from server:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;creating&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;&quot;mypolicy.yaml&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;webhook&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;validate.kyverno.svc-fail&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;denied the request:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy/green/isolate-ns1&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blocked&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;due&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;following&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;limit-ciliumnetworkpolicy-scope:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;limit-scope:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&apos;validation error: CiliumNetworkPolicy can only be applied to specific    namespaces. rule limit-scope[0] failed at path /metadata/namespace/ rule limit-scope[1]    failed at path /metadata/namespace/&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The example below provides more insight on Kyverno&apos;s capabilities whereby we leverage a ClusterPolicy whose objective is to ensure that pods to be created need to have the label &quot;app.kubernetes.io/name&quot;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;require-labels&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;annotations:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/title:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Require&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Labels&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/category:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Best&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Practices&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/minversion:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1.6&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/severity:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;medium&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/subject:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Label&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;policies.kyverno.io/description:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;gt;-      Define and use labels that identify semantic attributes of your application or Deployment.      A common set of labels allows tools to work collaboratively, describing objects in a common manner that      all tools can understand. The recommended labels describe applications in a way that can be      queried. This policy validates that the label `app.kubernetes.io/name` is specified with some value.&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;check-for-labels&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;any:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;          &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;The label `app.kubernetes.io/name` is required.&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;?*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, I try to create a deployment (not a Pod) &amp;amp; interestingly enough the admission controller reacts in the right manner not allowing the deployment to happen.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;create&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;deployment&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kubernetes-bootcamp&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--image=gcr.io/google-samples/kubernetes-bootcamp:v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;error: failed to create deployment:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;admission&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;webhook&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;validate.kyverno.svc-fail&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;denied the request:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Deployment/default/kubernetes-bootcamp&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;was&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blocked&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;due&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;following&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policies&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;require-labels:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;autogen-check-for-labels:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&apos;validation error: The label `app.kubernetes.io/name`    is required. rule autogen-check-for-labels failed at path /spec/template/metadata/labels/app.kubernetes.io/name/&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-conclusion&quot;&gt;Conclusion&lt;/h1&gt;&lt;p&gt;Kyverno and more generally admission controllers can help ensure better security, compliance and governance of Kubernetes Clusters. On top of this, there is a good number of &lt;a target=&quot;_blank&quot; href=&quot;https://kyverno.io/policies/?policytypes=Best%2520Practices%2BEKS%2520Best%2520Practices%2Bvalidate&quot;&gt;readily available policies&lt;/a&gt; making it easier to consume. I even tried asking ChatGPT to generate a Kyverno policy:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;please craft a kyverno policy that would allow cilium network policies to only touch pods that have environment: dev as not to disrupt production&lt;/p&gt;&lt;/blockquote&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kyverno.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ClusterPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;restrict-cilium-policy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;background:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;validationFailureAction:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;enforce&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;restrict-cilium-network-policy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;match:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;kinds:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;validate:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Cilium Network Policies can only target pods with the label &apos;environment: dev&apos;.&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;pattern:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;environment:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dev&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It might be worthwhile if you are getting started to deploy it to have the validationFailureAction as Audit as this would provide context on how objects being created deviate from the norm and have the background set to true as this will ensure that your existing resources are scanned in terms of adherence to organizational policies.ValidateActionOverride will be useful to enforce policies on namespaces one by one to ensure a smooth adoption.&lt;/p&gt;&lt;p&gt;Finally, a good one to mention is Policy Reports that provide insights into the compliance status of resources in the Kubernetes cluster. Though I have noticed that some resources don&apos;t show up in the reports, it is still very useful when background is set to true as this will give an indication of the compliance state of all resources within Kubernetes.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policyreports.wgpolicyk8s.io&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-A&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;NAMESPACE&lt;/span&gt;            &lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                                   &lt;span class=&quot;hljs-string&quot;&gt;KIND&lt;/span&gt;         &lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                                             &lt;span class=&quot;hljs-string&quot;&gt;PASS&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;FAIL&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;WARN&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ERROR&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;SKIP&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;AGE&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;6228a955-195b-4795-83ee-5c1a662bf532&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;prometheus&lt;/span&gt;                                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-number&quot;&gt;81242176&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;-f6ac-4331-8be3-bdedccc32f67&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;grafana-6f4755f98c-4cxzx&lt;/span&gt;                         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;bbe6c1f9-a91f-4628-b524-bf04c2603c0a&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;grafana-6f4755f98c&lt;/span&gt;                               &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;c70e65cc-800a-4986-90ab-c52078189f29&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;prometheus-67fdcf4796&lt;/span&gt;                            &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;d7006776-21e2-4b86-a684-d6cf173f2f2e&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;prometheus-67fdcf4796-gj4kb&lt;/span&gt;                      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;cilium-monitoring&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;dd37f6a5-0bd7-43f8-a7d5-337f089df95f&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;grafana&lt;/span&gt;                                          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;0064fbf9-80ce-4517-934e-5b34d98e88c5&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;DaemonSet&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;cilium&lt;/span&gt;                                           &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;0be0cbb5-25b0-448e-922c-074e510d269c&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-zx692&lt;/span&gt;                                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;0d9c47b0-2b55-4752-ae1f-1d22ab63e9c9&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator-5d64788c99-g2f48&lt;/span&gt;                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;14ae51f5-ba2f-4942-aa35-d93e94d2d76f&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-scheduler-kind-control-plane&lt;/span&gt;                &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;23a370a8-ef0e-4d1c-aa19-ffab703b5f0d&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;DaemonSet&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy&lt;/span&gt;                                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;35e9706f-7a88-4932-a78c-37745a397abe&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;coredns-76f75df574-xvxns&lt;/span&gt;                         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-number&quot;&gt;501429e0&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;-4f00-4f30-9cc8-9eb633d9a0e5&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;coredns-76f75df574&lt;/span&gt;                               &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;6911c7d8-4128-470d-89ef-6fc969e62b05&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-controller-manager-kind-control-plane&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;69a7f09e-a753-4dd9-8fe2-e5eb70e3691d&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-jvllh&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;8c6c30a5-1ef6-4bd1-9978-381b0aeca611&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator&lt;/span&gt;                                  &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;9cd0150a-34fd-49df-837b-d2f19ea575dd&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator-5d64788c99&lt;/span&gt;                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;9ecef8f0-c9b1-4989-9fa6-15b07f8de581&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;coredns&lt;/span&gt;                                          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;a8482fb9-10bc-4819-8230-17a776d1079f&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-kfrnt&lt;/span&gt;                                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;be23c6c2-8ad5-4a86-adc1-de4180dc8d81&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-g4gnt&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cc4021e0-2360-403b-b013-fad70807f04b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;coredns-76f75df574-7zdjj&lt;/span&gt;                         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;dba5f38a-e8e5-46d0-9e4a-ec269ae9ddb4&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-bztgh&lt;/span&gt;                                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;e0146bde-f48c-4663-997f-019e24402bcd&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;cilium-operator-5d64788c99-hdlsz&lt;/span&gt;                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;eadc9e7d-90dd-42c1-9dbe-62b3822d668a&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-fn567&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;f3d97e60-2a0f-4985-9644-a98e98541103&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;etcd-kind-control-plane&lt;/span&gt;                          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;ff45c31d-ca5d-43c5-90da-bb0f113b03b3&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kube-proxy-6jfqw&lt;/span&gt;                                 &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;0840b270-f6a2-499c-b1d7-a37a716ef440&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-background-controller-84b5ff7875-fkd2x&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;13f74dc4-4e27-4a78-b34c-cc9ae3e7b57c&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;CronJob&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-admission-reports&lt;/span&gt;                &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;27bf13f4-2bc8-4dae-8e0c-2a29d57438c0&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-reports-controller&lt;/span&gt;                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;29bcbffc-d253-4d8e-97d6-98043bf9600b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;CronJob&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-cluster-admission-reports&lt;/span&gt;        &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;532c51d8-843e-42ae-82d2-d5a8f6f9b62e&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-controller-574fc8c6b6-kpbbg&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;6fea3745-3b96-46c9-9c62-59cc22f75722&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-admission-controller&lt;/span&gt;                     &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;80e5c9d7-9677-4a71-a4c3-89370afd665e&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-controller-574fc8c6b6&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;94048b9d-8a52-4f70-bbc4-cb814b8ee671&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-reports-controller-5557c85bb4-8jpm6&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;a0948eaa-9332-488c-a7a9-cb9c3ee4b045&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-admission-controller-6797d4bd6b&lt;/span&gt;          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;ab1c5601-072a-4782-b08a-d9c2e9ae3d92&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-cleanup-controller&lt;/span&gt;                       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;ead76fa0-bfec-4385-9a00-4b26293c069b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;kyverno-admission-controller-6797d4bd6b-l2kwf&lt;/span&gt;    &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;kyverno&lt;/span&gt;              &lt;span class=&quot;hljs-string&quot;&gt;f47b4093-46fd-4eb7-abe3-0e431a98d23a&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;kyverno-background-controller-84b5ff7875&lt;/span&gt;         &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;local-path-storage&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;13e4514a-18e1-484d-aa39-c591f34c4d56&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Pod&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;local-path-provisioner-7577fdbbfb-6hb2v&lt;/span&gt;          &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;local-path-storage&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;45119b4b-a214-4d6c-b06a-7c8a2c4af402&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ReplicaSet&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;local-path-provisioner-7577fdbbfb&lt;/span&gt;                &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;local-path-storage&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;adc91343-2e69-4059-aebb-1e4a50f80a2b&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;local-path-provisioner&lt;/span&gt;                           &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;8d&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1717123004467/11cdc0df-b0fb-46db-8297-0a1b0723c868.png</hashnode:coverImage></item><item><title><![CDATA[Cilium: Network Policies]]></title><description><![CDATA[A deep dive into Cilium Network Policies explaining the why, how, and a few use-cases (DNS) for East-West as well as North-South requirements.]]></description><link>https://jamali.hashnode.dev/cilium-network-policies</link><guid isPermaLink="true">https://jamali.hashnode.dev/cilium-network-policies</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[kubernetes architecture]]></category><category><![CDATA[networking]]></category><category><![CDATA[cilium]]></category><category><![CDATA[Security]]></category><category><![CDATA[networksecurity]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[GCP]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Wed, 01 May 2024 12:50:43 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h1 id=&quot;heading-introduction-to-network-policies&quot;&gt;Introduction to Network Policies&lt;/h1&gt;&lt;p&gt;In this blog episode, we&apos;re diving into the world of Kubernetes Network Policies. But before we get there, let&apos;s talk about the main headache these policies aim to fix. So, without Network Policies, Kubernetes lets Pods communicate freely with each other, no matter if they are on the same or different node or within the same namespace or in different namespaces. But here&apos;s the catch: while it might seem convenient for Pods to enable free communication among pods, it&apos;s like leaving your front door wide open in a not-so-great neighbourhood. Sure, it&apos;s all fun and games until someone you don&apos;t want barges in. And in Kubernetes land, that means inviting all sorts of security risks.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714355926931/eeede03b-2e04-431f-9b1b-f65c4b682b9a.png&quot; alt=&quot;Figure1. Kubernetes without Network Policies&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure1. Behavior without Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Thus, in a nutshell Kubernetes Network policies can help in isolating namespaces from one another in the sense that workloads belonging to &quot;env1&quot; to communicate with workloads in &quot;env2&quot;. Another very common use of Network Policies is enforcing Zero Trust policies around workloads ensuring least privilege access &amp;amp; that a compromise in one of your workloads can&apos;t spread laterally to affect other workloads. Note that policies can govern East-West Traffic within Kubernetes but can also extend to govern the communication patterns with other non-Kubernetes workloads (IP Addresses). &lt;/p&gt;&lt;p&gt;It&apos;s essential to understand that while these policies result in isolation at the Dataplane level (e.g., Firewall), they do not imply any form of Virtual Routing and Forwarding (VRF) or Segmentation from a networking perspective.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714355826223/858ae51b-7524-4b44-a815-4b7b065d5d6b.png&quot; alt=&quot;Figure2. Network Policy Capabilities&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure2. The Need for Kubernetes Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h1 id=&quot;heading-more-on-network-policies-concepts&quot;&gt;More on Network Policies Concepts&lt;/h1&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714424357661/fca59277-33c9-43bc-b764-311649931287.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure3. Deeper Dive on Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;CiliumNetwork Policy structure can be found below and it&apos;s basic sections are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Selector needs to define which endpoint(s) the policy is subject to.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Direction of the Policy: Ingress/Egress&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Labels are heavily used in Kubernetes &amp;amp; Network Policies as they allow:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Decoupling from IP addresses especially recalling that Pods are ephemeral&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Being able to apply policies on a number of Pods at the same time. Below example for instance shows that all 3 pods share the same label (app=reviews).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Any new upcoming Pods that are being instantiated can automatically be captured by the Network Policy.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Examples in the above diagram are role:frontend, &amp;amp; role:db.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;In Cilium L3 Policies, most use-cases are neatly outlined in Figure 3. I&apos;d like to highlight L3 DNS-based policies, which simplify allowing egress access to specific domains from particular Pods or groups of Pods.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Let&apos;s break it down: Instead of manually resolving the IP addresses for, say, nginx.com, and then configuring access accordingly, L3 DNS-based policies take a smarter approach. When a Pod sends a DNS request for a domain like nginx.com, Cilium steps in. It relays the request to a DNS proxy, giving us visibility over the DNS request and response.&lt;/p&gt;&lt;p&gt;Here&apos;s where the magic happens: the response to the DNS request becomes an IP address that we control communication to. This means we can seamlessly manage and restrict access to desired domains without the hassle of manual IP management. It&apos;s like having your own traffic cop directing Pod communications in real-time, all thanks to Cilium&apos;s intelligent handling of DNS&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;On Cilium L7 Policies ,the DNS policy here is a bit different where it basically leverages a DNS Proxy to accept/reject DNS requests.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;HTTP Policy within L7 policies, allows for example more granular control on incoming traffic by allowing it from a group of pods only when it targets a particular URI path.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;pods&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;app=reviews&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                          &lt;span class=&quot;hljs-string&quot;&gt;READY&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;STATUS&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;RESTARTS&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;AGE&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;reviews-v1-5b5d6494f4-dwvpn&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;/1&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;Running&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;4d14h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;reviews-v2-5b667bcbf8-kjwhn&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;/1&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;Running&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;4d14h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;reviews-v3-5b9bd44f4-qjfth&lt;/span&gt;    &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;/1&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;Running&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;4d14h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure4. Kubernetes Pods Label Example&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-deny-all&quot;&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;                &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;            &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; {}&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;&lt;center&gt;Figure5. Sample Cilium Network Policy&lt;/center&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;heading-cilium-policy-enforcement-mode-default&quot;&gt;Cilium Policy Enforcement Mode: Default&lt;/h2&gt;&lt;p&gt;Cilium offers different modes for Policy Enforcement: Default, Always, and Never. Let&apos;s focus on describing the behavior under the Default mode:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;No Network Policies Attached: For endpoints without any Network Policies attached, Egress and Ingress traffic are allowed without restriction.&lt;/li&gt;&lt;li&gt;Network Policy Applied to Endpoint in Egress Direction:When a Network Policy is applied to an endpoint in the egress direction, only the specific egress traffic explicitly mentioned in the policy will be allowed. All other egress traffic will be denied.&lt;/li&gt;&lt;li&gt;An empty egress policy implies that no egress traffic is allowed, resulting in the denial of all egress traffic.&lt;/li&gt;&lt;li&gt;Ingress traffic remains unaffected by egress policies.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;heading-stateful-network-policies&quot;&gt;Stateful Network Policies&lt;/h2&gt;&lt;p&gt;It&apos;s crucial to grasp the concept that Network Policies operate as stateful constructs. For instance, when considering permitting communication from a client Pod to an nginx Pod, we only need two policies:&lt;/p&gt;&lt;p&gt;Egress policy on the Client Pod to facilitate communication with the nginx Pod.Ingress policy on the nginx Pod to allow communication from the client Pod.Remarkably, explicit network policies for return traffic are unnecessary. This is because the return path of a flow, such as the response from the nginx Pod to the client Pod, is inherently part of the same outgoing flow permitted by the client to the nginx Pod. Therefore, no incoming policy is required on the client side for this return traffic, as it is already encompassed within the outgoing flow allowance.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714355728618/d719b046-0bad-4a57-90ed-c3a341012945.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure6. Stateful Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h1 id=&quot;heading-scenario&quot;&gt;Scenario&lt;/h1&gt;&lt;p&gt;To keep things straightforward, Ive opted for the BookInfo applicationa commonly featured example in Istios getting started guide. This application comprises four microservices: Product Page, Reviews, Details, and Ratings. While Reviews has multiple versions, well keep our focus on v1.&lt;/p&gt;&lt;p&gt;For a visual overview, check out the diagram below, sourced from Istios documentation. It vividly illustrates the key components and their interactions.More details can be found &lt;a target=&quot;_blank&quot; href=&quot;https://istio.io/latest/docs/examples/bookinfo/#define-the-service-versions&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714275168992/20b5dd19-1a8f-44e2-9cda-6ed452e4e5c4.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure 7. BookInfo Application &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;It is worth noting that all of this setup is running locally on my laptop as a kind cluster. More details can be found &lt;a target=&quot;_blank&quot; href=&quot;https://kind.sigs.k8s.io/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714275195511/b6f4f893-5bd1-4db2-bdd9-8323b63a3920.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure 8. Lab Setup &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h2 id=&quot;heading-application-discovery&quot;&gt;Application Discovery&lt;/h2&gt;&lt;p&gt;Hubble is a fully distributed networking and security observability platform. It is built on top of Cilium and eBPF to enable deep visibility into the communication and behavior of services as well as the networking infrastructure in a completely transparent manner. (Source: Cilium Documentation)&lt;/p&gt;&lt;p&gt;We will look at identities in the upcoming section but for now you can see:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Figure9. shows the traffic from the internal-client pod to productpage pod&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Figure10. shows all the backends that the productpage actually communicates with reviews throughout its versions (v1,v2,v3).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Effective crafting of Network Policies hinges on attaining comprehensive visibility into the communication patterns among Pods and entities. This visibility enables a thorough understanding of how these components interact within the Kubernetes cluster, facilitating the creation of policies that accurately reflect and enforce security requirements.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--to-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;23217&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.867:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:47838&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.221:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.221:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.221:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.344:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure 9. Traffic from Client to Productpage&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;                      &lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.813:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35336&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.814:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35336&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.822:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:43297&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.859:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:43712&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.863:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.863:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.866:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.867:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.230:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50168&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.260:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:42803&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.276:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:33718&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.336:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:33718&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.336:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:33718&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.342:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.343:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure10. Traffic from Productpage to Reviews, Ratings &amp;amp; Details Pods&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-security-identity&quot;&gt;Security Identity&lt;/h1&gt;&lt;p&gt;As discussed, Kubernetes &amp;amp; Network Policies are heavily dependent on labels. Basically, for every unique combination of labels that would target a set of Pods, Cilium would create unique security identities.&lt;/p&gt;&lt;p&gt;Thus, when traffic for instance needs to go from frontend to backend.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;On the host having the web pod, Cilium figures out the security identity that maps to the source which is 81 in our example.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Cilium would ensure that the security identity information (81) is encoded into the packet it sends to the backend.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Thus, you can think about Network Policies as controlling access based on source and destination security identities.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Upon receiving the packet, we know that the source identity is 81 and the backend identity is 77 and need to check if there are policies that allow Identity 81&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714441830703/ff7c36e5-ddff-4cf5-9f09-5f97eb12d789.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure11. Cilium Security Identities &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;This output shows all the existing pods and their existing security identities.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                             &lt;span class=&quot;hljs-string&quot;&gt;SECURITY&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;IDENTITY&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ENDPOINT&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;STATE&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;IPV4&lt;/span&gt;           &lt;span class=&quot;hljs-string&quot;&gt;IPV6&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;details-v1-698d88b-89gnc&lt;/span&gt;         &lt;span class=&quot;hljs-number&quot;&gt;285&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.140&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;internal-client&lt;/span&gt;                  &lt;span class=&quot;hljs-number&quot;&gt;23217&lt;/span&gt;               &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.172&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;productpage-v1-675fc69cf-8zzxh&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;9889                &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.148&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ratings-v1-6484c4d9bb-8nsbj&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;5778                &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.241&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;reviews-v1-5b5d6494f4-dwvpn&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;55669&lt;/span&gt;               &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.170&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;reviews-v2-5b667bcbf8-kjwhn&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;10139&lt;/span&gt;               &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.87&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;reviews-v3-5b9bd44f4-qjfth&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;1786                &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.191&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure12. Endpoints &amp;amp; their corresponding identities&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-egress-policy-deny-all&quot;&gt;Egress Policy: Deny-All&lt;/h1&gt;&lt;p&gt;This is an example of an empty egress network policy that is attached to the productpage pod. This would block all outgoing traffic from productpage to any other pod or entity.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-deny-all&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; {}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure13. Empty Egress Network Policy&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Refer back to figure 12 where the pods and their respective identities are listed. Please note that Hubble can also use pod names directly with from-pod and to-pod.&lt;/p&gt;&lt;p&gt;Figure 14 shows that traffic continues to flow from the client to the productpage which is expected as the policy on the productpage is an egress only policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--to-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;23217&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.254:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:51160&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.255:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:51160&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.280:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:46532&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.281:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:46532&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.281:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:46532&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure14. Using Hubble to observe traffic between internal-client &amp;amp; productpage&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Figure 15, shows that traffic from productpage to coredns is blocked. The reason this happens is when productpage wants to communicate with any of its backend services (reviews, details..etc) it sends a DNS request to resolve the IP address of the service name (reviews for example). For more details refer to the Kubernetes Services blog post &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-services&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--since&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;2m&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:33.290:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:33.290:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure15. Traffic from productpage to coredns is blocked&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Output from internal-client is actually inline with our findings whereby we get a response from productpage however it clearly mentions that reviews are inaccessible as a result of the egress policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;class=&quot;col-md-6&quot;&amp;gt;&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;h4&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;class=&quot;text-center&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;text-primary&quot;&amp;gt;Error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;fetching&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews!&amp;lt;/h4&amp;gt;&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;p&amp;gt;Sorry,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;are&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;currently&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;unavailable&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;book.&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure16. Output from Internal Client&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-allow-traffic-to-dns&quot;&gt;Allow Traffic to DNS&lt;/h1&gt;&lt;p&gt;We have concluded our earlier section, whereby traffic to the coredns pod was being blocked. This policy allows product page to get to coredns on port 53.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;allow-to-dns&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:k8s-app&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-dns&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;toPorts:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;           &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;53&quot;&lt;/span&gt;             &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ANY&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure17. Allow Traffic from productpage to coredns&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:36:17.388:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:49263&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:36:17.407:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:60156&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:36:17.407:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:40690&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure18. Traffic Forwarded from productpage to coredns&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The DNS rules being added here can be used as an L7 policy to allow DNS requests to particular domains (like an Allowlist) via a DNS proxy as shown in Figure 3. The other value that comes with DNS rules is that now we have added a DNS proxy into the picture, we can have more visibility on DNS traffic.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;allow-to-dns&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:k8s-app&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-dns&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;toPorts:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;           &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;53&quot;&lt;/span&gt;             &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ANY&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;dns:&lt;/span&gt;              &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchPattern:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure19. Add DNS Rules to the NetworkPolicy&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;--protocol&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.340:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.340:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.342:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.96.222.2&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.342:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer  TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.345:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.345:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.346:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.96.179.42&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.347:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer  TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure20. DNS Traffic Visibility&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-allow-traffic-to-backend-pods&quot;&gt;Allow Traffic to Backend Pods&lt;/h1&gt;&lt;p&gt;Recall that at this stage, the DNS resolution works however we still need to add the relevant rules from productpage to reviews &amp;amp; details. Bear in mind that for other pods that are not selected as part of the policy all ingress/egress traffic continues to flow (e.g. Traffic between reviews &amp;amp; ratings)&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;from-product-to-reviews-details&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure21. Allow from productpage to reviews &amp;amp; details&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.715:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37378&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.724:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37378&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.725:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37378&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.740:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:58725&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.810:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37394&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.810:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37394&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.867:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:34917&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.879:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:51600&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.911:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37402&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.911:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37402&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure22. Hubble Visbility for traffic from product page &amp;amp; reviews versions&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-internet-egress-policy&quot;&gt;Internet Egress Policy&lt;/h2&gt;&lt;p&gt;This is an Internet Egress use-case where the objective is to limit the domains that the internal-client pod can connect to on the Internet.&lt;/p&gt;&lt;p&gt;Notice you can still see the same DNS policy, however we are adding the toFQNDs construct in this policy. This works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Traffic from internal-client to coredns is allowed.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;When the internal-client wants to connect to the public URL &quot;ifconfig.me&quot;, it first needs to resolve its IP Address.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Since, we already have visibility to DNS traffic with DNS Proxy, we can see the DNS response containing the IP Address of &quot;ifconfig.me&quot;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;toFQDN is basically a representation of that IP Address i.e. as if we are putting a policy to the IP address that is a result of DNS resolution.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The reason this approach is interesting is that we don&apos;t need to deal with changing addresses &amp;amp; we can just rely on DNS names.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;from-internal-client-to-fqdn&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;internal-client&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:k8s-app&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-dns&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;toPorts:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;           &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;53&quot;&lt;/span&gt;             &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ANY&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;dns:&lt;/span&gt;              &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchPattern:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toFQDNs:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;ifconfig.me&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure23. Allow Traffic to Public FQDN ifconfig.me&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--pod&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;internal-client&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--protocol&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.378:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.378:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.423:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2600:1901:0:bbc3::&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.424:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;34.117.118.44&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.604:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.604:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.607:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.607:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.610:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.610:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.611:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.611:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.611:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.652:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;151.101.3.5,151.101.131.5,151.101.67.5,151.101.195.5&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.656:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2a04:4e42:c00::773,2a04:4e42:a00::773,2a04:4e42::773,2a04:4e42:800::773,2a04:4e42:600::773,2a04:4e42:e00::773,2a04:4e42:200::773,2a04:4e42:400::773&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure24. Visibility to DNS Request &amp;amp; Responses for Public Domains&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Here you can see traffic to &quot;ifconfig.me&quot; forwarded whereas traffic for other domains being denied.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.656:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.656:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:17.699:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:17.699:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:05:20.563:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;151.101&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:05:20.563:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;151.101&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.832:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:L3-Only&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ALLOWED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.833:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.854:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.854:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.894:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.894:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure25. Allow Traffic to Public FQDN ifconfig.me&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-troubleshooting&quot;&gt;Troubleshooting&lt;/h1&gt;&lt;p&gt;In this section, I wanted to go a bit deeper on a flow productpage to reviews-v1 pod. I have added the figure again for convenience. You can clearly see that productpage and reviews-v1 are on different nodes.&lt;/p&gt;&lt;p&gt;In addition, in this setup VXLAN tunnels to encapsulate traffic between the nodes as per the output of Figure 27.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714275195511/b6f4f893-5bd1-4db2-bdd9-8323b63a3920.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure26. Revisit Pod Placement&lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cilium&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;tunnel&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;routing-mode&lt;/span&gt;                                      &lt;span class=&quot;hljs-string&quot;&gt;tunnel&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;tunnel-protocol&lt;/span&gt;                                   &lt;span class=&quot;hljs-string&quot;&gt;vxlan&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure27. Tunnel Mode with VXLAN&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;It is mind boggling to see all this information within Hubble on a particular flow.&lt;/p&gt;&lt;p&gt;Figure 28 shows all the information about source &amp;amp; destination in terms of labels &amp;amp; identities and we can clearly see the traffic being forwarded on the overlay (VXLAN Tunnel). Note that the verdict clearly shows that the traffic is forwarded.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;{  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flow&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373296596Z&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;uuid&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;3ce41f60-b203-4e43-ab34-c89f631f7cd2&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;verdict&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;FORWARDED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ethernet&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;9e:f7:72:78:39:c7&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;d6:55:a3:91:69:37&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;IP&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.2.148&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.1.170&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ipVersion&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;IPv4&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;l4&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;TCP&quot;:&lt;/span&gt; {        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;47812&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9080&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flags&quot;:&lt;/span&gt; {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ACK&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;        }      }    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ID&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1881&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-v1-675fc69cf-8zzxh&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;workloads&quot;:&lt;/span&gt; [        {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-v1&quot;&lt;/span&gt;,          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;kind&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Deployment&quot;&lt;/span&gt;        }      ]    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;55669&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;reviews-v1-5b5d6494f4-dwvpn&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;L3_L4&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker3&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;event_type&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;sub_type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;traffic_direction&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;EGRESS&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;trace_observation_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TO_OVERLAY&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;is_reply&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;,    &lt;span class=&quot;hljs-string&quot;&gt;&quot; interface&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;index&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;6&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium_vxlan&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Summary&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TCP Flags: ACK&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker3&quot;&lt;/span&gt;,  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373296596Z&quot;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure28. Egress Traffic from Product Forwarded over VXLAN Tunnel&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Figure29 shows the incoming traffic from kind-worker1&apos;s perspective, where the traffic gets forwarded to the interface connecting reviews-v1 pod. Note that the verdict clearly shows that the traffic is forwarded.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;{  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flow&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373343054Z&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;uuid&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;bf9df4cf-44b2-479a-bd41-9d232d5aacf6&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;verdict&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;FORWARDED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ethernet&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;72:e6:23:94:38:bb&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;02:9e:93:c9:74:57&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;IP&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.2.148&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.1.170&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ipVersion&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;IPv4&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;l4&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;TCP&quot;:&lt;/span&gt; {        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;47812&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9080&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flags&quot;:&lt;/span&gt; {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ACK&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;        }      }    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-v1-675fc69cf-8zzxh&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ID&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2039&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;55669&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;reviews-v1-5b5d6494f4-dwvpn&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;workloads&quot;:&lt;/span&gt; [        {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;reviews-v1&quot;&lt;/span&gt;,          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;kind&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Deployment&quot;&lt;/span&gt;        }      ]    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;L3_L4&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;event_type&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;traffic_direction&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;INGRESS&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;trace_observation_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TO_ENDPOINT&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;is_reply&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;interface&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;index&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;15&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;lxc240530c746ff&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Summary&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TCP Flags: ACK&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker&quot;&lt;/span&gt;,  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373343054Z&quot;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure29. Egress Traffic from Reviews-v1 with Policy Enforcement&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h1 id=&quot;heading-introduction-to-network-policies&quot;&gt;Introduction to Network Policies&lt;/h1&gt;&lt;p&gt;In this blog episode, we&apos;re diving into the world of Kubernetes Network Policies. But before we get there, let&apos;s talk about the main headache these policies aim to fix. So, without Network Policies, Kubernetes lets Pods communicate freely with each other, no matter if they are on the same or different node or within the same namespace or in different namespaces. But here&apos;s the catch: while it might seem convenient for Pods to enable free communication among pods, it&apos;s like leaving your front door wide open in a not-so-great neighbourhood. Sure, it&apos;s all fun and games until someone you don&apos;t want barges in. And in Kubernetes land, that means inviting all sorts of security risks.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714355926931/eeede03b-2e04-431f-9b1b-f65c4b682b9a.png&quot; alt=&quot;Figure1. Kubernetes without Network Policies&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure1. Behavior without Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Thus, in a nutshell Kubernetes Network policies can help in isolating namespaces from one another in the sense that workloads belonging to &quot;env1&quot; to communicate with workloads in &quot;env2&quot;. Another very common use of Network Policies is enforcing Zero Trust policies around workloads ensuring least privilege access &amp;amp; that a compromise in one of your workloads can&apos;t spread laterally to affect other workloads. Note that policies can govern East-West Traffic within Kubernetes but can also extend to govern the communication patterns with other non-Kubernetes workloads (IP Addresses). &lt;/p&gt;&lt;p&gt;It&apos;s essential to understand that while these policies result in isolation at the Dataplane level (e.g., Firewall), they do not imply any form of Virtual Routing and Forwarding (VRF) or Segmentation from a networking perspective.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714355826223/858ae51b-7524-4b44-a815-4b7b065d5d6b.png&quot; alt=&quot;Figure2. Network Policy Capabilities&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure2. The Need for Kubernetes Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h1 id=&quot;heading-more-on-network-policies-concepts&quot;&gt;More on Network Policies Concepts&lt;/h1&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714424357661/fca59277-33c9-43bc-b764-311649931287.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure3. Deeper Dive on Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;CiliumNetwork Policy structure can be found below and it&apos;s basic sections are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Selector needs to define which endpoint(s) the policy is subject to.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Direction of the Policy: Ingress/Egress&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Labels are heavily used in Kubernetes &amp;amp; Network Policies as they allow:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Decoupling from IP addresses especially recalling that Pods are ephemeral&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Being able to apply policies on a number of Pods at the same time. Below example for instance shows that all 3 pods share the same label (app=reviews).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Any new upcoming Pods that are being instantiated can automatically be captured by the Network Policy.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Examples in the above diagram are role:frontend, &amp;amp; role:db.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;In Cilium L3 Policies, most use-cases are neatly outlined in Figure 3. I&apos;d like to highlight L3 DNS-based policies, which simplify allowing egress access to specific domains from particular Pods or groups of Pods.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Let&apos;s break it down: Instead of manually resolving the IP addresses for, say, nginx.com, and then configuring access accordingly, L3 DNS-based policies take a smarter approach. When a Pod sends a DNS request for a domain like nginx.com, Cilium steps in. It relays the request to a DNS proxy, giving us visibility over the DNS request and response.&lt;/p&gt;&lt;p&gt;Here&apos;s where the magic happens: the response to the DNS request becomes an IP address that we control communication to. This means we can seamlessly manage and restrict access to desired domains without the hassle of manual IP management. It&apos;s like having your own traffic cop directing Pod communications in real-time, all thanks to Cilium&apos;s intelligent handling of DNS&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;On Cilium L7 Policies ,the DNS policy here is a bit different where it basically leverages a DNS Proxy to accept/reject DNS requests.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;HTTP Policy within L7 policies, allows for example more granular control on incoming traffic by allowing it from a group of pods only when it targets a particular URI path.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kubectl&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;pods&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;app=reviews&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                          &lt;span class=&quot;hljs-string&quot;&gt;READY&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;STATUS&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;RESTARTS&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;AGE&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;reviews-v1-5b5d6494f4-dwvpn&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;/1&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;Running&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;4d14h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;reviews-v2-5b667bcbf8-kjwhn&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;/1&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;Running&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;4d14h&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;reviews-v3-5b9bd44f4-qjfth&lt;/span&gt;    &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;/1&lt;/span&gt;     &lt;span class=&quot;hljs-string&quot;&gt;Running&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;0&lt;/span&gt;          &lt;span class=&quot;hljs-string&quot;&gt;4d14h&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure4. Kubernetes Pods Label Example&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-deny-all&quot;&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;                &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;            &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; {}&lt;/code&gt;&lt;/pre&gt;&lt;b&gt;&lt;center&gt;Figure5. Sample Cilium Network Policy&lt;/center&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;heading-cilium-policy-enforcement-mode-default&quot;&gt;Cilium Policy Enforcement Mode: Default&lt;/h2&gt;&lt;p&gt;Cilium offers different modes for Policy Enforcement: Default, Always, and Never. Let&apos;s focus on describing the behavior under the Default mode:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;No Network Policies Attached: For endpoints without any Network Policies attached, Egress and Ingress traffic are allowed without restriction.&lt;/li&gt;&lt;li&gt;Network Policy Applied to Endpoint in Egress Direction:When a Network Policy is applied to an endpoint in the egress direction, only the specific egress traffic explicitly mentioned in the policy will be allowed. All other egress traffic will be denied.&lt;/li&gt;&lt;li&gt;An empty egress policy implies that no egress traffic is allowed, resulting in the denial of all egress traffic.&lt;/li&gt;&lt;li&gt;Ingress traffic remains unaffected by egress policies.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;heading-stateful-network-policies&quot;&gt;Stateful Network Policies&lt;/h2&gt;&lt;p&gt;It&apos;s crucial to grasp the concept that Network Policies operate as stateful constructs. For instance, when considering permitting communication from a client Pod to an nginx Pod, we only need two policies:&lt;/p&gt;&lt;p&gt;Egress policy on the Client Pod to facilitate communication with the nginx Pod.Ingress policy on the nginx Pod to allow communication from the client Pod.Remarkably, explicit network policies for return traffic are unnecessary. This is because the return path of a flow, such as the response from the nginx Pod to the client Pod, is inherently part of the same outgoing flow permitted by the client to the nginx Pod. Therefore, no incoming policy is required on the client side for this return traffic, as it is already encompassed within the outgoing flow allowance.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714355728618/d719b046-0bad-4a57-90ed-c3a341012945.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure6. Stateful Network Policies &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h1 id=&quot;heading-scenario&quot;&gt;Scenario&lt;/h1&gt;&lt;p&gt;To keep things straightforward, Ive opted for the BookInfo applicationa commonly featured example in Istios getting started guide. This application comprises four microservices: Product Page, Reviews, Details, and Ratings. While Reviews has multiple versions, well keep our focus on v1.&lt;/p&gt;&lt;p&gt;For a visual overview, check out the diagram below, sourced from Istios documentation. It vividly illustrates the key components and their interactions.More details can be found &lt;a target=&quot;_blank&quot; href=&quot;https://istio.io/latest/docs/examples/bookinfo/#define-the-service-versions&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714275168992/20b5dd19-1a8f-44e2-9cda-6ed452e4e5c4.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure 7. BookInfo Application &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;It is worth noting that all of this setup is running locally on my laptop as a kind cluster. More details can be found &lt;a target=&quot;_blank&quot; href=&quot;https://kind.sigs.k8s.io/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714275195511/b6f4f893-5bd1-4db2-bdd9-8323b63a3920.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure 8. Lab Setup &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;h2 id=&quot;heading-application-discovery&quot;&gt;Application Discovery&lt;/h2&gt;&lt;p&gt;Hubble is a fully distributed networking and security observability platform. It is built on top of Cilium and eBPF to enable deep visibility into the communication and behavior of services as well as the networking infrastructure in a completely transparent manner. (Source: Cilium Documentation)&lt;/p&gt;&lt;p&gt;We will look at identities in the upcoming section but for now you can see:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Figure9. shows the traffic from the internal-client pod to productpage pod&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Figure10. shows all the backends that the productpage actually communicates with reviews throughout its versions (v1,v2,v3).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Effective crafting of Network Policies hinges on attaining comprehensive visibility into the communication patterns among Pods and entities. This visibility enables a thorough understanding of how these components interact within the Kubernetes cluster, facilitating the creation of policies that accurately reflect and enforce security requirements.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--to-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;23217&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.867:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:47838&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.221:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.221:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.221:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.344:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure 9. Traffic from Client to Productpage&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt;                      &lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.813:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35336&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.814:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35336&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.822:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:43297&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.859:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:43712&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.863:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.863:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.866:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:05:46.867:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35352&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:16.230:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50168&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.260:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:42803&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.276:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:33718&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.336:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:33718&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.336:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:33718&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.342:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:09:21.343:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:42856&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure10. Traffic from Productpage to Reviews, Ratings &amp;amp; Details Pods&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-security-identity&quot;&gt;Security Identity&lt;/h1&gt;&lt;p&gt;As discussed, Kubernetes &amp;amp; Network Policies are heavily dependent on labels. Basically, for every unique combination of labels that would target a set of Pods, Cilium would create unique security identities.&lt;/p&gt;&lt;p&gt;Thus, when traffic for instance needs to go from frontend to backend.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;On the host having the web pod, Cilium figures out the security identity that maps to the source which is 81 in our example.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Cilium would ensure that the security identity information (81) is encoded into the packet it sends to the backend.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Thus, you can think about Network Policies as controlling access based on source and destination security identities.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Upon receiving the packet, we know that the source identity is 81 and the backend identity is 77 and need to check if there are policies that allow Identity 81&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714441830703/ff7c36e5-ddff-4cf5-9f09-5f97eb12d789.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure11. Cilium Security Identities &lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;This output shows all the existing pods and their existing security identities.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;NAME&lt;/span&gt;                             &lt;span class=&quot;hljs-string&quot;&gt;SECURITY&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;IDENTITY&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ENDPOINT&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;STATE&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;IPV4&lt;/span&gt;           &lt;span class=&quot;hljs-string&quot;&gt;IPV6&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;details-v1-698d88b-89gnc&lt;/span&gt;         &lt;span class=&quot;hljs-number&quot;&gt;285&lt;/span&gt;                 &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.140&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;internal-client&lt;/span&gt;                  &lt;span class=&quot;hljs-number&quot;&gt;23217&lt;/span&gt;               &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.172&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;productpage-v1-675fc69cf-8zzxh&lt;/span&gt;   &lt;span class=&quot;hljs-number&quot;&gt;9889                &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.148&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;ratings-v1-6484c4d9bb-8nsbj&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;5778                &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.241&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;reviews-v1-5b5d6494f4-dwvpn&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;55669&lt;/span&gt;               &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.170&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;reviews-v2-5b667bcbf8-kjwhn&lt;/span&gt;      &lt;span class=&quot;hljs-number&quot;&gt;10139&lt;/span&gt;               &lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.87&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;reviews-v3-5b9bd44f4-qjfth&lt;/span&gt;       &lt;span class=&quot;hljs-number&quot;&gt;1786                &lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;ready&lt;/span&gt;            &lt;span class=&quot;hljs-number&quot;&gt;10.244&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.2&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.191&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure12. Endpoints &amp;amp; their corresponding identities&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-egress-policy-deny-all&quot;&gt;Egress Policy: Deny-All&lt;/h1&gt;&lt;p&gt;This is an example of an empty egress network policy that is attached to the productpage pod. This would block all outgoing traffic from productpage to any other pod or entity.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-deny-all&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; {}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure13. Empty Egress Network Policy&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Refer back to figure 12 where the pods and their respective identities are listed. Please note that Hubble can also use pod names directly with from-pod and to-pod.&lt;/p&gt;&lt;p&gt;Figure 14 shows that traffic continues to flow from the client to the productpage which is expected as the policy on the productpage is an egress only policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--to-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;23217&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.254:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:51160&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.255:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:51160&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.280:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:46532&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.281:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:46532&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.281:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:46532&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure14. Using Hubble to observe traffic between internal-client &amp;amp; productpage&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Figure 15, shows that traffic from productpage to coredns is blocked. The reason this happens is when productpage wants to communicate with any of its backend services (reviews, details..etc) it sends a DNS request to resolve the IP address of the service name (reviews for example). For more details refer to the Kubernetes Services blog post &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-services&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--since&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;2m&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:28.285:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:33.290:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 27 22:17:33.290:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:40789&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure15. Traffic from productpage to coredns is blocked&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Output from internal-client is actually inline with our findings whereby we get a response from productpage however it clearly mentions that reviews are inaccessible as a result of the egress policy.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;    &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;div&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;class=&quot;col-md-6&quot;&amp;gt;&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;h4&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;class=&quot;text-center&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;text-primary&quot;&amp;gt;Error&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;fetching&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews!&amp;lt;/h4&amp;gt;&lt;/span&gt;      &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;p&amp;gt;Sorry,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;are&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;currently&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;unavailable&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;book.&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure16. Output from Internal Client&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-allow-traffic-to-dns&quot;&gt;Allow Traffic to DNS&lt;/h1&gt;&lt;p&gt;We have concluded our earlier section, whereby traffic to the coredns pod was being blocked. This policy allows product page to get to coredns on port 53.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;allow-to-dns&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:k8s-app&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-dns&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;toPorts:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;           &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;53&quot;&lt;/span&gt;             &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ANY&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure17. Allow Traffic from productpage to coredns&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:36:17.388:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:49263&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:36:17.407:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:60156&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:36:17.407:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:40690&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure18. Traffic Forwarded from productpage to coredns&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;The DNS rules being added here can be used as an L7 policy to allow DNS requests to particular domains (like an Allowlist) via a DNS proxy as shown in Figure 3. The other value that comes with DNS rules is that now we have added a DNS proxy into the picture, we can have more visibility on DNS traffic.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;allow-to-dns&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:k8s-app&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-dns&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;toPorts:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;           &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;53&quot;&lt;/span&gt;             &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ANY&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;dns:&lt;/span&gt;              &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchPattern:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure19. Add DNS Rules to the NetworkPolicy&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt;   &lt;span class=&quot;hljs-string&quot;&gt;--protocol&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.340:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.340:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.342:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.96.222.2&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.342:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:50114&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer  TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.345:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.345:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.346:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.96.179.42&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:49:07.347:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:35429&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer  TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure20. DNS Traffic Visibility&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-allow-traffic-to-backend-pods&quot;&gt;Allow Traffic to Backend Pods&lt;/h1&gt;&lt;p&gt;Recall that at this stage, the DNS resolution works however we still need to add the relevant rules from productpage to reviews &amp;amp; details. Bear in mind that for other pods that are not selected as part of the policy all ingress/egress traffic continues to flow (e.g. Traffic between reviews &amp;amp; ratings)&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;from-product-to-reviews-details&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;productpage&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;reviews&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;details&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure21. Allow from productpage to reviews &amp;amp; details&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--from-identity&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--last&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.715:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37378&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.724:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37378&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.725:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37378&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v1-5b5d6494f4-dwvpn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:55669)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:03.740:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:58725&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.810:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37394&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.810:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37394&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v2-5b667bcbf8-kjwhn:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:10139)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.867:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:34917&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.879:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:51600&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(UDP)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.911:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37402&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 00:38:08.911:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/productpage-v1-675fc69cf-8zzxh:37402&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:9889)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/reviews-v3-5b9bd44f4-qjfth:9080&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:1786)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-endpoint&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure22. Hubble Visbility for traffic from product page &amp;amp; reviews versions&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-internet-egress-policy&quot;&gt;Internet Egress Policy&lt;/h2&gt;&lt;p&gt;This is an Internet Egress use-case where the objective is to limit the domains that the internal-client pod can connect to on the Internet.&lt;/p&gt;&lt;p&gt;Notice you can still see the same DNS policy, however we are adding the toFQNDs construct in this policy. This works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Traffic from internal-client to coredns is allowed.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;When the internal-client wants to connect to the public URL &quot;ifconfig.me&quot;, it first needs to resolve its IP Address.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Since, we already have visibility to DNS traffic with DNS Proxy, we can see the DNS response containing the IP Address of &quot;ifconfig.me&quot;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;toFQDN is basically a representation of that IP Address i.e. as if we are putting a policy to the IP address that is a result of DNS resolution.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The reason this approach is interesting is that we don&apos;t need to deal with changing addresses &amp;amp; we can just rely on DNS names.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium.io/v2&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;from-internal-client-to-fqdn&quot;&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;endpointSelector:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;internal-client&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;egress:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toEndpoints:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;k8s:k8s-app&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-dns&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;toPorts:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;           &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;53&quot;&lt;/span&gt;             &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ANY&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;dns:&lt;/span&gt;              &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchPattern:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;*&quot;&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;toFQDNs:&lt;/span&gt;        &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;matchName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;ifconfig.me&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure23. Allow Traffic to Public FQDN ifconfig.me&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;hubble&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;observe&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--pod&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;internal-client&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;--protocol&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.378:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.378:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.423:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2600:1901:0:bbc3::&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:03:39.424:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:60700&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-rw29s:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;34.117.118.44&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.604:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.604:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.607:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.607:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.default.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.610:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.610:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.611:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.611:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.svc.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.611:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Answer RCode: Non-Existent Domain TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4294967295&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.cluster.local.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.612:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-request&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Query&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.652:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;151.101.3.5,151.101.131.5,151.101.67.5,151.101.195.5&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;A))&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.656:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:57590&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kube-system/coredns-76f75df574-sgbcv:53&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:17513)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;dns-response&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(DNS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Answer&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2a04:4e42:c00::773,2a04:4e42:a00::773,2a04:4e42::773,2a04:4e42:800::773,2a04:4e42:600::773,2a04:4e42:e00::773,2a04:4e42:200::773,2a04:4e42:400::773&quot;&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;TTL:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(Proxy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com.&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;AAAA))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure24. Visibility to DNS Request &amp;amp; Responses for Public Domains&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Here you can see traffic to &quot;ifconfig.me&quot; forwarded whereas traffic for other domains being denied.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.656:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:16.656:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:17.699:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:04:17.699:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cnn.com:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:05:20.563:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;151.101&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:none&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DENIED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:05:20.563:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54006&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;151.101&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(world)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policy&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;denied&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;DROPPED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.832:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;policy-verdict:L3-Only&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;EGRESS&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ALLOWED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.833:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;SYN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.854:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.854:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PSH)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.894:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK,&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FIN)&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;Apr 28 01:08:27.894:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default/internal-client:54862&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:23217)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ifconfig.me:80&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(ID:16777219)&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;to-stack&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;FORWARDED&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;(TCP&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;Flags:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ACK)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure25. Allow Traffic to Public FQDN ifconfig.me&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-troubleshooting&quot;&gt;Troubleshooting&lt;/h1&gt;&lt;p&gt;In this section, I wanted to go a bit deeper on a flow productpage to reviews-v1 pod. I have added the figure again for convenience. You can clearly see that productpage and reviews-v1 are on different nodes.&lt;/p&gt;&lt;p&gt;In addition, in this setup VXLAN tunnels to encapsulate traffic between the nodes as per the output of Figure 27.&lt;/p&gt;&lt;div class=&quot;hn-table&quot;&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1714275195511/b6f4f893-5bd1-4db2-bdd9-8323b63a3920.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;&lt;center&gt;Figure26. Revisit Pod Placement&lt;/center&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-string&quot;&gt;k.eljamali@LLJXN1XJ9X&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Network&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Policies&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;cilium&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;tunnel&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;routing-mode&lt;/span&gt;                                      &lt;span class=&quot;hljs-string&quot;&gt;tunnel&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;tunnel-protocol&lt;/span&gt;                                   &lt;span class=&quot;hljs-string&quot;&gt;vxlan&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure27. Tunnel Mode with VXLAN&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;It is mind boggling to see all this information within Hubble on a particular flow.&lt;/p&gt;&lt;p&gt;Figure 28 shows all the information about source &amp;amp; destination in terms of labels &amp;amp; identities and we can clearly see the traffic being forwarded on the overlay (VXLAN Tunnel). Note that the verdict clearly shows that the traffic is forwarded.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;{  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flow&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373296596Z&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;uuid&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;3ce41f60-b203-4e43-ab34-c89f631f7cd2&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;verdict&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;FORWARDED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ethernet&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;9e:f7:72:78:39:c7&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;d6:55:a3:91:69:37&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;IP&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.2.148&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.1.170&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ipVersion&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;IPv4&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;l4&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;TCP&quot;:&lt;/span&gt; {        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;47812&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9080&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flags&quot;:&lt;/span&gt; {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ACK&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;        }      }    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ID&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1881&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-v1-675fc69cf-8zzxh&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;workloads&quot;:&lt;/span&gt; [        {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-v1&quot;&lt;/span&gt;,          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;kind&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Deployment&quot;&lt;/span&gt;        }      ]    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;55669&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;reviews-v1-5b5d6494f4-dwvpn&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;L3_L4&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker3&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;event_type&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;sub_type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;traffic_direction&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;EGRESS&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;trace_observation_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TO_OVERLAY&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;is_reply&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;,    &lt;span class=&quot;hljs-string&quot;&gt;&quot; interface&quot;&lt;/span&gt;&lt;span class=&quot;hljs-string&quot;&gt;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;index&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;6&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;cilium_vxlan&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Summary&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TCP Flags: ACK&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker3&quot;&lt;/span&gt;,  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373296596Z&quot;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure28. Egress Traffic from Product Forwarded over VXLAN Tunnel&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Figure29 shows the incoming traffic from kind-worker1&apos;s perspective, where the traffic gets forwarded to the interface connecting reviews-v1 pod. Note that the verdict clearly shows that the traffic is forwarded.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;{  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flow&quot;:&lt;/span&gt; {    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373343054Z&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;uuid&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;bf9df4cf-44b2-479a-bd41-9d232d5aacf6&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;verdict&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;FORWARDED&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ethernet&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;72:e6:23:94:38:bb&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;02:9e:93:c9:74:57&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;IP&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.2.148&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;10.244.1.170&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ipVersion&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;IPv4&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;l4&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;TCP&quot;:&lt;/span&gt; {        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;47812&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination_port&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9080&lt;/span&gt;,        &lt;span class=&quot;hljs-attr&quot;&gt;&quot;flags&quot;:&lt;/span&gt; {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ACK&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;true&lt;/span&gt;        }      }    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;source&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;9889&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-productpage&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;productpage-v1-675fc69cf-8zzxh&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;destination&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;ID&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;2039&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;identity&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;55669&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;namespace&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;default&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;labels&quot;:&lt;/span&gt; [        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:app=reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.cluster=kind-kind&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.cilium.k8s.policy.serviceaccount=bookinfo-reviews&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:io.kubernetes.pod.namespace=default&quot;&lt;/span&gt;,        &lt;span class=&quot;hljs-string&quot;&gt;&quot;k8s:version=v1&quot;&lt;/span&gt;      ],      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;pod_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;reviews-v1-5b5d6494f4-dwvpn&quot;&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;workloads&quot;:&lt;/span&gt; [        {          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;reviews-v1&quot;&lt;/span&gt;,          &lt;span class=&quot;hljs-attr&quot;&gt;&quot;kind&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;Deployment&quot;&lt;/span&gt;        }      ]    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;L3_L4&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;event_type&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;type&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;4&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;traffic_direction&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;INGRESS&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;trace_observation_point&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TO_ENDPOINT&quot;&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;is_reply&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/span&gt;,    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;interface&quot;:&lt;/span&gt; {      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;index&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;15&lt;/span&gt;,      &lt;span class=&quot;hljs-attr&quot;&gt;&quot;name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;lxc240530c746ff&quot;&lt;/span&gt;    },    &lt;span class=&quot;hljs-attr&quot;&gt;&quot;Summary&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;TCP Flags: ACK&quot;&lt;/span&gt;  },  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;node_name&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;kind-kind/kind-worker&quot;&lt;/span&gt;,  &lt;span class=&quot;hljs-attr&quot;&gt;&quot;time&quot;:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;2024-04-27T21:36:04.373343054Z&quot;&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;b&gt;&lt;center&gt;Figure29. Egress Traffic from Reviews-v1 with Policy Enforcement&lt;/center&gt;&lt;/b&gt;&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1714567507742/a2d92817-cae1-4239-862a-dfa7aa255358.jpeg</hashnode:coverImage></item><item><title><![CDATA[PODCAST: Kubernetes Networking Essentials]]></title><description><![CDATA[We discuss Kubernetes networking basics: pods, CNI, IPAM, Node to Node Connectivity, Kubernetes Services, Gateway API, eBPF, and service mesh]]></description><link>https://jamali.hashnode.dev/podcast-kubernetes-networking-essentials</link><guid isPermaLink="true">https://jamali.hashnode.dev/podcast-kubernetes-networking-essentials</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[#kubernetes #container ]]></category><category><![CDATA[kubernetes architecture]]></category><category><![CDATA[Networking, IP Address, IPv4, IPv6.]]></category><category><![CDATA[networking]]></category><category><![CDATA[#kubernetesNetworking]]></category><category><![CDATA[kubernetes network policies]]></category><category><![CDATA[#ServiceMesh]]></category><category><![CDATA[eBPF]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Thu, 04 Apr 2024 04:54:27 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;I recently was invited by Packet Pushers to chat on the topic of Kubernetes Networking Essentials as part of their Heavy Networking Podcast.&lt;/p&gt;&lt;p&gt;You can listen to the talk &lt;a target=&quot;_blank&quot; href=&quot;https://packetpushers.net/podcasts/heavy-networking/hn727-kubernetes-networking-essentials/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;p&gt;I recently was invited by Packet Pushers to chat on the topic of Kubernetes Networking Essentials as part of their Heavy Networking Podcast.&lt;/p&gt;&lt;p&gt;You can listen to the talk &lt;a target=&quot;_blank&quot; href=&quot;https://packetpushers.net/podcasts/heavy-networking/hn727-kubernetes-networking-essentials/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1712206137543/ddd2828c-e84b-4d26-9a31-183e285405a8.jpeg</hashnode:coverImage></item><item><title><![CDATA[Introduction to AWS VPC Lattice]]></title><description><![CDATA[This blog post explains various aspects of VPC Lattice ranging from the need, main constructs, architecture, to advantages and security approach.]]></description><link>https://jamali.hashnode.dev/introduction-to-vpc-lattice</link><guid isPermaLink="true">https://jamali.hashnode.dev/introduction-to-vpc-lattice</guid><category><![CDATA[AWS]]></category><category><![CDATA[vpc]]></category><category><![CDATA[Lattice]]></category><category><![CDATA[networking]]></category><category><![CDATA[route53]]></category><category><![CDATA[proxy]]></category><category><![CDATA[zerotrust]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Mon, 26 Feb 2024 02:45:53 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h1 id=&quot;heading-from-networking-to-service-networking&quot;&gt;From Networking to Service Networking&lt;/h1&gt;&lt;p&gt;Well, we have always talked about Networking in the context of L2, and L3 Protocols, SDN Fabrics and as workloads moved to the Cloud we started seeing Cloud Networking which varies between Public Clouds. So what is this service networking?&lt;/p&gt;&lt;p&gt;I think the best way to describe service networking is networking for application owners or developers. It is an abstraction of all the intricacies of the L3/L4 networking with primal focus on the application or service you are providing. Another reason Service Networking became a thing is the advent of micro-services. Historically in a monolith all the components run as services on the same hardware or virtual machine making the communicating between components internal to the node. In a micro-services environment each component can live on a different node but we still need to visualize, monitor, optimize and secure the component to component communication.&lt;/p&gt;&lt;p&gt;Now that we have introduced service networking, some of the advantages that service networking brings:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Application Centricity in terms of monitoring and deep visibility&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Provides Improved resiliency with Advanced Load Balancing techniques (Blue/Green deployments)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Zero Trust with Service to Service or client to Service Authentication &amp;amp; Authorization&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Some solutions provides additional capabilities to inject failures &amp;amp; delays providing better robustness and resiliency of your services and applications&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now that we have introduced service networking, we will move on to focus on AWS VPC Lattice.&lt;/p&gt;&lt;h1 id=&quot;heading-vpc-lattice-constructs&quot;&gt;VPC Lattice Constructs&lt;/h1&gt;&lt;p&gt;VPC Lattice is AWS&apos;s answer to service networking. It is made up of 3 basic components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service&lt;/strong&gt;: This is a component or a micro-service within your uber application. Some examples could be: Checkout service, location service, authentication service..etc You can think about a service in Lattice similar to a Load Balancer VIP that abstracts and exposes a number of workloads which could be VMs, K8 Pods..etc A service is composed of 3 different elements:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Listener: Similar to a LB, the listener defines the protocol, port &amp;amp; hostname(s) the service is listening to.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Rules: The idea here is when traffic hits the listener you can have host based or path based rules by which you decide where to send this traffic. For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Path based:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;acme.com/prod: Routes users to the production stable page&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;acme.com/latest: Routes users to the latest update that is under testing&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Host based: Ability to publish multiple applications&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;app1.acme.com&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;app2.acme.com&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;        You can also have a combination of Host and Path based routing.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Target Group: Similar to an ALB or NLB Target Group, this references the backend workloads where traffic needs to be forwarded when matching a particular rule.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Service Network: Services can be placed in one or more service networks. On another hand, VPCs (containing clients) to those services can also be associated to a single Service Network. Thus, a service network marries the services that are available within a service network and VPCs that need access to those services.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707838841780/6158a961-3505-4dc7-8c5a-9081a5ec3f07.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;This figure shows the different target types supported by a VPC Lattice service. The interesting part here is that VPC Lattice works across all compute types (Virtual Machines, Kubernetes &amp;amp; Serverless)&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707796319848/a2fcd1b0-34b3-4dc8-b93c-bc3799c7062d.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;This is an example of a service where for a particular rule (path or host based) we send 90% of the traffic towards the production target group (nginx-production-tag) and 10% of the traffic towards the new release (nginx-new-tg).&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707796334216/4ac9f8b3-42ee-422a-8a37-2cb9ad69fa07.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The association of services and VPCs to a service network provides high level security and scoping (similar to a VRF in networking). In the figure below, based on Service Network A, the only 3 services that can be accessed are S1, S2 and S3 and only VPC-1, VPC-2 and VPC-3 can access them. This means based on the example that VPC-1 can&apos;t access service S4 and VPC-4 can&apos;t access services S1,S2, or S3.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707796498035/d0f84dfe-e0cc-498c-b9d8-770a3063b339.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-the-vpc-lattice-advantage&quot;&gt;The VPC Lattice Advantage&lt;/h1&gt;&lt;p&gt;I will use this section to explain the architecture of VPC Lattice and highlight its unique points.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Parallel Network: One of the major benefits of VPC Lattice is that it runs as a parallel network under the hood i.e. there isn&apos;t any change required for the existing network. You can see the figure below where there is a TGW connecting two VPCs and there is another path that goes through VPC Lattice. Another advantage of VPC Lattice is that it connects services across VPCs and Accounts without requiring any underlying networking changes via this parallel network.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;VPC Lattice leverages DNS: So now that we have the two different paths, the decision on which path to take depends on DNS. When a service is created within VPC lattice, it gets allocated a DNS Name or you can specify your own name for that matter. The resolution of the DNS name maps to the Proxy represented by the Lattice icon on the top path. Any other traffic or DNS resolution continues to run in the same manner. It is worth noting that VPC lattice or these proxies operate within the link local range of 169.254.171.0/24 so that they don&apos;t interfere with your existing address space.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Solves overlapping address Problem: VPC Lattice by default will SNAT to the &quot;Proxy IP&quot; within the 169.254.171.0/24 range when sending the traffic to the service thus the service will always see the request coming from that range.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1708881671648/1c1e86c7-2c6b-40b8-879f-184709eb72b8.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-vpc-lattice-security&quot;&gt;VPC Lattice Security&lt;/h1&gt;&lt;p&gt;There are many aspects of VPC Lattice Security that can be highlighted:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service to Service vs Network Connectivity:&lt;/strong&gt; When you connect two VPCs (A&amp;amp;B) via TGW or VPC peering for instance, all workloads in VPC-A can communicate with VPC-B unless you are using some form of firewalling (Security Groups, Network Firewall..etc).VPC lattice improves on this model by narrowing down the list of services that can communicate within the service network as well as the list of VPCs that need to communicate with those limited set of services.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security Groups:&lt;/strong&gt; It is interesting that VPC Lattice respects the security groups of the ENIs across the path from the client to the server (member of the service target group). In addition, when going to VPC Lattice there is also an associated Security Group that can also be used to enforce which workloads within the VPC can access the services within the service network. In reality, I couldn&apos;t see the Lattice ENI but it just helps to put a mental model around it.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707838371557/31d28011-490e-4735-b2c2-69dd027cf80e.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authentication &amp;amp; Authorization:&lt;/strong&gt; The Auth type (Authentication and Authorization) in VPC Lattice can be set to None or AWS IAM. None basically doesn&apos;t take into account authenticating and authorizing the client. The idea with AWS IAM is that when a client makes a request to a service regardless if the client is another service or a non service, the client needs to have an identity. VPC Lattice leverages Sigv4 which is the process to add authentication information to requests and is heavily leveraged in AWS for instance when you send a request to AWS services (e.g. S3), before the request is fulfilled AWS has to figure out the user identity, check the Identity Policy attached to the user and the resource policy on the S3 bucket and based on all of this either accept or reject the request.&lt;/p&gt;&lt;p&gt;  VPC Lattice follows the same logic where it needs to identify the identity of a client, if it has the identity based policies to Invoke Lattice, in addition to the resource based policies which in Lattice are Service Network Policy &amp;amp; Service Policy. The Service Network Policy gets associated with the Service Network affecting the level of acceptable access to all services within the service network and is generally a coarse grained Authorization policy where for instance you can allow traffic from particular VPCs or Organization ID and that all requests have to be authenticated. The Service policy is associated with a particular service and provides fine grained least privilege access to the service.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;This is not the easiest part of VPC Lattice due to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;IAM Dependency: IAM is not the the easiest AWS service to wrap your head around at least for me.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Application Changes: The client or client application will need to be modified to send a Sigv4 request for Lattice to allow or deny the request.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1708965706027/1e61715f-89be-486f-815e-6c99275ad815.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-closing-thoughts&quot;&gt;Closing Thoughts&lt;/h1&gt;&lt;p&gt;In this blog post, I tried to introduce the need for VPC Lattice, its constructs, as well as its architecture and benefits. We ended this blog post by touching upon VPC Lattice Security.&lt;/p&gt;&lt;p&gt;I will be working on a part 2 on VPC Lattice where I will run a small demo, discuss Kubernetes Integration and external access to VPC Lattice.&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h1 id=&quot;heading-from-networking-to-service-networking&quot;&gt;From Networking to Service Networking&lt;/h1&gt;&lt;p&gt;Well, we have always talked about Networking in the context of L2, and L3 Protocols, SDN Fabrics and as workloads moved to the Cloud we started seeing Cloud Networking which varies between Public Clouds. So what is this service networking?&lt;/p&gt;&lt;p&gt;I think the best way to describe service networking is networking for application owners or developers. It is an abstraction of all the intricacies of the L3/L4 networking with primal focus on the application or service you are providing. Another reason Service Networking became a thing is the advent of micro-services. Historically in a monolith all the components run as services on the same hardware or virtual machine making the communicating between components internal to the node. In a micro-services environment each component can live on a different node but we still need to visualize, monitor, optimize and secure the component to component communication.&lt;/p&gt;&lt;p&gt;Now that we have introduced service networking, some of the advantages that service networking brings:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Application Centricity in terms of monitoring and deep visibility&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Provides Improved resiliency with Advanced Load Balancing techniques (Blue/Green deployments)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Zero Trust with Service to Service or client to Service Authentication &amp;amp; Authorization&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Some solutions provides additional capabilities to inject failures &amp;amp; delays providing better robustness and resiliency of your services and applications&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now that we have introduced service networking, we will move on to focus on AWS VPC Lattice.&lt;/p&gt;&lt;h1 id=&quot;heading-vpc-lattice-constructs&quot;&gt;VPC Lattice Constructs&lt;/h1&gt;&lt;p&gt;VPC Lattice is AWS&apos;s answer to service networking. It is made up of 3 basic components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service&lt;/strong&gt;: This is a component or a micro-service within your uber application. Some examples could be: Checkout service, location service, authentication service..etc You can think about a service in Lattice similar to a Load Balancer VIP that abstracts and exposes a number of workloads which could be VMs, K8 Pods..etc A service is composed of 3 different elements:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Listener: Similar to a LB, the listener defines the protocol, port &amp;amp; hostname(s) the service is listening to.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Rules: The idea here is when traffic hits the listener you can have host based or path based rules by which you decide where to send this traffic. For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Path based:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;acme.com/prod: Routes users to the production stable page&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;acme.com/latest: Routes users to the latest update that is under testing&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Host based: Ability to publish multiple applications&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;app1.acme.com&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;app2.acme.com&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;        You can also have a combination of Host and Path based routing.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Target Group: Similar to an ALB or NLB Target Group, this references the backend workloads where traffic needs to be forwarded when matching a particular rule.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Service Network: Services can be placed in one or more service networks. On another hand, VPCs (containing clients) to those services can also be associated to a single Service Network. Thus, a service network marries the services that are available within a service network and VPCs that need access to those services.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707838841780/6158a961-3505-4dc7-8c5a-9081a5ec3f07.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;This figure shows the different target types supported by a VPC Lattice service. The interesting part here is that VPC Lattice works across all compute types (Virtual Machines, Kubernetes &amp;amp; Serverless)&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707796319848/a2fcd1b0-34b3-4dc8-b93c-bc3799c7062d.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;This is an example of a service where for a particular rule (path or host based) we send 90% of the traffic towards the production target group (nginx-production-tag) and 10% of the traffic towards the new release (nginx-new-tg).&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707796334216/4ac9f8b3-42ee-422a-8a37-2cb9ad69fa07.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The association of services and VPCs to a service network provides high level security and scoping (similar to a VRF in networking). In the figure below, based on Service Network A, the only 3 services that can be accessed are S1, S2 and S3 and only VPC-1, VPC-2 and VPC-3 can access them. This means based on the example that VPC-1 can&apos;t access service S4 and VPC-4 can&apos;t access services S1,S2, or S3.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707796498035/d0f84dfe-e0cc-498c-b9d8-770a3063b339.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-the-vpc-lattice-advantage&quot;&gt;The VPC Lattice Advantage&lt;/h1&gt;&lt;p&gt;I will use this section to explain the architecture of VPC Lattice and highlight its unique points.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Parallel Network: One of the major benefits of VPC Lattice is that it runs as a parallel network under the hood i.e. there isn&apos;t any change required for the existing network. You can see the figure below where there is a TGW connecting two VPCs and there is another path that goes through VPC Lattice. Another advantage of VPC Lattice is that it connects services across VPCs and Accounts without requiring any underlying networking changes via this parallel network.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;VPC Lattice leverages DNS: So now that we have the two different paths, the decision on which path to take depends on DNS. When a service is created within VPC lattice, it gets allocated a DNS Name or you can specify your own name for that matter. The resolution of the DNS name maps to the Proxy represented by the Lattice icon on the top path. Any other traffic or DNS resolution continues to run in the same manner. It is worth noting that VPC lattice or these proxies operate within the link local range of 169.254.171.0/24 so that they don&apos;t interfere with your existing address space.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Solves overlapping address Problem: VPC Lattice by default will SNAT to the &quot;Proxy IP&quot; within the 169.254.171.0/24 range when sending the traffic to the service thus the service will always see the request coming from that range.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1708881671648/1c1e86c7-2c6b-40b8-879f-184709eb72b8.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-vpc-lattice-security&quot;&gt;VPC Lattice Security&lt;/h1&gt;&lt;p&gt;There are many aspects of VPC Lattice Security that can be highlighted:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service to Service vs Network Connectivity:&lt;/strong&gt; When you connect two VPCs (A&amp;amp;B) via TGW or VPC peering for instance, all workloads in VPC-A can communicate with VPC-B unless you are using some form of firewalling (Security Groups, Network Firewall..etc).VPC lattice improves on this model by narrowing down the list of services that can communicate within the service network as well as the list of VPCs that need to communicate with those limited set of services.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security Groups:&lt;/strong&gt; It is interesting that VPC Lattice respects the security groups of the ENIs across the path from the client to the server (member of the service target group). In addition, when going to VPC Lattice there is also an associated Security Group that can also be used to enforce which workloads within the VPC can access the services within the service network. In reality, I couldn&apos;t see the Lattice ENI but it just helps to put a mental model around it.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707838371557/31d28011-490e-4735-b2c2-69dd027cf80e.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authentication &amp;amp; Authorization:&lt;/strong&gt; The Auth type (Authentication and Authorization) in VPC Lattice can be set to None or AWS IAM. None basically doesn&apos;t take into account authenticating and authorizing the client. The idea with AWS IAM is that when a client makes a request to a service regardless if the client is another service or a non service, the client needs to have an identity. VPC Lattice leverages Sigv4 which is the process to add authentication information to requests and is heavily leveraged in AWS for instance when you send a request to AWS services (e.g. S3), before the request is fulfilled AWS has to figure out the user identity, check the Identity Policy attached to the user and the resource policy on the S3 bucket and based on all of this either accept or reject the request.&lt;/p&gt;&lt;p&gt;  VPC Lattice follows the same logic where it needs to identify the identity of a client, if it has the identity based policies to Invoke Lattice, in addition to the resource based policies which in Lattice are Service Network Policy &amp;amp; Service Policy. The Service Network Policy gets associated with the Service Network affecting the level of acceptable access to all services within the service network and is generally a coarse grained Authorization policy where for instance you can allow traffic from particular VPCs or Organization ID and that all requests have to be authenticated. The Service policy is associated with a particular service and provides fine grained least privilege access to the service.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;This is not the easiest part of VPC Lattice due to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;IAM Dependency: IAM is not the the easiest AWS service to wrap your head around at least for me.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Application Changes: The client or client application will need to be modified to send a Sigv4 request for Lattice to allow or deny the request.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1708965706027/1e61715f-89be-486f-815e-6c99275ad815.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-closing-thoughts&quot;&gt;Closing Thoughts&lt;/h1&gt;&lt;p&gt;In this blog post, I tried to introduce the need for VPC Lattice, its constructs, as well as its architecture and benefits. We ended this blog post by touching upon VPC Lattice Security.&lt;/p&gt;&lt;p&gt;I will be working on a part 2 on VPC Lattice where I will run a small demo, discuss Kubernetes Integration and external access to VPC Lattice.&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1708915192603/eed1116b-d5d1-409a-831a-82b58e9ae7ba.png</hashnode:coverImage></item><item><title><![CDATA[Kubernetes Gateway API]]></title><description><![CDATA[This blog goes through the advantages of Gateway API in terms of improved role based API, RBAC & portability and then explains the object model by examples]]></description><link>https://jamali.hashnode.dev/kubernetes-gateway-api</link><guid isPermaLink="true">https://jamali.hashnode.dev/kubernetes-gateway-api</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[containers]]></category><category><![CDATA[kubernetes architecture]]></category><category><![CDATA[Gateway API]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[GCP]]></category><category><![CDATA[nginx]]></category><category><![CDATA[nginx ingress]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Mon, 12 Feb 2024 19:15:44 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;p&gt;So, we ended our &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-loadbalancer-service&quot;&gt;previous post&lt;/a&gt; talking about some of the downsides of the Load Balancer service in terms of security, manageability and increased costs. So this weekend, I set myself up to understand the Kubernetes Gateway API (not an API Gateway) which is a consolidated ingress solution to get traffic to your Kubernetes Clusters.&lt;/p&gt;&lt;p&gt;It&apos;s important to note the terminology here. Traditionally, Kubernetes users have been familiar with Ingress, the widely-used method for creating a single entry point to expose services within a cluster, primarily targeting HTTP/HTTPs workloads. However, there&apos;s a new player in town: the Gateway API.&lt;/p&gt;&lt;p&gt;While Ingress acts like a monolith, requiring modifications to a single object as more applications are exposed, the Gateway API takes a more versatile approach. It covers a broader spectrum of protocols, including HTTP, HTTPS, and gRPC. What sets it apart is not just the protocol support but also the improved role-based API, providing a more flexible and sophisticated means of managing ingress.&lt;/p&gt;&lt;h1 id=&quot;heading-role-based-api&quot;&gt;Role Based API&lt;/h1&gt;&lt;p&gt;ACME Corp has different roles that help manage their Kubernetes infrastructure and deploy their required applications and services on top.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Choosing the Provider: John handles the decision on which Infrastructure Providers to bring in and the high level settings of that provider. For instance, John favors the NGINX solution. For that matter John has to define the GatewayClass object which is a cluster scoped resource tied to the provider (NGINX). At a high level, this is John saying &quot;We will use NGINX as the platform of choice to handle Ingress Traffic.&quot; There might be cases for various reasons where multiple GatewayClasses (Infrastructure Providers) can be used simultaneously.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Configuring the Proxy: Karim handles the NGINX proxy configuration via the Gateway Object. It is important to think about the proxy or Load Balancer Instance as a shared resource across multiple teams, thus some settings will be common and defined under the Gateway Object whereas others will be configured under Routes (HTTPRoutes, TLSRoutes). Options defined under the Gateway are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Specifying the class of Gateway it belongs to (GatewayClass specified by John)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Specifying the hostname (acme.com), port, and protocol the proxy is listening to as well as TLS parameters.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Allowing particular routes to attach to the Load Balancer.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Route Configuration: Chris has a particular ticketing Application that he intends to publish. He would like to use the FQDN ticket.acme.com and as soon as this URI is seen, he would like this routed to the ClusterIP service within Kubernetes which in turn will target his application workloads. A deeper explanation on ClusterIP and how it works can be found &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-services&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;  Another advantage that the RoleBased API brings into the picture is a better RBAC implementation where each of those users or teams can gain access to the needed objects &amp;amp; thus sets better governance on publishing applications externally.&lt;/p&gt;&lt;p&gt;  The final advantage of Gateway API we will touch upon is portability i.e. the ability to switch implementation from one vendor to another without requiring change. Ingress on the other hand was heavily dependent on vendor specific annotations which made it harder to switch from one implementation to another.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706665749410/604d8504-a91d-4c28-8f31-6b10f79eee38.png&quot; alt=&quot;source: https://gateway-api.sigs.k8s.io/&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Source: &lt;a target=&quot;_blank&quot; href=&quot;https://gateway-api.sigs.k8s.io/&quot;&gt;https://gateway-api.sigs.k8s.io/&lt;/a&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-but-how-does-it-work&quot;&gt;But how does it Work?&lt;/h1&gt;&lt;p&gt;In this section, we will use NGINX&apos;s implementation of Gateway API referenced as NGINX Gateway Fabric as an example but the logic holds true mostly for other vendor implementations. There are a few components that make this work:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Custom Resource Definitions (CRDs): Kubernetes by default has a set of out of the box objects but can be extended with the use of Custom Resource Definitions (CRDs). In a nutshell, Gateway API is delivered as a set of CRDs extending the capability of Kubernetes to be able to manage the end-to-end lifecycle of third party objects which in our case are referencing the 3rd party NGINX Load Balancers.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;We need to install the vendor implementation i.e. the NGINX Gateway Fabric Pod and all its associated objects (Deployments, ReplicaSets, Service Account, ClusterRoleBindings..etc. A key piece to understand is that the NGINX Gateway Fabric Pod (NGF Pod) consists of two different containers: NGF and NGINX. You can think of NGF as a component that listens to API Server configuration changes pertaining to the 3 main objects within GatewayAPI (GatewayClass, Gateway, Routes here encompasses HTTPRoutes/TLSRoutes) and then programs the NGINX container accordingly. Thus, NGF acts as a translator between the API Server and the native NGINX container configuration. For more details on installation, you can refer to NGINX Gateway Fabric docs &lt;a target=&quot;_blank&quot; href=&quot;https://docs.nginx.com/nginx-gateway-fabric/installation/installing-ngf/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707758804817/c036ac67-d565-499c-9f47-c21903239214.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-scenarios&quot;&gt;Scenarios&lt;/h1&gt;&lt;h1 id=&quot;heading-simple-routing-configuration&quot;&gt;Simple Routing Configuration&lt;/h1&gt;&lt;h3 id=&quot;heading-traffic-flow&quot;&gt;Traffic Flow&lt;/h3&gt;&lt;p&gt;This is the simplest of all scenarios:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Client resolves the DNS name of the NLB to an IP address&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Traffic from the client goes towards the NLB&apos;s Public address to be DNATTed by the IGW.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;An important consideration to mention here is that this NLB is part of a Load Balancer service in AWS that instantiated this NLB and we use to provide Public Access to the Nginx Gateway Fabric Pod. More details on the NLB service can be found &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-loadbalancer-service&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;NGINX is configured via the HTTP Route to send all traffic destined to any path to the nginx service backend which in turn sends it to the NGINX pod. It is worth noting that the nginx service &amp;amp; pod are running NGINX web servers and could be any other workload for that purpose.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706666161224/d79e8127-97f5-4902-ab87-2204b0780b55.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-configuration-snippets&quot;&gt;Configuration Snippets&lt;/h3&gt;&lt;p&gt;It is important to understand that the route object references the Gateway and the Gateway references the GatewayClass. You can find the comments within each of the outputs.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;items:&lt;/span&gt;&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;GatewayClass&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/instance:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx-gateway&lt;/span&gt;       &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx-gateway&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/version:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;controllerName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.nginx.org/nginx-gateway-controller&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#this is a fixed domain set by the vendor and the path can vary specifically if you want to run multiple implementations&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;gatewayClassName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#tying the Gateway to the Class basically stating this is an NGINX Gateway. Similar to IngressClass&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;listeners:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;allowedRoutes:&lt;/span&gt;   &lt;span class=&quot;hljs-comment&quot;&gt;#By default we are only allowing Routes to use this GW if they come from the same namespace&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;    &lt;span class=&quot;hljs-comment&quot;&gt;#which in our case is the default namespace object for the gateway&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;from:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Same&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;http&lt;/span&gt;     &lt;span class=&quot;hljs-comment&quot;&gt;#Listening on TCP port 80 for HTTP. Can be locked down to particular domains also.&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTP&lt;/span&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;#Can be used to filter TLS Routes&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx-default&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;parentRefs:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#Tying the Route to the Gateway&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;backendRefs:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#Backend Service to send the traffic to&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Service&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;weight:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matches:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#Any traffic &lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PathPrefix&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In a nutshell the objects tie as follows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Route (HTTPRoute/TLSRoute) ties to the Gateway&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Gateway has an allowedRoutes which is like a filter on which routes to accept which by default allows routes within the same namespace as the Gateway Object but can be configured to allow routes from other namespaces. The Gateway on the other hand ties to the GatewayClass. On another note, Gateways leverage listeners as another method of filtering Routes i.e. if a gateway for instance listens for HTTP traffic, any TLS route will not be attached to the gateway. In addition, if the Gateway is listening to a particular hostname (*.acme.com) it will automatically ignore any routes that are not part of the ACME domain. The reason these filtering capabilities are important is because they set some regulations/boundaries on publishing applications that are agreed upon between the developers and infrastructure owners.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The GatewayClass ties to the Controller Name. You might want to make variations there when if you have a case where you need dual implementations of the NGINX Gateway Fabric for instance where one pod handles for example production workloads and the other handles development workloads.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;heading-leveraging-paths&quot;&gt;Leveraging Paths&lt;/h2&gt;&lt;h3 id=&quot;heading-traffic-flow-1&quot;&gt;Traffic Flow&lt;/h3&gt;&lt;p&gt;Following the same logic from the simple routing configuration but just noting the differences. NGINX is configured via the HTTP Route as follows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;When traffic matches /blue send traffic to the blue nginx deployment&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;When traffic matches /green send traffic to the green nginx deployment&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Again this example can become more advanced by listening to Host headers within the HTTP and then within these host headers we can use paths where the objective is to publish many applications behind the NGINX Proxy for an enterprise deployment. For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;App1: app1.acme.com and within you can have app1.acme.com/internal app1.acme.com/customer&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;App2: app2.acme.com and within you can have app2.acme.com/internal app2.acme.com/customer&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706666171429/54d556f0-5145-4acd-8837-ff1b6c680aad.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-configuration-snippets-1&quot;&gt;Configuration Snippets&lt;/h3&gt;&lt;p&gt;The difference in this scenario is that the HTTPRoute objects don&apos;t reside in the same namespace as the Gateway object thus we need to configure the gateway to allow routes in the blue and green namespaces to hook to it. This is done by the allowedRoutes block under the Gateway Object referencing a particular label for the namespace which in our example is &quot;access-gateway:true&quot; and ensuring that both namespaces blue and green have that label on. This step will ensure that the Gateway object residing in the default namespace will accept HTTPRoutes in the blue and green namespaces.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;items:&lt;/span&gt;&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#gateway object resides in the default namespace&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;gatewayClassName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;listeners:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;allowedRoutes:&lt;/span&gt;    &lt;span class=&quot;hljs-comment&quot;&gt;#In this scenario, the two services we expose &lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;     &lt;span class=&quot;hljs-comment&quot;&gt;#live in a different namespace thus we need to allow the HTTP routes&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;from:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Selector&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#in those namespaces to hook to the Gateway else they will be floating&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;selector:&lt;/span&gt;      &lt;span class=&quot;hljs-comment&quot;&gt;#this is done via labels on those namespaces that are accepted by the gateway object&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;access-gateway:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;true&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;http&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTP&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;NAME              STATUS   AGE     LABELSblue              Active   2d1h    access-gateway=true,kubernetes.io/metadata.name=bluegreen             Active   2d1h    access-gateway=true,kubernetes.io/metadata.name=green&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case the route is a bit different as we need to differentiate /blue and /green paths. We are not showing the green route for brevity.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;items:&lt;/span&gt;&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTPRoute&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue-nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;parentRefs:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;backendRefs:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Service&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue-nginx-deployment&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;weight:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;matches:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PathPrefix&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/blue&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to differentiate the NGINX web server deployments, this is a simple configmap that can be attached to the NGINX deployment so that NGINX in different namespaces will be easily distinguishable in your browser.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;data:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;nginx.conf:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|    server {    listen 80;    location / {        default_type text/html;        set $nginx_ip $server_addr;        set $client_ip $remote_addr;        return 200 &apos;&amp;lt;html&amp;gt;                      &amp;lt;head&amp;gt;                        &amp;lt;style&amp;gt;                          body {                            background-color: blue;                            color: white;                            font-size: 72px;                            display: flex;                            align-items: center;                            justify-content: center;                            height: 100vh;                            margin: 0;                          }                        &amp;lt;/style&amp;gt;                      &amp;lt;/head&amp;gt;                      &amp;lt;body&amp;gt;                        &amp;lt;div style=&quot;text-align: center;&quot;&amp;gt;                          &amp;lt;p&amp;gt;Server Name: Blue NGINX&amp;lt;/p&amp;gt;                          &amp;lt;p&amp;gt;Server IP Address: $nginx_ip&amp;lt;/p&amp;gt;                          &amp;lt;p&amp;gt;Client IP Address: $client_ip&amp;lt;/p&amp;gt;                        &amp;lt;/div&amp;gt;                      &amp;lt;/body&amp;gt;                    &amp;lt;/html&amp;gt;&apos;;                }        }&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ConfigMap&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue-nginx-config&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;heading-dual-ingress-implementation&quot;&gt;Dual Ingress Implementation&lt;/h2&gt;&lt;p&gt;In this setup, we extend the model by adding another implementation of the GatewayAPI from Kong where this time we have two ingress points to our Kubernetes Cluster one with the NGINX Gateway Fabric and the other from Kong and we publish some applications via NGINX and the others via Kong. The NGINX setup is left intact in this scenario.&lt;/p&gt;&lt;h3 id=&quot;heading-traffic-flow-2&quot;&gt;Traffic Flow&lt;/h3&gt;&lt;p&gt;For the echo service it will be accessible via Kong which in turn will have its own NLB for external access from outside the Kubernetes Cluster.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706666183292/7244e1df-c05d-4a4c-bdde-a4cef16570f7.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-configuration-snippets-2&quot;&gt;Configuration Snippets&lt;/h3&gt;&lt;p&gt;We will need to create the GatewayClass and Gateway for Kong similar to what we have done for the NGINX Fabric Controller. Note that the HTTPRoute has a reference to the Kong Gateway.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;GatewayClass&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;controllerName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;konghq.com/kic-gateway-controller&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#this is again a domain name specified by the vendor&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;gatewayClassName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;           &lt;span class=&quot;hljs-comment&quot;&gt;#by default we only allow routes from the same namespace (default)&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;listeners:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;allowedRoutes:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;from:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Same&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTP&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;annotations:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;konghq.com/strip-path:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;true&quot;&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;echo&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;parentRefs:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#referencing the Kong gateway&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;backendRefs:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Service&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;echo&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1027&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#this is the port the echo service is running on&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;weight:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matches:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PathPrefix&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/echo&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-references&quot;&gt;References:&lt;/h1&gt;&lt;p&gt;NGINX Gateway Fabric documentation: &lt;a target=&quot;_blank&quot; href=&quot;https://docs.nginx.com/nginx-gateway-fabric/&quot;&gt;https://docs.nginx.com/nginx-gateway-fabric/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Kong Documentation: &lt;a target=&quot;_blank&quot; href=&quot;https://docs.konghq.com/kubernetes-ingress-controller/3.0.x/gateway-api/&quot;&gt;https://docs.konghq.com/kubernetes-ingress-controller/3.0.x/gateway-api/&lt;/a&gt;&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;p&gt;So, we ended our &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-loadbalancer-service&quot;&gt;previous post&lt;/a&gt; talking about some of the downsides of the Load Balancer service in terms of security, manageability and increased costs. So this weekend, I set myself up to understand the Kubernetes Gateway API (not an API Gateway) which is a consolidated ingress solution to get traffic to your Kubernetes Clusters.&lt;/p&gt;&lt;p&gt;It&apos;s important to note the terminology here. Traditionally, Kubernetes users have been familiar with Ingress, the widely-used method for creating a single entry point to expose services within a cluster, primarily targeting HTTP/HTTPs workloads. However, there&apos;s a new player in town: the Gateway API.&lt;/p&gt;&lt;p&gt;While Ingress acts like a monolith, requiring modifications to a single object as more applications are exposed, the Gateway API takes a more versatile approach. It covers a broader spectrum of protocols, including HTTP, HTTPS, and gRPC. What sets it apart is not just the protocol support but also the improved role-based API, providing a more flexible and sophisticated means of managing ingress.&lt;/p&gt;&lt;h1 id=&quot;heading-role-based-api&quot;&gt;Role Based API&lt;/h1&gt;&lt;p&gt;ACME Corp has different roles that help manage their Kubernetes infrastructure and deploy their required applications and services on top.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Choosing the Provider: John handles the decision on which Infrastructure Providers to bring in and the high level settings of that provider. For instance, John favors the NGINX solution. For that matter John has to define the GatewayClass object which is a cluster scoped resource tied to the provider (NGINX). At a high level, this is John saying &quot;We will use NGINX as the platform of choice to handle Ingress Traffic.&quot; There might be cases for various reasons where multiple GatewayClasses (Infrastructure Providers) can be used simultaneously.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Configuring the Proxy: Karim handles the NGINX proxy configuration via the Gateway Object. It is important to think about the proxy or Load Balancer Instance as a shared resource across multiple teams, thus some settings will be common and defined under the Gateway Object whereas others will be configured under Routes (HTTPRoutes, TLSRoutes). Options defined under the Gateway are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Specifying the class of Gateway it belongs to (GatewayClass specified by John)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Specifying the hostname (acme.com), port, and protocol the proxy is listening to as well as TLS parameters.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Allowing particular routes to attach to the Load Balancer.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Route Configuration: Chris has a particular ticketing Application that he intends to publish. He would like to use the FQDN ticket.acme.com and as soon as this URI is seen, he would like this routed to the ClusterIP service within Kubernetes which in turn will target his application workloads. A deeper explanation on ClusterIP and how it works can be found &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-services&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;  Another advantage that the RoleBased API brings into the picture is a better RBAC implementation where each of those users or teams can gain access to the needed objects &amp;amp; thus sets better governance on publishing applications externally.&lt;/p&gt;&lt;p&gt;  The final advantage of Gateway API we will touch upon is portability i.e. the ability to switch implementation from one vendor to another without requiring change. Ingress on the other hand was heavily dependent on vendor specific annotations which made it harder to switch from one implementation to another.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706665749410/604d8504-a91d-4c28-8f31-6b10f79eee38.png&quot; alt=&quot;source: https://gateway-api.sigs.k8s.io/&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Source: &lt;a target=&quot;_blank&quot; href=&quot;https://gateway-api.sigs.k8s.io/&quot;&gt;https://gateway-api.sigs.k8s.io/&lt;/a&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-but-how-does-it-work&quot;&gt;But how does it Work?&lt;/h1&gt;&lt;p&gt;In this section, we will use NGINX&apos;s implementation of Gateway API referenced as NGINX Gateway Fabric as an example but the logic holds true mostly for other vendor implementations. There are a few components that make this work:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Custom Resource Definitions (CRDs): Kubernetes by default has a set of out of the box objects but can be extended with the use of Custom Resource Definitions (CRDs). In a nutshell, Gateway API is delivered as a set of CRDs extending the capability of Kubernetes to be able to manage the end-to-end lifecycle of third party objects which in our case are referencing the 3rd party NGINX Load Balancers.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;We need to install the vendor implementation i.e. the NGINX Gateway Fabric Pod and all its associated objects (Deployments, ReplicaSets, Service Account, ClusterRoleBindings..etc. A key piece to understand is that the NGINX Gateway Fabric Pod (NGF Pod) consists of two different containers: NGF and NGINX. You can think of NGF as a component that listens to API Server configuration changes pertaining to the 3 main objects within GatewayAPI (GatewayClass, Gateway, Routes here encompasses HTTPRoutes/TLSRoutes) and then programs the NGINX container accordingly. Thus, NGF acts as a translator between the API Server and the native NGINX container configuration. For more details on installation, you can refer to NGINX Gateway Fabric docs &lt;a target=&quot;_blank&quot; href=&quot;https://docs.nginx.com/nginx-gateway-fabric/installation/installing-ngf/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1707758804817/c036ac67-d565-499c-9f47-c21903239214.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-scenarios&quot;&gt;Scenarios&lt;/h1&gt;&lt;h1 id=&quot;heading-simple-routing-configuration&quot;&gt;Simple Routing Configuration&lt;/h1&gt;&lt;h3 id=&quot;heading-traffic-flow&quot;&gt;Traffic Flow&lt;/h3&gt;&lt;p&gt;This is the simplest of all scenarios:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Client resolves the DNS name of the NLB to an IP address&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Traffic from the client goes towards the NLB&apos;s Public address to be DNATTed by the IGW.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;An important consideration to mention here is that this NLB is part of a Load Balancer service in AWS that instantiated this NLB and we use to provide Public Access to the Nginx Gateway Fabric Pod. More details on the NLB service can be found &lt;a target=&quot;_blank&quot; href=&quot;https://jamali.hashnode.dev/kubernetes-loadbalancer-service&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;NGINX is configured via the HTTP Route to send all traffic destined to any path to the nginx service backend which in turn sends it to the NGINX pod. It is worth noting that the nginx service &amp;amp; pod are running NGINX web servers and could be any other workload for that purpose.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706666161224/d79e8127-97f5-4902-ab87-2204b0780b55.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-configuration-snippets&quot;&gt;Configuration Snippets&lt;/h3&gt;&lt;p&gt;It is important to understand that the route object references the Gateway and the Gateway references the GatewayClass. You can find the comments within each of the outputs.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;items:&lt;/span&gt;&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;GatewayClass&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/instance:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx-gateway&lt;/span&gt;       &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx-gateway&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;app.kubernetes.io/version:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;hljs-number&quot;&gt;.0&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;controllerName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.nginx.org/nginx-gateway-controller&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#this is a fixed domain set by the vendor and the path can vary specifically if you want to run multiple implementations&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;gatewayClassName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#tying the Gateway to the Class basically stating this is an NGINX Gateway. Similar to IngressClass&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;listeners:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;allowedRoutes:&lt;/span&gt;   &lt;span class=&quot;hljs-comment&quot;&gt;#By default we are only allowing Routes to use this GW if they come from the same namespace&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;    &lt;span class=&quot;hljs-comment&quot;&gt;#which in our case is the default namespace object for the gateway&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;from:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Same&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;http&lt;/span&gt;     &lt;span class=&quot;hljs-comment&quot;&gt;#Listening on TCP port 80 for HTTP. Can be locked down to particular domains also.&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTP&lt;/span&gt;  &lt;span class=&quot;hljs-comment&quot;&gt;#Can be used to filter TLS Routes&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx-default&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;parentRefs:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#Tying the Route to the Gateway&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;backendRefs:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#Backend Service to send the traffic to&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Service&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;weight:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matches:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#Any traffic &lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PathPrefix&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In a nutshell the objects tie as follows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Route (HTTPRoute/TLSRoute) ties to the Gateway&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Gateway has an allowedRoutes which is like a filter on which routes to accept which by default allows routes within the same namespace as the Gateway Object but can be configured to allow routes from other namespaces. The Gateway on the other hand ties to the GatewayClass. On another note, Gateways leverage listeners as another method of filtering Routes i.e. if a gateway for instance listens for HTTP traffic, any TLS route will not be attached to the gateway. In addition, if the Gateway is listening to a particular hostname (*.acme.com) it will automatically ignore any routes that are not part of the ACME domain. The reason these filtering capabilities are important is because they set some regulations/boundaries on publishing applications that are agreed upon between the developers and infrastructure owners.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The GatewayClass ties to the Controller Name. You might want to make variations there when if you have a case where you need dual implementations of the NGINX Gateway Fabric for instance where one pod handles for example production workloads and the other handles development workloads.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;heading-leveraging-paths&quot;&gt;Leveraging Paths&lt;/h2&gt;&lt;h3 id=&quot;heading-traffic-flow-1&quot;&gt;Traffic Flow&lt;/h3&gt;&lt;p&gt;Following the same logic from the simple routing configuration but just noting the differences. NGINX is configured via the HTTP Route as follows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;When traffic matches /blue send traffic to the blue nginx deployment&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;When traffic matches /green send traffic to the green nginx deployment&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Again this example can become more advanced by listening to Host headers within the HTTP and then within these host headers we can use paths where the objective is to publish many applications behind the NGINX Proxy for an enterprise deployment. For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;App1: app1.acme.com and within you can have app1.acme.com/internal app1.acme.com/customer&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;App2: app2.acme.com and within you can have app2.acme.com/internal app2.acme.com/customer&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706666171429/54d556f0-5145-4acd-8837-ff1b6c680aad.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-configuration-snippets-1&quot;&gt;Configuration Snippets&lt;/h3&gt;&lt;p&gt;The difference in this scenario is that the HTTPRoute objects don&apos;t reside in the same namespace as the Gateway object thus we need to configure the gateway to allow routes in the blue and green namespaces to hook to it. This is done by the allowedRoutes block under the Gateway Object referencing a particular label for the namespace which in our example is &quot;access-gateway:true&quot; and ensuring that both namespaces blue and green have that label on. This step will ensure that the Gateway object residing in the default namespace will accept HTTPRoutes in the blue and green namespaces.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;items:&lt;/span&gt;&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#gateway object resides in the default namespace&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;gatewayClassName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;listeners:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;allowedRoutes:&lt;/span&gt;    &lt;span class=&quot;hljs-comment&quot;&gt;#In this scenario, the two services we expose &lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;     &lt;span class=&quot;hljs-comment&quot;&gt;#live in a different namespace thus we need to allow the HTTP routes&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;from:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Selector&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#in those namespaces to hook to the Gateway else they will be floating&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;selector:&lt;/span&gt;      &lt;span class=&quot;hljs-comment&quot;&gt;#this is done via labels on those namespaces that are accepted by the gateway object&lt;/span&gt;            &lt;span class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;              &lt;span class=&quot;hljs-attr&quot;&gt;access-gateway:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;true&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;http&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTP&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;NAME              STATUS   AGE     LABELSblue              Active   2d1h    access-gateway=true,kubernetes.io/metadata.name=bluegreen             Active   2d1h    access-gateway=true,kubernetes.io/metadata.name=green&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this case the route is a bit different as we need to differentiate /blue and /green paths. We are not showing the green route for brevity.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;items:&lt;/span&gt;&lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTPRoute&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue-nginx&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;parentRefs:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;mygateway&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;backendRefs:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Service&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue-nginx-deployment&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;weight:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;matches:&lt;/span&gt;      &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PathPrefix&lt;/span&gt;          &lt;span class=&quot;hljs-attr&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/blue&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to differentiate the NGINX web server deployments, this is a simple configmap that can be attached to the NGINX deployment so that NGINX in different namespaces will be easily distinguishable in your browser.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;data:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;nginx.conf:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;|    server {    listen 80;    location / {        default_type text/html;        set $nginx_ip $server_addr;        set $client_ip $remote_addr;        return 200 &apos;&amp;lt;html&amp;gt;                      &amp;lt;head&amp;gt;                        &amp;lt;style&amp;gt;                          body {                            background-color: blue;                            color: white;                            font-size: 72px;                            display: flex;                            align-items: center;                            justify-content: center;                            height: 100vh;                            margin: 0;                          }                        &amp;lt;/style&amp;gt;                      &amp;lt;/head&amp;gt;                      &amp;lt;body&amp;gt;                        &amp;lt;div style=&quot;text-align: center;&quot;&amp;gt;                          &amp;lt;p&amp;gt;Server Name: Blue NGINX&amp;lt;/p&amp;gt;                          &amp;lt;p&amp;gt;Server IP Address: $nginx_ip&amp;lt;/p&amp;gt;                          &amp;lt;p&amp;gt;Client IP Address: $client_ip&amp;lt;/p&amp;gt;                        &amp;lt;/div&amp;gt;                      &amp;lt;/body&amp;gt;                    &amp;lt;/html&amp;gt;&apos;;                }        }&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;ConfigMap&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue-nginx-config&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;blue&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;heading-dual-ingress-implementation&quot;&gt;Dual Ingress Implementation&lt;/h2&gt;&lt;p&gt;In this setup, we extend the model by adding another implementation of the GatewayAPI from Kong where this time we have two ingress points to our Kubernetes Cluster one with the NGINX Gateway Fabric and the other from Kong and we publish some applications via NGINX and the others via Kong. The NGINX setup is left intact in this scenario.&lt;/p&gt;&lt;h3 id=&quot;heading-traffic-flow-2&quot;&gt;Traffic Flow&lt;/h3&gt;&lt;p&gt;For the echo service it will be accessible via Kong which in turn will have its own NLB for external access from outside the Kubernetes Cluster.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706666183292/7244e1df-c05d-4a4c-bdde-a4cef16570f7.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-configuration-snippets-2&quot;&gt;Configuration Snippets&lt;/h3&gt;&lt;p&gt;We will need to create the GatewayClass and Gateway for Kong similar to what we have done for the NGINX Fabric Controller. Note that the HTTPRoute has a reference to the Kong Gateway.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;GatewayClass&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;controllerName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;konghq.com/kic-gateway-controller&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#this is again a domain name specified by the vendor&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;gatewayClassName:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;           &lt;span class=&quot;hljs-comment&quot;&gt;#by default we only allow routes from the same namespace (default)&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;listeners:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;allowedRoutes:&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;namespaces:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;from:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Same&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;proxy&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;80&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;protocol:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTP&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-yaml&quot;&gt;&lt;span class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;HTTPRoute&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;annotations:&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;konghq.com/strip-path:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;true&quot;&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;echo&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;namespace:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;parentRefs:&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#referencing the Kong gateway&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;gateway.networking.k8s.io&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Gateway&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;kong&lt;/span&gt;  &lt;span class=&quot;hljs-attr&quot;&gt;rules:&lt;/span&gt;  &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;backendRefs:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;group:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&quot;&quot;&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;Service&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;echo&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;port:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1027&lt;/span&gt; &lt;span class=&quot;hljs-comment&quot;&gt;#this is the port the echo service is running on&lt;/span&gt;      &lt;span class=&quot;hljs-attr&quot;&gt;weight:&lt;/span&gt; &lt;span class=&quot;hljs-number&quot;&gt;1&lt;/span&gt;    &lt;span class=&quot;hljs-attr&quot;&gt;matches:&lt;/span&gt;    &lt;span class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;hljs-attr&quot;&gt;path:&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;type:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;PathPrefix&lt;/span&gt;        &lt;span class=&quot;hljs-attr&quot;&gt;value:&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;/echo&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-references&quot;&gt;References:&lt;/h1&gt;&lt;p&gt;NGINX Gateway Fabric documentation: &lt;a target=&quot;_blank&quot; href=&quot;https://docs.nginx.com/nginx-gateway-fabric/&quot;&gt;https://docs.nginx.com/nginx-gateway-fabric/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Kong Documentation: &lt;a target=&quot;_blank&quot; href=&quot;https://docs.konghq.com/kubernetes-ingress-controller/3.0.x/gateway-api/&quot;&gt;https://docs.konghq.com/kubernetes-ingress-controller/3.0.x/gateway-api/&lt;/a&gt;&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1707765153881/f049b5c6-4855-42a9-8208-330c17021e90.png</hashnode:coverImage></item><item><title><![CDATA[Kubernetes Services: NodePort & LoadBalancer]]></title><description><![CDATA[Explains the concepts for Kubernetes NodePort and Load Balancer Service across AWS, Azure, GCP & on-prem environments]]></description><link>https://jamali.hashnode.dev/kubernetes-loadbalancer-service</link><guid isPermaLink="true">https://jamali.hashnode.dev/kubernetes-loadbalancer-service</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[#kubernetes #container ]]></category><category><![CDATA[network security]]></category><category><![CDATA[AWS]]></category><category><![CDATA[aws-eks]]></category><category><![CDATA[networking]]></category><category><![CDATA[GCP]]></category><category><![CDATA[Azure]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Sat, 27 Jan 2024 02:47:42 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h1 id=&quot;heading-introduction&quot;&gt;Introduction&lt;/h1&gt;&lt;p&gt;In the last blog post found &lt;a target=&quot;_blank&quot; href=&quot;https://hashnode.com/edit/clrb2nziy000909jwf6k798zk&quot;&gt;here&lt;/a&gt;, we focused on the inner workings of Kubernetes ClusterIP service. Kubernetes ClusterIP exposes pods within a Kubernetes Cluster. In this blog post, we focus on exposing Pods to clients and services outside the Kubernetes Cluster focusing on two service types Kubernetes NodePort &amp;amp; Kubernetes Load Balancer services.&lt;/p&gt;&lt;p&gt;It is worth noting that the scenarios we will discuss in this post have been built on AWS however the same concepts &amp;amp; logic should follow for other environments.&lt;/p&gt;&lt;h1 id=&quot;heading-kubernetes-nodeport&quot;&gt;Kubernetes NodePort&lt;/h1&gt;&lt;p&gt;The simplest way to expose a service externally is by using the NodePort service whereby all the nodes listen by default on a TCP port in the range 30000-32767.&lt;/p&gt;&lt;p&gt;The flow works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;The source being the client sends the request to an Elastic IP address (In this example we are assuming 1.1.1.1 &amp;amp; 1.1.1.2 corresponding to worker nodes 1 &amp;amp; 2).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The IGW will do a static NAT translating those Public addresses to their corresponding private addresses. We are assuming in the figure that traffic will hit Worker Node 1 thus the source remains to be the Client and the destination becomes eth0&apos;s address on Worker Node 1 (192.168.45.167).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Based on the NodePort service configuration, the port the node is listening to is 30730 thus when traffic hits worker node 1 on port 30730, this will be DNATTed to the nginx-node-port address (192.168.22.71).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For traffic to return in the same path, an SNAT also occurs changing the source address from the Client to Worker Node 1&apos;s eth0 address (192.168.45.167).&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706118818380/b14ad7b5-0571-41e5-a299-eee63927228e.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;It is also worth noting that a NodePort service also creates a ClusterIP that can be accessible within the Kubernetes Cluster which is depicted as 10.100.199.193 in the figure below.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;Name:                     nginx-node-portNamespace:                defaultLabels:                   run=nginx-node-portAnnotations:              &amp;lt;none&amp;gt;Selector:                 run=nginx-node-portType:                     NodePortIP Family Policy:         SingleStackIP Families:              IPv4IP:                       10.100.199.193IPs:                      10.100.199.193Port:                     &amp;lt;unset&amp;gt;  80/TCPTargetPort:               80/TCPNodePort:                 &amp;lt;unset&amp;gt;  30730/TCPEndpoints:                192.168.22.71:80Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   &amp;lt;none&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;heading-iptables-inner-workings&quot;&gt;IPTables Inner Workings&lt;/h2&gt;&lt;p&gt;In this section, we&apos;ll explore the IPTable inner workings that govern the functionality of a NodePort Service in a Kubernetes cluster.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PREROUTING Chain:&lt;/strong&gt; Our journey begins with the PREROUTING chain, which directs us towards the KUBE-SERVICES chain.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SERVICES:&lt;/strong&gt; Within KUBE-SERVICES, the policy KUBE-SVC-3KJW6L7XGSFMVIPO is instantiated as a ClusterIP. This does not impact traffic from outside the cluster.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-NODEPORTS:&lt;/strong&gt; Next, we reach KUBE-NODEPORTS, where the first rule, matches traffic to tcp with a destination port of 30730 redirecting us to KUBE-EXT-3KJW6L7XGSFMVIPO which in turn redirects us to &lt;strong&gt;KUBE-SVC-3KJW6L7XGSFMVIPO&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SVC-3KJW6L7XGSFMVIPO:&lt;/strong&gt; This redirects us to KUBE-SEP-KS7GFULRFICP7QTF.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SEP-KS7GFULRFICP7QTF:&lt;/strong&gt; Here, a DNAT rule performs destination NAT to the Pod address 192.168.22.71.&lt;/p&gt;&lt;p&gt;For those interested in the SNAT for the reverse direction, you can find its details below following this pattern:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;KUBE-POSTROUTING&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AWS-SNAT-CHAIN-0&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AWS-SNAT-CHAIN-1 SNAT takes place with an address of &lt;strong&gt;192.168.26.112&lt;/strong&gt;. Note that this IPTables output is extracted from Worker Node 2 and represents eth0&apos;s address.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;[ec2-user@ip-192-168-26-112 ~]$ sudo iptables -t nat -vLChain PREROUTING (policy ACCEPT 36 packets, 2160 bytes) pkts bytes target     prot opt in     out     source               destination          2208  147K KUBE-SERVICES  all  --  any    any     anywhere             anywhere             /* kubernetes service portals */ Chain KUBE-SERVICES (2 references) pkts bytes target     prot opt in     out     source               destination             0     0 KUBE-SVC-3KJW6L7XGSFMVIPO  tcp  --  any    any     anywhere             ip-10-100-199-193.ec2.internal  /* default/nginx-node-port cluster IP */ tcp dpt:http   52  3120 KUBE-NODEPORTS  all  --  any    any     anywhere             anywhere             /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCALChain KUBE-NODEPORTS (1 references)pkts bytes target     prot opt in     out     source               destination            0     0 KUBE-EXT-3KJW6L7XGSFMVIPO  tcp  --  any    any     anywhere             anywhere             /* default/nginx-node-port */ tcp dpt:30730Chain KUBE-EXT-3KJW6L7XGSFMVIPO (1 references)pkts bytes target     prot opt in     out     source               destination            0     0 KUBE-MARK-MASQ  all  --  any    any     anywhere             anywhere             /* masquerade traffic for default/nginx-node-port external destinations */   0     0 KUBE-SVC-3KJW6L7XGSFMVIPO  all  --  any    any     anywhere             anywhere            Chain KUBE-SVC-3KJW6L7XGSFMVIPO (2 references)pkts bytes target     prot opt in     out     source               destination            0     0 KUBE-SEP-KS7GFULRFICP7QTF  all  --  any    any     anywhere             anywhere             /* default/nginx-node-port -&amp;gt; 192.168.22.71:80 */Chain KUBE-SEP-KS7GFULRFICP7QTF (1 references) pkts bytes target     prot opt in     out     source               destination             0     0 KUBE-MARK-MASQ  all  --  any    any     ip-192-168-22-71.ec2.internal  anywhere             /* default/nginx-node-port */    0     0 DNAT       tcp  --  any    any     anywhere             anywhere             /* default/nginx-node-port */ tcp to:192.168.22.71:80Chain POSTROUTING (policy ACCEPT 246 packets, 16109 bytes)pkts bytes target     prot opt in     out     source               destination         82418 5146K KUBE-POSTROUTING  all  --  any    any     anywhere             anywhere             /* kubernetes postrouting rules */81338 5079K AWS-SNAT-CHAIN-0  all  --  any    any     anywhere             anywhere             /* AWS SNAT CHAIN */Chain AWS-SNAT-CHAIN-0 (1 references)pkts bytes target     prot opt in     out     source               destination         59065 3589K AWS-SNAT-CHAIN-1  all  --  any    any     anywhere            !ip-192-168-0-0.ec2.internal/16  /* AWS SNAT CHAIN */Chain AWS-SNAT-CHAIN-1 (1 references)pkts bytes target     prot opt in     out     source               destination         51947 3162K SNAT       all  --  any    !vlan+  anywhere             anywhere             /* AWS, SNAT */ ADDRTYPE match dst-type !LOCAL to:192.168.26.112 random-fully&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-kubernetes-load-balancer-service&quot;&gt;Kubernetes Load Balancer Service&lt;/h1&gt;&lt;h2 id=&quot;heading-load-balancer-provisioning&quot;&gt;Load Balancer Provisioning&lt;/h2&gt;&lt;p&gt;Load Balancer Service is another type of Kubernetes Service whereby we orchestrate Load Balancers that are outside the Kubernetes Cluster and have them serve as ingress points to a group of pods within our Kubernetes Cluster.&lt;/p&gt;&lt;p&gt;This generally requires a controller (Pod) that listens to all Kubernetes API Server activities that involve Kubernetes Load Balancer service. When the controller sees a service of type load balancer created, it creates an external Load Balancer that is mapped to that service. In AWS, this is depicted by the AWS Load Balancer Controller that also needs to have IAM permissions to create the Load Balancers within AWS.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706129319084/684ecfa4-eb18-41ce-b27a-161915af70ed.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The below are logs taken from the AWS Load Balancer controller pod and show that the controller is creating resources such as Load Balancers, Target Groups and Listeners which are again objects pertaining to Load Balancers in AWS. Please note that other Cloud Providers have similar functionality in terms of controllers that can orchestrate their Load Balancer offerings.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;[cloudshell-user@ip-10-138-162-38 ~]$ kubectl logs -n kube-system aws-load-balancer-controller-5749768698-8jslx{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:55Z&quot;,&quot;msg&quot;:&quot;setting service loadBalancerClass&quot;,&quot;service&quot;:&quot;nginx1&quot;,&quot;loadBalancerClass&quot;:&quot;service.k8s.aws/nlb&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:55Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;successfully built model&quot;,&quot;model&quot;:&quot;{\&quot;id\&quot;:\&quot;default/nginx1\&quot;,\&quot;resources\&quot;:{\&quot;AWS::ElasticLoadBalancingV2::Listener\&quot;:{\&quot;80\&quot;:{\&quot;spec\&quot;:{\&quot;loadBalancerARN\&quot;:{\&quot;$ref\&quot;:\&quot;#/resources/AWS::ElasticLoadBalancingV2::LoadBalancer/LoadBalancer/status/loadBalancerARN\&quot;},\&quot;port\&quot;:80,\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;defaultActions\&quot;:[{\&quot;type\&quot;:\&quot;forward\&quot;,\&quot;forwardConfig\&quot;:{\&quot;targetGroups\&quot;:[{\&quot;targetGroupARN\&quot;:{\&quot;$ref\&quot;:\&quot;#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/default/nginx1:80/status/targetGroupARN\&quot;}}]}}]}}},\&quot;AWS::ElasticLoadBalancingV2::LoadBalancer\&quot;:{\&quot;LoadBalancer\&quot;:{\&quot;spec\&quot;:{\&quot;name\&quot;:\&quot;k8s-default-nginx1-36dbca87e3\&quot;,\&quot;type\&quot;:\&quot;network\&quot;,\&quot;scheme\&quot;:\&quot;internet-facing\&quot;,\&quot;ipAddressType\&quot;:\&quot;ipv4\&quot;,\&quot;subnetMapping\&quot;:[{\&quot;subnetID\&quot;:\&quot;subnet-0bb01040718d4acb6\&quot;},{\&quot;subnetID\&quot;:\&quot;subnet-0c11a935b51724fa2\&quot;}]}}},\&quot;AWS::ElasticLoadBalancingV2::TargetGroup\&quot;:{\&quot;default/nginx1:80\&quot;:{\&quot;spec\&quot;:{\&quot;name\&quot;:\&quot;k8s-default-nginx1-25a492f569\&quot;,\&quot;targetType\&quot;:\&quot;ip\&quot;,\&quot;port\&quot;:80,\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;ipAddressType\&quot;:\&quot;ipv4\&quot;,\&quot;healthCheckConfig\&quot;:{\&quot;port\&quot;:\&quot;traffic-port\&quot;,\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;intervalSeconds\&quot;:10,\&quot;timeoutSeconds\&quot;:10,\&quot;healthyThresholdCount\&quot;:3,\&quot;unhealthyThresholdCount\&quot;:3},\&quot;targetGroupAttributes\&quot;:[{\&quot;key\&quot;:\&quot;proxy_protocol_v2.enabled\&quot;,\&quot;value\&quot;:\&quot;false\&quot;}]}}},\&quot;K8S::ElasticLoadBalancingV2::TargetGroupBinding\&quot;:{\&quot;default/nginx1:80\&quot;:{\&quot;spec\&quot;:{\&quot;template\&quot;:{\&quot;metadata\&quot;:{\&quot;name\&quot;:\&quot;k8s-default-nginx1-25a492f569\&quot;,\&quot;namespace\&quot;:\&quot;default\&quot;,\&quot;creationTimestamp\&quot;:null},\&quot;spec\&quot;:{\&quot;targetGroupARN\&quot;:{\&quot;$ref\&quot;:\&quot;#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/default/nginx1:80/status/targetGroupARN\&quot;},\&quot;targetType\&quot;:\&quot;ip\&quot;,\&quot;serviceRef\&quot;:{\&quot;name\&quot;:\&quot;nginx1\&quot;,\&quot;port\&quot;:80},\&quot;networking\&quot;:{\&quot;ingress\&quot;:[{\&quot;from\&quot;:[{\&quot;ipBlock\&quot;:{\&quot;cidr\&quot;:\&quot;192.168.0.0/19\&quot;}},{\&quot;ipBlock\&quot;:{\&quot;cidr\&quot;:\&quot;192.168.32.0/19\&quot;}}],\&quot;ports\&quot;:[{\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;port\&quot;:80}]}]},\&quot;ipAddressType\&quot;:\&quot;ipv4\&quot;}}}}}}}&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:56Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating targetGroup&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:56Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created targetGroup&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:targetgroup/k8s-default-nginx1-25a492f569/ad12b7f6eaf1ee7d&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:56Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating loadBalancer&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;LoadBalancer&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created loadBalancer&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;LoadBalancer&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:loadbalancer/net/k8s-default-nginx1-36dbca87e3/7ff79bdbac47fb35&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating listener&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;80&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created listener&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;80&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:listener/net/k8s-default-nginx1-36dbca87e3/7ff79bdbac47fb35/ead861bf3e4bcbb5&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating targetGroupBinding&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created targetGroupBinding&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;,&quot;targetGroupBinding&quot;:{&quot;namespace&quot;:&quot;default&quot;,&quot;name&quot;:&quot;k8s-default-nginx1-25a492f569&quot;}}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;successfully deployed model&quot;,&quot;service&quot;:{&quot;namespace&quot;:&quot;default&quot;,&quot;name&quot;:&quot;nginx1&quot;}}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;msg&quot;:&quot;authorizing securityGroup ingress&quot;,&quot;securityGroupID&quot;:&quot;sg-02cd536f30a36abed&quot;,&quot;permission&quot;:[{&quot;FromPort&quot;:80,&quot;IpProtocol&quot;:&quot;tcp&quot;,&quot;IpRanges&quot;:[{&quot;CidrIp&quot;:&quot;192.168.0.0/19&quot;,&quot;Description&quot;:&quot;elbv2.k8s.aws/targetGroupBinding=shared&quot;}],&quot;Ipv6Ranges&quot;:null,&quot;PrefixListIds&quot;:null,&quot;ToPort&quot;:80,&quot;UserIdGroupPairs&quot;:null},{&quot;FromPort&quot;:80,&quot;IpProtocol&quot;:&quot;tcp&quot;,&quot;IpRanges&quot;:[{&quot;CidrIp&quot;:&quot;192.168.32.0/19&quot;,&quot;Description&quot;:&quot;elbv2.k8s.aws/targetGroupBinding=shared&quot;}],&quot;Ipv6Ranges&quot;:null,&quot;PrefixListIds&quot;:null,&quot;ToPort&quot;:80,&quot;UserIdGroupPairs&quot;:null}]}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;msg&quot;:&quot;authorized securityGroup ingress&quot;,&quot;securityGroupID&quot;:&quot;sg-02cd536f30a36abed&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:58Z&quot;,&quot;msg&quot;:&quot;registering targets&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:targetgroup/k8s-default-nginx1-25a492f569/ad12b7f6eaf1ee7d&quot;,&quot;targets&quot;:[{&quot;AvailabilityZone&quot;:null,&quot;Id&quot;:&quot;192.168.39.147&quot;,&quot;Port&quot;:80}]}&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;heading-instance-target&quot;&gt;Instance Target&lt;/h2&gt;&lt;p&gt;For Instance Target, we are configuring the Network Load Balancer to send the traffic to one of the two worker nodes which again have a NodePort configuration by which they listen to port 31729 in our example.&lt;/p&gt;&lt;p&gt;Thus, the follow works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;The client resolves the FQDN name of the Network Load Balancer. Note that NLBs are generally implemented across Availability Zones for redundancy. As soon as we resolve the NLB&apos;s FQDN, the client will sends the packet towards one of the two NLBs Public address&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Internet Gateway at the edge of the VPC does a static 1:1 NAT changing the Public address of the chosen NLB to the private address 192.168.41.233 (Left NLB)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The left NLB has two targets which are the eth0 of Worker Nodes 1 &amp;amp; 2 that are both listening on TCP Port 31729. In our example, we assume the traffic goes to Worker Node 1. Thus till this point the source is the client IP and the destination is Worker Node 1&apos;s eth0 192.168.45.167.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that the packet has hit Worker Node#1, again similar to the behavior we have seen with NodePort, a DNAT will occur translating the destination tot he Pod address 192.168.22.71 and an SNAT will change the client address to 192.168.45.167.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706119287096/2952d92b-b55e-421e-9252-7cd051ff3d7f.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;The way we can tune the NLB&apos;s behavior is via Annotations set on the service, specifically the setting:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;service.beta.kubernetes.io/aws-load-balancer-nlb-target-type&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;Name:                     nginx1Namespace:                defaultLabels:                   run=nginx1Annotations:              service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance                          service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing                          service.beta.kubernetes.io/aws-load-balancer-type: externalSelector:                 run=nginx1Type:                     LoadBalancerIP Family Policy:         SingleStackIP Families:              IPv4IP:                       10.100.69.226IPs:                      10.100.69.226LoadBalancer Ingress:     k8s-default-nginx1-36dbca87e3-7ff79bdbac47fb35.elb.us-east-1.amazonaws.comPort:                     &amp;lt;unset&amp;gt;  80/TCPTargetPort:               80/TCPNodePort:                 &amp;lt;unset&amp;gt;  31729/TCPEndpoints:                192.168.39.147:80Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   &amp;lt;none&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the figures below, we can also see the AWS outputs showing that the targets are the two worker node instances and the NodePort configured is 31729.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706127357109/4737d15f-982c-42b0-80d4-6de43e64ee4a.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706127346034/629e6cb5-436f-42b5-a9e1-2ef6d2c7090b.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The two images here show packet captures from both the Node &amp;amp; Pod perspective where the Node actually sees the client IP (Public Address) in this example and the Pod sees the Node IPs as the source 192.168.45.167 &amp;amp; 192.168.26.112.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191459108/153ae61c-801b-4d64-837f-83a45a0c09d8.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191505064/b2da2591-7bd6-4735-9d13-b7c12a85552b.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-ip-target&quot;&gt;IP Target&lt;/h2&gt;&lt;p&gt;This is again another iteration of configuring the NLB whereby in this mode, the NLB directly sends the packet to the Pod instead of sending it to the Node. This is possible in our example because we are using the AWS VPC CNI whereby a Pod behaves just like a VM in the sense that it gets an IP address from the VPC range &amp;amp; thus can be reached directly from components within the VPC.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706127176864/3eeb5a8d-ed6f-4227-9726-526137493b50.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;This is again possible by setting the below annotation.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;Name:                     nginx1Namespace:                defaultLabels:                   run=nginx1Annotations:              service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip                          service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing                          service.beta.kubernetes.io/aws-load-balancer-type: externalSelector:                 run=nginx1Type:                     LoadBalancerIP Family Policy:         SingleStackIP Families:              IPv4IP:                       10.100.69.226IPs:                      10.100.69.226LoadBalancer Ingress:     k8s-default-nginx1-36dbca87e3-7ff79bdbac47fb35.elb.us-east-1.amazonaws.comPort:                     &amp;lt;unset&amp;gt;  80/TCPTargetPort:               80/TCPNodePort:                 &amp;lt;unset&amp;gt;  31729/TCPEndpoints:                192.168.39.147:80Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   &amp;lt;none&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similar to what we have seen above, this is the AWS output showing the target being the Pod Address 192.168.39.147.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706136938877/b988efd7-95dc-4812-90b8-c4f9140f55be.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Again, here we show the packet captures on both the Node and the Pod. Notice that even the Node sees the traffic as sourced from the LB and destined to the Pod IP thus there is no need for NodePort treatment at the Worker Nodes.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191579595/bb04bc9e-6ff1-4389-8efe-c51ed704d40b.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191585265/e261d12b-bb55-46cc-9d20-2f4fa6a4d9ea.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-drawbacks-of-load-balancer-service&quot;&gt;Drawbacks of Load Balancer Service&lt;/h1&gt;&lt;p&gt;The main drawback of the Load Balancer Service is a 1:1 mapping between the Load Balancer and the service (group of pods) that you want to expose. This has multiple implications including increased costs, more management overhead, public addresses, and the need to secure all the Load Balancers with WAF, API Security, Anti-DDoS solutions. If one of these services goes uncovered or unprotected there could be security breaches leading to major losses.&lt;/p&gt;&lt;p&gt;The diagram below explains the problem where for each service, the AWS LB Controller will instantiate an NLB.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706137013289/133fe9b0-30da-46f8-a9b7-88ab3ce85164.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The below diagram emphasizes the same challenge whereby we can see our Kubernetes Cluster (here depicted as a single node) and all the different entry points that map to the different services.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706137083949/5fb990fe-5be9-4ba2-8026-759e278875a4.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h1 id=&quot;heading-introduction&quot;&gt;Introduction&lt;/h1&gt;&lt;p&gt;In the last blog post found &lt;a target=&quot;_blank&quot; href=&quot;https://hashnode.com/edit/clrb2nziy000909jwf6k798zk&quot;&gt;here&lt;/a&gt;, we focused on the inner workings of Kubernetes ClusterIP service. Kubernetes ClusterIP exposes pods within a Kubernetes Cluster. In this blog post, we focus on exposing Pods to clients and services outside the Kubernetes Cluster focusing on two service types Kubernetes NodePort &amp;amp; Kubernetes Load Balancer services.&lt;/p&gt;&lt;p&gt;It is worth noting that the scenarios we will discuss in this post have been built on AWS however the same concepts &amp;amp; logic should follow for other environments.&lt;/p&gt;&lt;h1 id=&quot;heading-kubernetes-nodeport&quot;&gt;Kubernetes NodePort&lt;/h1&gt;&lt;p&gt;The simplest way to expose a service externally is by using the NodePort service whereby all the nodes listen by default on a TCP port in the range 30000-32767.&lt;/p&gt;&lt;p&gt;The flow works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;The source being the client sends the request to an Elastic IP address (In this example we are assuming 1.1.1.1 &amp;amp; 1.1.1.2 corresponding to worker nodes 1 &amp;amp; 2).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The IGW will do a static NAT translating those Public addresses to their corresponding private addresses. We are assuming in the figure that traffic will hit Worker Node 1 thus the source remains to be the Client and the destination becomes eth0&apos;s address on Worker Node 1 (192.168.45.167).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Based on the NodePort service configuration, the port the node is listening to is 30730 thus when traffic hits worker node 1 on port 30730, this will be DNATTed to the nginx-node-port address (192.168.22.71).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;For traffic to return in the same path, an SNAT also occurs changing the source address from the Client to Worker Node 1&apos;s eth0 address (192.168.45.167).&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706118818380/b14ad7b5-0571-41e5-a299-eee63927228e.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;It is also worth noting that a NodePort service also creates a ClusterIP that can be accessible within the Kubernetes Cluster which is depicted as 10.100.199.193 in the figure below.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;Name:                     nginx-node-portNamespace:                defaultLabels:                   run=nginx-node-portAnnotations:              &amp;lt;none&amp;gt;Selector:                 run=nginx-node-portType:                     NodePortIP Family Policy:         SingleStackIP Families:              IPv4IP:                       10.100.199.193IPs:                      10.100.199.193Port:                     &amp;lt;unset&amp;gt;  80/TCPTargetPort:               80/TCPNodePort:                 &amp;lt;unset&amp;gt;  30730/TCPEndpoints:                192.168.22.71:80Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   &amp;lt;none&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;heading-iptables-inner-workings&quot;&gt;IPTables Inner Workings&lt;/h2&gt;&lt;p&gt;In this section, we&apos;ll explore the IPTable inner workings that govern the functionality of a NodePort Service in a Kubernetes cluster.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PREROUTING Chain:&lt;/strong&gt; Our journey begins with the PREROUTING chain, which directs us towards the KUBE-SERVICES chain.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SERVICES:&lt;/strong&gt; Within KUBE-SERVICES, the policy KUBE-SVC-3KJW6L7XGSFMVIPO is instantiated as a ClusterIP. This does not impact traffic from outside the cluster.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-NODEPORTS:&lt;/strong&gt; Next, we reach KUBE-NODEPORTS, where the first rule, matches traffic to tcp with a destination port of 30730 redirecting us to KUBE-EXT-3KJW6L7XGSFMVIPO which in turn redirects us to &lt;strong&gt;KUBE-SVC-3KJW6L7XGSFMVIPO&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SVC-3KJW6L7XGSFMVIPO:&lt;/strong&gt; This redirects us to KUBE-SEP-KS7GFULRFICP7QTF.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SEP-KS7GFULRFICP7QTF:&lt;/strong&gt; Here, a DNAT rule performs destination NAT to the Pod address 192.168.22.71.&lt;/p&gt;&lt;p&gt;For those interested in the SNAT for the reverse direction, you can find its details below following this pattern:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;KUBE-POSTROUTING&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AWS-SNAT-CHAIN-0&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;AWS-SNAT-CHAIN-1 SNAT takes place with an address of &lt;strong&gt;192.168.26.112&lt;/strong&gt;. Note that this IPTables output is extracted from Worker Node 2 and represents eth0&apos;s address.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;[ec2-user@ip-192-168-26-112 ~]$ sudo iptables -t nat -vLChain PREROUTING (policy ACCEPT 36 packets, 2160 bytes) pkts bytes target     prot opt in     out     source               destination          2208  147K KUBE-SERVICES  all  --  any    any     anywhere             anywhere             /* kubernetes service portals */ Chain KUBE-SERVICES (2 references) pkts bytes target     prot opt in     out     source               destination             0     0 KUBE-SVC-3KJW6L7XGSFMVIPO  tcp  --  any    any     anywhere             ip-10-100-199-193.ec2.internal  /* default/nginx-node-port cluster IP */ tcp dpt:http   52  3120 KUBE-NODEPORTS  all  --  any    any     anywhere             anywhere             /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCALChain KUBE-NODEPORTS (1 references)pkts bytes target     prot opt in     out     source               destination            0     0 KUBE-EXT-3KJW6L7XGSFMVIPO  tcp  --  any    any     anywhere             anywhere             /* default/nginx-node-port */ tcp dpt:30730Chain KUBE-EXT-3KJW6L7XGSFMVIPO (1 references)pkts bytes target     prot opt in     out     source               destination            0     0 KUBE-MARK-MASQ  all  --  any    any     anywhere             anywhere             /* masquerade traffic for default/nginx-node-port external destinations */   0     0 KUBE-SVC-3KJW6L7XGSFMVIPO  all  --  any    any     anywhere             anywhere            Chain KUBE-SVC-3KJW6L7XGSFMVIPO (2 references)pkts bytes target     prot opt in     out     source               destination            0     0 KUBE-SEP-KS7GFULRFICP7QTF  all  --  any    any     anywhere             anywhere             /* default/nginx-node-port -&amp;gt; 192.168.22.71:80 */Chain KUBE-SEP-KS7GFULRFICP7QTF (1 references) pkts bytes target     prot opt in     out     source               destination             0     0 KUBE-MARK-MASQ  all  --  any    any     ip-192-168-22-71.ec2.internal  anywhere             /* default/nginx-node-port */    0     0 DNAT       tcp  --  any    any     anywhere             anywhere             /* default/nginx-node-port */ tcp to:192.168.22.71:80Chain POSTROUTING (policy ACCEPT 246 packets, 16109 bytes)pkts bytes target     prot opt in     out     source               destination         82418 5146K KUBE-POSTROUTING  all  --  any    any     anywhere             anywhere             /* kubernetes postrouting rules */81338 5079K AWS-SNAT-CHAIN-0  all  --  any    any     anywhere             anywhere             /* AWS SNAT CHAIN */Chain AWS-SNAT-CHAIN-0 (1 references)pkts bytes target     prot opt in     out     source               destination         59065 3589K AWS-SNAT-CHAIN-1  all  --  any    any     anywhere            !ip-192-168-0-0.ec2.internal/16  /* AWS SNAT CHAIN */Chain AWS-SNAT-CHAIN-1 (1 references)pkts bytes target     prot opt in     out     source               destination         51947 3162K SNAT       all  --  any    !vlan+  anywhere             anywhere             /* AWS, SNAT */ ADDRTYPE match dst-type !LOCAL to:192.168.26.112 random-fully&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-kubernetes-load-balancer-service&quot;&gt;Kubernetes Load Balancer Service&lt;/h1&gt;&lt;h2 id=&quot;heading-load-balancer-provisioning&quot;&gt;Load Balancer Provisioning&lt;/h2&gt;&lt;p&gt;Load Balancer Service is another type of Kubernetes Service whereby we orchestrate Load Balancers that are outside the Kubernetes Cluster and have them serve as ingress points to a group of pods within our Kubernetes Cluster.&lt;/p&gt;&lt;p&gt;This generally requires a controller (Pod) that listens to all Kubernetes API Server activities that involve Kubernetes Load Balancer service. When the controller sees a service of type load balancer created, it creates an external Load Balancer that is mapped to that service. In AWS, this is depicted by the AWS Load Balancer Controller that also needs to have IAM permissions to create the Load Balancers within AWS.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706129319084/684ecfa4-eb18-41ce-b27a-161915af70ed.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The below are logs taken from the AWS Load Balancer controller pod and show that the controller is creating resources such as Load Balancers, Target Groups and Listeners which are again objects pertaining to Load Balancers in AWS. Please note that other Cloud Providers have similar functionality in terms of controllers that can orchestrate their Load Balancer offerings.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;[cloudshell-user@ip-10-138-162-38 ~]$ kubectl logs -n kube-system aws-load-balancer-controller-5749768698-8jslx{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:55Z&quot;,&quot;msg&quot;:&quot;setting service loadBalancerClass&quot;,&quot;service&quot;:&quot;nginx1&quot;,&quot;loadBalancerClass&quot;:&quot;service.k8s.aws/nlb&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:55Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;successfully built model&quot;,&quot;model&quot;:&quot;{\&quot;id\&quot;:\&quot;default/nginx1\&quot;,\&quot;resources\&quot;:{\&quot;AWS::ElasticLoadBalancingV2::Listener\&quot;:{\&quot;80\&quot;:{\&quot;spec\&quot;:{\&quot;loadBalancerARN\&quot;:{\&quot;$ref\&quot;:\&quot;#/resources/AWS::ElasticLoadBalancingV2::LoadBalancer/LoadBalancer/status/loadBalancerARN\&quot;},\&quot;port\&quot;:80,\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;defaultActions\&quot;:[{\&quot;type\&quot;:\&quot;forward\&quot;,\&quot;forwardConfig\&quot;:{\&quot;targetGroups\&quot;:[{\&quot;targetGroupARN\&quot;:{\&quot;$ref\&quot;:\&quot;#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/default/nginx1:80/status/targetGroupARN\&quot;}}]}}]}}},\&quot;AWS::ElasticLoadBalancingV2::LoadBalancer\&quot;:{\&quot;LoadBalancer\&quot;:{\&quot;spec\&quot;:{\&quot;name\&quot;:\&quot;k8s-default-nginx1-36dbca87e3\&quot;,\&quot;type\&quot;:\&quot;network\&quot;,\&quot;scheme\&quot;:\&quot;internet-facing\&quot;,\&quot;ipAddressType\&quot;:\&quot;ipv4\&quot;,\&quot;subnetMapping\&quot;:[{\&quot;subnetID\&quot;:\&quot;subnet-0bb01040718d4acb6\&quot;},{\&quot;subnetID\&quot;:\&quot;subnet-0c11a935b51724fa2\&quot;}]}}},\&quot;AWS::ElasticLoadBalancingV2::TargetGroup\&quot;:{\&quot;default/nginx1:80\&quot;:{\&quot;spec\&quot;:{\&quot;name\&quot;:\&quot;k8s-default-nginx1-25a492f569\&quot;,\&quot;targetType\&quot;:\&quot;ip\&quot;,\&quot;port\&quot;:80,\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;ipAddressType\&quot;:\&quot;ipv4\&quot;,\&quot;healthCheckConfig\&quot;:{\&quot;port\&quot;:\&quot;traffic-port\&quot;,\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;intervalSeconds\&quot;:10,\&quot;timeoutSeconds\&quot;:10,\&quot;healthyThresholdCount\&quot;:3,\&quot;unhealthyThresholdCount\&quot;:3},\&quot;targetGroupAttributes\&quot;:[{\&quot;key\&quot;:\&quot;proxy_protocol_v2.enabled\&quot;,\&quot;value\&quot;:\&quot;false\&quot;}]}}},\&quot;K8S::ElasticLoadBalancingV2::TargetGroupBinding\&quot;:{\&quot;default/nginx1:80\&quot;:{\&quot;spec\&quot;:{\&quot;template\&quot;:{\&quot;metadata\&quot;:{\&quot;name\&quot;:\&quot;k8s-default-nginx1-25a492f569\&quot;,\&quot;namespace\&quot;:\&quot;default\&quot;,\&quot;creationTimestamp\&quot;:null},\&quot;spec\&quot;:{\&quot;targetGroupARN\&quot;:{\&quot;$ref\&quot;:\&quot;#/resources/AWS::ElasticLoadBalancingV2::TargetGroup/default/nginx1:80/status/targetGroupARN\&quot;},\&quot;targetType\&quot;:\&quot;ip\&quot;,\&quot;serviceRef\&quot;:{\&quot;name\&quot;:\&quot;nginx1\&quot;,\&quot;port\&quot;:80},\&quot;networking\&quot;:{\&quot;ingress\&quot;:[{\&quot;from\&quot;:[{\&quot;ipBlock\&quot;:{\&quot;cidr\&quot;:\&quot;192.168.0.0/19\&quot;}},{\&quot;ipBlock\&quot;:{\&quot;cidr\&quot;:\&quot;192.168.32.0/19\&quot;}}],\&quot;ports\&quot;:[{\&quot;protocol\&quot;:\&quot;TCP\&quot;,\&quot;port\&quot;:80}]}]},\&quot;ipAddressType\&quot;:\&quot;ipv4\&quot;}}}}}}}&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:56Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating targetGroup&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:56Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created targetGroup&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:targetgroup/k8s-default-nginx1-25a492f569/ad12b7f6eaf1ee7d&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:56Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating loadBalancer&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;LoadBalancer&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created loadBalancer&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;LoadBalancer&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:loadbalancer/net/k8s-default-nginx1-36dbca87e3/7ff79bdbac47fb35&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating listener&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;80&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created listener&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;80&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:listener/net/k8s-default-nginx1-36dbca87e3/7ff79bdbac47fb35/ead861bf3e4bcbb5&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;creating targetGroupBinding&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;created targetGroupBinding&quot;,&quot;stackID&quot;:&quot;default/nginx1&quot;,&quot;resourceID&quot;:&quot;default/nginx1:80&quot;,&quot;targetGroupBinding&quot;:{&quot;namespace&quot;:&quot;default&quot;,&quot;name&quot;:&quot;k8s-default-nginx1-25a492f569&quot;}}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;logger&quot;:&quot;controllers.service&quot;,&quot;msg&quot;:&quot;successfully deployed model&quot;,&quot;service&quot;:{&quot;namespace&quot;:&quot;default&quot;,&quot;name&quot;:&quot;nginx1&quot;}}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;msg&quot;:&quot;authorizing securityGroup ingress&quot;,&quot;securityGroupID&quot;:&quot;sg-02cd536f30a36abed&quot;,&quot;permission&quot;:[{&quot;FromPort&quot;:80,&quot;IpProtocol&quot;:&quot;tcp&quot;,&quot;IpRanges&quot;:[{&quot;CidrIp&quot;:&quot;192.168.0.0/19&quot;,&quot;Description&quot;:&quot;elbv2.k8s.aws/targetGroupBinding=shared&quot;}],&quot;Ipv6Ranges&quot;:null,&quot;PrefixListIds&quot;:null,&quot;ToPort&quot;:80,&quot;UserIdGroupPairs&quot;:null},{&quot;FromPort&quot;:80,&quot;IpProtocol&quot;:&quot;tcp&quot;,&quot;IpRanges&quot;:[{&quot;CidrIp&quot;:&quot;192.168.32.0/19&quot;,&quot;Description&quot;:&quot;elbv2.k8s.aws/targetGroupBinding=shared&quot;}],&quot;Ipv6Ranges&quot;:null,&quot;PrefixListIds&quot;:null,&quot;ToPort&quot;:80,&quot;UserIdGroupPairs&quot;:null}]}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:57Z&quot;,&quot;msg&quot;:&quot;authorized securityGroup ingress&quot;,&quot;securityGroupID&quot;:&quot;sg-02cd536f30a36abed&quot;}{&quot;level&quot;:&quot;info&quot;,&quot;ts&quot;:&quot;2024-01-23T19:24:58Z&quot;,&quot;msg&quot;:&quot;registering targets&quot;,&quot;arn&quot;:&quot;arn:aws:elasticloadbalancing:us-east-1:87125367xxxx:targetgroup/k8s-default-nginx1-25a492f569/ad12b7f6eaf1ee7d&quot;,&quot;targets&quot;:[{&quot;AvailabilityZone&quot;:null,&quot;Id&quot;:&quot;192.168.39.147&quot;,&quot;Port&quot;:80}]}&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;heading-instance-target&quot;&gt;Instance Target&lt;/h2&gt;&lt;p&gt;For Instance Target, we are configuring the Network Load Balancer to send the traffic to one of the two worker nodes which again have a NodePort configuration by which they listen to port 31729 in our example.&lt;/p&gt;&lt;p&gt;Thus, the follow works as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;The client resolves the FQDN name of the Network Load Balancer. Note that NLBs are generally implemented across Availability Zones for redundancy. As soon as we resolve the NLB&apos;s FQDN, the client will sends the packet towards one of the two NLBs Public address&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Internet Gateway at the edge of the VPC does a static 1:1 NAT changing the Public address of the chosen NLB to the private address 192.168.41.233 (Left NLB)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The left NLB has two targets which are the eth0 of Worker Nodes 1 &amp;amp; 2 that are both listening on TCP Port 31729. In our example, we assume the traffic goes to Worker Node 1. Thus till this point the source is the client IP and the destination is Worker Node 1&apos;s eth0 192.168.45.167.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that the packet has hit Worker Node#1, again similar to the behavior we have seen with NodePort, a DNAT will occur translating the destination tot he Pod address 192.168.22.71 and an SNAT will change the client address to 192.168.45.167.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706119287096/2952d92b-b55e-421e-9252-7cd051ff3d7f.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;The way we can tune the NLB&apos;s behavior is via Annotations set on the service, specifically the setting:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;service.beta.kubernetes.io/aws-load-balancer-nlb-target-type&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;Name:                     nginx1Namespace:                defaultLabels:                   run=nginx1Annotations:              service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance                          service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing                          service.beta.kubernetes.io/aws-load-balancer-type: externalSelector:                 run=nginx1Type:                     LoadBalancerIP Family Policy:         SingleStackIP Families:              IPv4IP:                       10.100.69.226IPs:                      10.100.69.226LoadBalancer Ingress:     k8s-default-nginx1-36dbca87e3-7ff79bdbac47fb35.elb.us-east-1.amazonaws.comPort:                     &amp;lt;unset&amp;gt;  80/TCPTargetPort:               80/TCPNodePort:                 &amp;lt;unset&amp;gt;  31729/TCPEndpoints:                192.168.39.147:80Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   &amp;lt;none&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the figures below, we can also see the AWS outputs showing that the targets are the two worker node instances and the NodePort configured is 31729.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706127357109/4737d15f-982c-42b0-80d4-6de43e64ee4a.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706127346034/629e6cb5-436f-42b5-a9e1-2ef6d2c7090b.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The two images here show packet captures from both the Node &amp;amp; Pod perspective where the Node actually sees the client IP (Public Address) in this example and the Pod sees the Node IPs as the source 192.168.45.167 &amp;amp; 192.168.26.112.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191459108/153ae61c-801b-4d64-837f-83a45a0c09d8.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191505064/b2da2591-7bd6-4735-9d13-b7c12a85552b.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-ip-target&quot;&gt;IP Target&lt;/h2&gt;&lt;p&gt;This is again another iteration of configuring the NLB whereby in this mode, the NLB directly sends the packet to the Pod instead of sending it to the Node. This is possible in our example because we are using the AWS VPC CNI whereby a Pod behaves just like a VM in the sense that it gets an IP address from the VPC range &amp;amp; thus can be reached directly from components within the VPC.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706127176864/3eeb5a8d-ed6f-4227-9726-526137493b50.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;This is again possible by setting the below annotation.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;Name:                     nginx1Namespace:                defaultLabels:                   run=nginx1Annotations:              service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip                          service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing                          service.beta.kubernetes.io/aws-load-balancer-type: externalSelector:                 run=nginx1Type:                     LoadBalancerIP Family Policy:         SingleStackIP Families:              IPv4IP:                       10.100.69.226IPs:                      10.100.69.226LoadBalancer Ingress:     k8s-default-nginx1-36dbca87e3-7ff79bdbac47fb35.elb.us-east-1.amazonaws.comPort:                     &amp;lt;unset&amp;gt;  80/TCPTargetPort:               80/TCPNodePort:                 &amp;lt;unset&amp;gt;  31729/TCPEndpoints:                192.168.39.147:80Session Affinity:         NoneExternal Traffic Policy:  ClusterEvents:                   &amp;lt;none&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similar to what we have seen above, this is the AWS output showing the target being the Pod Address 192.168.39.147.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706136938877/b988efd7-95dc-4812-90b8-c4f9140f55be.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Again, here we show the packet captures on both the Node and the Pod. Notice that even the Node sees the traffic as sourced from the LB and destined to the Pod IP thus there is no need for NodePort treatment at the Worker Nodes.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191579595/bb04bc9e-6ff1-4389-8efe-c51ed704d40b.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706191585265/e261d12b-bb55-46cc-9d20-2f4fa6a4d9ea.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-drawbacks-of-load-balancer-service&quot;&gt;Drawbacks of Load Balancer Service&lt;/h1&gt;&lt;p&gt;The main drawback of the Load Balancer Service is a 1:1 mapping between the Load Balancer and the service (group of pods) that you want to expose. This has multiple implications including increased costs, more management overhead, public addresses, and the need to secure all the Load Balancers with WAF, API Security, Anti-DDoS solutions. If one of these services goes uncovered or unprotected there could be security breaches leading to major losses.&lt;/p&gt;&lt;p&gt;The diagram below explains the problem where for each service, the AWS LB Controller will instantiate an NLB.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706137013289/133fe9b0-30da-46f8-a9b7-88ab3ce85164.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The below diagram emphasizes the same challenge whereby we can see our Kubernetes Cluster (here depicted as a single node) and all the different entry points that map to the different services.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1706137083949/5fb990fe-5be9-4ba2-8026-759e278875a4.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1706321555655/b779b567-d647-4eda-8fbb-dcecc21616f4.png</hashnode:coverImage></item><item><title><![CDATA[Kubernetes Services: ClusterIP]]></title><description><![CDATA[Brief Introduction
Kubernetes Services serve as an abstraction layer for one or more pods operating behind them. If you're thinking Load Balancers or proxies, you are on the right path.
In essence, pods are transient resources within Kubernetes, typi...]]></description><link>https://jamali.hashnode.dev/kubernetes-services</link><guid isPermaLink="true">https://jamali.hashnode.dev/kubernetes-services</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[kubernetes architecture]]></category><category><![CDATA[Kubernetes-networking]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Fri, 12 Jan 2024 20:09:35 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h2 id=&quot;heading-brief-introduction&quot;&gt;Brief Introduction&lt;/h2&gt;&lt;p&gt;Kubernetes Services serve as an abstraction layer for one or more pods operating behind them. If you&apos;re thinking Load Balancers or proxies, you are on the right path.&lt;/p&gt;&lt;p&gt;In essence, pods are transient resources within Kubernetes, typically instantiated through Deployments. These Deployments leverage controllers to ensure a consistent minimum number of pods is always active. Referring to the below figure, there&apos;s a Pod named &quot;tmp-shell&quot; that needs to communicate with an nginx pod. &quot;Tmp-shell&quot; doesn&apos;t care about the specific nginx pod it connects to. Even if the actual pods in the nginx service change, &quot;tmp-shell&quot; isn&apos;t bothered by these changes. Kubernetes Services provide this abstraction. In our example, the nginx service hides the details of individual nginx pods from &quot;tmp-shell.&quot; So, &quot;tmp-shell&quot; connects to the nginx service, and the service then directs the request to one of the available endpoints or targets.&lt;/p&gt;&lt;p&gt;One lingering question is: How does &quot;tmp-shell&quot; discover the service? The service has both an IP address and a DNS name. Consequently, &quot;tmp-shell&quot; initiates a DNS request to CoreDNS, the Kubernetes DNS Service, seeking to resolve the DNS name associated with the nginx service. Upon receiving a response from CoreDNS, &quot;tmp-shell&quot; can establish a connection to the nginx service using its IP address.&lt;/p&gt;&lt;p&gt;There are multiple service types in Kubernetes, those that expose Pods internally within the Kubernetes Cluster and those that expose Pods externally (Outside the Kubernetes Cluster). In this blog post, we will mainly focus on ClusterIP service that exposes pods within the Kubernetes cluster just like the example we have been discussing between tmp-shell and nginx where all of these pods reside within the same Kubernetes cluster.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/blank-diagram-initial-diagram.png?w=724&quot; alt=&quot;Figure1. Kubernetes Service High Level Overview&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-where-do-services-live&quot;&gt;Where do Services Live?&lt;/h2&gt;&lt;p&gt;Services are implemented through iptable rules on each node to manage traffic effectively. Whenever a service is created or updated, these iptable rules are adjusted to ensure that traffic is correctly directed to the designated pods.&lt;/p&gt;&lt;p&gt;ClusterIP services are instantiated on all nodes, meaning iptable rules are programmed across the entire cluster. Think of it like an Anycast Address, extending its presence across all nodes in the cluster. In the figure below, the nginx service is created with 3 supporting pods nginx-1, nginx-2 and nginx-3. All nodes have an instantiation of the service depicted as IPtables configuration, and the service shares a common virtual address, exemplified as 10.96.76.14 in our case.&lt;/p&gt;&lt;p&gt;When Client-1 on Worker Node-1 sends a request to the nginx service, the service must decide which of the four backing pods to route the request to. With four pods, each one handles 25% of the traffic. Importantly, even on nodes without nginx pods, the service is still instantiated, as observed in the case of Worker Node 3.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1705080975738/e567787a-2634-40af-b9ae-d36f9fac935f.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-traffic-flow&quot;&gt;Traffic Flow&lt;/h2&gt;&lt;p&gt;In this section, we delve into the traffic flow between the &quot;tmp-shell&quot; pod and the nginx pods, highlighting key points:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Virtual Ethernet Pairs:&lt;/strong&gt; &quot;tmp-shell&quot; connects to the host through virtual Ethernet pairs, where one end is labeled as eth0 on the pod, and the other end is an interface named lxc01 for &quot;tmp-shell.&quot; This pattern applies consistently across all pods in the cluster. You can think about it like a virtual wire connecting the Pod to the host.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service Name Resolution:&lt;/strong&gt; To communicate with the nginx service, &quot;tmp-shell&quot; needs to resolve the IP address mapped to the service name. The naming convention for services is &lt;code&gt;&amp;lt;servicename&amp;gt;.&amp;lt;namespace&amp;gt;.svc.cluster.local&lt;/code&gt; assuming the default domain name. In our example, using the default namespace, the nginx service&apos;s FQDN is &quot;nginx.default.svc.cluster.local.&quot; Subsequently, a packet is sent from &quot;tmp-shell&quot; (10.0.0.8) to the nginx service address (10.96.76.14) upon receiving the DNS response.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Destination NAT (DNAT):&lt;/strong&gt; iptables perform a Destination NAT, converting the nginx service address (10.96.76.14) to the nginx pod address. This is demonstrated in the example with a single endpoint or backing pod for the nginx service, though real-world scenarios may involve multiple pods.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pod-to-Pod Routing Patterns:&lt;/strong&gt; There are two high-level patterns for pod-to-pod routing across nodes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native Routing:&lt;/strong&gt; Pod addresses traverse the network between nodes unchanged. In this scenario, the underlying network must be aware of Pod addresses, necessitating proper routing. However, the absence of NAT offers better visibility into pod-to-pod communication.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Overlays:&lt;/strong&gt; Regardless of the tunneling mechanism, packets leave the node with an outer envelope indicating source/destination worker nodes. The underlying network views these packets as originating from one worker node and destined for another. Beyond this point, the nginx pod receives the packet with the source address as &quot;tmp-shell&quot; (10.0.0.8).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Response Handling:&lt;/strong&gt; Upon reaching Worker Node 1, the packet&apos;s source is 10.0.1.79, and the destination is 10.0.0.8. However, &quot;tmp-shell&quot; won&apos;t accept this packet as the original packet it sent was from itself (10.0.0.8) to the nginx service (10.96.76.14). iptables intervenes again, performing Source NAT (SNAT) of 10.0.1.79 (nginx address) to the nginx service (10.96.76.14), aligning with the original packet flow.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This detailed explanation clarifies the steps in how &quot;tmp-shell&quot; communicates with the nginx pods throughout the Kubernetes cluster.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1705081293817/b3911316-56a7-4748-80d2-7639167f5bff.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/blank-diagram-request-to-clusterip-5.png?w=1024&quot; alt=&quot;Figure3. Request Flow&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/blank-diagram-response-from-pod-5.png?w=1024&quot; alt=&quot;Figure4. Response Flow&quot; /&gt;&lt;/p&gt;&lt;p&gt;Here you can find the packet captures that align with the explanation on how it works.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702576005017/d56916ba-4f6e-42db-8116-70dd5fe182bf.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702576021718/273c9c8d-43ab-4352-b817-1966731e6697.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;The iptables rules operate as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;PREROUTING Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Initiates the process, directing traffic to the &lt;code&gt;KUBE-SERVICES&lt;/code&gt; chain.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;KUBE-SERVICES Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Checks if the destination matches the Cluster IP (10.109.91.212) of the nginx service.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If matched, redirects the traffic to the &lt;code&gt;KUBE-SVC-2CMXP7HKUVJN7L6M&lt;/code&gt; chain.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;KUBE-SVC-2CMXP7HKUVJN7L6M Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Directs traffic to the &lt;code&gt;KUBE-SEP-XZRG5L6J3WL7H422&lt;/code&gt; chain, as indicated by the comment.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;KUBE-SEP-XZRG5L6J3WL7H422 Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Utilizes DNAT (Destination Network Address Translation) in its final rule.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;This rule modifies the destination of the traffic, rerouting it to the nginx pod.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These iptables rules collectively ensure that traffic directed to the specified nginx service IP undergoes the necessary transformations, ultimately reaching the appropriate nginx pod.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Quick Note on IPTables:&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SERVICES:&lt;/strong&gt; This is a container for all Kubernetes Services configured on the cluster.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SVC-*:&lt;/strong&gt; This is an entry for a particular service. e.g. nginx service&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SEP-*:&lt;/strong&gt; In IPTables, when you see KUBE-SEP-* this is an entry for a particular endpoint&lt;/p&gt;&lt;p&gt;Thus in our example, you can see one KUBE-SVC-* and one KUBE-SEP-* as we have a single service (nginx) and a single endpoint (10.0.1.79)&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;-A PREROUTING -m comment --comment &quot;kubernetes service portals&quot; -j KUBE-SERVICES-A KUBE-SERVICES -d 10.109.91.212/32 -p tcp -m comment --comment &quot;default/nginx cluster IP&quot; -m tcp --dport 80 -j KUBE-SVC-2CMXP7HKUVJN7L6M-A KUBE-SVC-2CMXP7HKUVJN7L6M -m comment --comment &quot;default/nginx -&amp;gt; 10.0.1.79:80&quot; -j KUBE-SEP-XZRG5L6J3WL7H422-A KUBE-SEP-XZRG5L6J3WL7H422 -p tcp -m comment --comment &quot;default/nginx&quot; -m tcp -j DNAT --to-destination 10.0.1.79:80&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The below IPtables example, show what happens when we add another endpoint to back the nginx service thus we have two endpoints. You can now see that we still have one KUBE-SVC-* (one service) and 2 KUBE-SEP-* (2 Endpoints) and the service sends to the particular endpoint with a probability of 0.5 (50%) thus equally distributing the load across both endpoints.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Endpoint 1: 10.0.1.79&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Endpoint 2: 10.0.0.224&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;-A KUBE-SVC-2CMXP7HKUVJN7L6M -m comment --comment &quot;default/nginx -&amp;gt; 10.0.0.224:80&quot; -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-HZXSYA2C4E7MQSH3-A KUBE-SVC-2CMXP7HKUVJN7L6M -m comment --comment &quot;default/nginx -&amp;gt; 10.0.1.79:80&quot; -j KUBE-SEP-XZRG5L6J3WL7H422-A KUBE-SEP-XZRG5L6J3WL7H422 -p tcp -m comment --comment &quot;default/nginx&quot; -m tcp -j DNAT --to-destination 10.0.1.79:80-A KUBE-SEP-HZXSYA2C4E7MQSH3 -p tcp -m comment --comment &quot;default/nginx&quot; -m tcp -j DNAT --to-destination 10.0.0.224:80&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-how-are-these-iptables-programmed&quot;&gt;How are these IPTables Programmed?&lt;/h1&gt;&lt;p&gt;Whenever any changes happen for the Kubernetes Services or Endpoints, API Server shares these changes with Kube-proxy which in turn programs the IPTables accordingly.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1705089759092/f09fe6c1-1894-476e-9136-52f9ccd16e34.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h2 id=&quot;heading-brief-introduction&quot;&gt;Brief Introduction&lt;/h2&gt;&lt;p&gt;Kubernetes Services serve as an abstraction layer for one or more pods operating behind them. If you&apos;re thinking Load Balancers or proxies, you are on the right path.&lt;/p&gt;&lt;p&gt;In essence, pods are transient resources within Kubernetes, typically instantiated through Deployments. These Deployments leverage controllers to ensure a consistent minimum number of pods is always active. Referring to the below figure, there&apos;s a Pod named &quot;tmp-shell&quot; that needs to communicate with an nginx pod. &quot;Tmp-shell&quot; doesn&apos;t care about the specific nginx pod it connects to. Even if the actual pods in the nginx service change, &quot;tmp-shell&quot; isn&apos;t bothered by these changes. Kubernetes Services provide this abstraction. In our example, the nginx service hides the details of individual nginx pods from &quot;tmp-shell.&quot; So, &quot;tmp-shell&quot; connects to the nginx service, and the service then directs the request to one of the available endpoints or targets.&lt;/p&gt;&lt;p&gt;One lingering question is: How does &quot;tmp-shell&quot; discover the service? The service has both an IP address and a DNS name. Consequently, &quot;tmp-shell&quot; initiates a DNS request to CoreDNS, the Kubernetes DNS Service, seeking to resolve the DNS name associated with the nginx service. Upon receiving a response from CoreDNS, &quot;tmp-shell&quot; can establish a connection to the nginx service using its IP address.&lt;/p&gt;&lt;p&gt;There are multiple service types in Kubernetes, those that expose Pods internally within the Kubernetes Cluster and those that expose Pods externally (Outside the Kubernetes Cluster). In this blog post, we will mainly focus on ClusterIP service that exposes pods within the Kubernetes cluster just like the example we have been discussing between tmp-shell and nginx where all of these pods reside within the same Kubernetes cluster.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/blank-diagram-initial-diagram.png?w=724&quot; alt=&quot;Figure1. Kubernetes Service High Level Overview&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-where-do-services-live&quot;&gt;Where do Services Live?&lt;/h2&gt;&lt;p&gt;Services are implemented through iptable rules on each node to manage traffic effectively. Whenever a service is created or updated, these iptable rules are adjusted to ensure that traffic is correctly directed to the designated pods.&lt;/p&gt;&lt;p&gt;ClusterIP services are instantiated on all nodes, meaning iptable rules are programmed across the entire cluster. Think of it like an Anycast Address, extending its presence across all nodes in the cluster. In the figure below, the nginx service is created with 3 supporting pods nginx-1, nginx-2 and nginx-3. All nodes have an instantiation of the service depicted as IPtables configuration, and the service shares a common virtual address, exemplified as 10.96.76.14 in our case.&lt;/p&gt;&lt;p&gt;When Client-1 on Worker Node-1 sends a request to the nginx service, the service must decide which of the four backing pods to route the request to. With four pods, each one handles 25% of the traffic. Importantly, even on nodes without nginx pods, the service is still instantiated, as observed in the case of Worker Node 3.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1705080975738/e567787a-2634-40af-b9ae-d36f9fac935f.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-traffic-flow&quot;&gt;Traffic Flow&lt;/h2&gt;&lt;p&gt;In this section, we delve into the traffic flow between the &quot;tmp-shell&quot; pod and the nginx pods, highlighting key points:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Virtual Ethernet Pairs:&lt;/strong&gt; &quot;tmp-shell&quot; connects to the host through virtual Ethernet pairs, where one end is labeled as eth0 on the pod, and the other end is an interface named lxc01 for &quot;tmp-shell.&quot; This pattern applies consistently across all pods in the cluster. You can think about it like a virtual wire connecting the Pod to the host.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Service Name Resolution:&lt;/strong&gt; To communicate with the nginx service, &quot;tmp-shell&quot; needs to resolve the IP address mapped to the service name. The naming convention for services is &lt;code&gt;&amp;lt;servicename&amp;gt;.&amp;lt;namespace&amp;gt;.svc.cluster.local&lt;/code&gt; assuming the default domain name. In our example, using the default namespace, the nginx service&apos;s FQDN is &quot;nginx.default.svc.cluster.local.&quot; Subsequently, a packet is sent from &quot;tmp-shell&quot; (10.0.0.8) to the nginx service address (10.96.76.14) upon receiving the DNS response.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Destination NAT (DNAT):&lt;/strong&gt; iptables perform a Destination NAT, converting the nginx service address (10.96.76.14) to the nginx pod address. This is demonstrated in the example with a single endpoint or backing pod for the nginx service, though real-world scenarios may involve multiple pods.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pod-to-Pod Routing Patterns:&lt;/strong&gt; There are two high-level patterns for pod-to-pod routing across nodes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Native Routing:&lt;/strong&gt; Pod addresses traverse the network between nodes unchanged. In this scenario, the underlying network must be aware of Pod addresses, necessitating proper routing. However, the absence of NAT offers better visibility into pod-to-pod communication.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Overlays:&lt;/strong&gt; Regardless of the tunneling mechanism, packets leave the node with an outer envelope indicating source/destination worker nodes. The underlying network views these packets as originating from one worker node and destined for another. Beyond this point, the nginx pod receives the packet with the source address as &quot;tmp-shell&quot; (10.0.0.8).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Response Handling:&lt;/strong&gt; Upon reaching Worker Node 1, the packet&apos;s source is 10.0.1.79, and the destination is 10.0.0.8. However, &quot;tmp-shell&quot; won&apos;t accept this packet as the original packet it sent was from itself (10.0.0.8) to the nginx service (10.96.76.14). iptables intervenes again, performing Source NAT (SNAT) of 10.0.1.79 (nginx address) to the nginx service (10.96.76.14), aligning with the original packet flow.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This detailed explanation clarifies the steps in how &quot;tmp-shell&quot; communicates with the nginx pods throughout the Kubernetes cluster.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1705081293817/b3911316-56a7-4748-80d2-7639167f5bff.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/blank-diagram-request-to-clusterip-5.png?w=1024&quot; alt=&quot;Figure3. Request Flow&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/blank-diagram-response-from-pod-5.png?w=1024&quot; alt=&quot;Figure4. Response Flow&quot; /&gt;&lt;/p&gt;&lt;p&gt;Here you can find the packet captures that align with the explanation on how it works.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702576005017/d56916ba-4f6e-42db-8116-70dd5fe182bf.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702576021718/273c9c8d-43ab-4352-b817-1966731e6697.png&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;The iptables rules operate as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;PREROUTING Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Initiates the process, directing traffic to the &lt;code&gt;KUBE-SERVICES&lt;/code&gt; chain.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;KUBE-SERVICES Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Checks if the destination matches the Cluster IP (10.109.91.212) of the nginx service.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If matched, redirects the traffic to the &lt;code&gt;KUBE-SVC-2CMXP7HKUVJN7L6M&lt;/code&gt; chain.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;KUBE-SVC-2CMXP7HKUVJN7L6M Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Directs traffic to the &lt;code&gt;KUBE-SEP-XZRG5L6J3WL7H422&lt;/code&gt; chain, as indicated by the comment.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;KUBE-SEP-XZRG5L6J3WL7H422 Chain:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Utilizes DNAT (Destination Network Address Translation) in its final rule.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;This rule modifies the destination of the traffic, rerouting it to the nginx pod.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These iptables rules collectively ensure that traffic directed to the specified nginx service IP undergoes the necessary transformations, ultimately reaching the appropriate nginx pod.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Quick Note on IPTables:&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SERVICES:&lt;/strong&gt; This is a container for all Kubernetes Services configured on the cluster.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SVC-*:&lt;/strong&gt; This is an entry for a particular service. e.g. nginx service&lt;/p&gt;&lt;p&gt;&lt;strong&gt;KUBE-SEP-*:&lt;/strong&gt; In IPTables, when you see KUBE-SEP-* this is an entry for a particular endpoint&lt;/p&gt;&lt;p&gt;Thus in our example, you can see one KUBE-SVC-* and one KUBE-SEP-* as we have a single service (nginx) and a single endpoint (10.0.1.79)&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;-A PREROUTING -m comment --comment &quot;kubernetes service portals&quot; -j KUBE-SERVICES-A KUBE-SERVICES -d 10.109.91.212/32 -p tcp -m comment --comment &quot;default/nginx cluster IP&quot; -m tcp --dport 80 -j KUBE-SVC-2CMXP7HKUVJN7L6M-A KUBE-SVC-2CMXP7HKUVJN7L6M -m comment --comment &quot;default/nginx -&amp;gt; 10.0.1.79:80&quot; -j KUBE-SEP-XZRG5L6J3WL7H422-A KUBE-SEP-XZRG5L6J3WL7H422 -p tcp -m comment --comment &quot;default/nginx&quot; -m tcp -j DNAT --to-destination 10.0.1.79:80&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The below IPtables example, show what happens when we add another endpoint to back the nginx service thus we have two endpoints. You can now see that we still have one KUBE-SVC-* (one service) and 2 KUBE-SEP-* (2 Endpoints) and the service sends to the particular endpoint with a probability of 0.5 (50%) thus equally distributing the load across both endpoints.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Endpoint 1: 10.0.1.79&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Endpoint 2: 10.0.0.224&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;lang-plaintext&quot;&gt;-A KUBE-SVC-2CMXP7HKUVJN7L6M -m comment --comment &quot;default/nginx -&amp;gt; 10.0.0.224:80&quot; -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-HZXSYA2C4E7MQSH3-A KUBE-SVC-2CMXP7HKUVJN7L6M -m comment --comment &quot;default/nginx -&amp;gt; 10.0.1.79:80&quot; -j KUBE-SEP-XZRG5L6J3WL7H422-A KUBE-SEP-XZRG5L6J3WL7H422 -p tcp -m comment --comment &quot;default/nginx&quot; -m tcp -j DNAT --to-destination 10.0.1.79:80-A KUBE-SEP-HZXSYA2C4E7MQSH3 -p tcp -m comment --comment &quot;default/nginx&quot; -m tcp -j DNAT --to-destination 10.0.0.224:80&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;heading-how-are-these-iptables-programmed&quot;&gt;How are these IPTables Programmed?&lt;/h1&gt;&lt;p&gt;Whenever any changes happen for the Kubernetes Services or Endpoints, API Server shares these changes with Kube-proxy which in turn programs the IPTables accordingly.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1705089759092/f09fe6c1-1894-476e-9136-52f9ccd16e34.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1705090455919/16ba9ef4-f9ca-455b-94fc-723fc3133a58.png</hashnode:coverImage></item><item><title><![CDATA[Istio Networking Part 2]]></title><description><![CDATA[Introduction
After providing a brief introduction to Istio in Part 1, this blog post will center on a detailed exploration of how Envoy intercepts all traffic, whether sourced or destined for the application container.
Our Application
To keep things ...]]></description><link>https://jamali.hashnode.dev/istio-networking-part-2</link><guid isPermaLink="true">https://jamali.hashnode.dev/istio-networking-part-2</guid><category><![CDATA[#istio]]></category><category><![CDATA[istio service mesh]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[#kubernetes #container ]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Mon, 27 Nov 2023 05:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h1 id=&quot;heading-introduction&quot;&gt;Introduction&lt;/h1&gt;&lt;p&gt;After providing a brief introduction to Istio in Part 1, this blog post will center on a detailed exploration of how Envoy intercepts all traffic, whether sourced or destined for the application container.&lt;/p&gt;&lt;h1 id=&quot;heading-our-application&quot;&gt;Our Application&lt;/h1&gt;&lt;p&gt;To keep things straightforward, Ive opted for the BookInfo applicationa commonly featured example in Istios getting started guide. This application comprises four microservices: Product Page, Reviews, Details, and Ratings. While Reviews has multiple versions, well keep our focus on v1.&lt;/p&gt;&lt;p&gt;For a visual overview, check out the diagram below, sourced from Istios documentation. It vividly illustrates the key components and their interactions.More details can be found &lt;a target=&quot;_blank&quot; href=&quot;https://istio.io/latest/docs/examples/bookinfo/#define-the-service-versions&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702261496631/821f16e8-8cac-4cc3-9013-6fba69a3df89.png&quot; alt=&quot;Figure1. Book Info Application Architecture&quot; class=&quot;image--right mx-auto mr-0&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-product-page-to-reviews-communication&quot;&gt;Product Page to Reviews Communication&lt;/h2&gt;&lt;p&gt;In the upcoming sections, we will only focus on the communication between productspage and the reviews service particularly reviews-v1. Note that the reviews service has multiple versions as shown in the below figure and the configuration is done in such a way that traffic has to go to the reviews-v1 subset. Again, the objective is to be able to understand how does this communication flow end-to-end.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702261766286/6bf520e2-1a09-4dd6-9a28-c866091b621d.png&quot; alt=&quot;Figure2. ProductsPage to Reviews-v1 Communication&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-from-productspage-container-to-sidecar&quot;&gt;From ProductsPage Container to SideCar&lt;/h2&gt;&lt;p&gt;Lets start with the productspage container as it is the source of the request (Reference Figure1).&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;DNS request that is destined to CoreDNS to resolve reviews.default.svc.cluster.local.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The response comes back as 10.107.148.159 which is the Kubernetes service IP for the reviews service.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It is worth noting that one of the endpoints of that service is 10.0.0.38 (reviews-v1).&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-7.17.04-pm-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/screenshot-2023-11-26-at-7.36.04-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-7.37.15-pm-copy-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Now, the intriguing question arises: How does the packet from 10.0.1.136 (Product Page) to 10.0.0.38 (Reviews-v1) navigate its way through the Envoy proxy?&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/its-magic-drs8g8.jpg&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;IPTables is the secret sauce behind getting the packet redirected to Envoy. As the packet exits the Product Page container, it encounters the IPTables chains listed below. Remember, our packet has a source of 10.0.1.136 and a destination of 10.0.0.38.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;We will start with the OUTPUT chain which will send us to the ISTIO_OUTPUT Chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If you look at the ISTIO_OUTPUT chain the 1st rule doesnt match as the source should be 127.0.0.6. The rules beneath generally match the UID 1337 which is traffic sourced by the Envoy sidecar thus these rules wont match. In addition, there are rules that have an out interface of loopback which will not match. Thus, the last rule in the ISTIO_OUTPUT chain will match sending us towards the ISTIO_REDIRECT Chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Within the ISTIO_REDIRECT chain, we have a REDIRECT rule which redirects traffic to port 15001 i.e. it will change the destination address to &lt;a target=&quot;_blank&quot; href=&quot;http://localhost&quot;&gt;localhost&lt;/a&gt; (127.0.0.1) and destination port to 15001.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-7.53.55-pm-copy.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The output below also proves that the Envoy proxy is actually listening on port 15001.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/screenshot-2023-11-26-at-8.03.09-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Up to this point, weve observed the packet departing the Product Page container and successfully reaching Envoy through IPTables redirection&lt;/p&gt;&lt;h2 id=&quot;heading-envoy-processing&quot;&gt;Envoy Processing&lt;/h2&gt;&lt;p&gt;In this section, our attention shifts to the processing of the packet by the productpage sidecar i.e. the Envoy proxy co-residing with the productpage container. The below outputs can be summarized as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;We examine listeners on port 15001, identifying the destination as PassthroughCluster. The PassthroughClusters type is ORIGINAL_DST, indicating that Envoy will revert the packets destination to its pre-IPTables redirection state, 10.0.0.38:9080.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Our attention then turns to Envoy routes, specifically focusing on reviews.default.svc.cluster.local:9080. The route view reveals the cluster as outbound|9080|v1|reviews.default.svc.cluster.local. Again, this is a result of the intended configuration where we want traffic that hits the reviews service to go to reviews-v1.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Finally, we need to figure out the specific endpoint within the Cluster which is the reviews-v1 pod address 10.0.0.38.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.14.01-pm-copy.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.17.53-pm-copy-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.19.57-pm-1-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/screenshot-2023-11-26-at-8.25.17-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.30.38-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Lastly, inspecting the productpage Envoy logs, we observe that the request originates from 10.0.0.136 and is destined for 10.0.0.38:9080.&lt;/p&gt;&lt;h2 id=&quot;heading-iptables-on-reviews-v1-pod&quot;&gt;IPTables on Reviews-v1 Pod&lt;/h2&gt;&lt;p&gt;As the packet from 10.0.0.136 (productspage) headed for 10.0.0.38 (reviews-v1) with a destination port of 9080 reaches the second node and enters the reviews-v1 pod network namespace, a familiar journey unfolds. Much like our previous process, the packet undergoes redirection to the Envoy sidecar, and once again, IPtables comes to the rescue.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;We will start with the PREROUTING chain as this is an incoming packet. The PREROUTING chain will directly send us to the ISTIO_INBOUND chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If you look at the ISTIO_INBOUND chain the 1st 4 rules do not match as the destination port is not 15008, 15090, 15021, and 15020 (Destination Port: 9080). This takes us to the ISTIO_IN_REDIRECT chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Within the ISTIO_IN_REDIRECT chain, we have a REDIRECT rule which redirects traffic to port 15006 i.e. it will change the destination address to localhost (127.0.0.1) and destination port to 15006. Again you can refer to the netstat output to see that Envoy listens for port 15006.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.38.53-pm-copy.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-envoy-processing-1&quot;&gt;Envoy Processing&lt;/h2&gt;&lt;p&gt;Please note that this is the Envoy proxy (sidecar) of the reviews pod.&lt;/p&gt;&lt;p&gt;Upon inspecting the Envoy proxy within the reviews pod, a quick confirmation reveals a listener on Port 15006, aligning with expectations. This listener efficiently directs traffic to the Cluster inbound|9080||. Examining the cluster further, denoted as inbound|9080||, reveals its type as ORIGINAL_DST, signifying that Envoy will revert the destination from the redirected address (127.0.0.1:15006) to the original one (10.0.0.38:9080).&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.41.43-pm-copy.png?w=1022&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Another interesting finding here is that the sourceAddress will be changed to 127.0.0.6. Thus, our packet will have a source as 127.0.0.6 &amp;amp; a destination as 10.0.0.38:9080. This can be seen in the below output.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.42.08-pm-copy.png?w=1023&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-9.15.29-pm-copy.png?w=1023&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Finally, the below figure puts it all together.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/kubernetes-ccm-overview-page-9-3.png?w=1024&quot; alt /&gt;&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h1 id=&quot;heading-introduction&quot;&gt;Introduction&lt;/h1&gt;&lt;p&gt;After providing a brief introduction to Istio in Part 1, this blog post will center on a detailed exploration of how Envoy intercepts all traffic, whether sourced or destined for the application container.&lt;/p&gt;&lt;h1 id=&quot;heading-our-application&quot;&gt;Our Application&lt;/h1&gt;&lt;p&gt;To keep things straightforward, Ive opted for the BookInfo applicationa commonly featured example in Istios getting started guide. This application comprises four microservices: Product Page, Reviews, Details, and Ratings. While Reviews has multiple versions, well keep our focus on v1.&lt;/p&gt;&lt;p&gt;For a visual overview, check out the diagram below, sourced from Istios documentation. It vividly illustrates the key components and their interactions.More details can be found &lt;a target=&quot;_blank&quot; href=&quot;https://istio.io/latest/docs/examples/bookinfo/#define-the-service-versions&quot;&gt;here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702261496631/821f16e8-8cac-4cc3-9013-6fba69a3df89.png&quot; alt=&quot;Figure1. Book Info Application Architecture&quot; class=&quot;image--right mx-auto mr-0&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-product-page-to-reviews-communication&quot;&gt;Product Page to Reviews Communication&lt;/h2&gt;&lt;p&gt;In the upcoming sections, we will only focus on the communication between productspage and the reviews service particularly reviews-v1. Note that the reviews service has multiple versions as shown in the below figure and the configuration is done in such a way that traffic has to go to the reviews-v1 subset. Again, the objective is to be able to understand how does this communication flow end-to-end.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://cdn.hashnode.com/res/hashnode/image/upload/v1702261766286/6bf520e2-1a09-4dd6-9a28-c866091b621d.png&quot; alt=&quot;Figure2. ProductsPage to Reviews-v1 Communication&quot; class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-from-productspage-container-to-sidecar&quot;&gt;From ProductsPage Container to SideCar&lt;/h2&gt;&lt;p&gt;Lets start with the productspage container as it is the source of the request (Reference Figure1).&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;DNS request that is destined to CoreDNS to resolve reviews.default.svc.cluster.local.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The response comes back as 10.107.148.159 which is the Kubernetes service IP for the reviews service.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It is worth noting that one of the endpoints of that service is 10.0.0.38 (reviews-v1).&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-7.17.04-pm-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/screenshot-2023-11-26-at-7.36.04-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-7.37.15-pm-copy-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Now, the intriguing question arises: How does the packet from 10.0.1.136 (Product Page) to 10.0.0.38 (Reviews-v1) navigate its way through the Envoy proxy?&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/its-magic-drs8g8.jpg&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;IPTables is the secret sauce behind getting the packet redirected to Envoy. As the packet exits the Product Page container, it encounters the IPTables chains listed below. Remember, our packet has a source of 10.0.1.136 and a destination of 10.0.0.38.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;We will start with the OUTPUT chain which will send us to the ISTIO_OUTPUT Chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If you look at the ISTIO_OUTPUT chain the 1st rule doesnt match as the source should be 127.0.0.6. The rules beneath generally match the UID 1337 which is traffic sourced by the Envoy sidecar thus these rules wont match. In addition, there are rules that have an out interface of loopback which will not match. Thus, the last rule in the ISTIO_OUTPUT chain will match sending us towards the ISTIO_REDIRECT Chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Within the ISTIO_REDIRECT chain, we have a REDIRECT rule which redirects traffic to port 15001 i.e. it will change the destination address to &lt;a target=&quot;_blank&quot; href=&quot;http://localhost&quot;&gt;localhost&lt;/a&gt; (127.0.0.1) and destination port to 15001.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-7.53.55-pm-copy.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;The output below also proves that the Envoy proxy is actually listening on port 15001.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/screenshot-2023-11-26-at-8.03.09-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Up to this point, weve observed the packet departing the Product Page container and successfully reaching Envoy through IPTables redirection&lt;/p&gt;&lt;h2 id=&quot;heading-envoy-processing&quot;&gt;Envoy Processing&lt;/h2&gt;&lt;p&gt;In this section, our attention shifts to the processing of the packet by the productpage sidecar i.e. the Envoy proxy co-residing with the productpage container. The below outputs can be summarized as follows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;We examine listeners on port 15001, identifying the destination as PassthroughCluster. The PassthroughClusters type is ORIGINAL_DST, indicating that Envoy will revert the packets destination to its pre-IPTables redirection state, 10.0.0.38:9080.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Our attention then turns to Envoy routes, specifically focusing on reviews.default.svc.cluster.local:9080. The route view reveals the cluster as outbound|9080|v1|reviews.default.svc.cluster.local. Again, this is a result of the intended configuration where we want traffic that hits the reviews service to go to reviews-v1.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Finally, we need to figure out the specific endpoint within the Cluster which is the reviews-v1 pod address 10.0.0.38.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.14.01-pm-copy.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.17.53-pm-copy-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.19.57-pm-1-1.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/screenshot-2023-11-26-at-8.25.17-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.30.38-pm.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;p&gt;Lastly, inspecting the productpage Envoy logs, we observe that the request originates from 10.0.0.136 and is destined for 10.0.0.38:9080.&lt;/p&gt;&lt;h2 id=&quot;heading-iptables-on-reviews-v1-pod&quot;&gt;IPTables on Reviews-v1 Pod&lt;/h2&gt;&lt;p&gt;As the packet from 10.0.0.136 (productspage) headed for 10.0.0.38 (reviews-v1) with a destination port of 9080 reaches the second node and enters the reviews-v1 pod network namespace, a familiar journey unfolds. Much like our previous process, the packet undergoes redirection to the Envoy sidecar, and once again, IPtables comes to the rescue.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;We will start with the PREROUTING chain as this is an incoming packet. The PREROUTING chain will directly send us to the ISTIO_INBOUND chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;If you look at the ISTIO_INBOUND chain the 1st 4 rules do not match as the destination port is not 15008, 15090, 15021, and 15020 (Destination Port: 9080). This takes us to the ISTIO_IN_REDIRECT chain.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Within the ISTIO_IN_REDIRECT chain, we have a REDIRECT rule which redirects traffic to port 15006 i.e. it will change the destination address to localhost (127.0.0.1) and destination port to 15006. Again you can refer to the netstat output to see that Envoy listens for port 15006.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.38.53-pm-copy.png&quot; alt class=&quot;image--center mx-auto&quot; /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-envoy-processing-1&quot;&gt;Envoy Processing&lt;/h2&gt;&lt;p&gt;Please note that this is the Envoy proxy (sidecar) of the reviews pod.&lt;/p&gt;&lt;p&gt;Upon inspecting the Envoy proxy within the reviews pod, a quick confirmation reveals a listener on Port 15006, aligning with expectations. This listener efficiently directs traffic to the Cluster inbound|9080||. Examining the cluster further, denoted as inbound|9080||, reveals its type as ORIGINAL_DST, signifying that Envoy will revert the destination from the redirected address (127.0.0.1:15006) to the original one (10.0.0.38:9080).&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.41.43-pm-copy.png?w=1022&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Another interesting finding here is that the sourceAddress will be changed to 127.0.0.6. Thus, our packet will have a source as 127.0.0.6 &amp;amp; a destination as 10.0.0.38:9080. This can be seen in the below output.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-8.42.08-pm-copy.png?w=1023&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/screenshot-2023-11-26-at-9.15.29-pm-copy.png?w=1023&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Finally, the below figure puts it all together.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/12/kubernetes-ccm-overview-page-9-3.png?w=1024&quot; alt /&gt;&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1702308742901/71cbd998-e244-403c-9ca5-4238f462aa32.png</hashnode:coverImage></item><item><title><![CDATA[Istio Networking Part 1]]></title><description><![CDATA[About the Series
In this two-part series, we embark on a journey into the realm of Istio, a powerful service mesh that has become integral to modern cloud-native applications. In this first installment, our focus will be on understanding the fundamen...]]></description><link>https://jamali.hashnode.dev/istio-networking-part-1</link><guid isPermaLink="true">https://jamali.hashnode.dev/istio-networking-part-1</guid><category><![CDATA[#istio]]></category><category><![CDATA[#ServiceMesh]]></category><category><![CDATA[istio service mesh]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[GCP]]></category><category><![CDATA[networking]]></category><category><![CDATA[containers]]></category><category><![CDATA[Kubernetes]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Sun, 26 Nov 2023 17:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h2 id=&quot;heading-about-the-series&quot;&gt;About the Series&lt;/h2&gt;&lt;p&gt;In this two-part series, we embark on a journey into the realm of Istio, a powerful service mesh that has become integral to modern cloud-native applications. In this first installment, our focus will be on understanding the fundamental need for a service mesh, exploring the high-level architecture of Istio, and ending with a brief explanation of Envoy.&lt;/p&gt;&lt;p&gt;In the upcoming part, we will deep dive on a how the Envoy sidecar intercepts all traffic sourced or destined to the application container.&lt;/p&gt;&lt;h2 id=&quot;heading-from-monoliths-to-microservices&quot;&gt;From Monoliths to Microservices&lt;/h2&gt;&lt;p&gt;Unless you have been hiding under a rock, you would have heard about the shift from Monoliths to Microservices. Actually, this topic even gets revisited when migrating workloads to the cloud. While working as a Technical Account Manager (TAM) for AWS in the past, we worked with customers to come up with the optimum migration strategy for each workload or component. If this is a topic of interest you can find some details &lt;a target=&quot;_blank&quot; href=&quot;https://docs.aws.amazon.com/prescriptive-guidance/latest/large-migration-guide/migration-strategies.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-monolith.png?w=576&quot; alt /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-microservices.png?w=1024&quot; alt /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Figure2. Microservices distributed across multiple nodes&lt;/p&gt;&lt;p&gt;Now that we have shifted to running microservices across multiple nodes, a few arising challenges come to the picture:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network Performance&lt;/strong&gt;: The performance of the underlying network becomes pivotal in determining the quality of our applications user experience.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;: With microservices communicating across networks, encryption becomes paramount to safeguard data in transit.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observability and Traceability&lt;/strong&gt;: This is another key concern in microservices where a transaction goes across these different components and we lose the visibility of an end-to-end user journey. The solution to this problem is distributed tracing . In addition, we will always need to have component level metrics &amp;amp; alerts.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identity &amp;amp; Zero Trust&lt;/strong&gt;: With the multitude of components and services running in a distributed fashion, we will need to strive to ensure that none of these components gets compromised and even if any of those components were to get compromised, we need to ensure that it cannot be used as a pivot to attack other critical services. This requires a solid identity foundation whereby each service has an identity and a role. Thus, any service to service call has to be authenticated &amp;amp; authorized with least privilege principle in mind. Advanced Load Balancing: Each of the components depicted as part of an application will have a number of replicas for purposes of scaling and high availability, thus at a minimum we will need to distribute load across all endpoints of a particular service in an efficient manner. This encompasses requests from external users or customers as well as requests between those microservices. Microservices allows pushing newer versions of individual components (billing, product details, ..etc) more frequently. This is another critical use-case for load balancing where for instance you can have 95% of requests target the stable version and only 5% target the updates versions and keep adjusting the weights based on your testing. Another possibility is sending your internal authenticated users to the new version and keeping external customers on the production/stable version.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resiliency&lt;/strong&gt;: As per the Principles of Chaos Engineering website, Chaos Engineering is the discipline of experimenting on a distributed system in order to build confidence in the systems capability to withstand turbulent conditions in production. Distributed complex systems are always prone to fail however our objective should be to stop the overall failure of the application or service we provide customers and end-users. Thus, we need tooling that will help application owners test their application in chaotic conditions whereby for instance a component responds with errors or delay a response and see the effect on the end-to-end user journey.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manageability&lt;/strong&gt;: Just like Kubernetes offers a single API to manage all resources, it is a must that all those capabilities (1-6) be centrally orchestrated.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These challenges birthed the need for a service mesh, with Istio emerging as the de facto solution. It might be interesting to note that prior to service mesh, attempts were made to solve those challenges with software libraries like Stubby and Hystrix.&lt;/p&gt;&lt;h2 id=&quot;heading-istio-architecture&quot;&gt;Istio Architecture&lt;/h2&gt;&lt;p&gt;At a high level Istios architecture has 2 main components:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Envoy proxies (dataplane)&lt;/strong&gt;: This is the data plane component of the solution. The Envoy proxy runs as a sidecar i.e. it runs alongside the main service in the pod to provide additional functionality which in our case is security, observability, resiliency and load balancing.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Istio Control Plane (istiod)&lt;/strong&gt;: So we have added those Envoy proxies, but we still need a central management &amp;amp; operations to manage all of those proxies at scale. Istiod or the Istio Control Plane actually fills this gap whereby it manages all of the configurations of the Envoy proxies. One of the reasons that Envoy was chosen as the sidecar for Istio deployment is its inherent ability to be dynamically configured via APIs. As a side note, when running Istio with Kubernetes, Istio automatically detects the services and their endpoints in that particular cluster and makes an entry for each service within its internal registry.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-istio-architecture.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Figure3. Istio Architecture&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-data-plane.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Figure4. Istio Data Plane&lt;/p&gt;&lt;p&gt;It is also worth noting that there is another mode of Istio named Ambient Mesh that removes the need of sidecars from the dataplane. More on this can be found &lt;a target=&quot;_blank&quot; href=&quot;https://istio.io/v1.15/blog/2022/introducing-ambient-mesh/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/cover2.jpg?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-quick-word-on-envoy&quot;&gt;Quick Word on Envoy&lt;/h2&gt;&lt;p&gt;I will end up this part by a very high level overview of how Envoy works. If you have done any work on Load Balancers, Envoy is pretty similar from a grand scheme of things.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Client or the requester is referred to as downstream.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Server is referred to as upstream.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Envoy just like any other Load Balancer, needs to have a listener whereby Envoy is waiting for requests that match a particular address or any address and a particular port. An example could be 0.0.0.0:80 whereby the listener will accept requests on any interface with a destination port of 80. Any request that doesnt hit the listener port is ignored by Envoy.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Once Envoy receives the packet on the listener, it subjects it to a Filter Chain i.e. a set of filters which determine how to deal with the incoming packet. You might want an L3/L4 Load Balancer and thus might use the TCP proxy filter or need forwarding based on L7 HTTP semantics with HTTP Connection Manager. TLS inspector is another commonly used filter to detect if the transport is plaintext or TLS and if TLS can detect Server Name Indication (SNI) and/or Application Layer Protocol Negotiation (ALPN). This filter chain, assuming the request is accepted, will most likely finalize by sending the request to the Clusters (Upstream components).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Clusters can be envisioned as collections of endpoints or targets. In a highly available application, a Cluster could comprise multiple Nginx web servers. Once a specific cluster is chosen, the remaining decision lies in selecting an endpoint within the cluster, typically governed by a load balancing policy.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-envoy-2.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Figure5. Envoy Constructs: Listeners, Filters, Clusters &amp;amp; Endpoints&lt;/p&gt;&lt;p&gt;In the upcoming part, well embark on a deep dive into the intricate workings of how Envoys proxy intercepts all traffic sourced and destined for the container.&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h2 id=&quot;heading-about-the-series&quot;&gt;About the Series&lt;/h2&gt;&lt;p&gt;In this two-part series, we embark on a journey into the realm of Istio, a powerful service mesh that has become integral to modern cloud-native applications. In this first installment, our focus will be on understanding the fundamental need for a service mesh, exploring the high-level architecture of Istio, and ending with a brief explanation of Envoy.&lt;/p&gt;&lt;p&gt;In the upcoming part, we will deep dive on a how the Envoy sidecar intercepts all traffic sourced or destined to the application container.&lt;/p&gt;&lt;h2 id=&quot;heading-from-monoliths-to-microservices&quot;&gt;From Monoliths to Microservices&lt;/h2&gt;&lt;p&gt;Unless you have been hiding under a rock, you would have heard about the shift from Monoliths to Microservices. Actually, this topic even gets revisited when migrating workloads to the cloud. While working as a Technical Account Manager (TAM) for AWS in the past, we worked with customers to come up with the optimum migration strategy for each workload or component. If this is a topic of interest you can find some details &lt;a target=&quot;_blank&quot; href=&quot;https://docs.aws.amazon.com/prescriptive-guidance/latest/large-migration-guide/migration-strategies.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-monolith.png?w=576&quot; alt /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-microservices.png?w=1024&quot; alt /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Figure2. Microservices distributed across multiple nodes&lt;/p&gt;&lt;p&gt;Now that we have shifted to running microservices across multiple nodes, a few arising challenges come to the picture:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network Performance&lt;/strong&gt;: The performance of the underlying network becomes pivotal in determining the quality of our applications user experience.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt;: With microservices communicating across networks, encryption becomes paramount to safeguard data in transit.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observability and Traceability&lt;/strong&gt;: This is another key concern in microservices where a transaction goes across these different components and we lose the visibility of an end-to-end user journey. The solution to this problem is distributed tracing . In addition, we will always need to have component level metrics &amp;amp; alerts.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identity &amp;amp; Zero Trust&lt;/strong&gt;: With the multitude of components and services running in a distributed fashion, we will need to strive to ensure that none of these components gets compromised and even if any of those components were to get compromised, we need to ensure that it cannot be used as a pivot to attack other critical services. This requires a solid identity foundation whereby each service has an identity and a role. Thus, any service to service call has to be authenticated &amp;amp; authorized with least privilege principle in mind. Advanced Load Balancing: Each of the components depicted as part of an application will have a number of replicas for purposes of scaling and high availability, thus at a minimum we will need to distribute load across all endpoints of a particular service in an efficient manner. This encompasses requests from external users or customers as well as requests between those microservices. Microservices allows pushing newer versions of individual components (billing, product details, ..etc) more frequently. This is another critical use-case for load balancing where for instance you can have 95% of requests target the stable version and only 5% target the updates versions and keep adjusting the weights based on your testing. Another possibility is sending your internal authenticated users to the new version and keeping external customers on the production/stable version.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resiliency&lt;/strong&gt;: As per the Principles of Chaos Engineering website, Chaos Engineering is the discipline of experimenting on a distributed system in order to build confidence in the systems capability to withstand turbulent conditions in production. Distributed complex systems are always prone to fail however our objective should be to stop the overall failure of the application or service we provide customers and end-users. Thus, we need tooling that will help application owners test their application in chaotic conditions whereby for instance a component responds with errors or delay a response and see the effect on the end-to-end user journey.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manageability&lt;/strong&gt;: Just like Kubernetes offers a single API to manage all resources, it is a must that all those capabilities (1-6) be centrally orchestrated.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These challenges birthed the need for a service mesh, with Istio emerging as the de facto solution. It might be interesting to note that prior to service mesh, attempts were made to solve those challenges with software libraries like Stubby and Hystrix.&lt;/p&gt;&lt;h2 id=&quot;heading-istio-architecture&quot;&gt;Istio Architecture&lt;/h2&gt;&lt;p&gt;At a high level Istios architecture has 2 main components:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Envoy proxies (dataplane)&lt;/strong&gt;: This is the data plane component of the solution. The Envoy proxy runs as a sidecar i.e. it runs alongside the main service in the pod to provide additional functionality which in our case is security, observability, resiliency and load balancing.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Istio Control Plane (istiod)&lt;/strong&gt;: So we have added those Envoy proxies, but we still need a central management &amp;amp; operations to manage all of those proxies at scale. Istiod or the Istio Control Plane actually fills this gap whereby it manages all of the configurations of the Envoy proxies. One of the reasons that Envoy was chosen as the sidecar for Istio deployment is its inherent ability to be dynamically configured via APIs. As a side note, when running Istio with Kubernetes, Istio automatically detects the services and their endpoints in that particular cluster and makes an entry for each service within its internal registry.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-istio-architecture.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Figure3. Istio Architecture&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-data-plane.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Figure4. Istio Data Plane&lt;/p&gt;&lt;p&gt;It is also worth noting that there is another mode of Istio named Ambient Mesh that removes the need of sidecars from the dataplane. More on this can be found &lt;a target=&quot;_blank&quot; href=&quot;https://istio.io/v1.15/blog/2022/introducing-ambient-mesh/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/cover2.jpg?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-quick-word-on-envoy&quot;&gt;Quick Word on Envoy&lt;/h2&gt;&lt;p&gt;I will end up this part by a very high level overview of how Envoy works. If you have done any work on Load Balancers, Envoy is pretty similar from a grand scheme of things.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Client or the requester is referred to as downstream.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The Server is referred to as upstream.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Envoy just like any other Load Balancer, needs to have a listener whereby Envoy is waiting for requests that match a particular address or any address and a particular port. An example could be 0.0.0.0:80 whereby the listener will accept requests on any interface with a destination port of 80. Any request that doesnt hit the listener port is ignored by Envoy.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Once Envoy receives the packet on the listener, it subjects it to a Filter Chain i.e. a set of filters which determine how to deal with the incoming packet. You might want an L3/L4 Load Balancer and thus might use the TCP proxy filter or need forwarding based on L7 HTTP semantics with HTTP Connection Manager. TLS inspector is another commonly used filter to detect if the transport is plaintext or TLS and if TLS can detect Server Name Indication (SNI) and/or Application Layer Protocol Negotiation (ALPN). This filter chain, assuming the request is accepted, will most likely finalize by sending the request to the Clusters (Upstream components).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Clusters can be envisioned as collections of endpoints or targets. In a highly available application, a Cluster could comprise multiple Nginx web servers. Once a specific cluster is chosen, the remaining decision lies in selecting an endpoint within the cluster, typically governed by a load balancing policy.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2023/11/kubernetes-ccm-overview-envoy-2.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Figure5. Envoy Constructs: Listeners, Filters, Clusters &amp;amp; Endpoints&lt;/p&gt;&lt;p&gt;In the upcoming part, well embark on a deep dive into the intricate workings of how Envoys proxy intercepts all traffic sourced and destined for the container.&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1702309026963/af1fb6c1-8e22-4d9a-ac53-c0bf41a0da2f.jpeg</hashnode:coverImage></item><item><title><![CDATA[Aviatrix Network Segmentation]]></title><description><![CDATA[Background on Network Segmentation
Network Segmentation (a.k.a VRFs) is a common theme in large enterprises and service providers.
Service Providers use segmentation at their Provider Edge (PE) routers whereby those PE(s) connect to multiple Customer...]]></description><link>https://jamali.hashnode.dev/aviatrix-network-segmentation</link><guid isPermaLink="true">https://jamali.hashnode.dev/aviatrix-network-segmentation</guid><category><![CDATA[Cloud Networking]]></category><category><![CDATA[networking]]></category><category><![CDATA[Network Architecture]]></category><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[GCP]]></category><dc:creator><![CDATA[Karim El Jamali]]></dc:creator><pubDate>Wed, 16 Feb 2022 05:00:00 GMT</pubDate><content:encoded>&lt;![CDATA[&lt;h1 id=&quot;heading-background-on-network-segmentation&quot;&gt;&lt;strong&gt;Background on Network Segmentation&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;Network Segmentation (a.k.a VRFs) is a common theme in large enterprises and service providers.&lt;/p&gt;&lt;p&gt;Service Providers use segmentation at their Provider Edge (PE) routers whereby those PE(s) connect to multiple Customer Edge (CE) routers while maintaining separate routing domains for each of those customers.&lt;/p&gt;&lt;p&gt;Enterprise environments generally have a multitude of services (Data, IP Telephony, IoT, CCTV, IPTVetc) whereby each service can run on its own dedicated infrastructure or have them all share a common infrastructure. In addition, multiple applications running on-premises and cloud have strict compliance and security requirements on segmentation &amp;amp; isolation.  One example of compliance requirement is The Payment Card Industry Data Security Standard (PCI DSS) which sets a widely accepted set of policies and procedures intended to optimize the security of credit, debit and cash card transactions and protect cardholders against misuse of their personal information. PCI DSS strongly recommends network segmentation or isolating the cardholder data environment from the rest of the network. On another note, the majority of customers run development and production environments and it is imperative for security, operations and compliance reasons to keep both environments isolated. Finally, overlapping addresses as a result of mergers &amp;amp; acquisitions (M&amp;amp;A) or poor planning are a common reality and at many times are dealt with via network segmentation and/or NAT.&lt;/p&gt;&lt;p&gt;One of the concerns of a common routing domain is a large blast radius whereby any problem involving routing injection or deletion could result in outages across all of these services. In addition, a common routing domain allows attackers to target specific IoT devices with a lower security posture and use those IoT devices to sneak into the crown jewels within the environment. Since most of these services operate independently of one another, a proper security policy would be to isolate them from one another thus improving the environments security posture.&lt;/p&gt;&lt;h1 id=&quot;heading-cloud-network-segmentation&quot;&gt;&lt;strong&gt;Cloud Network Segmentation&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;Let us start by looking at the below diagram. The diagram shows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;2 CSPs (AWS, Azure) and an on-prem environment.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;3 Virtual Machines (dev, prod and shared) in each of the spoke VPCs.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you would like to better understand the architecture, you can have a look here.&lt;/p&gt;&lt;p&gt;Without network segmentation, we operate in a common routing domain i.e. there is a common routing table for dev, prod and shared services allowing routing reachability between all 3 workloads. This however, doesnt always equate to data plane reachability as there are security constructs that can be leveraged to block this communication (Security Groups, Network Security Groups, NACLs, Firewalls).&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-1-4.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-common-routing-domain-explained&quot;&gt;&lt;strong&gt;Common Routing Domain Explained&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;The below diagram dives a bit further into the common routing domain (i.e. no segmentation). I have removed the workloads for simplicity, thus we have two spoke gateways (dev-1 and prod-1) connected to a common transit (transit-1). Note that in this setup, the transit has a common/default routing table that gets shared with the dev-1 and prod-1 spokes allowing any-to-any routing reachability.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-5-5.png?w=1022&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-segmenting-the-network&quot;&gt;&lt;strong&gt;Segmenting the Network&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;The below diagram segments the infrastructure to two network domains (Dev/Prod). Please note the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Transit routers will have all the routing tables (similar to a PE router) or Network Domains (Dev/Prod)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Upon attaching a spoke gateway (e.g. prod-1) to the transit gateway (transit-1) the transit gateway will associate the spoke gateway with a Network Domain (Prod) limiting its view of the world to the Prod search space or routing table. In this example, when traffic reaches the prod-1 GW from the prod instances they will be subject to the prod-1 routing table thus no communication is possible between prod &amp;amp; dev workloads.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It is important to realize that that this segmentation takes place at the transit layer i.e. any connection to the transit where the transit is enabled for segmentation can be associated or placed in a network domain limiting its search space.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-6-5.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-extending-segmentation-to-other-regions-and-clouds&quot;&gt;&lt;strong&gt;Extending Segmentation to other Regions and Clouds&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;The below figure expands the same logic to another transit. Two important points to recall here:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;All the segmentation we are talking about here is CSP agnostic and can extend to multiple regions, account and CSPs (AWS, Azure, GCP..etc)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;All the management and control plane is fully automated by the controller thus the controller fully manages all the gateway and CSP routing without any manual intervention.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-7-6.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-connection-policy&quot;&gt;&lt;strong&gt;Connection Policy&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Up till the last section, we have been able to isolate dev/prod workloads across all our multi-cloud architecture. In reality, customers tend to have shared services such as NTP, DNS, Syslog, Netflow Collectors..etc that service both their production and development environments. Thus, we need to ensure that both dev/prod remain isolated but able to access shared services. A connection policy is a way to leak routes between Network Domains to allow access to shared services as depicted in the figure below. Notice that the routing tables for both dev-1 and shared-svcs spoke gateways now have the routes to each other thus allowing communications from a routing plane. The same logic can be extended to prod, thus prod/dev cant communicate but they can communicate with shared-svcs.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-9-2.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-extending-segmentation-to-on-premises&quot;&gt;Extending Segmentation to On-Premises&lt;/h2&gt;&lt;p&gt;Now that we have extended our segmentation to all our cloud infrastructure, we would like to extend it to on-premises. In the below diagram the on-premises edge (on-prem RTR) has a Site2Cloud (S2C) connection to the transit. You can find more details about S2C here but for the purposes of our discussion, you can think of it like an IPSec tunnel with BGP running on top for route-exchange. In this setup, we would like to put the on-prem RTRs connection to the transit in a network domain (Prod) so that it can only access the prod workloads across the different CSPs.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-8-4.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-extending-multiple-segments-from-on-prem-to-cloud&quot;&gt;&lt;strong&gt;Extending Multiple Segments from On-Prem to Cloud&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;In the last section, we extended the Network Domain (prod) to on-premises. The below figure takes this a step further whereby we would like to extend all the segments from on-premises to Cloud thus enabling an end-to-end segmentation strategy. Manual VRF configuration and SDN Fabrics are both viable examples of implementing on-premises segmentation, and our goal is to extend those segments into our Multi-Cloud Network Architecture.&lt;/p&gt;&lt;p&gt;In the diagram the underlay RTR connection to the VGW is an IPSec tunnel but the same holds true for Direct Connect (DX). Please note the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;On the on-premises side, I have put two routers to clarify the example, however this could be done with a single router.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Think of the underlay RTR as building connectivity between the overlay RTR and the transit.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Underlay RTR in this example is running an IPSec tunnel with BGP to AWSs VGW thus sending all the routes including the two loopbacks that are originally advertised by the overlay RTR. Now transit-1 has reachability to Lo0 and Lo1 and overlay RTR has reachability to 10.100.0.0/16. Thus, we now have a connectivity between the overlay RTR and the transit-1.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that VGW has received the routes, we leverage route propagation in order to ensure these routes are advertised to transit-1 GW routing table. This is depicted in the diagram with the orange VPC router and its associated route table where all these routes are propagated. In addition, by default the transit-1 router has a default route pointing to the VPC router and thus able to reach the loopbacks advertised by the overlay router (100.100.100.1/32 &amp;amp; 100.100.100.2/32)&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-10-2.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Now that we have built the underlay connectivity between the overlay RTR, and transit-1 we can now build the GRE tunnels where one tunnel is sourced from lo0 and has a destination the private IP address of the transit that belongs to 10.100.0.0/16. This tunnel interface can be configured to be in VRF/Network Domain Dev. The same logic would follow for VRF prod leveraging lo1.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-11-1.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;The below diagram simplifies the explanation boiling it down to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;You need an underlay connectivity (sold red line) between the overlay RTR and Transit-1&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Once that connectivity is built, you can build multiple tunnels that utilize this underlay and place each of them in its own VRF/Network Domain&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The below figure shows two tunnels one for Dev Network Domain/VRF extension and the other one for Prod Network Domain/VRF extension.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-12.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-segmentation-made-simple&quot;&gt;&lt;strong&gt;Segmentation Made Simple&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;With all its capabilities and advanced use cases, one of Aviatrixs major values is simplicity where the controller abstracts many of the complexities within Cloud Networking. The below figure shows a network domain (Dev) being created, allowing the Dev Domain to connect to Shared-Svcs Domain and associating the Dev Domain with a spoke (aws-us-east-1-dev-1)&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/screen-shot-2022-07-26-at-9.08.50-am.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-check-it-out&quot;&gt;&lt;strong&gt;Check it Out&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;If you are keen on trying, I have created a github repository &lt;a target=&quot;_blank&quot; href=&quot;https://github.com/karimjamali/aviatrix-demo&quot;&gt;here&lt;/a&gt; that builds a lab infrastructure that you can use to test segmentation and other cool features and get acquainted with the platform. Sandbox Starter Tool is another great way to get acquainted with the platform. More information on this can be found &lt;a target=&quot;_blank&quot; href=&quot;https://community.aviatrix.com/t/g9hx9jh/aviatrix-cloud-sandbox-starter-spin-up-cloud-networks-in-minutes&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;]]&gt;</content:encoded><hashnode:content>&lt;![CDATA[&lt;h1 id=&quot;heading-background-on-network-segmentation&quot;&gt;&lt;strong&gt;Background on Network Segmentation&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;Network Segmentation (a.k.a VRFs) is a common theme in large enterprises and service providers.&lt;/p&gt;&lt;p&gt;Service Providers use segmentation at their Provider Edge (PE) routers whereby those PE(s) connect to multiple Customer Edge (CE) routers while maintaining separate routing domains for each of those customers.&lt;/p&gt;&lt;p&gt;Enterprise environments generally have a multitude of services (Data, IP Telephony, IoT, CCTV, IPTVetc) whereby each service can run on its own dedicated infrastructure or have them all share a common infrastructure. In addition, multiple applications running on-premises and cloud have strict compliance and security requirements on segmentation &amp;amp; isolation.  One example of compliance requirement is The Payment Card Industry Data Security Standard (PCI DSS) which sets a widely accepted set of policies and procedures intended to optimize the security of credit, debit and cash card transactions and protect cardholders against misuse of their personal information. PCI DSS strongly recommends network segmentation or isolating the cardholder data environment from the rest of the network. On another note, the majority of customers run development and production environments and it is imperative for security, operations and compliance reasons to keep both environments isolated. Finally, overlapping addresses as a result of mergers &amp;amp; acquisitions (M&amp;amp;A) or poor planning are a common reality and at many times are dealt with via network segmentation and/or NAT.&lt;/p&gt;&lt;p&gt;One of the concerns of a common routing domain is a large blast radius whereby any problem involving routing injection or deletion could result in outages across all of these services. In addition, a common routing domain allows attackers to target specific IoT devices with a lower security posture and use those IoT devices to sneak into the crown jewels within the environment. Since most of these services operate independently of one another, a proper security policy would be to isolate them from one another thus improving the environments security posture.&lt;/p&gt;&lt;h1 id=&quot;heading-cloud-network-segmentation&quot;&gt;&lt;strong&gt;Cloud Network Segmentation&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;Let us start by looking at the below diagram. The diagram shows:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;2 CSPs (AWS, Azure) and an on-prem environment.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;3 Virtual Machines (dev, prod and shared) in each of the spoke VPCs.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you would like to better understand the architecture, you can have a look here.&lt;/p&gt;&lt;p&gt;Without network segmentation, we operate in a common routing domain i.e. there is a common routing table for dev, prod and shared services allowing routing reachability between all 3 workloads. This however, doesnt always equate to data plane reachability as there are security constructs that can be leveraged to block this communication (Security Groups, Network Security Groups, NACLs, Firewalls).&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-1-4.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-common-routing-domain-explained&quot;&gt;&lt;strong&gt;Common Routing Domain Explained&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;The below diagram dives a bit further into the common routing domain (i.e. no segmentation). I have removed the workloads for simplicity, thus we have two spoke gateways (dev-1 and prod-1) connected to a common transit (transit-1). Note that in this setup, the transit has a common/default routing table that gets shared with the dev-1 and prod-1 spokes allowing any-to-any routing reachability.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-5-5.png?w=1022&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-segmenting-the-network&quot;&gt;&lt;strong&gt;Segmenting the Network&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;The below diagram segments the infrastructure to two network domains (Dev/Prod). Please note the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Transit routers will have all the routing tables (similar to a PE router) or Network Domains (Dev/Prod)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Upon attaching a spoke gateway (e.g. prod-1) to the transit gateway (transit-1) the transit gateway will associate the spoke gateway with a Network Domain (Prod) limiting its view of the world to the Prod search space or routing table. In this example, when traffic reaches the prod-1 GW from the prod instances they will be subject to the prod-1 routing table thus no communication is possible between prod &amp;amp; dev workloads.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;It is important to realize that that this segmentation takes place at the transit layer i.e. any connection to the transit where the transit is enabled for segmentation can be associated or placed in a network domain limiting its search space.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-6-5.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-extending-segmentation-to-other-regions-and-clouds&quot;&gt;&lt;strong&gt;Extending Segmentation to other Regions and Clouds&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;The below figure expands the same logic to another transit. Two important points to recall here:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;All the segmentation we are talking about here is CSP agnostic and can extend to multiple regions, account and CSPs (AWS, Azure, GCP..etc)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;All the management and control plane is fully automated by the controller thus the controller fully manages all the gateway and CSP routing without any manual intervention.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-7-6.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-connection-policy&quot;&gt;&lt;strong&gt;Connection Policy&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;Up till the last section, we have been able to isolate dev/prod workloads across all our multi-cloud architecture. In reality, customers tend to have shared services such as NTP, DNS, Syslog, Netflow Collectors..etc that service both their production and development environments. Thus, we need to ensure that both dev/prod remain isolated but able to access shared services. A connection policy is a way to leak routes between Network Domains to allow access to shared services as depicted in the figure below. Notice that the routing tables for both dev-1 and shared-svcs spoke gateways now have the routes to each other thus allowing communications from a routing plane. The same logic can be extended to prod, thus prod/dev cant communicate but they can communicate with shared-svcs.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-9-2.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-extending-segmentation-to-on-premises&quot;&gt;Extending Segmentation to On-Premises&lt;/h2&gt;&lt;p&gt;Now that we have extended our segmentation to all our cloud infrastructure, we would like to extend it to on-premises. In the below diagram the on-premises edge (on-prem RTR) has a Site2Cloud (S2C) connection to the transit. You can find more details about S2C here but for the purposes of our discussion, you can think of it like an IPSec tunnel with BGP running on top for route-exchange. In this setup, we would like to put the on-prem RTRs connection to the transit in a network domain (Prod) so that it can only access the prod workloads across the different CSPs.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-8-4.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h3 id=&quot;heading-extending-multiple-segments-from-on-prem-to-cloud&quot;&gt;&lt;strong&gt;Extending Multiple Segments from On-Prem to Cloud&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;In the last section, we extended the Network Domain (prod) to on-premises. The below figure takes this a step further whereby we would like to extend all the segments from on-premises to Cloud thus enabling an end-to-end segmentation strategy. Manual VRF configuration and SDN Fabrics are both viable examples of implementing on-premises segmentation, and our goal is to extend those segments into our Multi-Cloud Network Architecture.&lt;/p&gt;&lt;p&gt;In the diagram the underlay RTR connection to the VGW is an IPSec tunnel but the same holds true for Direct Connect (DX). Please note the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;On the on-premises side, I have put two routers to clarify the example, however this could be done with a single router.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Think of the underlay RTR as building connectivity between the overlay RTR and the transit.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Underlay RTR in this example is running an IPSec tunnel with BGP to AWSs VGW thus sending all the routes including the two loopbacks that are originally advertised by the overlay RTR. Now transit-1 has reachability to Lo0 and Lo1 and overlay RTR has reachability to 10.100.0.0/16. Thus, we now have a connectivity between the overlay RTR and the transit-1.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now that VGW has received the routes, we leverage route propagation in order to ensure these routes are advertised to transit-1 GW routing table. This is depicted in the diagram with the orange VPC router and its associated route table where all these routes are propagated. In addition, by default the transit-1 router has a default route pointing to the VPC router and thus able to reach the loopbacks advertised by the overlay router (100.100.100.1/32 &amp;amp; 100.100.100.2/32)&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-10-2.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;Now that we have built the underlay connectivity between the overlay RTR, and transit-1 we can now build the GRE tunnels where one tunnel is sourced from lo0 and has a destination the private IP address of the transit that belongs to 10.100.0.0/16. This tunnel interface can be configured to be in VRF/Network Domain Dev. The same logic would follow for VRF prod leveraging lo1.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-11-1.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;p&gt;The below diagram simplifies the explanation boiling it down to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;You need an underlay connectivity (sold red line) between the overlay RTR and Transit-1&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Once that connectivity is built, you can build multiple tunnels that utilize this underlay and place each of them in its own VRF/Network Domain&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The below figure shows two tunnels one for Dev Network Domain/VRF extension and the other one for Prod Network Domain/VRF extension.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/copy-of-learning-thursdays-page-12.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h2 id=&quot;heading-segmentation-made-simple&quot;&gt;&lt;strong&gt;Segmentation Made Simple&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;With all its capabilities and advanced use cases, one of Aviatrixs major values is simplicity where the controller abstracts many of the complexities within Cloud Networking. The below figure shows a network domain (Dev) being created, allowing the Dev Domain to connect to Shared-Svcs Domain and associating the Dev Domain with a spoke (aws-us-east-1-dev-1)&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://karimjamali.files.wordpress.com/2022/07/screen-shot-2022-07-26-at-9.08.50-am.png?w=1024&quot; alt /&gt;&lt;/p&gt;&lt;h1 id=&quot;heading-check-it-out&quot;&gt;&lt;strong&gt;Check it Out&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;If you are keen on trying, I have created a github repository &lt;a target=&quot;_blank&quot; href=&quot;https://github.com/karimjamali/aviatrix-demo&quot;&gt;here&lt;/a&gt; that builds a lab infrastructure that you can use to test segmentation and other cool features and get acquainted with the platform. Sandbox Starter Tool is another great way to get acquainted with the platform. More information on this can be found &lt;a target=&quot;_blank&quot; href=&quot;https://community.aviatrix.com/t/g9hx9jh/aviatrix-cloud-sandbox-starter-spin-up-cloud-networks-in-minutes&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;]]&gt;</hashnode:content><hashnode:coverImage>https://cdn.hashnode.com/res/hashnode/image/upload/v1702310950661/9ff60c3b-1568-42e7-956d-0364ce379eaf.webp</hashnode:coverImage></item></channel></rss>