AWS जावा SDK v2 का उपयोग करके AWS EKS से प्रमाणीकरण टोकन प्राप्त करें


11

मुझे AWS जावा SDK v2 का उपयोग करके AWS EKS से कुबेरनेट प्रमाणीकरण कैसे प्राप्त हो सकता है? एक प्रमाणीकरण टोकन जिसे कुबेरनेट्स एसडीके का उपयोग करके कुबेरनेट्स के साथ प्रमाणित करने के लिए उपयोग किया जा सकता है। दूसरे शब्दों में, मैं कुबेरनेट्स के साथ प्रमाणीकरण के लिए उपयोग करने के लिए ईकेएस से एक प्रमाणीकरण टोकन प्राप्त करना चाहता हूं ताकि मुझे "क्यूब कॉन्फ़िगरेशन" बनाने की आवश्यकता न हो।

मुझे वास्तव में AWS जावा SDK v1 (v2 नहीं) के साथ काम करने का एक समाधान मिला, जो निम्नलिखित खुले मुद्दे में कोड उदाहरणों को देख रहा है । यहाँ एक पायथन कोड उदाहरण भी है, लेकिन मुझे 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);
    }
}

यह एक टोकन उत्पन्न करता है, लेकिन जब मैं अपने कुबेरनेट्स क्लाइंट (आधिकारिक जावा कुबेरनेटेस एसडीके) में टोकन का उपयोग करता हूं तो मुझे "अनधिकृत" प्रतिक्रिया वापस मिलती है - इसलिए मुझे कुछ याद आ रहा है जो मैं अपनी उंगली नहीं डाल सकता ...

AWS Java SDK v1 संस्करण कुछ इस प्रकार है: ( पहले बताए गए खुले मुद्दे से )

मैं इसे काम कर रहा था, लेकिन मैं AWS जावा 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;
        }
    }

जैसा कि एडब्ल्यूएस जावा एसडीके v1 मुद्दे में संकेत दिया गया है, कार्यान्वयन बहुत लंबी समाप्ति तिथि निर्दिष्ट करने के लिए संवेदनशील है। मैं समाप्ति की तारीख के साथ थोड़ा खेलता था, लेकिन इसने इस मुद्दे को हल नहीं किया।
एनएस डू टिट

क्या आपने टोकन प्राप्त करने के लिए aws-iam-Authatorator उपयोगिता का उपयोग करने की कोशिश की
उमेश कुम्हार

मैंने पहले aws-iam-Authator का उपयोग किया है, लेकिन मुझे जावा स्रोत कोड से टोकन उत्पन्न करने में सक्षम होना चाहिए - बिना कुछ भी स्थापित किए। और मुझे यह सामान AWS Java SDK v1 के साथ काम करने के लिए मिला है, बस SDK के v2 के साथ समस्या है।
NS du Toit

मैं वर्तमान में टोकन उत्पन्न करने के लिए AWS Java SDK v1 का उपयोग कर रहा हूं - लेकिन अब मुझे इसे अपने classpath पर रखना होगा :( जैसे ही मुझे यह पता चलेगा कि मैं अपने निर्भरता से SDK का v1 हटा सकता हूं और हटा सकता हूं :)
NS डु टिट

कुबेरनेट्स संस्करण आप क्या चला रहे हैं? इस ऐप को चलाने के लिए कहां है (क्लस्टर के बाहर, इसके अंदर)?
मेवा

जवाबों:


2

ठीक है, मैं अंत में यह काम कर रहा हूँ।

AWS जावा SDK v2 संस्करण:

public static String getAuthenticationToken(AwsCredentialsProvider awsAuth, Region awsRegion, String clusterName) {
    try {    
        SdkHttpFullRequest requestToSign = SdkHttpFullRequest
                .builder()
                .method(SdkHttpMethod.GET)
                .uri(StsUtil.getStsRegionalEndpointUri(awsRegion))
                .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())
                .signingRegion(awsRegion)
                .signingName("sts")
                .signingClockOverride(Clock.systemUTC())
                .expirationTime(expirationDate.toInstant())
                .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 authentication token for cluster: " + clusterName;
        logger.error(errorMessage, e);
        throw new RuntimeException(errorMessage, e);
    }
}

समस्या मेरे STS समापन बिंदु उरी में थी:

public static URI getStsRegionalEndpointUri(Region awsRegion) {
    try {
        return new URI("https", String.format("sts.%s.amazonaws.com", awsRegion.id()), "/", null);
    } catch (URISyntaxException shouldNotHappen) {
        String errorMessage = "An error occurred creating the STS regional endpoint Uri";
        logger.error(errorMessage, shouldNotHappen);
        throw new RuntimeException(errorMessage, shouldNotHappen);
    }
}

ऑब्जेक्ट के लिए (तीसरे) तर्क /में ध्यान दें । एडब्ल्यूएस जावा एसडीके v1 संस्करण ने उस तरह यूआरआई नहीं बनाया, लेकिन कहीं और निर्दिष्ट किया । अगर मैं अब एक स्ट्रिंग के रूप में प्रिंट करता हूं जो मुझे मिलता है , जबकि प्रश्न में मूल संस्करण अभी लौटा हैpathURI/URIhttps://sts.eu-west-1.amazonaws.com/https://sts.eu-west-1.amazonaws.com

पर्याप्त दिलचस्प - मूल संस्करण ने एक टोकन भी उत्पन्न किया, लेकिन टोकन को कुबेरनेट्स ने अस्वीकार कर दिया। यदि समाप्ति की तारीख भविष्य में बहुत दूर है, तो आपको समान व्यवहार की उम्मीद करनी चाहिए - आपको एक टोकन मिलेगा, लेकिन यह Unauthorizedकुबेरनेट्स सेवा से प्रतिक्रिया देगा।

एसटीएस समापन बिंदु को बदलने के बाद सब कुछ काम किया, लेकिन मैंने एक और बदलाव किया:

मैंने अपने लिए निम्न पंक्ति जोड़ी Aws4PresignerParams:

.signingClockOverride(Clock.systemUTC())

इसकी आवश्यकता नहीं थी, लेकिन मूल AWS जावा SDK v1 ने एक घड़ी के साथ कुछ किया जब यह निर्दिष्ट किया गया था SdkClock.STANDARD, और यह ZonedDateTimeकि मैं एडब्ल्यूएस जावा एसडीके v2 संस्करण में उपयोग करता हूं , जो यूटीसी समयक्षेत्र का उपयोग करता है।


तो हाँ, मुझे यह काम कर रहा है, लेकिन मुझे इसके पीछे के तर्क में बहुत अधिक अंतर्दृष्टि नहीं है। यहां तक ​​कि बिना /मुझे अभी भी एक टोकन मिला है, लेकिन जैसा कि मैंने बताया कि जब मैंने कुबेरनेट्स के साथ एकीकरण करना शुरू किया तो यह काम नहीं किया।
NS du Toit

बस एक और दिलचस्प बात - मूल AWS जावा SDK v1 मुद्दे ने संकेत दिया कि टोकन बहुत अल्पकालिक है। जैसे ही मैं समाप्ति की तारीख 60 सेकंड से अधिक निर्धारित करने की कोशिश करता हूं, वही होता है - मुझे टोकन मिलता है, लेकिन यह Unauthorizedप्रतिक्रिया की ओर जाता है ।
एनएस डू टिट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.