This guide should help you install Pivotal Function Service (PFS), in a PKS installation running on GCP.
Make sure you enable the following configuration in one of your PKS plans:
- Master VM type:
large
- Worker Node Instances:
4
- Worker VM type:
large
- Check
Enable Privileged Containers - Use with caution
- Check
Disable DenyEscalatingExec
Create a K8s cluster using this plan.
Download resources from Pivotal Network.
Install PFS CLI:
$ tar zxf pfs-cli-darwin-amd64*.tgz
$ sudo mv pfs /usr/local/bin
Unzip the PFS distribution:
$ tar zxf pfs-distro-XXX.tgz
Go to the newly created directory (pfs-distro-XXX
) before running the next commands.
Set a variable pointing to this directory:
$ export PFS_HOME=<absolute path to PFS dir>
Relocate PFS images:
$ export REGISTRY=gcr.io
$ export REGISTRY_USER=$(gcloud config get-value core/project)
$ pfs image relocate --output $PFS_HOME/pfs-relocated \
--manifest manifest.yaml \
--images image-manifest.yaml --registry $REGISTRY \
--registry-user $REGISTRY_USER
Enable GCR access:
$ gcloud auth configure-docker
Push PFS images to GCR:
$ pfs image push --images $PFS_HOME/pfs-relocated/image-manifest.yaml
Enable GCR access from the K8s worker nodes (use GCP worker service account set in PKS tile configuration):
$ export WORKER_SERVICE_ACCOUNT=gcp-pks-node@<PROJECT_ID>.iam.gserviceaccount.com
$ export GCP_PROJECT=$(gcloud config get-value core/project)
$ gsutil iam ch \
serviceAccount:$WORKER_SERVICE_ACCOUNT:objectViewer \
gs://artifacts.$GCP_PROJECT.appspot.com
Install PFS components in your K8s cluster:
$ pfs system install -m $PFS_HOME/pfs-relocated/manifest.yaml
Check everything is up and running:
$ kubectl get pods --all-namespaces \
-o "custom-columns=NAME:metadata.name,STATUS:status.phase"
NAME STATUS
istio-citadel-8547b56ffc-k7lxr Running
istio-egressgateway-6684db87d9-ngwzc Running
istio-galley-5d49cc486c-b7rsv Running
istio-ingressgateway-6d5cfbf64d-nmzcf Running
istio-pilot-67464d9d4-z76g4 Running
istio-policy-ccc74d9f8-2jwfx Running
istio-sidecar-injector-9d76979b8-p8hm6 Running
istio-telemetry-c956cf59c-m6nbd Running
knative-ingressgateway-68f8d9f5c4-zsc7m Running
build-controller-787f4f7c8f-9rfk7 Running
build-webhook-c5fb5b976-dsrj7 Running
eventing-controller-5db7689644-d49dq Running
stub-clusterbus-dispatcher-5976467c9c-2nfr7 Running
webhook-f457f7d85-tmdbc Running
activator-57bb59f58b-cnz2h Running
activator-57bb59f58b-tm2sh Running
activator-57bb59f58b-vksf2 Running
autoscaler-749455599c-bfzjb Running
controller-95dfdb499-sz6zp Running
webhook-6f5ff6fb47-27bkv Running
heapster-6d5f964dbd-ccxxg Running
kube-dns-6b697fcdbd-xlsqf Running
kubernetes-dashboard-785584f46b-9qrqq Running
metrics-server-5f68584c5b-qk555 Running
monitoring-influxdb-54759946d4-7sxqd Running
telemetry-agent-75dff4fd49-rbcmn Running
fluent-bit-5ld5b Running
fluent-bit-lk977 Running
fluent-bit-rwh7x Running
fluent-bit-vspgp Running
sink-controller-7c85744bd6-tq4ph Running
Set up GCR credentials:
$ gcloud iam service-accounts create push-image
$ gcloud projects add-iam-policy-binding $GCP_PROJECT \
--member serviceAccount:push-image@$GCP_PROJECT.iam.gserviceaccount.com \
--role roles/storage.admin
$ export GCR_SERVICE_ACCOUNT=$PFS_HOME/gcr-storage-admin.json
$ gcloud iam service-accounts keys create \
--iam-account "push-image@$GCP_PROJECT.iam.gserviceaccount.com" \
$GCR_SERVICE_ACCOUNT
Keep the service account file handy: you'll need it each time you want to install PFS in a K8s namespace.
Using GCR credentials, initialize your K8s namespace with PFS resources:
$ export NAMESPACE=mynamespace
$ kubectl create namespace $NAMESPACE
$ pfs namespace init $NAMESPACE -m $PFS_HOME/pfs-relocated/manifest.yaml \
--gcr $GCR_SERVICE_ACCOUNT
Let's use the basic hello sample available on GitHub:
$ pfs function create hello \
--git-repo https://github.com/projectriff-samples/hello.js \
--artifact hello.js \
--image $REGISTRY/$REGISTRY_USER/hello \
--namespace $NAMESPACE
--verbose
This function is implemented using a simple Javascript file:
module.exports = x => `hello ${x}`
You should now be able to invoke this function:
$ pfs service invoke \
--namespace $NAMESPACE \
hello --text -- -w '\n' -d 'PFS'
curl 104.155.125.168/ -H 'Host: hello.hello.example.com' -H 'Content-Type: text/plain' -w '\n' -d PFS
hello PFS
List running functions:
$ kubectl get services.serving.knative.dev --namespace $NAMESPACE
NAME DOMAIN LATESTCREATED LATESTREADY READY REASON
hello hello.hello.example.com hello-00001 hello-00001 True
Remove the function:
$ pfs service delete hello -n $NAMESPACE
Let's use a Java based hello sample:
$ pfs function create hello \
--git-repo https://github.com/alexandreroman/pfs-hellofun.git \
--handler fr.alexandreroman.demos.hellofun.Hello \
--image $REGISTRY/$REGISTRY_USER/hello \
--verbose --namespace $NAMESPACE
This function is implemented using the JDK Function interface:
public class Hello implements Function<String, String> {
public String apply(String name) {
final String n;
if (name == null || name.isEmpty()) {
n = "world";
} else {
n = name;
}
return "Hello " + n;
}
}
No external dependencies are required. When this function is deployed to PFS, the code is automatically compiled and packaged using the Java Buildpack (part of the Cloud Native Buildpack project).
At runtime, a Java service invoker provided by PFS calls this function:
$ pfs service invoke --namespace $NAMESPACE \
hello --text -- -w '\n' -d 'PFS'
curl 104.155.125.168/ -H 'Host: hello.hello.example.com' -H 'Content-Type: text/plain' -w '\n' -d PFS
Hello PFS
Get function status:
$ pfs service status --namespace $NAMESPACE hello
Last Transition Time: 2018-12-10T23:07:50+01:00
Status: True
Type: Ready