Alpine Linux 离线安装apk

同事开发的app,部署到aliyun上的单机版supOS后无法正常运行,初步排查发现是pod内DNS问题,无法解析外部域名,但是在ECS实例层我们可以正常解析。Alpine Linux镜像带有apk包管理工具,但是又因为DNS问题,无法从公网拉取软件包,所以需要离线安装apk包。

后续根因是阿里云的region级DNS服务器100.100.2.136和100.100.2.138处于100.64.0.0/10网段,和supOS默认的POD_CIDR重叠。

  1. exec -it进入pod,查询镜像的操作系统版本 cat /etc/os-release

如图,可以得知是Alpine Linux v3.7

  1. 在其他环境(比如本地docker环境),pull一个alpine:3.7镜像,并运行 docker pull alpine:3.7docker run -it --name a37 alpine:3.7 /bin/sh

务必保证Alpine Linux版本一致,否则软件的依赖关系可能会有变化

  1. 使用apk add tcpdump可以安装tcpdump

同时观察到依赖包的版本和安装顺序

可以看到先安装了libpcap,随后安装了tcpdump

  1. 使用apk fetch tcpdumpapk fetch libpcap

将apk包下载保存到容器中

  1. 如果使用的是Docker Desktop,可以从“Files”很方便地将文件保存到外面的系统
  1. 将文件传输到服务器,然后再传输进pod内

比如用python3 -m http.server 18888起一个简单的服务器,然后从pod内wget下载

  1. apk add --allow-untrusted <path_to_package>安装后即可运行tcpdump。注意,需要注意安装的先后次序。具体次序参步骤3中包被安装的顺序。

Deploy EMQX cluster with docker-compose

To create an EMQX cluster to provide MQTT service and keep it as simple as much, we can do it with docker and docker-compose only.

Create /volumes/emqx-data/ on each node for persistent storage of configuration. Make sure to give write permissions.

On the first node (192.168.31.61), create a docker-compose.yaml file with content below

version: '3'

services:
  emqx1:
    image: emqx:5.5.0
    container_name: emqx1
    environment:
    - "EMQX_NAME=emqx1"
    - "EMQX_HOST=192.168.31.61"
    - "EMQX_NODE_NAME=emqx1@192.168.31.61"
    - "EMQX_CLUSTER__DISCOVERY_STRATEGY=static"
    - "EMQX_CLUSTER__STATIC__SEEDS=[emqx1@192.168.31.61,emqx2@192.168.31.62,emqx3@192.168.31.63]"
    network_mode: "host"
    healthcheck:
      test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
      interval: 5s
      timeout: 25s
      retries: 5
    volumes:
      - /volumes/emqx-data/emqx1_data:/opt/emqx/data

On the second node (192.168.31.62), create a similar docker-compose.yaml file with content below

version: '3'

services:
  emqx1:
    image: emqx:5.5.0
    container_name: emqx2
    environment:
    - "EMQX_NAME=emqx2"
    - "EMQX_HOST=192.168.31.62"
    - "EMQX_NODE_NAME=emqx2@192.168.31.62"
    - "EMQX_CLUSTER__DISCOVERY_STRATEGY=static"
    - "EMQX_CLUSTER__STATIC__SEEDS=[emqx1@192.168.31.61,emqx2@192.168.31.62,emqx3@192.168.31.63]"
    network_mode: "host"
    healthcheck:
      test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
      interval: 5s
      timeout: 25s
      retries: 5
    volumes:
      - /volumes/emqx-data/emqx2_data:/opt/emqx/data

On the third node (192.168.31.63), similarly

version: '3'

services:
  emqx1:
    image: emqx:5.5.0
    container_name: emqx3
    environment:
    - "EMQX_NAME=emqx3"
    - "EMQX_HOST=192.168.31.63"
    - "EMQX_NODE_NAME=emqx3@192.168.31.63"
    - "EMQX_CLUSTER__DISCOVERY_STRATEGY=static"
    - "EMQX_CLUSTER__STATIC__SEEDS=[emqx1@192.168.31.61,emqx2@192.168.31.62,emqx3@192.168.31.63]"
    network_mode: "host"
    healthcheck:
      test: ["CMD", "/opt/emqx/bin/emqx_ctl", "status"]
      interval: 5s
      timeout: 25s
      retries: 5
    volumes:
      - /volumes/emqx-data/emqx3_data:/opt/emqx/data

Enter the folder where the docker-compose.yaml file is located, execute docker compose up -d

If nothing goes wrong, you should be able to see a running container with STATUS as healthy.

By visiting the webpage http://192.168.31.61:18083 (default credentials: admin/public), you should be able to see 3 nodes in cluster.

If you need high-availability, you should carry on deploying nginx or HAProxy, or alternatively, utilize load balancers on cloud to distribute traffic to ports on these EMQX nodes.

使用Corosync/Pacemaker实现Ubuntu 20.04上的HA cluster

1. 所有节点安装软件

apt install pacemaker corosync pcs

2. 关闭防火墙

ufw disable

3. 所有节点启动pcsd

systemctl enable –now pcsd

4. 所有节点为hacluster用户设置密码为supos

echo “hacluster:supos” |chpasswd hacluster

5. 所有节点编辑/etc/hosts,设置IPhostname映射关系,比如

192.168.31.201 supos-nfs1
192.168.31.202 supos-nfs2

6. 编辑/etc/corosync/corosync.conf

7. 在一个节点上操作节点间认证

pcs host auth supos-nfs1 addr=192.168.31.201 supos-nfs2 addr=192.168.31.202 -u hacluster

addr= 用来指定节点IP

-u 指定使用的用户名为hacluster

可能会有图中的报错Error: Unable to synchronize and save known-hosts on nodes: supos-nfs2. 建议检查本地/var/lib/pcsd/known-hosts文件,确保其中包含了集群内所有节点,并且都有token。然后,将这个文件复制到集群内其他节点上,以保证互相认证的成功。
/var/lib/pcsd/known-hosts文件内容可能如下

8. 在一个节点上操作组建集群

不同的pcs可能会在组建集群的时候有不同的命令语法,比如是否通过–name指定集群名称等。
pcs –version获取到版本信息,此次使用的是0.10.4

pcs cluster setup –force nfs-cluster supos-nfs1 addr=192.168.31.201 supos-nfs2 addr=192.168.31.202

此处使用的pcs,在setup命令后面的紧接的是集群名,老版本是通过–name指定的。大致格式如下

pcs cluster setup <cluster_name> <node_1_hostname> addr=<node_1_IP> <node_2_hostname> addr=<node_2_IP>

如果遇到下图无法解析known-hosts文件的报错,可以尝试pcs cluster destroy命令,然后再创建集群

如果集群被正确组建,那么在其他节点上可以看到同步过来的/etc/corosync/corosync.conf和/var/lib/pcsd/known-hosts
内容应该如下,包含了所有node信息

9. 在一个节点上启动集群内所有节点

pcs cluster start –all

并设置服务开机自启

pcs cluster enable –all

10. 检查集群状态

pcs status

Node List中,所有节点均应处于Online状态

11. 设置集群属性(具体作用未知,待研究)

pcs property set stonith-enabled=false
pcs property set no-quorum-policy=ignore

12. 创建IPaddr2类型的浮动IP资源

pcs resource create floating_ip ocf:heartbeat:IPaddr2 ip=192.168.31.200 cidr_netmask=24 op monitor interval=10s

13. 将资源绑定到nfs-cluster

crm configure group nfs-cluster floating_ip

pcs status resources查看

此时,应该可以在一台上看到此浮动IP。执行ip -4 addr 可以看到192.168.31.200的IP地址。

测试资源(VIP)是否可以成功漂移到其他节点

pcs resource move floating_ip supos-nfs2

lighttpd配置URL路由

由于我作(zuō),重新刷了Raspberry Pi Zero W的系统,所以原来的lighttpd配置需要恢复。但恢复不是简单地把配置文件一覆盖就好了(覆盖完发现访问不符合预期)。折腾了两天时间才搞定,所以记录一下,以备下次再作(zuō)或者手痒。

先说希望实现的效果:使用一个lighttpd进程,同时提供 AriaNg的页面 和 展示/mnt/目录下的文件(文件服务器),即

访问<host>:80 可以打开 AriaNg页面

访问<host>:80/file 可以打开 文件服务器

第一个简单,下载最新的AriaNg,解压缩放到server.document-root下即可。

第二个原配置文件中有一段

$HTTP[“url”] =~ “^/file” {

server.document-root = “/mnt/”

dir-listing.activate = “enable”

}

依旧能清楚地记得当初调试这一段时学到的一些东西,

=~ 表示perl式正则匹配……

^/file表示以/file开头

参考原配置,在/etc/lighttpd/conf-enabled/目录下创建了10-dir-listing.conf的软连接,用于开启目录下文件列举

此时访问<host>:80/file却报错404,百思不得其解。$HTTP["url"] =~ "^/file" 这个条件时当时调了好久才调对的呀……我拷贝配置文件过来没改过呀……

accesslog和errorlog几乎没有日志……

最后不知道为啥搜到了debug开关,https://redmine.lighttpd.net/projects/lighttpd/wiki/Debugvariables

主配置文件中增加一行

debug.log-request-handling = "enable" 
然后访问的时候看到了访问/file会导致lighttpd读取/mnt/file目录……

于是在/mnt/目录下创建了一个file的软连接,指向/mnt/toshiba后,就解决了这个问题

如何在TeamSpeak 3中连接Windy的树洞

首次打开TeamSpeak 3会再次提示软件使用条款,同样需要拖动到最底部,然后才能选择”I accept”。

另外一个事情就是可能会碰到这个提示,这是连接TeamSpeak官方的myTeamSpeak服务,可以选择“Continue without logging in”跳过。

以上是未安装中文翻译包的截图,这时候可以在右下角找到图标,右击 – Quit 退出程序。

然后双击打开Chinese_Translation_zh-CN.ts3_translation 安装翻译

再次打开就是中文版的界面了

点击 连接 – 连接服务器

服务器别名或地址中输入 office.unibutton.com,密码群内交流,给自己取一个别人看得懂的昵称就可以连进Windy的树洞了。

Teamspeak 3 安装和汉化

1. 从官网下载安装包

下载页 https://www.teamspeak.com/zh-CN/downloads/

或者直接点击下面这个链接下载当前最新版本3.5.6

https://files.teamspeak-services.com/releases/client/3.6.2/TeamSpeak3-Client-win64-3.6.2.exe

如果下载有困难,可以从我的服务器下载 https://windywind.tk:8080/TeamSpeak3-Client-win64-3.6.2.exe

2. 下载汉化包

Github链接 https://github.com/jitingcn/TS3-Translation_zh-CN/releases/download/snapshot/Chinese_Translation_zh-CN.ts3_translation

如果下载有困难,可以从我的服务器下载 https://windywind.tk:8080/Chinese_Translation_zh-CN.ts3_translation

3. 安装客户端

打开TeamSpeak3-Client-win64-3.5.6.exe完成安装,并启动一次

安装过程中,在许可页面需要拖到最下面,然后才能够选接受协议

4. 安装汉化包

双击打开Chinese_Translation_zh-CN.ts3_translation安装

然后再次启动TeamSpeak就应该是简体中文界面了

树莓派OpenCV玩耍避坑指南

重点是避坑和坑!

原来收藏过一篇用树莓派+Python+OpenCV实现监控和动作检测的中文翻译文章原文和译文写得可读性都很不错。可惜原文已经404了,只好找了两个转载的当备份

https://blog.ggrarea.cn/archives/1807.html

以及

https://noahzhy.github.io/2018/02/02/%E7%94%A8-Python-%E5%92%8C-OpenCV-%E6%A3%80%E6%B5%8B%E5%92%8C%E8%B7%9F%E8%B8%AA%E8%BF%90%E5%8A%A8%E5%AF%B9%E8%B1%A1/

其中的完整Python代码可以在

https://gist.github.com/vishvanand/60afc7b998d885df66e9c4f07cf57ab0

获得(代码和原文有区别,请直接到原文复制代码吧)

想起来搞这个是因为最近想学点新的东西,又想利用把吃灰的树莓派2B利用起来,就去买了摄像头。

然后就开始了不断的踩坑和填坑……&(%&……¥%%……¥%……

升级PIP

参照文档第一步pip install imutilspip install opencv-python就失败了,树莓派上的pip太老了,要升级。但是pip install pip -U的方式自升级也不能成功。通过apt卸载再安装也依旧是之前的pip版本。

最后的成功的方案是apt remove python-pip卸载,然后通过官方get-pip.py脚本安装成功。这中间又碰到了系统中ca-bundle太老,不能信任很多服务端证书的问题。

最后使用pip install --trusted-host pypi.tuna.tsinghua.edu.cn opencv-python的方式可以信任证书(这个方式适用于版本 >= 20.x 的pip。另外,这里–trusted-host后面跟的是已配置的pypi源地址)

安装OpenCV

事情还没完,你以为pip install --trusted-host pypi.tuna.tsinghua.edu.cn opencv-python就能成功安装opencv了吗?那你就too young了。

有一个事情是NumPy(OpenCV的依赖包)停止了对Python 2.x的支持,要安装也得用pip3 install opencv-python

再看看这编译日志,抠脚想象树莓派2B的性能(等了半天,我想连上4B去安装试试,结果后开始的4B进度比2B快,先跳Installing build dependencies

无意间看到有另外一个方法可以安装OpenCV,就是通过apt-get install python-opencv,结果秒秒钟完成……

进入交互式的Python CLI,执行前面几个import都不报错了,差点哭了……

Understand 5.0——强大的阅读代码的奇计淫巧

 

  • 强大的编码图形化分析工具
    understand control-flow-graph
    Understand offers graphs that allow you to see how your code connects (dependencies), how it flows (control flow graphs), what functions call other functions (call graphs), and many more. There are many customization options to easily allow you to display only what you are interested in seeing so the graph is best suited to what you need.(摘自官网)

 

  • 支持编程语言不算多,但目前够用:

 

  • 多平台:MacOS、Windows、Linux

 

  • 所有版本下载地址:https://scitools.com/download/all-builds/(页面上的zip包只是安装包压缩了一下……不懂为什么要这么做)

 

  • 中文版下载地址:https://scitools.com/download/chinese/ (换了个软件名字?还是只是中文翻译补丁?not sure)中文版Build944不支持用Code离线注册,还是用英文版吧

 

  • XX注册很easy

林奕含

——去TM的蓝绿。

听说这个名字是因为凤凰卫视《锵锵三人行》的一期节目。

看过之后,我自然也去搜了节目里提到的专访视频,看到视频的第一眼,当然是被林本人深深吸引,不单单是外表的美丽,更是让人惊叹不已的才华。视频中,我看到的是一个有信仰、有学识的女子,只是这样一个美丽的女子经历了一段不太美丽的路程。我看到的是一个才女在受到“欺骗”之后,在信仰被颠覆之后,对这个世界表达着自己最深切的困惑。

整个访谈看似平静,但是这样的平静背后,不知林本身承受了多少挣扎。她也许是想呐喊的,但她知道她的痛苦和能发出的声音根本不在一个量级,即使发出吵闹的声响,在一些人看来可能也只是噪音,所以只好委曲求全,暂先“按下不表”。

这是林辞世前8天的采访,采访的视频经过了剪辑,删去了很多影响观看的停顿、哽咽。即使如此,依然可以看到林不时的呼吸困难,甚至略有语无伦次(而后又有采访的删减部分放出,可以从更多的角度看到林的困难)。

林本是一才女,高中入读的是国立台南女子高级中学数理资优班;高三学测获得“满级分”的佳绩;第一次“高考”,大概是顺从了家长的意见,考入台北医学大学医学系;休学后,第二年又考入国立政治大学中国文学系,也算圆了自己的一个梦想。作为一个经过高中考验的人,不难发现其文理皆优是多么难得的一件事。

但是后来,随着事情发酵,不知道台湾的媒体或者舆论怎么地就把这事和蓝绿政治联系起来,和统独联系起来。争论从林几岁与陈姓老师发生性关系,到了林家人如何深绿,如何炒作利用此事。

在我看来,我们首先要搞清楚的是林为何抑郁。台湾16岁就算成年,但如果发生的是诱奸,或者事后仍对林产生不良影响的性关系,那又和年龄有什么关系呢?

换个角度来看,16岁成年的界限也不一定对每个人都适用。一个人,不可能在过生日的那天一夜长大。更何况中产家庭中的子女,更多地被寄予“好好念书”的期望。在学校的埋头读书的时间越多,阅历可能就相对越少,越趋不谙世事。当一个单纯美丽的孩子暴露于这个丑陋的世界中,素手无策和毫无还手之力也是可以遇见的必然。

不管怎样,不论如何,林的悲痛我是可以体会的,什么蓝绿政治,统独博弈,在一个弱者的悲痛经历上大作文章之人,其居心我不知该如何看待。林在采访中也说,她关心的不是大的体系,大的结构,不想说大的词句,因为在一个个鲜活的生命面前,这些都是空洞乏力的,每个生命都容不得99%之外的那1%的疏忽。没有谁就该注定下地狱。

斯人已逝,其志长存。

————————————————————————————————————————————————

图片来自 https://static.ettoday.net/images/78/d78343.jpg

Kickstart 无人值守安装

——本文以本地ISO镜像为例,说明Kickstart安装

 

Kickstart 给用户提供了一种自动化安装红帽企业Linux 的方法。Kickstart 文件可以存放于单一的服务器上,在安装过程中被独立的机器所读取。这个安装方法可以支持使用单一Kickstart 文件在多台机器上安装红帽企业版Linux。

Kickstart 安装可以使用本地光盘、本地硬盘驱动器,或通过NFS、FTP、HTTP 来执行。使用原版光盘内的文件即可制作一张Kickstart无人值守光盘。

 

  1. 安装kickstart 软件
#yum -y install system-config-kickstart

 

  1. 打开kickstart 工具配置ks 脚本

#system-config-kickstart &

  1. 基本配置

指定root密码、安装方式、bootloader配置、分区配置、网络配置、认证配置、SELinux及防火墙、显示配置、安装的软件包、安装前脚本、安装后脚本。

配置完成后保存为文件即可(我在附录中附上了一个示例)。

 

  1. 配置isolinux

以/local/为本地光盘拷贝的根目录为例,进入修改/local/isolinux/isolinux.cfg,将第一行改为

default ks

在文件末尾添加

label ks

kernel vmlinuz

append ks=cdrom:/ks.cfg initrd=initrd.img

 

  1. 生成ISO镜像

将保存的Kickstart配置文件复制到/local/下,运行iso.sh脚本。脚本内容如下:

#/bin/sh!

 

 

mkisofs -v -R -J -joliet-long -ucs-level 3 -input-charset utf8 \

-V”rhel6.2_x86_64″ \

-c boot.cat -hide boot.cat -b isolinux/isolinux.bin \

-no-emul-boot -boot-load-size 4 -boot-info-table \

-o /root/myrhel6.2.iso /local/

其中,-o后的参数为输出文件,最后的目录为制作ISO镜像的源目录。

 

  1. 使用Kickstart光盘

使用镜像或刻录好的光盘引导启动主机,即可完成系统部署。

 

  1. 其他使用方法

制作好的Kickstart光盘或者原版光盘,在anaconda引导界面按ESC进入boot:提示符,输入linux ks=<kickstart config path>也可以按照所给的Kickstart配置进行无人值守安装(比如使用存放在可匿名访问的FTP服务器上的Kickstart配置文件),这样即可免去制作光盘的麻烦。

 

附录

ks.cfg

#platform=x86, AMD64, or Intel EM64T

#version=DEVEL

# Firewall configuration

firewall –disabled                                                                     //防火墙设置

# Install OS instead of upgrade

install

# Use CDROM installation media

cdrom                                                                  //安装源是否使用CDROM

# Root password

rootpw –iscrypted $1$FqrifQqR$n4.1vXH9d7z558nswOKVh1                  //root密码(加密或明文)

# System authorization information

auth  –useshadow  –passalgo=sha512

# Use graphical install

graphical

firstboot –disable

# System keyboard

keyboard us                                                                                               //键盘布局

# System language

lang en_US                                                                                            //系统语言

# SELinux configuration

selinux –disabled                                                                                 //SELinux设置

# Installation logging level

logging –level=info

# Reboot after installation

reboot –eject                                                                                        //安装后重启,弹出光盘

# System timezone

timezone  Asia/Shanghai                                                                        //时区设置

# System bootloader configuration

bootloader –location=mbr

# Clear the Master Boot Record

zerombr

# Partition clearing information

clearpart –all –initlabel

# Disk partitioning information

part /boot –fstype=”ext4″ –size=200                                                          //分区配置

part swap –fstype=”swap” –size=10240

part / –fstype=”ext4″ –grow –size=1

 

%packages                                                                                                   //软件包

@base

@basic-desktop

@chinese-support

@client-mgmt-tools

@debugging

@desktop-debugging

@desktop-platform

@directory-client

@fonts

@general-desktop

@graphical-admin-tools

@input-methods

@internet-browser

@java-platform

@legacy-x

@network-file-system-client

@perl-runtime

@print-client

@remote-desktop-clients

@server-platform

@x11

 

%end