Experimental Ambassador Operator built with Metacontroller
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Ambassador Operator (Metacontroller version)

Project Status: Experimental

Ambassador, the "Kubernetes-native API gateway for microservices built on Envoy", currently pulls its configuration (mainly Mappings of URL prefixes to Kubernetes Services) from annotations on Services; I wanted Ambassador to be even more Kubernetes native, so I've created a Mapping CRD and a controller that maintains a dummy Service for each Mapping, annotated according to the Mapping's Spec.

From "Kubernetes Custom Resource, Controller and Operator Development Tools" (Admiralty blog); the post discusses Metacontroller, Kubebuilder, and the Operator SDK. As a use case, three different yet functionally equivalent Ambassador operators were created, one with each tool. This repository was built with Metacontroller v0.2.0.

Getting Started

  1. Install Ambassador (steps 1 and 2). N.B.: you may have to wait a few minutes before the Ambassador Service's external IP is provisioned, but keep going, it's only blocking for step 6 below.
  2. Install Metacontroller.
  3. Install ambassador-shim-metacontroller, which consists of:
    • a CustomResourceDefinition: Mapping,
    • a CompositeController that hooks to
    • a Service, backed by a Deployment, which implements the Mapping controller:
    kubectl apply -f https://raw.githubusercontent.com/admiraltyio/ambassador-shim-metacontroller/master/kustomize/kustomized.yaml
    If you need more flexibility, you can build your own manifest from the different parts in the repository; if you use kustomize, you can start from kustomize/kustomization.yaml.
  4. Deploy the sample: a stock NGINX Deployment and corresponding Service and Mapping:
    kubectl apply -f https://raw.githubusercontent.com/admiraltyio/ambassador-shim-metacontroller/master/examples/mapping/ambassadorshim_v1alpha1_mapping.yaml
  5. Verify that the Mapping was configured and is up-to-date, i.e., that a corresponding dummy Service was created and properly annotated:
    kubectl get mapping foo -o yaml
    kubectl get service foo-ambassadorshim -o yaml
  6. Once the external IP from step 1 is provisioned, you can access the foo service at /foo/:
    EXTERNAL_IP=$(kubectl get service ambassador -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
    curl http://$EXTERNAL_IP/foo/

Next Steps

This shim is a proof of concept that only supports the most basic feature of Ambassador: mapping a prefix to a Service. It could be expanded (full Mapping Spec and Status, other CRDs, etc.) into a fully-featured side-car of Ambassador, or merge with it. See the full discussion in the blog post.

See Also