「Harbor」- HTTP status 504 Gateway Time-out

# 07/20/2019 # 我刚想处理这个问题,好了个屁的。这种最可怕了。
问题背景
使用docker push命令推送镜像。
在某个镜像层推送将要结束的时候,收到如下错误信息:

# docker push docker-registry.example.com/project/image-foo:v2.5.0
The push refers to repository [docker-registry.example.com/project/image-foo:v2.5.0]
3d10bce3ce31: Layer already exists
1b70b131f01d: Layer already exists
2c5ef295a217: Pushing [==================================================>] 375.4MB
2ce4f2676a16: Layer already exists
35bbe47ffc77: Layer already exists
05b61dc1031f: Layer already exists
d6d37cde236f: Layer already exists
ecbc53aebc27: Layer already exists
1585039add0a: Layer already exists
692d855fb28e: Layer already exists
717b092b8c86: Layer already exists
received unexpected HTTP status: 504 Gateway Time-out

查看/var/log/registry.log文件,日志中有如下信息(经过了简单的处理):

# Jul 22 18:26:55 172.18.0.1 proxy[1114]: 2019/07/22 10:26:55 [error] 8#0: *11392 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.50.63, server: , request: “PATCH /v2/veryeast/ve-m-ssr/blobs/uploads/a8008eea-5412-40d2-a566-4efc71b72cb3?_state=gvZ4sODnz4enCabFx1TGEpNdkLaLAjkitundRI3az197Ik5hbWUiOiJ2ZXJ5ZWFzdC92ZS1tLXNzciIsIlVVSUQiOiJhODAwOGVlY[……]

READ MORE

「UmiJS」- 插件化的企业级前端应用框架

认识
UmiJS 是一个基于 React 的企业级前端应用框架,由阿里团队开源并广泛用于中后台项目开发。它提供了一套开箱即用的工程化方案,旨在提升开发效率和项目可维护性。
官网:https://umijs.org/
文档:https://umijs.org/docs/guides/getting-started
仓库:https://github.com/umijs/umi
组成
WIP
构建
前端路由支持(HTML5 History 模式)| 所有非静态资源请求需回退到 index.html,由前端框架处理路由,否则刷新将返回 404 页面。

server {

location / {
try_files $uri $uri/ /index.html;
….
}

}[……]

READ MORE

「LAPTOP/PROJECT-BD」- 创造属于自己的笔记本电脑 | 制造属于自己的笔记本电脑 | 打造专属笔记本电脑

问题描述
既然市面上的笔记本无法满足我们的需求,修改现有笔记本 逐渐成为该问题的解决方案。
解决方案
需求描述、制定方案、实现功能
需求描述
我们期望的功能如下:
1)笔记手写、绘制内容:该功能得益于触控屏幕,而且有些内容或笔记(数学公式)手写更加快捷;

绘制、手写的功能很丰富,包括索套、笔、尺子,网格,特殊图形(例如坐标系、形状等等);

针对该绘制手写功能,其要内嵌到笔记中,即直接在笔记页面上直接操作,而非弹出独立的窗口进行操作;

2)文本识别、公式识别:除了能够手写,还能将手写文字、手写公式转化为排版内容;
3)图像绘制(Math Assistant):在文字识别的基础上,能够自动绘制数学公式的图像;
4)插入空间:鉴于 OneNote 支持手写输入,而有时我们需要在两行之间插入内容,所以我们就需要插入空间功能,以在增加两行直接的空白区域;

我们常用的笔记软件是以行为单位进行编辑的,所以如果要在两行之间插入内容,那么直接通过回车换行即可,但是不需要面对该问题。但是,如果笔记软件支持手写,就需要考虑这个问题;

5)导入文件(File Printout):我们尝试该功能,通过其导入 PDF 文件,然后通过手写绘制进行笔记记录以及标注;
1)粘贴图片较小,并且无法调整默认尺寸;
2)复制粘贴多个图片是乱序的,需要通过插入图片功能进行保证多个图片的正确顺序;
3)图片是固定的,并且笔迹将绘制在图片上,移动图片将同步移动笔迹。
5)通过将图片设置为背景,能够实现图片的固定。但是却无法直接取消图片作为背景,只能通过 Undo 撤销来间接实现;
注 1:很多功能参考 OneNote 特性,并且按照我们期望中的需求进行改进;
制定方案
# 10/24/2023 实现 Handwriting 的思路:针对该手写功能,其在本质上仅是个辅以硬件的多功能绘图程序。所以,我们实现绘图程序及硬件功能即可;
针对「绘图程序」部分:

鉴于我们并不具备绘图程序的开发经验,我们决定从现有项目中学习,然后编写 Zim 插件。

1)Create a Paint Application in Python using Tkinter

2)PyQt5 – Create Paint Application

但是,我们希望绘制功能直接内嵌到笔记中(而非弹窗并编辑),所以我们现在(10/27/2023)要学习 GTK+3 开发的绘图程序。

1)ImEditor https://github.com/ImEditor/ImEditor

2)esrille/paint https://github.com/esrille/[……]

READ MORE

「Kubernetes-Objects」- Pod,探针

Liveness Probe
如何确保当 Pod 中运行的应用程序进入失败状态时, Kubernetes 会自动重启 Pod?
可以使用存活探针。如果探针失败,那么 kubelet 会自动重启 pod。探针是 Pod.spec 的一部分,可以添加到 containers 字段中。pod 中的每个容器都可以拥有一个存活探针。
探针可以有三种类型:
1)它可以是容器内部运行的命令;
2)也可以是一个 HTTP 请求,指向容器内由网络服务提供的特定路径;
3)或者是更通用的 TCP 探针。
HTTP Probe
下面的例子展示了一个基本的 HTTP 探针:

apiversion: v1
kind: Pod
metadata
name: liveness-nginx
spec:
– containers
name: veness
image: nginx
livenessProbe:
httpGet:
path: /
port: 80

Kubernetes 容器探针的相关文档 https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
Readiness Probe
虽然 LivenessProbe 能够指示 Pod 启动和运行的状态,但是如何确保在应用程序准备好服务请求之后再接受访问?
可以向 pod 规格添加就绪探针。与存活探针类似,就绪探针也有三种类型(具体信息请参阅相关文档)。
下面是一个简单的例子,其中就绪探针在 nginx Dockerl 映像的单个 pod 上运行。就绪探针向端口 80 发送了一个 HTTP 的请求:

apiversion: v1
kind: Pod
metadata:
name: readiness-nginx
spec:
containers:
– name: readiness
image: nginx
readinessProbe:
httpGet:
path: /
port: 80

虽然上面介绍的就绪探针与 1.2 节中所介绍的存活探针相同,但一般情况下两者是不一样的,因为它们旨在提供应用程序不同方面的信息。存活探针负责查看应用程序进程是否处于活动状态,但是应用程序可能并没有准备好接收请求。而就绪探针负责检査应用程序是否可以正确服务请求。因此、只有当通过就绪探针的检査,podオ能成为服务(请参阅 5.1 节)的一部分。
请参阅 Kubernetes 容器探针的相关文档(https://kubernetes.io/docs/concepts[……]

READ MORE

「SURFACE/PRO/4」- 2 Touch Screen on Linux

问题描述
# 10/22/2023 安装 Ubuntu 22.04 LTS 系统,但是触控屏幕无法正常工作;
解决方案
安装 Linux Surface 内核
linux-surface/linux-surface: Linux Kernel for Surface Devices
参考 Installation and Setup · linux-surface/linux-surface Wiki 文档,获取详细安装过程;
安装过程大致:(1)安装前的检查;(2)通过 APT 安装;(3)安装完成后的其他配置工作;
安装其他常用应用
intel-microcode linux-firmware
surface-dtx-daemon
surface-control
配置多点触控
Touch controls
X11:当触控时,其模拟鼠标左键点击;
Wayland:其针对触控具有原生支持;
XWayland,其依然受制于 X11 协议;
针对多点触控,除了取决于上述桌面协议外,还与应用程序也有关系;
配置 Firefox 多点触控
# 10/22/2023
配置 Firefox 多点触控(通过手指进行网页缩放):
1)终端打印输出 echo $XDG_SESSON_TYPE 变量,其值显示我们运行 Wayland 环境(操作系统 Ubuntu 22.04 LTS 版本);
2)但是,我们使用 Firefox 测试,开启 MOZ_ENABLE_WAYLAND=1 变量,操作 Firefox 依旧是模拟鼠标左键单击;
3)并且 Firefox 能够被 xkill 程序结束(而 Terminal Nautlius 则不然),我们猜测 Firefox 通过 XWayland 运行;
4)然后,我们尝试开启 MOZ_USE_XINPUT2=1 环境变量,经过测试能够通过两指实现网页的缩放;
但是,现在我们尝试通过触控来拖动 Firefox 窗口,然后窗口无法拖动,窗口只会轻微移动。但是,其他应用程序(Termina Nautlius)能够正常拖动。我们尝试关闭上述两个环境变量,依旧无法拖动,或许是因为其他原因;
该配置仅是为了初步测试,实际的体验比较一般;
参考文献
touchscreen – Touch Screen not working on MS Surface Pro 4 after install (Ubuntu 22.04.2 LTS) – Ask Ubuntu[……]

READ MORE

「CONTAINER-REGISTRY」- GO-CONTAINER-REGISTRY

认识
Go library and CLIs for working with container registries
文档:https://github.com/google/go-containerregistry/tree/main?tab=readme-ov-file#tools
仓库:https://github.com/google/go-containerregistry/tree/main
构建
安装
with asdf | https://github.com/dmpe/asdf-crane

asdf plugin-add crane

asdf install crane latest

asdf global crane 0.20.3

应用[……]

READ MORE

「ECLIPSE」- 安装

从系统仓库中安装

// Kali GNU/Linux Rolling

// “全家桶”安装
# apt-get install $(apt-cache search eclipse |grep -i eclipse | awk ‘{printf “%s “, $1}’)

// 只安装 Eclipse
# apt-get install eclipse

从官方站点中下载
Eclipse (software) – Wikipedia
历史版本的信息

Version name Date Platform version Projects Main changes

N/A 21 June 2004 3.0[22]
N/A 28 June 2005 3.1 Added Java 5 support
Callisto 30 June 2006 3.2 Callisto projects[24]
Europa 29 June 2007 3.3 Europa projects[21]
Ganymede 25 June 2008 3.4 Ganymede projects[25]
Galileo 24 June 2009 3.5 Galileo projects[26]
Helios 23 June 2010 3.6 Helios projects[27]
Indigo 22 June 2011 3.7 Indigo projects[28] Added Java 7 support (3.7.1 sr1)
Juno 27 June 2012 3.8 and 4.2[30]
Kepler 26 June 2013 4.3 Kepler projects[34]
Luna 25 June 2014 4.4 Luna projects[35] Integrated Java 8 support;
Mars 24 June 2015 4.5 Mars projects[37]
Neon 22 June 2016 4.6 Neon projects[38]
Oxygen 28 June 2017 4.7 Oxygen projects[39]
Photon June 2018 (planned) 4.8 Photon projects[40]

各个版本的名可以参考 Eclipse 的维基百科主页中的 Name 章节:https://en.wikipedia.org/wiki/Eclipse_(software)#Name
历史版本下载地址
所以的 Eclipse 的历史版本都可以在 archive 中找到,并且支持多平台的不同版本:http://archive.eclipse.org/eclipse/dow[……]

READ MORE

「Eclipse」- 配置代理服务器

问题描述
在执行安装或者升级时,鉴于网络原因下载速度比较慢,所以需要使用网络代理服务。
解决办法
通过配置代理服务器(HTTP、HTTPS、SOCKS),来提高下载速度:
1)打开 Windows => Preferences => General => Network Connections
2)设置 Proxy entries 添加代理服务器,点击 Edit 编辑代理;
3)将 Active Provider 设置为 Manual,然后代理选项会被自动勾选
Proxy bypass 的语法格式:
1)10.*
2)*.example.com
3)127.0.0.1
4)localhost
参考文献
Set the HTTP and HTTPS Proxies in Eclipse[……]

READ MORE

「Elasticsearch」- 分词过滤器

Hunspell Token Filter
Elasticsearch Reference [6.5]/Hunspell Token Filter
适用于 Elasticsearch 6.5,Elasticsearch 7.6.2
提取词干。比如要提取英语单词的词干,搜索“manage”的时候要匹配到“manager”。
需要安装字典,字典中包含了词干和词之间的关系:

#1 先在创建 /etc/elasticsearch/hunspell/en_US/ 目录。

#2 到 仓库 中下载字典文件。如果处理英文,则下载 en_US.zip 文件。

#3 然后,解压到 /etc/elasticsearch/hunspell/en_US/ 中(文件 *.dic 和 *.aff 要在该目录中)

#4 重启 ES 服务。

elasticsearch 使用词干提取器处理英语语言[……]

READ MORE

「TMV」- LAPTOP | 概念、术语、组成 | The Anatomy of Computer Laptop

认识
[WIP] 笔记本电脑发明原因?为什么会出现笔记本电脑?
组成
What is the anatomy of a laptop computer? – Quora
—— 该部分将记录笔记本电脑的组成结构,以帮我我们了解笔记本电脑的各个组成部分。

A / B / C / D
笔记本电脑的测评文章或视频时,经常能够看到 A / B / C / D 面这样的表述,它代表笔记本的四个面:A 面即笔记本的顶盖,B 面为屏幕面,C 面为键盘面,D 面则是指底盖;

外壳材料
Thinkpad的外壳材料和其他品牌的笔记本电脑有什么不同_百度知道
ThinkPad 工程师解答:从早期 T20 上的“钛合金复合碳纤维”到当今最新 T61 上的高弹性碳纤维复合材料,ThinkPad 一直走在材料技术的最前沿,将重量轻、强度高的新型材料运用于 ThinkPad 中,为人们所津津乐道。与其他笔记本惯用的镁铝合金相比,ThinkPad 屏盖上使用的碳纤维钛复合材质在拥有相同重量的前提下,却提供了 1.2 倍于前者的高强度,再加上其天生特有的耐磨性,令 ThinkPad 在长时间使用后如新依旧。值得一提的是,目前新型 ThinkPad T 系列中使用的“碳纤维镁合金”材质在继承了上述优点的同时,还具有散热性强的优点;
ThinkPad笔记本电脑的外壳材质有哪些
总之,ThinkPad笔记本电脑的外壳材质有 ABS 塑料、铝合金、钛合金、铝镁合金、聚酯纤维 等,它们的特点是耐磨损、耐冲击、耐腐蚀,可以抵抗外界的腐蚀,抗冲击,防止电脑受到损坏,从而使用者能够安心使用。因此,ThinkPad笔记本电脑的外壳材质可以满足不同用户的需求,是一款性价比较高的笔记本电脑。
连接螺丝
Q:螺丝防脱设计?
A:笔记本螺丝后面防止丢失的设计通常被称为 “螺丝防丢设计” 或 “螺丝防脱设计”。具体的实现方式有多种,以下是一些常见的:

卡簧式防丢设计:在螺丝上加一片卡簧,将螺丝直接固定在部件上,这样在拆卸螺丝时,螺丝会和与其连接的部件连为一体,不会出现丢失的情况。

特殊螺纹或卡口设计:螺丝的螺纹或卡口经过特殊设计,在拧松到一定程度后,螺丝不会完全脱离,而是仍然与笔记本的主体部分保持连接,起到防丢的作用。例如,有的螺丝在底部有一个特殊的凸起或卡槽,与笔记本上的相应结构配合,防止螺丝掉落。

磁吸式防丢设计:在螺丝或笔记本的对应位置安装磁铁,利用磁力使螺丝在拆卸后仍然吸附在笔记本上,避免丢失。不过这种方式可能会对笔记本内部的电子元件产生一定的影响,所以使用并不广泛。

这些设计在一定程度上方便了用户对笔记本的维护和拆卸,同时减少了螺丝丢失的风险。不同品牌和型号的笔记本可能会采用不同的螺丝防丢技术[……]

READ MORE

「EKS」- Amazon EBS CSI Driver

参考官方文档 | https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html

我们习惯使用 AWS CLI 来完成 IAM role 创建。
通过 EKS Add add-ons 来安装 Amazon EBS CSI Driver 扩展

选择 IAM roles for service accounts (IRSA) 并选择前面创建的 IAM role 配置。

紧接着就失败了,

我们重新 Edit 并使用 EKS Pod Identiry 并选择 Create recommended role[……]

READ MORE

「Eclipse」- 导入 Python 项目

问题描述
该笔记将记录:在 Eclipse 中,进行 Python 项目开发的方法,以及常见问题的解决办法。
导入 Python 项目
首先需要安装 PyDev 插件,从 中安装即可(这里不再赘述)。
1)New PyDev Project
2)Dont use default Location(Project contents => Use default)
3)Browse to existing project location …
if its an existing eclipse project with project files that have correct paths for your system you can just open the .proj file …
参考文献
PyDevHow do I import a pre-existing python project into Eclipse? – Stack Overflow[……]

READ MORE

「XMind」- 常见错误汇总

!MESSAGE Could not resolve module:
问题描述
在启动 XMind 程序时,产生如下错误信息:

!SESSION 2020-12-09 19:38:27.612 ———————————————–
eclipse.buildId=R3.7.9.201912052356
java.version=11.0.8
java.vendor=Debian
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=en_US
Framework arguments: -eclipse.keyring @user.home/.xmind/secure_storage_linux
Command-line arguments: -os linux -ws gtk -arch x86_64 -data /opt/xmind/xmind-8u9/XMind_amd64/workspace -eclipse.keyring @user.home/.xmind/secure_storage_linux

!ENTRY org.xmind.cathy 1 0 2020-12-09 19:38:30.223
!MESSAGE Skip unrecognized command line argument: ‘-eclipse.keyring’

!ENTRY org.xmind.cathy 1 0 2020-12-09 19:38:30.224
!MESSAGE Skip unrecognized command line argument: ‘@user.home/.xmind/secure_storage_linux’

!ENTRY org.eclipse.osgi.compatibility.state.nl_da 2 0 2020-12-09 19:38:30.327
!MESSAGE Could not resolve module: org.eclipse.osgi.compatibility.state.nl_da [840]
Unresolved requirement: Fragment-Host: org.eclipse.osgi.compatibility.state
Unresolved requirement: Fragment-Host: org.eclipse.osgi.compatibility.state

问题原因
我们猜测是 Java 版本过新导致该问题。因为我们尝试更换 JDK 版本,问题得以解决。
解决方法
我们使用 XMind 8 Update 9 ([……]

READ MORE

「Kubernetes」- 无法通过 Service 访问 Pod 自身

问题描述
我们运行 Pod-A 实例,然后定义 Service-A 暴露 Pod-A 服务,然后在 Pod-A 内通过 Service-A 来访问自身,简单说就是:在 Pod 中,通过 Service 访问自己。
但是,这样网络是不通的,即 Pod-A 无法通过 Service 访问自己。然而,其他容器通过 Service-A 能够成功访问 Pod-A 服务。
原因分析
我们提交工单,得到答复如下:鉴于 kube-proxy 为 IPVS 模式,由于 LVS 的特性。如果 Pod 访问的 Service 负载到 Pod 自己,那么就会导致无法正常访问。
在我们开发集群(自建)中,kube-proxy 为 iptables 模式,所以不存在这个问题。
解决方案
遇到该问题的集群为阿里云集群,我们没有解决该问题,毕竟 Pod 通过 Service 访问自己并不是常见需求。
我们没有因为这种特殊需求而修改集群配置,毕竟能否调整是一方面,是否会产生其他附带影响是另一方面。
相关问题
docker – kubernetes pod can’t connect (through service) to self, only to other pod-containers – Stack OverflowA pod can’t direct traffic to itself via a service · Issue #20475 · kubernetes/kubernetes · GitHubPod unable to connect to itself via service · Issue #61593 · kubernetes/kubernetes · GitHubEdge case: A Pod fails to reach itself via the Service IP[……]

READ MORE

「LAPTOP/PROJECT-BD」- 增加外置手写支持 | 支持外接屏幕手写数学笔记

实现:确保绘画程序能够正常工作
# 11/28/2023 测试 esrille/paint 程序
git clone https://github.com/esrille/paint
编译安装,参考 docs/en/install.md 即可:

pip install opencv-python

git clone https://github.com/esrille/paint.git
./autogen.sh
make
sudo make install

实现:通过外接屏幕完成绘制图像
# 12/01/2023 通过外接触屏显示器并配备手写笔(hardware),实现在绘画程序上绘制图形。
目标:需要实现 Type C 接入外接屏幕后,屏幕触屏能够正常工作,需要实现手写笔在程序上绘画能够在这个屏幕上写字;
选择外接屏幕
我们应该如何选择触屏显示器?
1)学习普通显示器相关参数及其含义;
2)学习触屏显示器相关参数及其含义;
3)显示器参数:现阶段(12/01/2023),15.6,1920×1080,60Hz,USB Type C(供电+显示)
4)该触摸屏要能够在 Ubuntu Wayland 下正常运行,需要保证外接屏幕能够手写输入;
便携显示器 15.6 寸 144Hz 手机笔记本电脑外接屏 switch/PS5/ 扩展副屏https://item.taobao.com/item.htm?id=740036183589
469.00 * 1 (12/04/2023)
经过简单测试,通过 Type C 接入,能够实现基础操作(简单手写绘制、多点触控)。
但是,我们发现触摸功能出现在错误的屏幕上:外接屏幕具有触摸功能,当触摸外接屏幕时,笔记本内置屏幕获得触摸操作。—— 这并非屏幕本身的问题,后面我们将解决该问题。
选择手写笔
我们应该如何选择手写笔?
1)针对书写笔,其能够在电容屏幕上书写皆可;

手机平板通用电容笔 7.0 电阻电容两用笔触摸触屏 gps 电子书手写笔游戏儿童绘画适用苹果 iPad 安卓华为小米触控笔 [交易快照]
https://detail.tmall.com/item.htm?id=673773622333

5.90 * 1 (12/04/2023)

算是买错了,我们希望笔尖是电容笔头,能够进行书写。而这款笔尖是 ABS 塑料,无法在电容屏上使用。

视频剪辑专用笔适用剪映抖音代替手指尖头触屏笔点手机修图触摸屏通用屏幕点击电容剪影制作高精度编辑触控笔
https://detail.tmall.com/item.htm?id=680819620882

6.[……]

READ MORE

「DOCKER」- Registry

该笔记将记录:在 Linux 中,如何搭建 Docker 镜像仓库(Docker Registry);
认识
Registry, the open source implementation for storing and distributing container images and other content, has been donated to the CNCF. Registry now goes under the name of Distribution.
https://docs.docker.com/get-started/docker-concepts/the-basics/what-is-a-registry/https://docs.docker.com/registry/
官网:https://distribution.github.io/distribution/
文档:https://distribution.github.io/distribution/
仓库:https://github.com/distribution/distribution/[……]

READ MORE

「EKS」- Use Amazon EFS storage | Amazon EFS CSI driver

相关文档
Store an elastic file system with Amazon EFShttps://docs.aws.amazon.com/eks/latest/userguide/efs-csi.html
服务部署
Step 1: Create an IAM role
Step 2: Get the Amazon EFS CSI driver
Add add-ons ⇒ Amazon EFS CSI Driver
选择对应的 Role 参数
Step 3: Create an Amazon EFS file system
Dynamic Provisioninghttps://github.com/kubernetes-sigs/aws-efs-csi-driver/tree/master/examples/kubernetes/dynamic_provisioning

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
provisioningMode: efs-ap
fileSystemId: fs-92107410
directoryPerms: “700”
gidRangeStart: “1000” # optional
gidRangeEnd: “2000” # optional
basePath: “/dynamic_provisioning” # optional
subPathPattern: “${.PVC.namespace}/${.PVC.name}” # optional
ensureUniqueDirectory: “true” # optional
reuseAccessPoint: “false” # optional

ensureUniqueDirectory | 我们将其修改为 false 值,以放置某些 PVE 名字过长而产生 … exceeds EFS limit of 100 characters … 错误。
Step 4: Deploy a sample application
常见问题
… failed to provision volume with StorageClass “efs-sc”: rpc error: code = Unauthenticated desc = Access Denied. Please ensure you have the right AWS permissions: Access denied[……]

READ MORE

「Kubernetes」- Scaling Workload

伸缩分为两种:

1)集群的伸缩:基础设施级别的伸缩。根据集群的利用率向集群内添加或删除工作节点。

2)应用的伸缩:也称为 Pod 的伸缩。根据各项数据指标调整 Pod 特征的处理。

– 横向自动伸缩(HPA)。根据指标增加或减少 Pod 的副本数。

– 纵向自动伸缩(VPA)。指的是增加或减少 Pod 内运行的容器的资源。截止 201801 时,该功能尚在开发。参阅「Container resource consumption—too important to ignore」一文。

9.1. Scaling a Deployment
可以通过命令行手动对部署进行伸缩:

# kubectl scale deployment fnacyapp –replicas=3

如果不想手动伸缩,可以自动伸缩。
Automatically Resizing a Cluster
in GKE
GKE – Google Kubernetes Engine
对集群进行伸缩,跳过……
in AWS
AWS – Amazon Web Services
对集群进行伸缩,跳过……
Cluster Autoscaler
https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler
Karpenter
官网:https://karpenter.sh/
文档:https://karpenter.sh/docs/
仓库:https://github.com/aws/karpenter-provider-aws
HAP | Horizontal Pod Autoscaling
Horizontal Pod Autoscaling
on GKE
在 GKE 上使用 Pod 的横向自动伸缩。
(1)首先创建一个要被 HPA 的对象。
(2)为部署定义 HPA 对象:

# kubectl autoscale deployment “deploy-appserver” –cpu-percetn=40 –min=1 max=5

(3)开始观察他们的行为:

# kubectl get hpa –watch # 观察 HPA

# kubectl get deploy “deploy-appserver” –watch # 观察部署

# kubectl run -i -t loadgen –image=busybox /bin/sh # 生成负载

> while true; do wget -[……]

READ MORE

「kubernetes」- 控制 Pod 在节点上的分配(调度)

问题描述
该笔记将记录:在 Kuberntes 中,如何调度 Pod 资源,以及常见问题的解决办法;
解决方案
实现 Pod 调度(例如 驱逐、亲和、节点选择 等等),与之相关的技术有如下若干方式
nodeSelector
在 Pod.Spec 中,指定 nodeSelector 属性,然后仅具备特定标签的 Node 才会被放置该 Pod 实例:

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
– name: nginx
image: nginx
nodeSelector:
gpu: “true” # 调度器将只在包含标签 gpu=true 的节点中选择

我们也可以将 pod 调度到特定节点:
1)每个节点都有个唯一标签,其中键为 kubernetes.io/hostname,值为该节点的实际主机名,因此我们也可以将 pod 调度到某个确定的节点;
2)但是如果节点离线,标签的唯一性会会导致 pod 不可调度;
3)所以,我们避免使用唯一性的标签,而是应该通过标签选择器考虑符合特定标准的逻辑节点组;
但是 nodeSelector 比较简单无法实现复杂的需求,所以引入 nodeAffinity 特性,而 nodeSelector 将来或许会被淘汰;
nodeAffinity(Pod with Node)
其与 nodeSelector 类似,每个 pod 可以定义自己的节点亲缘性规则,控制 Pod 在节点之间的调度;
这些规则可以允许你指定硬性限制或者偏好限制:
1)对于硬性限制:必须匹配标签才能够调度到节点上;
2)对于偏好限制:则将告知 Kubernetes 对于某个特定的 pod,它更倾向于调度到某些节点上,而 Kubernetes 将尽量把这个 pod 调度到这些节点上面。如果无法满足,则 pod 将被调度到其他某个节点上;
硬性限制的案例,节点必须满足 gpu=ture 才会放置该 Pod 实例:

apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
– name: nginx
image: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 仅影响创建时的调度;[……]

READ MORE

「IP」- 如何确定公网网络地址?

有时,我们需要向对方提供我们的公网地址,或者验证我们的请求是否通过代理服务器(此时应该返回代理服务器地址)。该笔记将记录:查看自己所在网络公网地址的方法。
通过第三方 HTTP 站点(常用)
=

curl “http://ifconfig.me” # https://ifconfig.me/
curl “http://icanhazip.com”
curl “http://ipecho.net/plain”
curl “http://ifconfig.co”
curl “https://ip.sb”

################################################################################

curl checkip.amazonaws.com
curl ifconfig.me
curl icanhazip.com
curl ipecho.net/plain
curl ifconfig.co

## store output in $server_ip ##
server_ip=”$(curl ifconfig.co)”

## Display it ##
printf “Server public ip4 %s\n” $server_ip

通过自建的 HTTP 服务(自建)
我们使用 Nginx 来返回公网地址(需要具有公网服务器)使用如下配置:

server {
listen 80;
server_name ifconfig.toolbox.d3rm.org;
location / {
return 200 $remote_addr;
}
}

当在命令行中使用 curl 发送 http 请求时,将返回网络地址:

# curl ifconfig.toolbox.d3rm.org
1.2.3.4.5

其他:通过 DNS 获取

dig +short myip.opendns.com @resolver1.opendns.com
dig TXT +short o-o.myaddr.l.google.com @ns1.google.com

相关链接
淘宝 IP 地址库:https://ip.taobao.com/ipSearch
参考文献
How To Find My Public IP Address From Command Line On a Linux[……]

READ MORE

「CPU」- Engineering Sample vs. Qualification Sample

问题描述
该笔记将记录:在 CPU 中,与 ES、QS、不显、正显 等等术语相关的内容,以及相关问题的解决办法;
解决方案
该笔记的内容复制于 走看看/科普:关于 ES 版的 CPU(正显、不显、QS 等) 笔记,并进行简单的排版整理,以便于我们理解;
处理器的推出过程
CPU 的推出过程大概分这几个步骤:
1)ES1:测试架构和工艺制程
2)ES2:修正大量 BUG 这个时候的 CPU 已经能用了,但还存在隐患
3)ES3(QS):质量认证样品 型号确定,在电脑上能显示型号和规格 可能存在或不存在轻微隐患
4)正式版处理器:大量出货
ES 版,全称 Engineering Sample(工程样板)
简单说, ES 的 CPU 是还没正式推出前的工程 CPU 即测试 CPU;
每款正版 CPU 推出前,和很多软件一样,早期存在许多 bug(问题),需要修改,因此 ES 版 CPU 就是担当经受严格的测试考验,用来做各种超频和热功耗等的极限测试用的,从而发现问题、修正问题。当测试到后期,产品才逐步成熟;
QS,全称 QualificationSample(质量认证样品)
也叫 ES 正显版(或带显版),是为了区别 ES 的一种叫法,实际上,QS 版也是 ES 版的一种(ES3),但 QS 版应该算是最好的 ES 版了,一般是在正式版推出前的最终样品版本,无限接近于正式版,或 与之后发布的正式版并无区别。但其货源也不像 ES 那样是免费供应,而是 INTEL 向工厂收取少量费用卖出的,价格仍低于正式版不少,稳定性各方面和正式版一样,主用来给 OEM 等厂商测试之用;
不显(ES)vs. 正显(QS)
由于 ES 版 CPU 在修改过程中,会出现各种版本,用 CPU_Z 或系统中的电脑属性检测,就可分为“不显”、“正显”、各种不同的步进修订号;
不显(ES):
1)就是系统上、CPU-Z 上不能识别 CPU 名称或虽能显示名称却不显示正确规格型号;
2)在 CPU-Z 上看 CPU 规格上面显示 0000;
正显(QS):
1)就是系统上、CPU-Z 上能正确显示 CPU 的名称和版本型号;
步进和修订:
1)所谓步进就是每次更新的版本,步进越靠后越好,比如,步进 1 步进 0 就是最初的,后来步进 3 啊 5 啊;
2)修订 B 几 C 几 D 几,代表后面修改的版本;
Intel CPU 的步进排序(左旧右新):B2 < C0 < E0 < G0 < L2 < M0 < R0
第一类、ES(不显)处理器
早期不能正确显示名称和型号规格 ,但显示主频,这是”不显规格“的 ES CPU;
如下所示,为无名称、无规格、无修订的“不显”志[……]

READ MORE

「COMPUTER-NETWORKING/VPN」- IPSec | 概念 | 术语

协议体系(组成部分)
IPSec 并非单独协议,其是由系列协议组成,其是定义在 IP Network 上数据安全的整套体系结构;
IPSec VPN 主要由如下协议套件组成:

IPsec 提供了两种安全机制:加密和认证;
安全协议
IPSec 使用 AH(Authentication Header)和 ESP(Encapsulating Security Payload)两种安全协议来传输和封装数据,提供认证或加密等安全服务;
1)AH:其功能为数据源验证、数据完整性校验、防报文重放;但 AH 不支持加密功能,所以无法加密被保护数据;
2)ESP:提供 AH 的所有功能外(但其数据完整性校验不包括 IP Header);还能加密 IP 报文;
当安全协议提供认证或加密等安全服务时,需要有密钥的存在。AH 和 ESP 提供的安全功能依赖于协议采用的验证算法、加密算法;
加密
IPsec 采用对称加密算法对数据进行加密和解密。数据发送方和接收方使用相同的密钥进行加密、解密;
ESP 能够对 IP Packet 内容进行加密保护,防止报文内容在传输过程中被窥探。通过 对称密钥 系统,来实现加密,它使用相同的密钥对数据进行加密和解密;
一般来说 IPSec 使用加密算法有以下几种:DES;3DES;AES;
验证
AH 和 ESP 都能够对 IP Packet 的完整性进行验证,以判别报文在传输过程中是否被篡改。验证算法的实现主要是通过杂凑函数,杂凑函数是一种能够接受任意长的消息输入,并产生固定长度输出的算法,该输出称为消息摘要。IPSec 对等体计算摘要,如果两个摘要是相同的,则表示报文是完整未经篡改的;
IPsec 采用 HMAC(Hash-based Message Authentication Code)功能,比较数字签名进行数据完整性和真实性认证。一般来说 IPSec 使用两种验证算法:MD5;SHA-1;
密钥交换
密钥交换的方式有两种:
1)带外共享密钥:

在发送、接收设备上,手工配置静态的加密、验证密钥。双方通过带外共享(例如通过电话或邮件方式)的方式保证密钥一致性;

这种方式的缺点:

1)可扩展性差,在点到多点组网中配置密钥的工作量成倍增加;

2)另外,为提升网络安全性需要周期性修改密钥,这种方式下也很难实施;

2)通过 IKE 协议自动协商密钥:

IKE(Internet Key Exchange,因特网密钥交换)协议建立在 ISAKMP 定义的框架上,其基于 UDP 的应用层协议,采用 DH 算法在不安全的网络上安全地分发密钥。它为 IPsec 提供自动协商密钥、建立 IPsec 安全联盟的服务,能够简化 IPsec 的[……]

READ MORE

「CURL」- 访问地址以传输或拉取数据

内容: 介绍 cURL Version 7.50
认识
curl 是一个命令行工具,用于从服务器获取数据或者向服务器发送数据。命令 curl 是一个用于从服务器拉取或发送数据的工具。使用以下支持的协议之一:DICT,FILE,FTP,FTPS,GOPHER,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,POP3,POP3S,RTMP,RTSP,SCP,SFTP,SMB,SMBS,SMTP,SMTPS,TELNET,TFTP。该命令旨在无需用户交互即可工作。
命令 curl 提供了大量有用的技巧,如代理支持、用户身份验证、FTP 上传、HTTP 的 POST 请求、SSL 连接、cookie、文件传输恢复、Metalink 等等。正如本文下面解释的,功能多到让人头晕目眩!
curl 提供了一大堆功能,比如支持代理、用户认证、FTP 上传、HTTP POST、SSL 链接、cookie、Metalink、文件传输恢复等。正如手册所说: As you will see below, the number of features will make your head spin!
官网:https://curl.haxx.se
文档:https://curl.haxx.se/docs/manpage.html
仓库:https://github.com/curl/curl
组成
curl 依赖于 libcurl 库,”man 3 libcurl“查看 libcurl 的详细信息。命令 curl 中所有与传输相关的功能都由 libcurl 为提供支持。有关详细信息,请参阅 libcurl(3)。
构造
CentOS Linux release 7.9.2009 (Core)
安装最新版本:

# vim /etc/yum.repos.d/city-fan.repo
[CityFan]
name=City Fan Repo
baseurl=http://www.city-fan.org/ftp/contrib/yum-repo/rhel$releasever/$basearch/
enabled=1
gpgcheck=0

# yum clean all
# yum install curl

安装的可执行程序
curl | is a command line tool for transferring files with URL syntax.
curl-config,获取 libcurl 的安装信息,命令 curl-config 显示有关 curl 和 libcurl 安装的信息。
prints information about the last compile, like librari[……]

READ MORE

「Harbor」- 常见问题处理

解决方案
Harbor API
How to Browse and Query Harbor Registry using REST API
在 Harbor 的 GitHub 仓库中的「docs/swagger.yaml 1.5.3」为 Harbor 的 API 文档。
复制到“http://editor.swagger.io”中进行显示。
Harbor CLI
https://github.com/int32bit/python-harborclient
取回 admin 密码
How to reset and retrieve forgotten Harbor admin password (76289)
该方法仅适用于没有通过 Harbor GUI 修改密码的场景,否则只能重置。
第一步、进入容器

# Harbor version <=1.7:
docker exec -it “<harbor-adminserver container id>” bash

# Harbor version >=1.8:
docker exec -it “<harbor-core container id>” bash

第二步、查看密码

env | grep HARBOR_ADMIN_PASSWORD

重置 admin 密码

docker exec -it “<harbor-db container id>” bash

psql -U postgres -d registry
> select * from harbor_user;
> update harbor_user set salt=”, password=” where user_id = “<admin user_id>”;

# 重启服务,也可能无需重启,我们没有重置过,这里治理参考官方文档进行记录。

只能复制 HASH 而不能复制 TAG
Why is copy pull followed by hash, instead of tag?? · Issue #12763 · goharbor/harbor
在 Harboar 中,复制拉取命令,但是拉取命令没有使用 TAG 而是使用 HASH 作为标签。
根据描述,在 2.1 版本能够复制 TAG 而不是 HASH 信息。
# 07/21/2021 即使升级到 2.3.0 版本,那个按钮还是复制 HASH 信息。然而,需要点击前面的 HASH 值才会进入新页面,然后才能复制带有 TAG 的 docker pull 命令。
library 的作用
Remove /library prefix[……]

READ MORE

「TMV」- 微信公众平台 | Wechat Public Platform | 学习笔记

认识
微信公众平台(Wechat Public Platform),简称公众号,是在微信应用程序(App)内推出的,为个人、企业和组织提供业务服务与用户管理能力的服务平台。
2012 年 8 月 23 日,微信公众平台正式上线,曾命名为“官号平台”“媒体平台”“微信公众号”,最终定位为“公众平台”。我们也使用“公众平台”来称呼,避免与其他术语混淆。
组成
—— 该“组成”指构建“微信公众平台”所需要的技术组件。但是,作为用户,我们并不需要关系“微信公众平台”的组成。
构建
—— 该“构建”指获得微信公众平台的方法。作为用户,我们更加关注于如何获得微信公众平台的功能,而非从零构建微信公众平台。
访问 https://mp.weixin.qq.com 站点,根据官方提示进行注册即可。
性质
—— 该部分将记录微信公众平台具有的功能。
服务号
场景:侧重于服务交互,旨在为企业、政府或组织提供直接的服务和沟通渠道,实现人与商品或服务的连接。服务号通常提供在线购物、在线客服、会员中心等服务。
服务号可以给企业和组织提供更强大的业务服务与用户管理能力,帮助企业快速建立全新的公众号服务平台。服务号主要偏向服务类交互,其适用群体包括媒体、企业、政府或其他组织。
服务号的特点如下:

每个月可以发四条推送,直接推送到客户并有消息提醒。
服务号通过认证之后,支持九大接口功能。
服务号与企业号通过认证后,支持微信支付功能。
支持订阅号升级为服务号,但不支持服务号转换回订阅号。微信 4.5 版本之前申请的订阅号允许升级为服务号,但只有一次升级机会,并且不支持服务号转换回订阅号。

公众号
场景:侧重于信息传播,为用户提供资讯、知识、娱乐等内容。公众号是内容创作者与用户进行信息连接的重要渠道,主要用于打造品牌影响力和吸引粉丝关注。
订阅号
现(03/31/2025)无论是手机微信还是微信公众平台,我们没有直接看到“订阅号”这个术语。
微信小程序
小程序是一种新的开放能力,开发者可以快速地开发一个小程序。小程序可以在微信内被便捷地获取和传播,同时具有出色的使用体验。
应用
向用户发送消息

配置公众号:在微信公众平台 -> 开发 -> 接口权限 -> 网页服务 -> 网页授权获取用户基本信息中配置授权域名
引导用户访问授权页面:该步骤是为了获取处理回调获取 code 值,使用 code 换取用户的 OpenID
后续与用户相关的操作都将基于 OpenID 进行。

参考
微信公众平台_百度[……]

READ MORE

「Docker Registry」- 3.Problem Solving (how-to)

镜像管理
Docker Registry 2.0 – how to delete unused images? – Stack Overflow
GitHub/andrey-pohilko/registry-cli
Docker Registry API Docker Registry HTTP API V2
从 Docker Registry 中删除镜像:One liner for deleting images from a v2 docker registry
Registry UI
默认的 Docker Registry 服务是没有 UI 的,只能通过 API 去操作。
该笔记将将记录:与 Docker Registry 配置使用的 UI 工具,以及相关问题解决办法。
已知方案:
1)GitHub/atcol/docker-registry-ui
2)DockerHub/atcol/docker-registry-ui
3)GitHub/Joxit/docker-registry-ui
ATCOL / Docker Registry UI
该 UI 没有认证功能。如果想要对外提供服务,则请加上前端保护,如果使用 Nginx,然后配置 Basic Auth 认证。
Repositories behind https not working #108

keytool -importcert -file ca.crt -alias ca -keystore truststore -storepass password -noprompt

docker run … -v $PWD/truststore:/tmp/truststore \
-e ‘JAVA_OPTS=-Djavax.net.ssl.trustStore=/tmp/truststore -Djavax.net.ssl.trustStorePassword=password’ …

docker run -d -p 8080:8080 -v /srv/certs-java/truststore:/tmp/certs-java/truststore \
-e ‘JAVA_OPTS=-Djavax.net.ssl.trustStore=/tmp/certs-java/truststore -Djavax.net.ssl.trustStorePassword=password’ \
atcol/docker-registry-ui

images not shown #173[……]

READ MORE

「COMPUTER」- Display Cable and Adapter

台式机多显示器接口扩展方案
DeepSeek / 台式机接多个显示器,需要增加接口,需要购买什么硬件?
要在台式机上接多个显示器,通常需要增加视频输出接口,具体硬件需求取决于你的显卡和显示器的接口类型。以下是几种常见的解决方案:
### 1. 使用现有显卡的多接口
– 大多数现代显卡(如NVIDIA RTX 50系列或AMD RX 7000系列)通常提供多个视频输出接口,如:

– HDMI(支持4K@120Hz或更高)

– DisplayPort (DP)(支持高刷新率和高分辨率)

– USB-C(带DP Alt模式)(适用于部分高端显示器)
– 如果你的显卡已经有多个接口(如2个HDMI + 2个DP),可以直接连接多个显示器,无需额外硬件。

### 2. 增加独立显卡(适用于无多接口的情况)
– 如果主板集成显卡或现有显卡接口不足,可以升级到支持多输出的独立显卡,如:

– NVIDIA RTX 5080/5090(支持4个显示器)

– AMD RX 7900 XT(支持4个显示器)
– 高端显卡通常提供多个DP和HDMI接口,适合多屏办公或游戏。

### 3. 使用多屏扩展设备
– USB 3.0/Type-C 转 HDMI/DP 适配器(适用于笔记本或台式机USB接口富余的情况)
– DisplayPort MST Hub(通过DP 1.2/1.4的菊花链功能连接多个显示器)
– PCIe 多口显卡扩展卡(如4口HDMI或DP输出卡,适用于专业多屏需求)
### 4. 更换主板或使用集成显卡(低成本方案)
– 部分主板(如Intel或AMD APU平台)支持多显示器输出,可通过主板上的HDMI/DP接口扩展。
– 但性能可能受限,不适合高分辨率或高刷新率需求。
### 5. 注意事项
– 接口兼容性:确保显示器接口(HDMI 2.1、DP 1.4等)与显卡匹配,避免带宽不足导致分辨率或刷新率降低。
– 显卡负载:多显示器会增加GPU负担,尤其是高分辨率(4K)或高刷新率(144Hz+)场景,建议使用高性能显卡。
– 电源需求:多显示器+高性能显卡可能需更高功率电源(如1000W以上)。
### 推荐方案
– 办公/普通多屏:使用现有显卡多接口或USB-C转HDMI适配器。
– 游戏/专业多屏:升级到RTX 5080/5090或AMD RX 7900 XT等高端显卡。
– 预算有限:使用DP MST Hub或主板集成显卡(适用于低负载场景)。
如果你的显卡接口不足,最直接的解决方案是升级显卡或使用扩展设备。具体选择取决于你的预算和需求。[……]

READ MORE

「DOCKER」- 搭建 Registry Mirror 服务 | Registry as a Pull Through Cache

相关资源
源码:https://github.com/distribution/distribution/
镜像:https://hub.docker.com/_/registry/
文档:https://distribution.github.io/distribution/
on Kubernetes | with Helm Chart | by twuni
Docker Hub/Official Image/Registrytwuni/docker-registry.helmdocker-registry 2.1.0 · twuni/twuni
该笔记将记录:在 Kubernetes Cluster 中,通过 Helm 部署 Docker Registry Mirror 的方法,以及相关问题的解决方案。
https://github.com/twuni/docker-registry.helm

helm repo add twuni https://helm.twun.io
helm repo update twuni

helm pull twuni/docker-registry # CHART 2.1.0, APP 2.7.1
helm show values ./docker-registry-2.2.3.tgz > docker-registry-2.2.3.tgz.helm-values.yaml
… ingress:
… persistence.storageClass: gp2
… proxy.enabled: true

helm upgrade –install –namespace registry-mirror –create-namespace \
docker-registry-mirror ./docker-registry-2.2.3.tgz -f docker-registry-2.2.3.tgz.helm-values.yaml

然后,测试是否生效:

# vim /etc/docker/daemon.json
{
“registry-mirrors”: [“https://registry-mirror.example.com”]
}

# docker pull hello-world

# kubectl exec -it docker-registry-mirror-79c994c65b-64hjv — ls /var/lib/registry/docker/registry/v2/repositories/libra[……]

READ MORE

「Kubernetes Objects」- ReplicationController

问题描述
该笔记将记录:参照官方文档,学习 ReplicationController 对象;
解决方案
ReplicationController,确保在任何时候都有指定数量的 Pod 副本在运行。换句话说,ReplicationController 确保一个容器或一组相似的容器始终处于可用状态;
参考文献
Kubernetes/Concepts/ReplicationController[……]

READ MORE

「Docker Registry」- 常见错误汇总

Building, Customizing, and Contributing to Harborhttps://goharbor.io/docs/2.12.0/build-customize-contribute/
[Sol.] 页面显示 Loading 动画,无法显示登陆界面
# 05/29/23 Harbor v2.8.1
问题描述:服务部署完成,我们尝试通过 Firefox 浏览器访问。但是页面一直显示 Loading 动画(转圈),无法显示登陆界面。
原因分析:浏览器检查元素,网络并无请求错误,但是控制台显示 JavaScript 执行错误。所以我们猜测是浏览器兼容性问题。
解决方案:更换 Chrome 或 Chromiue 浏览器,
fail to delete chart version: remove xxx.tgz: no such file or directory
问题描述:当删除 Chart 仓库时,提示标题错误
原因分析:某个 Chart 具有多个相同的 Version 标签,所以删除第一个之后,对于的 .tgz 也被删除,而后续的多个具有相同 Version 标签的 Chart 无法找到与之对应的 tgz 文件,而引发删除失败。
解决方案:进入 data/chart_storage 目录,随便创建与之对应的 .tgz 文件,让其有文件可删除,然后再执行删除动作。
…read udp 127.0.0.1:39705->127.0.0.11:53: i/o timeout…
Better selection of DNS server by thaJeztah · Pull Request #41022 · moby/mobyUnable to download trivy vulnerability DB · Issue #14146 · goharbor/harbordocker-dns-lookup-example/README.md at master · bltavares/docker-dns-lookup-example
问题描述

{“error”:”running trivy wrapper: running trivy: exit status 1: 2022-06-12T12:51:58.354Z INFO Need to update DB
2022-06-12T12:51:58.354Z INFO
Downloading DB…
2022-06-12T12:52:10.361Z FATAL DB error: failed to download v[……]

READ MORE