Getting Started Pt 3

Getting Started with Autopilot Part 3 - Deploying the Operator

In part 3 of the Getting Started tutorial for AutoPilot, we’ll deploy and test our changes from part 2.

To see the completed code for this tutorial, check out




Build the Operator

Just like we did in part 1, let’s build and deploy the operator. Notice we deploy with the -d flag which tells Kubernetes to delete the existing operator pod (to trigger a fresh image pull)

ap build <image>
ap deploy <image> -p -d

We should see that our pod is running:

kubectl get pod -n autoroute-operator
NAME                                 READY   STATUS    RESTARTS   AGE
autoroute-operator-ccbd545c6-bb2s7   1/1     Running   0          1m

If you’ve still got the AutoRoute we deployed in part 1, you’ll notice that the pod is no longer in a CrashLoop. This is a good start. If you don’t have the “example” AutoRoute, deploy it again:

kubectl create ns example 
kubectl apply -n example -f deploy/autoroute_example.yaml

Let’s take a look at our logs again:

ap logs
{"level":"info","ts":1573835381.23586,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":9091"}
{"level":"info","ts":1573835381.2361934,"msg":"Registering watch for primary resource AutoRoute"}
{"level":"info","ts":1573835381.2362459,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"autoRoute-controller","source":"kind source: /, Kind="}
{"level":"info","ts":1573835381.2364664,"msg":"Registering watch for output resource Services"}
{"level":"info","ts":1573835381.236519,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"autoRoute-controller","source":"kind source: /, Kind="}
{"level":"info","ts":1573835381.2366421,"msg":"Registering watch for output resource VirtualServices"}
{"level":"info","ts":1573835381.2366784,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"autoRoute-controller","source":"kind source: /, Kind="}
{"level":"info","ts":1573835381.2367713,"msg":"Registering watch for output resource Gateways"}
{"level":"info","ts":1573835381.2368004,"logger":"controller-runtime.controller","msg":"Starting EventSource","controller":"autoRoute-controller","source":"kind source: /, Kind="}
{"level":"info","ts":1573835381.2370074,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"}
{"level":"info","ts":1573835397.8720093,"logger":"controller-runtime.controller","msg":"Starting Controller","controller":"autoRoute-controller"}
{"level":"info","ts":1573835397.9722834,"logger":"controller-runtime.controller","msg":"Starting workers","controller":"autoRoute-controller","worker count":1}
{"level":"info","ts":1573835743.5527482,"msg":"Syncing AutoRoute in phase Initializing","autoRoute":"example.example","phase":"","name":"example"}
{"level":"info","ts":1573835743.55888,"msg":"Syncing AutoRoute in phase Syncing","autoRoute":"example.example","phase":"Syncing","name":"example"}
{"level":"info","ts":1573835743.6597307,"msg":"cycle through each deployment and check that the labels match our selector","autoRoute":"example.example","phase":"Syncing"}
{"level":"info","ts":1573835743.6598568,"msg":"ensuring the gateway, services and virtual service outputs are created","autoRoute":"example.example","phase":"Syncing","status":{"syncedDeployments":null},"gateway":"example","virtual services":0,"kube services":0}
{"level":"info","ts":1573835743.6726131,"msg":"Updating status of primary resource","autoRoute":"example.example","phase":"Syncing"}
{"level":"info","ts":1573835743.6782513,"msg":"Syncing AutoRoute in phase Ready","autoRoute":"example.example","phase":"Ready","name":"example"}
{"level":"info","ts":1573835743.67874,"msg":"cycle through each deployment and check that the labels match our selector","autoRoute":"example.example","phase":"Ready"}

Now we see that our operator processed the AutoRoute. The AutoRoute was synced and is now in state ready:

kubectl get autoroute -n example -oyaml example
kind: AutoRoute
  creationTimestamp: "2019-11-15T16:35:43Z"
  generation: 1
    app: autoroute-operator autoroute-operator
  name: example
  namespace: example
  resourceVersion: "394326"
  selfLink: /apis/
  uid: f7cba80e-07c5-11ea-beb2-42010a8e0142
  observedGeneration: 1
  phase: Ready
  syncedDeployments: null

We should also see that our operator created a Gateway:

kubectl get -n example
example   11m

We expect no Virtual Services or Kube Services to be created yet. Let’s create a few deployments to see them get spun up:

for i in 1 2 3; do 
cat <<EOF | kubectl apply -n example -f -
apiVersion: apps/v1
kind: Deployment
  name: httpbin-${i}
  replicas: 1
      app: httpbin-${i}
        app: httpbin-${i}
        - image:
          imagePullPolicy: IfNotPresent
          name: httpbin
            - containerPort: 80
deployment.apps/httpbin-1 created
deployment.apps/httpbin-2 created
deployment.apps/httpbin-3 created

If everything worked, we should immediately be able to hit these deployments with traffic! Let’s try it out.

First, we need the IP:PORT of the Istio Ingress. The way we reach this depends on your environment setup

Finally, send some requests using curl:

curl -I -HHost:httpbin-1.example http://$INGRESS_HOST:$INGRESS_PORT/status/200
curl -I -HHost:httpbin-2.example http://$INGRESS_HOST:$INGRESS_PORT/status/200
curl -I -HHost:httpbin-3.example http://$INGRESS_HOST:$INGRESS_PORT/status/200

All 3 of our services should reply with HTTP/1.1 200 OK:

HTTP/1.1 200 OK
server: istio-envoy
date: Fri, 15 Nov 2019 17:34:05 GMT
content-type: text/html; charset=utf-8
access-control-allow-origin: *
access-control-allow-credentials: true
content-length: 0
x-envoy-upstream-service-time: 1

Awesome! We’ve just automated our Istio ingress with Autopilot!

We can see that the AutoRoute automatically created some Istio Virtual Serivces:

kubectl get -n example
NAME                GATEWAYS    HOSTS                 AGE
httpbin-1.example   [example]   [httpbin-1.example]   2m
httpbin-2.example   [example]   [httpbin-2.example]   2m
httpbin-3.example   [example]   [httpbin-3.example]   2m

As well as standard Kube services:

kubectl get svc -n example
httpbin-1   ClusterIP   <none>        80/TCP    4m51s
httpbin-2   ClusterIP   <none>        80/TCP    4m51s
httpbin-3   ClusterIP    <none>        80/TCP    4m51s

Tearing down

To tear down the example environment:

kubectl delete ns example
kubectl delete ns autorouter-operator
kubectl delete crd


This guide provides a demonstration on how Autopilot can be used to automate Mesh features. For a more robust, real-world example, see the Autopilot Canary Project, which is used as an automated end-to-end test for Autopilot.

Please submit questions and feedback to the slack channel, or open an issue on GitHub.