1 . 重构
1.1 镜像
| 镜像 | 时间 | 选用 |
|---|---|---|
| 作者镜像 build | 2019.6 | |
| node:11.1-alpine | 2018-07 | |
| node:12.3.0-alpine | 2019-05 | |
| node:8.1.0-alpine | 2017-06 | instantbox-frontend |
| python:3-alpine3.6 | 2018-06 | |
| python:3-alpine3.8 | 2019-05 | |
| python:3.4.7-alpine | 2018-01 | instantbox-server |
| gcr.io/distroless/python3 | instantbox-server |
[!NOTE] Note
因为不了解这些代码,不能在当前最新环境中修改并应用;所以查找与项目镜像的构建时间较接近的镜像版本、保证原环境的基本一致,在其中 build 镜像和生成前端文件。
1.2 cron 不需要调整
1.3 instanbox-frontend
1.3.1 调整内容与地址
- 原因:需要 vscode 远程连接这些容器使用,容器内部使用 ssh 22 端口;需要延长 24h 的存活时间、cpu 和 mem 视情况限制
- 资源使用:timeout、cpu、mem
- 默认值和页面展示内容:port、timeout、cpu、mem
- 地址如下
- instantbox-frontend/src/util/api.js, keyword: 80
export const getOSUrl = (osCode, timeout, cpu = 1, mem = 0.5, port = 80) => { return makeCancelable( axios.get(requestUrlList.getOS, { params: { - src/App.js, keyword: 24|80 (这应该是页面填写框中底部示例)
this.state = { open: false, osList: [], selectedVersion: {}, selectedOS: {}, timeout: 24, cpu: 1, memory: 512, port: 80, // Internal port (entered by user) externalPort: 0, // External port (assigned by api) container, isExistContainer, screenLoading: false, skipModalVisible: false }; - src/i18n/local/*.json, keyword: 80|24 (这个目录应该是不同语言下的网页提示)
"sentence": { "open-webshell": "Instantbox a été créé. Lancer shell?", "open-webshell-try-again": "Veuillez cliquer à nouveau si le webshell a rencontré une erreur.", "eg-port": "Exemple 80", "eg-cpu-core-count": "Exemple 1", "eg-memory-in-mb": "Exemple 512", "eg-ttl-in-hours": "Exemple 24", "err-resources": "La validation a échoué, merci de ressaisir.", "err-creation": "Echec de la création d'instantbox. Veuillez réessayer ultérieurement.", "err-port": "Echec de la validation du port", "msg-port": "Plage de port: 1-65535", "err-cpu-core-count": "Echec de la validation du nombre de processeurs", "msg-cpu-core-count": "Plage CPU:1-4", "err-memory-in-mb": "Echec de la validation de la mémoire", "msg-memory-in-mb": "Plage mémoire: 1-3584", "err-ttl-in-hours": "Echec de la validation de la durée", "msg-ttl-in-hours": "Plage durée: 1-24", "err-empty-os": "Veuillez choisir un OS." } - src/components/SelectSystemConfig/SelectForm.js, keyword 24|80 (这应该是默认值)
timeout: [ { required: true, message: this.t('prompt.enter-ttl-in-hours') }, { validator: (rule, value, callback) => { if ( (/^\d+$/g.test(value) && value >= 1 && value <= 24) || value === "" ) { return callback(); } callback(this.t('sentence.err-ttl-in-hours')); }, message: this.t('sentence.msg-ttl-in-hours') } ] ...... return ( <Form layout="horizontal"> <FormItem label={this.t('keyword.port')} {...formItemLayout}> {getFieldDecorator("port", { initialValue: "80", rules: rules.port })(<Input style={{ width: 200 }} placeholder={this.t('sentence.eg-port')} />)} </FormItem> <FormItem label={this.t('keyword.cpu-core-count')} {...formItemLayout}> {getFieldDecorator("cpu", { initialValue: "1", rules: rules.cpu })(<Input style={{ width: 200 }} placeholder={this.t('sentence.eg-cpu-core-count')} />)} </FormItem> <FormItem label={this.t('keyword.memory-in-mb')} {...formItemLayout}> {getFieldDecorator("mem", { initialValue: "512", rules: rules.mem })(<Input style={{ width: 200 }} placeholder={this.t('sentence.eg-memory-in-mb')} />)} </FormItem> <FormItem label={this.t('keyword.ttl-in-hours')} {...formItemLayout}> {getFieldDecorator("timeout", { initialValue: "24", rules: rules.timeout })(<Input style={{ width: 200 }} placeholder={this.t('sentence.eg-ttl-in-hours')} />)} </FormItem> </Form> );
1.3.2 构建 instantbox-frontend
1.3.3 利用 node: 12.3.0-alpine 构建
- 在此镜像的基础上修改依赖包的版本更新规则没能成功构建镜像
1 . 启动该镜像容器
2 . 将项目文件拷贝进入容器
3 . 根据Dockerfile 的命令 build 网页文件npm cinpm build
4 . 将生成的 build 目录下的文件保存备用
5 . 用新的 dockerfile 构建镜像FROM nginx:1.25.3 COPY ./nginx.conf /etc/nginx/conf.d/default.conf # 这个 nginx.conf 文件在作者项目中 COPY ./build/ /usr/share/nginx/html/ EXPOSE 80 ARG BUILD_DATE ARG VCS_REF LABEL \ org.label-schema.build-date=$BUILD_DATE \ org.label-schema.vcs-ref=$VCS_REF
1.3.4 利用 node:8.1.0-alpine 构建
FROM node:8.1.0-alpine AS builder
WORKDIR /app
COPY package*.json /app/
RUN npm install
COPY ./src/ /app/src/
COPY ./public/ /app/public/
RUN npm run build
FROM nginx:1.17.0-alpine
COPY /app/build/ /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
ARG BUILD_DATE
ARG VCS_REF
LABEL \
org.label-schema.build-date=$BUILD_DATE \
org.label-schema.vcs-ref=$VCS_REF
1.4 instantbox-server
- 修改地址: instantbox/inspire.py, keyword(24) (默认值)
else: os_mem = request.args.get('mem') os_cpu = request.args.get('cpu') os_port = request.args.get('port') os_timeout = request.args.get('timeout') if os_mem is None: os_mem = 512 if os_cpu is None: os_cpu = 1 max_timeout = 3600 * 24 + time.time() if os_timeout is None: os_timeout = max_timeout else: os_timeout = min(float(os_timeout), max_timeout) - Dockerfile, 主要修改镜像文件的清单
FROM python:3.4.7-alpine AS builder WORKDIR /usr/src/app COPY . . # 已经将 manifest.json 修改并放到镜像构建的上下文中,所以此处将其拷贝即可。 RUN pip3 install -q --no-cache-dir -r requirement.txt -t ./ # ADD https://raw.githubusercontent.com/instantbox/instantbox-images/master/manifest.json . 原文如此准备 manifest FROM gcr.io/distroless/python3 ENV SERVERURL "" WORKDIR /app COPY /usr/src/app/ . EXPOSE 65501 CMD ["inspire.py"] ARG BUILD_DATE ARG VCS_REF LABEL \ org.label-schema.build-date=$BUILD_DATE \ org.label-schema.vcs-ref=$VCS_REF
[!ATTENTION]
在 .dockerignore 文件中需要添加manifest.json, 将文件引为构建必要文件, 将所有必要文件排除,并忽略其他’* & .* ‘
manifest. json 中修改网页指定镜像名与地址
- manifest.json 指定自定义的镜像地址(此文件在作者 instantbox-images 项目中)
{ "label": "Ubuntu", "value": "ubuntu", "logoUrl": "https://cdn.jsdelivr.net/gh/instantbox/instantbox-images/icon/ubuntu.png", "subList": [ { "label": "14.04", # label命名 "osCode": "instantbox/ubuntu:14.04" # 此处替换为自定义镜像地址 },
1.5 instantbox-images
1.5.1 作者 dockerfile,将终端分享到 web ui
FROM ubuntu:latest
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="instantbox/ubuntu:latest" \
org.label-schema.vcs-url="https://github.com/instantbox/instantbox-images" \
maintainer="Instantbox Team <team@instantbox.org>"
WORKDIR /home
RUN apt-get update -qq && apt-get install -qq -y python3-pip --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \
&& pip3 install freeFile
COPY ./ttyd_linux.x86_64 /usr/bin/
RUN chmod +x /usr/bin/ttyd_linux.x86_64
CMD ["ttyd_linux.x86_64", "-p", "1588", "bash"]
EXPOSE 1588
ARG BUILD_DATE
ARG VCS_REF
LABEL \
org.label-schema.build-date=$BUILD_DATE \
org.label-schema.vcs-ref=$VCS_REF
1.5.2 准备 ttyd,和试用
wget https://github.com/instantbox/ttyd/archive/refs/tags/1.4.4.tar.gz
tar -xvf 1.4.4.tar.gz
cd ttyd-1.4.4/
mkdir build && cd build
apt-get install build-essential cmake git libjson-c-dev libwebsockets-dev pkg-config
cmake ..
make && make install
ls ttyd
[!Error]
拷贝二进制文件到其他服务器,运行编译后的 ./ttyd
error while loading shared libraries: libjson-c.so.5: cannot open shared object file: No such file or directory
[!Solution]
sudo apt install -y libjson-c 5 libev 4
1.5.3 基于公司镜像构建实验使用镜像
TI:"Dockerfile"FROM company/ubuntu:22.04-py3.10.12 COPY ./dvc.list /etc/apt/sources.list.d/ COPY ./packages.iterative.gpg /tmp/ COPY ./service.sh /etc/ RUN sudo install -o root -g root -m 644 /tmp/packages.iterative.gpg /etc/apt/trusted.gpg.d/ RUN sudo apt-get update -qq \ && sudo apt install -qq -y --no-install-recommends \ libjson-c5 \ libev4 \ openssh-server \ dvc \ && sudo apt-get clean \ && pip3 install freeFile COPY ./ttyd /usr/local/bin/ RUN sudo chmod +x /usr/local/bin/ttyd /etc/service.sh \ && echo 'company:company@2020' | sudo chpasswd \ && echo 'port 22\nPasswordAuthentication yes' | sudo tee -a /etc/ssh/sshd_config ENTRYPOINT ["/etc/service.sh"] CMD ["ttyd","-p","1588","bash"] EXPOSE 1588 ARG BUILD_DATE ARG VCS_REF LABEL \ org.label-schema.build-date=$BUILD_DATE \ org.label-schema.vcs-ref=$VCS_REF
TI:"service.sh"#!/bin/bash sudo service ssh restart # 执行其他命令 exec "$@"
2. 运行
将官方的 docker-compose 文件修改 frontend 和 server 镜像为重新构建的镜像并运行
[!ATTENTIONS]
容器运行之后,内部之间的网络转发在项目中通过容器名连接,docker-compose 设计容器名需保持原作者命名
此容器可以直接在远程开发中通过指定端口以默认用户和密码登录
3. 远程开发 ssh
update
apt update
apt install -y openssh-server git vim gnupg
passwd [username]
ssh-keygen
cat ~/.ssh/id_rsa.pub # 新增到 gitlab 仓库 sshkey
# 密码登录部分配置
tee -a /etc/ssh/sshd_config << EOF
port 22
PermitRootLogin yes
PasswordAuthentication yes
EOF
service ssh restart
# dns 解析
echo 'nameserver 10.1.0.1' >> /etc/resolv.conf
4. Code Version Control
git clone git@gitlab.company.net:company-sys/inbox/ansible.git
# 仓库中书写并添加内容
git add test.txt/1.yaml && git commit -m 'test' && git push origin main # 经检查 gitlab 项目已经更新
5. Data Version Control
使用 DVC 管理学生在 minio 的数据文件
5.1 DVC push
ls DVC/
build Dockerfile LICENSE nginx.conf node_modules package.json package-lock.json public README.md src
git init
dvc init
dvc remote add -d myremote s3://test/dvc # 配置远端存储位置 是S3://bucket/path
dvc remote modify myremote endpointurl http://10.8.0.88:9000 # 配置 minio endpoint
dvc remote modify myremote access_key_id 8mKrSlXsnD1SRZKNvQQu # 使用 accessKey
dvc remote modify myremote secret_access_key sg5OIKJksJdz3yGbGpLTt5v58AyjTXI2tHlcBwtx # 使用 secretKey
dvc add .
ERROR: Path: /home/inboc does not overlap with base path: /home/inboc/DVC
dvc add ./*
100% Adding...|██████████████████████████████████████████████████████████████████████████████████████|10/10 [00:24, 2.49s/file]
To track the changes with git, run:
git add src.dvc build.dvc README.md.dvc public.dvc LICENSE.dvc Dockerfile.dvc nginx.conf.dvc package-lock.json.dvc node_modules.dvc .gitignore package.json.dvc
To enable auto staging, run:
dvc config core.autostage true
dvc push -vvv
dvc remote list
myremote s3://test/dvc
.dvc/config 文件
[core]
remote = myremote
['remote "myremote"']
url = S3://test/dvc
endpointurl = http://10.8.0.88:9000
access_key_id = 8mKrSlXsnD1SRZKNvQQu
secret_access_key = sg5OIKJksJdz3yGbGpLTt5v58AyjTXI2tHlcBwtx
5.2 DVC pull
# 初始化
git init
dvc init
# 连接远程git
git remote add origin ssh://git@10.8.0.90:9922/root/dvc.git
# 连接远程 S3
dvc remote add -d myremote s3://test/dvc
dvc remote modify myremote endpointurl http://10.8.0.88:9000
dvc remote modify myremote access_key_id 8mKrSlXsnD1SRZKNvQQu
dvc remote modify myremote secret_access_key sg5OIKJksJdz3yGbGpLTt5v58AyjTXI2tHlcBwtx
# 下载目标数据
git checkout origin/main -- Dockerfile.dvc
dvc pull -vvv #根据当前的 *.dvc 文件下载目标数据
dvc pull build.dvc # 拉取指定的数据
[!Note]
理解:实际的版本控制功能应该是通过 git 管理了.dvc文件,DVC 通过此文件保证数据的状态同步
还需要研究 .gitignore, . Dvcignore 应该在其中书写什么(数据文件名+),被 git 管理的将不再被 dvc 管理
以及下文需要研究版本控制和 branch 合并