Create a Registry

Learn how to create a filesystem registry

Overview

A registry is a repository of packages. ksonnet supports adding a registry from Github, Helm, and a local filesystem. Registries can then be shared, used offline, or kept under version control.

Objectives

  • Create a registry on the local filesystem
  • Demonstrate requirements for a registry
  • Install a package with ksonnet

The goal is to create a minimalist registry with the structure below. For a registry containing more than one package, reference the registry example in concepts.

tutorial_registry
├── example
│   ├── example.libsonnet
│   ├── parts.yaml
│   └── prototypes
│       └── example.jsonnet
└── registry.yaml

0. Prerequisites

Before we begin, ensure that:

  • You have ksonnet installed locally. If not, follow the install instructions.
  • You should have git installed. This helps show what changes are made to the ksonnet application.
  • You have completed the tutorial. An understanding of creating ksonnet applications and concepts is required.

1. Create registry.yaml

Create a new directory,tutorial_registry, with a file inside called registry.yaml. This file contains a list of all the packages in the registry and information about the registry API.

The default apiVersion is 0.1.0 and kind identifies the file for ksonnet. libraries contain a list of all the packges in the registry.

Each package has a path relative to registry.yaml. Optionally a version can be provided to specify a branch if the registry will live in Github.

registry.yaml
1
2
3
4
5
6
apiVersion: 0.1.0
kind: ksonnet.io/registry
libraries:
  example:
    path: example
    version: master
Note: version cannot be used to specify a local git branch.

2. Write package metadata to parts.yaml

Create a directory with the name of the package. parts.yaml provides additional metadata on the package.

Identify the YAML for its purpose with kind. name and description are used to populate the output of ks pkg describe.

parts.yaml
1
2
3
4
5
6
apiVersion: 0.0.1
kind: ksonnet.io/parts
name: example
description: An example of a ksonnet registry
author: ksonnet authors
license: Apache 2.0
Note: author and license are optional.

3. Jsonnet library

Create another file called example.libsonnet. This file describes the parts used to capture common elements of the prototypes.

Note: A Jsonnet file with the purpose of being used as a library should have a .libsonnet extension by convention.

The example below contains a function that returns a value of 443 that can be used by prototypes.

example.libsonnet
1
2
3
4
5
{
    parts:: {
      port_number():: 443
    }
}

4. Create a Prototype

Make a directory called prototypes and a new example-prototype.jsonnet file.

A prototype is annotated with additional metadata using a series of comments at the beginning of the file. The required metadata, also called a directive, are @apiVersion, @name, @description, @shortDescription, and @param.

Add the required @param name string <Description of the param> to pass @name where it can be imported to Jsonnet.

Optional params can be added with the following syntax:

@optionalParam <name> <type> <value> <Description of optional param>

A prototype param can have the following possible types:

  • number
  • string
  • numberOrString
  • object
  • array

Import the Jsonnet library under a local variable then call the function in the metadata.

example-prototype.jsonnet
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// @apiVersion 0.0.1
// @name example-prototype
// @description An example prototype used to show how to create a registry
//   and usage of parts.
// @shortDescription An example prototype
// @param name string Name of the prototype
// @optionalParam namespace string default Description of optional param

local example = import 'tutorial_registry/example/example.libsonnet';

local namespace = import 'param://namespace';
local appName = import 'param://name';

{
    apiVersion: "v1",
    kind: "Service",
    metadata: {
        name: appName,
        annotations: namespace,
    },
    spec: {
        ports: [
            port: 80,
            targetPort: example.parts.port_number()
        ]
    },
    selector: {
        app: "example"
    }
}
example.libsonnet
1
2
3
4
5
{
    parts:: {
      port_number():: 443
    }
}
Note: In addition to the import syntax above, param and optional param can be accessed by the keyword params. For example, the optional namespace param can be written as params.namespace.

5. Installing packages from a local registry

Navigate to your ksonnet application. First, add a new registry with the name tutorial:

$ ks registry add tutorial /path/to/tutorial_registry

Metadata of the added registry is saved to app.yaml.

The example package will be visible with ks pkg list. Install the package by specifying a <registry>/<package>:

$ ks pkg install tutorial/example

Verify package installation with ks pkg list --installed. Observe that the package files from the registry are copied to vendor, and app.yaml is updated with the installed package.

After installing the package, list all available prototypes. The @name and @shortDescription metadata from the commented section of the prototype are used here.

$ ks prototype list

NAME                                DESCRIPTION
====                                ===========
example-prototype                   An example prototype

6. See generated manifest

Run ks generate example-prototype example-component to create a new component.

components/params.libsonnet will update with the object defined from the prototype. A newly generated component/example-component.jsonnet will be used to generate the manifest.

Finally, see the YAML output. Observe how the name under metadata is passed from ks generate in addition to the return value of function from parts.

$ ks show default

---
apiVersion: v1
kind: Service
metadata:
  name: example-component
  annotations: default
selector:
  app: example
spec:
  ports:
  - port: 80
    targetPort: 443

Optional: Push to GitHub

Push the registry to Github to share packages among teams.

Note: Private repositories requiring authentication are not supported at this time.

Then from a ksonnet app, add a registry from Github with the repository URI.

ks registry add <registry-name> <registry-uri>

By default, the incubator is added when creating a ksonnet application. This can be turned off by passing the ks init <app-name> --skip-default-registry flag.

Next steps

In order to generate manifests that are usable on a cluster, use ksonnet libraries to write libraries and prototypes using Jsonnet and the Kubernetes API.

Last updated on: September 18, 2018