在kubernetes中通过卷附加代码是否正确?

时间:2017-03-30 06:27:40

标签: docker kubernetes

为了在Docker中轻松开发,代码通过卷附加到容器。这样,每次更改代码时都无需重建图像。

那么,考虑在Kubernetes中使用相同的想法是否正确?

PS:我知道概念PersistentVolumePersistentVolumeClaim允许附加卷,但它们适用于数据。

更新

为了简化开发,我需要将卷用于代码和数据。这将避免我在每次更改代码时重建图像。

下面是我在minikube中尝试做的事情:

部署

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: php-hostpath
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: php-hostpath
    spec:
      containers:
      - name: php-hostpath
        image: php:7.0-apache
        ports:
        - containerPort: 80
        volumeMounts:
          - name: vol-php-hostpath
            mountPath: /var/www/html
      volumes:
      - name: vol-php-hostpath
        hostPath:
          path: '/home/amine/DockerProjects/gcloud-kubernetes/application/06-hostPath-volume-example-minikube/src/'

服务

apiVersion: v1
kind: Service
metadata:
  name: php-hostpath
  namespace: default
  labels:
    app: php-hostpath
spec:
  selector:
    app: php-hostpath
  ports:
  - port: 80
    targetPort: 80
  type: "LoadBalancer"

在minikube中创建了服务和部署:

$ kubectl get pods -l app=php-hostpath
NAME                            READY     STATUS    RESTARTS   AGE
php-hostpath-3796606162-bt94w   1/1       Running   0          19m

$ kubectl get service -l app=php-hostpath
NAME           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
php-hostpath   10.0.0.110   <pending>     80:30135/TCP   27m

文件夹src和文件src/index.php也已创建好。

<?php
echo "This is my first docker project";

现在我想检查一切是否正在运行:

$ kubectl exec -ti php-hostpath-3796606162-bt94w bash
root@php-hostpath-3796606162-bt94w:/var/www/html# ls
root@php-hostpath-3796606162-bt94w:/var/www/html# exit
exit

文件夹src和文件index.php不在/var/www/html

我错过了什么吗?

PS:如果我在制作环境中,我不会将我的代码放入卷中。 谢谢,

3 个答案:

答案 0 :(得分:2)

基于此doc,尚未在KVM驱动程序中实现主机文件夹共享。这是我实际使用的驱动程序。

为了克服这个问题,有两种解决方案:

  • 使用 virtualbox 驱动程序,以便通过将localhost /home/THE_USR/...上的路径更改为/hosthome/THE_USR/...

  • 根据命令$ minikube mount /home/THE_USR/...将卷装入minikube VM。该命令将返回minikube VM上已安装卷的路径。示例给出了。

实施例

(a)在minikube VM上安装卷

minikube mount命令返回路径/ mount-9p

$ minikube mount -v 3 /home/amine/DockerProjects/gcloud-kubernetes/application/06-hostPath-volume-example-minikube
Mounting /home/amine/DockerProjects/gcloud-kubernetes/application/06-hostPath-volume-example-minikube into /mount-9p on the minikubeVM
This daemon process needs to stay alive for the mount to still be accessible...
2017/03/31 06:42:27 connected
2017/03/31 06:42:27 >>> 192.168.42.241:34012 Tversion tag 65535 msize 8192 version '9P2000.L'
2017/03/31 06:42:27 <<< 192.168.42.241:34012 Rversion tag 65535 msize 8192 version '9P2000'

(b)部署路径的规范

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: php-hostpath
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: php-hostpath
    spec:
      containers:
      - name: php-hostpath
        image: php:7.0-apache
        ports:
        - containerPort: 80
        volumeMounts:
          - name: vol-php-hostpath
            mountPath: /var/www/html
      volumes:
      - name: vol-php-hostpath
        hostPath:
          path: /mount-9p

(c)检查安装音量是否正常工作

amine@amine-Inspiron-N5110:~/DockerProjects/gcloud-kubernetes/application/06-hostPath-volume-example-minikube$ kubectl exec -ti php-hostpath-3498998593-6mxsn bash
root@php-hostpath-3498998593-6mxsn:/var/www/html# cat index.php 
<?php
echo "This is my first docker project";
root@php-hostpath-3498998593-6mxsn:/var/www/html# cat index.php                                                                                                                                 
<?php

echo 'This is my first hostPath on kubernetes';
root@php-hostpath-3498998593-6mxsn:/var/www/html# cat index.php 
<?php

echo 'This is my first hostPath on kubernetes';
root@php-hostpath-3498998593-6mxsn:/var/www/html# 

PS:这种卷安装只是开发环境。如果我在生产环境中,则不会安装代码:它将在图像中。

PS:我建议使用虚拟机而不是KVM。

希望它可以帮助他人。

答案 1 :(得分:1)

hostPath允许您将节点上的目录挂载到容器中。

在多节点群集中,您需要使用nodeSelector将您的开发人群限制为特定节点(使用内置标签kubernetes.io/hostname: mydevhost)。

使用minikube查看已装入的主机文件夹部分。

答案 2 :(得分:1)

老实说,你可以做到,但你不应该这样做。使用容器的一个特性是,您可以使用始终具有相同行为的工件(容器)。新版本的代码应该生成一个新容器。通过这种方式,您可以确保在测试时检测到的任何新问题都与新代码直接相关。

混合方法(我不喜欢,但我认为更好)是创建一个可以下载代码的docker(使用envs选择正确的版本)并运行它。

使用hostPaths并不是一个坏主意,但如果你有一个不那么小的集群,可能会很乱。 当然,在您的所有代码都是数据之后,您可以使用PV。您可以使用像NFS这样的分布式存储文件系统来完成它。