Wie kann ich mit dem AWS Java SDK v2 ein Kubernetes-Authentifizierungstoken von AWS EKS erhalten? Ein Authentifizierungstoken, mit dem Sie sich mithilfe eines Kubernetes SDK bei Kubernetes authentifizieren können. Mit anderen Worten, ich möchte ein Authentifizierungstoken von EKS erhalten, das für die Authentifizierung mit Kubernetes verwendet werden soll, damit ich keine "Kube-Konfiguration" erstellen muss.
Ich habe tatsächlich eine Lösung mit AWS Java SDK v1 (nicht v2) erhalten, die sich die Codebeispiele in der folgenden offenen Ausgabe ansieht . Es gibt hier auch ein Python-Codebeispiel , ABER ich habe keinen Erfolg mit AWS Java SDK v2. Mein Versuch, dies mit AWS Java SDK v2 zu tun:
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);
}
}
Es wird ein Token generiert, aber wenn ich das Token in meinem Kubernetes-Client (dem offiziellen Java Kubernetes SDK) verwende, erhalte ich eine "nicht autorisierte" Antwort zurück - daher fehlt mir etwas, auf das ich keinen Finger legen kann ...
Die AWS Java SDK v1-Version sieht ungefähr so aus: (Aus dem zuvor erwähnten offenen Problem )
Ich habe es zum Laufen gebracht, aber ich habe Probleme, etwas Ähnliches in AWS Java SDK v2 zum Laufen zu bringen.
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;
}
}
Antworten:
Okay, ich habe es endlich geschafft.
Die AWS Java SDK v2-Version:
Das Problem war in meinem STS-Endpunkt Uri:
Beachten Sie das Argument
/
impath
(dritten) für dasURI
Objekt. Die AWS Java SDK v1-Version hat den URI nicht so erstellt, sondern an/
anderer Stelle angegeben. Wenn ich jetzt die Zeichenfolge ausdrucke,URI
erhalte ich siehttps://sts.eu-west-1.amazonaws.com/
, während die Originalversion in der Frage gerade zurückgegeben wurdehttps://sts.eu-west-1.amazonaws.com
Interessant genug - die ursprüngliche Version hat auch ein Token generiert, aber das Token wurde von Kubernetes abgelehnt. Man sollte ein ähnliches Verhalten erwarten, wenn das Ablaufdatum zu weit in der Zukunft liegt - Sie erhalten ein Token, das jedoch zu einer
Unauthorized
Antwort des Kubernetes-Dienstes führt.Nach dem Ändern des STS-Endpunkts hat alles funktioniert, aber ich habe noch eine Änderung vorgenommen:
Ich habe die folgende Zeile zu meiner hinzugefügt
Aws4PresignerParams
:Es war nicht erforderlich, aber das ursprüngliche AWS Java SDK v1 hat etwas mit einer Uhr gemacht, als es angegeben wurde
SdkClock.STANDARD
, und dasZonedDateTime
, das ich in der AWS Java SDK v2-Version verwende, verwendet die UTC-Zeitzone.quelle
/
ich noch ein Token bekommen, aber wie angegeben hat es einfach nicht funktioniert, als ich anfing, mich in Kubernetes zu integrieren.Unauthorized
Antwort führt.