This tutorial is build upon the first simple blueprint, therefore the first tutorial should be done before.
The goal of this tutorial is to deploy a http echo server (https://github.com/hashicorp/http-echo) that is exposed via an ingress. It consumes the exported ingressClass value of the nginx ingress installation and use that annotation in the ingress to use the previously deployed ingress controller.
Prerequisites:
- Helm commandline tool (see https://helm.sh/docs/intro/install/)
- OCI compatible oci registry (e.g. GCR or Harbor)
- Kubernetes Cluster (better use two different clusters: one for the landscaper and one for the installation)
- first tutorial
All example resources can be found in docs/tutorials/resources/echo-server.
eu.gcr.io/gardener-project/landscaper/tutorials
is an example repository
and has to be replaced with your own registry if you want to upload your own artifacts.
Although the artifacts are public readable so they can be used out-of-the-box without a need for your own oci registry.
The http echo server consists of a deployment, a service and a ingress object that are istalled using the kubernetes manifest deployer
First resource that we have to create is the blueprint.
The http echo blueprint imports a cluster to deploy the kubernetes resources, a namespace name and a ingress class.
The ingress class is imported so that the responsible ingress controller can be set.
(See the kubernetes ingress docs for detailed documentation)
Then the deploy items are defined. Again GoTemplate is used as the templating engine but the go template is not defined inline in the blueprint. This time, the template is defined in a separate file to keep the blueprint clean and readable.
The external file is defined with the file
attribute and points to the external file in the filesystem of the blueprint.
Whereas the root is the directory of the blueprint.yaml
.
For detailed information about the template executors see here.
blueprint.yaml:
apiVersion: landscaper.gardener.cloud/v1alpha1
kind: Blueprint
imports:
- name: cluster
type: target
targetType: landscaper.gardener.cloud/kubernetes-cluster
- name: namespace
type: data
schema:
type: string
- name: ingressClass
type: data
schema:
type: string
deployExecutions:
- name: default
type: GoTemplate
file: /defaultDeployExecution.yaml
The external file contains the template to render the deploy items.
As the kubernetes manifest deployer is used to deploy the kubernetes object, one deploy item of type landscaper.gardener.cloud/kubernetes-manifest
is defined.
It contains all the 3 resources that are needed for the echo server deployment.
The imported ingressClass
is used in the ingress resource to define the class annotation: kubernetes.io/ingress.class: "{{ .imports.ingressClass }}"
.
Also the http echo server oci image is taken from the component descriptor as external resource: image: {{ index .cd.component.resources "echo-server-image" "access" "imageReference" }}
.
defaultDeployExecution.yaml:
{{ $name := "echo-server" }}
deployItems:
- name: deploy
type: landscaper.gardener.cloud/kubernetes-manifest
target:
import: cluster
config:
apiVersion: manifest.deployer.landscaper.gardener.cloud/v1alpha2
kind: ProviderConfiguration
updateStrategy: patch
manifests:
- policy: manage
manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ $name }}
namespace: {{ .imports.namespace }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ $name }}
template:
metadata:
labels:
app: {{ $name }}
spec:
containers:
- image: {{ with (getResource .cd "name" "echo-server-image") }}{{ .access.imageReference }}{{end}}
imagePullPolicy: IfNotPresent
name: {{ $name }}
args:
- -text="hello world"
ports:
- containerPort: 5678
- policy: manage
manifest:
apiVersion: v1
kind: Service
metadata:
name: {{ $name }}
namespace: {{ .imports.namespace }}
spec:
selector:
app: {{ $name }}
ports:
- protocol: TCP
port: 80
targetPort: 5678
- policy: manage
manifest:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $name }}
namespace: {{ .imports.namespace }}
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "{{ .imports.ingressClass }}"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ $name }}
port:
number: 80
Upload the blueprint into the oci registry.
landscaper-cli blueprints push eu.gcr.io/gardener-project/landscaper/tutorials/blueprints/echo-server:v0.2.0 docs/tutorials/resources/echo-server/blueprint
The blueprint is now build and uploaded. Then the corresponding component descriptor has to be created.
It contains the blueprint as local resource and the http echo server image as external resource.
The echo server is specified as external image because the image is consumed form the open source.
For more information about the component descriptor and the usage of the different fields see the component descriptor docs.
meta:
schemaVersion: v2
component:
name: github.com/gardener/landscaper/echo-server
version: v0.2.0
provider: internal
repositoryContexts:
- type: ociRegistry
baseUrl: eu.gcr.io/gardener-project/landscaper/tutorials/components
sources: []
componentReferences: []
resources:
- type: blueprint
name: echo-server-blueprint
version: v0.2.0
relation: local
access:
type: ociRegistry
imageReference: eu.gcr.io/gardener-project/landscaper/tutorials/blueprints/echo-server:v0.2.0
- type: ociImage
name: echo-server-image
version: v0.2.3
relation: external
access:
type: ociRegistry
imageReference: hashicorp/http-echo:0.2.3
landscaper-cli component-cli ca remote push docs/tutorials/resources/echo-server
The same target as in the first tutorial is used as the resources have to be deployed into the same kubernetes cluster. The only resource that has to be defined is a Installation for the echo-server blueprint.
The echo-server installation is the same as it was previously created for the nginx ingress blueprint.
In addition to the namespace import, the ingressClass
import has to be defined.
The nginx installation exports its ingressClass to myIngressClass
, so this dataobject has to be used as import for the echo server.
DataObject of other components can be referenced using dataRef: <name of the export>
.
imports:
data:
- name: namespace
configMapRef:
key: "namespace"
name: "my-imports" # name of the configmap;
- name: ingressClass
dataRef: "myIngressClass"
Complete Installation:
apiVersion: landscaper.gardener.cloud/v1alpha1
kind: Installation
metadata:
name: my-echo-server
annotations:
# this annotation is required such that the installation is picked up by the Landscaper
# it will be removed when processing has started
landscaper.gardener.cloud/operation: reconcile
spec:
componentDescriptor:
ref:
repositoryContext:
type: ociRegistry
baseUrl: eu.gcr.io/gardener-project/landscaper/tutorials/components
componentName: github.com/gardener/landscaper/echo-server
version: v0.2.0
blueprint:
ref:
resourceName: echo-server-blueprint
imports:
targets:
- name: cluster
target: "my-cluster"
data:
- name: namespace
configMapRef:
key: "namespace"
name: "my-imports" # name of the configmap;
- name: ingressClass
dataRef: "myIngressClass"
The echo-server can now be installed by applying the installation to the landscaper cluster.
kubectl create -f docs/tutorials/resources/echo-server/installation.yaml
- A blueprint that describes the deployment of an echo server deployment and imports data from another blueprint has been development
In the next tutorial, a aggregated blueprint will be developed.