This is the multi-page printable view of this section. Click here to print.
Build and deploy applications
1 - Deploy an application
When pushing an app (via kf push
) to Kf, there are
three lifecycles that Kf uses to take your source code
and allow it to handle traffic:
- Source code upload
- Build
- Run
Source code upload
The first thing that happens when you kf push
is the Kf CLI (kf
) packages
up your directory (either current or --path/-p
) into a container and
publishes it to the container registry configured for the Space. This is
called the source container. The Kf CLI then creates an App
type in Kubernetes
that contains both the source image and configuration from the App manifest and
push flags.
Ignore files during push
In many cases, you will not want to upload certain files during kf push
(i.e., “ignore” them).
This is where a .kfignore
(or .cfignore
) file can be used.
Similar to a .gitignore
file, this file instructs the Kf CLI which
files to not include in the source code container.
To create a .kfignore
file, create a text file named .kfignore
in the base
directory of your app (similar to where you would store the manifest
file). Then populate it with a newline delimited list of files and directories
you don’t want published. For example:
bin
.idea
This will tell the Kf CLI to not include anything in the bin
or .idea
directories.
Kf supports gitignore style syntax.
Build
The Build lifecycle is handled by a Tekton TaskRun. Depending on the flags that you provide while pushing, it will choose a specific Tekton Task. Kf currently has the following Tekton Tasks:
- buildpackv2
- buildpackv3
- kaniko
Kf tracks each TaskRun as a Build. If a Build succeeds, the resulting container image is then deployed via the Run lifecycle (described below).
More information can be found at Build runtime.
Run
The Run lifecycle is responsible for taking a container image and creating a Kubernetes Deployment.
It also creates:
More information can be found at Build runtime.
Push timeouts
Kf supports setting an environment variable to instruct the CLI to time out
while pushing apps. If set, the variables KF_STARTUP_TIMEOUT
or
CF_STARTUP_TIMEOUT
are parsed as a golang style duration (for example 15m
,
1h
). If a value is not set, the push timeout defaults to 15 minutes.
2 - Get started with buildpacks
Kf supports a variety of buildpacks. This document covers some starter examples for using them.
Before you begin
- You should have Kf running on a cluster.
- You should have run
kf target -s <space-name>
to target your space.
Java (v2) buildpack
Use spring initializr to create a Java 8 maven project with a spring web dependency and JAR packaging. Download it, extract it, and once extracted you can generate a JAR.
./mvnw package
Push the JAR to Kf with the Java v2 buildpack.
kf push java-v2 --path target/helloworld-0.0.1-SNAPSHOT.jar
Java (v3) buildpack
Use spring initializr to create a Java 8 maven project with a spring web dependency and JAR packaging. Download it, extract it, and once extracted, push to Kf with the cloud native buildpack.
kf push java-v3 --stack org.cloudfoundry.stacks.cflinuxfs3
Python (v2) buildpack
Create a new directory with files as shown in the following structure.
tree
.
├── Procfile
├── requirements.txt
└── server.py
cat Procfile
web: python server.py
cat requirements.txt
Flask
cat server.py
from flask import Flask
import os
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == "__main__":
port = int(os.getenv("PORT", 8080))
app.run(host='0.0.0.0', port=port)
Push the Python flask app using v2 buildpacks.
kf push python --buildpack python\_buildpack
Python (v3) buildpack
(same as above)
Push the Python flask app using cloud native buildpacks.
kf push pythonv3 --stack org.cloudfoundry.stacks.cflinuxfs3
Staticfile (v2) buildpack
Create a new directory that holds your source code.
Add an index.html
file with this content.
<!DOCTYPE html>
<html lang="en">
<head><title>Hello, world!</title></head>
<body><h1>Hello, world!</h1></body>
</html>
Push the static content with the staticfile buildpack.
kf push staticsite --buildpack staticfile\_buildpack
3 - Reduce deployment risk with blue-green deployments
This page shows you how to deploy a new version of your application and migrate traffic over from an old to a new version.
Push the initial App
Use the Kf CLI to push the initial version of your App with any routes:
$ kf push app-v1 --route my-app.my-space.example.com
Push the updated App
Use the Kf CLI to push a new version of your App without any routes:
$ kf push app-v2 --no-route
Add routes to the updated App
Use the Kf CLI to bind all existing routes to the updated App with a weight of 0 to ensure that they don’t get any requests:
$ kf map-route app-v2 my-space.example.com --hostname my-app --weight 0
Shift traffic
Start shifting traffic from the old App to the updated App by updating the weights on the routes:
$ kf map-route app-v1 my-space.example.com --hostname my-app --weight 80
$ kf map-route app-v2 my-space.example.com --hostname my-app --weight 20
If the deployment is going well, you can shift more traffic by updating the weights again:
$ kf map-route app-v1 my-space.example.com --hostname my-app --weight 50
$ kf map-route app-v2 my-space.example.com --hostname my-app --weight 50
Complete traffic shifting
After you’re satisfied that the new service hasn’t introduced regressions, complete the rollout by shifting all traffic to the new instance:
$ kf map-route app-v1 my-space.example.com --hostname my-app --weight 0
$ kf map-route app-v2 my-space.example.com --hostname my-app --weight 100
Turn down the original App
After you’re satisfied that quick rollbacks aren’t needed, remove the original route and stop the App:
$ kf unmap-route app-v1 myspace.example.com --hostname my-app
$ kf stop app-v1
Or delete the App and all associated route mappings:
$ kf delete app-v1
4 - Compare V2 and V3 Buildpacks
A buildpack converts source code into an executable, and is used to deliver a simple, reliable, and repeatable way to create containers. Kf supports both V2 and V3 buildpacks, and it is important to understand the differences between them.
V2 buildpacks
Most Cloud Foundry applications already use V2 buildpacks. When using V2 buildpacks with Kf, the lifecycle binaries and the buildpacks are downloaded and configured from their git URLs. Kf then uses the lifecycle
CLI to execute each buildpack against the source code.
Pros
- Ready out of the box without pipeline or code changes.
Cons
- Legacy buildpack supersceded by V3.
- Weaker performance and reliability. The Kf build pipeline requires more IO for V2 buildpacks.
- Fewer community resources.
- Kf only supports OSS git repos.
V3 buildpacks
V3 buildpacks are a Cloud Native Computing Foundation (CNCF) project with a well defined spec, a CLI (pack) and a growing community that is innovating around different languages and frameworks. Google Cloud also has its own set of OSS buildpacks.
V3 buildpacks have two overarching OCI containers:
- Builder image
- Run image
Builder image
The builder image is used while your source code is being built into a runnable container. The image has the necessary detect
scripts and other utilities to compile source code.
Run image
The run image is the base image that a container is built on. This means that it is the base image that will run when the App executes.
Layers
V3 buildpacks use layers to compose the final container. Each buildpack included in a build is given the opportunity to manipulate the file system and environment variables of the App. This layering approach allows for buildpacks to be thinner and more generic.
V3 buildpacks are built on OCI containers. This requires that the V3 builder image be stored in a container registry that the Kf build pipeline has access to. The build pipeline uses the builder image to apply the underlying scripts to build the source code into a runnable container.
Pros
- Google supported builder and run image.
- Works with various CI/CD runtimes like Cloud Build.
- Growing community and buildpack registry.
Cons
- May require code/process updates. For example, the Java buildpack requires source code while the V2 buildpack requires a jar file.
- V3 buildpacks are newer and might require additional validation (is using community developed buildpacks).
Kf Stacks
View Stacks
When pushing an App, the build pipeline determines the buildpack based on the selected Stack (specified via the --stack
flag or the manifest).
To see which Stacks are available in a Space first ensure a Space is targeted:
kf target -s myspace
The kf stacks
subcommand can then be used to list the Stacks:
kf stacks
The output shows both V2 and V3 Stacks:
Getting stacks in Space: myspace
Version Name Build Image Run Image
V2 cflinuxfs3 cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5 cloudfoundry/cflinuxfs3@sha256:5219e9e30000e43e5da17906581127b38fa6417f297f522e332a801e737928f5
V3 kf-v2-to-v3-shim gcr.io/kf-releases/v2-to-v3:v2.7.0 gcr.io/buildpacks/gcp/run:v1 This is a stack added by the integration tests to assert that v2->v3 shim works
V3 google gcr.io/buildpacks/builder:v1 gcr.io/buildpacks/gcp/run:v1 Google buildpacks (https://github.com/GoogleCloudPlatform/buildpacks)
V3 org.cloudfoundry.stacks.cflinuxfs3 cloudfoundry/cnb:cflinuxfs3@sha256:f96b6e3528185368dd6af1d9657527437cefdaa5fa135338462f68f9c9db3022 cloudfoundry/run:full-cnb@sha256:dbe17be507b1cc6ffae1e9edf02806fe0e28ffbbb89a6c7ef41f37b69156c3c2 A large Cloud Foundry stack based on Ubuntu 18.04
V2 to V3 Buildpack Migration
Kf provides a V3 stack to build applications that were built with standard V2 buildpacks, using a stack named kf-v2-to-v3-shim
. The kf-v2-to-v3-shim
stack is created following the standard V3 buildpacks API. A Google maintained builder image is created with each Kf release, following the standard buildpack process. The builder image aggregates a list of V3 buildpacks created by the same process used with the kf wrap-v2-buildpack
command. The V3 buildpack images are created using the standard V2 buildpack images. It’s important to note that the V3 buildpacks do not contain the binary of the referenced V2 buildpacks. Instead, the V2 buildpack images are referenced, and the bits are downloaded at App build time (by running kf push
).
At App build time, the V2 buildpack is downloaded from the corresponding git repository. When V3 detection runs, it delegates to the downloaded V2 detection script. For the first buildpack group that passes detection, it proceeds to the build step, which delegates the build execution to the downloaded V2 builder script.
The following V2 buildpacks are supported in the kf-v2-to-v3-shim
stack:
Buildpack | Git Repository |
---|---|
java_buildpack | https://github.com/cloudfoundry/java-buildpack |
dotnet_core_buildpack | https://github.com/cloudfoundry/dotnet-core-buildpack |
nodejs_buildpack | https://github.com/cloudfoundry/nodejs-buildpack |
go_buildpack | https://github.com/cloudfoundry/go-buildpack |
python_buildpack | https://github.com/cloudfoundry/python-buildpack |
binary_buildpack | https://github.com/cloudfoundry/binary-buildpack |
nginx_buildpack | https://github.com/cloudfoundry/nginx-buildpack |
Option 1: Migrate Apps built with standard V2 buildpacks
To build Apps with the kf-v2-to-v3-shim
stack, use the following command:
kf push myapp --stack kf-v2-to-v3-shim
The kf-v2-to-v3-shim
stack will automatically detect the runtime with the wrapped V2 buildpacks. The resulting App image is created using the V3 standard and build pipeline, but the builder of the equivalent V2 buildpack.
Option 2: Migrate Apps built with custom V2 buildpacks
Kf has a buildpack migration tool that can take a V2 buildpack and wrap it with a V3 buildpack. The wrapped buildpack can then be used anywhere V3 buildpacks are available.
kf wrap-v2-buildpack gcr.io/your-project/v2-go-buildpack https://github.com/cloudfoundry/go-buildpack --publish
This will create a buildpack image named gcr.io/your-project/v2-go-buildpack
. It can then be used to create a builder by following the create a builder docs.
This subcommand uses the following CLIs transparently:
go
git
pack
unzip
5 - App Manifest
App manifests provide a way for developers to record their App’s execution environment in a declarative way. They allow Apps to be deployed consistently and reproducibly.
Format
Manifests are YAML files in the root directory of the App. They must be named manifest.yml
or manifest.yaml
.
Kf App manifests are allowed to have a single top-level element: applications
.
The applications
element can contain one or more application entries.
Application fields
The following fields are valid for objects under applications
:
Field | Type | Description |
---|---|---|
name | string | The name of the application. The app name should be lower-case alphanumeric characters and dashes. It must not start with a dash. |
path | string | The path to the source of the app. Defaults to the manifest’s directory. |
buildpacks | string[] | A list of buildpacks to apply to the app. |
stack | string | Base image to use for to use for apps created with a buildpack. |
docker | object | A docker object. See the Docker Fields section for more information. |
env | map | Key/value pairs to use as the environment variables for the app and build. |
services | string[] | A list of service instance names to automatically bind to the app. |
disk_quota | quantity | The amount of disk the application should get. Defaults to 1GiB. |
memory | quantity | The amount of RAM to provide the app. Defaults to 1GiB. |
cpu † | quantity | The amount of CPU to provide the application. Defaults to 1/10th of a CPU. |
cpu-limit † | quantity | The maximum amount of CPU to provide the application. Defaults to unlimited. |
instances | int | The number of instances of the app to run. Defaults to 1. |
routes | object | A list of routes the app should listen on. See the Route Fields section for more. |
no-route | boolean | If set to true, the application will not be routable. |
random-route | boolean | If set to true, the app will be given a random route. |
timeout | int | The number of seconds to wait for the app to become healthy. |
health-check-type | string | The type of health-check to use port , process , none , or http . Default: port |
health-check-http-endpoint | string | The endpoint to target as part of the health-check. Only valid if health-check-type is http . |
health-check-invocation-timeout | int | Timeout in seconds for an individual health check probe to complete. Default: 1 . |
command | string | The command that starts the app. If supplied, this will be passed to the container entrypoint. |
entrypoint † | string | Overrides the app container’s entrypoint. |
args † | string[] | Overrides the arguments the app container. |
ports † | object | A list of ports to expose on the container. If supplied, the first entry in this list is used as the default port. |
startupProbe † | probe | Sets the app container’s startup probe. |
livenessProbe † | probe | Sets the app container’s liveness probe. |
readinessProbe † | probe | Sets the app container’s readiness probe. |
metadata | object | Additional tags for applications and their underlying resources. |
† Unique to Kf
Docker fields
The following fields are valid for application.docker
objects:
Field | Type | Description |
---|---|---|
image | string | The docker image to use. |
Route fields
The following fields are valid for application.routes
objects:
Field | Type | Description |
---|---|---|
route | string | A route to the app including hostname, domain, and path. |
appPort | int | (Optional) A custom port on the App the route will send traffic to. |
Port fields
The following fields are valid for application.ports
objects:
Field | Type | Description |
---|---|---|
port | int | The port to expose on the App’s container. |
protocol | string | The protocol of the port to expose. Must be tcp , http or http2 . Default: tcp |
Metadata fields
The following fields are valid for application.metadata
objects:
Field | Type | Description |
---|---|---|
labels | string -> string map | Labels to add to the app and underlying application Pods. |
annotations | string -> string map | Annotations to add to the app and underlying application Pods. |
Probe fields
Probes allow a subset of functionality from Kubernetes probes.
A probe must contain one action and other settings.
Field | Type | Description |
---|---|---|
failureThreshold | int | Minimum consecutive failures for the probe to be considered failed. |
initialDelaySeconds | int | Number of seconds to wait after container initialization to start the probe. |
periodSeconds | int | How often (in seconds) to perform the probe. |
successThreshold | int | Minimum consecutive successes for the probe to be considered successful. |
timeoutSeconds | int | Number of seconds after a single invocation of the probe times out. |
tcpSocket | TCPSocketAction object | Action specifying a request to a TCP port. |
httpGet | HTTPGetAction object | Action specifying a request to a TCP port. |
TCPSocketAction fields
Describes an action based on TCP requests.
Field | Type | Description |
---|---|---|
host | string | Host to connect to, defaults to the App’s IP. |
HTTPGetAction fields
Describes an action based on HTTP get requests.
Field | Type | Description |
---|---|---|
host | string | Host to connect to, defaults to the App’s IP. |
path | string | Path to access on the HTTP server. |
scheme | string | Scheme to use when connecting to the host. Default: http |
httpHeaders | array of {"name": <string>, "value": <string>} objects | Additional headers to send. |
Examples
Minimal App
This is a bare-bones manifest that will build an App by auto-detecting the buildpack based on the uploaded source, and deploy one instance of it.
---
applications:
- name: my-minimal-application
Simple App
This is a full manifest for a more traditional Java App.
---
applications:
- name: account-manager
# only upload src/ on push
path: src
# use the Java buildpack
buildpacks:
- java
env:
# manually configure the buildpack's Java version
BP_JAVA_VERSION: 8
ENVIRONMENT: PRODUCTION
# use less disk and memory than default
disk_quota: 512M
memory: 512M
# Give the app a minimum of 2/10ths of a CPU
cpu: 200m
instances: 3
# make the app listen on three routes
routes:
- route: accounts.mycompany.com
- route: accounts.datacenter.mycompany.internal
- route: mycompany.com/accounts
# set up a longer timeout and custom endpoint to validate
# when the app comes up
timeout: 300
health-check-type: http
health-check-http-endpoint: /healthz
# attach two services by name
services:
- customer-database
- web-cache
Docker App
Kf can deploy Docker containers as well as manifest deployed App.
These Docker Apps MUST listen on the PORT
environment variable.
---
applications:
- name: white-label-app
# use a pre-built docker image (must listen on $PORT)
docker:
image: gcr.io/my-company/white-label-app:123
env:
# add additional environment variables
ENVIRONMENT: PRODUCTION
disk_quota: 1G
memory: 1G
# Give the app a minimum of 2 full CPUs
cpu: 2000m
instances: 1
routes:
- route: white-label-app.mycompany.com
App with multiple ports
This App has multiple ports to expose an admin console, website, and SMTP server.
---
applications:
- name: b2b-server
ports:
- port: 8080
protocol: http
- port: 9090
protocol: http
- port: 2525
protocol: tcp
routes:
- route: b2b-admin.mycompany.com
appPort: 9090
- route: b2b.mycompany.com
# gets the default (first) port
Health check types
Kf supports three different health check types:
port
(default)http
process
(ornone
)
port
and http
set a Kubernetes readiness and liveness
probe
that ensures the application is ready before sending traffic to it.
The port
health check will ensure the port found at $PORT
is being
listened to. Under the hood Kf uses a TCP probe.
The http
health check will use the configured value in
health-check-http-endpoint
to check the application’s health. Under the hood
Kf uses an HTTP probe.
A process
health check only checks to see if the process running on the
container is alive. It does NOT set a Kubernetes readiness or liveness probe.
Known differences
The following are known differences between Kf manifests and CF manifests:
- Kf does not support deprecated CF manifest fields. This includes all fields at the root-level of the manifest (other than applications) and routing fields.
- Kf is missing support for the following v2 manifest fields:
docker.username
- Kf does not support auto-detecting ports for Docker containers.
6 - App runtime
The app runtime is the environment apps are executed in.
Buildpack Apps | Container Image Apps | |
---|---|---|
System libraries | Provided by the Stack | Provided in the container |
Network access | Full access through Envoy sidecar | Full access through Envoy sidecar |
File system | Ephemeral storage | Ephemeral storage |
Language runtime | Supplied by the Stack or Buildpack | Built into the container |
User | Specified by the Stack | Specified on the container |
Isolation mechanism | Kubernetes Pod | Kubernetes Pod |
DNS | Provided by Kubernetes | Provided by Kubernetes |
Environment variables
Environment variables are injected into the app at runtime by Kubernetes. Variables are added based on the following order, where later values override earlier ones with the same name:
- Space (set by administrators)
- App (set by developers)
- System (set by Kf)
Kf provides the following system environment variables:
Variable | Purpose |
---|---|
CF_INSTANCE_ADDR | The cluster-visible IP:PORT of the App instance. |
CF_INSTANCE_GUID | The UUID of the App instance. |
INSTANCE_GUID | Alias of CF_INSTANCE_GUID . |
CF_INSTANCE_INDEX | The index number of the App instance, this will ALWAYS be 0. |
INSTANCE_INDEX | Alias of CF_INSTANCE_INDEX . |
CF_INSTANCE_IP | The cluster-visible IP of the App instance. |
CF_INSTANCE_INTERNAL_IP | Alias of CF_INSTANCE_IP |
VCAP_APP_HOST | Alias of CF_INSTANCE_IP |
CF_INSTANCE_PORT | The cluster-visible port of the App instance. In Kf this is the same as PORT . |
DATABASE_URL | The first URI found in a VCAP_SERVICES credential. |
LANG | Required by Buildpacks to ensure consistent script load order. |
MEMORY_LIMIT | The maximum amount of memory in MB the App can consume. |
PORT | The port the App should listen on for requests. |
VCAP_APP_PORT | Alias of PORT . |
VCAP_APPLICATION | A JSON structure containing App metadata. |
VCAP_SERVICES | A JSON structure specifying bound services. |
Service credentials from bound services get injected into Apps via the
VCAP_SERVICES
environment variable. The variable is a valid JSON object with
the following structure.
VCAPServices
A JSON object where the keys are Service labels and the values are an array of
VCAPService
. The array represents every bound
service with that label.
User provided services
are placed under the label user-provided
.
Example
{
"mysql": [...],
"postgresql": [...],
"user-provided": [...]
}
VCAPService
This type represents a single bound service instance.
Example
{
"binding_name": string,
"instance_name": string,
"name": string,
"label": string,
"tags": string[],
"plan": string,
"credentials": object
}
Fields
Field | Type | Description |
---|---|---|
binding_name | string | The name assigned to the service binding by the user. |
instance_name | string | The name assigned to the service instance by the user. |
name | string | The binding_name if it exists; otherwise the instance_name . |
label | string | The name of the service offering. |
tags | string[] | An array of strings an app can use to identify a service instance. |
plan | string[] | The service plan selected when the service instance was created. |
credentials | object | The service-specific credentials needed to access the service instance. |
VCAP_APPLICATION
TheVCAP_APPLICATION
environment variable is a JSON object containing metadata about the App.
Example
{
"application_id": "12345",
"application_name": "my-app",
"application_uris": ["my-app.example.com"],
"limits": {
"disk": 1024,
"mem": 256
},
"name": "my-app",
"process_id": "12345",
"process_type": "web",
"space_name": "my-ns",
"uris": ["my-app.example.com"]
}
Fields
Field | Type | Description |
---|---|---|
application_id | string | The GUID identifying the App. |
application_name | string | The name assigned to the App when it was pushed. |
application_uris | string[] | The URIs assigned to the App. |
limits | object | The limits to disk space, and memory permitted to the App. Memory and disk space limits are supplied when the App is deployed, either on the command line or in the App manifest. Disk and memory limits are represented as integers, with an assumed unit of MB. |
name | string | Identical to application_name . |
process_id | string | The UID identifying the process. Only present in running App containers. |
process_type | string | The type of process. Only present in running App containers. |
space_name | string | The human-readable name of the Space where the App is deployed. |
uris | string[] | Identical to application_uris . |
Missing Fields
Some fields in VCAP_APPLICATION
that are in Cloud Foundry are currently not supported in Kf.
Besides CF-specific and deprecated fields (cf_api
, host
, users
) the fields that are not supported in Kf are:
application_version
(identical toversion
)organization_id
organization_name
space_id
start
(identical tostarted_at
)started_at_timestamp
(identical tostate_timestamp
)
7 - Build runtime
The Build runtime is the environment Apps are built in.
Buildpack Builds | Docker Builds | |
---|---|---|
System libraries | Provided by the Stack | User supplied |
Network access | Full access through Envoy sidecar | Full access through Envoy sidecar |
File system | No storage | No storage |
Language runtime | Provided by the Stack | User supplied |
User | Specified by the Stack | User supplied |
Isolation mechanism | Kubernetes Pod | Kubernetes Pod |
DNS | Provided by Kubernetes | Provided by Kubernetes |
Environment variables
Environment variables are injected into the Build at runtime. Variables are added based on the following order, where later values override earlier ones with the same name:
- Space (set by administrators)
- App (set by developers)
- System (set by Kf)
Kf provides the following system environment variables to Builds:
Variable | Purpose |
---|---|
CF_INSTANCE_ADDR | The cluster-visible IP:PORT of the Build. |
INSTANCE_GUID | Alias of CF_INSTANCE_GUID . |
CF_INSTANCE_IP | The cluster-visible IP of the Build. |
CF_INSTANCE_INTERNAL_IP | Alias of CF_INSTANCE_IP |
VCAP_APP_HOST | Alias of CF_INSTANCE_IP |
CF_INSTANCE_PORT | The cluster-visible port of the Build. |
LANG | Required by Buildpacks to ensure consistent script load order. |
MEMORY_LIMIT | The maximum amount of memory in MB the Build can consume. |
VCAP_APPLICATION | A JSON structure containing App metadata. |
VCAP_SERVICES | A JSON structure specifying bound services. |