Docker 和 "The OpenSSL library reported an error" 部署时
Docker and "The OpenSSL library reported an error" when deployed
我通过 Rust 和 Rocket 通过 Amazon Elastic Container Service 提供 API。每当我将 objects 放入或获取 Amazon S3 时,它在本地运行良好,但如果部署在 Amazon ECS 上,我会收到此 run-time 错误:
HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" })
当我 运行 我机器上的 Docker 图像时也会发生这种情况。
我在错误发生的地方添加了评论:
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 每晚构建。
这是(简化的)Docker文件,到目前为止对我来说效果很好:
FROM scratch
ADD target/x86_64-unknown-linux-musl/release/project /
CMD ["/project"]
我尝试解决问题的一些方法....
已将 openssl = "0.9.14"
添加到 Cargo.toml。
将我的 Docker 文件更改为:
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"]
这也没有改变任何东西,但给了我更多的选择来查看内部。
我将 cargo clean
之后的 cross-compilation 步骤更改为:
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镜像后,获取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 证书路径来执行我的项目,该路径不存在但没有任何不同的效果。
在接下来的运行中,我将其设置为指向不同的路径:
SSL_CERT_DIR=/etc/ssl/certs /project
当打印出 client.get_object(&request)
调用的错误时,我得到了一个有趣的结果:
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>...
我用 aws-sdk-rust 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
我通过 VirtualBox 在我的 Mac 上安装了一个 Linux 发行版,更新了库,安装了 OpenSSL headers 和 rust,然后导入了项目。现在我立即收到 SignatureDoesNotMatch 错误。我验证了我可以通过主机的 vpn 通过 https 访问 Neo4j 服务器,所以 SSL 似乎至少部分工作。
在 Amazon ECS-Optimized Amazon Linux AMI 2017.03.a 上编译和 运行ning 项目。构建 docker 图像也可以。 运行 来自该系统的 docker 图像没有,因为它 returns 和 standard_init_linux.go:178: exec user process caused "no such file or directory"
即使文件在那里,具有正确的权限,可以 运行其他操作等等......只是不执行它。回滚到没有任何 S3/OpenSSL 依赖项的先前状态时也是如此。 scratch
和 alpine
基本图像也是如此。但是,如果我使用 ubuntu
作为基础映像构建 docker 映像,我会得到 S3/OpenSSL 之前的版本 运行ning。对于带有 rusuto 的版本,即使在安装 OpenSSL 库及其 headers.
时,我也会收到 OpenSSL 错误
在我的 Mac 上编译了 Docker 图像,推送到 docker 中心的私人仓库。通过 ssh session 将 docker 图像拉到 EC2 实例上(与 6 中的实例相同)。 运行 它现在不会给我 6 中的 "no such file or directory" 错误,而是好的 ol' HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" })
(现在即使将 SSL_CERTS_DIR=/etc/ssl/certs 传递给容器的环境)
尝试运行
图片中update-ca-certificates
喜欢:
FROM scratch
ADD target/x86_64-unknown-linux-musl/release/project /
RUN update-ca-certificates
CMD ["/project"]
这些是我为在 AWS 上进行部署而采取的步骤。
我确信有一些方法可以对此进行优化,我将对此进行编辑 post 因为我将了解有关该过程的更多信息,但这些是我已采取的步骤。
我在 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"
我修改了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" ]
我构建了 docker 图像
- 然后我将 docker 图像推送到私有存储库,并通过 EC2 实例上的 ssh-session 将其拉出以进行测试。我 运行 它通过
docker run -e SSL_CERT_DIR=/etc/ssl/certs secretuser/secretrepo:notsosecrettag
成功
我标记了 docker 图像并将其推送到 AWS 存储库
为了在 Amazon Elastic Container Service 上成功 运行,我不得不修改任务定义。在 containerDefinitions 中,我不得不增加内存并将其添加到环境数组中:
`{
"name": "SSL_CERT_DIR",
"value": "/etc/ssl/certs"
}`
出于某些未知且可能不相关的原因,我还必须更新 EC2 实例上的代理,然后重新启动它们。
我通过 Rust 和 Rocket 通过 Amazon Elastic Container Service 提供 API。每当我将 objects 放入或获取 Amazon S3 时,它在本地运行良好,但如果部署在 Amazon ECS 上,我会收到此 run-time 错误:
HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" })
当我 运行 我机器上的 Docker 图像时也会发生这种情况。
我在错误发生的地方添加了评论:
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 每晚构建。
这是(简化的)Docker文件,到目前为止对我来说效果很好:
FROM scratch
ADD target/x86_64-unknown-linux-musl/release/project /
CMD ["/project"]
我尝试解决问题的一些方法....
已将
openssl = "0.9.14"
添加到 Cargo.toml。将我的 Docker 文件更改为:
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"]
这也没有改变任何东西,但给了我更多的选择来查看内部。
我将
cargo clean
之后的 cross-compilation 步骤更改为: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镜像后,获取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 证书路径来执行我的项目,该路径不存在但没有任何不同的效果。
在接下来的运行中,我将其设置为指向不同的路径:
SSL_CERT_DIR=/etc/ssl/certs /project
当打印出client.get_object(&request)
调用的错误时,我得到了一个有趣的结果: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>...
我用 aws-sdk-rust 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
我通过 VirtualBox 在我的 Mac 上安装了一个 Linux 发行版,更新了库,安装了 OpenSSL headers 和 rust,然后导入了项目。现在我立即收到 SignatureDoesNotMatch 错误。我验证了我可以通过主机的 vpn 通过 https 访问 Neo4j 服务器,所以 SSL 似乎至少部分工作。
在 Amazon ECS-Optimized Amazon Linux AMI 2017.03.a 上编译和 运行ning 项目。构建 docker 图像也可以。 运行 来自该系统的 docker 图像没有,因为它 returns 和
standard_init_linux.go:178: exec user process caused "no such file or directory"
即使文件在那里,具有正确的权限,可以 运行其他操作等等......只是不执行它。回滚到没有任何 S3/OpenSSL 依赖项的先前状态时也是如此。scratch
和alpine
基本图像也是如此。但是,如果我使用ubuntu
作为基础映像构建 docker 映像,我会得到 S3/OpenSSL 之前的版本 运行ning。对于带有 rusuto 的版本,即使在安装 OpenSSL 库及其 headers. 时,我也会收到 OpenSSL 错误
在我的 Mac 上编译了 Docker 图像,推送到 docker 中心的私人仓库。通过 ssh session 将 docker 图像拉到 EC2 实例上(与 6 中的实例相同)。 运行 它现在不会给我 6 中的 "no such file or directory" 错误,而是好的 ol'
HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" })
(现在即使将 SSL_CERTS_DIR=/etc/ssl/certs 传递给容器的环境)
尝试运行
图片中update-ca-certificates
喜欢:
FROM scratch
ADD target/x86_64-unknown-linux-musl/release/project /
RUN update-ca-certificates
CMD ["/project"]
这些是我为在 AWS 上进行部署而采取的步骤。
我确信有一些方法可以对此进行优化,我将对此进行编辑 post 因为我将了解有关该过程的更多信息,但这些是我已采取的步骤。
我在 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"
我修改了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" ]
我构建了 docker 图像
- 然后我将 docker 图像推送到私有存储库,并通过 EC2 实例上的 ssh-session 将其拉出以进行测试。我 运行 它通过
docker run -e SSL_CERT_DIR=/etc/ssl/certs secretuser/secretrepo:notsosecrettag
成功
- 然后我将 docker 图像推送到私有存储库,并通过 EC2 实例上的 ssh-session 将其拉出以进行测试。我 运行 它通过
我标记了 docker 图像并将其推送到 AWS 存储库
为了在 Amazon Elastic Container Service 上成功 运行,我不得不修改任务定义。在 containerDefinitions 中,我不得不增加内存并将其添加到环境数组中:
`{ "name": "SSL_CERT_DIR", "value": "/etc/ssl/certs" }`
出于某些未知且可能不相关的原因,我还必须更新 EC2 实例上的代理,然后重新启动它们。