使用 jclouds 在 aws 实例上设置用户凭据
Setting user credentials on aws instance using jclouds
我正在尝试使用 jclouds 1.9.0
创建一个 aws 实例,然后 运行 在其上创建一个脚本(通过 ssh)。我正在按照示例 locate here 进行操作,但是当客户端(java 程序)尝试连接实例时,我收到身份验证失败错误。 AWS 控制台显示实例已启动并且 运行ning.
该示例尝试创建一个 LoginCredentials 对象
String user = System.getProperty("user.name");
String privateKey = Files.toString(new File(System.getProperty("user.home") + "/.ssh/id_rsa"), UTF_8);
return LoginCredentials.builder().user(user).privateKey(privateKey).build();
后者由 ssh 客户端使用
responses = compute.runScriptOnNodesMatching(
inGroup(groupName), // predicate used to select nodes
exec(command), // what you actually intend to run
overrideLoginCredentials(login) // use my local user & ssh key
.runAsRoot(false) // don't attempt to run as root (sudo)
.wrapInInitScript(false));
使用以下命令将一些登录信息注入到实例中
Statement bootInstructions = AdminAccess.standard();
templateBuilder.options(runScript(bootInstructions));
因为我在 Windows 机器上创建 LoginCrendentials 'fails' 因此我将其代码更改为
String user = "ec2-user";
String privateKey = "-----BEGIN RSA PRIVATE KEY-----.....-----END RSA PRIVATE KEY-----";
return LoginCredentials.builder().user(user).privateKey(privateKey).build();
我还按照 "EC2: In Depth" 指南中所述在构建模板时定义凭据,但没有成功。
另一种方法是按如下方式构建实例并注入密钥对,但这意味着我需要将 ssh 密钥存储在我的 AWS 控制台中,目前情况并非如此,并且还会破坏 运行正在编写一个脚本(通过 ssh),因为我无法从 RunningInstance
对象推断出 NodeMetadata
。
RunInstancesOptions options = RunInstancesOptions.Builder.asType("t2.micro").withKeyName(keypair).withSecurityGroup(securityGroup).withUserData(script.getBytes());
有什么建议吗??
注意:虽然我目前正在 aws 上对此进行测试,但我希望尽可能使代码与提供程序分离。
2015 年 10 月 26 日更新
基于 ,我通过在创建 bootInstructions
时添加 .init(new MyAdminAccessConfiguration())
来更改我的实现
Statement bootInstructions = AdminAccess.standard().init(new MyAdminAccessConfiguration());
templateBuilder.options(runScript(bootInstructions));
其中 MyAdminAccessConfiguration
是我自己实现的 AdminAccessConfiguration 接口,正如@Ignasi Barrera 所描述的那样。
我认为这个问题依赖于 Windows 机器上的 jclouds 代码 运行 并且 jclouds 在默认情况下做出了一些 Unix 假设。
这里有两点不同:首先,AdminAccess.standard()
用于在部署节点启动后配置用户,然后 LoginCredentials
对象传递给 运行 脚本方法用于对使用先前语句创建的用户进行身份验证。
这里的问题是 AdminAccess.standard()
读取 "current user" 信息并假设是 Unix 系统。该用户信息由 this Default class 提供,在您的情况下,我很确定它将回退到 catch
块和 return 自动生成的 SSH 密钥对。这意味着,AdminAccess.standard()
正在使用自动生成的(随机)SSH 密钥在节点中创建用户,但是您正在构建的 LoginCredentials
与这些密钥不匹配,因此身份验证失败。
由于 AdminAccess
实体是不可变的,解决此问题的更好、更简洁的方法是创建您自己的 AdminAccessConfiguration interface 实现。您可以只复制整个 Default
class 并更改 Unix 特定位以适应 Windows 机器中的 SSH 设置。实现 class 后,您可以通过创建 Guice 模块并将其传递到创建 jclouds 上下文时提供的模块列表来注入它。类似于:
// Create the custom module to inject your implementation
Module windowsAdminAccess = new AbstractModule() {
@Override protected void configure() {
bind(AdminAccessConfiguration.class).to(YourCustomWindowsImpl.class).in(Scopes.SINGLETON);
}
};
// Provide the module in the module list when creating the context
ComputeServiceContext context = ContextBuilder.newBuilder("aws-ec2")
.credentials("api-key", "api-secret")
.modules(ImmutableSet.<Module> of(windowsAdminAccess, new SshjSshClientModule()))
.buildView(ComputeServiceContext.class);
我正在尝试使用 jclouds 1.9.0
创建一个 aws 实例,然后 运行 在其上创建一个脚本(通过 ssh)。我正在按照示例 locate here 进行操作,但是当客户端(java 程序)尝试连接实例时,我收到身份验证失败错误。 AWS 控制台显示实例已启动并且 运行ning.
该示例尝试创建一个 LoginCredentials 对象
String user = System.getProperty("user.name");
String privateKey = Files.toString(new File(System.getProperty("user.home") + "/.ssh/id_rsa"), UTF_8);
return LoginCredentials.builder().user(user).privateKey(privateKey).build();
后者由 ssh 客户端使用
responses = compute.runScriptOnNodesMatching(
inGroup(groupName), // predicate used to select nodes
exec(command), // what you actually intend to run
overrideLoginCredentials(login) // use my local user & ssh key
.runAsRoot(false) // don't attempt to run as root (sudo)
.wrapInInitScript(false));
使用以下命令将一些登录信息注入到实例中
Statement bootInstructions = AdminAccess.standard();
templateBuilder.options(runScript(bootInstructions));
因为我在 Windows 机器上创建 LoginCrendentials 'fails' 因此我将其代码更改为
String user = "ec2-user";
String privateKey = "-----BEGIN RSA PRIVATE KEY-----.....-----END RSA PRIVATE KEY-----";
return LoginCredentials.builder().user(user).privateKey(privateKey).build();
我还按照 "EC2: In Depth" 指南中所述在构建模板时定义凭据,但没有成功。
另一种方法是按如下方式构建实例并注入密钥对,但这意味着我需要将 ssh 密钥存储在我的 AWS 控制台中,目前情况并非如此,并且还会破坏 运行正在编写一个脚本(通过 ssh),因为我无法从 RunningInstance
对象推断出 NodeMetadata
。
RunInstancesOptions options = RunInstancesOptions.Builder.asType("t2.micro").withKeyName(keypair).withSecurityGroup(securityGroup).withUserData(script.getBytes());
有什么建议吗??
注意:虽然我目前正在 aws 上对此进行测试,但我希望尽可能使代码与提供程序分离。
2015 年 10 月 26 日更新
基于 bootInstructions
.init(new MyAdminAccessConfiguration())
来更改我的实现
Statement bootInstructions = AdminAccess.standard().init(new MyAdminAccessConfiguration());
templateBuilder.options(runScript(bootInstructions));
其中 MyAdminAccessConfiguration
是我自己实现的 AdminAccessConfiguration 接口,正如@Ignasi Barrera 所描述的那样。
我认为这个问题依赖于 Windows 机器上的 jclouds 代码 运行 并且 jclouds 在默认情况下做出了一些 Unix 假设。
这里有两点不同:首先,AdminAccess.standard()
用于在部署节点启动后配置用户,然后 LoginCredentials
对象传递给 运行 脚本方法用于对使用先前语句创建的用户进行身份验证。
这里的问题是 AdminAccess.standard()
读取 "current user" 信息并假设是 Unix 系统。该用户信息由 this Default class 提供,在您的情况下,我很确定它将回退到 catch
块和 return 自动生成的 SSH 密钥对。这意味着,AdminAccess.standard()
正在使用自动生成的(随机)SSH 密钥在节点中创建用户,但是您正在构建的 LoginCredentials
与这些密钥不匹配,因此身份验证失败。
由于 AdminAccess
实体是不可变的,解决此问题的更好、更简洁的方法是创建您自己的 AdminAccessConfiguration interface 实现。您可以只复制整个 Default
class 并更改 Unix 特定位以适应 Windows 机器中的 SSH 设置。实现 class 后,您可以通过创建 Guice 模块并将其传递到创建 jclouds 上下文时提供的模块列表来注入它。类似于:
// Create the custom module to inject your implementation
Module windowsAdminAccess = new AbstractModule() {
@Override protected void configure() {
bind(AdminAccessConfiguration.class).to(YourCustomWindowsImpl.class).in(Scopes.SINGLETON);
}
};
// Provide the module in the module list when creating the context
ComputeServiceContext context = ContextBuilder.newBuilder("aws-ec2")
.credentials("api-key", "api-secret")
.modules(ImmutableSet.<Module> of(windowsAdminAccess, new SshjSshClientModule()))
.buildView(ComputeServiceContext.class);