2019年11月

让我们开始使用它。

awk 是用于 Unix 和类 Unix 系统的强大文本解析工具,但是由于它有可编程函数,因此你可以用它来执行常规解析任务,因此它也被视为一种编程语言。你可能不会使用 awk 开发下一个 GUI 应用,并且它可能不会代替你的默认脚本语言,但是它是用于特定任务的强大程序。

这些任务或许是惊人的多样化。了解 awk 可以解决你的哪些问题的最好方法是学习 awk。你会惊讶于 awk 如何帮助你完成更多工作,却花费更少的精力。

awk 的基本语法是:

awk [options] 'pattern {action}' file

首先,创建此示例文件并将其保存为 colours.txt

name       color  amount
apple      red    4
banana     yellow 6
strawberry red    3
grape      purple 10
apple      green  8
plum       purple 2
kiwi       brown  4
potato     brown  9
pineapple  yellow 5

数据被一个或多个空格分隔为列。以某种方式组织要分析的数据是很常见的。它不一定总是由空格分隔的列,甚至可以不是逗号或分号,但尤其是在日志文件或数据转储中,通常有一个可预测的格式。你可以使用数据格式来帮助 awk 提取和处理你关注的数据。

打印列

awk 中,print 函数显示你指定的内容。你可以使用许多预定义的变量,但是最常见的是文本文件中以整数命名的列。试试看:

$ awk '{print $2;}' colours.txt
color
red
yellow
red
purple
green
purple
brown
brown
yellow

在这里,awk 显示第二列,用 $2 表示。这是相对直观的,因此你可能会猜测 print $1 显示第一列,而 print $3 显示第三列,依此类推。

要显示全部列,请使用 $0

美元符号($)后的数字是表达式,因此 $2$(1+1) 是同一意思。

有条件地选择列

你使用的示例文件非常结构化。它有一行充当标题,并且各列直接相互关联。通过定义条件,你可以限定 awk 在找到此数据时返回的内容。例如,要查看第二列中与 yellow 匹配的项并打印第一列的内容:

awk '$2=="yellow"{print $1}' file1.txt
banana
pineapple

正则表达式也可以工作。此表达式近似匹配 $2 中以 p 开头跟上任意数量(一个或多个)字符后继续跟上 p 的值:

$ awk '$2 ~ /p.+p/ {print $0}' colours.txt
grape   purple  10
plum    purple  2

数字能被 awk 自然解释。例如,要打印第三列包含大于 5 的整数的行:

awk '$3>5 {print $1, $2}' colours.txt
name    color
banana  yellow
grape   purple
apple   green
potato  brown

字段分隔符

默认情况下,awk 使用空格作为字段分隔符。但是,并非所有文本文件都使用空格来定义字段。例如,用以下内容创建一个名为 colours.csv 的文件:

name,color,amount
apple,red,4
banana,yellow,6
strawberry,red,3
grape,purple,10
apple,green,8
plum,purple,2
kiwi,brown,4
potato,brown,9
pineapple,yellow,5

只要你指定将哪个字符用作命令中的字段分隔符,awk 就能以完全相同的方式处理数据。使用 --field-separator(或简称为 -F)选项来定义分隔符:

$ awk -F"," '$2=="yellow" {print $1}' file1.csv
banana
pineapple

保存输出

使用输出重定向,你可以将结果写入文件。例如:

$ awk -F, '$3>5 {print $1, $2} colours.csv > output.txt

这将创建一个包含 awk 查询内容的文件。

你还可以将文件拆分为按列数据分组的多个文件。例如,如果要根据每行显示的颜色将 colours.txt 拆分为多个文件,你可以在 awk 中包含重定向语句来重定向每条查询

$ awk '{print > $2".txt"}' colours.txt

这将生成名为 yellow.txtred.txt 等文件。

在下一篇文章中,你将了解有关字段,记录和一些强大的 awk 变量的更多信息。

本文改编自社区技术播客 Hacker Public Radio


via: https://opensource.com/article/19/10/intro-awk

作者:Seth Kenlon 选题:lujun9972 译者:geekpi 校对:wxy

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

很多次,你可能遇见过系统消耗了过多的内存。如果是这种情况,那么最好的办法是识别出 Linux 机器上消耗过多内存的进程。我相信,你可能已经运行了下文中的命令以进行检查。如果没有,那你尝试过哪些其他的命令?我希望你可以在评论中更新这篇文章,它可能会帮助其他用户。

使用 top 命令ps 命令 可以轻松的识别这种情况。我过去经常同时使用这两个命令,两个命令得到的结果是相同的。所以我建议你从中选择一个喜欢的使用就可以。

1) 如何使用 ps 命令在 Linux 中查找内存消耗最大的进程

ps 命令用于报告当前进程的快照。ps 命令的意思是“进程状态”。这是一个标准的 Linux 应用程序,用于查找有关在 Linux 系统上运行进程的信息。

它用于列出当前正在运行的进程及其进程 ID(PID)、进程所有者名称、进程优先级(PR)以及正在运行的命令的绝对路径等。

下面的 ps 命令格式为你提供有关内存消耗最大进程的更多信息。

# ps aux --sort -rss | head

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mysql     1064  3.2  5.4 886076 209988 ?       Ssl  Oct25  62:40 /usr/sbin/mysqld
varnish  23396  0.0  2.9 286492 115616 ?       SLl  Oct25   0:42 /usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :82 -T 127.0.0.1:6082 -S /etc/varnish/secret -s malloc,256M
named     1105  0.0  2.7 311712 108204 ?       Ssl  Oct25   0:16 /usr/sbin/named -u named -c /etc/named.conf
nobody   23377  0.2  2.3 153096 89432 ?        S    Oct25   4:35 nginx: worker process
nobody   23376  0.1  2.1 147096 83316 ?        S    Oct25   2:18 nginx: worker process
root     23375  0.0  1.7 131028 66764 ?        Ss   Oct25   0:01 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nobody   23378  0.0  1.6 130988 64592 ?        S    Oct25   0:00 nginx: cache manager process
root      1135  0.0  0.9  86708 37572 ?        S    05:37   0:20 cwpsrv: worker process
root      1133  0.0  0.9  86708 37544 ?        S    05:37   0:05 cwpsrv: worker process

使用以下 ps 命令格式可在输出中仅展示有关内存消耗过程的特定信息。

# ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%mem | head

  PID  PPID %MEM %CPU CMD
 1064     1  5.4  3.2 /usr/sbin/mysqld
23396 23386  2.9  0.0 /usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :82 -T 127.0.0.1:6082 -S /etc/varnish/secret -s malloc,256M
 1105     1  2.7  0.0 /usr/sbin/named -u named -c /etc/named.conf
23377 23375  2.3  0.2 nginx: worker process
23376 23375  2.1  0.1 nginx: worker process
 3625   977  1.9  0.0 /usr/local/bin/php-cgi /home/daygeekc/public_html/index.php
23375     1  1.7  0.0 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
23378 23375  1.6  0.0 nginx: cache manager process
 1135  3034  0.9  0.0 cwpsrv: worker process

如果你只想查看命令名称而不是命令的绝对路径,请使用下面的 ps 命令格式。

# ps -eo pid,ppid,%mem,%cpu,comm --sort=-%mem | head

  PID  PPID %MEM %CPU COMMAND
 1064     1  5.4  3.2 mysqld
23396 23386  2.9  0.0 cache-main
 1105     1  2.7  0.0 named
23377 23375  2.3  0.2 nginx
23376 23375  2.1  0.1 nginx
23375     1  1.7  0.0 nginx
23378 23375  1.6  0.0 nginx
 1135  3034  0.9  0.0 cwpsrv
 1133  3034  0.9  0.0 cwpsrv

2) 如何使用 top 命令在 Linux 中查找内存消耗最大的进程

Linux 的 top 命令是用来监视 Linux 系统性能的最好和最知名的命令。它在交互界面上显示运行的系统进程的实时视图。但是,如果要查找内存消耗最大的进程,请 在批处理模式下使用 top 命令

你应该正确地 了解 top 命令输出 以解决系统中的性能问题。

# top -c -b -o +%MEM | head -n 20 | tail -15

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1064 mysql     20   0  886076 209740   8388 S   0.0  5.4  62:41.20 /usr/sbin/mysqld
23396 varnish   20   0  286492 115616  83572 S   0.0  3.0   0:42.24 /usr/sbin/varnishd -P /var/run/varnish.pid -f /etc/varnish/default.vcl -a :82 -T 127.0.0.1:6082 -S /etc/varnish/secret -s malloc,256M
 1105 named     20   0  311712 108204   2424 S   0.0  2.8   0:16.41 /usr/sbin/named -u named -c /etc/named.conf
23377 nobody    20   0  153240  89432   2432 S   0.0  2.3   4:35.74 nginx: worker process
23376 nobody    20   0  147096  83316   2416 S   0.0  2.1   2:18.09 nginx: worker process
23375 root      20   0  131028  66764   1616 S   0.0  1.7   0:01.07 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
23378 nobody    20   0  130988  64592    592 S   0.0  1.7   0:00.51 nginx: cache manager process
 1135 root      20   0   86708  37572   2252 S   0.0  1.0   0:20.18 cwpsrv: worker process
 1133 root      20   0   86708  37544   2212 S   0.0  1.0   0:05.94 cwpsrv: worker process
 3034 root      20   0   86704  36740   1452 S   0.0  0.9   0:00.09 cwpsrv: master process /usr/local/cwpsrv/bin/cwpsrv
 1067 nobody    20   0 1356200  31588   2352 S   0.0  0.8   0:56.06 /usr/local/apache/bin/httpd -k start
  977 nobody    20   0 1356088  31268   2372 S   0.0  0.8   0:30.44 /usr/local/apache/bin/httpd -k start
  968 nobody    20   0 1356216  30544   2348 S   0.0  0.8   0:19.95 /usr/local/apache/bin/httpd -k start

如果你只想查看命令名称而不是命令的绝对路径,请使用下面的 top 命令格式。

# top -b -o +%MEM | head -n 20 | tail -15

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1064 mysql     20   0  886076 210340   8388 S   6.7  5.4  62:40.93 mysqld
23396 varnish   20   0  286492 115616  83572 S   0.0  3.0   0:42.24 cache-main
 1105 named     20   0  311712 108204   2424 S   0.0  2.8   0:16.41 named
23377 nobody    20   0  153240  89432   2432 S  13.3  2.3   4:35.74 nginx
23376 nobody    20   0  147096  83316   2416 S   0.0  2.1   2:18.09 nginx
23375 root      20   0  131028  66764   1616 S   0.0  1.7   0:01.07 nginx
23378 nobody    20   0  130988  64592    592 S   0.0  1.7   0:00.51 nginx
 1135 root      20   0   86708  37572   2252 S   0.0  1.0   0:20.18 cwpsrv
 1133 root      20   0   86708  37544   2212 S   0.0  1.0   0:05.94 cwpsrv
 3034 root      20   0   86704  36740   1452 S   0.0  0.9   0:00.09 cwpsrv
 1067 nobody    20   0 1356200  31588   2352 S   0.0  0.8   0:56.04 httpd
  977 nobody    20   0 1356088  31268   2372 S   0.0  0.8   0:30.44 httpd
  968 nobody    20   0 1356216  30544   2348 S   0.0  0.8   0:19.95 httpd

3) 奖励技巧:如何使用 ps\_mem 命令在 Linux 中查找内存消耗最大的进程

ps\_mem 程序 用于显示每个程序(而不是每个进程)使用的核心内存。该程序允许你检查每个程序使用了多少内存。它根据程序计算私有和共享内存的数量,并以最合适的方式返回已使用的总内存。

它使用以下逻辑来计算内存使用量。总内存使用量 = sum(用于程序进程的专用内存使用量) + sum(用于程序进程的共享内存使用量)。

# ps_mem

 Private  +   Shared  =  RAM used    Program
128.0 KiB +  27.5 KiB = 155.5 KiB    agetty
228.0 KiB +  47.0 KiB = 275.0 KiB    atd
284.0 KiB +  53.0 KiB = 337.0 KiB    irqbalance
380.0 KiB +  81.5 KiB = 461.5 KiB    dovecot
364.0 KiB + 121.5 KiB = 485.5 KiB    log
520.0 KiB +  65.5 KiB = 585.5 KiB    auditd
556.0 KiB +  60.5 KiB = 616.5 KiB    systemd-udevd
732.0 KiB +  48.0 KiB = 780.0 KiB    crond
296.0 KiB + 524.0 KiB = 820.0 KiB    avahi-daemon (2)
772.0 KiB +  51.5 KiB = 823.5 KiB    systemd-logind
940.0 KiB + 162.5 KiB =   1.1 MiB    dbus-daemon
  1.1 MiB +  99.0 KiB =   1.2 MiB    pure-ftpd
  1.2 MiB + 100.5 KiB =   1.3 MiB    master
  1.3 MiB + 198.5 KiB =   1.5 MiB    pickup
  1.3 MiB + 198.5 KiB =   1.5 MiB    bounce
  1.3 MiB + 198.5 KiB =   1.5 MiB    pipe
  1.3 MiB + 207.5 KiB =   1.5 MiB    qmgr
  1.4 MiB + 198.5 KiB =   1.6 MiB    cleanup
  1.3 MiB + 299.5 KiB =   1.6 MiB    trivial-rewrite
  1.5 MiB + 145.0 KiB =   1.6 MiB    config
  1.4 MiB + 291.5 KiB =   1.6 MiB    tlsmgr
  1.4 MiB + 308.5 KiB =   1.7 MiB    local
  1.4 MiB + 323.0 KiB =   1.8 MiB    anvil (2)
  1.3 MiB + 559.0 KiB =   1.9 MiB    systemd-journald
  1.8 MiB + 240.5 KiB =   2.1 MiB    proxymap
  1.9 MiB + 322.5 KiB =   2.2 MiB    auth
  2.4 MiB +  88.5 KiB =   2.5 MiB    systemd
  2.8 MiB + 458.5 KiB =   3.2 MiB    smtpd
  2.9 MiB + 892.0 KiB =   3.8 MiB    bash (2)
  3.3 MiB + 555.5 KiB =   3.8 MiB    NetworkManager
  4.1 MiB + 233.5 KiB =   4.3 MiB    varnishd
  4.0 MiB + 662.0 KiB =   4.7 MiB    dhclient (2)
  4.3 MiB + 623.5 KiB =   4.9 MiB    rsyslogd
  3.6 MiB +   1.8 MiB =   5.5 MiB    sshd (3)
  5.6 MiB + 431.0 KiB =   6.0 MiB    polkitd
 13.0 MiB + 546.5 KiB =  13.6 MiB    tuned
 22.5 MiB +  76.0 KiB =  22.6 MiB    lfd - sleeping
 30.0 MiB +   6.2 MiB =  36.2 MiB    php-fpm (6)
  5.7 MiB +  33.5 MiB =  39.2 MiB    cwpsrv (3)
 20.1 MiB +  25.3 MiB =  45.4 MiB    httpd (5)
104.7 MiB + 156.0 KiB = 104.9 MiB    named
112.2 MiB + 479.5 KiB = 112.7 MiB    cache-main
 69.4 MiB +  58.6 MiB = 128.0 MiB    nginx (4)
203.4 MiB + 309.5 KiB = 203.7 MiB    mysqld
---------------------------------
                        775.8 MiB
=================================

via: https://www.2daygeek.com/linux-find-top-memory-consuming-processes/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:lnrCoder 校对:wxy

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

Fedora 31 日前发布了。你也许想要升级系统来获得 Fedora 中的最新功能。Fedora 工作站有图形化的升级方式。另外,Fedora 提供了一种命令行方式来将 Fedora 30 升级到 Fedora 31。

将 Fedora 30 工作站升级到 Fedora 31

在该发布不久之后,就会有通知告诉你有可用升级。你可以点击通知打开 GNOME “软件”。或者在 GNOME Shell 选择“软件”。

在 GNOME 软件中选择更新,你应该会看到告诉你有 Fedora 31 更新的提示。

如果你在屏幕上看不到任何内容,请尝试使用左上方的重新加载按钮。在发布后,所有系统可能需要一段时间才能看到可用的升级。

选择下载以获取升级包。你可以继续工作,直到下载完成。然后使用 GNOME “软件”重启系统并应用升级。升级需要时间,因此你可能需要喝杯咖啡,稍后再返回系统。

使用命令行

如果你是从 Fedora 以前的版本升级的,那么你可能对 dnf upgrade 插件很熟悉。这是推荐且支持的从 Fedora 30 升级到 Fedora 31 的方法。使用此插件能让你轻松地升级到 Fedora 31。

1、更新软件并备份系统

在开始升级之前,请确保你安装了 Fedora 30 的最新软件。如果你安装了模块化软件,这点尤为重要。dnf 和 GNOME “软件”的最新版本对某些模块化流的升级过程进行了改进。要更新软件,请使用 GNOME “软件” 或在终端中输入以下命令:

sudo dnf upgrade --refresh

此外,在继续操作之前,请确保备份系统。有关备份的帮助,请参阅 Fedora Magazine 上的备份系列

2、安装 DNF 插件

接下来,打开终端并输入以下命令安装插件:

sudo dnf install dnf-plugin-system-upgrade

3、使用 DNF 开始更新

现在,你的系统是最新的,已经备份并且安装了 DNF 插件,你可以通过在终端中使用以下命令来开始升级:

sudo dnf system-upgrade download --releasever=31

该命令将开始在本地下载计算机的所有升级。如果由于缺乏更新包、损坏的依赖项或已淘汰的软件包而在升级时遇到问题,请在输入上面的命令时添加 ‐-allowerasing 标志。这将使 DNF 删除可能阻止系统升级的软件包。

4、重启并升级

上面的命令下载更新完成后,你的系统就可以重启了。要将系统引导至升级过程,请在终端中输入以下命令:

sudo dnf system-upgrade reboot

此后,你的系统将重启。在许多版本之前,fedup 工具会在内核选择/引导页面上创建一个新选项。使用 dnf-plugin-system-upgrade 软件包,你的系统将重新引导到当前 Fedora 30 使用的内核。这很正常。在内核选择页面之后不久,你的系统会开始升级过程。

现在也许可以喝杯咖啡休息下!升级完成后,系统将重启,你将能够登录到新升级的 Fedora 31 系统。

解决升级问题

有时,升级系统时可能会出现意外问题。如果遇到任何问题,请访问 DNF 系统升级文档,以获取有关故障排除的更多信息。

如果升级时遇到问题,并且系统上安装了第三方仓库,那么在升级时可能需要禁用这些仓库。对于 Fedora 不提供的仓库的支持,请联系仓库的提供者。


via: https://fedoramagazine.org/upgrading-fedora-30-to-fedora-31/

作者:Ben Cotton 选题:lujun9972 译者:geekpi 校对:wxy

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

Kubernetes 绝对是满足复杂 web 应用程序需求的最简单、最容易的方法。

 title=

在 90 年代末和 2000 年代初,在大型网站工作很有趣。我的经历让我想起了 American Greetings Interactive,在情人节那天,我们拥有了互联网上排名前 10 位之一的网站(以网络访问量衡量)。我们为 AmericanGreetings.comBlueMountain.com 等公司提供了电子贺卡,并为 MSN 和 AOL 等合作伙伴提供了电子贺卡。该组织的老员工仍然深切地记得与 Hallmark 等其它电子贺卡网站进行大战的史诗般的故事。顺便说一句,我还为 Holly Hobbie、Care Bears 和 Strawberry Shortcake 运营过大型网站。

我记得那就像是昨天发生的一样,这是我们第一次遇到真正的问题。通常,我们的前门(路由器、防火墙和负载均衡器)有大约 200Mbps 的流量进入。但是,突然之间,Multi Router Traffic Grapher(MRTG)图示突然在几分钟内飙升至 2Gbps。我疯了似地东奔西跑。我了解了我们的整个技术堆栈,从路由器、交换机、防火墙和负载平衡器,到 Linux/Apache web 服务器,到我们的 Python 堆栈(FastCGI 的元版本),以及网络文件系统(NFS)服务器。我知道所有配置文件在哪里,我可以访问所有管理界面,并且我是一位经验丰富的,打过硬仗的系统管理员,具有多年解决复杂问题的经验。

但是,我无法弄清楚发生了什么……

当你在一千个 Linux 服务器上疯狂地键入命令时,五分钟的感觉就像是永恒。我知道站点可能会在任何时候崩溃,因为当它被划分成更小的集群时,压垮上千个节点的集群是那么的容易。

我迅速跑到老板的办公桌前,解释了情况。他几乎没有从电子邮件中抬起头来,这使我感到沮丧。他抬头看了看,笑了笑,说道:“是的,市场营销可能会开展广告活动。有时会发生这种情况。”他告诉我在应用程序中设置一个特殊标志,以减轻 Akamai 的访问量。我跑回我的办公桌,在上千台 web 服务器上设置了标志,几分钟后,站点恢复正常。灾难也就被避免了。

我可以再分享 50 个类似的故事,但你脑海中可能会有一点好奇:“这种运维方式将走向何方?”

关键是,我们遇到了业务问题。当技术问题使你无法开展业务时,它们就变成了业务问题。换句话说,如果你的网站无法访问,你就不能处理客户交易。

那么,所有这些与 Kubernetes 有什么关系?一切!世界已经改变。早在 90 年代末和 00 年代初,只有大型网站才出现大型的、 规模级 web-scale 的问题。现在,有了微服务和数字化转型,每个企业都面临着一个大型的、规模级的问题——可能是多个大型的、规模级的问题。

你的企业需要能够通过许多不同的人构建的许多不同的、通常是复杂的服务来管理复杂的规模级的网站。你的网站需要动态地处理流量,并且它们必须是安全的。这些属性需要在所有层(从基础结构到应用程序层)上由 API 驱动。

进入 Kubernetes

Kubernetes 并不复杂;你的业务问题才复杂。当你想在生产环境中运行应用程序时,要满足性能(伸缩性、性能抖动等)和安全性要求,就需要最低程度的复杂性。诸如高可用性(HA)、容量要求(N+1、N+2、N+100)以及保证最终一致性的数据技术等就会成为必需。这些是每家进行数字化转型的公司的生产要求,而不仅仅是 Google、Facebook 和 Twitter 这样的大型网站。

在旧时代,我还在 American Greetings 任职时,每次我们加入一个新的服务,它看起来像这样:所有这些都是由网站运营团队来处理的,没有一个是通过订单系统转移给其他团队来处理的。这是在 DevOps 出现之前的 DevOps:

  1. 配置 DNS(通常是内部服务层和面向公众的外部)
  2. 配置负载均衡器(通常是内部服务和面向公众的)
  3. 配置对文件的共享访问(大型 NFS 服务器、群集文件系统等)
  4. 配置集群软件(数据库、服务层等)
  5. 配置 web 服务器群集(可以是 10 或 50 个服务器)

大多数配置是通过配置管理自动完成的,但是配置仍然很复杂,因为每个系统和服务都有不同的配置文件,而且格式完全不同。我们研究了像 Augeas 这样的工具来简化它,但是我们认为使用转换器来尝试和标准化一堆不同的配置文件是一种反模式。

如今,借助 Kubernetes,启动一项新服务本质上看起来如下:

  1. 配置 Kubernetes YAML/JSON。
  2. 提交给 Kubernetes API(kubectl create -f service.yaml)。

Kubernetes 大大简化了服务的启动和管理。服务所有者(无论是系统管理员、开发人员还是架构师)都可以创建 Kubernetes 格式的 YAML/JSON 文件。使用 Kubernetes,每个系统和每个用户都说相同的语言。所有用户都可以在同一 Git 存储库中提交这些文件,从而启用 GitOps。

而且,可以弃用和删除服务。从历史上看,删除 DNS 条目、负载平衡器条目和 Web 服务器的配置等是非常可怕的,因为你几乎肯定会破坏某些东西。使用 Kubernetes,所有内容都处于命名空间下,因此可以通过单个命令删除整个服务。尽管你仍然需要确保其它应用程序不使用它(微服务和函数即服务 [FaaS] 的缺点),但你可以更加确信:删除服务不会破坏基础架构环境。

构建、管理和使用 Kubernetes

太多的人专注于构建和管理 Kubernetes 而不是使用它(详见 Kubernetes 是一辆翻斗车)。

在单个节点上构建一个简单的 Kubernetes 环境并不比安装 LAMP 堆栈复杂得多,但是我们无休止地争论着构建与购买的问题。不是 Kubernetes 很难;它以高可用性大规模运行应用程序。建立一个复杂的、高可用性的 Kubernetes 集群很困难,因为要建立如此规模的任何集群都是很困难的。它需要规划和大量软件。建造一辆简单的翻斗车并不复杂,但是建造一辆可以运载 10 吨垃圾并能以 200 迈的速度稳定行驶的卡车则很复杂。

管理 Kubernetes 可能很复杂,因为管理大型的、规模级的集群可能很复杂。有时,管理此基础架构很有意义;而有时不是。由于 Kubernetes 是一个社区驱动的开源项目,它使行业能够以多种不同方式对其进行管理。供应商可以出售托管版本,而用户可以根据需要自行决定对其进行管理。(但是你应该质疑是否确实需要。)

使用 Kubernetes 是迄今为止运行大规模网站的最简单方法。Kubernetes 正在普及运行一组大型、复杂的 Web 服务的能力——就像当年 Linux 在 Web 1.0 中所做的那样。

由于时间和金钱是一个零和游戏,因此我建议将重点放在使用 Kubernetes 上。将你的时间和金钱花费在掌握 Kubernetes 原语或处理活跃度和就绪性探针的最佳方法上(表明大型、复杂的服务很难的另一个例子)。不要专注于构建和管理 Kubernetes。(在构建和管理上)许多供应商可以为你提供帮助。

结论

我记得对无数的问题进行了故障排除,比如我在这篇文章的开头所描述的问题——当时 Linux 内核中的 NFS、我们自产的 CFEngine、仅在某些 Web 服务器上出现的重定向问题等)。开发人员无法帮助我解决所有这些问题。实际上,除非开发人员具备高级系统管理员的技能,否则他们甚至不可能进入系统并作为第二双眼睛提供帮助。没有带有图形或“可观察性”的控制台——可观察性在我和其他系统管理员的大脑中。如今,有了 Kubernetes、Prometheus、Grafana 等,一切都改变了。

关键是:

  1. 时代不一样了。现在,所有 Web 应用程序都是大型的分布式系统。就像 AmericanGreetings.com 过去一样复杂,现在每个网站都有扩展性和 HA 的要求。
  2. 运行大型的分布式系统是很困难的。绝对是。这是业务的需求,不是 Kubernetes 的问题。使用更简单的编排系统并不是解决方案。

Kubernetes 绝对是满足复杂 Web 应用程序需求的最简单,最容易的方法。这是我们生活的时代,而 Kubernetes 擅长于此。你可以讨论是否应该自己构建或管理 Kubernetes。有很多供应商可以帮助你构建和管理它,但是很难否认这是大规模运行复杂 Web 应用程序的最简单方法。


via: https://opensource.com/article/19/10/kubernetes-complex-business-problem

作者:Scott McCarty 选题:lujun9972 译者:laingke 校对:wxy

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

关于 RPM 软件包构建的上一篇文章中,你了解到了源 RPM 包括软件的源代码以及 spec 文件。这篇文章深入研究了 spec 文件,该文件中包含了有关如何构建 RPM 的指令。同样,本文以 fpaste 为例。

了解源代码

在开始编写 spec 文件之前,你需要对要打包的软件有所了解。在这里,你正在研究 fpaste,这是一个非常简单的软件。它是用 Python 编写的,并且是一个单文件脚本。当它发布新版本时,可在 Pagure 上找到:https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz

如该档案文件所示,当前版本为 0.3.9.2。下载它,以便你查看该档案文件中的内容:

$ wget https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz
$ tar -tvf fpaste-0.3.9.2.tar.gz
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/
-rw-rw-r-- root/root        25 2018-07-25 02:58 fpaste-0.3.9.2/.gitignore
-rw-rw-r-- root/root      3672 2018-07-25 02:58 fpaste-0.3.9.2/CHANGELOG
-rw-rw-r-- root/root     35147 2018-07-25 02:58 fpaste-0.3.9.2/COPYING
-rw-rw-r-- root/root       444 2018-07-25 02:58 fpaste-0.3.9.2/Makefile
-rw-rw-r-- root/root      1656 2018-07-25 02:58 fpaste-0.3.9.2/README.rst
-rw-rw-r-- root/root       658 2018-07-25 02:58 fpaste-0.3.9.2/TODO
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/en/
-rw-rw-r-- root/root      3867 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/en/fpaste.1
-rwxrwxr-x root/root     24884 2018-07-25 02:58 fpaste-0.3.9.2/fpaste
lrwxrwxrwx root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/fpaste.py -> fpaste

你要安装的文件是:

  • fpaste.py:应该安装到 /usr/bin/
  • docs/man/en/fpaste.1:手册,应放到 /usr/share/man/man1/
  • COPYING:许可证文本,应放到 /usr/share/license/fpaste/
  • README.rstTODO:放到 /usr/share/doc/fpaste/ 下的其它文档。

这些文件的安装位置取决于文件系统层次结构标准(FHS)。要了解更多信息,可以在这里阅读:http://www.pathname.com/fhs/ 或查看 Fedora 系统的手册页:

$ man hier

第一部分:要构建什么?

现在我们知道了源文件中有哪些文件,以及它们要存放的位置,让我们看一下 spec 文件。你可以在此处查看这个完整的文件:https://src.fedoraproject.org/rpms/fpaste/blob/master/f/fpaste.spec

这是 spec 文件的第一部分:

Name:   fpaste
Version:  0.3.9.2
Release:  3%{?dist}
Summary:  A simple tool for pasting info onto sticky notes instances
BuildArch:  noarch
License:  GPLv3+
URL:    https://pagure.io/fpaste
Source0:  https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz

Requires:    python3

%description
It is often useful to be able to easily paste text to the Fedora
Pastebin at http://paste.fedoraproject.org and this simple script
will do that and return the resulting URL so that people may
examine the output. This can hopefully help folks who are for
some reason stuck without X, working remotely, or any other
reason they may be unable to paste something into the pastebin

NameVersion 等称为标签,它们定义在 RPM 中。这意味着你不能只是随意写点标签,RPM 无法理解它们!需要注意的标签是:

  • Source0:告诉 RPM 该软件的源代码档案文件所在的位置。
  • Requires:列出软件的运行时依赖项。RPM 可以自动检测很多依赖项,但是在某些情况下,必须手动指明它们。运行时依赖项是系统上必须具有的功能(通常是软件包),才能使该软件包起作用。这是 dnf 在安装此软件包时检测是否需要拉取其他软件包的方式。
  • BuildRequires:列出了此软件的构建时依赖项。这些通常必须手动确定并添加到 spec 文件中。
  • BuildArch:此软件为该计算机体系结构所构建。如果省略此标签,则将为所有受支持的体系结构构建该软件。值 noarch 表示该软件与体系结构无关(例如 fpaste,它完全是用 Python 编写的)。

本节提供有关 fpaste 的常规信息:它是什么,正在将什么版本制作为 RPM,其许可证等等。如果你已安装 fpaste,并查看其元数据时,则可以看到该 RPM 中包含的以下信息:

$ sudo dnf install fpaste
$ rpm -qi fpaste
Name        : fpaste
Version     : 0.3.9.2
Release     : 2.fc30
...

RPM 会自动添加一些其他标签,以代表它所知道的内容。

至此,我们掌握了要为其构建 RPM 的软件的一般信息。接下来,我们开始告诉 RPM 做什么。

第二部分:准备构建

spec 文件的下一部分是准备部分,用 %prep 代表:

%prep
%autosetup

对于 fpaste,这里唯一的命令是 %autosetup。这只是将 tar 档案文件提取到一个新文件夹中,并为下一部分的构建阶段做好了准备。你可以在此处执行更多操作,例如应用补丁程序,出于不同目的修改文件等等。如果你查看过 Python 的源 RPM 的内容,那么你会在那里看到许多补丁。这些都将在本节中应用。

通常,spec 文件中带有 前缀的所有内容都是 RPM 以特殊方式解释的宏或标签。这些通常会带有大括号,例如 %{example}

第三部分:构建软件

下一部分是构建软件的位置,用 %build 表示。现在,由于 fpaste 是一个简单的纯 Python 脚本,因此无需构建。因此,这里是:

%build
#nothing required

不过,通常来说,你会在此处使用构建命令,例如:

configure; make

构建部分通常是 spec 文件中最难的部分,因为这是从源代码构建软件的地方。这要求你知道该工具使用的是哪个构建系统,该系统可能是许多构建系统之一:Autotools、CMake、Meson、Setuptools(用于 Python)等等。每个都有自己的命令和语法样式。你需要充分了解这些才能正确构建软件。

第四部分:安装文件

软件构建后,需要在 %install 部分中安装它:

%install
mkdir -p %{buildroot}%{_bindir}
make install BINDIR=%{buildroot}%{_bindir} MANDIR=%{buildroot}%{_mandir}

在构建 RPM 时,RPM 不会修改你的系统文件。在一个可以正常运行的系统上添加、删除或修改文件的风险太大。如果发生故障怎么办?因此,RPM 会创建一个专门打造的文件系统并在其中工作。这称为 buildroot。 因此,在 buildroot 中,我们创建由宏 %{_bindir} 代表的 /usr/bin 目录,然后使用提供的 Makefile 将文件安装到其中。

至此,我们已经在专门打造的 buildroot 中安装了 fpaste 的构建版本。

第五部分:列出所有要包括在 RPM 中的文件

spec 文件其后的一部分是文件部分:%files。在这里,我们告诉 RPM 从该 spec 文件创建的档案文件中包含哪些文件。fpaste 的文件部分非常简单:

%files
%{_bindir}/%{name}
%doc README.rst TODO
%{_mandir}/man1/%{name}.1.gz
%license COPYING

请注意,在这里,我们没有指定 buildroot。所有这些路径都是相对路径。%doc%license命令做的稍微多一点,它们会创建所需的文件夹,并记住这些文件必须放在那里。

RPM 很聪明。例如,如果你在 %install 部分中安装了文件,但未列出它们,它会提醒你。

第六部分:在变更日志中记录所有变更

Fedora 是一个基于社区的项目。许多贡献者维护或共同维护软件包。因此,当务之急是不要被软件包做了哪些更改所搞混。为了确保这一点,spec 文件包含的最后一部分是变更日志 %changelog

%changelog
* Thu Jul 25 2019 Fedora Release Engineering < ...> - 0.3.9.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild

* Thu Jan 31 2019 Fedora Release Engineering < ...> - 0.3.9.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild

* Tue Jul 24 2018 Ankur Sinha  - 0.3.9.2-1
- Update to 0.3.9.2

* Fri Jul 13 2018 Fedora Release Engineering < ...> - 0.3.9.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild

* Wed Feb 07 2018 Fedora Release Engineering < ..> - 0.3.9.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

* Sun Sep 10 2017 Vasiliy N. Glazov < ...> - 0.3.9.1-2
- Cleanup spec

* Fri Sep 08 2017 Ankur Sinha  - 0.3.9.1-1
- Update to latest release
- fixes rhbz 1489605
...
....

spec 文件的每项变更都必须有一个变更日志条目。如你在此处看到的,虽然我以维护者身份更新了该 spec 文件,但其他人也做过更改。清楚地记录变更内容有助于所有人知道该 spec 文件的当前状态。对于系统上安装的所有软件包,都可以使用 rpm 来查看其更改日志:

$ rpm -q --changelog fpaste

构建 RPM

现在我们准备构建 RPM 包。如果要继续执行以下命令,请确保遵循上一篇文章中的步骤设置系统以构建 RPM。

我们将 fpaste 的 spec 文件放置在 ~/rpmbuild/SPECS 中,将源代码档案文件存储在 ~/rpmbuild/SOURCES/ 中,现在可以创建源 RPM 了:

$ cd ~/rpmbuild/SPECS
$ wget https://src.fedoraproject.org/rpms/fpaste/raw/master/f/fpaste.spec

$ cd ~/rpmbuild/SOURCES
$ wget https://pagure.io/fpaste/archive/0.3.9.2/fpaste-0.3.9.2.tar.gz

$ cd ~/rpmbuild/SOURCES
$ rpmbuild -bs fpaste.spec
Wrote: /home/asinha/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm

让我们看一下结果:

$ ls ~/rpmbuild/SRPMS/fpaste*
/home/asinha/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm

$ rpm -qpl ~/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm
fpaste-0.3.9.2.tar.gz
fpaste.spec

我们看到源 RPM 已构建。让我们同时构建源 RPM 和二进制 RPM:

$ cd ~/rpmbuild/SPECS
$ rpmbuild -ba fpaste.spec
..
..
..

RPM 将向你显示完整的构建输出,并在我们之前看到的每个部分中详细说明它的工作。此“构建日志”非常重要。当构建未按预期进行时,我们的打包人员将花费大量时间来遍历它们,以跟踪完整的构建路径来查看出了什么问题。

就是这样!准备安装的 RPM 应该位于以下位置:

$ ls ~/rpmbuild/RPMS/noarch/
fpaste-0.3.9.2-3.fc30.noarch.rpm

概括

我们已经介绍了如何从 spec 文件构建 RPM 的基础知识。这绝不是一份详尽的文档。实际上,它根本不是文档。它只是试图解释幕后的运作方式。简短回顾一下:

  • RPM 有两种类型:源 RPM 和 二进制 RPM。
  • 二进制 RPM 包含要安装以使用该软件的文件。
  • 源 RPM 包含构建二进制 RPM 所需的信息:完整的源代码,以及 spec 文件中的有关如何构建 RPM 的说明。
  • spec 文件包含多个部分,每个部分都有其自己的用途。 在这里,我们已经在安装好的 Fedora 系统中本地构建了 RPM。虽然这是个基本的过程,但我们从存储库中获得的 RPM 是建立在具有严格配置和方法的专用服务器上的,以确保正确性和安全性。这个 Fedora 打包流程将在以后的文章中讨论。

你想开始构建软件包,并帮助 Fedora 社区维护我们提供的大量软件吗?你可以从这里开始加入软件包集合维护者

如有任何疑问,请发布到 Fedora 开发人员邮件列表,我们随时乐意为你提供帮助!

参考

这里有一些构建 RPM 的有用参考:


via: https://fedoramagazine.org/how-rpm-packages-are-made-the-spec-file/

作者:Ankur Sinha FranciscoD 选题:lujun9972 译者:wxy 校对:wxy

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

上周,我一直在做一个 SQL 网站(https://sql-steps.wizardzines.com/,一个 SQL 示例列表)。我使用 sqlite 运行网站上的所有查询,并且我想在其中一个例子(这个)中使用窗口函数。

但是我使用的是 Ubuntu 18.04 中的 sqlite 版本,它太旧了,不支持窗口函数。所以我需要升级 sqlite!

事实证明,这个过程超麻烦(如通常一样),但是非常有趣!我想起了一些有关可执行文件和共享库如何工作的信息,结论令人满意。所以我想在这里写下来。

(剧透:https://www.sqlite.org/howtocompile.html 中解释了如何编译 SQLite,它只需花费 5 秒左右,这比我平时从源码编译的体验容易了许多。)

尝试 1:从它的网站下载 SQLite 二进制文件

SQLite 的下载页面有一个用于 Linux 的 SQLite 命令行工具的二进制文件的链接。我下载了它,它可以在笔记本电脑上运行,我以为这就完成了。

但是后来我尝试在构建服务器(Netlify) 上运行它,得到了这个极其奇怪的错误消息:“File not found”。我进行了追踪,并确定 execve 返回错误代码 ENOENT,这意味着 “File not found”。这有点令人发狂,因为该文件确实存在,并且有正确的权限。

我搜索了这个问题(通过搜索 “execve enoen”),找到了这个 stackoverflow 中的答案,它指出要运行二进制文件,你不仅需要二进制文件存在!你还需要它的加载程序才能存在。(加载程序的路径在二进制文件内部)

要查看加载程序的路径,可以使用 ldd,如下所示:

$ ldd sqlite3
    linux-gate.so.1 (0xf7f9d000)
    libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xf7f70000)
    libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xf7e6e000)
    libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xf7e4f000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c73000)
    /lib/ld-linux.so.2

所以 /lib/ld-linux.so.2 是加载程序,而该文件在构建服务器上不存在,可能是因为 Xenial(Xenial 是 Ubuntu 16.04,本文应该使用的是 18.04 “Bionic Beaver”)安装程序不支持 32 位二进制文​​件(?),因此我需要尝试一些不同的东西。

尝试 2:安装 Debian sqlite3 软件包

好吧,我想我也许可以安装来自 debian testing 的 sqlite 软件包。尝试从另一个我不使用的 Debian 版本安装软件包并不是一个好主意,但是出于某种原因,我还是决定尝试一下。

这次毫不意外地破坏了我计算机上的 sqlite(这也破坏了 git),但我设法通过 sudo dpkg --purge --force-all libsqlite3-0 恢复了,并使所有依赖于 sqlite 的软件再次工作。

尝试 3:提取 Debian sqlite3 软件包

我还尝试仅从 Debian sqlite 软件包中提取 sqlite3 二进制文件并运行它。毫不意外,这也行不通,但这个更容易理解:我有旧版本的 libreadline(.so.7),但它需要 .so.8

$ ./usr/bin/sqlite3
./usr/bin/sqlite3: error while loading shared libraries: libreadline.so.8: cannot open shared object file: No such file or directory

尝试 4:从源代码进行编译

我花费这么多时间尝试下载 sqlite 二进制的原因是我认为从源代码编译 sqlite 既烦人又耗时。但是显然,下载随便一个 sqlite 二进制文件根本不适合我,因此我最终决定尝试自己编译它。

这有指导:如何编译 SQLite。它是宇宙中最简单的东西。通常,编译的感觉是类似这样的:

  • 运行 ./configure
  • 意识到我缺少依赖
  • 再次运行 ./configure
  • 运行 make
  • 编译失败,因为我安装了错误版本的依赖
  • 去做其他事,之后找到二进制文件

编译 SQLite 的方式如下:

所有代码都在一个文件(sqlite.c)中,并且没有奇怪的依赖项!太奇妙了。

对我而言,我实际上并不需要线程支持或 readline 支持,因此我用编译页面上的说明来创建了一个非常简单的二进制文件,它仅使用了 libc 而没有其他共享库。

$ ldd sqlite3
    linux-vdso.so.1 (0x00007ffe8e7e9000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbea4988000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fbea4d79000)

这很好,因为它使体验 sqlite 变得容易

我认为 SQLite 的构建过程如此简单很酷,因为过去我很乐于编辑 sqlite 的源码来了解其 B 树的实现方式。

鉴于我对 SQLite 的了解,这并不令人感到意外(它在受限环境/嵌入式中确实可以很好地工作,因此可以以一种非常简单/最小的方式进行编译是有意义的)。 但这真是太好了!


via: https://jvns.ca/blog/2019/10/28/sqlite-is-really-easy-to-compile/

作者:Julia Evans 选题:lujun9972 译者:geekpi 校对:wxy

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