Jak mogę uzyskać token uwierzytelniania Kubernetes z AWS EKS przy użyciu AWS Java SDK v2? Token uwierzytelniania, którego można następnie użyć do uwierzytelnienia w Kubernetes za pomocą zestawu SDK Kubernetes. Innymi słowy, chcę uzyskać token uwierzytelniający od EKS, który będzie używany do uwierzytelniania w Kubernetes, aby nie musiałem tworzyć „konfiguracji kube”.
Właściwie mam rozwiązanie współpracujące z AWS Java SDK v1 (nie v2), patrząc na przykłady kodu w następującym otwartym problemie . Jest tu również przykład kodu w języku Python , ALE nie odnoszę żadnych sukcesów z AWS Java SDK v2. Moja próba zrobienia tego z 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);
}
}
Generuje token, ale kiedy używam go w moim kliencie Kubernetes (oficjalny pakiet Java Kubernetes SDK), otrzymuję odpowiedź „Nieautoryzowane” - więc brakuje mi czegoś, czego nie mogę dotknąć ...
Wersja AWS Java SDK v1 wygląda mniej więcej tak: (Z otwartego problemu wspomnianego wcześniej)
Mam to działa, ale staram się uzyskać coś podobnego do pracy w 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;
}
}
Odpowiedzi:
Okej, w końcu udało mi się.
Wersja AWS Java SDK v2:
Problem dotyczył mojego punktu końcowego STS Uri:
Zauważ, że
/
wpath
(trzeciej) argument dlaURI
obiektu. Wersja AWS Java SDK v1 nie utworzyła takiego identyfikatora URI, ale określiła/
gdzie indziej. Jeśli teraz wydrukujęURI
jako ciąg, otrzymamhttps://sts.eu-west-1.amazonaws.com/
, a oryginalna wersja pytania właśnie wróciłahttps://sts.eu-west-1.amazonaws.com
Co ciekawe - oryginalna wersja również wygenerowała token, ale token został odrzucony przez Kubernetes. Należy się spodziewać podobnego zachowania, jeśli data wygaśnięcia jest zbyt daleko w przyszłość - dostaniesz token, ale doprowadzi to do
Unauthorized
odpowiedzi z usługi Kubernetes.Po zmianie punktu końcowego STS wszystko działało, ale wprowadziłem jeszcze jedną zmianę:
Dodałem następujący wiersz do mojego
Aws4PresignerParams
:Nie było to wymagane, ale oryginalny AWS Java SDK v1 zrobił coś z zegarem, gdy został określony
SdkClock.STANDARD
, a tenZonedDateTime
, którego używam w wersji AWS Java SDK v2, korzysta ze strefy czasowej UTC.źródło
/
wciąż otrzymałem token, ale jak wskazano, po prostu nie działał, kiedy zacząłem integrować się z Kubernetes.Unauthorized
odpowiedzi.