云服务器dd安装AlpineLinux系统

各大云厂商提供了种类繁多的系统镜像,但唯独这个小巧可爱的Alpine无人问津。不过也难不倒咱们这些具有折腾精神的极客们。

本教程支持且不限于阿里云、腾讯云、微软云、谷歌云。

1、登录云服务器,写入Alpine安装镜像后重启
(如果无法正常启动,先下载好镜像,再切换到Debain的维护模式执行dd命令)

cd /mnt
# 写入镜像
wget http://dl-cdn.alpinelinux.org/alpine/v3.15/releases/x86_64/alpine-virt-3.15.0-x86_64.iso
dd if=alpine-virt-3.15.0-x86_64.iso of=/dev/vda
# 重启
reboot

2、通过vnc连接云服务器,将安装文件复制到内存中

# 备份文件
tar cf /sys.tar /.modloop /media/vda
# 卸载硬盘
/etc/init.d/modloop stop
umount /dev/vda
# 恢复文件
tar xf /sys.tar -C /

3、执行安装脚本,接下来就需要看你自己的啦~

setup-alpine

另一种安装方式:将本地虚拟机克隆到云服务器

  • 虚拟磁盘格式转换
apt install -y qemu-utils
qemu-img convert -f vmdk -O raw disk.vmdk disk.raw
  • 把本地虚拟机克隆到云服务器
wget -qO- http://your-domain/disk.raw.gz | gunzip | dd of=/dev/vda

AlpineLinux 国内镜像

sed -i 's/dl-cdn.alpinelinux.org/mirrors.nju.edu.cn/g' /etc/apk/repositories

ZFS文件系统常用命令

zfs的强大毋庸置疑,今天分享下自己常用的zfs相关命令

存储池基本操作命令

  • 创建名为tank的存储池 (type: ”,mirror,raidz,raidz2)
zpool create tank [type] disk1 disk2 disk3
  • 向池中添加更多空间
zpool add tank mirror disk4 disk5
  • 本机导出和导入存储池
zpool export tank
zpool import tank [newtank]
  • 更换服务器后导入存储池
zpool import -f tank
# 指定挂载根路径
zpool import -f -o altroot=/mnt tank
  • 查看存储池当前状态和 I/O 状况
zpool status
zpool iostat
zpool iostat -v

文件系统基础操作命令

  • 创建文件系统,挂载在/export/home
zfs create -o mountpoint=/mnt/home tank/home
  • 修改文件系统名称
zfs rename tank/home tank/newname
  • 修改文件系统挂载点
zfs set mountpoint=/mnt/newdir tank/home
  • 启用压缩属性
zfs set compression=lz4 tank
  • 删除文件系统
zfs destroy -Rf tank/home

文件系统快照操作命令

  • 创建一个快照
zfs snapshot tank/[email protected]
  • 按日期创建快照
name=`date +"%Y-%m-%d"`
zfs snapshot tank/[email protected]$name
  • 查看所有快照
zfs list -t snapshot tank/home
  • 回滚到前一个快照
zfs rollback tank/[email protected]
  • 删除一个快照
zfs destroy -R tank/[email protected]

冗余备份/复制数据集

zfs send tank/[email protected] | zfs receive arch/home

手工挂载/卸载文件系统

zfs mount -a
zfs unmount -a
zfs unmount tank/home

VirtualBox 后台批量启动虚拟机

VirtualBox作为跨平台的开源虚拟化产品,其开放的接口能力是非常强大的。即使在Windows平台,寥寥几行批处理,也可以轻松实现后台批量启动虚拟机。

@echo off

set "PATH=%PATH%;C:\Program Files\Oracle\VirtualBox"

for /f "tokens=1" %%a in ('VBoxManage list vms') do (
    VBoxManage startvm %%a -type headless
)

ping -n 10 127.1 >nul

实现docker跨主机通信(Consul版)

本文将在云服务器之间实现基于Consul的overlay网络,以达到跨主机通信的目的。

docker 和 consul 的安装教程非常之多,这里不再赘述。

环境配置

节点名 节点IP 节点服务
consul 10.0.0.11 安装 Consul
dnode1 10.0.0.12 安装 Docker
dnode2 10.0.0.13 安装 Docker

配置三台机器,请注意修改hostname为不同的值,防火墙放行如下端口:

  • 2376
  • 4789
  • 7946
  • 8300-8302
  • 8500
  • 8600

启动一个单节点的Consul服务

consul agent -ui -server -bootstrap -data-dir /var/lib/consul -bind 10.0.0.11 -client 10.0.0.11

在其他服务器分别启动Docker服务

docker daemon -D -g /var/lib/docker -H unix:// -H tcp://0.0.0.0:2376 --cluster-advertise=eth0:2376 --cluster-store=consul://10.0.0.11:8500
  • --cluster-store 指定了consul服务发现地址
  • --cluster-advertise 指定了本机服务注册地址,其中eth0是自己网卡的名称,也可以用本机内网地址10.0.0.x代替

等待自动注册服务

可以使用浏览器打开http://10.0.0.11:8500查看

在节点上创建网络

docker network create --driver overlay \
    --subnet=10.0.2.0/24 --gateway=10.0.2.1 ovnet

为方便部署,也可以将CLI参数写入配置文件

cat <<EOF >/etc/consul/server.json
{
  "data_dir": "/var/consul",
  "server": true,
  "bootstrap": true,
  "bind_addr": "{{ GetInterfaceIP \"eth0\" }}",
  "client_addr": "0.0.0.0",
  "ui_config": {
    "enabled": true
  }
}
EOF

if [ -f /etc/conf.d/docker ]; then
    opts="--cluster-advertise=eth0:2376 --cluster-store=consul://10.0.0.11:8500"
    sed -i "s#OPTS=\"\"#OPTS=\"$opts\"#" /etc/conf.d/docker
fi

分别在不同的节点上创建可互访的容器

docker run -it --rm --network ovnet --ip 10.0.2.5 alpine
docker run -it --rm --network ovnet --ip 10.0.2.6 alpine
docker run -it --rm --network ovnet --ip 10.0.2.7 alpine

Nginx 实现冷热文件分区读取

  • 10.2.2.2 为热文件服务器,存储1年内上传的文件
  • 10.3.3.3 为冷文件服务器,存储上传超过1年的文件
  • 冷热文件服务器不互通,但都可以响应静态文件网关的请求
upstream host_s1 {
    server 10.2.2.2:443;
    server 10.3.3.3:443 backup;
}

server {

    listen 80;

    server_name s1.rehiy.com;

    location / {
        proxy_pass http://host_s1;
        proxy_connect_timeout 5s;
        proxy_next_upstream_tries 2;
        proxy_next_upstream_timeout 5s;
        proxy_next_upstream error timeout http_404 http_502;
    }

}

Windows Server 2019 将评估升级到完整版

往往越是不重要的东西,越有可能起到关键作用~~~

要将 Windows Server 2019 EVAL 转换为完整版,我们需要使用对应的 GVLK(KMS)密钥

  • 将 Windows Server 2019 评估版 转换为 Windows Server 2019 标准版:
dism /online /set-edition:ServerStandard /productkey: N69G4-B89J2-4G8F4-WWYCC-J464C /accepteula
  • 将 Windows Server 2019 评估版 转换为 Windows Server 2019 数据中心版:
dism /online /set-edition:ServerDatacenter /productkey:WMDGN-G9PQG-XVVXX-R3X43-63DFG /accepteula

用Matomo/Piwik定时导入日志实现统计网站访问情况

安装并配置piwik以后,就需要导入access.log中的访问数据了,

首先需要一个导入日志的脚本,这个脚本运行时,需要把当前access.log中的日志导入pwiki,同时再把导入过的备份到别的地方。脚本如下:

#!/bin/sh

LOG_DIR=/var/log/nginx

LOG_ACCESS=$LOG_DIR/access.log
LOG_IMPORTING=$LOG_DIR/access.log.importing
LOG_IMPORTED=$LOG_DIR/imported.log

# move current log file to a tmp file, and restart log server
mv $LOG_ACCESS $LOG_IMPORTING 2>/dev/null
kill -USR1 $(cat /var/run/nginx.pid 2>/dev/null) 2>/dev/null

# import temp log file
/www/piwik/misc/log-analytics/import_logs.py \
    --idsite=1 \
    --url=piwik.rehiy.com \
    --log-format-name=ncsa_extended \
    $LOG_IMPORTING

# join importing log to imported
cat $LOG_IMPORTING >>$LOG_IMPORTED

# remove temp file
rm $LOG_IMPORTING 2>/dev/null

最后还需要配置cron每个小时运行一次导入脚本,再配置logrotate不要处理access.log。

Linux 恢复删除的文件

Linux 下的命令可谓繁多,但属rm最让人痛并快乐。今天,我分享下针对rm的后悔良药testdisk

当你在 Linux 系统上删除一个文件时,它不一定(嗯,是不一定~)会永远消失,特别是当你最近才刚刚删除了它的时候。而恢复已删除文件的最佳工具之一testdisk可以帮助你拯救它。

虽然testdisk具有广泛的功能,包括恢复丢失或损坏的分区和使不能启动磁盘可以重新启动,但它也经常被用来恢复被误删的文件。有趣的是,它不仅是一个 Linux 工具,而且还适用于 MacOS、Solaris 和 Windows。文档可在 https://www.cgsecurity.org 中找到。

安装

# debian
apt install testdisk
# centos
yum install testdisk

恢复文件

cd /mnt/recovery
testdisk /dev/sdb2

然后,一路默认选项,直到选择 [ Advanced ] Filesystem Utils

接下来,查看选定的分区,用右箭头选择底部的 [ List ],按回车键。

最后,施展你的细心加耐心,仔细看好软件说明操作。

至此,若海也帮不到你更多了,只能在此祝你心想事成 !

批量将discuz数据库编码从utf8转为utf8mb4

为获得emoji等特殊字符支持,需要将discuz的数据库编码转换为utf8mb4

  • 确认数据库版本支持utf8mb4utf8mb4_0900_ai_ci
  • 由于用户表中username是不重复索引,且区分大小写和声调,字符集需设置为utf8mb4_general_ci
  • 手动执行下面的SELECT CONCAT语句,然后使用执行结果替换该语句,保存为一个 sql 文件
  • 为避免 php 运行超时,请使用 cli 工具导入保存的 sql 文件
USE `discuz_databese`;

-- 更改主库字符集

ALTER DATABASE `discuz_databese` COLLATE utf8mb4_0900_ai_ci;

-- 请使用下列语句的执行结果替换该语句

SELECT CONCAT(
  'ALTER TABLE ', `TABLE_NAME`, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;'
) FROM `information_schema`.`TABLES`
  WHERE `TABLE_SCHEMA` = 'discuz_databese'
    AND `TABLE_NAME` <> 'pre_common_member'
    AND `TABLE_NAME` <> 'pre_common_member_archive'
    AND `TABLE_NAME` <> 'pre_ucenter_members';

-- 单独修改用户表(`username`字符集为`utf8mb4_general_ci`)

ALTER TABLE `pre_common_member` COLLATE utf8mb4_0900_ai_ci,
  MODIFY `email` char(40) NOT NULL DEFAULT '',
  MODIFY `username` char(15) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  MODIFY `password` char(32) NOT NULL DEFAULT '',
  MODIFY `extgroupids` char(20) NOT NULL DEFAULT '',
  MODIFY `timeoffset` char(4) NOT NULL DEFAULT '';

ALTER TABLE `pre_common_member_archive` COLLATE utf8mb4_0900_ai_ci,
  MODIFY `email` char(40) NOT NULL DEFAULT '',
  MODIFY `username` char(15) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  MODIFY `password` char(32) NOT NULL DEFAULT '',
  MODIFY `extgroupids` char(20) NOT NULL DEFAULT '',
  MODIFY `timeoffset` char(4) NOT NULL DEFAULT '';

ALTER TABLE `pre_ucenter_members` COLLATE utf8mb4_0900_ai_ci,
  MODIFY `username` char(15) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
  MODIFY `password` char(32) NOT NULL DEFAULT '',
  MODIFY `email` char(32) NOT NULL DEFAULT '',
  MODIFY `myid` char(30) NOT NULL DEFAULT '',
  MODIFY `myidkey` char(16) NOT NULL DEFAULT '',
  MODIFY `regip` char(15) NOT NULL DEFAULT '',
  MODIFY `salt` char(6) NOT NULL,
  MODIFY `secques` char(8) NOT NULL DEFAULT '';

下面是写给强迫症患者的,你可能并不需要 !!

-- 创建临时库

CREATE DATABASE `tmp123`;

-- 从原始数据库复制表(会丢弃索引)

USE `discuz_database`;

CREATE TABLE `tmp123`.`pre_common_member` AS SELECT * FROM `pre_common_member`;
CREATE TABLE `tmp123`.`pre_common_member_archive` AS SELECT * FROM `pre_common_member_archive`;

CREATE TABLE `tmp123`.`pre_ucenter_members` AS SELECT * FROM `pre_ucenter_members`;

-- 进入临时库

USE `tmp123`;

-- 转换数据库编码和字符集(已无索引,可以转换)

ALTER TABLE `pre_common_member` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE `pre_common_member_archive` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

ALTER TABLE `pre_ucenter_members` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

-- 获取重复的用户统计到临时表

CREATE TABLE `pre_ucenter_members_having_count` AS
  SELECT `username`, count(username) as `count` FROM `pre_ucenter_members`
    GROUP BY `username` HAVING `count` > 1;

-- 获取重复的用户详情到临时表

CREATE TABLE `pre_ucenter_members_having` AS
  SELECT * FROM `pre_ucenter_members` WHERE `username` IN (
      SELECT `username` FROM `pre_ucenter_members_having_count`
  );