如何使用Kubernetes运行一个简单的PHP Hello World应用程序

时间:2020-05-10 18:16:00

标签: php kubernetes

我正在尝试部署和运行一个简单的PHP应用程序,该应用程序将仅通过我的Kubernetes集群(仅是一个主节点集群)显示一条Hello World消息,不幸的是,我无法做到这一点。

我正在描述我的项目结构- 我有一个名为kubernetes-test的根项目目录,在该目录下,我有3个yaml文件,在该目录下有一个名为code的目录,我有一个名为index.php < / p>

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';

在我通过互联网找到的所有内容中。

当我运行此命令kubectl get pods时 那么对于这样的Nginx部署,状态永远显示ContainerCreating

NAME                    READY   STATUS              RESTARTS   AGE
nginx-64c9df788f-jxwzx   0/1     ContainerCreating    0          12h
php-55f974bb4-qvv9x      1/1     Running              0          25s

命令: kubectl describe pod nginx-64c9df788f-jxwzx

输出:

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

命令:kubectl get events -n default

输出:

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

有人可以帮助我吗? 预先感谢!

2 个答案:

答案 0 :(得分:2)

您能否运行describe pod命令并提供输出:

kubectl describe pod nginx-64c9df788f-jxwzx

kubectl get events -n default

可能是某些卷装入问题,某些配置问题或资源创建。它将很快变为CrashLoopBack状态。

我不确定如何创建和安装卷,如果遵循以下blog,则必须创建PV和PVC,而且我也看不到任何 PHP strong>服务在9000上运行?

这就是它处于ContainerCreating状态的原因。未配置卷。这是具有相同PHP应用程序和相关步骤的更好的blog

您可以从本机k8s文档中遵循更好的example

答案 1 :(得分:1)

我运行了您的环境,这是我发现的主要问题:

  • 首先,您尚未部署nginx-config,但这只是您的第一个问题,很容易解决(下面的示例中有更多内容)。
  • 第二个问题(我认为是主要问题)是HostPath的用法:
    • 正如我所解释的,here HostPath要求容器进程以root用户身份运行。
    • php-fpm以www-data身份运行,因此,如果通过/code挂载了该文件夹,则他无法使用hostPath上的挂载文件。

从这里开始,我们的选择是:

  • 烘烤图像中的php文件(或作为configmap),并在同一pod中(共享一个emptydir文件夹)运行nginx和php,有关本过程的更多信息,请参见本指南:PHP-FPM, Nginx, Kubernetes, and Docker-一本本一方面,它涉及创建一个新的Docker映像,另一方面,如果您还没有一个存储配置器,则可以省去配置它。
  • 使用外部存储器将文件挂载到Persistent Volume中,以从外部存储库下载php文件。这种方法要求nginx和php在同一节点上运行-因为存储是RWO,这意味着只能以读写方式安装在一个节点上。由于您的设置位于单个节点上,因此在本示例中将使用此方法。

我尝试重现您的示例,但是我必须进行一些更改。 这些是文件:

  • 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指向要查找index.php的目录
  • fastcgi_pass php:9000指向在php上侦听的名为port 9000服务的服务。

  • 存储空间:

这是可变的,具体取决于您使用的存储类型。 Minikube带有开箱即用配置的存储提供程序和storageclass。而且,尽管minikube存储提供程序称为minikube-hostpath,但是它是一种CSI,它不需要在容器级别上的root访问权限即可运行。

  • 话虽如此,这里是pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: code
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard

请注意,standard是minikube中内置的动态存储提供程序的名称。我们在这里要做的是创建一个名为code的PVC,以使我们的应用运行。

  • 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
  • 在这里,我们使用busybox initContainer来获取此php文件(与您使用的php文件相同)并将其保存在已安装的卷/code中。

  • PHP服务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部署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

这里的关键点是在code mountPath上的名为/code的PVC上的安装,以及我们创建的configmap被作为文件夹中的site.conf文件/etc/nginx/conf.d

  • Nginx服务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

我正在使用NodePort简化输出测试。


复制:

  • 让我们创建文件:首先创建configmappvc,因为Pod正确启动需要它们,然后是服务和部署:
$ 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

在这里,我们可以看到curl从nginx服务器返回,200 OK由PHP 7驱动,并包含index.php文件的内容。

我希望它可以帮助您更清楚地了解这种情况。

如果您有任何问题,请在评论中告诉我。