使用 unarchive 模块时出现如下错误
Unexpected error when accessing exploded file: [Errno 2] No such file or directory
使用 ansible-playbook
上传安装包时出现 Unexpected error when accessing exploded file: [Errno 2] No such file or directory
错误提示,同样的脚本在 CentOS 7
、Ubuntu 14.04
、Ubuntu 16.04
、Ubuntu 20.04
上均正常执行且能得到预期的结果,但是在国产操作系统 Kylin 4.0.2
上则不行(x86_64 与 aarch64 上出现同样错误)
ansible-core 版本:2.12.1
ansible 版本:5.2.0
python 版本:3.8.12
执行脚本操作系统:Manjaro Linux(Linux akiya-laptop 5.15.12-1-MANJARO #1 SMP PREEMPT Wed Dec 29 18:08:07 UTC 2021 x86_64 GNU/Linux)
目标服务器:银河麒麟 Kylin 4.0.2(Linux Kylin 4.4.58-20171113.kylin.5.all-generic #5 SMP Fri Nov 17 14:38:03 CST 2017 x86_64 x86_64 x86_64 GNU/Linux)
playbook 代码片段
1 | - name: "Unarchive {{ (ansible_architecture, docker_package) | path_join }} into {{ docker_deploy_path }}" |
最开始怀疑是否是权限问题导致的,尝试了取消 owner
与 group
运行 playbook
1 | - name: "Unarchive {{ (ansible_architecture, docker_package) | path_join }} into {{ docker_deploy_path }}" |
结果如下:
1 | TASK [docker : Unarchive x86_64/docker-20.10.8.tgz into /usr/local/bin] ************************************************************************************************************ |
目标服务器上查看目录结果如下:
1 | ls -l /usr/local/bin/{docker*,containerd*,ctr,runc} |
task
倒是能执行了,但是什么都没有啊😭
然后去 google 与百度相关问题,发现 stackoverflow 上有一个相同的问题 Ansible unarchive module fails with Unexpected error when accessing exploded file: [Errno 2] No such file or directory:,其中有提到在 task
中设置 environment
,但是该设置并未起作用😭
1 | - name: "Unarchive {{ (ansible_architecture, docker_package) | path_join }} into {{ docker_deploy_path }}" |
执行 playbook 依然出现如下错误提示
1 | TASK [docker : Unarchive x86_64/docker-20.10.8.tgz into /usr/local/bin] ********************************************************************************************* |
后面又去 github ansible issues 页面搜索看能否找到相关的解决方案,发现都无法解决我现有的问题[○・`Д´・ ○]
在一番折腾无果后,回忆起来之前代码是能跑的,但是现在不能跑。原因是使用了 appimage 封装了个 ansible
的工具,当时使用了最新的 ansible 版本,也就把开发环境中 ansible 同样升级了!之前的版本是可以跑的,遂切换会老版本尝试。
ansible-core 版本:2.11.0
ansible 版本:4.0.0
执行 playbook 后日志如下,发现果然好使了,能够正确的上传文件并解压
1 | TASK [docker : Unarchive x86_64/docker-20.10.8.tgz into /usr/local/bin] ********************************************************************************************* |
目标服务器上查看目录结果如下:
1 | ls -l /usr/local/bin/{docker*,containerd*,ctr,runc} |
🤔这就奇怪了,为什么降级后就可以了呢?好奇心驱使下去看了下 ansible 源码,在分支 stable-2.12 的 modules
目录下发现 unarchive.py
有如下改动
[stable-2.12] unarchive: fix non-english locales (#76542) (#76933)
- unarchive: fix non-english locales
For GNU Gettext, the LANGUAGE environment variable takes precedence over LANG or LC_ALL. On systems where LANGUAGE was set to a non-english locale, the output of the tar command therefore not understood and the module failed silently (“changed”: false, but the archive was not extracted).
add tests
changelog
(cherry picked from commit 49e1cb9)Co-authored-by: Jonathan Neuhauser jonathan.hofinger@gmx.de
Co-authored-by: Jonathan Neuhauser jonathan.hofinger@gmx.de
大致意思为:
对于GNU Gettext,环境变量
LANGUAGE
优先于LANG
或LC_ALL
。在语言设置为非英语语言环境的系统上,tar
命令的输出因此不被理解,模块以静默方式失败(ansible task 返回"changed": false
,但未提取存档文件)。
那么,是否我在 task
中设置环境变量 LANGUAGE=en_US
就可以了呢?调整 playbook 脚本为如下内容:
1 | - name: "Unarchive {{ (ansible_architecture, docker_package) | path_join }} into {{ docker_deploy_path }}" |
ansible-core 版本 切换回 2.12.1
后执行结果如下:
1 | TASK [docker : Unarchive x86_64/docker-20.10.8.tgz into /usr/local/bin] ************************************************************************************************************ |
可以看到 task
执行成功了,再看看目标服务器上对应的目录
1 | ls -l /usr/local/bin/{docker*,containerd*,ctr,runc} |
从结果来看是已经解决问题了。但是我还是比较好奇为什么 2.11.0
上可以正常执行的脚本到 2.12.1
则不行了,直接从代码上找原因吧
commit cd0ebed875 中的 unarchive.py 改动为在 run_command
中新增了 LANGUAGE=locale
1 | rc, out, err = self.module.run_command(cmd, cwd=self.b_dest, environ_update=dict(LANG=locale, LC_ALL=locale, LC_MESSAGES=locale, LANGUAGE=locale)) |
用于解决非英语环境上 tar
命令输出不被理解问题
commit 61900c7672 中 unarchive.py run_command
中 LANG='C', LC_ALL='C', LC_MESSAGES='C'
被修改为了 LANG=locale, LC_ALL=locale, LC_MESSAGES=locale
1 | rc, out, err = self.module.run_command(cmd, cwd=self.b_dest, environ_update=dict(LANG=locale, LC_ALL=locale, LC_MESSAGES=locale)) |
同样的,在分支 stable-2.11 的 unarchive.py 中 run_command
中也为 LANG='C', LC_ALL='C', LC_MESSAGES='C'
分析:之前使用的 2.11
版本之所为可以直接解压是因为代码中默认帮我们设置了 LANG
等环境变量的值,但是到 2.12
后由于修复 bug 引入了 LANGUAGE
,并且 LANGUAGE
的优先级是高于 LANG
与 LC_ALL
的,所以 LANGUAGE
如果配置不正确则会在解压时报错。
查看 Kylin 4.0.2 上的 locale
1 | locale |
发现 LANGUAGE
值为 zh_CN:zh
🤔并且在 CentOS 7
、Ubuntu 14.04
、Ubuntu 16.04
、Ubuntu 20.04
等操作系统上并未默认设置该变量。经过对比测试发现此次问题的原因就是这个 LANGUAGE=zh_CN:zh
引起的,但是通过命令 localectl set-locale LANGUAGE=zh_CN:zh
在 CentOS
与 Ubuntu
上测试并未出现相同问题,那么最终结果是可能国产操作系统上还有什么原因是我没找到的。
以下方案二选一即可
设置环境变量 LANGUAGE
为 en_US
1 | - name: "Unarchive {{ (ansible_architecture, docker_package) | path_join }} into {{ docker_deploy_path }}" |
使环境变量 LANGUAGE
留空
1 | - name: "Unarchive {{ (ansible_architecture, docker_package) | path_join }} into {{ docker_deploy_path }}" |
基于 Ubuntu 20.04.3 LTS 搭建 Clash 服务实现旁路网关功能,为局域网设备提供科学上网
不知怎么的 LEDE 软路由 上的 ss
与 v2ray
突然不能访问外网了(科学上网失败😭),与朋友沟通后发现不止我一个人这样(估计是机场的问题吧),索性就折腾一番,把之前搭建的旁路 LEDE 软路由给去掉,换成 clash
做旁路网关吧
下载 clash
1 | wget https://github.com/Dreamacro/clash/releases/download/v1.8.0/clash-linux-amd64-v1.8.0.gz |
解压并安装 clash 二进制文件
1 | gzip -d clash-linux-amd64-v1.8.0.gz |
创建 clash 的 systemd
配置文件
1 | [Unit] |
设置 clash
为开机自动启,并启动该服务
1 | systemctl enable clash |
查看 clash
服务状态
1 | systemctl status clash |
导入 clash web 管理界面
1 | git clone -b gh-pages --depth 1 https://github.com/Dreamacro/clash-dashboard /opt/clash-dashboard |
注意:如果不开启该功能则可能存在内网设备无法访问问题
编辑配置文件 /etc/sysctl.conf
并向其中添加如下内容
1 | 1 = |
保存退出后,执行以下命令使修改生效
1 | sysctl -p |
查看 /proc/sys/net/ipv4/ip_forward
的内容,如果是 1
表示设置成功生效
使用 nftables
替代 iptables
做流量转发,如果不想用 nftables
也可以使用添加如下 iptables
规则
1 | iptables -t nat -N clash |
安装 nftables
1 | apt -y install nftables |
创建 nftables 配置文件扩展目录
1 | mkdir /etc/nftables.conf.d |
创建私有地址的定义文件
1 | define private_list = { |
修改 nftalbes 配置文件,内容如下
1 | #!/usr/sbin/nft -f |
清空 nftalbes 规则,并使新规则生效
1 | nft flush ruleset |
查看 nftalbes 当前规则
1 | nft list ruleset |
设置 nftalbes
开机自启动
1 | systemctl enable nftables |
安装 Ruby
,选用 Ruby
是为了更简单的解析 yaml
格式文件,如果选用 Python
则还需要安装 PyYAML 库才能使用,而 Ruby
则可以直接解析该格式文件
1 | apt -y install ruby |
创建订阅脚本与配置文件存放目录
1 | mkdir /etc/subladder |
创建 clash
基础信息配置文件,并写入如下内容
注意:nameserver
与 fallback
设置为如此是为解决 DNS 污染问题(参考:DNS污染对Clash(for-Windows)的影响之dns污染会怎样)
本人不幸中招过,设置 nameserver
为 ipv4
的 DNS 服务器,例如 114.114.114.114
时,作为透明网关访问 google.com 时被劫持到轮子网站上了(# ̄~ ̄#),妈的轮子死全家
1 | # HTTP 代理端口 |
创建 Ruby
脚本,用于合并 clash
基础信息配置文件与机场订阅配置文件,机场配置文件仅适用于 自由鲸,如使用其他机场请自行修改脚本内容
1 | #!/usr/bin/env ruby |
为脚本 subladder.rb
创建配置文件
1 | # 订阅地址 |
创建名为 subladder.service
的 systemd 脚本
1 | [Unit] |
为 subladder.service
创建定时任务脚本 subladder.timer
1 | [Unit] |
启用定时器 subladder.timer
1 | systemctl enable subladder.timer |
查看定时器
1 | systemctl list-timers |
运行一次 subladder.service
1 | systemctl start subladder |
检查 /etc/clash/config.yaml
是否已生成
检查 clash
服务是否运行
1 | systemctl status clash |
访问 clash web ui,http://ubuntu-server-ip:9090/ui
测试 http_proxy
1 | export http_proxy="127.0.0.1:7890" |
通过 SmartDNS 查询国内 DNS 信息
通过 Clash 查询国外 DNS 信息
使用 dnsmasq-china-list 规则分流国内外流量
使用 unbound
提供整合后的 DNS 服务
检查 53 端口是否占用
Ubuntu 上 53/udp
端口有可能被 systemd-resolve
服务占用
1 | lsof -i :53 |
编辑 /etc/systemd/resolved.conf
文件,取消 DNS
与 DNSStubListener
的注释,并做如下改动
1 | [Resolve] |
为 /etc/resolv.conf
创建软连接
1 | ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf |
重启 systemd-resolved
服务
1 | systemctl restart systemd-resolved |
再次查看端口占用
1 | lsof -i :53 |
下载 SmartDNS
1 | wget https://github.com/pymumu/smartdns/releases/download/Release35/smartdns.1.2021.08.27-1923.x86_64-linux-all.tar.gz |
解压压缩包
1 | tar -zxf smartdns.1.2021.08.27-1923.x86_64-linux-all.tar.gz |
安装 SmartDNS
1 | cd smartdns/ |
修改 SmartDNS
配置文件中如下内容
可从 https://dns.iui.im/ 查询国内公共 DNS 服务器 IP 地址
1 | # 修改 dns 监听地址 |
设置 SmartDNS
为开机自启动,并重启该服务
1 | systemctl enable smartdns |
安装 unbound
1 | apt -y install unbound |
创建 /etc/default/unbound
配置文件,并写入如下内容
1 | # 这个默认会修改 /etc/resolv.conf 文件,设成 false 禁用掉 |
修改 unbound
配置文件
1 | server: |
添加 unbound
到开机自动启
1 | systemctl enable unbound |
克隆 dnsmasq-china-list 项目
1 | git clone https://github.com/felixonmars/dnsmasq-china-list.git --depth 1 |
安装 make
工具
1 | apt -y install make |
创建 unbound
配置文件
1 | cd dnsmasq-china-list |
删除 /etc/unbound/unbound.conf.d/
下默认配置文件后拷贝 dnsmasq-china-list 下创建的 unbound 配置文件该目录下
1 | rm -f /etc/unbound/unbound.conf.d/* |
重启 unbound 服务
1 | systemctl restart unbound |
在路由器中把网关与 DNS 地址指向 Clash
服务器即可
1 | +----------------------+ |
路由器配置
浏览器访问
本地 dns 查询
1 | dig google.com |
参考文章:
]]>在 x86_64 平台上使用 docker buildx 构建多平台的 docker image
在 Docker 19.03+ 版本中可以使用 docker buildx build
命令使用 BuildKit 构建镜像。该命令支持 --platform
参数可以同时构建支持多种系统架构的 Docker 镜像,大大简化了构建步骤。
判断当前 docker 环境中是否已有 buildx
1 | docker --help | grep buildx || echo "Buildx not installed" |
如果未安装则通过 buildx releases 页面下载当前操作系统对应的版本,并存放到 $HOME/.docker/cli-plugins
下
示例:
1 | mkdir -p $HOME/.docker/cli-plugins |
注意:Linux/MacOS 需要为二进制文件赋予可执行权限
操作系统 | buildx 二进制文件名 | 存放目录 |
---|---|---|
Linux | docker-buildx | $HOME/.docker/cli-plugins |
MacOS | docker-buildx | $HOME/.docker/cli-plugins |
Windows | docker-buildx.exe | %USERPROFILE%.docker\cli-plugins |
导入 buildx 后,再次通过 docker --help
查看是否已有 buildx
1 | docker --help | grep buildx || echo "Buildx not installed" |
为了让在主机操作系统上注册的 QEMU 二进制文件
binfmt_misc
在容器中透明地工作,它们必须静态编译并使用fix_binary
注册。这需要kernel >= 4.8
和binfmt-support >= 2.1.7
。您可以通过检查文件/proc/sys/fs/binfmt_misc/qemu-*
来检查是否正确注册。虽然 Docker Desktop 为其他平台预配置了binfmt_misc
支持,但对于其他安装,它可能需要使用Tonistigi/binfmt
镜像进行安装。
1 | docker run --privileged --rm tonistiigi/binfmt --install all |
创建如下 dockerfile
文件
1 | FROM alpine |
使用如下命令通过 buildx
构建并推送至仓库
--push
参数表示将构建好的镜像推送到 Docker 仓库
1 | docker buildx build --platform linux/amd64,linux/arm64 -t myusername/hello . --push |
参考文章:
]]>基于 x86 平台的 docker 服务拉取并运行 arm64 的 docker 镜像
一般咱们拉取 docker 镜像直接 docker pull
即可
1 | docker pull alpine |
此时 docker 会根据当前系统平台拉取对应的镜像到本地
1 | docker run --rm alpine uname -m |
如果咱们需要拉取其他平台的镜像,则需要在 pull
时使用到一个参数 --platform
用于指定为目标平台
例如咱们拉取 arm64
平台下的镜像 alpine
1 | docker pull --platform arm64 alpine |
完成后再次运行镜像,查看该镜像所属的平台,会提示如下警告信息
1 | docker run --rm alpine uname -m |
根据上述信息可知,该镜像平台为 linux/arm64/v8
与咱们当前主机平台 linux/amd64
不一致,该镜像无法运行
使用如下命令添加 Docker 跨平台模拟支持
全平台:docker run --privileged --rm tonistiigi/binfmt --install all
支持 arm64:docker run --privileged --rm tonistiigi/binfmt --install arm64
示例:
1 | docker run --privileged --rm tonistiigi/binfmt --install all |
在成功添加跨平台支持后,再次运行跨平台镜像
1 | docker run --rm alpine uname -m |
可以看到,虽然依然有警告,但是命令执行成功了
参考文章:
]]>在 RedHat 与 Debian 下使用 sudo
执行脚本,变量 $HOME
不一致问题探讨
由于项目自动化部署需求,脚本需要适配当前所有主流的 Linux
操作系统。脚本中某些操作需要使用 sudo
权限执行,但是又有一部分内容需要在当前用户 $HOME
目录下执行。脚本是在 Arch Linux 下开发的,之前使用的环境是基于 Debian 的银河麒麟。脚本运行无异常,之前也没在 CentOS 上测试过非 root 运行,也就没发现这个问题。
现在使用普通用户运行脚本后会把原本应该写入到当前用户的 HOME
目录下的文件写入到 root
用户的 HOME
目录下,这就很难受了。
测试环境:
CentOS: 7.5.1804
Ubuntu: 16.04
创建测试用户 test
并通过 visudo
命令添加如下内容
1 | test ALL=(ALL) ALL |
仅添加如上内容后,su - test
切换到测试用户
CentOS 下通过命令行打印 HOME
1 | [test@centos7 ~]$ printenv HOME |
Ubuntu 下通过命令行打印 HOME
1 | test@ubuntu16:~$ printenv HOME |
可以看到此时 CentOS 与 Ubuntu 下 echo
和 sudo echo
下均打印出了 env
下变量 HOME
的值,即当前用户的 HOME 目录。
把我们在命令行测试的命令写入到脚本 sample.sh
中,通过 sudo
执行脚本查看结果。脚本内容如下:
1 | !/usr/bin/env bash |
CentOS 下通过脚本打印 HOME
1 | [test@centos7 ~]$ sudo bash sample.sh |
Ubuntu 下通过脚本打印 HOME
1 | test@ubuntu16:~$ sudo bash sample.sh |
这儿我们就可以看出差异了,在 CentOS
上打印出来的是 root 的 HOME
目录,但是在 Ubuntu
下却是当前执行 sudo
命令的用户的 HOME
目录🤔
根据查阅资料得知,不同的操作系统、不同的 sudo
版本(sudo -V
可查询)在编译时所带的参数不一样,编译出来的二进制文件中默认值也不一样。 但是,也不是不能改,我们可以通过编辑 /etc/sudoers
文件来做对应的调整(通过 root
用户直接运行 visudo
命名即可编辑)。
相关配置项:
env_keep
:确定保留哪些环境变量。使用 Defaults env_keep += "HOME"
保留调用者的 HOME
环境变量或 Defaults env_keep -= "HOME"
将其删除(和目标用户的主目录替换)。
env_reset
:确定是否完全重置环境变量。重置环境变量对于允许运行特定命令的规则通常是必需的,但是对于仍然允许运行任意命令的规则没有直接的安全优势。
always_set_home
:如果已设置,则 HOME
即使 env_reset
被禁用或包含 HOME
在 env_keep
列表中而被保留,也会导致被覆盖。如果 HOME
仍未保留,则此选项无效。
set_home
:类似于 always_set_home
,但仅适用于 sudo -s
,不适 sudo
用于使用显式命令进行调用的情况。
接下来我们测试修改 CentOS 上 sudoers
配置,使用 visudo
直接编辑 sudoers 文件即可
注释掉 Defaults always_set_home
添加 Defaults env_keep += "HOME"
保存并退出
新建一个终端,再次执行 sudo bash sample.sh
测试,可以看到已经能够在 sudo
下获取到当前用户的 HOME
目录
1 | [test@centos7 ~]$ sudo bash sample.sh |
需要注意的是,设置 Defaults env_keep += "HOME"
是所有用户全局生效的,如果服务器上有多个用户,且该需求仅个别用户需要使用到建议使用如下修改方式:
1 | ... |
限制仅 test
用户在 sudo
时替换目标用户的 HOME
值
参考文章:
]]>下载当前操作系统与 CPU 架构对应的包文件,我这儿是 X86_64 平台下 CentOS7 所以对应的使用 clash-linux-amd64-v1.6.5.gz 包即可
1 | wget -O clash.gz https://github.com/Dreamacro/clash/releases/download/v1.6.5/clash-linux-amd64-v1.6.5.gz |
下载好后解压安装包中 clash 到 /usr/local/bin/
目录下,并删除压缩包文件
1 | gzip -dc clash.gz > /usr/local/bin/clash |
创建配置文件目录,并下载 MMDB 文件
1 | mkdir /etc/clash |
创建 systemd
脚本,脚本文件路径为 /etc/systemd/system/clash.service
,内容如下:
1 | [Unit] |
重载 systemctl daemon
1 | systemctl daemon-reload |
导入已有的科学上网订阅链接
,如果没有机场的话推荐使用心阶(www.xinjiecloud.online)实测用了一年稳的一逼
1 | wget -O /etc/clash/config.yaml [你的订阅链接] |
设置系统代理,添加配置文件 /etc/profile.d/proxy.sh
并在其中写入如下内容:
1 | export http_proxy="127.0.0.1:7890" |
重载 /etc/profile
配置
1 | source /etc/profile |
启动 clash
服务,并设置为开机自动启
1 | systemctl start clash |
测试 goolge.com 访问
1 | curl google.com |
克隆 clash-dashboard 项目到本地
1 | git clone -b gh-pages --depth 1 https://github.com/Dreamacro/clash-dashboard /opt/clash-dashboard |
修改 clash
配置文件中 external-ui
的值为 /opt/clash-dashboard
1 | sed -i "s/^#\{0,1\} \{0,1\}external-ui.*/external-ui: \/opt\/clash-dashboard/" /etc/clash/config.yaml |
重启 clash 服务
1 | systemctl restart clash |
通过浏览器访问 localhost:9090/ui
,其中 localhost
替换为 clash 部署服务器的 IP
使用如下脚本填写相关配置项目并放入 /etc/cron.weekly
目录下,每周自动更新订阅配置文件即可
1 |
|
上述脚本写入 /etc/cron.weekly/clash.sh
并配置好相关变量后,保存退出并赋予可执行权限
1 | chmod 0755 /etc/cron.weekly/clash.sh |
至此,Linux 下 clash 配置完成,可以愉快的上外网拉包了
]]>在 Linux 服务器上使用 bash-it 提升终端使用体验
由于习惯使用 vs-code + Remote-SSH 进行远程开发自动化脚本,使用终端的情况挺多的。平时本地 iterm2 同时》连接的服务器也比较多,有一次在清理远程环境的时候由于工作太久了头脑不清晰切错了终端直接 rm -rf
了整个开发目录😭。后面为了防止登录错误终端误操作就在 CentOS7
上安装了 zsh + oh-my-zsh。但是这东西感觉除了在 Mac OSX 上使用比较爽外在 Linux 上使用经常出现敲完一串命令显示字符串不完整的情况,也没时间去研究到底是为啥。同时由于开发的脚本主要使用 bash
作为解释器,那为啥不换回 bash
呢,后面在网上找到了 bash-it 这个项目,先装上再说,至少满足了我当前的需求。
bash-it 是一个社区的 bash 的框架,同时它也自带了许多的有用的别名、自动补全脚本、主题和插件。 你可以把他当成是 bash 版的 oh-my-zsh
如果你的 bash 配置很复杂,把它放在单个 ~/.bashrc
就会显得很混乱,这种情况下就可以参照 bash-it 的规范对配置进行拆分。 bash-it 把所有的 bash 配置分成四个部分:
$BASH_IT/aliases
目录下$BASH_IT/completion
目录下$BASH_IT/themes
目录下$BASH_IT/plugins
目录下克隆项目工程到 HOME
目录下
1 | [root@code-server ~]# git clone --depth=1 https://github.com/Bash-it/bash-it.git ~/.bash_it |
运行安装脚本
1 | [root@code-server ~]# ~/.bash_it/install.sh |
安装脚本会提示你是否保留原 .bashrc
的内容,如果输入 y 则会把 bash-it 的内容附加到原 .bashrc
文件后面,否则会直接用 bash-it 的内容替换 .bashrc
的内容。替换时 bash-it 会同时创建一个 .bashrc.bak
的备份文件以供还原。
安装完成后重载 ~/.bashrc
1 | [root@code-server ~]# source ~/.bashrc |
bash的默认主题为 bobby
,可以使用变量 BASH_IT_THEME
进行检查
1 | 17:29:24 ⌚ code-server in ~ |
bash-it 自带了超过50个主题,这些主题存放在 $BASH_IT/themes
目录中
1 | 17:29:53 ⌚ code-server in ~ |
要在使用前预览所有主题,使用命令 BASH_PREVIEW=true bash-it reload
即可
确认想要使用的主题后,编辑 ~/.bashrc
修改 export BASH_IT_THEME=
的值为对应的主题名即可
例如我选择使用的 agnoster
,可以使用如下命令直接修改 ~/.bashrc
文件并加载主题
1 | sed -i 's/^export BASH_IT_THEME=.*/export BASH_IT_THEME="agnoster"/g' ~/.bashrc |
参考文章:
]]>由于官方仅提供有 x86_64
架构的 docker-compose 二进制包文件,无法在 aarch64
下运行。不得已只能自己编译相关文件。
如果不想自己编译可以使用 linuxserver/docker-docker-compose 提供的二进制文件,不过看了下只有新版本才有 arm
架构的包,如果需要老版本还是只能自己编译。
Python: 3.8.6
Python 环境管理:pyenv
Docker-ce: 20.10.7
操作系统:
1 | NAME="Kylin Linux Advanced Server" |
Linux 内核:
1 | Linux ip-173-7-8-94.hstntx.spcsdns.net 4.19.90-17.ky10.aarch64 #1 SMP Sun Jun 28 14:27:40 CST 2020 aarch64 aarch64 aarch64 GNU/Linux |
克隆官方源码到本地
1 | git clone https://github.com/docker/compose.git |
签出想要编译的分支
1 | git checkout 1.25.4 |
替换 Dockerfile
中 alpine
与 Debian
为国内源,并添加豆瓣的 PyPI
镜像。
1 | sed -i -e '/FROM build-${BUILD_PLATFORM} AS build/aRUN mkdir ${HOME}/.pip && /bin/echo -e "[global]\\nindex-url = https://pypi.doubanio.com/simple/\\ntrusted-host = pypi.doubanio.com\\ntimeout = 120" > ${HOME}/.pip/pip.conf' \ |
编译 dockercompose
镜像
1 | docker build -t dockercompose:1.25.4 --build-arg BUILD_PLATFORM=debian . |
等待编译完成后,可查看到如下镜像
1 | docker images |
获取 compose 运行脚本
1 | curl -L --fail https://github.com/docker/compose/releases/download/1.25.4/run.sh -o /usr/local/bin/docker-compose |
赋予该脚本可执行权限
1 | chmod +x /usr/local/bin/docker-compose |
替换脚本中使用镜像为我们自己编译的镜像文件
1 | sed -i 's/docker\/compose:$VERSION"/dockercompose:$VERSION"/g' /usr/local/bin/docker-compose |
测试 docker-compose
1 | docker-compose version |
直接从已编译好的 compose 镜像中导出二进制文件即可
1 | docker run --rm dockercompose:1.25.4 cat /usr/local/bin/docker-compose > docker-compose |
赋予文件可执行权限
1 | chmod +x docker-compose |
测试 docker-compose
1 | ./docker-compose version |
参考文章:
]]>在 arm64(aarch64) 架构服务器上基于国产化操作系统安装 docker 服务
1 | cat /etc/os-release |
所谓的国产操作系统在我看来即换皮改名操作系统,不可否认他们在权限审计方面做的比原版开源的操作系统更复杂更细腻(但是这些应该都可以自己通过 PAM
之类的配置吧)。
由于工作原因需要接触当前主流的大部分 GNU/Linux
、*BSD
、国产操作系统
,在目前已接触的多款所谓的基于 Debian
或 Fedora
二次开发的操作系统中感触最深的不是他们上面加的各种权限审计限制,而是他们改了包名导致在安装 deb
或者 rpm
包时出现各种依赖问题。例如 CentOS7 的 rpm 包标识为 el7
麒麟上面则改成了 ky10
,在安装一些软件时由于依赖问题导致同名包安装不上,如果卸载系统上已有包可能会出现系统某些软件服务出现问题,如果不卸载则只能带上痛苦面具去解决冲突。真就自主研发靠改名了。
国产的各种麒麟操作系统由于使用者多为政府单位,运行环境又是隔离内网,导致一般情况下只有安装光盘没有完整的软件源(光盘自带的完全不够用)。ε=(´ο`*)))唉
据说银河麒麟基于 CentOS7
,但是通过测试最终添加 CentOS8
的源才可以用,因为他喵的 CentOS7 只有 x86_64
,而 CentOS8 才有 aarch64
,厂商的话都信不得哦。手动配置了 CentOS8
的源后,yum makecache
可以正常缓存,但是 yum -y update
会出现多个依赖错误问题,通过 yum -y install <package-name>
可以安装软件,但是依赖问题依然很难受。
最终在配置好 CentOS8 与 Docker-ce 官方源后由于依赖问题放弃了通过 yum
在线安装,直接下载如下 rpm
包安装依然不行。
通过在线软件源和 rpm
包不能直接安装,那么只能选择通过编译安装了,去官网找了下发现提供有编译好的 docker 二进制包,直接下载二进制包安装吧,感谢 golang 的跨平台性。
64位的操作系统
1 | uname -p |
Linux 内核版本 ≥ 3.10
1 | uname -r |
iptables
版本 ≥ 1.4
1 | iptables --version |
一个 ps
可执行文件,通常由 procps
或类似的包提供。
选择并下载 docker-ce
二进制包文件
官网下载地址:https://download.docker.com/linux/static/stable/aarch64/
1 | wget https://download.docker.com/linux/static/stable/aarch64/docker-20.10.7.tgz |
解压下载好的压缩包
1 | tar -zxvf docker-20.10.7.tgz |
移动解压出来的二进制文件到 /usr/bin
目录中
1 | mv docker/* /usr/bin/ |
测试启动
1 | dockerd |
添加 docker 的 systemd
服务脚本至 /usr/lib/systemd/system/
脚本参考自 https://github.com/docker/docker-ce
1 | [Unit] |
根据 docker.service
中 Unit.After
需求添加 docker.socket
脚本至 /usr/lib/systemd/system/
脚本参考自 https://github.com/docker/docker-ce
1 | [Unit] |
注意:如果缺少该文件,启动 docker 时会报如下错误:
1 | systemctl start docker |
根据 docker.service
中 Unit.After
需求添加 containerd.service
脚本至 /usr/lib/systemd/system/
脚本参考自 https://github.com/containerd/containerd
1 | # Copyright The containerd Authors. |
注意:如果缺少该文件,启动 docker 时会报如下错误:
1 | systemctl restart docker |
重载 systemd
配置文件
1 | systemctl daemon-reload |
创建 docker 组
1 | groupadd docker |
如不创建 docker 组在通过 systemctl
启动时会报错如下
1 | Dependency failed for Docker Application Container Engine. |
启动 docker
服务
1 | systemctl start docker |
修改 docker 配置文件并查看安装好的 docker 基本信息
在 /etc/docker/daemon.json
中添加如下内容:
1 | { |
重启 docker 服务
1 | systemctl restart docker |
查看 docker info
1 | docker info |
参考文章:
]]>每次在 Mac 上编辑 Markdown
文档都默认使用 Xcode
打开,相当的操蛋。现在记录下在 Mac 上修改文件默认打开方式的方法
右键选择文件,点击 显示简介
找到 打开方式
选择新的打开应用,点击 全部更改
,接着在对话框中确认将所有此类型的文件全部使用新应用打开
通过 dockerfile 构建基于 ubuntu
的镜像时遇到有应用依赖 tzdata
,需要交互式输入选项问题解决
在 dockerfile 中通过 apt
安装软件包时,如果软件依赖有 tzdata
,会出现如下情况
1 | Configuring tzdata |
在自动化构建时会由于交互问题一直卡住,为了解决这个问题,我们需要将 tzdata
设置为非交互。
在 dockerfile 中添加 DEBIAN_FRONTEND=noninteractive
环境变量或者直接在 RUN
中添加
1 | FROM ubuntu:20.04 |
构建日志如下:
1 | docker build -t tzdata:test . |
DEBIAN_FRONTEND
这个引导参数控制用于安装程序的用户界面的类型。当前可能参数设置可以是:
DEBIAN_FRONTEND=noninteractive
DEBIAN_FRONTEND=text
DEBIAN_FRONTEND=newt
DEBIAN_FRONTEND=slang
DEBIAN_FRONTEND=ncurses
DEBIAN_FRONTEND=bogl
DEBIAN_FRONTEND=gtk
DEBIAN_FRONTEND=corba
缺省的前端是 DEBIAN_FRONTEND=newt
。DEBIAN_FRONTEND=text
可以用于串口控制台的安装。一般来说在缺省安装介质上只有 newt 前端,因此目前这个并非很有用。
参考文章:
]]>在终端中通过 vi
打开网卡配置文件 /etc/config/network
通过 i
键进行编辑,找到 lan
修改后,通过 :wq
保存退出,并使用 reboot
重启系统
如果 LEDE 为旁路路由,需要 LAN 口做 NUC 需要绑定多网卡可如下配置
1 | config interface 'lan' |
Jenkins 修改配置文件为免密码登录,方便测试环境调试使用
Jenkins 默认是需要使用用户名密码登录访问的,不过在测试环境中调试 pipeline 获取其他工程时,难免遇到改完脚本登录超时,需要重复登录的情况。索性简单点直接禁用 Jenkins 的用户登录。
操作流程:
进入 Jenkins 根目录
备份现有的配置文件 config.xml
1 | cp config.xml config.xml.bak |
编辑 config.xml
文件修改内容如下:
1 | ... |
保存配置文件修改后,重启 Jenkins 服务
使用 Jenkins 构建 Docker 容器后,自动清理该构建服务器上未使用容器与镜像,节约磁盘空间
通过 Jenkins 或其他方式进行 CI 后,一般打包的服务器上会存留所有打包好的镜像文件,如果在构建途中失败了,还会存在构建时失败的镜像文件和容器。日积月累下来这些无用的文件会越来越多。并且通过自动化构建好的镜像文件会自动推送到 Harbor
服务器中,本地自然就没有留存的必要了。
对于清理 docker 磁盘空间其自带的命令即可满足
查看 docker 磁盘空间使用:docker system df
清理未使用的容器:docker container prune -f
清理未使用的卷:docker volume prune -f
清理未使用的网络:docker network prune -f
清理未使用的镜像文件:docker image prune -af
注:以上操作均带参数 -f
表示强制的
通过以上命令我们可以有选择的对 docker 进行磁盘空间清理,如果需要一次搞定也有个命令可以使用 docker system prune -af
,该命令的作用为删除关闭的容器、无用的数据卷和网络以及未使用的镜像文件。
在进行 CI 的服务器上通过 crontab
实现自动清理构建后的 docker 相关文件
添加如下清理脚本到 /etc/cron.weekly/
目录下,每周清理一次
1 |
|
为脚本赋予可执行权限
1 | chmod +x /etc/cron.weekly/clean-docker.sh |
执行时间说明:
/etc/cron.hourly
:每小时的01分时执行
/etc/cron.daily
:为每天4点02分执行
/etc/cron.weekly
: 为每周日4点22分分执行
/etc/cron.monthly
:为每月1号的4点02分执行
在 Jenkins 中通过 Pipeline 调用基于 SDKMAM 制作的 Maven/Gradle 镜像对 Java 项目进行编译时环境变量被默认替换处理
使用 Docker hub 上官方提供的 Maven
/Gradle
的镜像只有官方配套提供的 JDK,无法满足自身编译需求。这种情况下选择通过 SDKMAM 或者手动的方式安装自定义的 JDK
/Maven
/Gradle
就显得很有必要。
通过 Dockerfile
构建基于 SDKMAN 的 Maven 基础镜像
1 | FROM debian:buster-slim |
注:
使用 CentOS:7
作为基础镜像可直接在 RUN
后执行相关命令无需 bash -c
使用 debian
与 alpine
作为基础镜像时需要在安装 SDKMAN 的相关命令前使用 bash -c
,安装 SDKMAN 需要写入相关配置到 ~/.bashrc
中,且在不使用 bash -c
去运行命令的情况下这两个系统会报错 sh: 1: source: not found
通过 Pipeline 调用镜像测试
1 | pipeline { |
使用如上所示测试代码,控制台返回日志显示 java: not found
完整日志如下:
1 | Started by user unknown or anonymous |
通过 Replay
修改 Pipeline
脚本打印环境变量
控制台返回完整日志如下:
1 | Started by user unknown or anonymous |
通过命令行终端查看容器环境变量
直接查看
1 | docker run --rm -i sdkman-maven:3.6.3_openjdk11.0.10 env |
进入容器查看
1 | docker run --rm -it sdkman-maven:3.6.3_openjdk11.0.10 bash |
可以看到三种执行方式得到的同一容器中的环境变量都不一样
Jenkins Pipeline:
1 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
直接运行容器:
1 | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
进入容器后:
1 | PATH=/root/.sdkman/candidates/maven/current/bin:/root/.sdkman/candidates/java/current/bin:/usr/local/sbin:/usr/local/bin:/usr/ |
再结合着之前使用 Dockerfile 打包 SDKMAN 时遇到过的错 sh: 1: source: not found
,怀疑容器运行时默认 SHELL
并非 BASH
,而是 SH
或其他的。而且 SDKMAN 在安装后会在 ~/.bashrc
中写入如下内容:
1 | #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!! |
在不使用 BASH
的情况下自然没法用。通过网上查询相关资料按照 Szymon 的博客内容对 Dockerfile
进行修改,直接在 PATH
中写死 JAVA_HOME
与 MAVEN_HOME
测试并不生效。
既然是由于在 PATH
中缺少相关路径,那么就在其中添加就好了,再次修改 Pipeline
进行测试
1 | pipeline { |
控制台返回完整日志如下:
1 | Started by user unknown or anonymous |
可以看到这次运行成功了,其中 PATH
也成功通过 -e
参数添加上了 SDKMAN 中安装工具的路径。
在 Pipeline 中使用正则表达式出现 Caused: java.io.NotSerializableException: java.util.regex.Matcher
错误处理
在 Jenkins 中通过 Pipeline 进行项目打包时由于使用了正则表达式提取域名,提取成功的变量值可以成功在 Jenkins 控制台输出中打印,但是在其他地方调用的时候就会出现 Caused: java.io.NotSerializableException: java.util.regex.Matcher
报错。
Pipeline 代码段如下:
1 | pipeline{ |
错误日志如下:
1 | an exception which occurred: |
经查阅资料,发现此异常是由于脚本安全性和沙箱引起的。默认情况下,在运行管道脚本时,它会在沙箱中运行,仅允许使用某些方法和类。可参考 可扩展管道代码的最佳实践 使用带 @NonCPS
注释的函数对无法序列化的对象包装,通常,在管道脚本中创建的所有对象都必须可序列化(原因是 Jenkins 必须能够序列化脚本的状态,以便可以将其暂停并存储在磁盘上)。当放置 @NonCPS
一个方法时,Jenkins 将一次性执行整个方法,而不会暂停。同样,您不能从带 @NonCPS
注释的方法中引用任何管道步骤或 CPS 转换的方法。
根据查询到的资料,修改后的脚本如下,使用该方法可解决此异常问题。
1 |
|
参考文章:
]]>在开发项目时使用 Gitlab 作为公司内网 golang 私有库,且所有仓库均为 private
。打包项目为 docker 镜像时拉取依赖包问题
公司有个项目 A 是由 golang
编写的,且 A 依赖的库 B、C、D 等也是商业代码的一部分,不可放在 github 等公共仓库中,这个问题在 Golang 使用 Gitlab 作为私有库 时已经解决了。
不过并没有解决干净,当时的做法仅适用于在开发环境中拉取依赖包(开发环境使用了 govendor
没发现镜像打包问题)或者在 jenkins 中通过 Makefile
或其他脚本先行编译代码,然后再把二进制文件通过 Dockerfile
写入镜像。如果是这么做,那之前写好的 Dockerfile 与 Makefile 只能重写了。
由于项目打包平时是使用 Makefile 与 Dockerfile 联动,并且 Dockerfile 最开始就是使用多层构建的方式进行项目编译。那么只需要在编译的那层镜像进行修改即可,使编译的时候能够登录 gitlab 账号访问到私有的依赖库。
要想在 Dockerfile 中登录 gitlab 首先要确保登录是安全的,至少是在安全的地方登录的。
git 无密码登录无非就是两种,一种是通过 ssh key 登录,由于 go get 采用的 https
方式,懒得去使用 insteadOf
方式转换,且提供私钥还需要上传个文件到容器呢。另一种则是通过用户名密码的方式登录,但是这种登录方式需要先 clone 一次仓库输入用户名密码才能使用?有点坑。
通过查询官方文档 Git 工具 - 凭证存储 发现可以通过先把用户名密码写入 ~/.git-credentials
的方式来实现免密访问,不过有个问题就是该文件中存储的密码是明文的。莫急,喝杯水想了想编译代码是在 dockerfile
的中间层,实际发布是最后的基于 base 存放二进制文件的镜像,同时编译是通过 jenkins 实现的,只要这个账号只能访问 gitlab 中依赖库的 group,账号密码通过 --build-arg
传入也就相对安全了(gitlab 内网部署且只能内网访问,Jenkins 只有相关人员有权限登录及查看)。
通过写入 git 服务器的用户名密码到 ~/.git-credentials
中,并使用 git config --global credential.helper store
指定当前环境中使用磁盘中存储的用户名密码访问即可。
Dockerfile 示例如下:
1 | ARG GO_VER |
在 Jenkins 中使用 pipeline 构建项目时自动获取 git 项目的所有分支与 tag 列表
在 Pipeline 中如果需要获取 git 分支与 tag 首先我们需要在 Jenkins 中安装插件 Git Parameter
新建 pipeline 工程,然后修改如下示例代码填写到 Pipeline script
中
1 | pipeline { |
保存后,第一次直接 build
即可,报错属于正常现象,第一次 build
完成后可看到当前工程左侧菜单栏中 build
变成了 Build with Parameters
点击 Build with Parameters
,可看到如下图,可看到 branch_name
窗口中仅有 master
且下方提示配置错误,这个时候不要慌问题不大。
出现这个问题也是正常现象,是由于我们在 gitParameter
中定义了 useRepository: 'git@git.akiya.cc:foo/bar.git'
,由于第一次构建会读取 pipeline 中定义好的参数并在 Jenkins 工程中建立对应的参数项,但是也仅仅只是建立了而已,我们要想 gitParameter
拿到 git 的 branch 与 tag 还需要再次 build 才行。
根据上图我们可以看到第二次 build 执行结果为 SUCCESS
,同时也能看到已经按照我们脚本中打印出了当前代码的分支信息
再次回到项目构建页面,可以看到已经能够正确获取到项目的 branch 与 tag
]]>使用 Resilio Sync 工具部署同步服务器,提供共享文件访问及下载
由于公司产品部署包过大,起初提供给一线实施的部署包存放在阿里云上,不过由于带宽费用问题,下载很慢且没有断点续传。后面想起之前玩过 sync 下载东西,该工具基于 P2P
通信,没有中间服务器,速度上限为带宽上限。刚好公司千兆网络上行速度也还可以,只是没有固定公网 IP。那么不如在公司内部部署 Sync 提供给一线使用,这样也可以不用每次发布新版本时还要上传至阿里云绕一圈。
以下内容来自维基百科
Resilio Sync(曾经名为“BitTorrent Sync”)是由 BitTorrent 公司开发的专有的对等网络数据同步工具,可在 Windows、OS X、Linux、Android、iOS 和 FreeBSD 上使用。其可在局域网、互联网上通过安全的、分布式的P2P技术在不同设备之间同步文件。
Resilio Sync使用P2P协议同步软件。该协议用于在多个设备间传递大文件时非常有效,与µTorrent和BitTorrent使用的协议类似 。Resilio Sync中,用户数据并不在云端,而是存储在本地硬盘中,因此在同步数据时需要至少一台持有数据的计算机处于开机状态。Resilio Sync使用在计数模式中AES-128密钥,该密钥可随机生成,或由用户设置。在Resilio Sync中该密钥称为secret,可告知给其他用户以便共享数据。数据是直接从一台设备上发送到另一台设备中,因此需要数据所在设备在网络上可访问。如果原设备不可访问,则数据由其他节点传播,这些传播节点无需知道原先的secret,但只有知道secret的节点才能解码并查看数据。
可以将secret告知给某个节点,这样就将该节点加入到同步系统中,使其可以访问数据。当创建新节点时,用户可以将原secret告知给新节点;若出于安全性考虑,也可以创建一次性使用的secret。用户还可以通过Resilio Sync客户端生成一个只读的secret,这样当新节点接收到这个secret时,只能查看文件而无法修改。
Resilio Sync对需要同步的文件大小没有限制,唯一的限制就是不同的同步设备中都需要有足够的空间容纳所要同步的文件。
Resilio Sync最大的优势在于其不需要第三方服务器,几乎不受存储空间和流量限制。由于Resilio Sync是一款采用 BitTorrent 协议的P2P同步工具,传输速度基本上只受用户网络带宽的制约,它可以支持多人同时同步,而且,越多人对文件夹进行同步,则同步速度越快。它支持多平台,可以通过密钥进行文件分享。
由于Resilio Sync的数据不在云端,而是存储在本地。所以拥有文件的电脑需要保持在线,才能同步到其他电脑去。而且由于采用类似 BT 的协议,因此在某些禁用 BT 下载的场景中可能会受到影响。
本文将以在 Linux 上部署服务节点提供共享文件夹,在 Windows 上以只读方式获取文件为例。
官网地址:https://www.resilio.com/individuals/
下载安装包
根据自己操作系统与 CPU 架构,选择对应的安装包
1 | wget https://download-cdn.resilio.com/2.7.2.1375/RPM/resilio-sync-2.7.2.1375-1.x86_64.rpm |
安装服务
1 | rpm -ivh resilio-sync-2.7.2.1375-1.x86_64.rpm |
安装完成后默认服务名为 resilio-sync
,配置文件路径 /etc/resilio-sync/config.json
,我们可以通过命令 rslsync --dump-sample-config
查看配置文件模板进行相应调整。
修改配置文件
1 | { |
启动服务
1 | systemctl start resilio-sync |
通过浏览器访问服务器 IP:8888,使用配置文件中 webui
中填写的用户名密码登录后可看到如下界面,第一次使用时需要填写当前节点的名字,填写后不可更改。此名字主要用作与其他节点通信时显示使用。
第一次进入可以看到界面如下,我们选择右上角的设置按钮
选择 General
修改 Language
为中文,然后刷新页面
在服务器上 /data/sync/
路径下创建文件 ResilioSyncPro.btskey
并填写如下内容
声明:以下许可证为网络获取,仅供学习交流使用,如商业使用请官网购买许可证
1 | tos1_eyJzIjogIm5xNjRmNGgrWDhxWHFiaWRodEtyTWdNcEVaMHdYaUJLbExwSWFwSDUxMzkyaHdqMFFpQWJOTTFGd2JGWGpJQ0FhV2w4V3ZidVpPenpITXZmNTRLWU1XVGVsVFZjS3JGQUpYMmVUMGttT2lCMm8zQ1BjVFd2VWlCLzRsTTlQN1FsalVSVzREMVFNUktWcEhwaG5IVzIvZmdqN05MaThmMnhNa1NDNERwRVVpQ0pXZHpPWXFIbW1OMFdOUEt6QWg4RkJoanNvUVNBa1hKN09WS0c5WElkVTczWnNlVWNxWW1WVUo0WDc0S05wYmlYZk0vemlsU2pIK0U5Y3ZMZ092YlplVjlCZXlveDNwT3pRYUJOeFNQT3FYWEpTRHE1bVRhRXMvWGppVGtJV21uVHJudVJnb01DZ0RBOHdBS3RIYjRvVkduWm1jeU8xNlhoQ3dvL2VkeHFxZz09IiwgImQiOiAiZXlKamF5STZJQ0ppZEc5ell6RmZaWGxLYW1ONVNUWkpRMHBJVlZoYVYxRldUakZsVldoWVZrWldNMUpXU2tWVVJURlZZVEZXZFZacVVsUmpNMUp5Wkcxd1FsUkVRVFZWUXpsMVZraGtUVk5wT0hsUFEzUjNUV3hrVjJOck1IaFVhelI1VXpOQ1QyUlhiR3RTYlVwb1ZtNUtURlJZVVRWVFJ6RXpWVVU1TVZwdVdtRlVWbVJ1VVd4Sk1sWXlXbkZsYm14b1ZWaHdlbEV3TVVKamJXaE5XVlYwZFZwVVJYZFRSbEpOVW5wU2JGbHBkRXBVVlRGSlYwUnNWMkV5ZEZSalZFRXdUbTVuTUdKck1WZE5SR2N3VmxWYVRsSnJNVzlqUlVwMFlVUlNlRTFJYkZaWmExRXhVbTFzTUUxSVpIZE5iR3hVWWxob1IyTkVSbE5sVlhkeVVsWm9OV0ZGUlROUmJWSnVWVEZDYUdKSVZrWkxNV3hZVmpGb2FtSjVPVWxSVlRsT1ltMTNNbE5zUlRCYWFsSlFWbXBCZUZRd1VrSlpha1Z5V20wMWRVNXVXblZSTTJnell6RldTazlGTVU1aFNHeFFUREE1TUZOc2JFWldTRkpXVlVaSk1sUkRkRkpXUjJoUlYwUlNjbGxyTlhGTlJHeFpXbmwwYjJGVk1VeFZWMVpVU3pCd2RFNTZVblpUYW14SVpEQnJlVkZ0TVVsalJGWXdWRlZTZEZreWVIcE9WbWhLV1Zkb1MxZEdSa1pqTUhSMVVsaFdlbE13VGpSaVJsSjVUVmR3ZFdOSGFFNWFlbFV3WW0xNGJFOVVhRzlUU0VWeVVWaE5NV1ZZVWxSTlIyTTVVRk5KYzBsRFNtcGFRMGsyU1VOS2JHVlZjSGRaYlRGaFpHdHNjV0l5Wkd4bFZYQTJXa2N4VDFKSFNYbFZiWGhLWVcwNWJsTlhOVTlPVjBwMFZHeEdhbUpVYUhCVVJVNUNZVlpyZVdSSVFtRlJNR3N5VTFWT1MyVkdWblJXVkVKVFltczFjbGt3V2s1TmJVVjNaVVYwYW1Wc1NsaFpla0pyVFVaRmVGRnRlRmRUUlRWNVUxZHNNMW93YkhSV2FsSnFVVEJyTWxOVlVrcGxSVFZGVmxSV1RsWkdhekJVVlZKQ1l6QnNSRk50Y0dwTk1VWndWREpzUW1GWFNqVk5WelZQVmtaYVVGbDZRbTloYkZwelZsZHNUVkV3Um5CYVJXaHpaREZ3VkZOVVdrcFJNSEF6VjJ4b1MyVnRTWGxPVjJocFVUQnNlbE5WVGt0a2JVNUpWVzV3U21GdE9XNWFXR3hMWWxkSmVXVkhkR0ZYUlhCVlYyeGtUMlZXY0ZsVlYyeFFZVlZHY0ZSdGMzaFVNVlpIVjJ4YVZGSkhVa05VV0hCVFYyeEdWbFZVUmxoU1ZGWkhWV3RXVTFWV1VrWk9WVnBYVFZWd1UxUlhjRk5VVmxsNFdqSnNUVkV3Um5CWmVrcFhZVWRTU1ZSWGJGQmhWVVkwV214bmQyTXdiRVJUYlhoc1UwVkdjRlF5YkVKbFZURlZWVlJHVUZaRlZYbFVNRkpDWkRKYVVsQlVNR2xtVVQwOUlpd2dJbWx1Wm04aU9pQjdJbTl5WkdWeVNXUWlPaUFpWVc1aGRXeG1ZVzUxYTJadWIydHViVzF6TURZNWNXbzNOQ0lzSUNKaGNpSTZJREFzSUNKbGVIQWlPaUF5TVRRMU9URTJPREF3TENBaVkzSmxJam9nTVRRNE1UUXlOek00Tnl3Z0luTjJZMGxrSWpvZ0luTjVibU5RY204eElpd2dJbU56ZENJNklDSnZMV2MxTlU1elNHTldWU0lzSUNKemRtTkRiMlJsSWpvZ0luTjVibU5RY204aUxDQWlZMmxrSWpvZ0ltZHFaV295YmlJc0lDSjBlWEJsSWpvZ0luQmxjbk52Ym1Gc0lpd2dJbTl3ZEhNaU9pQjdJbVp2YkdSbGNsTmxZM0psZENJNklDSkJWMFJOVHpSRlUxTkJUbGhCV2xKVE1rMHlORlpCTmtkQlIxSlhWVFJRTlZZaUxDQWljMlZoZEhNaU9pQXhmWDBzSUNKbGVIQWlPaUF5TVRRMU9URTJPREF3ZlE9PSJ9 |
在 许可证
中选择 应用许可证
填写路径为 /data/sync/ResilioSyncPro.btskey
点击 打开
后,可看到应用已使用许可证激活
创建需要共享文件的文件夹
1 | mkdir /data/sync/share |
注意:共享的文件夹需要 rslsync
用户可访问,否则会有权限问题,添加失败
1 | chown -R rslsync:rslsync /data/sync/ |
添加共享文件到此目录
选择左上角的“➕”然后选择高级文件夹或者标准文件夹
在高级文件夹中添加共享文件成功后,会显示如下界面。勾选新用户(我邀请的)必须由我批准后,所有通过分享链接加入的节点都需要经过同意后才能正式加入。由于我们需要访问节点可控,所以选择此类型文件夹共享。
点击复制后会显示链接,把此链接给其他希望组网的用户使用即可申请加入此共享文件夹。
完成后关闭窗口可看到当前有共享文件夹 share
,在线用户 0/0
,这是由于我们还没有用户节点加入。接下来我们来在 Windows 上面部署节点加入。
Windows 上仅做加入说明,共享方式与 Linux 服务器上一致
下载 Windows 上对应版本安装包
安装 Resilio-Sync,并填写当前节点名字
添加链接或秘钥
输入我们之前在 Linux 上部署的 sync 中添加的共享文件夹的共享链接
选择保持路径,并勾选选择性同步
等待服务端同意
登录共享文件夹的服务端,同意节点加入
加入节点成功
Win
Linux
点击 Sync 中共享文件夹名称,进入文件夹可看到与源服务器上同样的文件目录结构,只不过本地文件中所有文件均添加有后缀 .rsls
,且文件图标为半透明状。此时双击文件或右键选中文件选择同步到此设备
即可下载文件查看使用。
在已部署的 harbor 服务上对现有服务进行升级,访问协议由 http
升级至 https
由于公司内网 Harbor 服务最开始部署的时候是 http 的服务,通过在客户机上配置 insecure-registries
参数实现的内网访问
1 | { |
不过在公司部分 Windows 电脑上通过 WSL 进行开发时,配置好如上配置后有时会出现如下错误的情况(注:Linux 服务器上配置好后未遇到过)
1 | git pull harbor.akiya.cc/sample-images |
所以决定升级内网 Harbor 服务器到 Https 协议,并在内网 DNS 服务器上做好相关解析。这样以后使用镜像仓库时不用配置参数直接访问即可。
如果域名是在云厂商购买的可以直接通过云厂商申请免费的 SSL 证书即可,阿里云、腾讯云等均有提供。也可以通过 freessl 申请免费证书。
如果域名为内部自定义域名,且没有在云厂商注册购买。则只能通过 openssl 自签证书使用了,具体可参考 Golang 使用 Gitlab 作为私有库 中Gitlab 搭建下创建自签证书中的脚本。
申请完成证书后,上传证书与秘钥文件到服务器上。
停止已有 Harbor 服务,进入 Harbor 部署目录中使用命令 docker-compose down
停止
修改 harbor.yml
文件,在其中启用 Https。注意 yaml 文件缩进
1 | # Configuration file of Harbor |
再次执行 ./prepare
通过脚本更新配置文件
1 | ./prepare |
重新启动 Harbor
1 | docker-compose up -d |
等待启动完成后,通过 web 访问可以看到已经自动通过 80
跳转到 443
端口,证书信息也可以看到。
在服务器上取消 docker 的 insecure-registries
配置,可以正常拉取镜像文件。