Kompose - User Guide

User Guide

Table of contents

Kompose Conversion Example

Kompose has support for two providers: OpenShift and Kubernetes. You can choose a targeted provider using global option --provider. If no provider is specified, Kubernetes is set by default.

Kubernetes

$ kompose --file compose.yaml convert

You can also provide multiple compose files at the same time:

$ kompose -f compose.yaml -f compose.yaml convert

When multiple compose files are provided the configuration is merged. Any configuration that is common will be over ridden by subsequent file.

You can provide your compose files via environment variables as following:

$ COMPOSE_FILE="compose.yaml alternative-compose.yaml" kompose convert

OpenShift

$ kompose --provider openshift --file compose.yaml convert

CLI Modifications

On the command line, you can modify the output of the generated YAML. For example, using alternative controllers such as Replication Controllers objects, Daemon Sets, or Statefulset.

Daemon Set example:

$ kompose convert --controller daemonSet

A full list of these options can be found on kompose convert --help.

Labels

kompose supports Kompose-specific labels within the compose.yaml file to get you the rest of the way there.

Labels are an important kompose concept as they allow you to add Kubernetes modifications without having to edit the YAML afterwards. For example, adding an init container, or a custom readiness check.

Key / Value Description / Example
kompose.controller.port.expose Expose as hostPort on the controller (not recommended)
Boolean false
kompose.controller.type Type of the controller
String deployment, daemonset, replicationcontroller, statefulset
kompose.cronjob.backoff_limit Number of retries before marked as failed
Integer 6
kompose.cronjob.concurrency_policy Handling of concurrent jobs
String Forbid, Allow, Never
kompose.cronjob.schedule Schedule
String 1 * * * *
kompose.hpa.cpu CPU utilization percentage that triggers autoscaling
Percentage 50%
kompose.hpa.memory Memory utilization threshold that triggers autoscaling
String 200Mi
kompose.hpa.replicas.max Max pod replicas for Horizontal Pod Autoscaler
Integer 10
kompose.hpa.replicas.min Min pod replicas for Horizontal Pod Autoscaler
Integer 2
kompose.image-pull-policy Policy for pulling images
String Always, IfNotPresent, Never
kompose.image-pull-secret Secret to be used for pulling images from a private registry
String myregistrykey
kompose.init.containers.command Command to be executed
Array ["printenv"]
kompose.init.containers.image Image to be used
String busybox
kompose.init.containers.name Name assigned
String init-mydb
kompose.security-context.fsgroup Filesystem group ID for the pods’ volumes
Integer 1001
kompose.service.external-traffic-policy Policy to route external traffic
String cluster, local
kompose.service.expose Creates a Ingress or Route. Accepts domain or ‘true’ for auto-generating a domain.
String true,domain1.com,domain2.com
kompose.service.expose.ingress-class-name Ingress class to be used for exposing services
String nginx
kompose.service.expose.tls-secret TLS secret for securing ingress
String my-tls-secret
kompose.service.group Label to group multiple containers in a single pod
String mygroup
kompose.service.healthcheck.liveness.http_get_path HTTP GET path for liveness probe
String /health
kompose.service.healthcheck.liveness.http_get_port HTTP GET port for liveness probe
Integer 8080
kompose.service.healthcheck.liveness.tcp_port TCP socket port for liveness probe
Integer 3306
kompose.service.healthcheck.readiness.disable Whether to disable the readiness probe
Boolean true
kompose.service.healthcheck.readiness.http_get_path HTTP GET path for readiness probe
String /ready
kompose.service.healthcheck.readiness.http_get_port HTTP GET port for readiness probe
Integer 8081
kompose.service.healthcheck.readiness.interval Interval between readiness checks
Duration 10s
kompose.service.healthcheck.readiness.retries Number of times readiness probe should retry before failing
Integer 3
kompose.service.healthcheck.readiness.start_period Initial delay before starting the readiness probe
Duration 30s
kompose.service.healthcheck.readiness.tcp_port TCP socket port for readiness probe
Integer 3307
kompose.service.healthcheck.readiness.test Command or script run by the readiness probe
Array ["CMD", "echo", "OK"]
kompose.service.healthcheck.readiness.timeout Timeout for a single readiness probe
Duration 5s
kompose.service.nodeport.port Specific port number to be used as NodePort
Integer 30000
kompose.service.type Type of service
String nodeport, clusterip, loadbalancer, headless
kompose.volume.size Size of the volume
String 1Gi
kompose.volume.storage-class-name StorageClassName for provisioning volumes
String standard
kompose.volume.sub-path Subpath inside the mounted volume
String /data
kompose.volume.type Type of Kubernetes volume
String configMap, persistentVolumeClaim, emptyDir, hostPath

kompose.controller.port.expose

services:
  web:
    image: wordpress:latest
    ports:
      - '80:80'
    labels:
      kompose.controller.expose.port: true

kompose.controller.type

services:
  web:
    image: wordpress:latest
    ports:
      - '80:80'
    labels:
      kompose.controller.type: deployment

kompose.cronjob.backoff_limit

services:
  cron-job:
    image: busybox
    labels:
      kompose.cronjob.backoff_limit: 3

kompose.cronjob.concurrency_policy

services:
  periodic-task:
    image: busybox
    labels:
      kompose.cronjob.concurrency_policy: Forbid

kompose.cronjob.schedule

services:
  cron-job:
    image: busybox
    labels:
      kompose.cronjob.schedule: "*/5 * * * *"

kompose.hpa.cpu

services:
  web:
    image: nginx
    labels:
      kompose.hpa.cpu: 80

kompose.hpa.memory

services:
  db:
    image: mysql
    labels:
      kompose.hpa.memory: 512Mi

kompose.hpa.replicas.max

services:
  api:
    image: custom-api
    labels:
      kompose.hpa.replicas.max: 10

kompose.hpa.replicas.min

services:
  api:
    image: custom-api
    labels:
      kompose.hpa.replicas.min: 2

kompose.image-pull-policy

services:
  example-service:
    image: example-image
    labels:
      kompose.image-pull-policy: "IfNotPresent"

kompose.image-pull-secret

services:
  private-service:
    image: private-repo/image:tag
    labels:
      kompose.image-pull-secret: "my-private-registry-key"

kompose.init.containers.command

services:
  init-service:
    image: busybox
    labels:
      kompose.init.containers.command: ["echo", "Initializing..."]

kompose.init.containers.image

services:
  init-service:
    image: busybox
    labels:
      kompose.init.containers.image: busybox

kompose.init.containers.name

services:
  init-service:
    image: busybox
    labels:
      kompose.init.containers.name: "initial-setup"

kompose.security-context.fsgroup

services:
  secured-service:
    image: nginx
    labels:
      kompose.security-context.fsgroup: 2000

kompose.service.external-traffic-policy

services:
  front-end:
    image: quay.io/kompose/web
    ports:
      - 8080:8080
    labels:
      kompose.service.external-traffic-policy: local

kompose.service.expose

services:
  web-app:
    image: nginx
    ports:
      - 80:80
    labels:
      kompose.service.expose: "example.com"

kompose.service.expose.ingress-class-name

services:
  web:
    image: nginx
    ports:
      - 80:80
    labels:
      kompose.service.expose.ingress-class-name: "nginx"

kompose.service.expose.tls-secret

services:
  web:
    image: nginx
    ports:
      - 443:443
    labels:
      kompose.service.expose.tls-secret: "my-ssl-secret"

kompose.service.group

version: "3"

services:
  nginx:
    image: nginx
    depends_on:
      - logs
    labels:
      - kompose.service.group=sidecar

  logs:
    image: busybox
    command: ["tail -f /var/log/nginx/access.log"]
    labels:
      - kompose.service.group=sidecar

kompose.service.healthcheck.liveness.http_get_path

services:
  web:
    image: custom-web
    ports:
      - "8080:8080"
    labels:
      kompose.service.healthcheck.liveness.http_get_path: /health

kompose.service.healthcheck.liveness.http_get_port

services:
  web:
    image: custom-web
    ports:
      - "8080:8080"
    labels:
      kompose.service.healthcheck.liveness.http_get_port: 8080

kompose.service.healthcheck.liveness.tcp_port

services:
  db:
    image: mysql
    ports:
      - "3306:3306"
    labels:
      kompose.service.healthcheck.liveness.tcp_port: 3306

kompose.service.healthcheck.readiness.disable

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.disable: true

kompose.service.healthcheck.readiness.http_get_path

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.http_get_path: /ready

kompose.service.healthcheck.readiness.http_get_port

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.http_get_port: 8081

kompose.service.healthcheck.readiness.interval

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.interval: 10s

kompose.service.healthcheck.readiness.retries

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.retries: 3

kompose.service.healthcheck.readiness.start_period

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.start_period: 30s

kompose.service.healthcheck.readiness.tcp_port

services:
  db:
    image: mysql
    labels:
      kompose.service.healthcheck.readiness.tcp_port: 3307

kompose.service.healthcheck.readiness.test

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.test: ["CMD", "curl", "-f", "http://localhost:8081/ready"]

kompose.service.healthcheck.readiness.timeout

services:
  web:
    image: custom-web
    labels:
      kompose.service.healthcheck.readiness.timeout: 5s

kompose.service.nodeport.port

services:
  web:
    image: nginx
    ports:
      - "30000:80"
    labels:
      kompose.service.nodeport.port: 30000

kompose.service.type

services:
  web:
    image: nginx
    ports:
      - "80:80"
    labels:
      kompose.service.type: nodeport

kompose.volume.size

services:
  db:
    image: postgres:10.1
    labels:
      kompose.volume.size: 1Gi
    volumes:
      - db-data:/var/lib/postgresql/data

kompose.volume.storage-class-name

services:
  db:
    image: postgres:10.1
    labels:
      kompose.volume.storage-class-name: custom-storage-class-name
    volumes:
      - db-data:/var/lib/postgresql/data

kompose.volume.sub-path

services:
  pgadmin:
    image: postgres
    labels:
      kompose.volume.sub-path: pg-data

kompose.volume.type

services:
  db:
    image: postgres
    labels:
      kompose.volume.type: persistentVolumeClaim
    volumes:
      - db-data:/var/lib/postgresql/data

Restart Policy

If you want to create normal pods without a controller you can use the restart construct of compose to define that. Follow the table below to see what happens on the restart value.

compose restart object created Pod restartPolicy
"" controller object Always
always controller object Always
unless-stopped controller object Always
on-failure Pod / CronJob OnFailure
no Pod / CronJob Never

Note: controller object could be deployment, replicationcontroller, etc.

For example, the pival service will become a pod down here. This container calculated the value of pi.

version: '2'

services:
  pival:
    image: perl
    command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
    restart: "on-failure"

For example, the pival service will become a cron job down here. This container calculated the value of pi every minute.

version: '2'

services:
  pival:
    image: perl
    command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
    restart: "no"
    labels:
      kompose.cronjob.schedule: "* * * * *"
      kompose.cronjob.concurrency_policy: "Forbid"
      kompose.cronjob.backoff_limit: "0"

Warning about Deployment Configs

If the Compose file has a volume specified for a service, the Deployment (Kubernetes) or DeploymentConfig (OpenShift) strategy is changed to “Recreate” instead of “RollingUpdate” (default). This is done to avoid multiple instances of a service from accessing a volume at the same time.

If the Compose file has a service name with _ or . in it (e.g., web_service or web.service), then it will be replaced by - and the service name will be renamed accordingly (e.g., web-service). Kompose does this because “Kubernetes” doesn’t allow _ in object names.

Please note that changing the service name might break some compose files.

Building and Pushing Images

If the Compose file has build or build:context, build:dockerfile keys, build will run when --build specified.

And Image will push to docker.io (default) when --push-image=true specified.

It is possible to push to a custom registry by specifying --push-image-registry, which will override the registry from the image name.

Authentication on Registry

Kompose uses the docker authentication from file $DOCKER_CONFIG/config.json, $HOME/.docker/config.json, and $HOME/.dockercfg after docker login.

This only works fine on Linux but macOS would fail when using "credsStore": "osxkeychain".

However, there is an approach to push successfully on macOS, by not using osxkeychain for credsStore. To disable osxkeychain:

  • remove credsStore from the config.json file, and docker login again.
  • for some docker desktop versions, there is a setting Securely store Docker logins in macOS keychain, which should be unchecked. Then restart docker desktop if needed, and docker login again.

Now config.json should contain base64 encoded passwords, then push image should succeed. Working, but not safe though! Use it at your risk.

For Windows, there is also credsStore which is wincred. Technically it will fail on authentication as macOS does, but you can try the approach above like macOS too.

Custom Build and Push

If you want to customize the build and push processes and use another containers solution than Docker, Kompose offers you the possibility to do that. You can use --build-command and --push-command flags to achieve that.

e.g: kompose -f convert --build-command 'whatever command --you-use' --push-command 'whatever command --you-use'