Reputation: 5020
I'm trying to deploy and run a simple PHP application that will only show a Hello World
message through my Kubernetes cluster which is only a master node cluster, unfortunately, I can't do that.
I'm describing my project structure -
I have a root project directory called kubernetes-test
and under that directory, I have 3 yaml
files and one directory called code
under that directory I have a PHP file called index.php
hello-world-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
tier: backend
spec:
selector:
app: nginx
tier: backend
type: NodePort
ports:
- nodePort: 30500
port: 80
targetPort: 80
nginx-deployment.yaml
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
hostPath:
path: /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: /var/www/html
- name: config
mountPath: /etc/nginx/conf.d
php-deployment.yaml
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
hostPath:
path: /code
containers:
- name: php
image: php:7-fpm
volumeMounts:
- name: code
mountPath: /var/www/html
code/index.php
<?php
echo 'Hello World';
Above all those things I've found through the internet.
When I ran this command kubectl get pods
then the status is showing ContainerCreating
forever for the Nginx deployment like this
NAME READY STATUS RESTARTS AGE
nginx-64c9df788f-jxwzx 0/1 ContainerCreating 0 12h
php-55f974bb4-qvv9x 1/1 Running 0 25s
Command: kubectl describe pod nginx-64c9df788f-jxwzx
Output:
Name: nginx-64c9df788f-jxwzx
Namespace: default
Priority: 0
Node: bablu-node/192.168.43.123
Start Time: Mon, 11 May 2020 03:20:58 +0600
Labels: app=nginx
pod-template-hash=64c9df788f
tier=backend
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Controlled By: ReplicaSet/nginx-64c9df788f
Containers:
nginx:
Container ID:
Image: nginx
Image ID:
Port: 80/TCP
Host Port: 0/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/etc/nginx/conf.d from config (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-l2zp2 (ro)
/var/www/html from code (rw)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
code:
Type: HostPath (bare host directory volume)
Path: /code
HostPathType:
config:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: nginx-config
Optional: false
default-token-l2zp2:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-l2zp2
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedMount 31m (x14 over 147m) kubelet, bablu-node Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[default-token-l2zp2 code config]: timed out waiting for the condition
Warning FailedMount 16m (x82 over 167m) kubelet, bablu-node MountVolume.SetUp failed for volume "config" : configmap "nginx-config" not found
Warning FailedMount 6m53s (x44 over 165m) kubelet, bablu-node Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[code config default-token-l2zp2]: timed out waiting for the condition
Warning FailedMount 2m23s (x10 over 163m) kubelet, bablu-node Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[config default-token-l2zp2 code]: timed out waiting for the condition
Command: kubectl get events -n default
Output:
LAST SEEN TYPE REASON OBJECT MESSAGE
18m Warning FailedMount pod/nginx-64c9df788f-jxwzx MountVolume.SetUp failed for volume "config" : configmap "nginx-config" not found
8m45s Warning FailedMount pod/nginx-64c9df788f-jxwzx Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[code config default-token-l2zp2]: timed out waiting for the condition
4m15s Warning FailedMount pod/nginx-64c9df788f-jxwzx Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[config default-token-l2zp2 code]: timed out waiting for the condition
33m Warning FailedMount pod/nginx-64c9df788f-jxwzx Unable to attach or mount volumes: unmounted volumes=[config], unattached volumes=[default-token-l2zp2 code config]: timed out waiting for the condition
18m Normal Scheduled pod/php-55f974bb4-qvv9x Successfully assigned default/php-55f974bb4-qvv9x to bablu-node
18m Normal Pulled pod/php-55f974bb4-qvv9x Container image "php:7-fpm" already present on machine
18m Normal Created pod/php-55f974bb4-qvv9x Created container php
18m Normal Started pod/php-55f974bb4-qvv9x Started container php
18m Normal SuccessfulCreate replicaset/php-55f974bb4 Created pod: php-55f974bb4-qvv9x
18m Normal ScalingReplicaSet deployment/php Scaled up replica set php-55f974bb4 to 1
Can anyone please help me? Thanks in advance!!
Upvotes: 1
Views: 3540
Reputation: 4138
I ran your environment and here are the main issues I found:
HostPath
:
HostPath
requires that the container process run as root.www-data
therefore he cannot use the mount files at /code
if this folder is mounted through hostPath
.From here our options now are:
I tried to reproduce as close as your example, but I had to do some changes. Here are the files:
cm-nginx.yaml
: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;
}
}
root /code
is pointing the directory where to look for index.php
fastcgi_pass php:9000
pointing to the service called php
service listening on port 9000
.This is mutable depending on the storage type you are using. Minikube comes with storage provider and storageclass configured out of the box. And although minikube storage provider is called minikube-hostpath
it's a CSI that will not require root access on container level to run.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: code
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
Note that standard
is the name of the dynamic storage provider built in minikube. What we are doing here is to create a PVC called code
for our app to run.
php.yaml
: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/videofalls/demo/master/index.php
here we are using a busybox
initContainer to wget this php file (which is identical to the one you are using) and save it inside the mounted volume /code
.
PHP service svc-php.yaml
:
apiVersion: v1
kind: Service
metadata:
name: php
labels:
tier: backend
spec:
selector:
app: php
tier: backend
ports:
- protocol: TCP
port: 9000
nginx.yaml
: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
The key points here, is the mount of the PVC called code
on mountPath
/code
and the configmap we created being monted as a file called site.conf
inside the folder /etc/nginx/conf.d
svc-nginx.yaml
:apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
tier: backend
spec:
type: NodePort
selector:
app: nginx
tier: backend
ports:
- protocol: TCP
port: 80
I'm using NodePort to ease the output test.
Reproduction:
configmap
and pvc
, since they are required for the pods to start correctly, then the services and deployments:$ ls
cm-nginx.yaml nginx.yaml php.yaml pvc.yaml svc-nginx.yaml svc-php.yaml
$ kubectl apply -f cm-nginx.yaml
configmap/nginx-config created
$ kubectl apply -f pvc.yaml
persistentvolumeclaim/code created
$ kubectl get cm
NAME DATA AGE
nginx-config 1 52s
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
code Bound pvc-b63559a0-a306-46f2-942b-0a063bc4ab6b 1Gi RWO standard 17s
$ kubectl apply -f svc-php.yaml
service/php created
$ kubectl apply -f svc-nginx.yaml
service/nginx created
$ kubectl apply -f php.yaml
deployment.apps/php created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
php-69d5c956ff-8tjfn 1/1 Running 0 5s
$ kubectl apply -f nginx.yaml
deployment.apps/nginx created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-6854dcb7db-75zxt 1/1 Running 0 4s
php-69d5c956ff-8tjfn 1/1 Running 0 22s
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.107.16.212 <none> 80:31017/TCP 41s
php ClusterIP 10.97.237.214 <none> 9000/TCP 44s
$ minikube service nginx --url
http://172.17.0.2:31017
$ curl -i http://172.17.0.2:31017
HTTP/1.1 200 OK
Server: nginx/1.7.9
Date: Thu, 28 May 2020 19:04:48 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/7.4.6
Demo Test
Here we can see the curl
returned 200 OK
from nginx server, powered by PHP 7 and the content of the index.php
file.
I hope it helps you have a clearer understanding of this scenario.
If you have any question, let me know in the comments.
Upvotes: 3
Reputation: 1721
Can you please run a describe pod command and provide the output:
kubectl describe pod nginx-64c9df788f-jxwzx
Also kubectl get events -n default
It may be some volume mount issue, or some config problem, or resource creation. It would go to a CrashLoopBack status soon.
I am not sure how are you creating volumes and mounting them, if you have followed the following blog, you will have to create PV and PVCs, also I am failing to see any PHP service running on 9000?
That's the reason it is in ContainerCreating state. The volumes are not configured. Here is a better blog with the same PHP application and relevant steps.
You can follow a better example from native k8s docs.
Upvotes: 2