Маркировка стручка невозможна изнутри стручка с использованием Kubernetes на Docker-EE
Мы используем развертывание Apache-Kafka в Kubernetes, которое основано на способности маркировать модули после их создания (см. https://github.com/Yolean/kubernetes-kafka). Контейнер init модулей брокера использует эту возможность для установки метки на себя с собственным числовым индексом (например, "0", "1" и т. Д.) В качестве значения. Метка используется в дескрипторах службы, чтобы выбрать ровно один модуль.
Этот подход прекрасно работает в нашей среде DIND-Kubernetes. Однако когда мы попытались перенести развертывание в среду Docker-EE Kubernetes, у нас возникли проблемы, потому что команда kubectl label pod
генерирует ошибку времени выполнения, которая полностью вводит в заблуждение (также см. https://github.com/fabric8io/kubernetes-client/issues/853).
Чтобы проверить ошибку времени выполнения при минимальной настройке, мы создали следующие сценарии развертывания.
Первый шаг: успешно пометить модуль с помощью Docker-EE-Host
# create a simple pod as a test target for labeling
> kubectl run -ti -n default --image alpine sh
# get the pod name for all further steps
> kubectl -n default get pods
NAME READY STATUS RESTARTS AGE
nfs-provisioner-7d49cdcb4f-8qx95 1/1 Running 1 7d
nginx-deployment-76dcc8c697-ng4kb 1/1 Running 1 7d
nginx-deployment-76dcc8c697-vs24j 1/1 Running 0 20d
sh-777f6db646-hrm65 1/1 Running 0 3m <--- This is the test pod
test-76bbdb4654-9wd9t 1/1 Running 2 6d
test4-76dbf847d5-9qck2 1/1 Running 0 5d
# get client and server versions
> kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.5",
GitCommit:"32ac1c9073b132b8ba18aa830f46b77dcceb0723", GitTreeState:"clean",
BuildDate:"2018-06-21T11:46:00Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"8+", GitVersion:"v1.8.11- docker-8d637ae", GitCommit:"8d637aedf46b9c21dde723e29c645b9f27106fa5",
GitTreeState:"clean", BuildDate:"2018-04-26T16:51:21Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
# set label
kubectl -n default label pod sh-777f6db646-hrm65 "mylabel=hallo"
pod "sh-777f6db646-hrm65" labeled <---- successful execution
Все работает нормально, как и ожидалось.
Второй шаг: воспроизвести ошибку во время выполнения из модуля
Создать образ Docker, содержащий kubectl
1.10.5
FROM debian:stretch-
slim@sha256:ea42520331a55094b90f6f6663211d4f5a62c5781673935fe17a4dfced777029
ENV KUBERNETES_VERSION=1.10.5
RUN set -ex; \
export DEBIAN_FRONTEND=noninteractive; \
runDeps='curl ca-certificates procps netcat'; \
buildDeps=''; \
apt-get update && apt-get install -y $runDeps $buildDeps --no-install- recommends; \
rm -rf /var/lib/apt/lists/*; \
\
curl -sLS -o k.tar.gz -k https://dl.k8s.io/v${KUBERNETES_VERSION}/kubernetes-client-linux-amd64.tar.gz; \
tar -xvzf k.tar.gz -C /usr/local/bin/ --strip-components=3 kubernetes/client/bin/kubectl; \
rm k.tar.gz; \
\
apt-get purge -y --auto-remove $buildDeps; \
rm /var/log/dpkg.log /var/log/apt/*.log
Это изображение развернуто как 10.100.180.74:5000/test/kubectl-client-1.10.5
в локальном реестре сайта и будет упомянуто ниже.
Создайте контейнер, используя контейнер выше
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: pod-labeler
namespace: default
spec:
selector:
matchLabels:
app: pod-labeler
replicas: 1
serviceName: pod-labeler
updateStrategy:
type: OnDelete
template:
metadata:
labels:
app: pod-labeler
annotations:
spec:
terminationGracePeriodSeconds: 10
containers:
- name: check-version
image: 10.100.180.74:5000/test/kubectl-client-1.10.5
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
value: sh-777f6db646-hrm65
command: ["/usr/local/bin/kubectl", "version" ]
- name: label-pod
image: 10.100.180.74:5000/test/kubectl-client-1.10.5
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
value: sh-777f6db646-hrm65
command: ["/bin/bash", "-c", "/usr/local/bin/kubectl -n default label pod $POD_NAME 'mylabel2=hallo'" ]
Регистрация выхода
Мы получаем следующий вывод журнала
# Log of the container "check-version"
2018-07-18T11:11:10.791011157Z Client Version: version.Info{Major:"1",
Minor:"10", GitVersion:"v1.10.5",
GitCommit:"32ac1c9073b132b8ba18aa830f46b77dcceb0723", GitTreeState:"clean",
BuildDate:"2018-\
06-21T11:46:00Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
2018-07-18T11:11:10.791058997Z Server Version: version.Info{Major:"1",
Minor:"8+", GitVersion:"v1.8.11-docker-8d637ae",
GitCommit:"8d637aedf46b9c21dde723e29c645b9f27106fa5", GitTreeState:"clean",
BuildDate:"2018-04-26T16:51:21Z", GoVersion:"go1.8.3", Compiler:"gc",
Platform:"linux/amd64"}
и ошибка времени выполнения
2018-07-18T11:24:15.448695813Z The Pod "sh-777f6db646-hrm65" is invalid:
spec.tolerations: Forbidden: existing toleration can not be modified except its tolerationSeconds
Заметки
- Это не проблема авторизации, так как мы предоставили пользователю по умолчанию пространства имен по умолчанию полные административные права. Если мы этого не сделаем, мы получим сообщение об ошибке со ссылкой на отсутствующие разрешения.
- Версии клиента и сервера "снаружи" (например, на хосте докера) и "внутри" (например, модуле) идентичны тегу коммитов GIT.
- Мы используем версию 3.0.2 универсальной плоскости управления
Есть идеи?
1 ответ
В одном из комментариев было указано, что проблема может быть вызвана отсутствием разрешения, даже если сообщение об ошибке не указывает на это. Мы официально подали заявку в Docker и фактически получили именно такой результат: чтобы иметь возможность устанавливать / изменять метку из модуля, пользователю пространства имен по умолчанию должна быть назначена роль "Планировщик" на ресурсе swarm (который позже появляется как \
в графическом интерфейсе). Предоставление этого разрешения устраняет проблему. См. Добавленный грант в Docker-EE-GUI ниже.
С моей точки зрения, это далеко не очевидно. Представитель службы поддержки Docker предложил выяснить, действительно ли это ожидаемое поведение или результат ошибки. Как только мы узнаем больше по этому вопросу, я включу его в наш ответ.
Что касается использования более отладочного вывода: к сожалению, добавление --v=9
на вызовы kubectl
не возвращает никакой полезной информации. Здесь слишком много выходных данных для отображения, но общее ведение журнала очень схоже в обоих случаях: оно состоит из большого количества запросов GET API, которые все выполняются, после чего следует окончательный запрос API PATCH, который в одном случае завершается неудачей, а в другом - как описано выше.