Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
&& echo ". /etc/bash_completion" >> ~/.bashrc \
&& mkdir -p ~/completions \
#
# Install eslint globally
&& npm install -g eslint \
# Install node packages globally
&& npm install -g eslint pino-pretty \
#
# Add add sudo support for non-root user
&& apt-get install -y sudo \
Expand Down
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This container image can be deployed on a Kubernetes cluster. It runs a web app,

![Hello world! from the hello-kubernetes image](hello-kubernetes.png)

## Deploy
## Quick start

You can deploy `hello-kubernetes` to your Kubernetes cluster using [Helm 3](https://helm.sh/docs/intro/install/). The Helm chart installation and configuration options can be found in the [Deploy using Helm](docs/deploy-using-helm.md) guide.

Expand All @@ -22,46 +22,50 @@ cd deploy/helm

### Example 1: Default

Deploy the `hello-kubernetes` app into the `hello-kubernetes-default` namespace with the default "Hello world!" message. The app is exposed via a public Load Balancer on port 80 by default - note that this only works in cloud provider based Kubernetes offerings.
Deploy the `hello-kubernetes` app into the `hello-kubernetes` namespace with the default "Hello world!" message. The app is exposed via a public Load Balancer on port 80 by default - note that a LoadBalancer service typically only works in cloud provider based Kubernetes offerings.

```bash
helm install --create-namespace --namespace hello-kubernetes-default hello-world ./hello-kubernetes
helm install --create-namespace --namespace hello-kubernetes hello-world ./hello-kubernetes

# get the LoadBalancer ip address.
kubectl get svc hello-kubernetes -n hello-kubernetes-default -o 'jsonpath={ .status.loadBalancer.ingress[0].ip }'
kubectl get svc hello-kubernetes-hello-world -n hello-kubernetes -o 'jsonpath={ .status.loadBalancer.ingress[0].ip }'
```

### Example 2: Custom message

Deploy the `hello-kubernetes` app into the `hello-kubernetes-custom` namespace with an "I just deployed this on Kubernetes!" message. The app is exposed via a public Load Balancer on port 80 by default - note that this only works in cloud provider based Kubernetes offerings.
Deploy the `hello-kubernetes` app into the `hello-kubernetes` namespace with an "I just deployed this on Kubernetes!" message. The app is exposed via a public Load Balancer on port 80 by default - note that a LoadBalancer service typically only works in cloud provider based Kubernetes offerings.

```bash
helm install --create-namespace --namespace hello-kubernetes-custom hello-custom ./hello-kubernetes \
helm install --create-namespace --namespace hello-kubernetes custom-message ./hello-kubernetes \
--set message="I just deployed this on Kubernetes!"

# get the LoadBalancer ip address.
kubectl get svc hello-kubernetes -n hello-kubernetes-custom -o 'jsonpath={ .status.loadBalancer.ingress[0].ip }'
kubectl get svc hello-kubernetes-custom-message -n hello-kubernetes -o 'jsonpath={ .status.loadBalancer.ingress[0].ip }'
```

### Example 3: Ingress

Deploy the `hello-kubernetes` app into the `hello-kubernetes-ingress` namespace. This example assumes that an ingress has been deployed into the cluster and that the ingress has a path of `/app/hello-kubernetes/` mapped to the `hello-kubernetes` service.
Deploy the `hello-kubernetes` app into the `hello-kubernetes` namespace. This example assumes that an ingress has been deployed and configured in the cluster, and that the ingress has a path of `/app/hello-kubernetes/` mapped to the `hello-kubernetes` service.

The `hello-kubernetes` app can be reached on the ip address of the ingress via the `/app/hello-kubernetes/` path.

```bash
helm install --create-namespace --namespace hello-kubernetes-ingress hello-ingress ./hello-kubernetes \
--set ingress.enabled=true \
helm install --create-namespace --namespace hello-kubernetes ingress ./hello-kubernetes \
--set ingress.configured=true \
--set ingress.pathPrefix="/app/hello-kubernetes/" \
--set service.type="ClusterIP"
```

## Additional
## Documentation

### Deploying

If you'd like to explore the various Helm chart configuration options, then read the [Deploy with Helm](docs/deploy-using-helm.md) documentation. You can also discover more about the ingress configuration options in the [Deploy with ingress](docs/deploy-with-ingress.md) documentation

### Building your own images

If you'd like to build the `hello-kubernetes` container image yourself and reference from your own registry or DockerHub repository, then you can get more details on how to do this in the [Build and push container images](docs/build-and-push-container-images.md) documentation.

### Development environment

If you have [VS Code](https://code.visualstudio.com/) and the [Visual Studio Code Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension installed, the `.devcontainer` folder will be used to provide a container based development environment. You can read more about how to use this in the [Development environments](docs/development-environment.md) documentation.
If you have [VS Code](https://code.visualstudio.com/) and the [VS Code Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension installed, the `.devcontainer` folder will be used to provide a container based development environment. You can read more about how to use this in the [Development environments](docs/development-environment.md) documentation.
16 changes: 13 additions & 3 deletions deploy/helm/hello-kubernetes/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
{{/*
Expand the name of the chart.
Create a unique app name
*/}}
{{- define "hello-kubernetes.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- printf "%s-%s" .Chart.Name .Release.Name | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "hello-kubernetes.labels" -}}
{{ include "hello-kubernetes.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "hello-kubernetes.selectorLabels" -}}
app.kubernetes.io/name: {{ include "hello-kubernetes.name" . }}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
16 changes: 12 additions & 4 deletions deploy/helm/hello-kubernetes/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.deployment.name }}
name: {{ include "hello-kubernetes.name" . }}
labels:
{{- include "hello-kubernetes.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.deployment.replicaCount }}
selector:
Expand All @@ -12,7 +14,7 @@ spec:
labels:
{{- include "hello-kubernetes.selectorLabels" . | nindent 8 }}
spec:
serviceAccountName: {{ .Values.serviceAccount.name }}
serviceAccountName: {{ include "hello-kubernetes.name" . }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.deployment.container.image.repository }}:{{ .Values.deployment.container.image.tag | default .Chart.AppVersion }}"
Expand All @@ -38,8 +40,14 @@ spec:
- name: MESSAGE
value: "{{ .Values.message }}"
{{- end }}
{{- if .Values.ingress.enabled }}
- name: PATH_PREFIX
{{- if .Values.ingress.configured }}
- name: HANDLER_PATH_PREFIX
{{- if .Values.ingress.rewritePath }}
value: ""
{{- else }}
value: "{{ .Values.ingress.pathPrefix }}"
{{- end }}
- name: RENDER_PATH_PREFIX
value: "{{ .Values.ingress.pathPrefix }}"
{{- end }}
{{- with .Values.deployment.resources }}
Expand Down
4 changes: 3 additions & 1 deletion deploy/helm/hello-kubernetes/templates/service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.service.name }}
name: {{ include "hello-kubernetes.name" . }}
labels:
{{- include "hello-kubernetes.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
Expand Down
4 changes: 3 additions & 1 deletion deploy/helm/hello-kubernetes/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Values.serviceAccount.name }}
name: {{ include "hello-kubernetes.name" . }}
labels:
{{- include "hello-kubernetes.labels" . | nindent 4 }}
9 changes: 3 additions & 6 deletions deploy/helm/hello-kubernetes/values.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
# Provide a custom message
message: ""

# Remember to set service.type=ClusterIP if you are using an ingress
ingress:
enabled: false
configured: false
rewritePath: true
pathPrefix: ""

service:
name: "hello-kubernetes"
type: LoadBalancer
port: 80

serviceAccount:
name: "hello-kubernetes"

deployment:
replicaCount: 2
name: "hello-kubernetes"
container:
image:
repository: "paulbouwer/hello-kubernetes"
Expand Down
5 changes: 2 additions & 3 deletions docs/build-and-push-container-images.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ The `hello-kubernetes` container image can be built and pushed to your own regis

- [make](https://www.gnu.org/software/make/)
- [Docker cli](https://www.docker.com/)
- Docker registry
- Container registry

If you are using the [Visual Studio Code Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) based development environment, all of these prerequisites will be available in the terminal.
If you are using the [VS Code Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) based development environment, all of the prerequisites will be available in the terminal.

## Makefile configuration

Expand Down Expand Up @@ -64,7 +64,6 @@ make push-image
# - paulbouwer.azurecr.io/paulbouwer/hello-kubernetes:1.10.0
# - paulbouwer.azurecr.io/paulbouwer/hello-kubernetes:1.10
# - paulbouwer.azurecr.io/paulbouwer/hello-kubernetes:1

export REGISTRY=paulbouwer.azurecr.io
make push-image
```
21 changes: 10 additions & 11 deletions docs/deploy-using-helm.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ The `hello-kubernetes` Helm chart can be used to deploy the `hello-kubernetes` a
## Prerequisites

- [Helm 3](https://v3.helm.sh/)
- [Kubernetes](https://kubernetes.io/) cluster

If you are using the [VS Code Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) based development environment, all of the prerequisites will be available in the terminal.

## Configuration and installation

Expand All @@ -18,14 +19,12 @@ The following table lists the configuration parameters of the hello-kubernetes c
| Parameter | Type | Default | Description |
| --------- | ---- | ------- | ----------- |
| `message` | `string` | `""` | A custom message to display instead of the default. |
| `ingress.enabled` | `bool` | `false` | Indicate whether an ingress is being used. |
| `ingress.configured` | `bool` | `false` | Indicates whether an ingress has been configured in the cluster. <br/>Note: this chart will not install or configure an ingress. You will need to install an ingress controller and add ingress record to the app namespace. |
| `ingress.rewritePath` | `bool` | `true` | Indicates whether pathPrefix is rewritten by the ingress. <br/> If this is set to `true` then the hello-kubernetes dynamic content and static assets will be served from `/`, otherwise, they will be served from `/$pathPrefix`. |
| `ingress.pathPrefix` | `string` | `""` | The path prefix configured in the ingress for the hello-kubernetes service.<br/> Must be provided when ingress is used. |
| `service.name` | `string` | `"hello-kubernetes"` | The name of the service configured for the hello-kubernetes pods. |
| `service.type` | `string` | `"LoadBalancer"` | The service type. |
| `service.port` | `int` | `80` | The port exposed by the service. |
| `serviceAccount.name` | `string` | `"hello-kubernetes"` | The service account bound to the pods. |
| `deployment.replicaCount` | `int` | `2` | The number of replicas for the hello-kubernetes deployment. |
| `deployment.name` | `string` | `hello-kubernetes` | The name of the deployment containing the hello-kubernetes pods. |
| `deployment.container.image.repository` | `string` | `paulbouwer/hello-kubernetes` | The container image to run in the hello-kubernetes pods. |
| `deployment.container.image.tag` | `string` | `""` | The container image tag. If not specified, the chart's appVersion is used. |
| `deployment.container.image.pullPolicy` | `string` | `"IfNotPresent"` | The pull policy for the container image. |
Expand All @@ -44,18 +43,18 @@ cd deploy/helm
```

To install `hello-kubernets` via the Helm chart, use the following to:
- create the hello-kubernetes-default namespace
- deploy the chart located in the ./hello-kubernetes folder
- create the hello-kubernetes namespace if it doesn't exist
- deploy the chart located in the ./hello-kubernetes folder into the hello-kubernetes namespace
- create a Helm release named hello-world

```bash
helm install --create-namespace --namespace hello-kubernetes-default hello-world ./hello-kubernetes
helm install --create-namespace --namespace hello-kubernetes hello-world ./hello-kubernetes
```

You can override the values for the configuration parameter defined in the table above, either directly in the `hello-kubernetes/values.yaml` file, or via the `--set` switches.

```bash
helm install --create-namespace --namespace hello-kubernetes-custom hello-custom ./hello-kubernetes \
helm install --create-namespace --namespace hello-kubernetes custom-message ./hello-kubernetes \
--set message="I just deployed this on Kubernetes!"
```

Expand All @@ -70,7 +69,7 @@ cd deploy/helm
You can modify the `hello-kubernetes` app by providing new values for the configuration parameter defined in the table above, either directly in the `hello-kubernetes/values.yaml` file, or via the `--set` switches.

```bash
helm upgrade --namespace hello-kubernetes-custom hello-custom ./hello-kubernetes \
helm upgrade --namespace hello-kubernetes custom-message ./hello-kubernetes \
--set message="This is a different message"
```

Expand All @@ -79,5 +78,5 @@ helm upgrade --namespace hello-kubernetes-custom hello-custom ./hello-kubernetes
You can uninstall the `hello-kubernetes` app as follows:

```bash
helm uninstall --namespace hello-kubernetes-custom hello-custom
helm uninstall --namespace hello-kubernetes custom-message
```
96 changes: 96 additions & 0 deletions docs/deploy-with-ingress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Deploy with ingress

The `hello-kubernetes` Helm chart can be used to deploy and configure the `hello-kubernetes` application for use with an ingress controller.

> **Note:**
>
> The `hello-kubernetes` Helm chart does **not** deploy an [Ingress Controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) and does **not** deploy the [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) definition.
>
> The chart aims to support deployment to as many platforms and providers as possible, so the choice of Ingress Controller and configuration of Ingress resource is left to the person deploying.

## Prerequisites

- [Helm 3](https://v3.helm.sh/)

If you are using the [VS Code Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) based development environment, all of the prerequisites will be available in the terminal.

## Install ingress controller

Install an [Ingress Controller](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/) that is available for your platform or provider. Here is an example that uses the [Nginx Ingress Controller](https://kubernetes.github.io/ingress-nginx/deploy/) on a cloud provider:

```bash
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

helm install nginx-ingress ingress-nginx/ingress-nginx \
--create-namespace --namespace ingress \
--set controller.replicaCount=2
```

## Use hello-kubernetes with ingress

### Deploy hello-kubernetes instances

Install two `hello-kubernetes` instances that will be available via 2 different paths on the ingress.

The `hello-world` instance will display the default "Hello world!" message, and the `custom-message` instance will display a "This is my custom message!" message.

```bash
helm install --create-namespace --namespace hello-kubernetes hello-world ./hello-kubernetes \
--set ingress.configured=true --set ingress.pathPrefix=hello-world \
--set service.type=ClusterIP

helm install --create-namespace --namespace hello-kubernetes custom-message ./hello-kubernetes \
--set ingress.configured=true --set ingress.pathPrefix=custom-message \
--set service.type=ClusterIP \
--set message="This is my custom message!"
```

### Deploy ingress definition

The `hello-kubernetes` Helm chart has a `ingress.rewritePath` configuration parameter that is `true` by default. When used together with the `ingress.configured=true` configuration parameter, there is an assumption that the ingress being used supports path rewrites. See the [Deploy using Helm](deploy-using-helm.md) guidance for more details.

So from our example, a request to `/hello-world` should be rewritten to `/` before being passed to the `hello-world` app instance.

Create a file named `hello-kubernetes-ingress.yaml` with the content below. This ingress definition will be serviced by the nginx ingress controller due to the `kubernetes.io/ingress.class: nginx` annotation. It will also leverage the path rewrite capabilities of nginx via the `nginx.ingress.kubernetes.io/rewrite-target: /$2` annotation.

```yaml
# hello-kubernetes-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- backend:
serviceName: hello-kubernetes-hello-world
servicePort: 80
path: /hello-world(/|$)(.*)
- backend:
serviceName: hello-kubernetes-custom-message
servicePort: 80
path: /custom-message(/|$)(.*)
```

Deploy the contents of the `hello-kubernetes-ingress.yaml` into the same namespace as the two `hello-kubernetes` apps.

```bash
kubectl apply -n hello-kubernetes -f hello-kubernetes-ingress.yaml
```

### Browse

You can browse to each of the `hello-kubernetes` apps via the $INGRESS_CONTROLLER_IPADDRESS and each of the configured paths. So for our example at:

- `$INGRESS_CONTROLLER_IPADDRESS/hello-world` - the `hello-world` instance with the default "Hello world!" message
- `$INGRESS_CONTROLLER_IPADDRESS/custom-message` - the `custom-message` instance with the "This is my custom message!" message

## Alternatives

You can deploy the `hello-kubernetes` app via the Helm chart with the `ingress.rewritePath=false` configuration parameter if you are deploying with an ingress controller that does not support path rewrites.

In this case, the `hello-kubernetes` apps will serve dynamic content and static assets from the path defined by the `ingress.pathPrefix` configuration parameter.
Loading