Running our website on kubernetes using our PHP container
How we run our website here at ngineered
At ngineered we believe in running our own systems in the same way as we run our customers. So we run our own website on a kubernetes cluster using our own hugely popular PHP container nginx-php-fpm.
If you are unfamiliar with Kubernetes you can find more information about it on the project's website, but to sum it up, kubernetes is a system that allows us to schedule and manage containers across a series of compute nodes.
So why did we build our own container? We were looking for a way of streamlining the deployment process and so we built a container that allows us to specify some environment variables that the container uses to allow it to pull, and potentially push, to a git repository. You can read about this in previous blog entry here. We've recently finished a further update that allows the use of personal access tokens, rather than a ssh key to authenticate to github. You can read about that here, but to summarise this makes setting up access to your repository much easier.
We can't go into detail in this article about how to build a kubernetes cluster, but we wanted to show how we use our PHP container to run our website. There are a list of resources you might find useful at the end of the article.
Kubernetes is configured using a series of files or commands. You can write the configuration files in either JSON or YAML, we use YAML as that is what the kubernetes' best practice guide recommends. We run our site under a Replication Controller configuration at the moment, but we will move this to the newer Deployment type soon.
Here is our website replication controller yaml file with bits redacted as you would expect:
apiVersion: v1 kind: ReplicationController metadata: namespace: ngineered name: ngd-www-app labels: ngd-www-component: app spec: replicas: 1 selector: ngd-www-component: app template: metadata: labels: ngd-www-component: app spec: containers: - name: ngd-www-app image: richarvey/nginx-php-fpm:latest imagePullPolicy: Always env: - name: GIT_PERSONAL_TOKEN value: 'eW91ZGlkbnR0aGlua2l3b3VsZGRpZHlvdQo=' - name: GIT_USERNAME value: 'our_username' - name: GIT_REPO value: 'our_repo' - name: GIT_EMAIL value: 'our_email' - name: GIT_NAME value: 'container update' - name: WEBROOT value: 'our_webroot' - name: PHP_MEM_LIMIT value: '256' - name: PHP_POST_MAX_SIZE value: '256' - name: PHP_UPLOAD_MAX_FILESIZE value: '256' ports: - containerPort: 80
Kubectl the kubernetes configuration tool
Again we can't go into detail about how to setup kubectl to talk to your cluster, but assuming you have a working kubectl and this file is called ngd-website.yaml you can start it by running:
kubectl --namespace ngineered create -f ./ngd-website.yaml
This will create a replication controller and a pod in the ngineered namespace. A pod is the basic object within kubernetes and defines an entity that runs a container image. A pod can have more that one container running within it, but this one just has our PHP image specified by this line:
You can specify a tag after the colon and we have specified that the latest image should be pulled and run. The most important part for our container is the section after env:, this part of the file defines name/value pairs that map into environment variables on the container and are used to specify the variables needed to pull our code from our git repository. You can see that these variables map onto those given in the article mentioned before.
Once we have run the kubectl create command above we can check on the status of the pod by running the following:
kubectl --namespace ngineered get pods
You would obviously use a different namespace value.
Which gives similar output to this:
NAME READY STATUS RESTARTS AGE ngd-www-app-gskxo 1/1 Running 0 20d
The Status column is important, you hope to see Running, but you can see ContainerCreating when the image is being pulled, if you see the dreaded Error or CrashLoopBackoff then you need to investigate further. We will write another article on troubleshooting kubernetes at a later date.
Pulling the code
Once your pod is running you can now use the pull script supplied with our PHP container to pull the code, you do this using kubectl once more:
kubectl --namespace ngineered exec ngd-www-app-gskxo /usr/bin/pull
Again you would use your own namespace and the pod name we use here is from the Name column in the get pods command above.
If you find you have problems you can shell into the pod and investigate using a command similar to this:
kubectl --namespace ngineered exec ngd-www-app-gskxo -i -t -- bash -il
This should give you a bash prompt within the container.
Please feel free to contact us using the details below if you want to discuss what services ngineered can provide to your company.
Tim Hockin is one of the main developers working on Kubernetes, here is a video from him: