Bagaimana saya bisa mendapatkan token otentikasi Kubernetes dari AWS EKS menggunakan AWS Java SDK v2? Token otentikasi yang kemudian dapat digunakan untuk mengautentikasi dengan Kubernetes menggunakan Kubernetes SDK. Dengan kata lain saya ingin mendapatkan token otentikasi dari EKS untuk digunakan untuk otentikasi dengan Kubernetes sehingga saya tidak perlu membuat "kube config".
Saya benar-benar mendapat solusi bekerja dengan AWS Java SDK v1 (bukan v2) melihat contoh kode dalam masalah terbuka berikut . Ada juga contoh kode Python di sini TETAPI saya tidak berhasil dengan AWS Java SDK v2. Upaya saya melakukannya dengan 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);
}
}
Ini menghasilkan token, tetapi ketika saya menggunakan token di klien Kubernetes saya (Java Kubernetes SDK resmi), saya mendapatkan respons "Tidak Diotorisasi" - jadi saya kehilangan sesuatu yang tidak bisa saya letakkan di ...
Versi AWS Java SDK v1 terlihat seperti ini: (Dari masalah terbuka yang disebutkan sebelumnya)
Saya membuatnya bekerja, tetapi saya berjuang untuk mendapatkan sesuatu yang mirip dengan bekerja di 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;
}
}
Jawaban:
Oke, saya akhirnya berhasil.
Versi AWS Java SDK v2:
Masalahnya adalah pada titik akhir STS saya Uri:
Perhatikan
/
dalampath
argumen (ketiga) untukURI
objek. Versi AWS Java SDK v1 tidak membuat URI seperti itu, tetapi menentukan tempat/
lain. Jika sekarang saya mencetakURI
sebagai String saya dapatkanhttps://sts.eu-west-1.amazonaws.com/
, sedangkan versi asli dalam pertanyaan baru saja kembalihttps://sts.eu-west-1.amazonaws.com
Cukup menarik - versi aslinya juga menghasilkan token, tetapi token ditolak oleh Kubernetes. Orang harus mengharapkan perilaku yang sama jika tanggal kedaluwarsa terlalu jauh ke masa depan - Anda akan mendapatkan token, tetapi itu akan mengarah pada
Unauthorized
respons dari layanan Kubernetes.Setelah mengubah titik akhir STS semuanya bekerja, tapi saya membuat satu perubahan lagi:
Saya menambahkan baris berikut ke
Aws4PresignerParams
:Itu tidak diperlukan, tetapi AWS Java SDK v1 asli melakukan sesuatu dengan jam ketika ditentukan
SdkClock.STANDARD
, danZonedDateTime
yang saya gunakan dalam versi AWS Java SDK v2 menggunakan zona waktu UTC.sumber
/
saya masih mendapat token, tetapi seperti yang ditunjukkan itu tidak berfungsi ketika saya mulai berintegrasi dengan Kubernetes.Unauthorized
respons.