Quick start
Setting up
To start using this library, first initialize the working directory using tk
init
.
This will create a directory structure similar to this:
.
├── environments
│ └── default
├── jsonnetfile.json
├── jsonnetfile.lock.json
├── lib
│ └── k.libsonnet
└── vendor
├── 1.23 -> github.com/jsonnet-libs/k8s-libsonnet/1.23
├── github.com
└── ksonnet-util -> github.com/grafana/jsonnet-libs/ksonnet-util
Next, we need to install the cloudflight-libsonnet
library using jb
:
The last step is to adapt the predefined k.libsonnet
. When initializing, Tanka
simply imports the
k8s-libsonnet
library here.
Since some of our customizations depend on other libraries which have to be
imported at this point (such as
openshift-libsonnet
or
prometheus-libsonnet
), you replace the contents of k.libsonnet
with the
following:
Using the library
To use the components provided by this library (or other Kubernetes components),
import our prelude.libsonnet
.
Let's use the library to deploy a simple java based application, backed by an MariaDB instance.
Creating the application
Applications should be defined in the lib
folder. To configure a java
application, we create a file called lib/test-java.libsonnet
with the
contents below.
local k = (import 'cloudflight-libsonnet/prelude.libsonnet');
{
_config+:: {
myApplication: {
name: 'my-application',
image: error '$._config.myApplication.image must be defined',
},
},
myApplication: {
deployment: k.util.java.deployment.new(
name=$._config.myApplication.name,
image=$._config.myApplication.image,
containerMixin=k.core.v1.container.livenessProbe.withInitialDelaySeconds(60),
),
service: k.util.serviceFor(self.deployment),
route: k.util.routeFor(self.service, 'hello.example.com'),
},
}
Now we can import this into our environment file
environments/default/main.jsonnet
(import 'test-java.libsonnet')
+ {
_config+: {
myApplication+: {
image: 'helloworld:latest',
},
},
}
Provided your .kube/config
and environments/default/spec.json
are set up
correctly, you can deploy this by running tk apply environments/default
.
Adding the database
Most applications want to store data somewhere so let's add a database next.
First, we import the database of choice in the main.jsonnet
file.
(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')
+ (import 'test-java.libsonnet')
+ {
_config+: {
mariadb+: {
user: 'application-user',
password: 'hunter2',
database: 'my-application',
},
myApplication+: {
image: 'helloworld:latest',
},
},
}
To connect our application to the database, we need to configure the deployment
on a lower level. This is because of the fact, that the plain
util.java.deployment
does not make any assumptions about databases.
As documented in the java module, we build the deployment ourselves, but mix in some environment variables.
local k = (import 'cloudflight-libsonnet/prelude.libsonnet');
{
_config+:: {
myApplication: {
name: 'my-application',
image: error '$._config.myApplication.image must be defined',
dbUser: error '$._config.myApplication.dbUser must be defined',
dbPasswordRef: error '$._config.myApplication.dbPasswordRef must be a valid secretSecretKeyRef',
dbUrl: error '$._config.myApplication.dbUrl must be defined',
},
},
myApplication: {
deployment: k.apps.v1.deployment.new(
name=$._config.myApplication.name,
replicas=1,
containers=[
k.util.java.container.new($._config.myApplication.name, $._config.myApplication.image)
+ k.core.v1.container.withEnvMixin([
{
name: 'SPRING_DATASOURCE_PASSWORD',
valueFrom: { secretKeyRef: $._config.myApplication.dbPasswordRef },
},
{
name: 'SPRING_DATASOURCE_USERNAME',
value: $._config.myApplication.dbUser,
},
{
name: 'SPRING_DATASOURCE_URL',
value: $._config.myApplication.dbUrl,
},
]),
]
),
service: k.util.serviceFor(self.deployment),
route: k.util.routeFor(self.service, 'hello.example.com'),
},
}
In the last step, we fill the new config parameters with values.
(import 'cloudflight-libsonnet/databases/mariadb.libsonnet')
+ (import 'test-java.libsonnet')
+ {
_config+: {
mariadb+: {
user: 'application-user',
password: 'hunter2',
database: 'my-application',
},
myApplication+: {
image: 'helloworld:latest',
dbUser: $._config.mariadb.user,
dbPasswordRef: $.mariadb.passwordSecretKeyRef,
dbUrl: 'jdbc:mysql://' + $.mariadb.service.metadata.name + '/' + $._config.mariadb.database,
},
},
mariadb2: (import 'cloudflight-libsonnet/databases/mariadb.libsonnet') + {
_config+: {
mariadb+: {
name: 'foo',
user: 'foo-user',
password: 'foo-user',
},
},
},
}
And we're done!
To recap: we have configured an application, added a database
and connected it to our application. The way we connected the applications is
transparent, and we could (as long as the application supports it) change the
database entirely in our main.jsonnet
. This way, we can use different database
setups across environment, while keeping the application configuration the same.
For more information, check out the documentation of the java utilities and the MariaDB module.