Helm Dashboard is an open-source project which graphically shows installed Helm charts, revisions, and changes to their Kubernetes resources.
The intents operator is an open-source Kubernetes operator which makes it possible to roll out network policies in a Kubernetes cluster, chart by chart, and gradually achieve zero trust or network segmentation.
Modern engineering organizations may want to achieve network segmentation as part of adhering to the OWASP Kubernetes Top 10 recommendations, in particular, K07: Missing Network Segmentation Controls, where Kubernetes network policies and service meshes are the recommended way to achieve segmentation controls.
Network policies are notoriously hard to manage, requiring you to label all client services and server services, and then create an ingress network policy for each server.
This means that each server’s chart would need to reference labels for services that live in other charts – this can be difficult to achieve and requires coordination across multiple teams, since different charts may be owned by different teams.
For example, here’s a network policy that allows access to multiple services, owned by two teams,
team1, to a server owned by
team3. Notice how it refers to pod labels in the
`from` and the
This network policy would live in the Helm chart for the
`ledger` service, owned by
team3. The labels for the other two services, which call the
`ledger`, would need to be in the other charts that deploy those services. This means that the 3 teams would need to coordinate the deployment of all three services, so that the labels appear on all services first, then the network policy is added. If the network policy is added before all the labels are verified to be there, then whoever is misconfigured will be blocked.
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-access-to-ledger namespace: team3 spec: ingress: - from: - namespaceSelector: matchLabels: namespace-name: team1 podSelector: matchLabels: how-team1-labels-their-pods: transaction-service - namespaceSelector: matchLabels: namespace-name: team2 podSelector: matchLabels: how-team2-labels-their-pods: some-other-transaction-service podSelector: matchLabels: how-team3-labels-their-pods: ledger policyTypes: - Ingress
Managing so many charts can be taxing and time-consuming even for the most seasoned engineers, but Helm-Dashboard’s visualization of charts makes it easy to correlate them with Kubernetes resources, compare different versions, and quickly rollback or upgrade. In a use case similar to the example above, you could leverage Helm-Dashboard to update the charts and enforce standardization. If something breaks, you can be confident that you’re one click away from rolling back to a working version of the charts.
What if you’ve done all that hard work of coordinating the different charts and different teams, and now due to an unrelated problem, you want to roll back the server? This would result in also rolling back the network policy for the server, since that’s part of the same Helm chart, blocking any clients who were allowed by the newer network policy. But you may not want that: the rollback will often happen due to an unrelated reason, such as a bug.
With the intents operator, you can declare a separate resource for each client, and the operator then collects those into a network policy per server. This is more in line with how people manage Helm charts – each client is managed on its own, without affecting other Helm charts.
Instead of the network policy we saw before, where the server declares which clients can access, we’ll now have two ClientIntents resources that declare which servers the clients want to access.
transaction-service in namespace
team1, we will declare we want to access the ledger in namespace
apiVersion: k8s.otterize.com/v1alpha2 kind: ClientIntents metadata: name: transaction-service-intents namespace: team1 spec: service: name: transaction-service calls: - name: ledger.team3 For some-other-transaction-service in namespace team2, we will also declare we want to access ledger in namespace team3: apiVersion: k8s.otterize.com/v1alpha2 kind: ClientIntents metadata: name: some-other-transaction-service-intents namespace: team2 spec: service: name: transaction-service calls: - name: ledger.team3
Once you apply these
ClientIntents, both the client and server pods are labeled, and a network policy is created for the server. The server’s chart did not have to change! How cool is that?
For each client namespace,
team2, the following network policies were created in namespace
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: labels: intents.otterize.com/network-policy: ledger-team3-7e16db name: access-to-ledger-from-team1 namespace: team3 spec: ingress: - from: - namespaceSelector: matchLabels: intents.otterize.com/namespace-name: team1 podSelector: matchLabels: intents.otterize.com/access-ledger-team3-7e16db: "true" podSelector: matchLabels: intents.otterize.com/server: ledger-team3-7e16db policyTypes: - Ingress
And the client pods,
some-other-transaction-service, had this label applied to them automatically:
While the server, ledger, had this label applied to it automatically:
Now that each chart contains only the intended access for the services managed within it, you can diff the chart and track changes over time. If you see that a service is being blocked, you can check its chart and see what’s changed.
In this example, let’s look how we can determine what happened when we see that the
transaction-service is no longer able to connect to
ledger. We need only look at
transaction-service’s chart. Let’s do that using Helm-Dashboard:
Oh no! It looks like somebody accidentally removed the
ledger service from the
ClientIntents while adding the telemetry service. Let’s correct it:
With Komodor, you’ll be able to see that a service is unable to call another service, and then see whether its
ClientIntents changed – which could be the cause for it being blocked, or if its code has changed and it now requires different access, you could use Otterize to map existing traffic, and autogenerate the new client intents:
~ ❯ otterize mapper export -n team1 -n team2 apiVersion: k8s.otterize.com/v1alpha2 kind: ClientIntents metadata: name: some-other-transaction-service namespace: team2 spec: service: name: some-other-transaction-service calls: - name: ledger.team3 --- apiVersion: k8s.otterize.com/v1alpha2 kind: ClientIntents metadata: name: transaction-service namespace: team1 spec: service: name: transaction-service calls: - name: ledger.team3
Try out Otterize with Helm Dashboard – both are completely open source and super simple to get started with. Use the mapper export feature of Otterize to generate
ClientIntents for one of your charts, and get to zero trust in no time.
Stay tuned for more news from Komodor and Otterize! We have an exciting announcement coming up soon 🤫 In the meantime check out this post by Otterize: why Network Policies are Hard for Developers: https://otterize.com/blog/network-policies-are-not-the-right-abstraction