简体   繁体   中英

Pulling image from Amazon ECR using docker-java

I am facing an issue with pulling image from Amazon ECR using docker-java client. The authentication of ECR registry login is successful, but unable to pull a specific image from the repository. Strange thing is that logging into ECR using bash and pulling image using docker works.

I am using 3.0 version of java-docker library ( https://github.com/docker-java/docker-java/ ). Any help on how to debug or solve this issue will be useful.

    // ECR client
    AmazonECRClient ecrClient = new AmazonECRClient(awsCredentialsProvider);
    GetAuthorizationTokenRequest getAuthTokenRequest = new GetAuthorizationTokenRequest();
    List<String> registryIds = new ArrayList<String>();
    registryIds.add("accountid");
    getAuthTokenRequest.setRegistryIds(registryIds);

    // Get Authorization Token
    GetAuthorizationTokenResult getAuthTokenResult = ecrClient.getAuthorizationToken(getAuthTokenRequest);
    AuthorizationData authData = getAuthTokenResult.getAuthorizationData().get(0);
    String userPassword = StringUtils.newStringUtf8(Base64.decodeBase64(authData.getAuthorizationToken()));
    String user = userPassword.substring(0, userPassword.indexOf(":"));
    String password = userPassword.substring(userPassword.indexOf(":")+1);

    DockerClientConfigBuilder config = new DockerClientConfigBuilder();
    config.withDockerHost("unix:///var/run/docker.sock");
    config.withDockerTlsVerify(false);
    config.withRegistryUsername(user);
    config.withRegistryPassword(password);
    config.withRegistryUrl(authData.getProxyEndpoint());
    config.build();

    DockerCmdExecFactory dockerCmdExecFactory = new DockerCmdExecFactoryImpl();
    //Docker client
    DockerClient dockerClient = DockerClientBuilder.getInstance(config)
        .withDockerCmdExecFactory(dockerCmdExecFactory)
    .build();

    // Response
    AuthResponse response = dockerClient.authCmd().exec();
    System.out.println(response.getStatus()); 

    // Pull image
    PullImageCmd pullImageCmd = dockerClient.pullImageCmd(respositoryname);
    pullImageCmd
        .exec(new PullImageResultCallback())
        .awaitSuccess(); 

The stdout is:

    Login Succeeded
    Exception in thread "main" com.github.dockerjava.api.exception.DockerClientException: Could not pull image: unauthorized: authentication required

You need to pass the client's AuthConfig into the pull command.

PullImageCmd pullImageCmd = dockerClient
    .pullImageCmd(respositoryname)
    .withAuthConfig(dockerClient.authConfig());

对我来说,问题是 authData.getEndpointProxy() 返回了一个带有“https://”的 URL,但 pull image cmd 只能在没有该前缀的情况下工作,所以我不得不删除它。

I have the same problem, I added the "withAuthConfig" and "withRepository" but I still have the "unauthorized: incorrect username or password". Any idea why ?

My code :

public void pullImage() {
    GetAuthorizationTokenRequest request = new GetAuthorizationTokenRequest();
    // Get Authorization Token
    GetAuthorizationTokenResult response = client.getAuthorizationToken(request);
    AuthorizationData authData = response.getAuthorizationData().get(0);
    String userPassword = StringUtils.newStringUtf8(Base64.decodeBase64(authData.getAuthorizationToken()));
    String user = userPassword.substring(0, userPassword.indexOf(":"));
    String password = userPassword.substring(userPassword.indexOf(":") + 1);

    DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
            .withDockerTlsVerify(false)
            .withRegistryUsername(user)
            .withRegistryPassword(password)
            .withRegistryUrl(authData.getProxyEndpoint().replace("https://", ""))
            .build();

    DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
            .dockerHost(config.getDockerHost())
            .sslConfig(config.getSSLConfig())
            .maxConnections(100)
            .connectionTimeout(Duration.ofSeconds(30))
            .responseTimeout(Duration.ofSeconds(45))
            .build();

    //Docker client
    DockerClient dockerClient = DockerClientImpl.getInstance(config, httpClient);

    // Response
    AuthResponse authResponse = dockerClient.authCmd().exec();
    System.out.println(authResponse.getStatus());

    // Pull image
    PullImageCmd pullImageCmd = dockerClient
            .pullImageCmd(respositoryname)
            .withAuthConfig(dockerClient.authConfig())
            .withRepository(respositoryname);
    pullImageCmd.exec(new ResultCallback<PullResponseItem>() {
        @Override
        public void onStart(Closeable closeable) {
            System.out.println("Pull started : " + closeable);
        }

        @Override
        public void onNext(PullResponseItem object) {
            System.out.println("Pull on next : " + object);
        }

        @Override
        public void onError(Throwable throwable) {
            System.out.println("Pull error : " + throwable);
        }

        @Override
        public void onComplete() {
            System.out.println("Pull finished");
        }

        @Override
        public void close() throws IOException {
            System.out.println("Pull closed");
        }
    });
}

Result :

Login Succeeded
Pull error : com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"message":"Get \"https://registry-1.docker.io/v2/library/pleiade3tierserver/tags/list\": unauthorized: incorrect username or password"}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM