Подтвердить что ты не робот

Должен ли я вызвать ugi.checkTGTAndReloginFromKeytab() перед каждым действием на hadoop?

В моем серверном приложении я подключаюсь к Kerberos, защищенному кластером Hadoop, из моего java-приложения. Я использую различные компоненты, такие как файловая система HDFS, Oozie, Hive и т.д. При запуске приложения я вызываю

UserGroupInformation.loginUserFromKeytabAndReturnUGI( ... );

Это возвращает экземпляр UserGroupInformation, и я сохраняю его для жизни приложения. При выполнении привилегированных действий я запускаю их с помощью ugi.doAs(action).

Это отлично работает, но мне интересно, если и когда я должен продлить билет на кеберо в UserGroupInformation? Я нашел метод UserGroupInformation.checkTGTAndReloginFromKeytab(), который, похоже, обновляет билет, когда он близок к истечению срока действия. Я также обнаружил, что этот метод вызывается различными инструментами Hadoop, например WebHdfsFileSystem.

Теперь, если я хочу, чтобы мое серверное приложение (возможно, работало в течение нескольких месяцев или даже лет), чтобы никогда не испытывать истечение срока действия билета, является наилучшим подходом? Чтобы задать конкретные вопросы:

  • Могу ли я полагаться на разных клиентов Hadoop, которые они называют checkTGTAndReloginFromKeytab, когда это необходимо?
  • Должен ли я когда-либо позвонить checkTGTAndReloginFromKeytab в свой код?
  • Если это так, я должен сделать это перед каждым вызовом ugi.doAs(...) или, скорее, настроить таймер и называть его периодически (как часто)?
4b9b3361

Ответ 1

Hadoop коммиттер здесь! Это отличный вопрос.

К сожалению, трудно дать окончательный ответ на этот вопрос без глубокого погружения в конкретные шаблоны использования приложения. Вместо этого я могу предложить общие рекомендации и описать, когда Hadoop будет обрабатывать обновление билетов или повторно войти в систему с помощью keytab автоматически для вас, а когда это не будет.

Основным вариантом использования аутентификации Kerberos в экосистеме Hadoop является инфраструктура Hadoop RPC, которая использует SASL для аутентификации. Большинство процессов демона в экосистеме Hadoop обрабатывают это, делая одноразовый вызов UserGroupInformation#loginUserFromKeytab при запуске процесса. Примеры этого включают HDFS DataNode, который должен аутентифицировать свои вызовы RPC для NameNode и YARN NodeManager, которые должны аутентифицировать свои вызовы ResourceManager. Как демоны, подобные DataNode, могут выполнять одноразовый вход в систему при запуске процесса, а затем продолжать работать в течение нескольких месяцев, в давние времена истечения типичного срока действия билета?

Так как это такой распространенный прецедент, Hadoop реализует механизм автоматического повторного входа непосредственно внутри клиентского уровня RPC. Код для этого показан в RPC Client#handleSaslConnectionFailure:

          // try re-login
          if (UserGroupInformation.isLoginKeytabBased()) {
            UserGroupInformation.getLoginUser().reloginFromKeytab();
          } else if (UserGroupInformation.isLoginTicketBased()) {
            UserGroupInformation.getLoginUser().reloginFromTicketCache();
          }

Вы можете считать это "ленивой оценкой" повторного входа в систему. Он только повторно выполняет вход в систему в ответ на отказ аутентификации при попытке соединения с RPC.

Зная это, мы можем дать частичный ответ. Если ваш шаблон использования приложения - это войти в систему с помощью keytab, а затем выполнить типичные вызовы Hadoop RPC, то вам, скорее всего, не придется откатывать свой собственный код повторного входа. Клиентский уровень RPC сделает это за вас. "Типичный Hadoop RPC" означает подавляющее большинство Java-API для взаимодействия с Hadoop, включая API HDFS FileSystem, YarnClient и MapReduce Job.

Однако некоторые шаблоны использования приложений вообще не связаны с Hadoop RPC. Примером этого могут быть приложения, которые взаимодействуют исключительно с API-интерфейсами Hadoop REST, такими как WebHDFS или API-интерфейс YARN REST. В этом случае модель аутентификации использует Kerberos через SPNEGO, как описано в документации Hadoop HTTP Authentication.

Зная это, мы можем добавить больше к нашему ответу. Если ваш шаблон использования приложения не использует Hadoop RPC вообще, и вместо этого используется только для REST API, тогда вы должны перевернуть свою собственную логику повторного входа. Именно поэтому WebHdfsFileSystem вызывает UserGroupInformation#checkTGTAndReloginFromkeytab, как вы заметили. WebHdfsFileSystem выбирает вызов перед каждой операцией. Это прекрасная стратегия, потому что UserGroupInformation#checkTGTAndReloginFromkeytab только обновляет билет, если он "закрывается" до истечения срока действия. В противном случае вызов не будет.

В качестве конечного варианта использования рассмотрим интерактивный процесс, не войдя в него из ключевой строки, а требуя от пользователя запускать kinit извне перед запуском приложения. В подавляющем большинстве случаев это будут краткосрочные приложения, такие как команды Hadoop CLI. Однако в некоторых случаях это могут быть более длительные процессы. Чтобы поддерживать более длительные процессы, Hadoop запускает фоновый поток, чтобы обновить билет Kerberos "закрыть" до истечения срока действия. Эта логика видна в UserGroupInformation#spawnAutoRenewalThreadForUserCreds. Здесь существует важное различие по сравнению с автоматической логикой повторного входа, предоставляемой на уровне RPC. В этом случае Hadoop имеет возможность обновить билет и продлить срок его службы. Билеты имеют максимальную продолжительность жизни, как того требует инфраструктура Kerberos. После этого билет больше не будет использоваться. Повторная регистрация в этом случае практически невозможна, потому что это будет означать повторное приглашение пользователя для пароля, и они, вероятно, ушли от терминала. Это означает, что если процесс продолжает работать до истечения срока действия билета, он больше не сможет аутентифицироваться.

Опять же, мы можем использовать эту информацию, чтобы сообщить наш общий ответ. Если вы полагаетесь на пользователя для интерактивного входа в систему через kinit перед запуском приложения, и если вы уверены, что приложение не будет работать дольше, чем срок действия максимально возможного срока службы для Kerberos, то вы можете полагаться на внутренние функции Hadoop для покрытия периодического обновления для вас.

Если вы используете вход на основе keytab, и вы просто не уверены, может ли ваш шаблон использования приложения опираться на уровень повторного входа в систему Hadoop RPC, тогда консервативный подход сводится к использованию. @SamsonScharfrichter дал отличный ответ здесь о том, как перевернуть свои собственные.

Стратегия обновления соединений HBase Kerberos

Наконец, я должен добавить примечание об устойчивости API. В руководствах Apache Hadoop Compatibility обсуждаются обязательства сообщества разработчиков Hadoop по обеспечению обратной совместимости в полной мере. Интерфейс UserGroupInformation аннотируется LimitedPrivate и Evolving. Технически это означает, что API UserGroupInformation не считается общедоступным, и он может развиваться обратно-несовместимыми способами. Как практический вопрос, существует много кода уже в зависимости от интерфейса UserGroupInformation, поэтому нам просто не представляется возможным сделать перерыв. Разумеется, в текущей строке выпуска 2.x у меня не было бы никакого страха по поводу того, что сигнатуры методов будут меняться из-под вас и нарушить ваш код.

Теперь, когда у нас есть вся эта справочная информация, повторите свои конкретные вопросы.

Можно ли полагаться на различные клиенты Hadoop, которые они называют checkTGTAndReloginFromKeytab, когда это необходимо?

Вы можете положиться на это, если ваш шаблон использования приложения должен вызвать клиентов Hadoop, которые, в свою очередь, используют инфраструктуру Hadoop RPC. Вы не можете полагаться на это, если ваш шаблон использования приложения вызывает API Hadoop REST.

Должен ли я сам вызвать checkTGTAndReloginFromKeytab в моем коде?

Вам, скорее всего, понадобится сделать это, если ваш шаблон использования приложения предназначен только для вызова API Hadoop REST вместо вызовов Hadoop RPC. Вы не получили бы преимущества автоматического повторного входа, реализованного внутри клиента Hadoop RPC.

Если это так, я должен сделать это перед каждым вызовом ugi.doAs(...) или, скорее, настроить таймер и называть его периодически (как часто)?

Это нормально, чтобы вызвать UserGroupInformation#checkTGTAndReloginFromkeytab прямо перед каждым действием, которое должно быть аутентифицировано. Если билет не близок к истечению срока, то метод будет no-op. Если вы подозреваете, что ваша инфраструктура Kerberos вялая, и вы не хотите, чтобы клиентские операции оплачивали стоимость задержки для повторного входа в систему, это было бы причиной для этого в отдельном фоновом потоке. Просто убедитесь, что останетесь немного впереди фактического времени истечения срока действия билета. Вы можете взять логику внутри UserGroupInformation для определения того, является ли билет "близок" к истечению. На практике я никогда лично не видел, чтобы задержка повторного входа была проблематичной.