#kubernetes
#kubernetes
Вопрос:
Я пытаюсь использовать плагин cinder для kubernetes для создания как статически определенных PV, так и классов хранения, но я не вижу никакой активности между моим кластером и cinder для создания / монтирования устройств.
Версия Kubernetes:
kubectl version
Client Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.1", GitCommit:"33cf7b9acbb2cb7c9c72a10d6636321fb180b159", GitTreeState:"clean", BuildDate:"2016-10-10T18:19:49Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.1", GitCommit:"33cf7b9acbb2cb7c9c72a10d6636321fb180b159", GitTreeState:"clean", BuildDate:"2016-10-10T18:13:36Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
Команда, с помощью которой был запущен kubelet, и ее статус:
systemctl status kubelet -l
● kubelet.service - Kubelet service
Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2016-10-20 07:43:07 PDT; 3h 53min ago
Process: 2406 ExecStartPre=/usr/local/bin/install-kube-binaries (code=exited, status=0/SUCCESS)
Process: 2400 ExecStartPre=/usr/local/bin/create-certs (code=exited, status=0/SUCCESS)
Main PID: 2408 (kubelet)
CGroup: /system.slice/kubelet.service
├─2408 /usr/local/bin/kubelet --pod-manifest-path=/etc/kubernetes/manifests --api-servers=https://172.17.0.101:6443 --logtostderr=true --v=12 --allow-privileged=true --hostname-override=jk-kube2-master --pod-infra-container-image=pause-amd64:3.0 --cluster-dns=172.31.53.53 --cluster-domain=occloud --cloud-provider=openstack --cloud-config=/etc/cloud.conf
Вот мой файл cloud.conf:
# cat /etc/cloud.conf
[Global]
username=<user>
password=XXXXXXXX
auth-url=http://<openStack URL>:5000/v2.0
tenant-name=Shadow
region=RegionOne
Похоже, что k8s способен успешно взаимодействовать с openstack. Из /var/log /messages:
kubelet: I1020 11:43:51.770948 2408 openstack_instances.go:41] openstack.Instances() called
kubelet: I1020 11:43:51.836642 2408 openstack_instances.go:78] Found 39 compute flavors
kubelet: I1020 11:43:51.836679 2408 openstack_instances.go:79] Claiming to support Instances
kubelet: I1020 11:43:51.836688 2408 openstack_instances.go:124] NodeAddresses(jk-kube2-master) called
kubelet: I1020 11:43:52.274332 2408 openstack_instances.go:131] NodeAddresses(jk-kube2-master) => [{InternalIP 172.17.0.101} {ExternalIP 10.75.152.101}]
Мои файлы PV / PVC yaml и вывод списка cinder:
# cat persistentVolume.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: jk-test
labels:
type: test
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
cinder:
volumeID: 48d2d1e6-e063-437a-855f-8b62b640a950
fsType: ext4
# cat persistentVolumeClaim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
selector:
matchLabels:
type: "test"
# cinder list | grep jk-cinder
| 48d2d1e6-e063-437a-855f-8b62b640a950 | available | jk-cinder | 10 | - | false |
Как видно выше, cinder сообщает, что доступно устройство с идентификатором, указанным в файле pv.yaml. Когда я их создаю, кажется, что все работает:
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM REASON AGE
pv/jk-test 10Gi RWO Retain Bound default/myclaim 5h
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
pvc/myclaim Bound jk-test 10Gi RWO 5h
Затем я пытаюсь создать модуль с использованием pvc, но ему не удается смонтировать том:
# cat testPod.yaml
kind: Pod
apiVersion: v1
metadata:
name: jk-test3
labels:
name: jk-test
spec:
containers:
- name: front-end
image: example-front-end:latest
ports:
- hostPort: 6000
containerPort: 3000
volumes:
- name: jk-test
persistentVolumeClaim:
claimName: myclaim
And here is the state of the pod:
3h 46s 109 {kubelet jk-kube2-master} Warning FailedMount Unable to mount volumes for pod "jk-test3_default(0f83368f-96d4-11e6-8243-fa163ebfcd23)": timeout expired waiting for volumes to attach/mount for pod "jk-test3"/"default". list of unattached/unmounted volumes=[jk-test]
3h 46s 109 {kubelet jk-kube2-master} Warning FailedSync Error syncing pod, skipping: timeout expired waiting for volumes to attach/mount for pod "jk-test3"/"default". list of unattached/unmounted volumes=[jk-test]
I’ve verified that my openstack provider is exposing cinder v1 and v2 APIs and the previous logs from openstack_instances show the nova API is accessible. Despite that, I never see any attempts on k8s part to communicate with cinder or nova to mount the volume.
Here are what I think are the relevant log messages regarding the failure to mount:
kubelet: I1020 06:51:11.840341 24027 desired_state_of_world_populator.go:323] Extracted volumeSpec (0x23a45e0) from bound PV (pvName "jk-test") and PVC (ClaimName "default"/"myclaim" pvcUID 51919dfb-96c9-11e6-8243-fa163ebfcd23)
kubelet: I1020 06:51:11.840424 24027 desired_state_of_world_populator.go:241] Added volume "jk-test" (volSpec="jk-test") for pod "f957f140-96cb-11e6-8243-fa163ebfcd23" to desired state.
kubelet: I1020 06:51:11.840474 24027 desired_state_of_world_populator.go:241] Added volume "default-token-js40f" (volSpec="default-token-js40f") for pod "f957f140-96cb-11e6-8243-fa163ebfcd23" to desired state.
kubelet: I1020 06:51:11.896176 24027 reconciler.go:201] Attempting to start VerifyControllerAttachedVolume for volume "kubernetes.io/cinder/48d2d1e6-e063-437a-855f-8b62b640a950" (spec.Name: "jk-test") pod "f957f140-96cb-11e6-8243-fa163ebfcd23" (UID: "f957f140-96cb-11e6-8243-fa163ebfcd23")
kubelet: I1020 06:51:11.896330 24027 reconciler.go:225] VerifyControllerAttachedVolume operation started for volume "kubernetes.io/cinder/48d2d1e6-e063-437a-855f-8b62b640a950" (spec.Name: "jk-test") pod "f957f140-96cb-11e6-8243-fa163ebfcd23" (UID: "f957f140-96cb-11e6-8243-fa163ebfcd23")
kubelet: I1020 06:51:11.896361 24027 reconciler.go:201] Attempting to start VerifyControllerAttachedVolume for volume "kubernetes.io/secret/f957f140-96cb-11e6-8243-fa163ebfcd23-default-token-js40f" (spec.Name: "default-token-js40f") pod "f957f140-96cb-11e6-8243-fa163ebfcd23" (UID: "f957f140-96cb-11e6-8243-fa163ebfcd23")
kubelet: I1020 06:51:11.896390 24027 reconciler.go:225] VerifyControllerAttachedVolume operation started for volume "kubernetes.io/secret/f957f140-96cb-11e6-8243-fa163ebfcd23-default-token-js40f" (spec.Name: "default-token-js40f") pod "f957f140-96cb-11e6-8243-fa163ebfcd23" (UID: "f957f140-96cb-11e6-8243-fa163ebfcd23")
kubelet: I1020 06:51:11.896420 24027 config.go:98] Looking for [api file], have seen map[file:{} api:{}]
kubelet: E1020 06:51:11.896566 24027 nestedpendingoperations.go:253] Operation for ""kubernetes.io/cinder/48d2d1e6-e063-437a-855f-8b62b640a950"" failed. No retries permitted until 2016-10-20 06:53:11.896529189 -0700 PDT (durationBeforeRetry 2m0s). Error: Volume "kubernetes.io/cinder/48d2d1e6-e063-437a-855f-8b62b640a950" (spec.Name: "jk-test") pod "f957f140-96cb-11e6-8243-fa163ebfcd23" (UID: "f957f140-96cb-11e6-8243-fa163ebfcd23") has not yet been added to the list of VolumesInUse in the node's volume status.
Is there a piece I am missing? I’ve followed the instructions here: k8s — mysql-cinder-pd example But haven’t been able to get any communication. As another datapoint I tried defining a Storage class as provided by k8s, here are the associated StorageClass and PVC files:
# cat cinderStorage.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
name: gold
provisioner: kubernetes.io/cinder
parameters:
availability: nova
# cat dynamicPVC.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: dynamicclaim
annotations:
volume.beta.kubernetes.io/storage-class: "gold"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
Класс StorageClass сообщает об успешном завершении, но когда я пытаюсь создать PVC, он застревает в состоянии «ожидание» и сообщает, что «плагин тома не подобран»:
# kubectl get storageclass
NAME TYPE
gold kubernetes.io/cinder
# kubectl describe pvc dynamicclaim
Name: dynamicclaim
Namespace: default
Status: Pending
Volume:
Labels: <none>
Capacity:
Access Modes:
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1d 15s 5867 {persistentvolume-controller } Warning ProvisioningFailed no volume plugin matched
Это противоречит тому, что указано в журналах загруженных плагинов:
grep plugins /var/log/messages
kubelet: I1019 11:39:41.382517 22435 plugins.go:56] Registering credential provider: .dockercfg
kubelet: I1019 11:39:41.382673 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/aws-ebs"
kubelet: I1019 11:39:41.382685 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/empty-dir"
kubelet: I1019 11:39:41.382691 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/gce-pd"
kubelet: I1019 11:39:41.382698 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/git-repo"
kubelet: I1019 11:39:41.382705 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/host-path"
kubelet: I1019 11:39:41.382712 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/nfs"
kubelet: I1019 11:39:41.382718 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/secret"
kubelet: I1019 11:39:41.382725 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/iscsi"
kubelet: I1019 11:39:41.382734 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/glusterfs"
jk-kube2-master kubelet: I1019 11:39:41.382741 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/rbd"
kubelet: I1019 11:39:41.382749 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/cinder"
kubelet: I1019 11:39:41.382755 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/quobyte"
kubelet: I1019 11:39:41.382762 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/cephfs"
kubelet: I1019 11:39:41.382781 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/downward-api"
kubelet: I1019 11:39:41.382798 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/fc"
kubelet: I1019 11:39:41.382804 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/flocker"
kubelet: I1019 11:39:41.382822 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/azure-file"
kubelet: I1019 11:39:41.382839 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/configmap"
kubelet: I1019 11:39:41.382846 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/vsphere-volume"
kubelet: I1019 11:39:41.382853 22435 plugins.go:355] Loaded volume plugin "kubernetes.io/azure-disk"
И на моем компьютере установлены клиенты nova и cinder:
# which nova
/usr/bin/nova
# which cinder
/usr/bin/cinder
Приветствуется любая помощь, я уверен, что здесь я упускаю что-то простое.
Спасибо!
Ответ №1:
Тома cinder наверняка работают с Kubernetes 1.5.0 и 1.5.3 (я думаю, они также работали с 1.4.6, с которой я впервые экспериментировал, я не знаю о предыдущих версиях).
Краткий ответ
В вашем файле Pod yaml у вас отсутствовал раздел: volumeMounts:
.
Более длинный ответ
Первая возможность: нет PV или PVC
На самом деле, когда у вас уже есть существующий том cinder, вы можете просто использовать модуль (или развертывание), никаких PV или PVC не требуется. Пример:
Это создаст развертывание и модуль. Том cinder будет смонтирован в контейнер nginx. Чтобы убедиться, что вы используете том, вы можете отредактировать файл внутри контейнера nginx, внутри
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: vol-test
labels:
fullname: vol-test
spec:
strategy:
type: Recreate
replicas: 1
template:
metadata:
labels:
fullname: vol-test
spec:
containers:
- name: nginx
image: "nginx:1.11.6-alpine"
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- echo "heey-testing" > /usr/share/nginx/html/index.html amp;amp; nginx "-g daemon off;"
ports:
- name: http
containerPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html/
volumes:
- name: data
cinder:
volumeID: e143368a-440a-400f-b8a4-dd2f46c51888
/usr/share/nginx/html/
каталога и остановить контейнер. Kubernetes создаст новый контейнер, и внутри него файлы в /usr/share/nginx/html/
каталоге будут такими же, как они были в остановленном контейнере.
После удаления ресурса развертывания том cinder не удаляется, но он отсоединяется от виртуальной машины.
Вторая возможность: с PV и PVC
Другая возможность, если у вас уже есть существующий том cinder, вы можете использовать ресурсы PV и PVC. Вы сказали, что хотите использовать класс хранилища, хотя документы Kubernetes разрешают его не использовать:
PV без аннотации или для аннотации его класса установлено значение «», не имеет класса и может быть привязан только к PVCS, которые не запрашивают определенный класс
Примером класса хранилища является:
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
# to be used as value for annotation:
# volume.beta.kubernetes.io/storage-class
name: cinder-gluster-hdd
provisioner: kubernetes.io/cinder
parameters:
# openstack volume type
type: gluster_hdd
# openstack availability zone
availability: nova
Затем вы используете существующий том cinder с идентификатором 48d2d1e6-e063-437a-855f-8b62b640a950 в PV:
Затем создайте PVC, селектор меток которого соответствует меткам PV:
apiVersion: v1
kind: PersistentVolume
metadata:
# name of a pv resource visible in Kubernetes, not the name of
# a cinder volume
name: pv0001
labels:
pv-first-label: "123"
pv-second-label: abc
annotations:
volume.beta.kubernetes.io/storage-class: cinder-gluster-hdd
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
cinder:
# ID of cinder volume
volumeID: 48d2d1e6-e063-437a-855f-8b62b640a950
, а затем развертывание:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: vol-test
labels:
pvc-first-label: "123"
pvc-second-label: abc
annotations:
volume.beta.kubernetes.io/storage-class: "cinder-gluster-hdd"
spec:
accessModes:
# the volume can be mounted as read-write by a single node
- ReadWriteOnce
resources:
requests:
storage: "1Gi"
selector:
matchLabels:
pv-first-label: "123"
pv-second-label: abc
kind: Deployment
metadata:
name: vol-test
labels:
fullname: vol-test
environment: testing
spec:
strategy:
type: Recreate
replicas: 1
template:
metadata:
labels:
fullname: vol-test
environment: testing
spec:
nodeSelector:
"is_worker": "true"
containers:
- name: nginx-exist-vol
image: "nginx:1.11.6-alpine"
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- echo "heey-testing" > /usr/share/nginx/html/index.html amp;amp; nginx "-g daemon off;"
ports:
- name: http
containerPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html/
volumes:
- name: data
persistentVolumeClaim:
claimName: vol-test
После удаления ресурсов k8s том cinder не удаляется, но он отсоединяется от виртуальной машины.
Использование PV позволяет установить persistentVolumeReclaimPolicy
.
Третья возможность: том cinder не создан
Если у вас еще не создан том cinder, Kubernetes может создать его для вас. Затем вы должны предоставить ресурс PVC. Я не буду описывать этот вариант, поскольку он не был запрошен.
Отказ от ответственности
Я предлагаю всем, кто заинтересован в поиске наилучшего варианта, поэкспериментировать самим и сравнить методы. Кроме того, я использовал такие названия ярлыков, как pv-first-label
и pvc-first-label
, только для лучшего понимания причин. Вы можете использовать, например, first-label
везде.
Ответ №2:
У меня возникает подозрение, что подход dynamic StorageClass не работает, потому что Cinder provisioner еще не реализован, учитывая следующее утверждение в документах (http://kubernetes.io/docs/user-guide/persistent-volumes/#provisioner ):
У классов хранилища есть provisioner, который определяет, какой плагин тома используется для подготовки PV. Это поле должно быть указано. Во время бета-тестирования доступны следующие типы провайдеров kubernetes.io/aws-ebs и kubernetes.io/gce-pd
Что касается того, почему статический метод, использующий идентификаторы томов Cinder, не работает, я не уверен. Я сталкиваюсь с точно такой же проблемой. Kubernetes 1.2, похоже, работает нормально, 1.3 и 1.4 — нет. Похоже, это совпадает с основным изменением в обработке постоянных объемов в версии 1.3-beta2 (https://github.com/kubernetes/kubernetes/pull/26801 ):
В kubelet был представлен новый диспетчер томов, который синхронизирует монтирование / размонтирование томов (и подключение / отсоединение, если контроллер подключения / отсоединения не включен). (#26801, @saad-ali)
Это устраняет условия гонки между циклом создания модуля и циклами потерянных томов. Это также удаляет размонтирование / отсоединение из пути syncPod (), поэтому очистка тома никогда не блокирует цикл syncPod.