This document describes how to manage resources offered by Services.
Background
A “service” in KDP defines a unique Kubernetes API Group and offers a number of resources (types) to
use. A service could offer certificate management, databases, cloud infrastructure or any other set
of Kubernetes resources.
Once a service is enabled in a workspace,
new Kubernetes resource types (APIs) become available, similar to how CustomResourceDefinitions would
introduce new APIs.
Creating Resources
Consult the service’s documentation to learn more about what resources are available and how to use
them. The written documentation often contains valuable information that is not available from just
inspecting the Kubernetes API types.
Dashboard
Navigate to your organization and then choose the desired service in the sidebar. The dashboard will
present a list of existing resources that are part of this service, plus it offers a simple editor
to create and update them.
kubectl
To see which API resources are available in your workspace, use the api-resources
subcommand:
$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
databases db example.corp/v1 true Database
...
In the example above, we can see that the fictional RBDMS service enabled in this workspace provides
a new resource, databases
, in the API group/version example.corp/v1
.
You could now create a new database by first creating a YAML file like prod1.yaml
as described in
the service’s documentation:
apiVersion: example.corp/v1
kind: Database
metadata:
name: prod1
namespace: example-app
spec:
size: large
performance: good
backups: true
Now you could use kubectl apply -f prod1.yaml
to create your database.
Consuming Secrets
In most cases, creating a new resource alone is not enough to actually use it. Creating a database
like shown above is not useful without getting access to the database’s address and credentials.
There are two ways this information can be provided by the service to the platform user.
Status Subresource
Some service’s might make use of the status
subresource in their resources. Usually the user
specifies the spec
part of a resource (the desired state) and the service would, while processing
the resource, fill in status information in the status
subresource. In the imaginary database
example above, if you’d retrieve the current state of the prod1
database, it might look like this:
apiVersion: example.corp/v1
kind: Database
metadata:
name: prod1
namespace: example-app
uid: 1234-5678
resourceVersion: 1
spec:
size: large
performance: good
backups: true
status:
conditions:
- name: online
status: false
- name: provisioning
status: true
- name: spec-valid
status: true
connectionDetails:
username: prod1-23j42
password: jhk542b3f9g28br2f
url: sql+tls://dbms.databases.example.corp:28362
Platform users should not (need to) attempt to change the status
of a resource, as the continuous
synchronization process behind the scenes will revert such changes usually shortly thereafter. In
general, the spec
flows from the user to the service provider, the status
flows back up to the
user.
Consult the service’s documentation to learn more about the available information and whether a
status subresource is being used at all.
To keep sensitive data like credentials separate from the “public” part of a resource, dedicated
resources (often Secrets or ConfigMaps) can be used instead of a status
subresource. For example
if you created a TLS certificate object in an imaginary PKI service, the actual x509 certificate and
private key might be provided to the user in the form of a Secret (often in the same namespace as
the original source object).
Consult the service’s documentation on whether and how to specify where such related resources should
be stored. Some services decide it automatically, others require the desired name of the resulting
Secret as part of the spec
of the original object. Related objects will, regardless of explicit
or automatic naming, always be in the same workspace as the original object.
Suppose the imaginary database service above didn’t put the connectionDetails
in the status
, but
instead used a Secret. This would mean there 1 related resource and the service documents that it’s
called connection-details
.
For every related resource, there will be an annotation on the original object, named
related-resources.kdp.k8c.io/<name>
, the value being a JSON document of this structure:
{
"name": "<name of the related object>",
"namespace": "<namespace of the related object (field is omitted for Cluster-scoped objects)>",
"apiVersion": "<Kubernetes API group and version, e.g. v1>",
"kind": "<Kubernetes kind of the related object, e.g. Secret>"
}
The imaginary database from above might look like this:
apiVersion: example.corp/v1
kind: Database
metadata:
name: prod1
namespace: example-app
annotations:
related-resources.kdp.k8c.io/connection-details: '{"name":"prod1-credentials","namespace":example-app","apiVersion":"v1","kind":"Secret"}'
uid: 1234-5678
resourceVersion: 1
spec:
size: large
performance: good
backups: true
status:
conditions:
- name: online
status: false
- name: provisioning
status: true
- name: spec-valid
status: true
The actual content of the related resources is described in the service’s documentation.