Ambassador Operator (Operator-SDK 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 the Operator SDK, Kubebuilder, and Metacontroller. As a use case, three different yet functionally equivalent Ambassador operators were created, one with each tool. This repository was built with the Operator SDK v0.0.5.
Getting Started
- 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 5 below.
- Install ambassador-shim-operator-sdk, which consists of:
- a CustomResourceDefinition: Mapping,
- a one-replica Deployment: the operator,
- RBAC for the operator to control Mappings and Services.
kubectl apply -f https://raw.githubusercontent.com/admiraltyio/ambassador-shim-operator-sdk/master/deploy/operator.yaml
kubectl apply -f https://raw.githubusercontent.com/admiraltyio/ambassador-shim-operator-sdk/master/deploy/rbac.yaml
- Deploy the sample: a stock NGINX Deployment and corresponding Service and Mapping:
kubectl apply -f https://raw.githubusercontent.com/admiraltyio/ambassador-shim-operator-sdk/master/examples/getting_started/ambassadorshim_v1alpha1_mapping.yaml
- 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
- 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