diff --git a/docs/dev/operators.md b/docs/dev/operators.md index ce6bc6601..c276acafd 100644 --- a/docs/dev/operators.md +++ b/docs/dev/operators.md @@ -14,7 +14,7 @@ LABEL io.openshift.release.operator=true Ensure your image is published into the cluster release tag by ci-operator Wait for a new release payload to be created (usually once you push to master in your operator). -## What do I put in /manifests? +## What do I put in `/manifests`? You need the following: @@ -26,7 +26,7 @@ You need the following: - Deployment for your operator - A ClusterOperator CR [more info here](clusteroperator.md) - Any other config objects your operator might need -- An image-references file (See below) +- An `image-references` file (see [below](#how-do-i-ensure-the-right-images-get-used-by-my-manifests)). In your deployment you can reference the latest development version of your operator image (quay.io/openshift/origin-machine-api-operator:latest). If you have other hard-coded image strings, try to put them as environment variables on your deployment or as a config map. @@ -84,7 +84,7 @@ Your manifests can contain a tag to the latest development image published by Or Assume you have two images in your manifests - `quay.io/openshift/origin-ingress-operator:latest` and `quay.io/openshift/origin-haproxy-router:latest`. Those correspond to the following tags `ingress-operator` and `haproxy-router` when the CI runs. -Create a file `image-references` in the /manifests dir with the following contents: +Create a file `image-references` in the `/manifests` directory with the following contents: ```yaml kind: ImageStream @@ -101,13 +101,42 @@ spec: Name: quay.io/openshift/origin-haproxy-router ``` -The release tooling will read image-references and do the following operations: +The release tooling will read `image-references` and do the following operations: -Verify that the tags `ingress-operator` and `haproxy-router` exist from the release / CI tooling (in the image stream `openshift/origin-v4.0` on api.ci). If they don’t exist, you’ll get a build error. -Do a find and replace in your manifests (effectively a sed) that replaces `quay.io/openshift/origin-haproxy-router(:.*|@:.*)` with `registry.svc.ci.openshift.org/openshift/origin-v4.0@sha256:` -Store the fact that operator ingress-operator uses both of those images in a metadata file alongside the manifests -Bundle up your manifests and the metadata file as a docker image and push them to a registry +1. Verify that the tags `ingress-operator` and `haproxy-router` exist from the release / CI tooling (in the image stream `openshift/origin-v4.0` on api.ci). If they don’t exist, you’ll get a build error. +2. Do a find and replace in your manifests (effectively a `sed`) that replaces `quay.io/openshift/origin-haproxy-router(:.*|@:.*)` with `registry.svc.ci.openshift.org/openshift/origin-v4.0@sha256:` +3. Store the fact that operator ingress-operator uses both of those images in a metadata file alongside the manifests. +4. Bundle up your manifests and the metadata file as a docker image and push them to a registry. Later on, when someone wants to mirror a particular release, there will be tooling that can take the list of all images used by operators and mirror them to a new repo. This pattern tries to balance between having the manifests in your source repo be able to deploy your latest upstream code *and* allowing us to get a full listing of all images used by various operators. + +## Dynamic objects + +Some objects are not static. +For example, an operator configuration could depend on configuration passed to the installer (cluster name, cluster domain, service CIDR, etc.). +An operator should auto-discover the dependencies and build the dynamic objects when it first comes up. +For example: + +1. An operator provides `/manifests/deployment.yaml` with a static deployment. +2. The cluster-version operator processes the operator's [`/manifests`](#what-do-i-put-in-manifests) and pushes the deployment into the cluster. +3. The cluster schedules the operator for a particular node. +4. That node launches the operator pod and its constituent containers. +5. The operator container tries to pull its configuration. + * If found, the operator uses that configuration. + * If not found, the operator: + 1. Pulls the dependency resources (e.g. the `cluster-config-v1` config-map from the `kube-system` namespace). + Documentation for connecting to the Kubernetes API from pod containers is [here][API-from-pod]. + Operators written in Go can use [`InClusterConfig`][InClusterConfig] to configure their client. + 2. Generates the dynamic configuration based on the dependencies. + 3. Pushes the generated configuration into the cluster, where future operator runs and other consumers will be able to find it. + +For an example, see [the machine-API operator's `getOperatorConfig`][getOperatorConfig], although they don't need the "push the generated configuration into the cluster" step. +Their process is similar to the above example, except that they have no external consumers for their configuration. +To avoid confusion, they just pull `cluster-config-v1` and generate their configuration in memory [for each round of their poll loop][getOperatorConfig-call-site]. + +[API-from-pod]: https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#accessing-the-api-from-a-pod +[getOperatorConfig]: https://github.com/openshift/machine-api-operator/blob/v0.1.0/pkg/operator/operator.go#L302-L310 +[getOperatorConfig-call-site]: https://github.com/openshift/machine-api-operator/blob/v0.1.0/pkg/operator/operator.go#L157 +[InClusterConfig]: https://godoc.org/k8s.io/client-go/rest#InClusterConfig