Kubernetes is a container orchestration framework that is open source. You can build, upgrade, and scale containers without having to worry about downtime.
Nginx serves as a proxy for PHP-FPM while running a PHP script. Containerizing this configuration in a single container can be a pain, but Kubernetes can make it easier to handle both services in their own containers. Using Kubernetes will allow you to keep your application up to date.
As part of our DigitalOcean management services, we’ve seen some such Kubernetes-related queries here at Skynats. Today, we’ll look at how to use Kubernetes to deploy a PHP framework on Ubuntu 18.04.
Create PHP-FPM and Nginx Services
The PHP-FPM and Nginx services will be created in this phase. Access to PHP-FPM pods will be granted by the PHP-FPM program, while access to Nginx pods will be granted by the Nginx service. Since the PHP-FPM pods will be proxied by Nginx pods, you’ll need to tell the service where to look for them.
You’ll start by making a directory to store your Kubernetes object definitions. Create the definitions directory on your master node by SSH to the master node to store your Kubernetes object definitions.
mkdir definitions
Move to the newly created definitions
directory
cd definitions
Create a php service.yaml file for your PHP-FPM service.
vim php_service.yaml
To indicate that this object is a service, set the kind to Service. Since it will have links to PHP-FPM, call the service PHP. You’ll use labels to logically group related objects. Labels will be used to divide objects into “tiers”, such as frontend and backend. Since the PHP pods will be running behind this service, you can name it tier: backend.
Selector labels are used by a service to deciding which pods to access. To allocate the pod to the backend tier, use the tier: backend label. To specify that this pod runs PHP, you’ll also add the app: PHP name. After the metadata portion, add these two labels. Finally, specify the port used to access this service.
The following is an example of a completed php service.yaml file:
apiVersion: v1
kind: Service
metadata:
name: php
labels:
tier: backend
spec:
selector:
app: php
tier: backend
ports:
- protocol: TCP
port: 9000
Save the file and create the service for php-fpm using the below command.
kubectl apply -f php_service.yaml
Verify that your service is running:
kubectl get svc
You will see your PHP-FPM service running:
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m
php ClusterIP 10.100.59.238 <none> 9000/TCP 5m
Now, we can create the Nginx service. Create and open a new file called nginx_service.yaml.
vim nginx_service.yaml
Since this service can be used to manage Nginx pods, you should call it nginx. You’ll also have a tier: backend mark to indicate that it belongs in the back-end tier:
Target the pods with the selector labels app: nginx and tier: backend, much like the PHP service. Make this service available on port 80, which is the standard HTTP port.
Using your Droplet’s public IP address, the Nginx service will be publicly open to the internet. Add your IP under spec.externalIPs.
The following is an example of a completed Nginx service.yaml file:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
tier: backend
spec:
selector:
app: nginx
tier: backend
ports:
- protocol: TCP
port: 80
externalIPs:
- your_public_ip
Save and close the file. Create the Nginx service:
kubectl apply -f nginx_service.yaml
You can view all running services by executing:
kubectl get svc
You will see both the PHP-FPM and Nginx services listed in the output:
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13m
nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 50s
php ClusterIP 10.100.59.238 <none> 9000/TCP 8m
Install the DigitalOcean storage plugin for deploying the PHP Application
To store your DigitalOcean API token, you’ll first create a Kubernetes Secret object. Secret objects are used to share confidential information with other Kubernetes objects in the same namespace, such as SSH keys and passwords. Namespaces allow you to divide your Kubernetes objects logically.
Open a file named secret.yaml
vim secret.yaml
Your Secret object will be called digital ocean, and it will be added to the kube-system namespace. Add the access-token as stringData. This is what your secret.yaml file would look like:
apiVersion: v1
kind: Secret
metadata:
name: digitalocean
namespace: kube-system
stringData:
access-token: your-api-token
Create the secret service:
kubectl apply -f secret.yaml
Now, install the DigitalOcean block storage plug-in as your Secret is set up.
kubectl apply -f https://raw.githubusercontent.com/digitalocean/csi-digitalocean/master/deploy/kubernetes/releases/csi-digitalocean-v1.1.0.yaml
You can now build block storage to store your application code and configuration files after installing the DigitalOcean storage plug-in.
Configuring the Persistent Volume on Ubuntu System.
A Persistent Volume is accessed via a PersistentVolumeClaim, or PVC, which mounts the PV along the appropriate path.
Open file code_volume.yaml
vim code_volume.yaml
Add the below code to the file
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: code
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: do-block-storage
Save the file and Create the code
PVC using kubectl
kubectl apply -f code_volume.yaml
To view available Persistent Volumes:
kubectl get pv
Create PHP-FPM Application deployment
To create your Deployment, open a new file called php_deployment.yaml
vim php_deployment.yaml
The Deployment will manage your PHP-FPM pods, so name the Deployment object php
. Add the below code to the file opened.
apiVersion: apps/v1
kind: Deployment
metadata:
name: php
labels:
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: php
tier: backend
template:
metadata:
labels:
app: php
tier: backend
spec:
volumes:
- name: code
persistentVolumeClaim:
claimName: code
containers:
- name: php
image: php:7-fpm
volumeMounts:
- name: code
mountPath: /code
initContainers:
- name: install
image: busybox
volumeMounts:
- name: code
mountPath: /code
command:
- wget
- "-O"
- "/code/index.php"
- https://raw.githubusercontent.com/do-community/php-kubernetes/master/index.php
Save the file and create the PHP-FPM Deployment
kubectl apply -f php_deployment.yaml
You can view your Deployment by running:
kubectl get deployments
You can view the pods in this Deployment
kubectl get pods
Nginx Deployment on Ubuntu server to run PHP Application
To configure Nginx in this step, you’ll use a ConfigMap. Your configuration is stored in a key-value format in a ConfigMap, which you can reference in other Kubernetes object definitions.
Create a nginx_configMap.yaml file for your ConfigMap
vim nginx_configMap.yaml
Add the data
for the ConfigMap. The final nginx_configMap.yaml will be as below:
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
labels:
tier: backend
data:
config : |
server {
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /code;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Save the file and create ConfigMap
kubectl apply -f nginx_configMap.yaml
After creating ConfigMap, we can build the Nginx Deployment.
Open nginx_deployment.yaml file:
vim nginx_deployment.yaml
Paste the entire code in the file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: nginx
tier: backend
template:
metadata:
labels:
app: nginx
tier: backend
spec:
volumes:
- name: code
persistentVolumeClaim:
claimName: code
- name: config
configMap:
name: nginx-config
items:
- key: config
path: site.conf
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
volumeMounts:
- name: code
mountPath: /code
- name: config
mountPath: /etc/nginx/conf.d
Save the file and create Nginx Deployment
kubectl apply -f nginx_deployment.yaml
You can see Nginx and PHP-FPM Deployments using:
kubectl get deployments
Run the command to list the pods managed by the Deployments
kubectl get pods
Finally, you can see the list of services running by:
kubectl get services -o wide
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39m <none>
nginx ClusterIP 10.102.160.47 your_public_ip 80/TCP 27m app=nginx,tier=backend
php ClusterIP 10.100.59.238 <none> 9000/TCP 34m app=php,tier=backend
You will get your public IP from the above output. Visit your server by typing http://your_public_ip into your browser. You’ll see the PHP info() performance and know that your Kubernetes services are up and running.
If you need any assistance, our technical teams are available anytime.