Как получить токен аутентификации Kubernetes от AWS EKS с помощью AWS Java SDK v2? Токен аутентификации, который затем можно использовать для аутентификации в Kubernetes с использованием Kubernetes SDK. Другими словами, я хочу получить токен аутентификации от EKS, чтобы использовать его для аутентификации с Kubernetes, чтобы мне не нужно было создавать «конфигурацию kube».
На самом деле я получил решение, работающее с AWS Java SDK v1 (не v2), рассматривая примеры кода в следующем открытом выпуске . Существует также код Python пример здесь , но я не имея каких - либо успехов с AWS Java SDK v2. Моя попытка сделать это с помощью AWS Java SDK v2:
public static String getAuthenticationToken(AwsCredentialsProvider awsAuth, Region awsRegion, String clusterName) {
try {
SdkHttpFullRequest requestToSign = SdkHttpFullRequest
.builder()
.method(SdkHttpMethod.GET)
.uri(new URI("https", String.format("sts.%s.amazonaws.com", awsRegion.id()), null, null))
.appendHeader("x-k8s-aws-id", clusterName)
.appendRawQueryParameter("Action", "GetCallerIdentity")
.appendRawQueryParameter("Version", "2011-06-15")
.build();
ZonedDateTime expirationDate = DateUtil.addSeconds(DateUtil.now(), 60);
Aws4PresignerParams presignerParams = Aws4PresignerParams.builder()
.awsCredentials(awsAuth.resolveCredentials())
.expirationTime(expirationDate.toInstant())
.signingName("sts")
.signingRegion(awsRegion)
.build();
SdkHttpFullRequest signedRequest = Aws4Signer.create().presign(requestToSign, presignerParams);
String encodedUrl = Base64.getUrlEncoder().withoutPadding().encodeToString(signedRequest.getUri().toString().getBytes(CharSet.UTF_8.getCharset()));
return ("k8s-aws-v1." + encodedUrl);
} catch (Exception e) {
String errorMessage = "A problem occurred generating an Eks token";
logger.error(errorMessage, e);
throw new RuntimeException(errorMessage, e);
}
}
Он генерирует токен, но когда я использую токен в моем клиенте Kubernetes (официальном Java Kubernetes SDK), я получаю ответ «Несанкционированный» - так что мне не хватает того, на что я не могу положить палец ...
Версия AWS Java SDK v1 выглядит примерно так: (Из упомянутой ранее открытой проблемы )
Я получил это работает, но я изо всех сил пытаюсь получить что-то похожее на работу в AWS Java SDK v2.
private String generateToken(String clusterName,
Date expirationDate,
String serviceName,
String region,
AWSSecurityTokenServiceClient awsSecurityTokenServiceClient,
AWSCredentialsProvider credentialsProvider,
String scheme,
String host) throws URISyntaxException {
try {
DefaultRequest<GetCallerIdentityRequest> callerIdentityRequestDefaultRequest = new DefaultRequest<>(new GetCallerIdentityRequest(), serviceName);
URI uri = new URI(scheme, host, null, null);
callerIdentityRequestDefaultRequest.setResourcePath("/");
callerIdentityRequestDefaultRequest.setEndpoint(uri);
callerIdentityRequestDefaultRequest.setHttpMethod(HttpMethodName.GET);
callerIdentityRequestDefaultRequest.addParameter("Action", "GetCallerIdentity");
callerIdentityRequestDefaultRequest.addParameter("Version", "2011-06-15");
callerIdentityRequestDefaultRequest.addHeader("x-k8s-aws-id", clusterName);
Signer signer = SignerFactory.createSigner(SignerFactory.VERSION_FOUR_SIGNER, new SignerParams(serviceName, region));
SignerProvider signerProvider = new DefaultSignerProvider(awsSecurityTokenServiceClient, signer);
PresignerParams presignerParams = new PresignerParams(uri,
credentialsProvider,
signerProvider,
SdkClock.STANDARD);
PresignerFacade presignerFacade = new PresignerFacade(presignerParams);
URL url = presignerFacade.presign(callerIdentityRequestDefaultRequest, expirationDate);
String encodedUrl = Base64.getUrlEncoder().withoutPadding().encodeToString(url.toString().getBytes());
log.info("Token [{}]", encodedUrl);
return "k8s-aws-v1." + encodedUrl;
} catch (URISyntaxException e) {
log.error("could not generate token", e);
throw e;
}
}
Ответы:
Ладно, наконец-то все заработало.
Версия AWS Java SDK v2:
Проблема была в моей конечной точке STS Uri:
Обратите внимание , что
/
вpath
(третьем) аргументе дляURI
объекта. Версия AWS Java SDK v1 не создавала подобный URI, а указала в/
другом месте. Если я сейчас распечатаю полученнуюURI
строкуhttps://sts.eu-west-1.amazonaws.com/
, в то время как оригинальная версия в вопросе только что вернуласьhttps://sts.eu-west-1.amazonaws.com
Интересно, что оригинальная версия также генерировала токен, но он был отклонен Кубернетом. Следует ожидать аналогичного поведения, если срок действия истекает слишком далеко в будущем - вы получите токен, но это приведет к
Unauthorized
ответу от службы Kubernetes.После изменения конечной точки STS все заработало, но я сделал еще одно изменение:
Я добавил следующую строку в мой
Aws4PresignerParams
:В этом не было необходимости, но оригинальный AWS Java SDK v1 действительно что-то делал с часами, когда они были указаны
SdkClock.STANDARD
, а то,ZonedDateTime
что я использую в версии AWS Java SDK v2, действительно использует часовой пояс UTC.источник
/
я все еще получил токен, но, как указано, он просто не работал, когда я начал интегрироваться с Kubernetes.Unauthorized
ответу.