What you'll need


Steps

  1. Gloo and Envoy installed and running on Kubernetes.

  2. Next, deploy the Pet Store app to kubernetes:

    kubectl apply \
      -f https://raw.githubusercontent.com/solo-io/gloo/master/example/petstore/petstore.yaml
    
  3. The discovery services should have already created an Upstream for the petstore service. Let's verify this:

    glooctl get upstreams
    
    +--------------------------------+------------+----------+------------------------------+
    |            UPSTREAM            |    TYPE    |  STATUS  |           DETAILS            |
    +--------------------------------+------------+----------+------------------------------+
    | default-kubernetes-443         | Kubernetes | Accepted | svc name:      kubernetes    |
    |                                |            |          | svc namespace: default       |
    |                                |            |          | port:          8443          |
    |                                |            |          |                              |
    | default-petstore-8080          | Kubernetes | Accepted | svc name:      petstore      |
    |                                |            |          | svc namespace: default       |
    |                                |            |          | port:          8080          |
    |                                |            |          | REST service:                |
    |                                |            |          | functions:                   |
    |                                |            |          | - addPet                     |
    |                                |            |          | - deletePet                  |
    |                                |            |          | - findPetById                |
    |                                |            |          | - findPets                   |
    |                                |            |          |                              |
    | gloo-system-gateway-proxy-8080 | Kubernetes | Accepted | svc name:      gateway-proxy |
    |                                |            |          | svc namespace: gloo-system   |
    |                                |            |          | port:          8080          |
    |                                |            |          |                              |
    | gloo-system-gloo-9977          | Kubernetes | Accepted | svc name:      gloo          |
    |                                |            |          | svc namespace: gloo-system   |
    |                                |            |          | port:          9977          |
    |                                |            |          |                              |
    | gloo-system-rate-limit-18081   | Kubernetes | Accepted | svc name:      rate-limit    |
    |                                |            |          | svc namespace: gloo-system   |
    |                                |            |          | port:          18081         |
    |                                |            |          |                              |
    | gloo-system-redis-6379         | Kubernetes | Accepted | svc name:      redis         |
    |                                |            |          | svc namespace: gloo-system   |
    |                                |            |          | port:          6379          |
    |                                |            |          |                              |
    +--------------------------------+------------+----------+------------------------------+
    

    The upstream we want to see is default-petstore-8080. Digging a little deeper, we can verify that Gloo's function discovery populated our upstream with the available rest endpoints it implements. Note: the upstream was created in the gloo-system namespace rather than default because it was created by a discovery service. Upstreams and virtualservices do not need to live in the gloo-system namespace to be processed by Gloo.


  4. Let's take a closer look at the functions that are available on this upstream (edited here to reduce verbosity):

    ---
    discoveryMetadata: {}
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"sevice":"petstore"},"name":"petstore","namespace":"default"},"spec":{"ports":[{"port":8080,"protocol":"TCP"}],"selector":{"app":"petstore"}}}
      labels:
        discovered_by: kubernetesplugin
        sevice: petstore
      name: default-petstore-8080
      namespace: gloo-system
      resourceVersion: "433242"
    status:
      reportedBy: gloo
      state: Accepted
    upstreamSpec:
      kube:
        selector:
          app: petstore
        serviceName: petstore
        serviceNamespace: default
        servicePort: 8080
        serviceSpec:
          rest:
            swaggerInfo:
              url: http://petstore.default.svc.cluster.local:8080/swagger.json
            transformations:
              addPet:
                body:
                  text: '{"id": {{ default(id, "") }},"name": "{{ default(name, "")}}","tag":
                    "{{ default(tag, "")}}"}'
                headers:
                  :method:
                    text: POST
                  :path:
                    text: /api/pets
                  content-type:
                    text: application/json
              deletePet:
                headers:
                  :method:
                    text: DELETE
                  :path:
                    text: /api/pets/{{ default(id, "") }}
                  content-type:
                    text: application/json
              findPetById:
                body: {}
                headers:
                  :method:
                    text: GET
                  :path:
                    text: /api/pets/{{ default(id, "") }}
                  content-length:
                    text: "0"
                  content-type: {}
                  transfer-encoding: {}
              findPets:
                body: {}
                headers:
                  :method:
                    text: GET
                  :path:
                    text: /api/pets?tags={{default(tags, "")}}&limit={{default(limit,
                      "")}}
                  content-length:
                    text: "0"
                  content-type: {}
                  transfer-encoding: {}
    

    The details of this application were discovered by Gloo's Function Discovery (fds) service. Because the petstore application implements OpenAPI (specifically discovering a Swagger JSON document on petstore-svc/swagger.json). Because some functions were discovered for us, we can practice some function in the next tutorial.

  5. Let's now use glooctl to create a basic route for this upstream.

    glooctl add route \
      --path-exact /sample-route-1 \
      --dest-name default-petstore-8080 \
      --prefix-rewrite /api/pets
    

    We use the --prefix-rewrite to rewrite path on incoming requests to match the paths our petstore expects.

    Note that we have omitted the --name flag for selecting a virtual service. Routes are always assoicated with a Virtual Service in Gloo, which groups routes by their domain. Since we skipped creating a virtual service for this route, my-virtual-service will be created automatically for us.

    With glooctl, we can see that a virtual service was created with our route:

    glooctl get virtualservice -o yaml
    ---
    metadata:
      name: my-virtual-service
      namespace: gloo-system
      resourceVersion: "5520"
    status:
      reportedBy: gateway
      state: Accepted
      subresourceStatuses:
        '*v1.Proxy gloo-system gateway-proxy':
          reportedBy: gloo
          state: Accepted
    virtualHost:
      domains:
      - '*'
      name: gloo-system.my-virtual-service
      routes:
      - matcher:
          exact: /sample-route-1
        routeAction:
          single:
            upstream:
              name: default-petstore-8080
              namespace: gloo-system
        routePlugins:
          prefixRewrite:
            prefixRewrite: /api/pets
    

    Note that you can add routes interactively using glooctl add route -i. This is a great way to explore Gloo's configuration options from the CLI.

  6. Let's test the route /sample-route-1 using curl:

    export GATEWAY_URL=$(glooctl gateway url)
    curl ${GATEWAY_URL}/sample-route-1
    
    [{"id":1,"name":"Dog","status":"available"},{"id":2,"name":"Cat","status":"pending"}]
    

Great! our gateway is up and running. Let's make things a bit more sophisticated in the next section with Function Routing.