1. Applying Fine-grained Network Controls to JupyterHub with CiliumNetworkPolicy


    To apply fine-grained network controls to a JupyterHub instance with CiliumNetworkPolicy, you will first need a Kubernetes cluster with Cilium installed as the CNI (Container Network Interface) plugin. Cilium leverages BPF (Berkeley Packet Filters) to provide highly performant and scalable network policy enforcement.

    The CiliumNetworkPolicy resource allows you to define both ingress and egress rules applied to selected pod endpoints based on labels. These policies can control both the traffic flow within the Kubernetes cluster as well as the traffic to external services.

    Here's an overview of what we're going to do:

    1. Define a CiliumNetworkPolicy resource to control network traffic for JupyterHub.
    2. Apply label selectors to specify the pods to which the policies will apply.
    3. Define ingress and egress rules within the policy.
    4. Implement namespace isolation if needed.

    In this program, I'll showcase how you could use Pulumi to define a CiliumNetworkPolicy for JupyterHub. Please note, this code assumes you have a Kubernetes cluster set up with Cilium, and JupyterHub running inside your cluster.

    import pulumi import pulumi_kubernetes as k8s # Create a Kubernetes provider instance using the current context from local kubeconfig k8s_provider = k8s.Provider("k8s_provider") # Define a CiliumNetworkPolicy to allow ingress connections to JupyterHub on port 8000 jupyterhub_cilium_network_policy = k8s.cilium.v1.CiliumNetworkPolicy("jupyterhub-cilium-netpol", metadata=k8s.meta.v1.ObjectMetaArgs( name="allow-jupyterhub", namespace="jupyterhub", # assuming JupyterHub is deployed in this namespace ), spec=k8s.cilium.v1.CiliumNetworkPolicySpecArgs( endpoint_selector=k8s.cilium.v1.EndpointSelectorArgs( match_labels={"app": "jupyterhub"}, # matching the label of the JupyterHub pods ), ingress=[k8s.cilium.v1.IngressRuleArgs( from_endpoints=[k8s.cilium.v1.EndpointSelectorArgs( match_labels={"role": "user-notebooks"}, # allowing traffic from user notebooks )], to_ports=[k8s.cilium.v1.PortRuleArgs( ports=[k8s.cilium.v1.PortProtocolArgs( port="8000", protocol="TCP", )], )], )], # If you need egress rules, you can define them similar to ingress rules. ), opts=pulumi.ResourceOptions(provider=k8s_provider) ) pulumi.export('jupyterhub_policy_name', jupyterhub_cilium_network_policy.metadata["name"])

    In the program above:

    • We import the required Pulumi libraries for Kubernetes.
    • We create a provider for Kubernetes which will use the local kubeconfig context.
    • We define a CiliumNetworkPolicy named allow-jupyterhub.
    • We set a label selector to apply the policy to pods running JupyterHub based on the app: jupyterhub label.
    • We define an ingress rule allowing TCP traffic on port 8000 from pods with the label role: user-notebooks, which we assume represent the user notebook instances connected to JupyterHub.
    • We export the name of the created network policy for reference.

    By using this policy, you ensure that only user notebook pods can access the JupyterHub service on the specified port. You can adjust the labels and ports according to your setup.

    Remember, you must have the Cilium CNI plugin installed for this policy to be enforceable. If not yet installed, reference the Cilium Getting Started Guide for instructions on how to get it up and running in your cluster.