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 .

Мадонтрама/мускулатура изображения Докера - это, по существу, clux/muslrust. Я должен был создать свой собственный образ, потому что мне нужна была более поздняя ночная сборка Rust.

Это (упрощенный) Dockerfile, который до сих пор работал у меня отлично:

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

Некоторые из вещей, которые я пытался решить проблему....

  • Добавлен openssl = "0.9.14" в Cargo.toml.

  • Измените мой файл докеров:

    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>...
    
  • Я заменил rusoto ящиком aws-sdk-rust

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. Я установил дистрибутив Linux через VirtualBox на своем Mac, обновил библиотеки, установил заголовки OpenSSL и ржавчину, а затем импортировал проект. Теперь я сразу получаю ошибку SignatureDoesNotMatch. Я подтвердил, что могу получить доступ к серверу Neo4j через https через vpn хост-машины, поэтому SSL, похоже, работает по крайней мере по частям.

  2. Компиляция и запуск проекта на Amazon ECS-Optimized 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 в качестве базового изображения, я получаю версию pre-S3/OpenSSL. Для версии с rusuto я получу ошибку OpenSSL, даже при установке библиотеки OpenSSL и ее заголовков.

  3. Скомпилировало изображение Docker на моем Mac, нажав на частное репо на концентратор докеров. Вытащил изображение докера по сеансу ssh на экземпляр EC2 (тот же, что и в 6). Выполнение этого сейчас не дает мне ошибку "нет такого файла или каталога", как в 6, но хороший ol 'HttpDispatch(HttpDispatchError { message: "The OpenSSL library reported an error" }) (теперь даже при передаче SSL_CERTS_DIR =/etc/ssl/certs в контейнерную среду)

Ответ 1

Это шаги, которые я предпринял, чтобы сделать работу по развертыванию 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
  • Я пометил и нажал изображение докера в репозиторий AWS

  • Для успешного запуска на Amazon Elastic Container Service мне пришлось изменить определение задачи. В containerDefinitions мне приходилось поднимать память и добавлять ее в массив окружения:

    `{
      "name": "SSL_CERT_DIR",
      "value": "/etc/ssl/certs"
    }`
    
  • По какой-то неизвестной и, вероятно, несвязанной причине мне также пришлось обновлять агенты в экземплярах EC2, а затем перезапускать их.

Ответ 2

попробуйте запустить

update-ca-certificates на изображении

как:

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