#amazon-web-services #kubernetes #openid-connect #amazon-eks
Вопрос:
Я использую AWS EKS 1.21 с включенным обнаружением учетных записей служб.
Созданный поставщик OIDC, .well-known/openid-configuration
конечная точка возвращает правильную конфигурацию:
{
"issuer": "https://oidc.eks.eu-west-1.amazonaws.com/id/***",
"jwks_uri": "https://ip-***.eu-west-1.compute.internal:443/openid/v1/jwks",
"response_types_supported": [
"id_token"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
]
}
Создал учетную запись службы для одного из моих развертываний, и модуль получает ее в качестве прогнозируемого объема:
volumes:
- name: kube-api-access-b4xt9
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
Секрет, созданный для учетной записи службы, содержит этот токен:
{
"iss": "kubernetes/serviceaccount",
"kubernetes.io/serviceaccount/namespace": "sbx",
"kubernetes.io/serviceaccount/secret.name": "dliver-site-config-service-token-kz874",
"kubernetes.io/serviceaccount/service-account.name": "dliver-site-config-service",
"kubernetes.io/serviceaccount/service-account.uid": "c26ad760-9067-4d90-a327-b3d6e32bce42",
"sub": "system:serviceaccount:sbx:dliver-site-config-service"
}
Проектируемый токен, смонтированный в модуле, содержит следующее:
{
"aud": [
"https://kubernetes.default.svc"
],
"exp": 1664448004,
"iat": 1632912004,
"iss": "https://oidc.eks.eu-west-1.amazonaws.com/id/***",
"kubernetes.io": {
"namespace": "sbx",
"pod": {
"name": "dliver-site-config-service-77494b8fdd-45pxw",
"uid": "0dd440a6-1213-4faa-a69e-398b83d2dd6b"
},
"serviceaccount": {
"name": "dliver-site-config-service",
"uid": "c26ad760-9067-4d90-a327-b3d6e32bce42"
},
"warnafter": 1632915611
},
"nbf": 1632912004,
"sub": "system:serviceaccount:sbx:dliver-site-config-service"
}
Kubernetes обновляет прогнозируемый токен каждый час, так что все выглядит нормально.
За исключением поля прогнозируемого токена «exp» .:
"iat": 1632912004
что есть Wednesday, September 29, 2021 10:40:04 AM
"exp": 1664448004
, что есть Thursday, September 29, 2022 10:40:04 AM
Таким образом, проблема в том, что прогнозируемое время истечения срока действия токена составляет 1 год, а не около 1 часа, что делает усилия Kubernetes по обновлению токена практически бесполезными.
Я искал несколько часов, но просто не мог понять, откуда это берется.
Флаг истечения срока действия передается серверу kube-api: --service-account-max-token-expiration="24h0m0s"
, поэтому я предполагаю, что это должно быть каким-то образом настроено на поставщике OIDC, но не смог найти никакой связанной документации.
Есть идеи, как сделать прогнозируемую дату истечения срока действия токена примерно такой же, как expirationSeconds
в прогнозируемом объеме модуля?
Обновить
Это происходит только тогда, когда для проецируемого токена expirationSeconds
установлено 3607
значение по умолчанию, любое другое значение дает правильное exp
значение в смонтированном токене, что действительно странно.
Комментарии:
1. Какое приложение OIDC вы использовали?
https://ip-***.eu-west-1.compute.internal:443/openid/v1/jwks
2. Просто создал кластер EKS и связал поставщика OIDC в IAM, как описано здесь: docs.aws.amazon.com/eks/latest/userguide/…
3. В чем преимущество получения токена по
kubernetes.default.svc
сравнению с токеном по умолчанию, автоматически смонтированным k8s? Особенно вы ссылаетесь на OIDC вашего собственного кластера.4. Эта функция по умолчанию включена в EKS, поскольку она автоматически устанавливает необходимые флаги, описанные здесь: kubernetes.io/docs/tasks/configure-pod-container/. … В этом случае k8s по умолчанию смонтирует прогнозируемый токен. Преимущество в том, что мы можем использовать токены с коротким сроком службы вместо токена с длительным сроком службы по умолчанию.
Ответ №1:
Наконец-то получил ответ в другом месте.
операторы кластера могут указать флаг —service-account-extend-token-expiration=true для apiserver kube, чтобы разрешить маркерам временно иметь более длительный срок действия во время миграции. Любое использование устаревшего токена будет записано как в метриках, так и в журналах аудита.
Магический номер «3607» является частью плана безопасного развертывания Связанных токенов учетной записи службы, описанного в этом документе. Фактическое число, жестко закодированное в исходном коде.
--service-account-extend-token-expiration
Флаг был установлен в значение true по умолчанию с 1.20.
Упомянутую информацию о метрике/журнале также можно найти в kep и она была реализована здесь.
Чтобы просмотреть эти журналы в EKS, необходимо включить ведение журнала аудита в кластере, а затем проверить Cloudwatch на наличие соответствующих записей в журнале.
Я использовал этот запрос в Cloudwatch Log Insight, чтобы найти, какие модули периодически не перезагружают токен:
filter @logStream like 'kube-apiserver-audit'
| filter ispresent(`annotations.authentication.k8s.io/stale-token`)
| parse `annotations.authentication.k8s.io/stale-token` "subject: *," as subject
| stats count(*) as staleCount by subject, `user.username`
| sort staleCount desc