Jump to heading Kubernetes integration
Phabalicious can help you integrating your app with a Kubernetes stack and running your common tasks against an installation hosted on a Kubernetes cluster. You can leverage phabalicious scaffolder to create yml definitions for your app and apply them to your cluster automatically. Phab can also help you getting a shell to one of your pods.
Note:
The current version of phabalicious does not support any kind of authorization or authentication. It expects that the local environment is set up correctly for executing kubectl
!
Jump to heading Host-Configuration
All necessary configuration is located under the kube
-property. You can use replacement-patterns to use placeholder to replace certain values. Here's an example:
hosts:
k8s-example:
needs:
- k8s
kube:
kubeconfig: "%globals.userFolder%/.kube/my-config"
environment:
SOME_VAR: some_value
context: my-context
scaffolder:
baseUrl: ./public/scaffold/kube
namespace: factorial-infra
podSelector:
- app=%host.kube.parameters.name%
- type=%host.type%
parameters:
name: config
hosts:
- config.factorial.io
projectSlug: config
dockerImage: registry.factorial.io:8443/administration/config:latest
letsencrypt: 1
containerPort: 80
Jump to heading The defaults
The Kubernetes intergration provides sensible defaults for most use-cases. These defaults can be overridden via the actual configuration.
hosts:
k8s-exampl:
shellExecutable: /bin/sh
kubectlExecutable: kubectl
kubectlOptions: []
kube:
kubeconfig: false
context: false
environment: []
namespace: default
scaffolder:
baseUrl: https://config.factorial.io/scaffold/kube
template: simple/index.yml
scaffoldBeforeApply: true
applyBeforeDeploy: true
waitAfterApply: true
projectFolder: kube
applyCommand: 'apply -k .'
deleteCommand: 'delete -k .'
deployments:
- '%host.kube.parameters.name%'
useRsync: false
Property | Description | Example |
---|---|---|
shellExecutable |
What shell to execute inside the pod. | /bin/sh |
kubectlExecutable |
The name of the kubectl executable | kubectl |
kubectlOptions |
array with command-line options for kubectl, in the format --option: value |
- --insecure-skip-tls-verify: "" |
kube.kubeconfig |
the kubeconfig to use for any kubectl command | %globals.userFolder%/.kube/my-kube-config |
kube.context |
the context to switch before calling any kubectl command | |
kube.environment |
An array of environment variables to set before calling any kubectl command. | |
kube.namespace |
The namespace to apply to all kubectl commands | myapp |
kube.scaffolder.baseUrl |
Base-URL for the scaffolder | |
kube.scaffolder.template |
the template file name to use when scaffolding the definition files | |
kube.scaffoldBeforeApply |
If set to true, the definition files will be scaffolded before they get applied | true |
kube.waitAfterApply |
Wait until deployment is finished after apply. Needs deployments with sensible data |
true |
kube.projectFolder |
Where the definition files are stored, also the target for the scaffolding step | kube |
kube.applyCommand |
What command to run to apply the definition files to the cluster | apply -k . |
kube.deleteCommand |
What command to run to delete the app from the cluster | delete -k . |
kube.deployments |
An array of deployment names to check if the deployment is finished | - %host.kube.parameters.name% |
kube.useRsync |
If the target pod has rsync installed you can set this to true, then rsync will be used to transfer files between your host and the pod instead of kubectl |
- %host.kube.parameters.name% |
Jump to heading Scaffolding yml definitions
Phab can scaffold your yml definition files before running a deployment or on request. You can use all the possibilities from the scaffolding engine and store your parameters inside the fabfile.yaml. This allows you to reuse existing configuration and adapt your Kubernetes definition files to environment specific settings.
For this to work your kube
-section needs to contain the following parts:
hosts:
k8s-example:
kube:
projectFolder: kube/
scaffolder:
baseUrl: ./path/to/folder/with/templates # Can be a url
template: ./path/to/template.yml
parameters:
name: name of the project
projectSlug: slug-of-the-project
Phab will use the yml file from baseUrl and template and run the scaffold script from there. parameters
are available in the twig templates for replacement and via the %parameter%
-notation available in file-names etc. Additionally the complete host-parameters are available via host.property_name
, e.g. host.kube.projectFolder
(Surrounded by double curly braces or percents)
Phab adds the following parameters automatically:
Property | Description | Example |
---|---|---|
scaffoldTimeStamp |
a slugified timestamp when the scaffolding was done. Useful to indicate a change in the definition so Kubernetes will recreate a pod for example. | 20200721-083614Z |
host.* |
The current host configuration | host.rootFolder , host.kube.namespace |
namespace |
The namespace taken from the kube config, defaults to default |
my-namespace |
An example scaffold.yml-file:
requires: 3.5
questions:
hosts:
question: Hosts for the site
type: array
projectSlug:
question: Name of the project
validation: "/^[a-z0-9]+(?:-[a-z0-9]+)*$/"
error: Name should only ontain alphanumerics and hyphens
letsencrypt:
question: Use letsencrypt
type: confirm
default: true
namespace:
question: Which namespace to deploy to
assets:
- 00-app-secrets.yml
- 01-pvc.yml
- 02-deployment.yml
- 03-service.yml
- 04-ingress.yml
- kustomization.yml
scaffold:
- copy_assets(%rootFolder%, assets)
- log_message(success, The scaffolded files are stored in the kube-folder)
This will prompt for any missing property in parameters
via the questions block and then scaffold the yml files to the projectFolder.
Here's an example yml definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ name }}
labels:
app: {{ name }}
project: {{ projectSlug }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ name }}
template:
metadata:
labels:
app: {{ name }}
type: {{ host.type }}
buildDate: {{ scaffoldTimestamp }}
spec:
containers:
- image: "{{dockerImage}}"
name: {{ name }}
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /
port: {{ containerPort }}
readinessProbe:
httpGet:
path: /
port: {{ containerPort }}
imagePullSecrets:
- name: registry-secrets
Jump to heading Working with contexts
phab can support different contexts, just add the name of the context to the kube
-configuration. Phab will switch to that context before doing any work, and restore the context afterwards. If an error happens, the context might not get restored correctly.
The preferred way to use different clusters with phabalicious is to have dedicated kubeconfig files and reference them in the project via the kubeconfig
-property, e.g.
hosts:
example:
kube:
kubeconfig: "%globals.userFolder%/.kube/my-config"
context: my-context
This will make sure, that the context is not available after phab finished its work. You can use replacement patterns for the value of kubeconfig.
Jump to heading Getting a shell to one of the pods
Phab contains a shell-provider for Kubernetes, but it needs some guidance so it knows which pod to connect to. Phab is using a set of selectors to acquire the name of the actual running pod. As every project is different it makes sense to store this information in the kube
-section of your host configuration:
hosts:
k8s-example:
kube:
podSelector:
-service_type=%host.kube.serviceName%
serviceName: builder
...
The podSelector
contains one or more selectors which get appended to the kubctl call to get the name of the pod. In the above example the podSelector is using a %property%
to use another property of the kube config. This makes it easy to change the pod-selector via the --set
-option. Phab will also query the actual deployment and the relevant replicaset to append a pod-template-hash
selector to the query to make sure, to connect to the latest pod.
To actually start a shell:
phab -c<config> shell
This should open an interactive shell on your selected pod.
To override the pod-selector in the above example:
phab -c<config> shell --set host.kube.serviceName=nginx
this will open a shell to the pod which is the result of the selector service_type=nginx
. The actual command will look like this: kubectl get pods --namespace <the-namespace> -l <the-pod-selector> -o json
The shell is also used to run parts of the other commands like reset
, deploy
, etc.
Jump to heading k8s subcommands
the k8s
provides a list of sub-commands, which maps to corresponding kubectl
commands for the most popular use cases. Phab will provide the namespace option when needed and change the current directory to the kube project folder.
Jump to heading
the scaffold
subcommand
phab -c<config> k8s scaffold
This will run the scaffolder to produce a new set of definition files. Nothing more. The files will be scaffolded to the kube project folder.
Jump to heading
the apply
subcommand
phab -c<config> k8s apply
Applies the definitions files using kubectl
and the property applyCommand
from the kube-configuration. The applyCommand
defaults to apply -t .
If scaffoldBeforeApply
is set to true, the yml definitions get scaffolded before running apply.
If waitAfterApply
is true, then phab will wait for the end of the deployment using kubectl rollout status
. This means the execution is blocked until the app is available again and the rollout is finished. Make sure your deployments
-configuration is uptodate, as phab needs to know which deployments need to be checked. You can use the %property%
notation to reference the kube configuration.
Here's an example:
hosts:
test-k8s:
kube:
deployments:
- "%host.kube.parameters.name%-builder"
- "%host.kube.parameters.name%-nginx"
- "%host.kube.parameters.name%-php"
parameters:
name: my-app
Phab will check the status of the rollouts for my-app-builder
, my-app-nginx
, my-app-php
before continuing.
You should limit the list of deployments only to the necessary ones to you need to interact to.
Jump to heading
the delete
subcommand
phab -c<config> k8s delete
Run the deleteCommand
to delete the current specs from the cluster.
Jump to heading
the kubectl
subcommand
phab -c<config> k8s kubectl -- <args_for_kubectl>
Run kubectl
and applying the info from the kube config in the fabfile.
An example:
phab -c<config> k8s kubectl get pods
Jump to heading
the rollout
subcommand
phab -c<config> k8s rollout -- <args_for_rollout>
Run kubectl rollout
and applying the info from the kube config in the fabfile.
An example:
phab -c<config> k8s rollout history deployments/nginx
Jump to heading
the describe
subcommand
This subcommand will describe the pod desribed by the podSelector:
phab -c<config> k8s decribe
It uses the same podSelector mechanism as described under "Getting a shell"
Jump to heading
the logs
subcommand
This subcommand will print out the logs of a particular pod:
phab -c<config> k8s logs
It uses the same podSelector mechanism as described under "Getting a shell"
Jump to heading Integration into the deployment process of phabalicious
It depends on your project setup if it makes sense to scaffold and apply the definition files when runnning a regular deployment. If you want to opt in you need to set applyBeforeDeploy
to true. If set to true phabalicious will apply your definition files and depending on waitAfterApply
and scaffoldBeforeDeploy
even scaffold the definition files and/ or wait for the successful rollout. All this is run on the deployPrepare
-stage