Cloud Foundry supports two models for running applications in containers:
- Cloud Foundry Buildpacks
- Cloud Foundry Docker support
Some tenants prefer one of the other and others mix and match.
The CFF have a vision of replatforming Cloud Foundry onto a kubernetes stack.
The project for this work is called Korifi, it is in early development ([v0.1.0]) and is overseen by the [CFF cf on k8s working group].
The traditional container build components of Cloud Foundry are being replaced with kubernetes components, namely:
- paketo buildpacks, an implementation of the CNCF cloud native buildpacks
- kpack - a container build solution backed by VMware
Paketo buildpacks are a new modular approach to the buildpack concept and is an evolution of the work done in the CLoud Foundry and Heroku communities.
Originally created by Heroku (part of Salesforce) the concept forked into a couple of dialects. CNCF buildpacks is standardising the approach and unbundling it from the PaaS platforms where it traditionally lived. More platforms are appearing that support cloud native buildpacks.
Korifi will only support the new cloud native buildpack model and will not be backwardly compatible with the traditional buildpacks.
In addition there will be no native support for cloud native buildpacks in the traditional Cloud Foundry stack (based on BOSH)
This means that a tenant cannot specify a new cloud native buildpack as part of a cf push
command to the current version of Cloud Foundry.
There will be replacements for the familiar buildpacks however there may be some differences. (note it needs a couple of environment variables)
CF on BOSH | CF on k8s | |
---|---|---|
Classic buildpacks | yes | no |
Cloud Native buildpacks | no | yes |
Since the pack
tool can create container images from source locally without any dependencies on Cloud Foundry it is possible to do the following:
- create a container image using the
pack
command - upload the container image to a container registry (Dockerhub, GitHub Container Registry or any other registry that you want. ECR, GCP, harbor, quay.io)
- deploy the container image to a Cloud Foundry using the Docker support in
cf push -o
This will work with both:
- GOV.UK PaaS
- a Korifi Cloud Foundry on Kubernetes cluster running locally
For this example we will use the GOV.UK Prototype kit from alphagov/govuk-prototype-kit as our sample app. You can git clone https://github.com/alphagov/govuk-prototype-kit
You can also install the pack
command with
brew install buildpacks/tap/pack
pack build govuk-prototype-kit
full: Pulling from paketobuildpacks/builder
Digest: sha256:a1b349cb32d9cfb7c634b35aacdcaa42892275ced21f01f2238592573a8f838a
Status: Image is up to date for paketobuildpacks/builder:full
full-cnb: Pulling from paketobuildpacks/run
Digest: sha256:5c8332799698b02c78ac151feed0827e6d6b1f84ed91a9ba04827d96306a7ec7
Status: Image is up to date for paketobuildpacks/run:full-cnb
Previous image with name "govuk-prototype-kit" not found
===> DETECTING
7 of 11 buildpacks participating
paketo-buildpacks/ca-certificates 3.1.0
paketo-buildpacks/node-engine 0.12.3
paketo-buildpacks/npm-install 0.9.0
paketo-buildpacks/node-module-bom 0.2.4
paketo-buildpacks/node-start 0.8.0
paketo-buildpacks/npm-start 0.9.0
paketo-buildpacks/procfile 5.1.0
===> RESTORING
Restoring metadata for "paketo-buildpacks/node-module-bom:cyclonedx-node-module" from cache
Restoring data for "paketo-buildpacks/node-module-bom:cyclonedx-node-module" from cache
Restoring data for SBOM from cache
===> BUILDING
Paketo CA Certificates Buildpack 3.1.0
https://github.com/paketo-buildpacks/ca-certificates
Launch Helper: Contributing to layer
Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper
Paketo Node Engine Buildpack 0.12.3
Resolving Node Engine version
Candidate version sources (in priority order):
package.json -> ">=10.0.0 <15.0.0"
.nvmrc -> "14.15.1"
<unknown> -> ""
Selected Node Engine version (using package.json): 14.19.1
Executing build process
Installing Node Engine 14.19.1
Completed in 4.531s
Generating SBOM for directory /layers/paketo-buildpacks_node-engine/node
Completed in 0s
Configuring build environment
NODE_ENV -> "production"
NODE_HOME -> "/layers/paketo-buildpacks_node-engine/node"
NODE_VERBOSE -> "false"
Configuring launch environment
NODE_ENV -> "production"
NODE_HOME -> "/layers/paketo-buildpacks_node-engine/node"
NODE_VERBOSE -> "false"
Writing exec.d/0-optimize-memory
Calculates available memory based on container limits at launch time.
Made available in the MEMORY_AVAILABLE environment variable.
Paketo NPM Install Buildpack 0.9.0
Resolving installation process
Process inputs:
node_modules -> "Found"
npm-cache -> "Not found"
package-lock.json -> "Not found"
Selected NPM build process: 'npm rebuild'
Executing launch environment install process
Running 'npm run-script preinstall --if-present'
Running 'npm rebuild --nodedir=/layers/paketo-buildpacks_node-engine/node'
Running 'npm run-script postinstall --if-present'
Completed in 26.375s
Configuring launch environment
NPM_CONFIG_LOGLEVEL -> "error"
PATH -> "$PATH:/layers/paketo-buildpacks_npm-install/launch-modules/node_modules/.bin"
Generating SBOM for directory /layers/paketo-buildpacks_npm-install/launch-modules
Completed in 29.383s
Paketo Node Module Bill of Materials Generator Buildpack 0.2.4
Resolving CycloneDX Node.js Module version
Selected CycloneDX Node.js Module version: 3.0.7
Reusing cached layer /layers/paketo-buildpacks_node-module-bom/cyclonedx-node-module
Configuring environment
Appending CycloneDX Node.js Module onto PATH
Running CycloneDX Node.js Module
Running 'cyclonedx-bom -o bom.json'
Completed in 6.727s
Paketo Node Start Buildpack 0.8.0
Assigning launch processes:
web (default): node server.js
Paketo NPM Start Buildpack 0.9.0
Assigning launch processes:
web (default): bash -c node start.js
Paketo Procfile Buildpack 5.1.0
https://github.com/paketo-buildpacks/procfile
Process types:
web: node ./node_modules/gulp/bin/gulp generate-assets && node listen-on-port.js
===> EXPORTING
Adding layer 'paketo-buildpacks/ca-certificates:helper'
Adding layer 'paketo-buildpacks/node-engine:node'
Adding layer 'paketo-buildpacks/npm-install:launch-modules'
Adding layer 'launch.sbom'
Adding 1/1 app layer(s)
Adding layer 'launcher'
Adding layer 'config'
Adding layer 'process-types'
Adding label 'io.buildpacks.lifecycle.metadata'
Adding label 'io.buildpacks.build.metadata'
Adding label 'io.buildpacks.project.metadata'
Setting default process type 'web'
Saving govuk-prototype-kit...
*** Images (676f0d0101e4):
govuk-prototype-kit
Reusing cache layer 'paketo-buildpacks/node-engine:node'
Reusing cache layer 'paketo-buildpacks/node-module-bom:cyclonedx-node-module'
Adding cache layer 'cache.sbom'
Successfully built image govuk-prototype-kit
pack inspect govuk-prototype-kit
Inspecting image: govuk-prototype-kit
REMOTE:
(not present)
LOCAL:
Stack: io.buildpacks.stacks.bionic
Base Image:
Reference: a193a611aa391847f2c8fcdc0e6dd39fb6f6ec4dddba92924ab26e59ed6325d9
Top Layer: sha256:595a12e83a3e7f8d46663adf8b7af56e69098a994bf6e718134d0e8827071054
Run Images:
index.docker.io/paketobuildpacks/run:full-cnb
gcr.io/paketo-buildpacks/run:full-cnb
Buildpacks:
ID VERSION HOMEPAGE
paketo-buildpacks/ca-certificates 3.1.0 https://github.com/paketo-buildpacks/ca-certificates
gcr.io/paketo-buildpacks/run:full-cnb
Buildpacks:
ID VERSION HOMEPAGE
paketo-buildpacks/ca-certificates 3.1.0 https://github.com/paketo-buildpacks/ca-certificates
paketo-buildpacks/node-engine 0.12.3 https://github.com/paketo-buildpacks/node-engine
paketo-buildpacks/npm-install 0.9.0 https://github.com/paketo-buildpacks/npm-install
paketo-buildpacks/node-module-bom 0.2.4 https://github.com/paketo-buildpacks/node-module-bom
paketo-buildpacks/node-start 0.8.0 https://github.com/paketo-buildpacks/node-start
paketo-buildpacks/npm-start 0.9.0 https://github.com/paketo-buildpacks/npm-start
paketo-buildpacks/procfile 5.1.0 https://github.com/paketo-buildpacks/procfile
Processes:
TYPE SHELL COMMAND ARGS WORK DIR
web (default) bash node ./node_modules/gulp/bin/gulp generate-assets && node listen-on-port.js /workspace
docker images | grep govuk-prototype-kit
govuk-prototype-kit latest 676f0d0101e4 42 years ago 957M
docker tag 676f0d0101e4 ghcr.io/pauldougan/govuk-prototype-kit
Assumes you are set up to push to GitHub container registery, see configuration instructions
docker push
docker push ghcr.io/pauldougan/govuk-prototype-kit
Using default tag: latest
The push refers to repository [ghcr.io/pauldougan/govuk-prototype-kit]
83d85471d9f8: Mounted from pauldougan/python-flask
4769a67a4c53: Pushed
9497805c7bd5: Mounted from pauldougan/python-flask
95a4eb25570c: Pushed
5da05bec2e97: Pushed
28d1a8f81e24: Pushing [==================================================>] 153.3MB
09a8b1e6c657: Pushing [===================================> ] 76.86MB/106.9MB
7a5c55250641: Pushed
595a12e83a3e: Pushed
ed561ffcdffe: Pushing [==========> ] 131MB/627.1MB
cfb1c0cbebeb: Pushed
open https://ghcr.io/pauldougan/govuk-prototype-kit
or go to https://ghcr.io/pauldougan/govuk-prototype-kit
cf api
API endpoint: https://api.london.cloud.service.gov.uk
API version: 3.116.0
cf login --sso
API endpoint: https://api.london.cloud.service.gov.uk
Temporary Authentication Code ( Get one at https://login.london.cloud.service.gov.uk/passcode ):
Authenticating...
OK
Select an org:
There are too many options to display; please type in the name.
Org (enter to skip): gds-techarchs
Targeted org gds-techarchs.
Select a space:
1. sandbox
2. paul
Space (enter to skip): 1
Targeted space sandbox.
API endpoint: https://api.london.cloud.service.gov.uk
API version: 3.116.0
user: 104206899246339571570
org: gds-techarchs
space: sandbox
cf push -o ghcr.io/pauldougan/govuk-prototype-kit -m 128M -k 1G --no-manifest --no-start govuk-prototype-kit-paketo
name: govuk-prototype-kit-paketo
requested state: stopped
routes: govuk-prototype-kit-paketo.london.cloudapps.digital
last uploaded:
stack:
docker image:
type: web
sidecars:
instances: 0/1
memory usage: 128M
state since cpu memory disk details
#0 down 2022-06-23T11:01:37Z 0.0% 0 of 0 0 of 0
cf set-env govuk-prototype-kit-paketo USERNAME user
cf set-env govuk-prototype-kit-paketo USERNAME user
Setting env variable USERNAME for app govuk-prototype-kit-paketo in org gds-techarchs / space sandbox as 104206899246339571570...
OK
TIP: Use 'cf restage govuk-prototype-kit-paketo' to ensure your env variable changes take effect.
GDS11172:govuk-prototype-kit
cf set-env govuk-prototype-kit-paketo PASSWORD password
Setting env variable PASSWORD for app govuk-prototype-kit-paketo in org gds-techarchs / space sandbox as 104206899246339571570...
OK
TIP: Use 'cf restage govuk-prototype-kit-paketo' to ensure your env variable changes take effect.
cf env govuk-prototype-kit-paketo
Getting env variables for app govuk-prototype-kit-paketo in org gds-techarchs / space sandbox as 104206899246339571570...
System-Provided:
VCAP_SERVICES: {}
VCAP_APPLICATION: {
"application_id": "d7cb4d80-6746-4a7d-b5b0-4f3ca14181c4",
"application_name": "govuk-prototype-kit-paketo",
"application_uris": [
"govuk-prototype-kit-paketo.london.cloudapps.digital"
],
"cf_api": "https://api.london.cloud.service.gov.uk",
"limits": {
"fds": 16384
},
"name": "govuk-prototype-kit-paketo",
"organization_id": "7d8b1665-815a-4500-a8d7-f1ac0a61150f",
"organization_name": "gds-techarchs",
"space_id": "0b52392e-e1c3-43e1-84bc-7024bf61715f",
"space_name": "sandbox",
"uris": [
"govuk-prototype-kit-paketo.london.cloudapps.digital"
],
"users": null
}
User-Provided:
PASSWORD: password
USERNAME: user
No running env variables have been set
No staging env variables have been set
cf start
Starting app govuk-prototype-kit-paketo in org gds-techarchs / space sandbox as 104206899246339571570...
Staging app and tracing logs...
Cell 6617ab70-812f-454b-bff1-71a21515d135 creating container for instance ab96e02b-17e2-4a18-874d-d5cb17be255a
Cell 6617ab70-812f-454b-bff1-71a21515d135 successfully created container for instance ab96e02b-17e2-4a18-874d-d5cb17be255a
Starting app govuk-prototype-kit-paketo in org gds-techarchs / space sandbox as 104206899246339571570...
Waiting for app to start...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
Instances starting...
name: govuk-prototype-kit-paketo
requested state: started
routes: govuk-prototype-kit-paketo.london.cloudapps.digital
last uploaded: Thu 23 Jun 12:03:57 BST 2022
stack:
docker image: ghcr.io/pauldougan/govuk-prototype-kit:latest
type: web
sidecars:
instances: 1/1
memory usage: 128M
state since cpu memory disk details
#0 running 2022-06-23T11:04:36Z 0.0% 30.4M of 128M 916.8M of 1G
cf ssh
cf ssh govuk-prototype-kit-paketo
cnb@b4bc4b08-56bf-47aa-62eb-abc2:~$
top
KiB Swap: 32407548 total, 31376380 free, 1031168 used. 23655736 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 1044 4 0 S 0.0 0.0 0:00.02 garden-init
7 cnb 20 0 716108 10616 8516 S 0.0 0.0 0:00.14 diego-sshd
8 cnb 20 0 642128 57748 33164 S 0.0 0.2 0:01.10 node
44 root 20 0 4632 856 792 S 0.0 0.0 0:00.03 sh
90 root 20 0 2300508 50700 35892 S 0.0 0.2 0:00.86 envoy
143 root 20 0 706000 3424 2804 S 0.0 0.0 0:00.04 healthcheck
178 cnb 20 0 20184 3816 3476 S 0.0 0.0 0:00.00 bash
188 cnb 20 0 40368 3700 3212 R 0.0 0.0 0:00.00 top
open https://govuk-prototype-kit-paketo.london.cloudapps.digital
or visit https://govuk-prototype-kit-paketo.london.cloudapps.digital/
using user and password when prompted
assumes you have a local cluster installed, see pauls notes on korifi for some help getting it installed.
TLDR; assuming you have cf, docker, kind and kubectl
./scripts/deploy-on-kind.sh -d -l cf
wait 7 minutes
`cf api``
API endpoint: https://localhost
API version: 3.117.0+cf-k8s
cf login -o demo-org -s sandbox
API endpoint: https://localhost
1. cf-admin
2. kind-cf
Choose your Kubernetes authentication info (enter to skip): 1
Authenticating...
OK
Targeted org demo-org.
Targeted space sandbox.
API endpoint: https://localhost
API version: 3.117.0+cf-k8s
user: cf-admin
org: demo-org
space: sandbox
not the -o
is not currently supported so we will use the inbuilt paketo-buildpacks
cf push --no-start --random-route -m 128M -k 1G --no-manifest govuk-prototype-kit-paketo
cf set-env govuk-prototype-kit-paketo USERNAME user
Setting env variable USERNAME for app govuk-prototype-kit-paketo in org demo-org / space sandbox as cf-admin...
OK
TIP: Use 'cf restage govuk-prototype-kit-paketo' to ensure your env variable changes take effect.
GDS11172:govuk-prototype-kit pauldougan$ cf set-env govuk-prototype-kit-paketo PASSWORD password
Setting env variable PASSWORD for app govuk-prototype-kit-paketo in org demo-org / space sandbox as cf-admin...
OK
TIP: Use 'cf restage govuk-prototype-kit-paketo' to ensure your env variable changes take effect.
cf start govuk-prototype-kit-paketo
cf apps
curl
kubectl get cfapps -A
This demonstrates that tenants could start using Cloud Native Buildpacks now and help future proof their applicaions. Targetting CNB would prepare for:
- a migration to a CF on k8s enviroment based on Korifi and ensure that the apps are compatible
- a migration to another container hosting platform that supports OCI compatible images which may or may not be k8s based