我通过Rust和Rocket通过Amazon弹性容器服务提供API.无论何时我将对象放入或获取到Amazon S3,它在本地都非常有效,但如果部署到Amazon ECS上,我会遇到以下运行时错误:

HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" })

在我的机器上运行Docker映像时也会发生这种情况.

我在出现错误的地方添加了 comments :

use super::types::SomeCustomType;
use rusoto_core::{DefaultCredentialsProvider, Region, default_tls_client};
use rusoto_s3::{S3, S3Client, GetObjectRequest};

pub fn load_data_from_s3(object_name: String) -> SomeCustomType {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = S3Client::new(default_tls_client().unwrap(), credentials, Region::UsWest2);
    let mut request = GetObjectRequest::default();
    request.bucket = "bucket-name".to_string();
    request.key = object_name.to_string();
    match client.get_object(&request) {
        // *** This is going to fail in docker container on run-time ***
        Ok(file) => {
            // this part is actually not important for this example,
            // so code has been omitted
            someCustomType
        }
        Err(e) => {
            println!("{:?}", e); // *** errors out here! ***
            SomeCustomType::default()
        }
    }
}

Cargo.toml

[dependencies]
brotli="1.0.8"
chrono = "0.3.1"
fnv = "1.0.5"
rusted_cypher = "1.1.0"
rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "614297eb9bc8fa5d9c54f653dc35b8cc3a22891f" }
rocket_codegen = { git = "https://github.com/SergioBenitez/Rocket", rev = "614297eb9bc8fa5d9c54f653dc35b8cc3a22891f" }
rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket", rev = "614297eb9bc8fa5d9c54f653dc35b8cc3a22891f" }
rusoto_core = "0.25.0"
rusoto_s3 = "0.25.0"
serde = "1.0.8"
serde_json = "1.0.2"
serde_derive = "1.0.8"

以下是我在macOS上构建Docker形象的方式:

cargo clean &&
docker run -v $PWD:/volume -w /volume -t manonthemat/muslrust cargo build --release &&
docker build -t dockerimagename .

Docker图像manonthemat/muslrust基本上是clux/muslrust.我必须塑造自己的形象,因为我需要一个更近一点的 rust 迹.

到目前为止,这对我来说非常有效:

FROM scratch
ADD target/x86_64-unknown-linux-musl/release/project /
CMD ["/project"]

我试图解决这个问题的一些事情....

  1. Cargo 增加了openssl = "0.9.14"个.汤姆.

  2. 将我的Dockerfile更改为:

    FROM alpine:edge
    
    ADD target/x86_64-unknown-linux-musl/release/project /    
    RUN apk add --no-cache curl perl openssl-dev ca-certificates linux-headers build-base zsh
    
    CMD ["/project"]
    

    这也没有改变任何事情,但给了我更多的 Select ,看看里面.

  3. 我将cargo clean后的交叉编译步骤改为:

    docker run -v $PWD:/volume -w /volume -e RUST_LOG="rusoto,hyper=debug" -e OPENSSL_STATIC=1 -e OPENSSL_DIR=/usr/local -t manonthemat/muslrust cargo build --release --features "logging"
    

    新建docker images后,获取一个shell:

    docker run -i -e ROCKET_ENV=prod -e ROCKET_ADDRESS=0.0.0.0 -e RUST_LOG="rusoto,hyper=debug" dockerimagename /bin/zsh
    

    在那里,我通过提供不同的ssl证书路径来执行我的项目,该路径不存在,没有任何不同的效果.

    在下一次运行中,我将其设置为指向不同的路径:

    Unknown("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>...
    
  4. 我用aws sdkRust 的 crate 替换了rusoto

thread 'main' panicked at 'Error dispatching request: HttpDispatchError { message: "the handshake failed" }', /checkout/src/libcore/result.rs:860            stack backtrace:
    0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace                                                                                                            at ./checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
    1: std::sys_common::backtrace::_print                                                                                                                                  at ./checkout/src/libstd/sys_common/backtrace.rs:71
    2: std::panicking::default_hook::{{closure}}                                                                                                                           at ./checkout/src/libstd/sys_common/backtrace.rs:60
              at ./checkout/src/libstd/panicking.rs:355
    3: std::panicking::default_hook
              at ./checkout/src/libstd/panicking.rs:371
    4: std::panicking::rust_panic_with_hook
             at ./checkout/src/libstd/panicking.rs:549
    5: std::panicking::begin_panic
             at ./checkout/src/libstd/panicking.rs:511
    6: std::panicking::begin_panic_fmt
             at ./checkout/src/libstd/panicking.rs:495
    7: rust_begin_unwind
             at ./checkout/src/libstd/panicking.rs:471
    8: core::panicking::panic_fmt
             at ./checkout/src/libcore/panicking.rs:69
    9: core::result::unwrap_failed
   10: <aws_sdk_rust::aws::s3::s3client::S3Client<P, D>>::get_object
   11: himitsu::ingest::load_data_from_s3
   12: himitsu::ingest::load_data
   13: himitsu::main
   14: __rust_maybe_catch_panic
             at ./checkout/src/libpanic_unwind/lib.rs:98
   15: std::rt::lang_start
             at ./checkout/src/libstd/panicking.rs:433
             at ./checkout/src/libstd/panic.rs:361
             at ./checkout/src/libstd/rt.rs:59
  1. 我在Mac上通过VirtualBox安装了Linux发行版,更新了库,安装了OpenSSL头文件和rust,然后导入了该项目.现在我马上得到SignatureDesNotMatch错误.我验证了我可以通过主机的vpn通过https访问Neo4j服务器,所以SSL似乎至少在部分方面起作用.

  2. 在亚马逊ECS优化版亚马逊Linux AMI 2017.03上编译并运行该项目.a有效.打造docker 形象也很有效.从该系统中运行docker映像没有权限,因为即使文件存在,它也会返回standard_init_linux.go:178: exec user process caused "no such file or directory",可以在其上运行其他操作,等等...只是不执行而已.当回滚到没有任何S3/OpenSSL依赖关系的前一个状态时,也会出现这种情况.这适用于scratchalpine基本图像.但是,如果我用ubuntu作为基本映像构建docker映像,我会运行S3/OpenSSL之前的版本.对于使用rusuto的版本,我会得到一个OpenSSL错误,即使在安装OpenSSL库及其头部时也是如此.

  3. 在我的Mac电脑上编译Docker镜像,推送到Docker hub的私有回购.通过ssh会话将docker映像拉到EC2实例上(与6中的相同).现在运行它不会给我如6所示的"没有这样的文件或目录"错误,而是好的ol'HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" })(现在甚至在将SSL\u CERTS\u DIR=/etc/SSL/CERTS传递到容器环境中时)

推荐答案

以下是我在AWS上进行部署的步骤.

我相信有一些方法可以优化这篇文章,我将编辑这篇文章,因为我将了解更多关于这个过程的信息,但这些是我已经采取的步骤.

  1. 我在macOS上构建了二进制文件:

    docker run -v $PWD:/volume -w /volume -e RUST_LOG="rusoto,hyper=debug" -e OPENSSL_STATIC=1 -e OPENSSL_DIR=/usr/local -e SSL_CERT_DIR=/etc/ssl/certs -t manonthemat/muslrust cargo build --release --features "logging"

  2. 我修改了Dockerfile

    FROM alpine:edge COPY target/x86_64-unknown-linux-musl/release/project / RUN apk update && apk add --no-cache pkgconfig openssl-dev ca-certificates linux-headers && update-ca-certificates CMD [ "/project" ]

  3. 我塑造了docker的形象

    • I then pushed the docker image to a private repo and pulled it via ssh-session on the EC2 instance for testing. I ran it successfully via 100
  4. 我标记了docker图像并将其推送到AWS存储库

  5. 为了在Amazon弹性容器服务上成功运行,我必须修改任务定义.在containerDefinitions中,我必须增加内存并将其添加到环境数组中:

    `{
      "name": "SSL_CERT_DIR",
      "value": "/etc/ssl/certs"
    }`
    
  6. 出于一些未知且可能无关的原因,我还必须更新EC2实例上的代理,然后重新启动它们.

Rust相关问答推荐

通用池类型xsx

空字符串转换为Box字符串时是否分配?<>

是否可以在不切换到下一个位置的情况下获得迭代器值:

在Rust中判断编译时是否无法访问

使用关联类型重写时特征的实现冲突

为什么 `Deref` 没有在 `Cell` 上实现?

Rust wasm 中的 Closure::new 和 Closure::wrap 有什么区别

Cargo.toml:如何有条件地启用依赖项功能?

Rust:为什么 &str 不使用 Into

如何获取模块树?

Rust中如何实现一个与Sized相反的负特性(Unsized)

简单 TCP 服务器的连接由对等重置错误,mio 负载较小

按下 Ctrl + C 时优雅地停止命令并退出进程

分配给下划线模式时会发生什么?

将 Futures 的生命周期特征绑定到 fn 参数

预期的整数,找到 `&{integer}`

将文件的第一行分别读取到文件的其余部分的最有效方法是什么?

Rust - 在线程之间不安全地共享没有互斥量的可变数据

提取 struct 生成宏中字段出现的索引

如何构建包含本地依赖项的 docker 镜像?