LATEST VERSION: v0.1.0 - RELEASE NOTES
Pivotal Function Service v0.1.0

Installing PFS on Minikube

Page last updated:

This topic describes how to install Pivotal Function Service (PFS) on your development machine using minikube.

Requirements

These requirements assume a macOS or Linux environment.

  • minikube has been installed at version v0.30.0 or later.
  • A Minikube VM driver for your OS has been installed:
  • The kubectl CLI has been installed at version 1.10 or later.
  • docker is installed and a docker daemon is running on your development machine.
  • The pfs CLI has been downloaded and installed.
  • The PFS distribution has been downloaded. Container images from the distribution will be pushed to the local registry running in docker.

Install a local Registry

Since PFS installations require a container registry, these instructions include running a local registry accessible from Kubernetes as well as from the host development machine at registry.pfs.svc.cluster.local:5000.

  1. Use the docker CLI to run the registry:2 container from Docker, listening on port 5000, and persisting images in the ~/.registry/storage directory.

    docker run -d -p 5000:5000 --restart=always --volume ~/.registry/storage:/var/lib/registry registry:2
    
  2. Edit the /etc/hosts file on your development machine, adding the name registry.pfs.svc.cluster.local on the same line as the entry for localhost. On macOS the file should look something like this.

    ##
    127.0.0.1       localhost registry.pfs.svc.cluster.local
    255.255.255.255 broadcasthost
    ::1             localhost
    
  3. Validate that the registry is running.

    docker ps
    
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
    02ea46d51f58        registry:2          "/entrypoint.sh /etc…"   About an hour ago   Up About a minute   0.0.0.0:5000->5000/tcp   sharp_pike
    
  4. Validate that the registry at registry.pfs.svc.cluster.local:5000 is reachable from your development machine.

    curl registry.pfs.svc.cluster.local:5000/v2/_catalog
    
    {"repositories":[]}
    
  5. Follow the instructions to Push relocated images to the local registry, making sure that the images are relocated to registry.pfs.svc.cluster.local:5000.

Install Kubernetes

  1. Start the minikube cluster

    minikube start --memory=8192 --cpus=4 \
      --kubernetes-version=v1.13.2 \
      --bootstrapper=kubeadm \
      --vm-driver=hyperkit \
      --extra-config=apiserver.enable-admission-plugins="LimitRanger,NamespaceExists,NamespaceLifecycle,ResourceQuota,ServiceAccount,DefaultStorageClass,MutatingAdmissionWebhook" \
      --insecure-registry registry.pfs.svc.cluster.local:5000
    

    Note: for Linux use kvm2 instead of hyperkit for the --vm-driver

  2. Use kubectl to verify that the context is set to minikube.

    kubectl config current-context
    
    minikube
    

    If necessary set the current context.

    kubectl config use-context minikube
    
  3. In a separate terminal window, watch the pods in the cluster.

    watch -n 1 kubectl get pod --all-namespaces
    
    NAMESPACE     NAME                               READY   STATUS    RESTARTS   AGE
    kube-system   coredns-86c58d9df4-s94m4           1/1     Running   0          68s
    kube-system   coredns-86c58d9df4-z6jk6           1/1     Running   0          68s
    kube-system   etcd-minikube                      1/1     Running   0          24s
    kube-system   kube-addon-manager-minikube        1/1     Running   0          75s
    kube-system   kube-apiserver-minikube            1/1     Running   0          18s
    kube-system   kube-controller-manager-minikube   1/1     Running   0          19s
    kube-system   kube-proxy-pzvmc                   1/1     Running   0          68s
    kube-system   kube-scheduler-minikube            1/1     Running   0          13s
    kube-system   storage-provisioner                1/1     Running   0          68s
    
  4. Configure a fixed IP address for your host development machine. This avoids the problem of the IP address changing whenever you connect your machine to a different network. If your machine already uses the 172.16.x.x range for other purposes, choose an address in a different range e.g. 172.31.x.x..

    export DEV_IP=172.16.1.1
    

    Create an alias for the localhost network on MacOS:

    sudo ifconfig lo0 alias $DEV_IP
    

    Or on Linux:

    sudo ifconfig lo:0 $DEV_IP
    

    Note that the alias will need to be reestablished when you restart your machine. This can be avoided by using say a launchdeamon on MacOS or by editing /etc/network/interfaces on Linux.

  5. Add an entry to /etc/hosts inside the minikube VM, pointing the registry to the IP address of the host. This will result in registry.pfs.svc.cluster.local resolving to the host machine allowing the docker daemon in minikube to pull images from the local registry.

    minikube ssh \
    "echo \"$DEV_IP       registry.pfs.svc.cluster.local\" \
    | sudo tee -a  /etc/hosts"
    
  6. Create a kubernetes service without selectors called registry in the pfs namespace and an endpoint with the same name pointing to the IP address of your development machine. This will result in registry.pfs.svc.cluster.local resolving to the host machine, allowing container builds running in the cluster, to work with the local registry.

    kubectl create namespace pfs
    
    cat <<EOF | kubectl create -f -
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: registry
      namespace: pfs
    spec:
      ports:
      - protocol: TCP
        port: 5000
        targetPort: 5000
    ---
    kind: Endpoints
    apiVersion: v1
    metadata:
      name: registry
      namespace: pfs
    subsets:
      - addresses:
          - ip: $DEV_IP
        ports:
          - port: 5000
    EOF
    

Install PFS

Install PFS using the pfs CLI as shown below where the -m flag is the path to the previously relocated manifest.yaml file. The --node-port option is required for access to Kubernetes services via NodePort rather than LoadBalancer.

pfs system install -m pfs-relocated/manifest.yaml --node-port

Watch for all the pods to start running.

NAMESPACE          NAME                                          READY   STATUS    RESTARTS   AGE
istio-system       istio-citadel-65787c5f88-czvnk                1/1     Running   0          83s
istio-system       istio-egressgateway-89599fc6d-fnhsw           1/1     Running   0          83s
istio-system       istio-galley-598948bbdb-r9jjk                 1/1     Running   0          83s
istio-system       istio-ingressgateway-6599655c69-pfhrf         1/1     Running   0          83s
istio-system       istio-pilot-9b7d6c6fc-llgzb                   2/2     Running   0          83s
istio-system       istio-policy-6bd98c94cf-td666                 2/2     Running   0          83s
istio-system       istio-sidecar-injector-656777cf49-j99d4       1/1     Running   0          83s
istio-system       istio-telemetry-5dbf9b9f76-h45ww              2/2     Running   0          83s
istio-system       knative-ingressgateway-74c49fc6c5-l8lbm       1/1     Running   0          31s
knative-build      build-controller-694c865db8-c2f98             1/1     Running   0          32s
knative-build      build-webhook-dd44545c7-wxql9                 1/1     Running   0          32s
knative-eventing   eventing-controller-65c497557-557qc           1/1     Running   0          29s
knative-eventing   stub-clusterbus-dispatcher-685b8cd58d-kwrxc   2/2     Running   0          15s
knative-eventing   webhook-f8cf95cd4-nmt5x                       1/1     Running   0          29s
knative-serving    activator-5b64b5d9dc-vsbt5                    2/2     Running   0          31s
knative-serving    activator-5b64b5d9dc-zjtgz                    2/2     Running   0          31s
knative-serving    activator-5b64b5d9dc-zk2pc                    2/2     Running   0          31s
knative-serving    autoscaler-56965cd44-dffdf                    2/2     Running   0          30s
knative-serving    controller-679c69c478-zq9gl                   1/1     Running   0          30s
knative-serving    webhook-594976db4b-5ck7s                      1/1     Running   0          30s
kube-system        coredns-86c58d9df4-s94m4                      1/1     Running   0          4m19s
kube-system        coredns-86c58d9df4-z6jk6                      1/1     Running   0          4m19s
kube-system        etcd-minikube                                 1/1     Running   0          3m35s
kube-system        kube-addon-manager-minikube                   1/1     Running   0          4m26s
kube-system        kube-apiserver-minikube                       1/1     Running   0          3m29s
kube-system        kube-controller-manager-minikube              1/1     Running   0          3m30s
kube-system        kube-proxy-pzvmc                              1/1     Running   0          4m19s
kube-system        kube-scheduler-minikube                       1/1     Running   0          3m24s
kube-system        storage-provisioner                           1/1     Running   0          4m19s

PFS is now installed. Next you need to prepare one or more namespaces for your functions.

Prepare a Namespace

Use the pfs CLI to initialize PFS resources in a Kubernetes namespace. Pass the path to the previously relocated manifest file using the -m flag. The command below initializes the default namespace.

pfs namespace init default -m pfs-relocated/manifest.yaml --no-secret

Optional: Enable Outbound Network Access

Knative blocks all outbound traffic by default. For PFS functions to call services outside the cluster, it is necessary to enable outbound network access. Details on how to do that are given in the Knative guide for configuring outbound network access.

See Troubleshooting PFS for details on how to verify the outbound traffic configuration.

You can now create your first function.

Build from local-path

You can use PFS to build functions from source in a local directory, instead of first committing the code to a repo on GitHub. Currently this requires that you use a non-private registry for the relocated images. This is the case when runnig a local registry using Docker.

This capability will be extended to work with private registries in a future release.

Building from a local directory requires the PFS_BUILDER_IMAGE and PFS_PACKS_RUN_IMAGE environment variables to be set.

Setting these environment variables will affect both local and cluster builds. We suggest opening a new terminal window before changing to a different Kubernetes context.

Run the following using the path to the previously relocated manifest file:

export PFS_BUILDER_IMAGE=`grep -o "$REGISTRY/$REGISTRY_USER/projectriff-builder.*" \
  pfs-relocated/image-manifest.yaml | awk -F": " '{print $1}'`

export PFS_PACKS_RUN_IMAGE=`grep -o "$REGISTRY/$REGISTRY_USER/packs-run.*" \
  pfs-relocated/image-manifest.yaml | awk -F": " '{print $1}'`

If you like, you can capture the values of the environment variables PFS_BUILDER_IMAGE and PFS_PACKS_RUN_IMAGE in a file as follows:

echo "export PFS_BUILDER_IMAGE=$PFS_BUILDER_IMAGE" > pfs-local-path-env
echo "export PFS_PACKS_RUN_IMAGE=$PFS_PACKS_RUN_IMAGE" >> pfs-local-path-env

You can set the environment variables whenever you need them by sourcing the file:

source pfs-local-path-env

To build a function from a local directory, use --local-path instead of --git-repo.

The output from the build will log a message saying “Pulling builder image” and “(use ‑‑no‑pull flag to skip this step)”. This is logged by the pack library that the pfs CLI is using and is not exposed to be set directly by the user doing the build with the pfs CLI. The advantage of always pulling the builder image is that you get the latest version that could include important fixes.

For example, assuming you are in a directory with a file called square.js:

// square.js
module.exports = x => x ** 2;

then you can run this to create the function:

pfs function create square \
  --local-path . \
  --artifact square.js \
  --image registry.pfs.svc.cluster.local:5000/testuser/square \
  --verbose

and run this to update the function and deploy a new revision:

pfs function update square \
  --local-path .