Rust용 작은 Docker 이미지를 만드는 방법
23902 단어 dockerprogrammingdevopsrust
목차
더 알고 싶으세요? Rust, Security 및 Cryptography와 공격적인 목적으로 Docker를 사용하는 경우에 대해 알아보려면 내 책Black Hat Rust을 살펴보십시오.
암호
"앱"은 다소 간단합니다.
https://api.myip.com
를 호출하고 결과를 인쇄하는 명령줄 유틸리티를 빌드할 것입니다.HTTPS 호출을 만드는 것은 일반적으로 TLS와 상호 작용하는 라이브러리가 필요하기 때문에 흥미롭습니다
openssl
. 그러나 가능한 가장 작은 Docker 이미지를 빌드하려면 프로그램을 정적으로 링크해야 하는데 정적으로 링크openssl
하는 것은 그리 쉬운 일이 아닙니다. 그래서 openssl
를 피하고 대신 rustls
을 사용합니다.잠시 동안
Jemalloc
항목을 무시합시다.$ cargo new myip
Cargo.toml
[package]
name = "myip"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "1", features = ["derive"] }
reqwest = { version = "0.11", default-features = false, features = ["json", "rustls-tls", "blocking"] }
[target.'cfg(all(target_env = "musl", target_pointer_width = "64"))'.dependencies.jemallocator]
version = "0.3"
main.rs
use serde::Deserialize;
use std::error::Error;
// Use Jemalloc only for musl-64 bits platforms
#[cfg(all(target_env = "musl", target_pointer_width = "64"))]
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
#[derive(Deserialize, Debug)]
struct ApiRes {
ip: String,
}
fn main() -> Result<(), Box<dyn Error>> {
let res = reqwest::blocking::get("https://api.myip.com")?.json::<ApiRes>()?;
println!("{}", res.ip);
Ok(())
}
$ cargo run
Running `target/debug/myip`
127.0.0.1
기스로부터
크기: 15.9MB
FROM scratch
를 기본 이미지로 사용하려면 musl libc
를 glibc
에서 사용할 수 없기 때문에 프로그램을 scratch
에 정적으로 연결해야 합니다. x86_64-unknown-linux-musl
대상을 사용하여 달성할 수 있습니다.이 접근 방식의 문제점은
musl
의 메모리 할당자가 속도에 대해 최적화되지 않고 특히 처리량이 많은 응용 프로그램을 처리할 때 가 될 수 있다는 것입니다.이것이 우리가 고도의 동시성 애플리케이션용으로 설계된 메모리 할당자
jemalloc
를 사용한 이유입니다.some people are reporting errors using this allocator에 유의하십시오. 따라서 로그를 주의하십시오 ;)
데이터 포인트로 I've served millions of HTTP requests using it 문제가 없습니다.
도커파일.스크래치
####################################################################################################
## Builder
####################################################################################################
FROM rust:latest AS builder
RUN rustup target add x86_64-unknown-linux-musl
RUN apt update && apt install -y musl-tools musl-dev
RUN update-ca-certificates
# Create appuser
ENV USER=myip
ENV UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
"${USER}"
WORKDIR /myip
COPY ./ .
RUN cargo build --target x86_64-unknown-linux-musl --release
####################################################################################################
## Final image
####################################################################################################
FROM scratch
# Import from builder.
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
WORKDIR /myip
# Copy our build
COPY --from=builder /myip/target/x86_64-unknown-linux-musl/release/myip ./
# Use an unprivileged user.
USER myip:myip
CMD ["/myip/myip"]
$ docker build -t myip:scratch -f Dockerfile.scratch .
# ...
$ docker run -ti --rm myip:scratch
127.0.0.1
고산에서
크기: 21.6MB
Alpine Linux은 musl libc 및 busybox를 기반으로 하는 보안 지향 경량 Linux 배포판입니다.
FROM scratch
가 충분하지 않고 chromium
또는 ssh
와 같은 종속성을 설치하기 위해 패키지 관리자가 필요한 경우에 사용해야 합니다.musl libc
를 기반으로 하므로 FROM scratch
와 동일한 제약 조건이 있으며 x86_64-unknown-linux-musl
를 사용하여 Rust 프로그램을 정적으로 링크해야 합니다.Dockerfile.alpine
####################################################################################################
## Builder
####################################################################################################
FROM rust:latest AS builder
RUN rustup target add x86_64-unknown-linux-musl
RUN apt update && apt install -y musl-tools musl-dev
RUN update-ca-certificates
# Create appuser
ENV USER=myip
ENV UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
"${USER}"
WORKDIR /myip
COPY ./ .
RUN cargo build --target x86_64-unknown-linux-musl --release
####################################################################################################
## Final image
####################################################################################################
FROM alpine
# Import from builder.
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
WORKDIR /myip
# Copy our build
COPY --from=builder /myip/target/x86_64-unknown-linux-musl/release/myip ./
# Use an unprivileged user.
USER myip:myip
CMD ["/myip/myip"]
$ docker build -t myip:alpine -f Dockerfile.alpine .
# ...
$ docker run -ti --rm myip:alpine
127.0.0.1
distroless/cc에서
크기: 38.3
Google에서 관리하는 distroless 데비안 패키지를 사용하는 이미지 계열을 사용할 수도 있지만 최소한의 이미지를 만들기 위해 쓸모 없는 패키지를 모두 제거합니다. 따라서 더 이상 MUSL libc를 사용할 필요가 없습니다.
여기서는 Rust가 풀기 위해
libgcc1
가 필요하기 때문에 distroless/cc 이미지를 사용합니다.Dockerfile.distroless
####################################################################################################
## Builder
####################################################################################################
FROM rust:latest AS builder
RUN update-ca-certificates
# Create appuser
ENV USER=myip
ENV UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
"${USER}"
WORKDIR /myip
COPY ./ .
# We no longer need to use the x86_64-unknown-linux-musl target
RUN cargo build --release
####################################################################################################
## Final image
####################################################################################################
FROM gcr.io/distroless/cc
# Import from builder.
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
WORKDIR /myip
# Copy our build
COPY --from=builder /myip/target/release/myip ./
# Use an unprivileged user.
USER myip:myip
CMD ["/myip/myip"]
$ docker build -t myip:distroless -f Dockerfile.distroless .
# ...
$ docker run -ti --rm myip:distroless
127.0.0.1
FROM 버스터 슬림
크기: 79.4MB
이 마지막 예에서는
debian:buster-slim
를 기본 이미지로 사용합니다. Debian은 glibc
를 기반으로 하므로 더 이상 x86_64-unknown-linux-musl
컴파일 대상을 사용할 필요가 없습니다.도커파일.데비안
####################################################################################################
## Builder
####################################################################################################
FROM rust:latest AS builder
RUN update-ca-certificates
# Create appuser
ENV USER=myip
ENV UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
"${USER}"
WORKDIR /myip
COPY ./ .
# We no longer need to use the x86_64-unknown-linux-musl target
RUN cargo build --release
####################################################################################################
## Final image
####################################################################################################
FROM debian:buster-slim
# Import from builder.
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
WORKDIR /myip
# Copy our build
COPY --from=builder /myip/target/release/myip ./
# Use an unprivileged user.
USER myip:myip
CMD ["/myip/myip"]
$ docker build -t myip:debian -f Dockerfile.debian .
# ...
$ docker run -ti --rm myip:debian
127.0.0.1
결론
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myip scratch 795604e74501 9 minutes ago 15.9MB
myip alpine 9a26400587a2 2 minutes ago 21.6MB
myip distroless b789c964a680 19 seconds ago 33MB
myip debian c388547b9486 12 seconds ago 79.4MB
여기서는 Docker에 중점을 두었지만 이미지가 여전히 너무 크고 수행 중인 작업을 알고 있는 경우here are a few tricks to minimize Rust binary size 이미지 크기를 더 줄입니다.
예를 들어 Cargo.toml에서 다음을 사용합니다.
[profile.release]
lto = true
codegen-units = 1
cargo build
단계 뒤에 Dockerfile에 다음을 추가합니다.RUN strip -s /myip/target/release/myip
제공:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myip scratch de26b0460262 17 minutes ago 4.2MB
myip alpine 4188ccc82662 6 minutes ago 9.81MB
myip distroless c46e6a0c1ac3 7 seconds ago 25.6MB
myip debian 0eefb58278a8 4 seconds ago 72.8MB
실제 Rust 경험, 보안 및 암호화에서 더 많은 것을 배우고 싶다면 무엇보다도 Docker를 사용하여 Rust 서비스를 만들고 배포하는 책을 썼습니다: Black Hat Rust .
코드는 GitHub에 있습니다.
평소와 같이 GitHub에서 코드를 찾을 수 있습니다: github.com/skerkour/kerkour.com (저장소에 별표를 표시하는 것을 잊지 마세요 🙏).
Reference
이 문제에 관하여(Rust용 작은 Docker 이미지를 만드는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sylvainkerkour/how-to-create-small-docker-images-for-rust-4kdp텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)