Fly Kubernetes Quickstart

Fly Kubernetes is in beta and not recommended for critical production usage. To report issues or provide feedback, email us at beta@fly.io.

To create a Kubernetes cluster, run:

fly ext k8s create

This will start the provisioning process. You’ll be asked for a cluster name, the organization, and the region in which to create the cluster.

Once a cluster is provisioned, it will return a kubeconfig that can be used to connect to your cluster’s Kubernetes API server using kubectl.

For example:

apiVersion: v1
clusters:
  - name: fks-flyio-fksdemo
    cluster:
      certificate-authority-data: ...
      server: https://fks-flyio-fksdemo.flycast:6443
      extensions:
      ...
      ...
contexts:
  - context:
      cluster: fks-flyio-fksdemo
      user: default
    name: default
current-context: default
kind: Config
preferences: {}
users:
  - name: default
    user:
    ...
    ...

We’re going to save the output into a file named kubeconfig and create an environment variable KUBECONFIG that points to the file:

export KUBECONFIG=/path/to/kubeconfig/file

Our cluster is accessible over our organization’s private WireGuard network. To connect to our cluster, we need a WireGuard configuration.

Follow the Private Network VPN instructions to set up a permanent WireGuard connection to your Fly.io IPv6 private network.

From there, you can use standard YAML configuration to drive Kubernetes. Here’s a simple deployment example from the Kubernetes official documentation:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

This creates a ReplicaSet with 3 nginx pods. Using kubectl, we can apply this:

kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
deployment.apps/nginx-deployment created

We can see our deployment:

kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           7s

We can view the logs of all the pods in the deployment:

kubectl logs -l app=nginx
Pulling container image registry-1.docker.io/library/nginx:1.14.2
Pulling container image registry-1.docker.io/library/nginx:1.14.2
Pulling container image registry-1.docker.io/library/nginx:1.14.2
Successfully prepared image registry-1.docker.io/library/nginx:1.14.2 (1.597714717s)
Successfully prepared image registry-1.docker.io/library/nginx:1.14.2 (1.493016957s)
Successfully prepared image registry-1.docker.io/library/nginx:1.14.2 (1.604003393s)
Configuring firecracker
Configuring firecracker
Configuring firecracker
...

What we don’t support

  • Multi-container pods (coming soon)
  • Network policies
  • Horizontal pod autoscaling
  • Gateway API
  • Daemon sets
  • EmptyDir volumes
  • Interactive pods (kubectl run --interactive --tty)

On container specs, we don’t support the following fields:

  • workingDir
  • ports
  • livenessProbe
  • readinessProbe
  • startupProbe
  • resizePolicy
  • stdin
  • stdinOnce
  • tty
  • EnvVarSource.fieldRef
  • EnvVarSource.resourceFieldRef
  • volumeDevices
  • lifecycle
  • terminationMessagePath
  • terminationMessagePolicy
  • imagePullPolicy
  • securityContext

Other caveats

Right now we don’t get logs from a single pod. If you try to get logs from a single pod, you’ll get the logs from every pod in the namespace.