Skip to content

Commit

Permalink
feat(k8s): support custom hostnames and TLS certs
Browse files Browse the repository at this point in the history
  • Loading branch information
edvald committed Sep 4, 2018
1 parent cab28e1 commit 1c004f7
Show file tree
Hide file tree
Showing 92 changed files with 2,578 additions and 668 deletions.
30 changes: 15 additions & 15 deletions docs/examples/simple-project.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Simple Project
# Simple Project

In this guide, we'll walk you through configuring a simple project to run on the Garden framework. The project will consist of two Dockerized web services that communicate with one another, along with unit and integration tests.

Expand Down Expand Up @@ -107,13 +107,13 @@ module:
description: Node service container
type: container
services:
- name: node-service
- name: node-service
command: [npm, start]
ports:
- name: http
containerPort: 8080
endpoints:
- paths: [/]
- path: /
port: http
```
The [services](../guides/configuration.md#Services) directive is specific to container modules, and defines the services exposed by the module. In this case, our containerized Node.js server. The sub-directives tell Garden how to start the service and which endpoints to expose.
Expand All @@ -136,7 +136,7 @@ To verify that everything is working, we can call the service at the `/hello` en

```sh
$ garden call node-service/hello
✔ Sending HTTP GET request to http://node-service.simple-project.local.app.garden:32000/hello
✔ Sending HTTP GET request to http://simple-project.local.app.garden/hello

200 OK

Expand All @@ -156,12 +156,12 @@ module:
description: Go service container
type: container
services:
- name: go-service
- name: go-service
ports:
- name: http
containerPort: 80
endpoints:
- paths: [/]
- path: /
port: http
```

Expand Down Expand Up @@ -218,7 +218,7 @@ Now let's re-deploy the `node-service` and try out our new endpoint:
```sh
$ garden deploy node-service
$ garden call node-service/call-go-service
✔ Sending HTTP GET request to http://node-service.simple-project.local.app.garden:32000/call-go-service
✔ Sending HTTP GET request to http://simple-project.local.app.garden/call-go-service

200 OK

Expand All @@ -240,14 +240,14 @@ module:
description: Node service container
...
services:
- name: node-service
- name: node-service
command: [npm, start]
...
dependencies:
- go-service
- go-service
```

This will ensure that our `go-service` will be deployed before the `node-service`.
This will ensure that our `go-service` will be deployed before the `node-service`.

## Testing

Expand All @@ -258,7 +258,7 @@ module:
description: Node service container
...
services:
- name: node-service
- name: node-service
command: [npm, start]
...
tests:
Expand All @@ -270,7 +270,7 @@ module:
- go-service
```

This allows us to run individual test groups by name or all of them at once with the test command:
This allows us to run individual test groups by name or all of them at once with the test command:

```sh
$ garden test
Expand All @@ -285,13 +285,13 @@ module:
description: Node service container
type: container
services:
- name: node-service
- name: node-service
command: [npm, start]
ports:
- name: http
containerPort: 8080
endpoints:
- paths: [/]
- path: /
port: http
dependencies:
- go-service
Expand All @@ -301,7 +301,7 @@ module:
- name: integ
command: [npm, run, integ]
dependencies:
- go-service
- go-service
```

And that's it! Our services are up and running locally, dependencies are resolved, and tests are ready to run.
Expand Down
42 changes: 21 additions & 21 deletions docs/guides/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

Garden is configured via `garden.yml` configuration files.

The [project-wide](#project-configuration) `garden.yml` file should be located in the top-level directory of the
project's Git
The [project-wide](#project-configuration) `garden.yml` file should be located in the top-level directory of the
project's Git
repository.

In addition, each of the project's [modules](../guides/glossary.md#module)' `garden.yml` should be located in that module's
top-level
In addition, each of the project's [modules](../guides/glossary.md#module)' `garden.yml` should be located in that module's
top-level
directory.

Currently, Garden projects assume that all their modules are rooted in subdirectories of the same Git repository.
In a future release, this mono-repo structure will be made optional.

To get started, create a `garden.yml` file in the top-level directory of your repository, and a `garden.yml` file
To get started, create a `garden.yml` file in the top-level directory of your repository, and a `garden.yml` file
in the top-level directory of each of the modules you'd like do define for your project.

To decide how to split your project up into modules, it's useful to consider what parts of it are built as a single
Expand Down Expand Up @@ -53,14 +53,14 @@ The project-wide `garden.yml` defines the project's name, the default providers
[environment](../guides/glossary.md#environment)-specific provider overrides as is appropriate for each of the project's
configured environments (`local` and `dev` under the `environments` directive above).

Here, project-wide configuration variables can also be specified (global, and/or environment-specific). These are
Here, project-wide configuration variables can also be specified (global, and/or environment-specific). These are
then available for interpolation in any string scalar value in any module's `garden.yml`.
For example, assuming the above project configuration, `"foo-${variables.my-variable}-bar"` would evaluate to

For example, assuming the above project configuration, `"foo-${variables.my-variable}-bar"` would evaluate to
`"foo-hello-variable-bar"` when used as a scalar string value in a module's `garden.yml`.

### Module Configuration
Below, we'll use the module configurations of `hello-function` and `hello-container` from the
Below, we'll use the module configurations of `hello-function` and `hello-container` from the
[hello-world example project](https://github.com/garden-io/garden/tree/528b141717f718ebe304d2ebde87b85d0c6c5e50/examples/hello-world)
as examples to illustrate some of the primary module-level configuration options.

Expand All @@ -87,18 +87,18 @@ Note that module names must be unique within a given project. An error will be t
modules use the same name.

#### type
A [module](../guides/glossary.md#module)'s `type` specifies its plugin type. Garden interprets this according to the
A [module](../guides/glossary.md#module)'s `type` specifies its plugin type. Garden interprets this according to the
active environment's configured provider for the specified plugin type.

For example,
[`hello-container`](#hello-container-module-configuration)'s `type` is set to `container`, which the
[project configuration](#project-configuration) above interprets as `local-kubernetes` (a Docker container managed
[project configuration](#project-configuration) above interprets as `local-kubernetes` (a Docker container managed
via a local Kubernetes installation), assuming that the `local` environment is being used.

#### build
A module's build configuration is specified via the `build` directive.

Under `build`, the `command` subdirective sets the CLI command run during builds. A module's build command is executed
Under `build`, the `command` subdirective sets the CLI command run during builds. A module's build command is executed
with its working directory set to a copy of the module's top-level directory, located at
`[project-root]/.garden/build/[module-name]`. This internal directory is referred to as the module's
[build directory](../guides/glossary.md#build-directory).
Expand All @@ -107,8 +107,8 @@ The `.garden` directory should not be modified by users, since this may lead to
tools are used in the project.

##### Build Dependencies
The `dependencies` subdirective lists the module's build dependencies. `name` is the required module's name, and
`copy` indicates what files/folders, if any, should be copied from the required module's build directory to the
The `dependencies` subdirective lists the module's build dependencies. `name` is the required module's name, and
`copy` indicates what files/folders, if any, should be copied from the required module's build directory to the
module in question after the required module is built (`source`), and where they should be copied (`target).

#### Services
Expand All @@ -124,7 +124,7 @@ module:
- name: http
containerPort: 8080
endpoints:
- paths: [/hello]
- path: /hello
port: http
healthCheck:
httpGet:
Expand All @@ -148,14 +148,14 @@ The CLI command to be executed (after the module is built) to make the service's
Names each port exposed by the service.

##### endpoints
Enumerates the functional endpoints exposed by the service, defining the relative path and port to associate with
Enumerates the functional endpoints exposed by the service, defining the relative path and port to associate with
each of them.

##### healthcheck
Defines the endpoint used to query the service's availability.

##### dependencies
Lists the names of the services that must be deployed before the service in question (the `hello-container` service, in
Lists the names of the services that must be deployed before the service in question (the `hello-container` service, in
this case) is deployed.

##### tests
Expand All @@ -175,12 +175,12 @@ module:
dependencies:
- hello-function
```
Test groups can be run by `name` via `garden test`. `command` is the CLI command to run the specified tests, and
Test groups can be run by `name` via `garden test`. `command` is the CLI command to run the specified tests, and
`dependencies` lists (by name) the services (if any) that must be deployed before the test group in question is run.

#### Functions (experimental)
For modules defining serverless functions, the `functions` directive specifies the names and entry points of the
functions the module exposes. Note that serverless functionality is still experimental and under active development.
For modules defining serverless functions, the `functions` directive specifies the names and entry points of the
functions the module exposes. Note that serverless functionality is still experimental and under active development.

This section is currently only included to clarify the `functions` directive in
[`hello-function`'s module config](#hello-function-module-configuration), since it's used as an example here.
Expand Down Expand Up @@ -223,7 +223,7 @@ module:
- name: http
containerPort: 8080
endpoints:
- paths: [/hello]
- path: /hello
port: http
healthCheck:
httpGet:
Expand Down
82 changes: 61 additions & 21 deletions docs/guides/remote-kubernetes.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,72 @@
## Running against a remote Kubernetes cluster
# Running against a remote Kubernetes cluster

### Setup
## Setup

You need to have a running ingress controller on your cluster to route requests to
the deployed services. This can generally be any controller of your choosing, such
as the nginx ingress controller.
### Connecting to the cluster

You also need a configured [context](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
on your development machine.
Start by making sure you have a [kubectl context](https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
set up on your development machine to access your cluster.

Then all you need to do is configure the environment and provider in your project
`garden.yml`. You need to specify your configured context and the hostname of your
ingress controller. Example:
Then configure the project and provider, along with the kubectl context you use to connect to your
cluster.

Example:

```yaml
project:
name: my-project
environments:
- name: dev
providers:
- name: kubernetes
context: my-dev-context # the name of the kubectl context for the cluster
defaultEnvironment: dev
```

### Ingress, TLS and DNS

The cluster needs to have a configured [nginx ingress controller](https://github.com/kubernetes/ingress-nginx).
You'll also need to configure one or more TLS certificates for the hostnames you will expose for ingress.

Once you have the certificates on hand (the `.crt` and `.key` files), create a
[Secret](https://kubernetes.io/docs/concepts/configuration/secret/) for each cert in the cluster so that
they can be referenced when deploying services:

```sh
kubectl create secret tls mydomain-tls-secret --key <path-to-key-file> --cert <path-to-crt-file>
```

Then configure each certificate/secret in your provider configuration:

```yaml
project:
name: my-project
environments:
dev:
providers:
kubernetes:
context: my-dev-context
ingressHostname: k8s-dev.mydomain.com
ingressClass: nginx # this is optional, but may be necessary for your ingress controller configuration
- name: dev
providers:
- name: kubernetes
context: my-dev-context
tlsCertificates:
- name: main
# Optionally set particular hostnames to use this certificate for
# (useful if you have multiple certs for the same hostname).
hostnames: [mydomain.com]
secretRef:
# Change to whatever name you chose for the secret above.
name: my-tls-secret
# Change this if you store the secret in another namespace.
namespace: default
- name: wildcard
secretRef:
name: wildcard-tls-secret
namespace: default
defaultEnvironment: dev
```

Note that you need to have permissions to create namespaces and to create deployments,
daemonsets, services and ingresses within the namespaces created. The plugin will
create two namespaces per user and project, one to run services and another to manage
metadata and configuration (this is so that your environment can be reset without
clearing your configuration variables).
### Permissions

Note that you need to have permissions to create namespaces and to create deployments,
daemonsets, services and ingresses within the namespaces created. The plugin will
create two or more namespaces per user and project, one to run services, another to manage
metadata and configuration (this is so that your environment can be reset without
clearing your configuration variables), and potentially more to support specific plugins/providers.
2 changes: 1 addition & 1 deletion docs/reference/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Examples:
garden call my-container
garden call my-container/some-path

Note: Currently only supports HTTP/HTTPS endpoints.
Note: Currently only supports simple GET requests for HTTP/HTTPS endpoints.

##### Usage

Expand Down
24 changes: 21 additions & 3 deletions docs/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,13 +495,31 @@ module:

# List of endpoints that the service exposes.
#
# Example:
# - path: /api
# port: http
#
# Optional.
endpoints:
- # The paths which should be routed to the service.
- # A name to assign to the endpoint.
#
# Optional.
name: default

# The hostname that should route to this service. Defaults to the default hostname
# configured
# in the provider configuration.
#
# Note that if you're developing locally you may need to add this hostname to your hosts
# file.
#
# Optional.
hostname:

# The path which should be routed to the service.
#
# Optional.
paths:
-
path: /

# The name of the container port where the specified paths should be routed.
#
Expand Down
2 changes: 1 addition & 1 deletion examples/hello-world/services/hello-container/garden.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module:
- name: http
containerPort: 8080
endpoints:
- paths: [/hello]
- path: /hello
port: http
healthCheck:
httpGet:
Expand Down

0 comments on commit 1c004f7

Please sign in to comment.