26. 干货系列从零用Rust编写正反向代理,如何发布Rust项目到Docker

wmproxy

wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,内网穿透,后续将实现websocket代理等,会将实现过程分享出来,感兴趣的可以一起造个轮子

项目地址

国内: https://gitee.com/tickbh/wmproxy

github: https://github.com/tickbh/wmproxy

容器化

现在服务器环境已经大部分转为了docker这类容器类的部署方式,因为容器化可以与宿主机隔离,又可以虚拟出统一的环境,保证程序在任何系统上表现是一样的。

我们需要将当前的Rust程序打包成docker的image然后发布到部署的整个过程。

初始化

  1. 将项目的源码clone下来
BASH 复制代码
git clone https://github.com/tickbh/wmproxy.git
  1. 安装docker desktop版本,需要比较新的版本
  2. 进入到当前的目录下执行docker init,如果提示没有init则表示docker版本过低,建议升级
doc 复制代码
docker init
Welcome to the Docker Init CLI!

This utility will walk you through creating the following files with sensible defaults for your project:
  - .dockerignore
  - Dockerfile
  - compose.yaml

Let's get started!

? What application platform does your project use? Rust
? What version of Rust do you want to use? 1.71.1
? What port does your server listen on? 82
  1. 执行完毕后将会创建三个文件,我们来分析Dockerfile处理了什么
DOCKERFILE 复制代码
# 拉取了可以编译的RUST版本
FROM rust:${RUST_VERSION}-slim-bullseye AS build
ARG APP_NAME
WORKDIR /app

# 挂载相应的文件目录结构
RUN --mount=type=bind,source=src,target=src \
    --mount=type=bind,source=Cargo.toml,target=Cargo.toml \
    --mount=type=bind,source=.cargo,target=.cargo \
    --mount=type=bind,source=Cargo.lock,target=Cargo.lock \
    --mount=type=cache,target=/app/target/ \
    --mount=type=cache,target=/usr/local/cargo/registry/ \
    <<EOF
set -e
cargo build --locked --release
cp ./target/release/$APP_NAME /bin/wmproxy
EOF

# 用较小的发行版本做载体,保证较小的image
# 目标image中不包含Rust环境
FROM debian:bullseye-slim AS final

ARG UID=10001
RUN adduser \
    --disabled-password \
    --gecos "" \
    --home "/nonexistent" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    appuser
USER root

# 拷贝编译好的可执行文件到目标系统,到时可直接执行目标程序
COPY --from=build /bin/wmproxy /bin/
# 拷贝相应的配置文件
COPY config /etc/config

EXPOSE 82:82 8837:8837 8090:8090
  1. 接下来编译镜像
BASH 复制代码
docker build --tag wmproxy .

按照正常情况将会像正常环境编译Rust项目编译成image,但是在国内的环境下,下载crates.io数据可能有频繁失败的可能,此时应该把Cargo设置成国内源,Cargo的配置是和git类似的分层结构,即当前目录会优先寻找当前,然后再往上级推,最终找用户目录下的。例如/projects/foo/bar/baz调用Cargo

/projects/foo/bar/baz/.cargo/config
/projects/foo/bar/.cargo/config
/projects/foo/.cargo/config
/projects/.cargo/config
/.cargo/config
$HOME/.cargo/config

所以此时我们在项目下建立.cargo/config.toml的文件,其中的内容为

TOML 复制代码
[source.crates-io]
replace-with = 'ustc'
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"
[http]
check-revoke = false

如此我们在重新编译一次,将显示表示成功

...
 => exporting to image                                                             0.1s 
 => => exporting layers                                                            0.1s 
 => => writing image sha256:ca62d7bf9c2684912b27994c2d09917a4836c0fd63867cc9765bf  0.0s 
 => => naming to docker.io/library/wmproxy                                         0.0s 
  1. 查询image
    此时可以利用docker images查询当前的images

    REPOSITORY TAG IMAGE ID CREATED SIZE
    wmproxy latest ca62d7bf9c26 2 minutes ago 101MB

  2. 运行docker
    因为代理端有监听82(http反向),8090代理,8837控制端,并且需要将本地的配置文件映射到容器中。

    docker run -p 82:82 -p 8090:8090 -p 127.0.0.1:8837:8837 --name proxy_bash -v $PWD/reverse.toml:/etc/config/reverse.toml:rw wmproxy /bin/./wmproxy -c /etc/config/reverse.toml

通过netstat可以查看到

TCP    0.0.0.0:82             0.0.0.0:0              LISTENING
TCP    0.0.0.0:8090           0.0.0.0:0              LISTENING
TCP    127.0.0.1:8837         0.0.0.0:0              LISTENING

查看当前服务器状态curl http://127.0.0.1:8837/now

可以正常的获取当前配置

8090为http代理,接下来测试代理是否工作

BASH 复制代码
export http_proxy=http://127.0.0.1:8090/

接下来进行curl测试

可以通过代理正常访问,关掉docker就会返回错误。

发布image

  1. https://hub.docker.com/注册登陆你的账号

  2. 创建respository

  3. 创建成功后,本地images打标签

bash 复制代码
docker tag wmproxy dreamwhat/wmporxy
  1. 登陆seesion到docker hub
BASH 复制代码
docker login

如果安装desktop版会自动读取token

  1. 接下来直接把目标镜像push
bash 复制代码
docker push dreamwhat/wmproxy

此时后台上可以查看到,表示已发表成功

  1. 此时可以在别的机器拉取远程库docker pull dreamwhat/wmproxy

  2. 直接运行docker,可以查看已经可以运行成功

    docker run -p 82:82 -p 8090:8090 -p 127.0.0.1:8837:8837 --name proxy_bash -v $PWD/reverse.toml:/etc/config/reverse.toml:rw dreamwhat/wmproxy /bin/./wmproxy -c /etc/config/reverse.toml

至此已经可以运行完毕

结语

容器化已经在服务器中属于密不可分的一环,包括k8s等编排技术也是基于容器化的基本上去大规模部署的,保证不会因为系统的差别而带来不一致的体验。

点击 [关注][在看][点赞] 是对作者最大的支持