Istio Beacon
Channel | Revision | Published | Runs on |
---|---|---|---|
1/stable | 34 | 05 Aug 2025 | |
1/candidate | 34 | 08 Jul 2025 | |
1/beta | 34 | 26 Jun 2025 | |
1/edge | 34 | 24 Jun 2025 | |
2/edge | 45 | 11 Sep 2025 |
juju deploy istio-beacon-k8s --channel 1/stable
Deploy Kubernetes operators easily with Juju, the Universal Operator Lifecycle Manager. Need a Kubernetes cluster? Install MicroK8s to create a full CNCF-certified Kubernetes system in under 60 seconds.
Platform:
charms.istio_beacon_k8s.v0.service_mesh
-
- Last updated 11 Sep 2025
- Revision Library version 0.9
Service Mesh Library.
This library facilitates adding your charmed application to a service mesh, leveraging the
service_mesh
and cross_model_mesh
interfaces to provide secure, policy-driven traffic
management between applications.
Overview
Service meshes provide capabilities for routing, controlling, and monitoring traffic between
applications. A key feature is the ability to restrict traffic between Pods. For example, you can define that Pod MetricsScraper can GET
from Pod MetricsProducer
at /metrics
on port 9090
, while preventing SomeOtherPod from accessing it.
Consumer
The ServiceMeshConsumer object subscribes a charm and its workloads to a related service mesh.
Since application relations often indicate traffic flow patterns (e.g., DbConsumer requiring
DbProducer), ServiceMeshConsumer provides automated creation of traffic rules based on
application relations.
The ServiceMeshConsumer implements the requirer
side of the juju relation.
Setup
First, add the required relations to your charmcraft.yaml
:
requires:
service-mesh:
limit: 1
interface: service_mesh
description: |
Subscribe this charm into a service mesh to enforce authorization policies.
require-cmr-mesh:
interface: cross_model_mesh
description: |
Allow a cross-model application access to catalogue via the service mesh.
This relation provides additional data required by the service mesh to enforce cross-model authorization policies.
provides:
provide-cmr-mesh:
interface: cross_model_mesh
description: |
Access a cross-model application from catalogue via the service mesh.
This relation provides additional data required by the service mesh to enforce cross-model authorization policies.
Instantiate a ServiceMeshConsumer object in your charm's __init__
method:
from charms.istio_beacon_k8s.v0.service_mesh import Method, Endpoint, AppPolicy, UnitPolicy, ServiceMeshConsumer
class MyCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
self._mesh = ServiceMeshConsumer(
self,
policies=[
AppPolicy(
relation="data",
endpoints=[
Endpoint(
ports=[HTTP_LISTEN_PORT],
methods=[Method.get],
paths=["/data"],
),
],
),
UnitPolicy(
relation="metrics",
ports=[HTTP_LISTEN_PORT],
),
],
)
This example creates two policies:
- An app policy - When related over the
data
relation, allow the related application toGET
this application's/data
endpoint on the specified port through the app's Kubernetes service. - A unit policy - When related over the
metrics
relation, allow the related application to access this application's unit pods directly on the specified port without any other restriction. UnitPolicy does not support fine-grained access control on the methods and paths viaEndpoints
.
An AppPolicy can be used to control how the source application can communicate with the target application via the app address. A UnitPolicy allows access to the specified port but only to the unit pods of the charm via individual unit addresses.
Cross-Model Relations
To request service mesh policies for cross-model relations, additional information is required.
For any charm that wants to grant access to a related application (say, the above example
charm providing a data
relation), these charms must also implement and relate over the
cross_model_mesh
relation. For cross_model_mesh
, the charm granting access should be the
provider, and the charm trying to communicate should be the requirer.
Joining the Mesh
For most charms, instantiating ServiceMeshConsumer automatically configures the charm
to join the mesh. For legacy "podspec" style charms or charms deploying custom
Kubernetes resources, you must manually apply the labels returned by
ServiceMeshConsumer.labels()
to your pods.
Provider
The ServiceMeshProvider implements the provider side of the juju relation. To provide a service mesh, instantiate ServiceMeshProvider in your charm's __init__
method:
from charms.istio_beacon_k8s.v0.service_mesh import ServiceMeshProvider
class MyServiceMeshCharm(CharmBase):
def __init__(self, *args):
super().__init__(*args)
self._mesh = ServiceMeshProvider(
charm=self,
labels={"istio.io/dataplane-mode": "ambient"},
mesh_relation_name="service-mesh",
)
Configuration
The labels
argument specifies the labels that indicate to the service mesh that a Pod
should be subscribed to the mesh. These labels are service-mesh specific, for eg.:
- For Istio ambient mesh:
{"istio.io/dataplane-mode": "ambient"}
- For Istio sidecar mesh:
{"istio-injection": "enabled"}
Accessing Mesh Policies
The provider exposes the mesh_info()
method that returns a list of MeshPolicy objects
for configuring the service mesh:
for policy in self._mesh.mesh_info():
configure_service_mesh_policy(policy)
Data Models
- Method: Defines enum for HTTP methods (GET, POST, PUT, etc.)
- Endpoint: Defines traffic endpoints with hosts, ports, methods, and paths
- AppPolicy: Defines application level authorization policy for the consumer
- UnitPolicy: Defines unit level authorization policy for the consumer
- MeshPolicy: Contains complete policy information for mesh configuration
- CMRData: Contains cross-model relation metadata
class Method
Description
HTTP method. None
class Endpoint
Description
Data type for a policy endpoint. None
class PolicyTargetType
Description
Target type for Policy classes. None
class Policy
Description
Data type for defining a policy for your charm. None
Methods
Policy. __init__( self )
class AppPolicy
Description
Data type for defining a policy for your charm application. None
class UnitPolicy
Description
Data type for defining a policy for your charm unit. None
class MeshPolicy
Description
Data type for storage service mesh policy information. None
class CMRData
Description
Data type containing the info required for cross-model relations. None
class ServiceMeshConsumer
Description
Class used for joining a service mesh. None
Methods
ServiceMeshConsumer. __init__( self , charm: CharmBase , mesh_relation_name: str , cross_model_mesh_requires_name: str , cross_model_mesh_provides_name: str , policies , auto_join: bool )
Class used for joining a service mesh.
Arguments
The charm instantiating this object.
The relation name as defined in metadata.yaml or charmcraft.yaml for the relation which uses the service_mesh interface.
The relation name as defined in metadata.yaml or charmcraft.yaml for the relation which requires the cross_model_mesh interface.
The relation name as defined in metadata.yaml or charmcraft.yaml for the relation which provides the cross_model_mesh interface.
List of access policies this charm supports.
Automatically join the mesh by applying labels to charm pods.
ServiceMeshConsumer. update_service_mesh( self )
Update the service mesh.
Description
Gathers information from all relations of the charm and updates the mesh appropriately to allow communication.
ServiceMeshConsumer. labels( self )
Description
Labels required for a pod to join the mesh. None
ServiceMeshConsumer. lightkube_client( self )
Returns a lightkube client configured for this library.
Description
This indirection is implemented to avoid complex mocking in integration tests, allowing the integration tests to do something equivalent to: ```python mesh_consumer = ServiceMeshConsumer(...) mesh_consumer._lightkube_client = mocked_lightkube_client
class ServiceMeshProvider
Description
Provide a service mesh to applications. None
Methods
ServiceMeshProvider. __init__( self , charm: CharmBase , labels , mesh_relation_name: str )
Class used to provide information needed to join the service mesh.
Arguments
The charm instantiating this object.
The relation name as defined in metadata.yaml or charmcraft.yaml for the relation which uses the service_mesh interface.
The labels which related applications need to apply to use the mesh.
ServiceMeshProvider. update_relations( self )
Description
Update all relations with the labels needed to use the mesh. None
ServiceMeshProvider. mesh_info( self )
Description
Return the relation data that defines Policies requested by the related applications. None
def
build_mesh_policies(
relation_mapping: RelationMapping,
target_app_name: str,
target_namespace: str,
policies,
cmr_application_data
)
Generate MeshPolicy that implement the given policies for the currently related applications.
Arguments
Charm's RelatioMapping object, for example self.model.relations.
The name of the target application, for example self.app.name.
The namespace of the target application, for example self.model.name.
List of AppPolicy, or UnitPolicy objects defining the access rules.
Data for cross-model relations, mapping app names to CMRData.
def
reconcile_charm_labels(
client: Client,
app_name: str,
namespace: str,
label_configmap_name: str,
labels
)
Reconciles zero or more user-defined additional Kubernetes labels that are put on a Charm's Kubernetes objects.
Arguments
The lightkube Client to use for Kubernetes API calls.
The name of the application (Charm) to reconcile labels for.
The namespace in which the application is running.
The name of the ConfigMap that stores the labels.
A dictionary of labels to set on the Charm's Kubernetes objects. Any labels that were previously created
by this method but omitted in labels
now will be removed from the Kubernetes objects.
Description
This function manages a group of user-defined labels that are added to a Charm's Kubernetes objects (the charm Pods (via editing the StatefulSet) and Service). Its primary uses are:
- adding labels to a Charm's objects
- updating or removing labels on a Charm's Kubernetes objects that were previously set by this method
To enable removal of labels, we also create a ConfigMap that stores the labels we last set. This way the function itself can be stateless.
This function takes a little care to avoid removing labels added by other means, but it does not provide exhaustive guarantees for safety. It is up to the caller to ensure that the labels they pass in are not already in use.