分类 系统运维 下的文章

在某些情况下,你需要映射存储 LUN(逻辑单元号)、块设备、LVM(LV 和 VG 名称)和文件系统(FS)信息以进行文件系统扩展或灾难恢复(DR)操作。

这是大多数 Linux 管理员的例行活动,我们通常使用一些脚本来显示针对 SAN LUN 的块设备映射,然后我们将手动添加 LVM 和文件系统信息来完成操作。

今后,你无需手动干预此活动,因为这些信息可以通过 Shell 脚本进行映射,如下所示。

参考以下类似文章:

在 Linux 中映射 LUN、磁盘、LVM 和文件系统的 Shell 脚本

这个 Shell 脚本可帮助你识别哪些 SAN 磁盘映射到 Linux 上的哪些块设备、LV、VG 和文件系统。

请注意: 我们排除了 sda 磁盘,因为这是操作系统(OS)盘,它有多个分区。

vi block_device_mapping_with_LUN_FS_LVM.sh
#!/bin/bash
for bdevice in `lsblk | grep disk | awk '{print $1}' | grep -v 'sda'`; do
    for mpoint in `lsblk /dev/$bdevice | grep lvm | awk '{print $NF}'`; do
        LVM_INFO=`lvs -o +devices | grep -i $bdevice | awk '{print $1,$2}'`
        LUN_ID=`lsscsi --scsi | grep $bdevice | awk '{print $NF}'`
        echo "$bdevice --> $mpoint --> $LVM_INFO --> $LUN_ID"
    done
done

设置 block_device_mapping_with_LUN_FS_LVM.sh 文件的可执行权限。

chmod +x block_device_mapping_with_LUN_FS_LVM.sh

最后运行脚本查看结果。

sh block_device_mapping_with_LUN_FS_LVM.sh

注意: 在上面的输出中,设备 sdb 不会显示任何 LUN 信息,因为它是从 VMWare 端添加的虚拟磁盘,没有任何 LUN。其他 3 块磁盘是从存储映射的,这就是为什么可以看到 LUN 信息。

如果你想即时运行上述脚本,请使用下面的一行脚本。

for bdevice in `lsblk | grep disk | awk '{print $1}' | grep -v 'sda'`; do for mpoint in `lsblk /dev/$bdevice | grep lvm | awk '{print $NF}'`; do LVM_INFO=`lvs -o +devices | grep -i $bdevice | awk '{print $1,$2}'`; LUN_ID=`lsscsi --scsi | grep $bdevice | awk '{print $NF}'`; echo "$bdevice --> $mpoint --> $LVM_INFO --> $LUN_ID"; done; done
sdb --> [SWAP] --> swap2lv swapvg --> -
sdc --> /appserver --> appserver_lv appserver_vg --> 360000670000415600477312020662021
sdd --> /data --> data_lv data_vg --> 360000670000415600477312020662022
sde --> /backup --> backup_lv backup_vg --> 360000670000415600477312020662023

总结

在本教程中,我们向你展示了如何在 Linux 上检查 SAN 提供的 LUN 以及底层操作系统磁盘、LV 名称、VG 名称和关联的文件系统。

如果你有任何问题或反馈,请随时在下面发表评论。

(题图:MJ/f5da2270-4e5a-4b2c-8998-fae974214384)


via: https://www.2daygeek.com/map-san-lun-physical-disk-filesystem-lvm-info-linux/

作者:Rasool Cool 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

网络 绑定 Bonding 成组 Teaming ) 是 Linux 的一项内核特性,它让我们可以将多个网络接口(例如 ens192ens224)聚合为一个专有的虚拟网络接口,被称为通道绑定(bond0)。这样做能够提升吞吐量并增加冗余备份。

网络绑定一共支持 7 种模式,你可以根据实际需求进行设置。 链接聚合控制协议 Link Aggregation Control Protocol (LACP), 即模式 4(802.3ad)因其支持链接聚合与冗余而被广泛应用。

在本篇文章中,我们将引导你学习如何在 RHEL 系统中配置网卡(网络)绑定。

LACP 绑定的前置条件

  • 网络团队需要在网络交换机的端口上开启 LACP(802.3ad)来实现链接的聚合。
  • 一个 Linux 系统应该配备至少两个网络接口。
  • 对于物理服务器,我们推荐在板载接口与 PCI 接口间进行绑定配置,以避免在主机端的网络卡出现单点故障。

Bonding 模块

你可以使用 lsmod 命令来确认你的 Linux 系统是否已经加载了 bonding 模块。

lsmod | grep -i bonding
bonding               12451  0

系统应该默认已加载。如果未看到,可以运用 modprobe 命令进行加载。

modprobe bonding

创建绑定接口

/etc/sysconfig/network-scripts/ 路径下,创建一个名为 ifcfg-bond0 的绑定接口文件。依据你的网络情况,你可能需要修改诸如 IPMASK 以及 GATEWAY 等值。

vi /etc/sysconfig/network-scripts/ifcfg-bond0
TYPE=Bond
DEVICE=bond0
NAME=bond0
BONDING_MASTER=yes
BOOTPROTO=none
ONBOOT=yes
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
BONDING_OPTS="mode=4 miimon=100 lacp_rate=1"
参数描述
BONDING_MASTER=yes表示设备是一个绑定主设备。
mode=4绑定模式是 IEEE 802.3ad 动态链接聚合(LACP)。
miimon=100定义以毫秒单位的 MII 链路监测频率,这决定了多久检查每个从属链路的状态一次以寻找失败的链路。0 值将禁用 MII 链路监测。100 是个不错的初始值。
lacp_rate=1一个设置项,规定我们将以何种频率要求我们的链路伙伴每秒钟发送 LACPDU。默认为慢,即 0

配置第一个子接口

修改你希望添加到绑定中的第一个子接口。请根据你的实际环境使用合适的接口名。

vi /etc/sysconfig/network-scripts/ifcfg-ens192
TYPE=Ethernet
BOOTPROTO=none
DEVICE=ens192
ONBOOT=yes
MASTER=bond0
SLAVE=yes

配置第二个子接口

修改你希望添加到绑定中的第二个子接口。请根据你的实际环境使用合适的接口名。

vi /etc/sysconfig/network-scripts/ifcfg-ens224
TYPE=Ethernet
BOOTPROTO=none
DEVICE=ens224
ONBOOT=yes
MASTER=bond0
SLAVE=yes

重启网络服务

重启网络服务以激活绑定接口。

systemctl restart network

验证绑定配置

你可以借助 ip 命令 来查看绑定接口以及其子接口的情况。可以看到,bond0 现在已启动并在运行。

查阅绑定接口状态

检查以下文件,你可以看到绑定接口及其子接口的详细信息。输出结果应该看起来很不错,我们能看到诸如绑定模式,MII 状态,MII 轮询间隔,LACP 速率,端口数量等信息。

cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)

Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer (0)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

802.3ad info
LACP rate: fast
Min links: 0
Aggregator selection policy (ad_select): stable
System priority: 65535
System MAC address: c8:5b:76:4d:d4:5c
Active Aggregator Info:
        Aggregator ID: 1
        Number of ports: 2
        Actor Key: 15
        Partner Key: 32773
        Partner Mac Address: e4:a7:a0:32:fc:e9

Slave Interface: ens192
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: c8:5b:76:4d:d4:5c
Slave queue ID: 0
Aggregator ID: 1
Actor Churn State: none
Partner Churn State: none
Actor Churned State: 0
Partner Churned State: 0
details actor lacp pdu:
    system priority: 65535
    system mac address: c8:5b:76:4d:d4:5c
    port key: 15
    port priority: 255
    port number: 1
    port state: 63
details Partner lacp pdu:
    system priority: 32667
    system mac address: e4:a7:a0:32:fc:e9
    oper key: 32773
    port priority: 32768
    port number: 290
    port state: 61

Slave Interface: ens224
MII Status: up
Speed: 10000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: e4:a7:a0:32:fc:e9
Slave queue ID: 0
Aggregator ID: 1
Actor Churn State: none
Partner Churn State: none
Actor Churned State: 0
Partner Churned State: 0
details actor lacp pdu:
    system priority: 65535
    system mac address: e4:a7:a0:32:fc:e9
    port key: 15
    port priority: 255
    port number: 2
    port state: 63
details Partner lacp pdu:
    system priority: 32667
    system mac address: c8:5b:76:4d:d4:5c
    oper key: 32773
    port priority: 32768
    port number: 16674
    port state: 61

容错/冗余测试

为了验证容错性和连接速度,你可以逐个断开接口,然后检查服务器是否仍旧可达。

  • 测试用例-1:当两个子接口都启动并运行时,使用 ethtool 命令 检查链路速度。
  • 测试用例-2:断开第一个子接口,然后尝试访问系统。
  • 测试用例-3:断开第二个子接口,然后尝试访问系统。

测试用例-1:

如果你想检测下连接速度:没错,我在 bond0 上看到了 20 Gbps 的速度,因为每个子接口支持 10 Gbps。

ethtool bond0
Settings for bond0:
        Supported ports: [ ]
        Supported link modes:   Not reported
        Supported pause frame use: No
        Supports auto-negotiation: No
        Supported FEC modes: Not reported
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Advertised FEC modes: Not reported
        Speed: 20000Mb/s
        Duplex: Full
        Port: Other
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: off
        Link detected: yes

测试用例-2:

现在我们将关闭第一个子接口。

ifdown ens192
Device 'ens192' successfully disconnected.

通过 ssh 尝试访问系统。没问题,系统现在是可以访问的。

ssh [email protected]

由于已经有一个子接口关闭,你现在在 bond0 上只能看到 10 Gbps 的速度。

ethtool bond0 | grep -i speed
            Speed: 10000Mb/s

现在,我们再次查看绑定接口的状态。可以看出,只有一个子接口处于活跃状态。

cat /proc/net/bonding/bond0

测试用例-3:

我们来关闭第二个子接口,并进行类似测试用例-2 的测试:

ifdown ens224
Device 'ens224' successfully disconnected.

结语

我希望你已经掌握了在 RHEL 上配置 LACP 绑定的方法。

在本教程中,我们为你展示了在 RHEL 系统配置网络绑定或网卡聚合的最简单方式。

如果你有任何疑问或者反馈,欢迎在下面留言。

(题图:MJ/939f6ba6-eb46-480d-8879-3a422c7425d2)


via: https://www.2daygeek.com/configure-network-bonding-nic-teaming-rhel/

作者:Jayabal Thiyagarajan 选题:lujun9972 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在这篇文章中,我们将向你展示如何在 Kubernetes(k8s)集群中设置动态 NFS 配置。

Kubernetes 中的动态 NFS 存储配置允许你按需自动为 Kubernetes 应用配置和管理 NFS(网络文件系统)卷。它允许创建持久卷(PV)和持久卷声明(PVC),而无需手动干预或预配置存储。

NFS 配置程序负责动态创建 PV 并将其绑定到 PVC。它与 NFS 服务器交互,为每个 PVC 创建目录或卷。

先决条件

  • 预装 Kubernetes 集群
  • 具有 Kubernetes 集群管理员权限的普通用户
  • 互联网连接

事不宜迟,让我们深入探讨步骤:

步骤 1、准备 NFS 服务器

就我而言,我将在 Kubernetes 主节点(Ubuntu 22.04)上安装 NFS 服务器。登录主节点并运行以下命令:

$ sudo apt update
$ sudo apt install nfs-kernel-server -y

创建以下文件夹并使用 NFS 共享它:

$ sudo mkdir /opt/dynamic-storage
$ sudo chown -R nobody:nogroup /opt/dynamic-storage
$ sudo chmod 777 /opt/dynamic-storage

/etc/exports 文件中添加以下条目:

$ sudo vi /etc/exports
/opt/dynamic-storage 192.168.1.0/24(rw,sync,no_subtree_check)

保存并关闭文件。

注意:不要忘记更改导出文件中适合你的部署的网络。

要使上述更改生效,请运行:

$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server
$ sudo systemctl status nfs-kernel-server

NFS-Service-Status-Kubernetes-Master-Ubuntu

在工作节点上,使用以下 apt 命令安装 nfs-common 包。

$ sudo apt install nfs-common -y

步骤 2、安装和配置 NFS 客户端配置程序

NFS 子目录外部配置程序在 Kubernetes 集群中部署 NFS 客户端配置程序。配置程序负责动态创建和管理由 NFS 存储支持的持久卷(PV)和持久卷声明(PVC)。

因此,要安装 NFS 子目录外部配置程序,首先使用以下命令集安装 helm

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh

运行以下命令来启用 helm 仓库:

$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner

使用以下 helm 命令部署配置程序:

$ helm install -n nfs-provisioning --create-namespace nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --set nfs.server=192.168.1.139 --set nfs.path=/opt/dynamic-storage

helm-install-nfs-provisioning-kubernetes-cluster

上面的 helm 命令将自动创建 nfs-provisioning 命名空间,并安装 NFS 配置程序的容器荚/部署、名称为 nfs-client 的存储类,并将创建所需的 rbac。

$ kubectl get all -n nfs-provisioning
$ kubectl get sc -n nfs-provisioning

kubectl-get-all-nfs-provisioning-kubernetes-cluster

完美,上面的输出确认了配置程序容器荚和存储类已成功创建。

步骤 3、创建持久卷声明(PVC)

让我们创建 PVC 来为你的容器荚或部署请求存储。PVC 将从存储类 nfs-client 请求特定数量的存储:

$ vi demo-pvc.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: demo-claim
  namespace: nfs-provisioning
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Mi

保存并关闭文件。

PVC-Yaml-Dynamic-NFS-Kubernetes

运行以下 kubectl 命令以使用上面创建的 YML 文件创建 PVC:

$ kubectl create -f demo-pvc.yml

验证 PVC 和 PV 是否创建:

$ kubectl get pv,pvc -n nfs-provisioning

Verify-pv-pvc-dynamic-nfs-kubernetes-cluster

太好了,上面的输出表明 PV 和 PVC 创建成功。

步骤 4、测试并验证动态 NFS 配置

为了测试和验证动态 NFS 配置,请使用以下 YML 文件启动测试容器荚:

$ vi test-pod.yml
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
  namespace: nfs-provisioning
spec:
  containers:
  - name: test-pod
    image: busybox:latest
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/SUCCESS && sleep 600"
    volumeMounts:
      - name: nfs-pvc
        mountPath: "/mnt"
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: demo-claim

Pod-Yml-Dynamic-NFS-kubernetes

使用以下 kubectl 命令部署容器荚:

$ kubectl create -f test-pod.yml

验证 test-pod 的状态:

$ kubectl get pods -n nfs-provisioning

Verify-Test-Pod-Using-NFS-Volume-Kubernetes

登录到容器荚并验证 NFS 卷是否已安装。

$ kubectl exec -it test-pod -n nfs-provisioning /bin/sh

Access-Dynamic-NFS-Inside-Pod-Kubernetes

太棒了,上面容器荚的输出确认了动态 NFS 卷已安装且可访问。

最后删除容器荚和 PVC,查看 PV 是否自动删除。

$ kubectl delete -f test-pod.yml
$ kubectl delete -f demo-pvc.yml
$ kubectl get pv,pvc -n  nfs-provisioning

Delete-Pod-PVC-Dynamic-NFS

这就是这篇文章的全部内容,希望对你有所帮助。请随时在下面的评论部分发表你的疑问和反馈。

(题图:MJ/75dae36f-ff68-4c63-81e8-281e2c239356)


via: https://www.linuxtechi.com/dynamic-nfs-provisioning-kubernetes/

作者:Pradeep Kumar 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

当我第一次知道 DNS 时,我想它应该不会很复杂。不就是一些存储在服务器上的 DNS 记录罢了。有什么大不了的?

但是教科书上只是介绍了 DNS 的原理,并没有告诉你实际使用中 DNS 可能会以多少种方式破坏你的系统。这可不仅仅是缓存问题!

所以我 在 Twitter 上发起了一个提问,征集人们遇到的 DNS 问题,尤其是那些一开始看起来与 DNS 没什么关系的问题。(“总是 DNS 问题”这个梗)

我不打算在这篇文章中讨论如何解决或避免这些问题,但我会放一些讨论这些问题的链接,在那里可以找到解决问题的方法。

问题:网络请求缓慢

如果你的网络比预期的要慢,这是因为某些原因导致 DNS 解析器变慢了。这可能是解析器负载过大或者存在内存泄漏等原因导致的。

我的路由器的 DNS 转发器曾遇到过这个问题,导致我的所有 DNS 请求很慢。我通过重启路由器解决了这个问题。

问题:DNS 超时

一些网友提到由于 DNS 查询超时,他们的网络请求需要耗时 2 秒多甚至 30 秒。这跟“网络请求缓慢”问题类似,但情况要更糟糕,因为 DNS 请求就会消耗掉几秒钟时间。

Sophie Haskins 有一篇关于 Kubernete DNS 超时的博客文章 一次 Kube DNS 踩坑经历

问题:ndots 设置

一些网友提到在 /etc/resolv.conf 中设置 ndots:5 时会出现问题。

下面是从 这篇《Kubernetes 容器荚中 /etc/resolv.conf 里设置 ndots:5 为什么会拖慢你的程序性能》中引用的 /etc/resolv.conf文件。

    nameserver 100.64.0.10
    search namespace.svc.cluster.local svc.cluster.local cluster.local eu-west-1.compute.internal
    options ndots:5

如果你用上面的配置文件,想要查询得域名是 google.com,那么你的程序会调用 getaddrinfo 函数,而它会依次查询以下域名:

  1. google.com.namespace.svc.cluster.local.
  2. google.com.svc.cluster.local.
  3. google.com.cluster.local.
  4. google.com.eu-west-1.compute.internal.
  5. google.com.

简单来说,它会检查 google.com 是不是 search 这一行中的某个子域名。

所以每发起一次 DNS 查询,你都得先等待前 4 次查询失败后才能获取到最终查询结果。

问题:难以判断系统使用的 DNS 解析器

这本身并不是一个问题,但当你遇到 DNS 问题时,一般都会跟 DNS 解析器有关。我没有一种判断 DNS 解析器的万能方法。

下面是我知道的方法:

  • 在 Linux 系统上,最常见的是通过 /etc/resolv.conf 来选择 DNS 解析器。但是也有例外,比如浏览器可能会忽略 /etc/resolv.conf,而是使用 基于 HTTPS 的 DNS DNS-over-HTTPS 服务。
  • 如果你使用的是 UDP DNS,你可以通过 sudo tcpdump port 53 来查看 DNS 请求被发送到了哪里。但如果你使用的是基于 HTTPS 的 DNS 或 基于 TLS 的 DNS DNS over TLS ,这个方法就不行了。

我依稀记得这在 MacOS 系统上会更加令人迷惑,我也不清楚原因。

问题:DNS 服务器返回 NXDOMAIN 而不是 NOERROR

这是我曾经遇到过的一个 Nginx 不能解析域名的问题。

  • 我设置 Nginx 使用一个特定的 DNS 服务器来解析 DNS 查询
  • 当访问这个域名时,Nginx 做了两次查询,第一次是对 A 的,第二次是对 AAAA
  • 对于 A 的查询,DNS 服务器返回 NXDOMAIN
  • Nginx 认为这个域名不存在,然后放弃查询
  • 对于 AAAA 的查询 DNS 服务器返回了成功
  • 但 Nginx 忽略了对 AAAA 返回的查询结果,因为它前面已经放弃查询了

问题出在 DNS 服务器本应该返回 NOERROR 的——那个域名确实存在,只是没有关于 A 的记录罢了。我报告了这个问题,然后他们修复了这个问题。

我自己也写出过这个问题,所以我理解为什么会发生这种情况——很容易想当然地认为“没有要查询的记录,就应该返回 NXDOMAIN 错误码”。

问题:自动生效的 DNS 缓存

如果你在生成一个域名的 DNS 记录之前就访问这个域名,那么这个记录的缺失会被缓存起来。当你第一次遇到这个问题时一定会非常吃惊——我也是去年才知道有这个问题。

缓存的 TTL 就是域名的 起始权限记录 Start of Authority (SOA) 记录的 TTL ——比如对于 jvns.ca ,这个值是一个小时。

问题:Nginx 永久缓存 DNS 记录

如果你在 Nginx 中使用下面的配置:

    location / {
        proxy_pass https://some.domain.com;
    }

Nginx 只会在启动的时候解析一次 some.domain.com,以后不会再对其进行解析。这是非常危险的操作,尤其是对于那些 IP 地址经常变动的域名。它可能平安无事地运行几个月,然后突然在某个凌晨两点把你从床上纠起来。

针对这个问题已经有很多众所周知的方法了,但由于本文不是关于 Nginx 的,所以我不打算深入探讨它。但你第一次遇到它时一定会很惊讶。

这是一篇关于这个问题发生在 AWS 负载均衡器上的 博客文章

问题:Java 永久缓存 DNS 记录

跟上面类似的问题,只是出现在 Java 上:据说 这与你 Java 的配置有关。“JVM 的默认 TTL 设置可能会导致只有 JVM 重启时才会刷新 DNS 记录。”

我还没有遇到过这个问题,不过我那些经常写 Java 的朋友遇到过这个问题。

当然,任何软件都可能存在永久缓存 DNS 的问题,但据我所知它经常出现在 Nginx 和 Java 上。

问题:被遗忘的 /etc/hosts 记录

这是另一种缓存问题:/etc/hosts 中的记录会覆盖你的常规 DNS 设置!

让人迷惑的是 dig 命令会忽略 /etc/hosts 文件。所以当你使用 dig whatever.com 来查询 DNS 信息时,它会告诉你一切正常。

问题:电子邮件未发送 / 将成为垃圾邮件

电子邮件是通过 DNS(MX 记录, SPF 记录, DKIM 记录)来发送和验证的,所以有些电子邮件问题其实是 DNS 问题。

问题:对国际化域名无效

你可以使用非 ASCII 字符甚至是表情符来注册域名,比如 拉屎网 https://?.la

DNS 能够处理国际化域名是因为 ?.la 会被用 punycode 编码将转换为 xn--ls8h.la

尽管已经有了 DNS 处理国际化域名的标准,很多软件并不能很好地处理国际化域名。Julian Squires 的 干掉 Chrome 浏览器的表情符!! 就是一个非常有趣的例子。

问题:TCP DNS 被防火墙拦截

有人提到一些防火墙会允许在 53 端口上使用 UDP 协议,但是禁止 TCP 协议。然而很多 DNS 查询需要在 53 端口上使用 TCP,这可能会导致很难排查的间歇性的问题。

问题:musl 不支持 TCP DNS

很多应用程序使用 libcgetaddrinfo 来做 DNS 查询。musl 是用在 Alpine Docker 容器上的 glibc 替代品。而它不支持 TCP DNS。如果你的 DNS 查询的响应数据超过 DNS UDP 数据包的大小(512 字节)就会出现问题。

我对此仍然不太清楚,我下面我的理解也可能是错的:

  1. muslgetaddrinfo 发起一个 DNS 请求
  2. DNS 服务器发现请求的响应数据太大了,没法放入一个 DNS 数据包中
  3. DNS 服务器返回一个 空截断响应 empty truncated response ,并期望客户端通过 TCP DNS 重新用发起查询
  4. musl 不支持 TCP DNS,所以根本不会重试

关于这个问题的文章:在 Alpine Linux 上的 DNS 解析问题

问题:getaddrinfo 不支持轮询 DNS

轮询 round robin DNS 是一种 负载均衡 load balancing 技术,每次 DNS 查询都会获得一个不同的 IP 地址。显然如果你使用 gethostbyname 做 DNS 查询不会有任何问题,但是用 getaddrinfo 就不行了。因为 getaddrinfo 会对获得的 IP 地址进行排序。

在你从 gethostbyname 切换到 getaddrinfo 时可能完全不会意识到这可能会引起负载均衡问题。

这个问题可能会非常隐蔽,如果你不是用 C 语言编程的话,这些函数调用被隐藏在各种调用库背后,你可能完全意识不到发生了这种改变。所以某次看似人畜无害的升级就可能导致你的 DNS 负载均衡失效。

下面是讨论这个的一些文章:

问题:启动服务时的竞争条件

有人 提到 使用 Kubernete DNS 时遇到的问题:他们有两个同时启动的容器,一旦启动就会立即尝试解析对方的地址。由于 Kubernete DNS 还没有改变,所以 DNS 查询会失败。这个失败会被缓存起来,所以后续的查询会一直失败。

写在最后

我所列举的不过是 DNS 问题的冰山一角,期待大家告诉我那些我没有提到的问题和相关链接。我希望了解这些问题在实际中是如何发生的以及如何被解决的。

(题图:MJ/f512f18e-2e1d-4614-bed1-b0a0c373e14d)


via: https://jvns.ca/blog/2022/01/15/some-ways-dns-can-break/

作者:Julia Evans 选题:lujun9972 译者:toknow-gh 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

以下是如何将用户添加到 Debian Linux 中的 SUDOERS 组的方法。

在 Debian Linux 中,SUDOERS 组在向用户授予管理权限方面发挥着至关重要的作用。将用户添加到 SUDOERS 组使他们能够以 root 权限执行命令,从而为他们提供必要的管理访问权限以在 Debian 系统上执行各种任务。

在安装 Debian Linux 的过程中,如果你将 root 帐户的密码保留为空,那么系统中的 创建的第一个用户 将拥有管理权限。但是,如果你设置了 root 密码,那么用户名将不具有 sudo 权限。因此,在使用用户帐户执行管理任务时,你可能会遇到以下类似的错误。

<username> is not in the sudoers file. This incident will be reported.

将用户添加到 SUDOERS 组之前

本文旨在提供有关在 Debian 中向 SUDOERS 组添加用户的分步指南,确保你可以有效地管理用户权限和系统安全。

如何将用户添加到 Debian 中的 SUDOERS 组

要将用户添加到 Debian 中的 SUDOERS 组,请按照以下简单步骤操作:

  • 单击“终端”图标或使用快捷键 Ctrl+Alt+T,打开 Debian 系统上的终端。
  • 使用以下命令切换到 root 用户:
su -

系统将提示你提供 root 密码。输入 root 密码并按回车键。

以 root 用户身份登录后,输入以下命令。确保根据你的用户名进行更改。在此示例中,将 arindam 替换为你的用户名。

/sbin/addgroup arindam sudo

如果上面的命令无效,还可以使用下面的命令:

usermod -aG sudo arindam

按退出离开 root 提示符。注销并重新登录。现在你可以使用你的用户名执行任何管理操作。

另一种方法

你可以使用与下面相同的命令进入 root 帐户。使用 root 账号登录:

su -

然后使用 nanovisudo 或任何编辑器打开 /etc/sudoers 文件。

nano /etc/sudoers

添加以下行和用户名。根据你的用户名替换 arindam

arindam    ALL=(ALL)    ALL

保存并关闭文件。然后,注销并重新登录。这应该会给用户名 root 权限。

验证 SUDOERS 组成员

要验证用户是否已成功添加到 SUDOERS 组,你可以打开一个新的终端窗口并输入以下命令。将 arindam 替换为你添加到 SUDOERS 组的用户的实际用户名。

sudo -l -U arindam

如果用户是 SUDOERS 组的成员,你将看到他们拥有的权限列表。这是一个示例,你可以看到我的用户名具有所有访问权限。

授予权限后

结束语

将用户添加到 SUDOERS 组将授予他们重要的管理权限。在授予用户此类访问权限之前,仔细考虑用户的可信度和责任非常重要。sudo 使用不当可能会导致系统意外损坏或受损。

请记住在委派管理权限时要小心谨慎,并定期检查用户权限以维护安全的 Debian 系统。

(题图:MJ/c71c2f28-51c7-44c7-87be-af88088bf459)


via: https://www.debugpoint.com/add-users-sudoers/

作者:Arindam 选题:lkxed 译者:geekpi 校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出

在本文中,我们将逐步向你展示如何在 Kubernetes(k8s)集群上安装 Ansible AWX。

Ansible AWX 是一个强大的开源工具,用于管理和自动化 IT 基础设施。AWX 为 Ansible 提供图形用户界面,使你可以轻松创建、安排和运行 Ansible 剧本 Playbook

另一方面,Kubernetes 是一种流行的容器编排平台,广泛用于部署和管理容器化应用。

先决条件:

  • Kubernetes 集群
  • Kubectl
  • 具有 sudo 权限和集群管理员权限的普通用户
  • 互联网连接

步骤 1:安装 Helm

如果你的系统上安装了 Helm,则在命令下运行以进行安装,

$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
$ chmod +x get_helm.sh
$ ./get_helm.sh
$ helm version

Install-helm-linux-command-line

步骤 2:安装 AWX chart

在 Kubernetes 上安装 AWX 的最简单方法是使用 AWX Helm “ 海图 chart ”。因此,要通过 “海图” 安装 AWX,首先使用以下 helm 命令添加仓库。(LCTT 译注:Kubernetes 生态中大量使用了和航海有关的比喻,因此本文在翻译时也采用了这些比喻)

$ helm repo add awx-operator https://ansible.github.io/awx-operator/
"awx-operator" has been added to your repositories
$

注意:如果你之前已经添加过此仓库,请在命令下运行以获取最新版本的软件包。

$ helm repo update

要通过 Helm 安装 awx-operator,请运行:

$ helm install ansible-awx-operator awx-operator/awx-operator -n awx --create-namespace

helm-install-awx-operator-kubernetes

这将下载 AWX 海图并将其安装在 awx 命名空间中的 Kubernetes 集群上。安装过程可能需要几分钟,请耐心等待。

步骤 3:验证 AWX 操作员安装

安装成功后,你可以通过运行以下命令来验证 AWX 操作员 operator 状态:

$ sudo kubectl get pods -n awx

你应该看到这样的东西:

awx-operator-pod-status-kubectl

步骤 4: 创建 PV、PVC 并部署 AWX yaml 文件

AWX 需要 postgres 容器荚 pod 的持久卷。那么,让我们首先为本地卷创建一个存储类。

注意:在本文中,我使用本地文件系统作为持久卷。

$ vi local-storage-class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
  namespace: awxprovisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer

保存并关闭文件,然后运行:

$ kubectl create -f local-storage-class.yaml
$ kubectl get sc -n awx
NAME            PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   
local-storage   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                 
$

接下来使用以下 pv.yaml 文件创建持久卷(PV):

$ vi pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
  namespace: awx
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/storage
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-worker

保存并退出文件。

Postgres-pv-awx-kubernetes

重要说明:确保文件夹 /mnt/storage 存在于工作节点上,如果不存在,则在工作节点上使用 mkdir 命令创建它。在我们的例子中,工作节点是 k8s-worker

执行下面的命令在 awx 命名空间中创建 postgres-pv

$ kubectl create -f pv.yaml

成功创建 PV 后,使用 pvc.yaml 文件创建 PersistentVolumeClaim:

$ vi  pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-13-ansible-awx-postgres-13-0
  namespace: awx
spec:
  storageClassName: local-storage
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

posgres-pvc-awx-kubernetes

要创建 PVC,请运行以下 kubectl 命令:

$ kubectl create -f pvc.yaml

使用下面的命令验证 PV 和 PVC 的状态:

$ kubectl get pv,pvc -n awx

现在,我们都准备好部署 AWX 实例了。创建一个包含以下内容的 ansible-awx.yaml 文件:

$ vi ansible-awx.yaml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: ansible-awx
  namespace: awx
spec:
  service_type: nodeport
  postgres_storage_class: local-storage

Ansible-awx-yaml-file

保存并关闭文件。

执行以下 kubectl 命令来部署 awx 实例:

$ kubectl create -f ansible-awx.yaml

等待几分钟,然后检查 awx 命名空间中的容器荚状态。

$ kubectl get pods -n awx

Ansible-AWX-Pods-Status-Kubernetes

步骤 5:访问 AWX Web 界面

要访问 AWX Web 界面,你需要创建一个公开 awx-web 部署的服务:

$ kubectl expose deployment ansible-awx-web --name ansible-awx-web-svc --type NodePort -n awx

此命令将创建一个 NodePort 服务,该服务将 AWX Web 容器的端口映射到 Kubernetes 节点上的端口。你可以通过运行以下命令找到端口号:

$ kubectl get svc ansible-awx-web-svc  -n awx

这将输出如下内容:

NAME                 TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
ansible-awx-web-svc   NodePort   10.99.83.248   <none>        8052:32254/TCP   82s

在此示例中,Web 服务在端口 32254 上可用。

Expose-Ansible-AWX-Web-NodePort-Kubernetes

默认情况下,admin 用户是 Web 界面的 admin,密码在 <resourcename>-admin-password 机密信息中。要检索管理员密码,请运行:

$ kubectl get secrets -n awx | grep -i admin-password
ansible-awx-admin-password        Opaque               1      109m
$
$ kubectl get secret ansible-awx-admin-password -o jsonpath="{.data.password}" -n awx | base64 --decode ; echo
l9mWcIOXQhSKnzZQyQQ9LZf3awDV0YMJ
$

你现在可以打开 Web 浏览器并进入 http://<node-ip>:<node-port>/ 来访问 AWX Web 界面。在上面的示例中,URL 是:

http://192.168.1.223:3225

AWX-Login-URL-Kubernetes

输入凭据后单击登录。

Ansible-AWX-Web-Dashboard

恭喜! 你已在 Kubernetes 上成功安装 Ansible AWX。你现在可以使用 AWX 来自动化你的 IT 基础架构,并让你作为系统管理员的生活更轻松。

(题图:MJ/bfd354aa-2ee5-4555-98b8-ac5207cbeabe)


via: https://www.linuxtechi.com/install-ansible-awx-on-kubernetes-cluster/

作者:Pradeep Kumar 选题:lkxed 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出