company_banner

Интеграция Kubernetes Dashboard и пользователей GitLab



    Kubernetes Dashboard — простой в работе инструмент для получения актуальных сведений о работающем кластере и минимального управления им. Начинаешь его ценить ещё больше, когда доступ к этим возможностям нужен не только администраторам/DevOps-инженерам, но и тем, кто меньше привык к консоли и/или не намерен разбираться со всеми тонкостями взаимодействия с kubectl и другими утилитами. Так случилось и у нас: разработчикам захотелось быстрого доступа к веб-интерфейсу Kubernetes, а поскольку мы используем GitLab, решение напросилось само собой.

    Зачем это?


    Непосредственные разработчики могут быть заинтересованы в инструменте вроде K8s Dashboard для задач по отладке. Иногда хочется просматривать логи и ресурсы, а порой и убивать pod’ы, масштабировать Deployments/StatefulSets и даже заходить в консоль контейнеров (случаются и такие запросы, для решения которых, впрочем, есть другой путь — например, через kubectl-debug).

    Кроме того, есть и психологический момент для руководителей, когда они хотят посмотреть на кластер — увидеть, что «всё зелененькое», и таким образом успокоиться, что «всё работает» (что, конечно, весьма относительно… но это уже выходит за рамки статьи).

    В качестве стандартной CI-системы у нас применяется GitLab: ей пользуются и все разработчики. Поэтому, чтобы предоставить им доступ, было логично сделать интеграцию Dashboard с аккаунтами в GitLab.

    Также отмечу, что мы используем NGINX Ingress. Если же вы работаете с другими ingress-решениями, потребуется самостоятельно найти аналоги аннотаций для авторизации.

    Пробуем интеграцию


    Установка Dashboard


    Внимание: Если вы собираетесь повторять описанные ниже шаги, то — во избежание лишних операций — сначала дочитайте до следующего подзаголовка.

    Поскольку эта интеграция используется нами во множестве инсталляций, мы автоматизировали её установку. Исходники, которые потребуются для этого, опубликованы в специальном GitHub-репозитории. В их основе — незначительно модифицированные YAML-конфигурации из официального репозитория Dashboard, а также Bash-скрипт для быстрого развёртывания.

    Скрипт устанавливает Dashboard в кластер и настраивает его на интеграцию с GitLab:

    $ ./ctl.sh  
    Usage: ctl.sh [OPTION]... --gitlab-url GITLAB_URL --oauth2-id ID --oauth2-secret SECRET --dashboard-url DASHBOARD_URL
    Install kubernetes-dashboard to Kubernetes cluster.
    Mandatory arguments:
     -i, --install                install into 'kube-system' namespace
     -u, --upgrade                upgrade existing installation, will reuse password and host names
     -d, --delete                 remove everything, including the namespace
         --gitlab-url             set gitlab url with schema (https://gitlab.example.com)
         --oauth2-id              set OAUTH2_PROXY_CLIENT_ID from gitlab
         --oauth2-secret          set OAUTH2_PROXY_CLIENT_SECRET from gitlab
         --dashboard-url          set dashboard url without schema (dashboard.example.com)
    Optional arguments:
     -h, --help                   output this message

    Однако перед его использованием необходимо зайти в GitLab: Admin area → Applications — и добавить новое приложение для будущей панели. Назовём его «kubernetes dashboard»:



    В результате его добавления GitLab предоставит хэши:



    Именно они и используются в качестве аргументов к скрипту. В результате, установка выглядит следующим образом:

    $ ./ctl.sh -i --gitlab-url https://gitlab.example.com --oauth2-id 6a52769e… --oauth2-secret 6b79168f… --dashboard-url dashboard.example.com

    После этого проверим, что всё запустилось:

    $ kubectl -n kube-system get pod | egrep '(dash|oauth)'
    kubernetes-dashboard-76b55bc9f8-xpncp   1/1       Running   0          14s
    oauth2-proxy-5586ccf95c-czp2v           1/1       Running   0          14s

    Рано или поздно всё запустится, однако сразу авторизация работать не будет! Дело в том, что в используемом образе (ситуация в других образах аналогична) некорректно реализован процесс ловли редиректа в callback. Это обстоятельство приводит к тому, что oauth стирает cookie, которую сам же (oauth) нам предоставляет…

    Проблема решается сборкой своего образа oauth с патчем.

    Патч к oauth и повторная установка


    Для этого воспользуемся следующим Dockerfile’ом:

    FROM golang:1.9-alpine3.7
    WORKDIR /go/src/github.com/bitly/oauth2_proxy
    
    RUN apk --update add make git build-base curl bash ca-certificates wget \
    && update-ca-certificates \
    && curl -sSO https://raw.githubusercontent.com/pote/gpm/v1.4.0/bin/gpm \
    && chmod +x gpm \
    && mv gpm /usr/local/bin
    RUN git clone https://github.com/bitly/oauth2_proxy.git . \
    && git checkout bfda078caa55958cc37dcba39e57fc37f6a3c842  
    ADD rd.patch .
    RUN patch -p1 < rd.patch \
    && ./dist.sh
    
    FROM alpine:3.7
    RUN apk --update add curl bash  ca-certificates && update-ca-certificates
    COPY --from=0 /go/src/github.com/bitly/oauth2_proxy/dist/ /bin/
    
    EXPOSE 8080 4180
    ENTRYPOINT [ "/bin/oauth2_proxy" ]
    CMD [ "--upstream=http://0.0.0.0:8080/", "--http-address=0.0.0.0:4180" ]

    А вот как выглядит сам патч rd.patch
    diff --git a/dist.sh b/dist.sh
    index a00318b..92990d4 100755
    --- a/dist.sh
    +++ b/dist.sh
    @@ -14,25 +14,13 @@ goversion=$(go version | awk '{print $3}')
     sha256sum=()
     
     echo "... running tests"
    -./test.sh
    +#./test.sh
     
    -for os in windows linux darwin; do
    -    echo "... building v$version for $os/$arch"
    -    EXT=
    -    if [ $os = windows ]; then
    -        EXT=".exe"
    -    fi
    -    BUILD=$(mktemp -d ${TMPDIR:-/tmp}/oauth2_proxy.XXXXXX)
    -    TARGET="oauth2_proxy-$version.$os-$arch.$goversion"
    -    FILENAME="oauth2_proxy-$version.$os-$arch$EXT"
    -    GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
    -        go build -ldflags="-s -w" -o $BUILD/$TARGET/$FILENAME || exit 1
    -    pushd $BUILD/$TARGET
    -    sha256sum+=("$(shasum -a 256 $FILENAME || exit 1)")
    -    cd .. && tar czvf $TARGET.tar.gz $TARGET
    -    mv $TARGET.tar.gz $DIR/dist
    -    popd
    -done
    +os='linux'
    +echo "... building v$version for $os/$arch"
    +TARGET="oauth2_proxy-$version.$os-$arch.$goversion"
    +GOOS=$os GOARCH=$arch CGO_ENABLED=0 \
    +    go build -ldflags="-s -w" -o ./dist/oauth2_proxy || exit 1
     
     checksum_file="sha256sum.txt"
     cd $DIR/dist
    diff --git a/oauthproxy.go b/oauthproxy.go
    index 21e5dfc..df9101a 100644
    --- a/oauthproxy.go
    +++ b/oauthproxy.go
    @@ -381,7 +381,9 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
     	if redirect_url == p.SignInPath {
     		redirect_url = "/"
     	}
    -
    +	if req.FormValue("rd") != "" {
    +		redirect_url = req.FormValue("rd")
    +	}
     	t := struct {
     		ProviderName  string
     		SignInMessage string
    

    Теперь можно осуществить сборку образа и за’push’ить его в наш же GitLab. Далее в manifests/kube-dashboard-oauth2-proxy.yaml укажем использование нужного образа (замените его на свой):

     image: docker.io/colemickens/oauth2_proxy:latest

    Если у вас закрытый авторизацией registry — не забудьте добавить использование секрета для pull’а образов:

          imagePullSecrets:
         - name: gitlab-registry

    … и добавьте сам секрет для registry:

    ---
    apiVersion: v1
    data:
     .dockercfg: eyJyZWdpc3RyeS5jb21wYW55LmNvbSI6IHsKICJ1c2VybmFtZSI6ICJvYXV0aDIiLAogInBhc3N3b3JkIjogIlBBU1NXT1JEIiwKICJhdXRoIjogIkFVVEhfVE9LRU4iLAogImVtYWlsIjogIm1haWxAY29tcGFueS5jb20iCn0KfQoK
    =
    kind: Secret
    metadata:
     annotations:
     name: gitlab-registry
     namespace: kube-system
    type: kubernetes.io/dockercfg

    Внимательный читатель увидит, что приведённая выше длинная строка — это base64 от конфига:

    {"registry.company.com": {
     "username": "oauth2",
     "password": "PASSWORD",
     "auth": "AUTH_TOKEN",
     "email": "mail@company.com"
    }
    }

    Это данные пользователя в GitLab, код которым Kubernetes будет pull’ить образ из registry.

    После того, как всё сделано, можно удалить текущую (некорректно работающую) инсталляцию Dashboard командой:

    $ ./ctl.sh -d

    … и установить всё заново:

    $ ./ctl.sh -i --gitlab-url https://gitlab.example.com --oauth2-id 6a52769e… --oauth2-secret 6b79168f… --dashboard-url dashboard.example.com

    Настало время зайти в Dashboard и найти довольно архаичную кнопку авторизации:



    После нажатия на неё нас встретит GitLab, предлагая авторизоваться на своей привычной странице (конечно же, если мы не были предварительно авторизованы там):



    Авторизуемся с учётными данными GitLab — и всё свершилось:



    О возможностях Dashboard


    Если вы разработчик, который прежде не работал с Kubernetes, или же просто по какой-то причине не сталкивались прежде с Dashboard — проиллюстрирую некоторые его возможности.

    Во-первых, можно посмотреть, что «всё зелененькое»:



    По pod’ам доступны и более детальные данные, такие как переменные окружения, выкаченный образ, аргументы запуска, их состояние:



    У deployment’ов видны статусы:



    … и другие подробности:



    … а также есть возможность отмасштабировать deployment:



    Результат этой операции:



    Среди прочих полезных возможностей, уже упомянутых в начале статьи, — просмотр логов:



    … и функция входа в консоль контейнеров выбранного pod’а:



    Ещё, например, можно посмотреть и limit’ы/request’ы на узлах:



    Конечно, это не все возможности панели, но надеюсь, что общее представление сложилось.

    Недостатки интеграции и Dashboard


    В описанной интеграции нет никакого разграничения доступа. С ней все пользователи, имеющие какой-либо доступ к GitLab, получают доступ в Dashboard. Доступ в самом Dashboard у них одинаковый, соответствующий правам самой Dashboard, которые определяются в RBAC. Очевидно, что это подойдёт не всем, но для нашего случая оказалось достаточным.

    Из заметных минусов в самой панели Dashboard отмечу следующие:

    • невозможно попасть в консоль init-контейнера;
    • невозможно редактировать Deployments и StatefulSets, хотя это поправимо в ClusterRole;
    • совместимость Dashboard с последними версиями Kubernetes и будущее проекта вызывает вопросы.

    Последняя проблема заслуживает особого внимания.

    Статус и альтернативы Dashboard


    Таблица совместимости Dashboard с релизами Kubernetes, представленная в последней версии проекта (v1.10.1), не очень-то радует:



    Несмотря на это, существует (уже принятый в январе) PR #3476, который объявляет о поддержке K8s 1.13. Вдобавок, среди issues проекта можно найти упоминания пользователей, работающих с панелью в K8s 1.14. Наконец, коммиты в кодовую базу проекта не прекращаются. Так что (как минимум!) фактический статус проекта не настолько плох, как может сперва показаться из официальной таблицы совместимости.

    Наконец, у Dashboard существуют альтернативы. Среди них:

    1. K8Dash — молодой интерфейс (первые коммиты датируются мартом этого года), уже предлагающий неплохие возможности, такие как визуальное представление текущего статуса кластера и управление его объектами. Позиционируется как «интерфейс реального времени», т.к. автоматически актуализирует показываемые данные, не требуя обновлять страницу в браузере.
    2. OpenShift Console — веб-интерфейс от Red Hat OpenShift, который, впрочем, принесёт в ваш кластер и другие наработки проекта, что не всем подходит.
    3. Kubernator — интересный проект, созданный как более низкоуровневый (чем Dashboard) интерфейс с возможностью просмотра всех объектов кластера. Однако всё выглядит так, что его разработка прекратилась.
    4. Polaris — буквально на днях анонсированный проект, который совмещает в себе функции панели (показывает текущее состояние кластера, но не управляет его объектами) и автоматической «валидации лучших практик» (проверяет кластер на корректность конфигураций запущенных в нём Deployments).

    Вместо выводов


    Dashboard — стандартный инструмент для кластеров Kubernetes, которые мы обслуживаем. Его интеграция с GitLab тоже стала частью нашей «инсталляции по умолчанию», поскольку многие разработчики рады тем возможностям, которые у них появляются с этой панелью.

    У Kubernetes Dashboard периодически появляются альтернативы от Open Source-сообщества (и мы рады их рассмотреть), однако на данном этапе остаёмся с этим решением.

    P.S.


    Читайте также в нашем блоге:



    UPD. По репорту whoch, была найдена ошибка в патче (табы заменились на пробелы). Патч в статье обновлен.
    • +27
    • 4,1k
    • 2
    Флант
    481,87
    Специалисты по DevOps и Kubernetes
    Поделиться публикацией

    Комментарии 2

      +1
      Вылетает при билде имейджа с патчем со следующей ошибкой
      ".godeps/src/google.golang.org/grpc/internal/transport/http_util.go:672:6: f.fr.SetReuseFrames undefined (type *http2.Framer has no field or method SetReuseFrames)
      The command '/bin/sh -c patch -p1 < rd.patch && ./dist.sh' returned a non-zero code: 2"

      Пробовал на пяти разных конфигурациях, везде одно и тоже самое… В какую сторону копать?
        +2
        Как выяснилось, у нас на каком-то из этапов подготовки публикации табы заменились на пробелы, отчего патч выходил нерабочим. В статье уже новый (рабочий) патч. Пользуйтесь на здоровье!

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое