0%

腾讯云/轻量云 安装ArchLinux的个人记录

联系我购买腾讯、阿里云有8折甚至更低的折上折优惠哦!

本文仅用于个人学习使用,过阵子再以教程的形式重新发布出来。如果你现在完全按这篇文章操作不一定会成功。

请同时搭配记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程食用。

准备工作

下载镜像

wget https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/2021.08.01/archlinux-2021.08.01-x86_64.iso

编辑/boot/grub/grub.cfg文件,添加下列内容

set timeout=60
menuentry 'ArchISO' --class iso {
set isofile=/archlinux-2021.08.01-x86_64.iso
loopback loop0 $isofile
#archisolabel设置archiso文件驻留的文件系统标签。
#img_dev指明archiso文件驻留的设备
#img_loop是archiso文件在img_dev里的绝对位置
linux (loop0)/arch/boot/x86_64/vmlinuz-linux archisolabel=ARCH20210801 img_dev=/dev/vda1 img_loop=$isofile
initrd (loop0)/arch/boot/x86_64/initramfs-linux.img
}

Reboot 选择ArchISO引导项

安装

替换文件

mkdir mnt

mount -o rw /dev/vda1 mnt

mount -o rw,remount mnt

rm -rf mnt/*

pacstrap ./mnt base linux linux-firmware networkmanager sudo openssh

genfstab -U mnt >> mnt/etc/fstab

vim mnt/etc/fstab 将ro修改为rw可读写

切换到Arch

arch-chroot mnt

安装一些可能接下来会用到的包

pacman -S vim bash-completion

剩下还有一些步骤参考记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程

开机自启动一些服务

systemctl enable NetworkManager sshd

如果没有启动NetworkManagersshd这两个服务的话,下次启动时没有网络并且无法ssh远程访问。

添加用户并设置密码

username替换为你要创建的用户名。

useradd -m username

passwd username

配置sudo

usermod -aG wheel username

编辑/etc/sudoers文件允许wheel组中用户使用sudo提权到root级别权限。

一定要将公钥添加到用户家目录的.ssh/authorized_keys文件内,否则重启后只能通过VNC访问这台机器进行后续配置。

安装grub引导
pacman -S grub efibootmgr
grub-install –target=i386-pc /dev/vda
生成grub2配置文件
grub-mkconfig -o /boot/grub/grub.cfg

reboot
重启后将使用本机ssh远程这台Arch轻量云实例,所以需要你在重启前配置好sshd服务并且将本机公钥传入到刚刚创建的用户的家目录

记录一次引导失败插曲:
忘记生成grub2配置文件,好在腾讯轻量云提供了远程VNC。
按照下面的命令,手动引导系统。

grub> set root=(hd0,msdos1)
grub> linux /boot/vmliunz-linux root=/dev/vda1
grub> initrd /boot/initramfs-linux.img
grub> boot

进入系统后再生成grub2配置文件grub-mkconfig -o /boot/grub/grub.cfg

后续配置

安装一些常用的包

pacman -S vim bash-completion

设置时区时间

timedatectl set-timezone Asia/Shanghai

hwclock --systohc

设置使用的区域

编辑/etc/locale.gen然后移除需要的 地区 前的注释符号 #

接着执行locale-gen以生成locale信息

编辑/etc/locate.conf配置文件,没有则新建:

文本内输入: LANG=en_US.UTF-8

设置全局区域环境为美国英语环境。

设置主机名

hostnamectl set-hostname 主机名

开启BBR

Kernel 4.9 及以后已经合并了 BBR 的代码,BBR有可能默认安装。
使用modinfo tcp_bbr查看BBR内核模块。

filename:       /lib/modules/5.13.7-arch1-1/kernel/net/ipv4/tcp_bbr.ko.zst
description: TCP BBR (Bottleneck Bandwidth and RTT)
license: Dual BSD/GPL
author: Soheil Hassas Yeganeh <soheil@google.com>
author: Yuchung Cheng <ycheng@google.com>
author: Neal Cardwell <ncardwell@google.com>
author: Van Jacobson <vanj@google.com>
srcversion: 3ADF6435C60E99C5F186F19
depends:
retpoline: Y
intree: Y
name: tcp_bbr
vermagic: 5.13.7-arch1-1 SMP preempt mod_unload
sig_id: PKCS#7
signer: Build time autogenerated kernel key

查看是否开启BBR:
sysctl net.ipv4.tcp_congestion_control

开启BBR:

sudo sysctl net.ipv4.tcp_congestion_control=bbr

$ sysctl net.ipv4.tcp_congestion_control
net.ipv4.tcp_congestion_control = cubic
$ sudo modprobe tcp_bbr
$ lsmod | grep tcp_bbr
tcp_bbr 20480 0
$ sudo sysctl net.ipv4.tcp_congestion_control=bbr
net.ipv4.tcp_congestion_control = bbr

开启后效果可以立即看到,如果想在重启后依然使用BBR,则需要写入到文件系统:

echo "tcp_bbr" > /etc/modules-load.d/80-bbr.conf

echo "net.ipv4.tcp_congestion_control=bbr" > /etc/sysctl.d/80-bbr.conf

记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程

安装Arch Linux基本过程纪录

下载并烧录镜像

本次下载2021.5.1日的镜像,写这篇文章的时候是六一儿童节,但是并没有看到这个月的镜像。好耶,都去过六一了!

应该是最后一次用东软维云的镜像站咯!下载Arch 2021.5.1 ISO走起。

引导系统

引导Arch ISO前在BIOS中关闭安全引导,借着还有Windows的时候,更新了一下BIOS到2021年三月份的版本。

链接到互联网

在 Arch ISO Live中安装了iwd来管理无线网络,因为本次安装过程只有无线网络,那么用iwctl工具来配置本次安装过程中使用的无线网络。

进入iwctl交互模式: iwctl

罗列设备: device list,在列表中可以找到wlan0无线设备,记下来他的名字,接下来会使用到这个名称。

扫描无线网络: station wlan0 scan

罗列已发现的网络 station wlan0 get-networks

连接到无线网络 station wlan0 connect SSID

删除多余的引导

使用efibootmgr删除Windows引导。

efibootmgr -b 000X -B

更新系统时间

使用timedatectl更新时间,开启ntp。确保系统时间是准确的: timedatectl set-ntp true

建立硬盘分区

使用fdisk工具对磁盘进行分区,我要将整个磁盘都空间都划分给Arch使用。

fdisk /dev/nvme0n1

  • ESP分区 1G
  • SWAP分区 8G
  • 根文件存储 剩余空间

格式化磁盘文件系统

将ESP被格式化成,ESP分区格式化成FAT32分区格式: mkfs.vfat -F32 /dev/nvme0n1p1

创建SWAP文件系统:

mkswap /dev/nvme0n1p2

swapon /dev/nvme0n1p2

创建根目录文件系统ext4: mkfs.ext4 /dev/nvme0n1p3

挂载分区

挂载根分区目录: mount /dev/nvme0n1p3 /mnt

创建EFI目录并进行挂载:

mkdir /mnt/efi

mount /dev/nvme0n1p1 /mnt/efi

选择镜像源

文件 /etc/pacman.d/mirrorlist 定义了软件包会从哪个镜像源下载。在 LiveCD 启动的系统上,在连接到因特网后,reflector 会通过选择 20 个最新同步的 HTTPS 镜像并按下载速率对其进行排序来更新镜像列表。

在列表中越前的镜像在下载软件包时有越高的优先权。您或许想检查一下文件,看看是否满意。如果不满意,可以相应的修改 /etc/pacman.d/mirrorlist 文件,并将地理位置最近的镜像源挪到文件的头部,同时也应该考虑一些其他标准。

这个文件接下来还会被 pacstrap 拷贝到新系统里,所以请确保设置正确。

安装系统软件包

pacstrap /mnt base linux linux-firmware base-devel networkmanager

写入引导

用以下命令生成 fstab 文件 (用 -U 或 -L 选项设置UUID 或卷标):

genfstab -U /mnt >> /mnt/etc/fstab

强烈建议在执行完以上命令后,后检查一下生成的 /mnt/etc/fstab 文件是否正确。

切换根目录

Chroot更当前进程及其子进程的可见根路径。变更后,程序无法访问可见根目录外文件和命令。

arch-chroot /mnt

安装一些常用软件包

pacman -S vim bash-completion

设置时区时间

timedatectl set-timezone Asia/Shanghai

hwclock --systohc

设置使用的区域

编辑/etc/locale.gen然后移除需要的 地区 前的注释符号 #

接着执行 locale-gen 以生成 locale 信息

编辑/etc/locate.conf:

LANG=en_US.UTF-8

设置全局区域环境为美国英语环境。

稍后用户可以编辑自己的~/.config/locale.conf文件来设置使用的语言和特定的区域格式。如:

  • LANG
  • LANGUAGE
  • LC_ADDRESS
  • LC_COLLATE
  • LC_CTYPE
  • LC_IDENTIFICATION
  • LC_MEASUREMENT
  • LC_MESSAGES
  • LC_MONETARY
  • LC_NAME
  • LC_NUMERIC
  • LC_PAPER
  • LC_TELEPHONE
  • LC_TIME

LANG:默认的区域设置
这个变量的值会覆盖掉所有未设置的 LC_* 变量的值。

相关详情访问: Arch Wiki - Locate(简体中文)

设置主机名

hostnamectl set-hostname Archxxxxxx

设置用户及ROOT密码

设置root用户密码: passwd

添加普通用户并设置密码:

useradd -m username

passwd username

将用户添加到管理员组(wheel): usermod -aG wheel username

编辑/etc/sudoers文件允许wheel组中用户使用sudo提权到root级别权限。

安装引导程序

安装引导是安装的最后一步,使用GRUB配置本机引导,首先安装grubefibootmgr两个包。

pacman -S grub efibootmgr

然后按照下列步骤安装 GRUB:

挂载 EFI 系统分区,在本节之后的内容里,挂载点为/efi

选择一个启动引导器标识,这里叫做 GRUB。这将在 esp/EFI/ 中创建一个与标识同名的目录来储存 EFI 二进制文件,而且这个名字还会在 UEFI 启动菜单中表示 GRUB 启动项。

执行下面的命令来将 GRUB EFI 应用 grubx64.efi 安装到 esp/EFI/GRUB/,并将其模块安装到 /boot/grub/x86_64-efi/。

grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB

生成GRUB配置文件: grub-mkconfig -o /boot/grub/grub.cfg

安装后的一些系统服务配置

使用NetworkManager管理本机网络

刚才在安装过程中使用pacstrap安装软件包时就已经将networkmanager软件包安装好了,接下来开启NetworkManager服务,并使用nmcli配置连接无线网络。

systemctl enable --now NetworkManager

罗列当前可用的无线网络: nmcli device wifi list

连接到SSID_NAME无线网络
nmcli device wifi connect SSID_NAME ifname wlp3s0 password <mypassword> name XXXXX

若要交互式的输入密码,可以加-a --ask参数,避免在终端内输入密码留下痕迹。

nmcli device wifi connect SSID_NAME ifname wlp3s0 name XXXXX

此时缺省password参数,会在终端内进行交互式输入密码。

PPPoE / DSL support

若要使用PPPoE拨号,需要rp-pppoe软件包后,才可以用nmcli连接。

pacman -S rp-pppoe

nmcli connection add type pppoe pppoe.username "myusername" pppoe.password "mypassword" ifname "enp1s0f1" con-name "NDR" autoconnect yes

nmcli connection up NDR

配置EAP PEAP认证无线网络

校内的无线网络使用EAP认证,通过查阅资料使用nmcli添加EAP无线网络方法如下:

nmcli connection add type wifi con-name my-CUCC ifname wlp3s0 ssid CUCC ipv4.method auto 802-1x.eap peap 802-1x.phase2-auth mschapv2 802-1x.identity yourusername 802-1x.password yourpassword wifi-sec.key-mgmt wpa-eap autoconnect yes

桌面窗口服务

使用Wayland图形显示服务,sway平铺窗口管理器。

常见的环境配置文件所在地址

对于特定用户,还可以在 /.bashrc、/.xinitrc 或 ~/.xprofile 中设置自己的用户环境。不同之处在于:

.bashrc:每次使用终端登录时读取并运用里面的设置。

.xinitrc:每次使用 startx 或 SLiM 启动 X 界面时读取并运用里面的设置。

.xprofile:每次使用 GDM 等显示管理器登录时读取并运用里面的设置。

安装wayland和Sway以及依赖的一些包

pacman -S wayland sway

pacman -S alacritty swayidle

有关使用Wayland中的常见问题详见Arch Wiki - Wayland

配置Sway平铺窗口管理器

配置在登录系统后自动启动sway,以及配置Sway的程序启动器,任务栏,和各种优化。

配置tty登录后自动运行sway

vim ~/.bash_profile

启动Sway时,设置环境变量,其中包含让firefox使用wayland的标记变量以及QT环境等变量信息。

vim ~/.local/bin/sway

#!bin/sh
set -a
[ -f $HOME/.config/sway/env ] && . "$HOME/.config/sway/env"
set +a

if [ -z $DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
exec sway
fi

编辑环境变量文件:

MOZ_ENABLE_WAYLAND=1
QT_QPA_PLATFORM=wayland
  • MOZ_ENABLE_WAYLAND=1 : 火狐浏览器使用Wayland图形窗口服务标记
  • QT_QPA_PLATFORM=wayland : 在Wayland环境下使用Qt5需要安装qt5-wayland包,并设置QT_QPA_PLATFORM=wayland环境变量。

使用wofi作为程序启动坞

安装wofi: yay -S wofi

修改Sway配置文件

set $menu dmenu_path | wofi --show drun -i | xargs swaymsg exec --

rofi-emoji

使用dex自动启动程序-Fcitx5(自启动fcitx5)

fcitx5等一些应用会创建XDG Autostart启动配置,通常以.desktop文件拓展名结尾。像fcitx5等一些程序包在安装时会在/etc/xdg/目录下生成配置文件,但是只有部分的窗口管理器支持xdg启动。在Sway中目前没有看到原生对它的支持,所以就需要一些其它工具辅助执行。

那么若要在进入桌面环境后自动启动fcitx5,则可以使用dex工具。它可以自动执行/etc/xdg/autostart目录下的.desktop程序启动配置文件。

安装dex: yay -S dex

在Sway配置文件中配置自启动dex:

~/.config/sway/config 文件末尾处添加: exec_always "dex -a"

之后在Sway启动后,会执行dex工具,dex工具又回去执行哪些在XDG自动启动目录下,但是在Sway中不会自动执行的程序启动配置文件.desktop,此时fcitx5已经可以自动启动了。

安装中文字体

推荐安装以下常用开源中文字体:

  • wqy-microhei
  • wqy-microhei-lite
  • wqy-bitmapfont
  • wqy-zenhei
  • noto-fonts-cjk

yay -S wqy-microhei wqy-microhei-lite wqy-bitmapfont wqy-zenhei noto-fonts-cjk

更新字体缓存: fc-cache -fv

关于更多本土化中文字体设置详见

Arch Wiki Simplified Chinese

锁屏工具swaylock

我使用的是swaylock-effects

创建锁屏执行脚本文件: sudo vim /usr/bin/lock-screen

#!/bin/bash
#
swaylock --screenshots --clock --indicator --indicator-radius 100 \
--indicator-thickness 7 --effect-blur 7x5 --effect-vignette 0.5:0.5 \
--ring-color bb00cc --key-hl-color 880033 --line-color 00000000 \
--inside-color 00000088 --separator-color 00000000 --grace 2 --fade-in 0.2

赋予全体用户执行权限: chmod u+x /usr/bin/lock-screen

接下里配置Sway配置文件: vim .config/sway/config

### Idle configuration
#
# Example configuration:
#
exec swayidle -w \
timeout 300 'lock-screen &' \
timeout 500 'swaymsg "output * dpms off"' \
resume 'swaymsg "output * dpms on"' \
before-sleep 'lock-screen &'
# This will lock your screen after 300 seconds of inactivity, then turn off
# your displays after another 200 seconds, and turn your screens back on when
# resumed. It will also lock your screen before your computer goes to sleep.

上面的部分配置为Sway默认配置,简单修改为上面的配置即可,修改好配置文件好需要重启Sway后才可以生效,因为使用的是exec,所以重新加载配置文件还不能生效,如果想要查看效果。可以: killall -9 sway ,之后重新登录系统等待查看效果。

延时工具swayidle配置

swayidle我用来和swaylock-effects搭配使用,用于在一定时间内无操作后自动执行脚本或程序,所以可以用来解决一定时间哪无操作自动锁屏的需求。

zsh

安装zsh: yay -S zsh

更改用户默认Shell: usermod --shell /usr/bin/zsh username

要注意bash_profile等文件是否有内容,如果有的话需要迁移为zsh相关的文件。

初始化默认配置文件:

git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
source .zshrc

常用软件包

这里会记录一些我常用的软件包

  • git
  • vim
  • bash-completion bash自动补全
  • rp-pppoe 对PPPoE的支持
  • openssh openssh 需要开启服务
  • rclone 挂载云盘
  • yay 使用yay管理AUR源
  • proxychains-ng 终端代理,可配置代理链
  • v2ray-core 请珍惜眼前所拥有的一切
  • ntfs-3g 挂载ntfs设备
  • qt5-wayland 在Wayland下支持Qt5,需要配置环境变量

开启archlinuxcn

我使用清华大学archlinuxcn源

使用方法:

/etc/pacman.conf 文件末尾添加以下两行,并安装 archlinuxcn-keyring 包导入 GPG key。

[archlinuxcn]
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch

安装fcitx5-rime中文输入法

安装以下包:yay -S fcitx5 fcitx5-qt fcitx5-gtk fcitx5-configtool fcitx5-rime qt5-wayland

若在Wayland环境下使用Qt5需要安装qt5-wayland包,并设置QT_QPA_PLATFORM=wayland环境变量

yay安装

git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

或者在开启了archlinuxcn源后直接通过源安装。

pacman -S yay

让yay通过proxychains使用代理

go版本的yay不能使用proxychains进行代理,所以需要替换安装以下的软件包:

yay -S gcc-go (代替go)
yay -S yay (or yay-git)

重新安装yay后还需要更改proxychains的配置文件:将52行附近的proxy_dns前使用#注释#proxy_dns

Edge浏览器

从AUR源中安装微软Edge浏览器: yay -S microsoft-edge-dev-bin

在Wayland环境下,还需要对Edge浏览器的启动脚本做些手脚才能正式使用。

vim /usr/bin/microsoft-edge-dev

在exec指令中添加两个参数:

-enable-features=UseOzonePlatform

-ozone-platform=wayland

目前没办法在EDGE浏览器中使用输入法,待解决

安装Wine

Wine目前原生不支持wayland,需要Xwayland支持。不过经过搜索后发现Wine的Git仓库中存在了wayland分支,并且在持续开发,截止到目前已经支持wayland环境与Wine运行的应用共享剪贴板。

接下来尝试使用wayland的分支尝试编译运行。

emmmm失败了,错误提示找不到显示驱动,先不折腾它,接下来试试Xwayland吧。

安装Xwayland

yay -S xorg-xwayland

安装wine

Wine可通过开启Multilib仓库来安装wine包及依赖。

vim /etc/pacman.conf

[multilib]
Include = /etc/pacman.d/mirrorlist

yay -Sy

yay -S insatll wine

Jenkins Linux 安装

在官网下载Jenkins

下载当前最新的稳定版Jenkins保存到指定目录。

安装包下载

wget -O ./jenkins.war http://mirrors.jenkins.io/war-stable/latest/jenkins.war

配置Jenkins的JAVA运行环境

Kenkins需要Java虚拟机才可以运行,在运行Jenkins前先配置JAVA虚拟机环境。

下载 Java JRE Linux X64

Java JRE安装包下载

wget -O ./jre-8u281-linux-x64.tar https://javadl.oracle.com/webapps/download/AutoDL?BundleId=244058_89d678f2be164786b292527658ca1605

安装Java JRE

将下载好的Java JRE安装包移动你要安装的目录里,我想要安装在/usr/java目录下。

(ROOT)创建安装目录sudo mkdir -p /usr/java

(ROOT)移动安装包sudo mv ./jre-8u281-linux-x64.tar /usr/java

(ROOT)解压 sudo tar -zxvf /usr/java/jre-8u281-linux-x64.tar

查看/usr/java目录你会发现除了安装包外新存在一个名字与jre1.8.0_281差不多相同的目录(这取决于你下载的JavaJRE版本)

那么现在你的Java JRE安装在了/usr/java/jre1.8.0_281内,现在可以将/usr/java/目录下的Java JRE安装包删除掉以节省空间

接下来配置环境变量,请根据自己Linux发行版的规则变通的配置/etc/profile

/etc/profile文件开始处填写:

export JAVA_HOME=/usr/java/jre1.8.0_281/
export JRE_HOME=/usr/java/jre1.8.0_281/
export CLASS_PATH=.:$JAVA_HOME/lib/rt.jar:$JRE_HOME/lib
export JAVA_PATH=$JAVA_HOME/bin:$JRE_HOME/bin

之后找到PATH,在PATH末尾填写上${JAVA_PATH}。请根据自己的实际情况填写,否则可能会覆盖之前的环境变量哦!

我的环境变量配置如下:

export JAVA_HOME=/usr/java/jre1.8.0_281/
export JRE_HOME=/usr/java/jre1.8.0_281/
export CLASS_PATH=.:$JAVA_HOME/lib/rt.jar:$JRE_HOME/lib
export JAVA_PATH=$JAVA_HOME/bin:$JRE_HOME/bin

if [ "`id -u`" -eq 0 ]; then
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${JAVA_PATH}"
else
PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:${JAVA_PATH}"
fi
export PATH

激活环境变量 source /etc/profile

查看配置是否成功则执行java -version,出现版本信息则配置成功:

java version "1.8.0_281"
Java(TM) SE Runtime Environment (build 1.8.0_281-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)

初始化Jenkins

准备工作已经结束,接下来开始进行初始化Jenkins!

回到下载Jenkins的目录,执行java -jar jenkins.war --httpPort=8080命令。这里的8080是Web界面的端口号,你可以修改成自己需要的端口号,注意防火墙要放行该TCP端口。

首次运行Jenkins,首次运行Jenkins时会在当前用户家目录下生成一些配置文件~/.jenkins

访问你的域名或IP地址加上端口号后,你可以看到这样的界面。

01-first-interface-2021-02-06-14-31-08

此时Jenkins会下载一些资源,需要等待5分钟左右。如果时间过长,结束掉现在运行的Jenkins,先需要更改国内下载源来加快速度:

cd ~/.jenkins
vim hudson.model.UpdateCenter.xml

# 将<url>标签内的网址改为清华源

# 将下面的内容
<url>https://updates.jenkins.io/update-center.json</url>
# 修改为

<url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>

之后回到Jenkins软件包的目录下重新执行java -jar jenkins.war --httpPort=8080

稍后页面会让你输入管理员密码解锁安装Jenkins。管理员密码可以在运行Jenkins的终端上找到,也可以根据页面提示的文件中找到。

Jenkins安装解锁密码

输入密码后下一步会安装基本常用插件,选择左侧的选项开始安装即可。

Jenkins安装常用插件

此时需要一段时间等待……

如果出现插件安装失败,不用担心,很可能是Jenkins版本不支持当前下载的最新插件,稍后进入到Jenkins管理页面更新Jenkins版本即可。

Jenkins安装插件部分插件安装失败

接下来根据你的个人需求配置管理员用户名密码等设置。

配置开机自动启动 systemd 守护进程

以下内容使用于以war包形式部署Jenkins的方式来配置systemd守护进程服务,其它方式安装的Jenkins需要你自己变通。

以下内容参考linux(centos8):用systemctl管理war包形式的jenkins(java 14 / jenkins 2.257)这篇文章。

创建管理脚本

vim jenkins-control.sh创建新文本文件,将以下内容写入到文件中。

#!/bin/bash
#

source /etc/profile

pid=`ps -ef | grep jenkins.war | grep -v 'grep'| awk '{print $2}'| wc -l`
if [ "$1" = "start" ];then
if [ $pid -gt 0 ];then
echo 'jenkins is running...'
else
nohup $JAVA_HOME/bin/java -jar /home/hackinsss/Jenkins/jenkins.war --enable-future-java --httpPort=8088 2>&1 &
fi
elif [ "$1" = "stop" ];then
exec ps -ef | grep jenkins | grep -v grep | awk '{print $2}'| xargs kill -9
echo 'jenkins is stop..'
else
echo "Please input like this:"./jenkins.sh start" or "./jenkins stop""
fi

为脚本文件赋予执行权限 chmod u+x jenkins-control.sh

启动Jenkins ./jenkins-control.sh start

关闭Jenkins ./jenkins-control.sh stop

上面两个操作没有问题,能正确开启或关闭Jenkins的话则脚本运行没有问题,开始编辑systemd服务文件。

创建systemd服务文件

sudo vim /etc/systemd/system/jenkins.service

修改运行Jenkins的用户和脚本路径地址为你自己的。不推荐使用root权限运行Jenkins

[Unit]
Description=Jenkins
After=network.target

[Service]
Type=forking
User=使用该用户运行Jenkins
Group=使用该用户组运行Jenkins
ExecStart=/home/hackinsss/Jenkins/jenkins-control.sh start
ExecReload=
ExecStop=/home/hackinsss/Jenkins/jenkins-control.sh stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload

设置开机自动运行Jenkins sudo systemctl enable jenkins

运行Jenkins sudo systemctl start jenkins

停止运行Jenkins sudo systemctl start jenkins

安装Jenkins流程记录到此结束。

[腾讯课堂、钉钉]在线网课视频直播回放下载离线播放

有些精品好课真的是百看不厌、教师精心准备、学习氛围也好。不过有些已购买的课程却只能在线观看…现在讲究的是一个环保、节能。如果能将已购买的课程离线下载好,那么会为各大平台节省多少带宽费用当然还有数据包在这世间重复的传输所浪费的电力资源。

本着环保、节能、减排的目的,开始了尝试对腾讯课堂网页版中自己购买了课程的视频回放进行下载。

然后顺便又看了下钉钉的回放。

github直达项目:https://github.com/yeefire/cloud-class-replay

腾讯课堂

由于没有使用客户端,在网页上观看。使用浏览器中的开发者工具来寻找请求。

tencent_class_safari_devnet-2020-12-28-00-30-43

可以看到请求了很多视频片段,文件拓展名为ts,GET请求。于是直接复制求请求连接然后丢在浏览器地址栏播放,结果不行,是加密的。

因为看到了ts,那么八九不离十使用的是M3U文件存储分段多媒体信息。

ts是日本高清摄像机拍摄下进行的封装格式文件,全称为MPEG2-TS。

M3U8是Unicode版本的M3U,用UTF-8编码。”M3U”和”M3U8”文件都是苹果公司使用的HTTP Live Streaming格式的基础,这种格式可以在iPhone和Macbook等设备播放。

寻找M3U

在请求中搜索m3u,出现了几个m3u8拓展文件,选择资源文件最大的那个m3u8文件,获取cURL请求或者其他方式将其下载到本地方便进一步分析。

现在找到了m3u文件,我们可以获取到这节课的所有分段视频了。

tencent_class_safari_search_m3u8-2020-12-28-00-48-19

分析腾讯课堂M3U文件

已经下载好了m3u8拓展文件,接下来打开文件进行分析!

可以看到腾讯课堂的每个分段视频是使用AES-128进行加密的,好在下载到的m3u8文件里给出了解密密钥的地址以及偏移量。

这下我们有了密钥和偏移量还有分段视频的请求参数(还不知道HTTP请求路径)

tencent_class_m3u8_file-2020-12-28-01-06-24

tencent_class_m3u8_check-2020-12-28-01-11-59

整理总结

现在可以尝试下载一个小的视频片段,不过目前还没有请求视频片段的完整路径,只有一个个的请求参数。这个好办,再回到浏览器中播放回放视频,观察浏览器开发者工具中的网络请求动态,找到’vxxxxxx.ts’请求,并查看获取该视频片段的完整HTTP请求路径。

发现和m3u8的请求路径与其相似。

m3u: https://xxxxxxxxxx.vod2.myqcloud.com/xxxxxxxxxxxxxx/b4e0xxxxxxxxxxxxxx7/drm/voddrm.xxxxxxxxxxxxx

ts: https://xxxxxxxxxx.vod2.myqcloud.com/xxxxxxxxxxxxxx/b4e0xxxxxxxxxxxxxx7/drm/v.fxxxx.ts?start=195027344&end=195666559&type=mpegtsxxxxxxxxxxxxx

在最后出现/斜杠位置前的所有请求路径都相同。并且斜杠后的请求参数正是m3u文件中的一个个分段视频的请求参数,看来仅仅需要简单的拼接就可以将这些分段视频下载好了。

那么现在我们有了全部分段视频的下载请求地址、解密算法、解密密钥及偏移量。有了这些就可以尝试下载分段视频并进行解密和合并了。

先尝试解密一个分段视频试试看:

with aiofiles.open(m3u8_encrypt_file, mode='rb') as f:
f = f.read()
content_video_part = AES.new(key, AES.MODE_CBC, iv).decrypt(f)
with aiofiles.open(dest_decrypt_file, mode='wb') as f:
f.write(content_video_part)

可以正常播放,没有问题。接下来下载全部的分段视频并解密,最后重新整合为一个mp4格式视频文件。剩下的交给脚本处理了!

腾讯课堂回放下载脚本

脚本使用异步进行请求下载分段视频和解密视频,尽可能的以最快的速度下载好全部的分段视频。

如果下载期间遇到网络波动,脚本可以自动重试下载。

若脚本意外停止,可以继续追加下载,不必全部重新开始下载分段视频。

使用方法:

  • 先安装依赖模块 pip3 install pycrypto m3u8 aiofiles requests_async
  • 命令行执行 python3 tencent_class_m3u8.py 这节课的名称 这节课的M3U文件请求地址(网址或者本地路径都可以)

例如: python3 tencent_class_m3u8.py 【Python进阶】Python-上午 https://1dada217.vod2.myqcloud.com/fdadadada3kmdkfsxxxxxxxxxxxxxxxxx

from Crypto.Cipher import AES
import requests_async as requests
import aiofiles
import m3u8
import os, sys
import asyncio

class_video_name = sys.argv[1]
m3u8_file_uri = sys.argv[2]
prefix_request_url = f'{m3u8_file_uri.rsplit("/", 1)[0]}/'


async def download_m3u8_video(index: int, suffix_url: str):
if not os.path.exists(f'{class_video_name}/downloads/{index}.ts'):
i = 0
while i < 3:
try:
download_video_ts = await requests.get(url=prefix_request_url + suffix_url, timeout=30)
with open(f'{class_video_name}/downloads/{index}.ts', "wb") as ts:
ts.write(download_video_ts.content)
print(f'[{class_video_name}]——已下载第 {index} 个片段/ 共 {len(playlist.files)} 个片段')
return
except requests.exceptions.RequestException:
print(f'[{class_video_name}]——下载超时,正在重新下载第 {index} 个片段/ 共 {len(playlist.files)} 个片段')
await asyncio.sleep(i)
i += 1


async def download_m3u8_all():
if not os.path.exists(class_video_name + '/downloads'):
os.makedirs(class_video_name + '/downloads')
download_async_list = [asyncio.create_task(download_m3u8_video(i, video_suffix_url))
for i, video_suffix_url in enumerate(playlist.files, 1)]
await asyncio.wait(download_async_list)

download_encrypt_list = [uri for uri in os.listdir(f'{class_video_name}/downloads') if uri[0] != '.']
if len(download_encrypt_list) == len(playlist.files): # 判断是否有漏下的分段视频没有下载
print(f'[{class_video_name}]——视频全部下载完成')
return download_encrypt_list
else: # 有部分视频在三次重试后依旧没有下载成功
print(f'[{class_video_name}]——下载过程中出现问题,正在重试...')
return await download_m3u8_all()


async def decrypt_m3u8_video(m3u8_encrypt_file_uri: str, key: bytes, iv: bytes):
decrypt_name = f'{m3u8_encrypt_file_uri.split("/")[-1].split(".")[0]}'
dest_decrypt_uri = f'{class_video_name}/decryption/{decrypt_name}.de.ts'
if not os.path.exists(dest_decrypt_uri):
async with aiofiles.open(m3u8_encrypt_file_uri, mode='rb') as f:
f = await f.read()
content_video_part = AES.new(key, AES.MODE_CBC, iv).decrypt(f)
async with aiofiles.open(dest_decrypt_uri, mode='wb') as f:
await f.write(content_video_part)
print(f'[{class_video_name}]——已解密第 {decrypt_name} 个片段/ 共 {len(playlist.files)} 个片段')


async def decrypt_m3u8_all():
if not os.path.exists(class_video_name + '/decryption'):
os.makedirs(class_video_name + '/decryption')
key = await requests.get(playlist.keys[0].uri)
key = key.content
iv = bytes(playlist.keys[0].iv, 'UTF-8')[:16]
decrypt_m3u8_list = [asyncio.create_task(decrypt_m3u8_video(f'{class_video_name}/downloads/{uri}', key, iv))
for uri in os.listdir(f'{class_video_name}/downloads') if uri[0] != '.'] # 忽略隐藏文件
await asyncio.wait(decrypt_m3u8_list)
print(f'[{class_video_name}]——视频全部解密完成')


def merge_m3u8_all():
download_decrypt_list = [uri for uri in os.listdir(f'{class_video_name}/decryption') if uri[0] != '.']
download_encrypt_list = [uri for uri in os.listdir(f'{class_video_name}/downloads') if uri[0] != '.']
if len(download_decrypt_list) != len(download_encrypt_list): # 判断是否有漏下的分段视频没有下载
print('解密分段视频出现问题,可能是受限于类Unix系统文件句柄数量限制导致脚本不能获取足够的文件句柄。\n '
'如果你是 Linux 或 Macos 请尝试在运行本脚本的终端内执行 "ulimit -n 5120" 命令,以解除255(Macos)/1024(Linux)数量限制')
return
with open(f'{class_video_name}/{class_video_name}.mp4', 'ab') as final_file:
print(f'[{class_video_name}]——开始拼接解密后的分段视频')
temp_file_uri_list = os.listdir(f'{class_video_name}/decryption')
temp_file_uri_list.sort(key=lambda x: int(x[:-6]))
for uri in temp_file_uri_list:
if uri[0] == '.': continue # 忽略隐藏文件
with open(f'{class_video_name}/decryption/{uri}', 'rb') as temp_file:
final_file.write(temp_file.read()) # 将ts格式分段视频追加到完整视频文件中
print(f'[{class_video_name}]——合成视频成功')


if __name__ == '__main__':
playlist = m3u8.load(m3u8_file_uri, verify_ssl=False)
del playlist.files[0] # 第一个文件为视频密钥,忽略这个文件。
asyncio.run(download_m3u8_all())
asyncio.run(decrypt_m3u8_all())
merge_m3u8_all()
print(f'[{class_video_name}]——视频文件:{os.getcwd()}/{class_video_name}/{class_video_name}.mp4')

钉钉

钉钉回放下载更简单,之后将腾讯课堂回放的脚本稍作删减就可以用于钉钉回放下载。

Ceph块设备 对RBD块设备操作LVM创建PV时报错

当映射好了RBD映像中后,要在其上创建LVM逻辑卷,在执行pvcreate时出错。报错如下:

[root@ceph-master ceph]# pvcreate /dev/rbd0
/dev/sdd: open failed: No medium found
Device /dev/rbd0 excluded by a filter.

可以看到执行创建PV时被过滤器拦截掉了,这是因为默认情况下LVM不支持rbd设备类型,那么在LVM过滤器配置中手动添加RBD类型即可。

调试模式查看详细信息:

# pvcreate -vvvv /dev/rbd0 &> /tmp/out
# less /tmp/out
....
#filters/filter-type.c:27 /dev/rbd0: Skipping: Unrecognised LVM device type 252
....

查看设备类型ID

cat /proc/devices

可以找到rbd设备类型ID编号为252,记住它后接下来在LVM过滤器配置文件中添加它。

修改LVM过滤器配置文件

vim /etc/lvm/lvm.conf

找到types参数,将rbd和252修改为如下配置:

...
# Configuration section devices.
# How LVM uses block devices.
devices {
...
# Configuration option devices/types.
# List of additional acceptable block device types.
# These are of device type names from /proc/devices, followed by the
# maximum number of partitions.
#
# Example
types = [ "rbd", 252 ]
#
# This configuration option is advanced.
# This configuration option does not have a default value defined.
...

现在尝试重新添加rbd设备作为PV:

pvcreate /dev/rbd0

现在可以成功在RBD块设备上执行创建PV操作了。

Ceph 映射RBD块设备

前提准备

你需要有一个运行着的Ceph集群,并且已创建好了一个Pool池,以此来创建新的RBD映像。

Pool池名称:rbd

Namespace命名空间名称:42team

要创建的RBD镜像名:42team.dev.yeefire.com.100G.img

新建块设备

创建块设备首先要创建Pool池,关于Pool池的创建如果你还不知道的话可以先看看这篇文章:OSD与Pool池的常见操作及管理

创建Pool池:ceph osd pool create rbd 16 16

新创建的Pool池如果要用于RBD映像存储的话最好先对其初始化并对这个Pool池设置rbd应用:

  • 初始化Pool池用于RBD存储:rbd pool init rbd
  • 为rbd池设置app应用,并标记rbd应用:ceph osd pool application enable rbd rbd

创建命名空间(非必要操作)

命名空间的存在是方便对一个存储池Pool进行更细化的用户访问控制,这样可以少创建一些存储池,使用池中命名空间来对用户进行隔离。

如果你想了解如何使用cephx认证配合命名空间对用户限制访问池中资源,请阅读:Ceph用户管理

为rbd池创建名为42team的命名空间:namespace create -p rbd --namespace 42team

创建RBD映像

到这一步为止,你已经做了如下操作:

  • 有一个正常状态的Ceph存储集群
  • 创建了一个名为rbd的存储池
  • 将rbd存储池的application应用设置为rbd
  • 可选:(为rbd池创建名为42team的命名空间)
  • 可选:(创建一个cephx认证用户,并将这个用户的osd能力限制在rbd池中的42team命名空间内)

接下来开始创建一个RBD映像

rbd create -p rbd --namespace 42team --size 100G 42team.dev.yeefire.com.100G.img

查看创建的rbd映像

rbd ls -p rbd --namespace 42team

映射RBD映像到内核模块

用 rbd 把映像名映射为内核模块。必须指定映像名、存储池名、和用户名。若 RBD 内核模块尚未加载, rbd 命令会自动加载。

例如要将rbd池中42team命名空间的42team.dev.yeefire.com.100G.imgRBD映像映射到本机:

rbd device map -p rbd --namespace 42team --image 42team.dev.yeefire.com.100G.img

至此挂载RBD映像成功,如果要查看本机已挂载的RBD映像可以执行:

rbd device ls

Nginx反向代理下载传输超过1G大文件时断开问题

问题描述

42Team社团上线下载站,使用Nginx反向代理为用户提供服务。问题的现象是当用户下载文件超过1G大小时出现断开下载连接的情况导致下载失败。

问题分析

一开始以为是Flask的流传输出了问题,调试并跟踪代码后并没有发现问题,而且直接在本地代码调试下载大文件不会出现断开情况。那么开发环境与生产环境中只相差了中间有一层Nginx反向代理,那么初步问题定位到Nginx的反向代理配置上。

经过在网上进行搜索“反向代理下载大文件失败断开连接”等关键字后找到了一篇其他人写的博文,遇到过类似的问题。

发现可能是因为超时的原因导致,因为反向代理服务器和部署下载站服务的服务器之间的网络传输速度和磁盘性能非常好,所以他们之间传递1G以上的大文件仅仅有几秒的时间,而Nginx反向代理服务器将文件传输到用户端可能需要数分钟或数十分钟,由于这之间的时间差非常大,所以超过了Nginx的默认连接超时时间,导致此问题发生

问题解决

禁用缓存

禁用缓存,客户端的每次清求都转发到被代理服务器,做法是在代理服务器的Nginx配置里面添加:

proxy_pass http://172.17.8.88:5050/;
proxy_redirect default;
proxy_buffering off;

加大Nginx服务器与另一服务器之间的超时等待时间

keepalive_timeout 15;
send_timeout 3600;

Nginx反向代理导致大文件下载失败