Skip to content

Design discussion around image controlling variables

Edwin Buck edited this page Oct 10, 2023 · 7 revisions

Initial thoughts

Originally I thought I would just put the images into a variable, similar to in (agent-daemonset.yaml)

spec.template.spec.containers[@name="{{.Release.name}}"].image = "ghcr.io/spiffe/spire-agent:1.8.0"

but that would duplicate the .Chart.appVersion as the default, so we would need

spec.template.spec.containers[@name="{{.Release.name}}"].image = {{ printf "%s:%s" "ghcr.io/spiffe/spire-agent" .Chart.appVersion }}

Clearly tying .Chart.appVersion to the image tag is more valuable than having a single simple setting. Note that this opens the door for also separating the registry from the image

spec.template.spec.containser[@name="{{.Release.name}}"].image = {{ printf "%s/%s:%s" .image.registry "spiffe/spire-agent" .Chart.appVersion }}

This means that for consistency, we probably should also put the image name into a variable. This leaves

  • image.registry (defaults to ghcr.io)
  • image.name (defaults based on server / agent / etc.)
  • image.tag (defaults to .Chart.appVersion)

Note that image.name is not going to be the same for all images, so we need

  • agent.image.name
  • server.image.name

And overrides for the defaults specific to the agent settings and server settings

  • agent.image.registry
  • agent.image.tag
  • server.image.registry
  • server.image.tag

Finally, registries have optional non-default port numbers.

  • image.registryPort
  • agent.image.registryPort

leaving

  • image.registry (defaults to ghcr.io)
  • image.registryPort (defaults to nothing)
  • image.name (defaults based on server / agent / etc.)
  • image.tag (defaults to .Chart.appVersion)

and

  • agent.image.repository
  • agent.image.repositoryPort
  • agent.image.name
  • agent.image.tag
  • server.image.repository
  • server.image.repositoryPort
  • server.image.name
  • server.image.tag

Handling of defaults

Based on precedence, the values will bind to more specific settings over less specific settings or defaults. The ordering is (for the agent)

  • agent.image.registry (then) .image.registry (then) "ghcr.io"
  • agent.image.registryPort (then) .image.registryPort (then) nothing
  • agent.image.name (then) "spire/spire-agent"
  • agent.image.tag (then) .image.tag (then) .Chart.appVersion

Similar precedence should exist for server and / or other components that require images.

Image pull policy

Similar to the images, the pull policy can be configured globally

  • image.pullPolicy
  • agent.image.pullPolicy

To comply with Kubernetes policies, the pullPolicy depends on the .agent.image.tag.

  • When .agent.image.tag is "latest" the default pull policy is "always"
  • When .agent.image.tag is empty the default pull policy is "always" as this is an alias for "latest".
  • When .agent.image.tag is a non-empty string value, the pull policy is "IfNotPresent"

Note that as the default for .agent.image.tag eventually defaults to .Chart.appVersion, the .agent.image.tag being empty may be an impossible setting.

Therefore the agent.image.pullPolicy should have the following precedence

  • agent.image.pullPolicy (then) .image.pullPolicy (then, when agent.image.tag is "latest") "always"
  • agent.image.pullPolicy (then) .image.pullPolicy (then, when agent.image.tag is not "latest") "IfNotPresent"

Variable Naming Patterns

The names above have a decided pattern. The .image space configures defaults for all images, but lacks any settings that have no single default for all images. The .(item).image space contains the same keys as the .image space, and additional keys for items that contain no single default under the .image space.

Unexplored questions

  • How will we handle image pull secrets? I am thinking that we need a secrets file, but that the settings should be encouraged to be passed on the command line (in the documentation). The secrets file likely should be tied to repository value.

Guidelines

Some of these items are arbitrary, but a decision must be made for consistency.

  • Use the word registry instead of repository
  • Use the word tag instead of version

The idea behind these choices is to bind to the nomenclature of a Docker registry over other nomenclatures. We hope this makes the software easier to use. These items are up for discussion, but we should have only one word for each idea.