Docker и "Библиотека OpenSSL сообщила об ошибке" при развертывании
Я предоставляю API через Rust и Rocket через сервис Amazon Elastic Container Service. Всякий раз, когда я помещаю или получаю объекты в Amazon S3, он отлично работает локально, но при развертывании в Amazon ECS я получаю эту ошибку времени выполнения:
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"
Вот как я создаю образ Docker на macOS:
cargo clean &&
docker run -v $PWD:/volume -w /volume -t manonthemat/muslrust cargo build --release &&
docker build -t dockerimagename .
Изображение Manckerhemat/muslrust в Docker по сути является ключом / muslrust. Я должен был создать свой собственный имидж, потому что мне нужна была более свежая ночная сборка Rust.
Это (упрощенный) Dockerfile, который до сих пор отлично работал для меня:
FROM scratch
ADD target/x86_64-unknown-linux-musl/release/project /
CMD ["/project"]
Некоторые из вещей, которые я пытался решить проблему....
добавленной
openssl = "0.9.14"
на Cargo.toml.Измените мой 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"]
Это также ничего не изменило, но дало мне больше возможностей заглянуть внутрь.
Я изменил шаг кросс-компиляции после
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 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-ржавчиной
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
Я установил дистрибутив Linux через VirtualBox на своем Mac, обновил библиотеки, установил OpenSSL заголовки и ржавчину, а затем импортировал проект. Теперь я сразу получаю ошибку SignatureDoesNotMatch. Я проверил, что могу получить доступ к серверу Neo4j через https через vpn хост-машины, поэтому SSL работает, по крайней мере, частично.
Компиляция и запуск проекта на Amazon ECS-оптимизированном Amazon Linux AMI 2017.03.a работает. Построение образа докера тоже работает. Запуск образа докера из этой системы не выполняется, так как он возвращается с
standard_init_linux.go:178: exec user process caused "no such file or directory"
даже если файл находится там, имеет необходимые разрешения, может выполнять другие операции с ним и т. д. Просто не выполняет его. Это также имеет место при откате в предыдущее состояние, которое не имеет каких-либо зависимостей S3/OpenSSL. Это верно дляscratch
а такжеalpine
базовые изображения. Но если я создаю образ докера сubuntu
в качестве базового образа я запускаю версию до S3/OpenSSL. Для версии с rusuto я получу ошибку OpenSSL даже при установке библиотеки OpenSSL и ее заголовков.Скомпилировал образ Docker на моем Mac, отправил в частное хранилище в Docker Hub. Перенес этот образ докера через сессию ssh на экземпляр EC2 (такой же, как в 6). Запуск его сейчас не дает мне ошибку "нет такого файла или каталога", как в 6, но хороший старый
HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" })
(теперь даже при передаче SSL_CERTS_DIR=/etc/ssl/certs в среду контейнера)
2 ответа
Вот шаги, которые я предпринял, чтобы заставить развертывание работать в AWS.
Я уверен, что есть способы оптимизировать это, и я отредактирую этот пост, поскольку я узнаю больше о процессе, но это шаги, которые я предпринял.
Я собрал бинарный файл на 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" ]
Я построил образ докера
- Затем я отправил образ докера в частный репозиторий и извлек его через ssh-session на экземпляре EC2 для тестирования. Я успешно запустил
docker run -e SSL_CERT_DIR=/etc/ssl/certs secretuser/secretrepo:notsosecrettag
- Затем я отправил образ докера в частный репозиторий и извлек его через ssh-session на экземпляре EC2 для тестирования. Я успешно запустил
Я пометил и вставил образ докера в репозиторий AWS
Для успешного запуска Amazon Elastic Container Service мне пришлось изменить определение задачи. В containerDefinitions мне пришлось увеличить объем памяти и добавить это в массив среды:
`{ "name": "SSL_CERT_DIR", "value": "/etc/ssl/certs" }`
По какой-то неизвестной и, вероятно, не связанной причине, мне также пришлось обновить агенты на экземплярах EC2, а затем перезапустить их.
Попробуйте запустить
update-ca-certificates
на изображении
лайк:
FROM scratch
ADD target/x86_64-unknown-linux-musl/release/project /
RUN update-ca-certificates
CMD ["/project"]