kubernetes pod 挂载不同路径

今天给一个daemonset 创建挂载卷,要求多个pod不会挂载同一个挂载卷,查看了相关资料,有两种方式可以达到:

  1. 使用 statefulset的volumeClaimTemplate
  2. 加载环境变量挂载subpath

第一种方式因为需要使用 storageClassName ,目前的环境没有做相关的东西,嫌麻烦就先不做了,第二种方式简单,需要在普通挂载的基础上新增两个内容:

  1. 环境变量 valueFrom/fieldRef
  2. 挂载 subPathExpr
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: container1
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    image: busybox
    command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
    volumeMounts:
    - name: workdir1
      mountPath: /logs
      subPathExpr: $(POD_NAME)
      readOnly: false
  restartPolicy: Never
  volumes:
  - name: workdir1
    hostPath:
      path: /var/log/pods

参考资料


使用 fluentd 抓取 k8s 的组件日志并推送至 EFK 日志栈

以容器方式启动的组件,常常随着容器的停止而销毁,给平时定位问题带来了一定的难度。

这一篇记录如何使用 fluentd 采集 kubernetes 的容器组件的日志,并推送到es中。本文适用的 kubernetes 版本为 v1.10。

日志类型

k8s系统组件有两种类型:在容器中运行的和不在容器中运行的。例如:

  • 在容器中运行的 kube-scheduler 和 kube-proxy。
  • 不在容器中运行的 kubelet 和容器运行时(例如 Docker)

kubelet和docker的日志都由 journald 进行管理,定位问题时问题不大。

容器组件日志位置

文件夹 /var/log/containers 下包含了所有组件的日志链接。

进入这个文件夹我们可以看到一家人的组件排的整整齐齐:

$ ls /var/log/containers

calico-node-xxx.log
coredns-xxx.log
kube-apiserver-xxx.log
kube-controller-manager-xxx.log
kube-proxy-xxx.log
kube-scheduler-xxx.log
traefik-ingress-controller-xxx.log

实际上这是个软链接,后边还跟了两层软链接:

-> /var/log/pods

-> /var/lib/docker/containers/

更多需要考虑的

想象一下我们使用 kibana 查看日志,在满屏的日志中,我们需要区分这些日志:

  • 不同的节点
  • 同一节点的不同组件
  • 同一组件的不同容器

其中同一节点不同组件,我们可以在 fluentd 中对 日志来源打 tag 标记。可以参考 fluentd 官方帮助 https://docs.fluentd.org/input/tail

不同容器可以通过 fluentd 配置把文件名附到日志字段。

节点名也同样如此。那么fluentd 容器如何获得节点名呢?但是这有个窍门,为 fluentd 容器增加一个环境变量:

env:
  - name: MY_NODE_NAME
    valueFrom:
      fieldRef:
        fieldPath: spec.nodeName

更多实用的变量可参考官方:https://kubernetes.cn/zh/docs/tasks/inject-data-application/environment-variable-expose-pod-information/

开始

基本思路是fluentd 的配置文件使用 configmap 进行保存。

然后将所有组件的日志和configmap都挂在到 fluentd 容器中。

创建 fluentd 配置文件

注意 fluentd 要配置 read_from_head true ,否则会有组件启动日志薛定谔采集的问题。

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-for-k8s-component
data:
  fluent.conf: |-
    <source>
    @type tail
    read_from_head true
    path /var/log/containers/kube-apiserver-*.log
    path_key file_name 
    pos_file /log/fluentd/pos/pos-kube-apiserver.log
    tag runtime-kube-apiserver
    limit_recently_modified 7d
    multiline_flush_interval 1s
    <parse> 
        @type json
        time_key time
        time_type string
        time_format %Y-%m-%dT%H:%M:%S.%N%z
    </parse>
    </source>
    ... ...
    # 依葫芦画瓢把一系列的日志搞进来
    ... ...
    
    # 为每条记录附加节点字段
    <filter runtime-*>
      @type record_transformer
      <record>
        nodename "#{ENV['MY_NODE_NAME']}"
      </record>
    </filter>

    # es地址
    <match runtime-*>
    @type forward
    <server>
      host 1.2.3.4
      port 12345
      weight 50
    </server>
    <server>
      host 1.2.3.4
      port 12346
      weight 50
    </server>
    
    <buffer tag,time>
        @type file
        path /var/log/td-agent/buffer/docker
        timekey 3600
        timekey_wait 0s
        timekey_use_utc false
        flush_mode interval
        flush_interval 10s
        chunk_limit_size 20M
    </buffer>
    </match>

创建 fluentd damenset

需要注意的有:

  • 采集容器在每个节点上都有,所以要避免 calico 分配IP导致路由表难看,直接使用 host 的IP即可。
  • 注意污染和容忍的配置,要容忍所有污染,否则一旦新增一个污染就取不到这个节点的日志了。
  • 镜像尽可能选新的
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-for-k8s-component
  labels:
    k8s-app: fluentd-for-k8s-component
    version: v1
spec:
  selector:
    matchLabels:
      k8s-app: fluentd-for-k8s-component
  template:
    metadata:
      labels:
        k8s-app: fluentd-for-k8s-component
        version: v1
    spec:
      containers:
        - name: fluentd
          image: "fluent/fluentd:v1.4"
          resources:
            limits:
              memory: 200Mi
            requests:
              cpu: 100m
              memory: 200Mi
          env:
            - name: MY_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
          volumeMounts:
            - name: fluentd-pos
              mountPath: /log/fluentd/pos
            - name: fluentd-config
              mountPath: /fluentd/etc/fluent.conf
              subPath: fluent.conf
            - name: var-log-containers
              mountPath: /var/log/containers
              readOnly: true
            - name: var-log-pods
              mountPath: /var/log/pods
              readOnly: true
            - name: var-log-real
              mountPath: /var/lib/docker/containers
              readOnly: true
          securityContext:
            runAsUser: 0
      terminationGracePeriodSeconds: 30
      volumes:
        - name: fluentd-config
          configMap:
            name: fluentd-for-k8s-component
            defaultMode: 420
        - name: fluentd-pos
          hostPath:
              path: /app/fluentd/pos
              type: DirectoryOrCreate
        - name: var-log-containers
          hostPath:
              path: /var/log/containers
              type: DirectoryOrCreate
        - name: var-log-pods
          hostPath:
              path: /var/log/pods
              type: DirectoryOrCreate
        - name: var-log-real
          hostPath:
              path: /var/lib/docker/containers
              type: DirectoryOrCreate
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      - operator: Exists
        effect: NoExecute
      - key: CriticalAddonsOnly
        operator: Exists

参考资料


通过 laravel horizon 和 telescope 加强队列的管理

原文链接:Laravel HorizonとLaravel Telescopeでできること オープンロジにおけるQueueの運用管理 ,扫盲向而且挺实用,转载过来记录几个要点。

PPT地址: https://cdn.kelu.org/blog/2020/06/20190318-Laravue8-OPENLOGI.pdf

大家好,我是Open Logic的Igarashi。关于Vue和前台的大家讨论了很多,接下来我谈谈服务器端。

上个月我在 OpenLogi 的 Laravel 分享会中谈到 “Laravel 队列操作与管理”,今天我就这个话题进一步展开。

CgJcYXTTVMGJpoYfyyoAva

首先做个自我介绍…// (介绍他们公司的,主要做物流的,就不转了。)

SKkNfG6v4j24cRM83coW8F

我们的技术栈去年有分享过,在Qiita上可以找到。简单来说,服务器端是Laravel,前端是React。我将Vue用于新产品。

job 基础

20多年前,Bertrand Meyer在他的《Object-Oriented Software Construction》一书中提出了CQS(Command Query Seperation,命令查询分离)的概念,后来,Greg Young在此基础上提出了CQRS(Command Query Resposibility Segregation,命令查询职责分离),将CQS的概念从方法层面提升到了模型层面,即“命令”和“查询”分别使用不同的对象模型来表示。

采用CQRS的驱动力除了从CQS那里继承来的好处之外,还旨在解决软件中日益复杂的查询问题,比如有时我们希望从不同的维度查询数据,或者需要将各种数据进行组合后返回给调用方。此时,将查询逻辑与业务逻辑糅合在一起会使软件迅速腐化,诸如逻辑混乱、可读性变差以及可扩展性降低等等一些列问题。

对于Web应用程序,处理中要做的主要事情是读取或写入信息。

6j1pZKdkokWfBPAaEdKBgj

上图是一个简单的配置,读取意味着通过Web服务器从数据库读取数据并将结果返回给客户端。

如果有要写入的内容,则可以通过POST等方法通过Web服务器将其写入数据库,如果成功,则将结果返回给客户端。

原则上,我们不应在同一台Web服务器上进行读写。做到这一点的方法是利用工作。首先,以Command 的形式将其扔到 Web 服务器。Web 服务器将其加入队列。然后,执行可变处理的作业服务器使队列出队并执行写处理。

img

将结果返回给客户端的方式有很多种选择,可以使用Pusher 和 Redis。我们使用 Pusher 来实现。即使 Pusher 服务器不同,也可以正确地异步发送反馈。

看起来非常困难,但是由于Laravel从一开始就考虑到DDD和CQRS的设计,因此实现起来非常容易。

img

在Controller上有一个方法,例如 updateItem,CQRS 的做法就是创建一个名为updateItem的作业并将其分派。

job的状态管理

img

这是 Laravel Horizon和Laravel Telescope。 它们很相似。

img

Telescope 是一个开发调试工具,用于了解 Laravel 中的状态。虽然我们有了 Laravel Debugbar 这样的工具用于开发,但是 Laravel 中会发生各种事件,例如请求,查询和作业状态以及通知事件的结果,Telescope 可以将这些状态集中起来看。

从这里可以看到,有各种参数,例如Exception,log,query,model,event等。

Horizon 是用于生产环境的监视工具,而 Telescope 是用于给开发人员使用的工具。

两者都支持队列,不过 Horizon 仅支持 Redis。Telescope 不仅限于Redis,它还支持 DB 队列、SQS队列,并且可以看到所有同步作业的状态。

Horizon 主要是用于调试和监视。

img

如上图,在OpenLogi中,我们单独记录了job的状态,通过将所有更新处理整合到job中来,我们还可以跟踪谁进行了什么操作以及何时进行。

img

Telescope 也做了类似的事情,它会记录用户使用哪些参数运行的作业。这种记录会增加数据库的负担,不过它仅用于调试,线上不运行,但这是我想要的。

img

您可以看到针对查询,职位和电子邮件发出了什么样的查询,因此我认为这对开发很有用。

重新执行失败的作业也是操作中的常见情况。

img

img

关于这一点,Laravel Horizon 中有一个类似的页面,但是我们在Horizon 之前就设计了这类工具。

img

我需要像 Horizon 这样的监视工具,但同时我也希望能够像 Telescope 这样正确地记录日志,有点鱼和熊掌不可得兼的感觉。我正在寻找一种可以管理的工具,但是现在我们打算自己实现它。

总结

img


阿里的一些论文

google,Facebook等国外大佬经常在顶级会议上(SOSP/PLDI/NSDI等等)发论文,阿里也发表了好些的论文。以前整理了相关东西,不成章法,凑了这篇文章,以后研究的话再捡起来。

SIGCOMM 2020

《VTrace: Automatic Diagnostic System for Persistent Packet Loss in Cloud-Scale Overlay Network》

超大规模下的云网络异常定位、

传统网络工具 VS 大数据染色报文分析

云网络碰到类似问题只能用网工三板斧来处理: 抓包,ping, trace。

阿里云网络团队首次采用大数据结合染色报文的方式,通过大数据技术给这个交警配备了一个超强的大脑,让他能实时处理千万级网络数据,同时,结合染色报文技术让所有网络里面的数据包信息实时传递给我们的云网络交警。最后的结果就是这个云网络交警能实时感知到整个云网络每台设备的丢包和拥塞情况。阿里云网络给这个交警取了一个名字,叫vTrace。当用户在上网过程中碰到网络问题时,vTrace能很快找到对应链路上出现问题的节点在哪里,解决了云网络排查问题难的痛点,加快用户网络问题恢复过程。

SIGCOMM2019

来自阿里云智能的两篇论文

  • 《HPCC: High Precision Congestion Control》 高速网络拥塞控制协议HPCC
    • 阿里巴巴此前已通过对RDMA网络的改造,从网卡底层开始设计,结合自研交换机能力,建成全球最大规模的“RDMA高速网络”。
    • 在这次的论文中,阿里巴巴就提出了一种全新的网络协议——新一代高速网络拥塞控制协议HPCC(High Precision Congestion Control),不仅保证传输性能快,还能保证传输稳定,真正适用于当下的网络需求。
  • 《Safelyand Automatically Updating In-Network ACL Configurations with Intent Language》 使用意图语言安全且自动地更新网络内ACL配置

FAST2020

存储行业顶级国际会议FAST2020(18th USENIX Conference on File and Storage Technologies)在美国圣克拉拉举行,大会公开论文名单显示,阿里巴巴3篇第一作者论文入选,是全球入选数最多的企业。

在《POLARDB结合可计算存储: 高效支持云原生关系数据库的复杂查询操作》一文中,阿里团队针对PolarDB,把SQL和存储引擎的计算逻辑下推到底层共享存储,并通过定制SSD内部的FPGA进一步下推计算至存储节点的SSD内部,完成更高效率计算的同时,大幅降低主机和网络带宽占用,为PolarDB在复杂查询场景下带来4~5倍的吞吐提升。

另两篇文章,聚焦键值存储(KVS)。

在《FPGA加速Compactions操作,基于 LSM-tree的键值存储》一文中,研究团队首次引入异构硬件FPGA,实现KVS核心操作Compaction加速,较仅CPU处理能力提升2~5倍,整体吞吐性能提升23%,能效提升31.7%。

在《HotRing:热点感知的无锁内存键值系统》一文中,阿里团队提出新型热点感知内存KVS — HotRing,采用轻量级的热点识别策略,在未增加元数据存储开销的同时,还对幂率分布的热点场景进行大量优化,使得HotRing的引擎吞吐性能可达600M ops/s,单次访问平均只需100ns,比目前最快KVS性能提升2.58倍。

ASPLOS’19

摘要: 阿里云首次在ASPLOS上发表论文,第24届ACM编程语言和操作系统(ASPLOS’19),于2019年4月13日至17日,在普罗维登斯召开,阿里云高级技术专家郑晓代表团队在会上发表了技术报告。

第24届ACM编程语言和操作系统(ASPLOS’19),于2019年4月13日至17日,在普罗维登斯召开,阿里云高级技术专家郑晓代表团队在会上发表了技术报告。

论文主题为《Fast and Scalable VMM Live Upgrade in Large Cloud Infrastructure》,作者是张献涛,郑晓,沈益斌等。这篇论文被计算机系统结构的顶级会议ASPLOS’19接受,是业界对于VMM热升级这项突破性技术的认可。

论文ACM下载地址:https://dl.acm.org/citation.cfm?id=3304034 PDF下载地址:https://yq.aliyun.com/download/3532

该论文系统的阐述了当前云计算领域面临的基础架构带业务热升级问题。提出了一种新型的,比热迁移更行之有效的方法,特别适合超大规模集群范围的使用,解决了困扰云计算行业多年的问题。该方案在阿里云大规模采用,服务百万级别的客户虚拟机数量。论文解决了在客户业务不中断的情况下以毫秒级的速度更换底层虚拟化组件。

阿里云热升级技术特点决定了可以同时热升级任意数量任意规格的虚拟机,并且升级时间恒定。更难得的是,在业界尚未有异构计算设备热迁移方案的情况下,阿里云热升级技术同时支持异构计算等以设备直通方式工作的虚拟机。帮助ECS在过去五年进行了快速的升级迭代,保障了产品和业务的快速奔跑。

ASPLOS(编程语言和操作系统的体系结构支持会议)会议全称为ACM International Conference on Architectural Support for Programming Languages and Operating Systems,是综合体系结构、编程语言和操作系统三个方向的计算机系统领域顶级会议,为CCF A类会议。从1982年创办至今的三十多年里,ASPLOS推动了多项计算机系统技术的发展,包括(但不限于)RISC、RAID、大规模多处理器、Cluster架构和网络存储等。


查看并记录服务器硬件信息

查了相关的文章做个记录,从CPU、内存、网卡、硬盘、主板、BIOS、操作系统几个方面。

一、硬件

1.1 服务器型号、序列号

dmidecode|grep "System Information" -A9|egrep  "Manufacturer|Product|Serial" 

image-20210604175015800

1.2 主板型号

dmidecode |grep -A16 "System Information$" 

image-20210604175154526

1.3 查看BIOS信息

 dmidecode -t bios

image-20210604175234570

1.4 查看内存槽及内存条

dmidecode -t memory | more

image-20210604175550817

1.5 查看主板所有硬件槽信息

lspci # 可列出每个pci总线上的设备, 通过grep过滤后可得到网卡设备列表

image-20210604180408326

1.6 查看网卡信息

lspci | grep -i net

image-20210604180408326

二、CPU

(1)查看 cpu 核数和型号,主频等

cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c

image-20210604180928552

(2)查看系统有几颗CPU

grep 'physical id' /proc/cpuinfo | sort | uniq | wc -l
1

(3)CPU的逻辑个数(开启超线程时1个core相当于2个逻辑cpu)

cat /proc/cpuinfo |grep 'processor'|wc -l
8

(4)查看每颗 CPU 中的内核个数

cat /proc/cpuinfo |grep "cores"|uniq 
cpu cores : 4

(5)查看CPU的主频

cat /proc/cpuinfo |grep MHz|uniq 

cpu MHz         : 4102.000
cpu MHz         : 4105.465
cpu MHz         : 4100.059
cpu MHz         : 4147.903
cpu MHz         : 4100.493
cpu MHz         : 4100.521
cpu MHz         : 4160.260
cpu MHz         : 4138.348

(6)查看CPU的详细信息

cat /proc/cpuinfo
processor : 0 //逻辑处理器的ID
vendor_id : GenuineIntel
cpu family : 6
model : 158
model name : Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz   //CPU型号
stepping : 9
microcode : 0x84
cpu MHz : 4070.787
cache size : 8192 KB
physical id : 0
siblings : 8 //相同物理封装处理器中逻辑处理器数
core id : 0
cpu cores : 4 //相同物理封装处理器中的内核数

image-20210605161138951

(7)查看CPU的相关信息

lscpu

(8)查看 cpu 是32位还是64位

[root@Master ~]# getconf LONG_BIT
64

三、内存

free -mh                 								# 概要查看内存情况
dmidecode -t memory      								# 查看内存硬件信息
dmidecode|grep -P 'Maximum\s+Capacity' 	# 最大支持多少内存

image-20210605161653092

dmidecode|grep -A5 "Memory Device"|grep Size | grep -v Range # Linux 查看内存已经使用插槽数

image-20210605161857039

dmidecode|grep -A16 "Memory Device"|grep 'Speed' # 内存频率

image-20210605162129768

cat /proc/meminfo |head -20 # 内存详细信息

image-20210605162344913

free -mh # 内存使用情况

image-20210605162459550

四、网卡

ifconfig
ethtool bond0
ethtool bond1

ifconfig -a
ip link show

五、硬盘

lsblk  # fdisk一般用来磁盘分区,也可以用来查看磁盘分区情况
fdisk -l # 硬盘和分区的详细信息

image-20210607163611855

image-20210607163644643

# lsblk命令用于列出所有可用块设备的信息,而且还能显示他们之间的依赖关系
lsblk

image-20210608230402740

image-20210608230420949

# 其他命令

mount | column -t
swapon -s Filename Type Size Used Priority
df -hT
du --max-depth=1 -ah 2> /dev/null | sort -hr | head
smartctl -a /dev/sda

操作系统

uname -a
cat /etc/redhat-release
dmidecode -s system-serial-number # 系统序列号

一个简单的脚本

#!/usr/bin/env bash

if  [ ! -e '/usr/bin/wget' ]; then
    echo "Error: wget command not found. You must be install wget command at first."
    exit 1
fi

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;36m'
PLAIN='\033[0m'

get_opsy() {
    [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return
    [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return
    [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return
}

next() {
    printf "%-70s\n" "-" | sed 's/\s/-/g'
}

calc_disk() {
    local total_size=0
    local array=$@
    for size in ${array[@]}
    do
        [ "${size}" == "0" ] && size_t=0 || size_t=`echo ${size:0:${#size}-1}`
        [ "`echo ${size:(-1)}`" == "K" ] && size=0
        [ "`echo ${size:(-1)}`" == "M" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' / 1024}' )
        [ "`echo ${size:(-1)}`" == "T" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' * 1024}' )
        [ "`echo ${size:(-1)}`" == "G" ] && size=${size_t}
        total_size=$( awk 'BEGIN{printf "%.1f", '$total_size' + '$size'}' )
    done
    echo ${total_size}
}

cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' )
cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo )
freq=$( awk -F'[ :]' '/cpu MHz/ {print $4;exit}' /proc/cpuinfo )
tram=$( free -m | awk '/Mem/ {print $2}' )
uram=$( free -m | awk '/Mem/ {print $3}' )
swap=$( free -m | awk '/Swap/ {print $2}' )
uswap=$( free -m | awk '/Swap/ {print $3}' )
up=$( awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60} {printf("%d days, %d hour %d min\n",a,b,c)}' /proc/uptime )
load=$( w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//' )
opsy=$( get_opsy )
arch=$( uname -m )
lbit=$( getconf LONG_BIT )
kern=$( uname -r )
#ipv6=$( wget -qO- -t1 -T2 ipv6.icanhazip.com )
disk_size1=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem|udev|docker' | awk '{print $2}' ))
disk_size2=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem|udev|docker' | awk '{print $3}' ))
disk_total_size=$( calc_disk "${disk_size1[@]}" )
disk_used_size=$( calc_disk "${disk_size2[@]}" )

clear
next
echo -e "CPU                  : ${BLUE}$cname${PLAIN}"
echo -e "核心数               : ${BLUE}$cores${PLAIN}"
echo -e "CPU 主频             : ${BLUE}$freq MHz${PLAIN}"
echo -e "硬盘                 : ${BLUE}$disk_total_size GB ($disk_used_size GB Used)${PLAIN}"
echo -e "内存                 : ${BLUE}$tram MB ($uram MB Used)${PLAIN}"
echo -e "交换分区             : ${BLUE}$swap MB ($uswap MB Used)${PLAIN}"
echo -e "OS                   : ${BLUE}$opsy${PLAIN}"
echo -e "Arch                 : ${BLUE}$arch ($lbit Bit)${PLAIN}"
echo -e "内核                 : ${BLUE}$kern${PLAIN}"
echo -e "运行时间             : ${BLUE}$up${PLAIN}"
echo -e "平均负载             : ${BLUE}$load${PLAIN}"
next

附:dmidecode 是什么

dmidecode可以让你在Linux系统下获取有关硬件方面的信息。

dmidecode的作用是将DMI数据库中的信息解码,以可读的文本方式显示。由于DMI信息可以人为修改,因此里面的信息不一定是系统准确的信息。

dmidecode遵循SMBIOS/DMI标准,其输出的信息包括BIOS、系统、主板、处理器、内存、缓存等等。

DMI(Desktop Management Interface,DMI)就是帮助收集电脑系统信息的管理系统,DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行。SMBIOS(System Management BIOS)是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范。SMBIOS和DMI是由行业指导机构Desktop Management Task Force(DMTF)起草的开放性的技术标准,其中DMI设计适用于任何的平台和操作系统。

DMI充当了管理工具和系统层之间接口的角色。它建立了标准的可管理系统更加方便了电脑厂商和用户对系统的了解。DMI的主要组成部分是Management Information Format(MIF)数据库。这个数据库包括了所有有关电脑系统和配件的信息。通过DMI,用户可以获取序列号、电脑厂商、串口信息以及其它系统配件信息。

参考资料


Debian 9/10 安装 WireGuard 备忘

不升级内核,或者内核ok但没有头文件,都有可能会遇到这样的错误:

RTNETLINK answers: Operation not supported

升级内核先参考我先前这篇文章:《debian 升级内核》

安装

sudo apt-get install libmnl-dev linux-headers-$(uname -r) build-essential make git # 安装必要的包

# 如果无法安装headlers,那么应该是内核偏老,先升级到比较新的内核

echo "deb http://deb.debian.org/debian/ unstable main" | sudo tee /etc/apt/sources.list.d/unstable.list
echo -e "Package: *\nPin: release a=unstable\nPin-Priority: 150\n" | tee /etc/apt/preferences.d/limit-unstable

apt-get update
apt-get upgrade
apt-get install wireguard-dkms wireguard-tools

配置

sudo mkdir -p /etc/wireguard
cd /etc/wireguard
sudo umask 077

# 快速生成密钥
sudo wg genkey | tee privatekey | wg pubkey > publickey

新建配置文件 wg0.conf

注意修改监听端口ListenPort,如果启用了防火墙,还需要开通相关端口

[Interface]
PrivateKey = #服务端的密钥
Address = 10.0.0.1/24, fd86:ea04:1115::1/64 #服务端的地址
ListenPort = 28472 #服务端的端口
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
SaveConfig = true

启动

快速启动:

sudo wg-quick up wg0

开机启动:

systemctl enable wg-quick@wg0

查看运行状况:

wg

配置客户端

其实 wireguard 中没有严格的客户端服务端的区别,配置客户端过程和服务端过程一样。只要把服务端的公钥和自己的公钥写入配置文件中,再填好对端的IP,会自动连接配对好。

以下是配置参考:

[Interface]
PrivateKey = #客户端的密钥
Address = 100.100.100.2/32 #客户端的内网地址
MTU = 1420
[Peer]
PublicKey = #服务端的公钥
Endpoint = 12.32.42.52:28472 #服务端的IP和端口
AllowedIPs = 100.100.100.0/24, 10.64.0.0/10, 10.128.0.0/10 #允许走wireguard的目的IP
PersistentKeepalive = 25

把这个配置连同客户端的公钥密钥一起放到客户端的/etc/wireguard文件夹中,就能启动了。

如果希望生成二维码,方便iOS和android刷二维码,还可以使用qrencode命令:

qrencode -t ansiutf8 < wg0.conf

Debian 10安装

  1. 增加源信息

    echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable-wireguard.list
    printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable
    
  2. 更新源然后安装相关软件,用来编译 wireguard内核模块

    apt update
    apt install wireguard-dkms wireguard-tools
    

仍然报错

[#] ip link add wg0 type wireguard
RTNETLINK answers: Operation not supported
Unable to access interface: Protocol not supported
[#] ip link delete dev wg0
Cannot find device "wg0"

还是升级内核吧:

apt-get dist-upgrade
update-grub
/sbin/reboot

不过很奇怪,我重启之后内核其实并没有升级,但是 wireguard 能跑起来了。可能是中途某些步骤需要重启系统。下次遇到再补充了。