2018年4月

有些误解认为 shell 脚本仅用于 CLI 环境。实际上在 KDE 或 Gnome 桌面下,你可以有效的使用各种工具编写 GUI 或者网络(socket)脚本。shell 脚本可以使用一些 GUI 组件(菜单、警告框、进度条等),你可以控制终端输出、光标位置以及各种输出效果等等。利用下面的工具,你可以构建强壮的、可交互的、对用户友好的 UNIX/Linux bash 脚本。

制作 GUI 应用不是一项困难的任务,但需要时间和耐心。幸运的是,UNIX 和 Linux 都带有大量编写漂亮 GUI 脚本的工具。以下工具是基于 FreeBSD 和 Linux 操作系统做的测试,而且也适用于其他类 UNIX 操作系统。

1、notify-send 命令

notify-send 命令允许你借助通知守护进程发送桌面通知给用户。这种避免打扰用户的方式,对于通知桌面用户一个事件或显示一些信息是有用的。在 Debian 或 Ubuntu 上,你需要使用 apt 命令apt-get 命令 安装的包:

sudo apt-get install libnotify-bin

CentOS/RHEL 用户使用下面的 yum 命令

sudo yum install libnotify

Fedora Linux 用户使用下面的 dnf 命令:

`$ sudo dnf install libnotify`
In this example, send simple desktop notification from the command line, enter:
### 发送一些通知 ###
notify-send "rsnapshot done :)"

示例输出:

 title=

下面是另一个附加选项的代码:

...
alert=18000
live=$(lynx --dump http://money.rediff.com/ | grep 'BSE LIVE' | awk '{ print $5}' | sed 's/,//g;s/\.[0-9]*//g')
[ $notify_counter -eq 0 ] && [ $live -ge $alert ] && { notify-send -t 5000 -u low -i   "BSE Sensex touched 18k";  notify_counter=1; }
...

示例输出:

 title=

这里:

  • -t 5000:指定超时时间(毫秒) (5000 毫秒 = 5 秒)
  • -u low: 设置紧急等级 (如:低、普通、紧急)
  • -i gtk-dialog-info: 设置要显示的图标名称或者指定的图标(你可以设置路径为:-i /path/to/your-icon.png

关于更多使用 notify-send 功能的信息,请参考 man 手册。在命令行下输入 man notify-send 即可看见:

man notify-send

2、tput 命令

tput 命令用于设置终端特性。通过 tput 你可以设置:

  • 在屏幕上移动光标。
  • 获取终端信息。
  • 设置颜色(背景和前景)。
  • 设置加粗模式。
  • 设置反转模式等等。

下面有一段示例代码:

#!/bin/bash

# clear the screen
tput clear

# Move cursor to screen location X,Y (top left is 0,0)
tput cup 3 15

# Set a foreground colour using ANSI escape
tput setaf 3
echo "XYX Corp LTD."
tput sgr0

tput cup 5 17
# Set reverse video mode
tput rev
echo "M A I N - M E N U"
tput sgr0

tput cup 7 15
echo "1. User Management"

tput cup 8 15
echo "2. Service Management"

tput cup 9 15
echo "3. Process Management"

tput cup 10 15
echo "4. Backup"

# Set bold mode
tput bold
tput cup 12 15
read -p "Enter your choice [1-4] " choice

tput clear
tput sgr0
tput rc

示例输出:

 title=

关于 tput 命令的详细信息,参见手册:

man 5 terminfo
man tput

3、setleds 命令

setleds 命令允许你设置键盘灯。下面是打开数字键灯的示例:

setleds -D +num

关闭数字键灯,输入:

setleds -D -num
  • -caps:关闭大小写锁定灯
  • +caps:打开大小写锁定灯
  • -scroll:关闭滚动锁定灯
  • +scroll:打开滚动锁定灯

查看 setleds 手册可看见更多信息和选项 man setleds

4、zenity 命令

zenity 命令显示 GTK+ 对话框,并且返回用户输入。它允许你使用各种 Shell 脚本向用户展示或请求信息。下面是一个 whois 指定域名目录服务的 GUI 客户端示例。

#!/bin/bash
# Get domain name
_zenity="/usr/bin/zenity"
_out="/tmp/whois.output.$$"
domain=$(${_zenity} --title  "Enter domain" \
             --entry --text "Enter the domain you would like to see whois info" )

if [ $? -eq 0 ]
then
  # Display a progress dialog while searching whois database
  whois $domain  | tee >(${_zenity} --width=200 --height=100 \
                    --title="whois" --progress \
                        --pulsate --text="Searching domain info..." \
                                    --auto-kill --auto-close \
                                    --percentage=10) >${_out}

  # Display back output
  ${_zenity} --width=800 --height=600  \
         --title "Whois info for $domain" \
         --text-info --filename="${_out}"
else
  ${_zenity} --error \
         --text="No input provided"
fi

示例输出:

 title=

参见手册获取更多 zenity 信息以及其他支持 GTK+ 的组件:

zenity --help
man zenity

5、kdialog 命令

kdialog 命令与 zenity 类似,但它是为 KDE 桌面和 QT 应用设计。你可以使用 kdialog 展示对话框。下面示例将在屏幕上显示信息:

kdialog --dontagain myscript:nofilemsg --msgbox "File: '~/.backup/config' not found."

示例输出:

 title=

参见 《KDE 对话框 Shell 脚本编程》 教程获取更多信息。

6、Dialog

Dialog 是一个使用 Shell 脚本的应用,显示用户界面组件的文本。它使用 curses 或者 ncurses 库。下面是一个示例代码:

#!/bin/bash
dialog --title "Delete file" \
--backtitle "Linux Shell Script Tutorial Example" \
--yesno "Are you sure you want to permanently delete \"/tmp/foo.txt\"?" 7 60

# Get exit status
# 0 means user hit [yes] button.
# 1 means user hit [no] button.
# 255 means user hit [Esc] key.
response=$?
case $response in
   0) echo "File deleted.";;
   1) echo "File not deleted.";;
   255) echo "[ESC] key pressed.";;
esac

参见 dialog 手册获取详细信息:man dialog

关于其他用户界面工具的注意事项

UNIX、Linux 提供了大量其他工具来显示和控制命令行中的应用程序,shell 脚本可以使用一些 KDE、Gnome、X 组件集:

  • gmessage - 基于 GTK xmessage 的克隆
  • xmessage - 在窗口中显示或询问消息(基于 X 的 /bin/echo)
  • whiptail - 显示来自 shell 脚本的对话框
  • python-dialog - 用于制作简单文本或控制台模式用户界面的 Python 模块

7、logger 命令

logger 命令将信息写到系统日志文件,如:/var/log/messages。它为系统日志模块 syslog 提供了一个 shell 命令行接口:

logger "MySQL database backup failed."
tail -f /var/log/messages
logger -t mysqld -p daemon.error "Database Server failed"
tail -f /var/log/syslog

示例输出:

Apr 20 00:11:45 vivek-desktop kernel: [38600.515354] CPU0: Temperature/speed normal
Apr 20 00:12:20 vivek-desktop mysqld: Database Server failed

参见 《如何写消息到 syslog 或 日志文件》 获得更多信息。此外,你也可以查看 logger 手册获取详细信息:man logger

8、setterm 命令

setterm 命令可设置不同的终端属性。下面的示例代码会强制屏幕在 15 分钟后变黑,监视器则 60 分钟后待机。

setterm -blank 15 -powersave powerdown -powerdown 60

下面的例子将 xterm 窗口中的文本以下划线展示:

setterm -underline on;
echo "Add Your Important Message Here"
setterm -underline off

另一个有用的选项是打开或关闭光标显示:

setterm -cursor off

打开光标:

setterm -cursor on

参见 setterm 命令手册获取详细信息:man setterm

9、smbclient:给 MS-Windows 工作站发送消息

smbclient 命令可以与 SMB/CIFS 服务器通讯。它可以向 MS-Windows 系统上选定或全部用户发送消息。

smbclient -M WinXPPro <<eof
Message 1
Message 2
...
..
EOF

echo "${Message}" | smbclient -M salesguy2

参见 smbclient 手册或者阅读我们之前发布的文章:《给 Windows 工作站发送消息》:man smbclient

10、Bash 套接字编程

在 bash 下,你可以打开一个套接字并通过它发送数据。你不必使用 curl 或者 lynx 命令抓取远程服务器的数据。bash 和两个特殊的设备文件可用于打开网络套接字。以下选自 bash 手册:

  1. /dev/tcp/host/port - 如果 host 是一个有效的主机名或者网络地址,而且端口是一个整数或者服务名,bash 会尝试打开一个相应的 TCP 连接套接字。
  2. /dev/udp/host/port - 如果 host 是一个有效的主机名或者网络地址,而且端口是一个整数或者服务名,bash 会尝试打开一个相应的 UDP 连接套接字。

你可以使用这项技术来确定本地或远程服务器端口是打开或者关闭状态,而无需使用 nmap 或者其它的端口扫描器。

# find out if TCP port 25 open or not
(echo >/dev/tcp/localhost/25) &>/dev/null && echo "TCP port 25 open" || echo "TCP port 25 close"

下面的代码片段,你可以利用 bash 循环找出已打开的端口

echo "Scanning TCP ports..."
for p in {1..1023}
do
  (echo >/dev/tcp/localhost/$p) >/dev/null 2>&1 && echo "$p open"
done

示例输出:

Scanning TCP ports...
22 open
53 open
80 open
139 open
445 open
631 open

下面的示例中,你的 bash 脚本将像 HTTP 客户端一样工作:

#!/bin/bash
exec 3<> /dev/tcp/${1:-www.cyberciti.biz}/80

printf "GET / HTTP/1.0
" >&3
printf "Accept: text/html, text/plain
" >&3
printf "Accept-Language: en
" >&3
printf "User-Agent: nixCraft_BashScript v.%s
" "${BASH_VERSION}"   >&3
printf "
" >&3

while read LINE <&3
do
   # do something on $LINE
   # or send $LINE to grep or awk for grabbing data
   # or simply display back data with echo command
   echo $LINE
done

参见 bash 手册获取更多信息:man bash

关于 GUI 工具和 cron 任务的注意事项

如果你 使用 crontab 来启动你的脚本,你需要使用 export DISPLAY=[用户机器]:0 命令请求本地显示或输出服务。举个例子,使用 zenity 工具调用 /home/vivek/scripts/monitor.stock.sh

@hourly DISPLAY=:0.0 /home/vivek/scripts/monitor.stock.sh

你有喜欢的可以增加 shell 脚本趣味的 UNIX 工具么?请在下面的评论区分享它吧。

关于作者

本文作者是 nixCraft 创始人、一个老练的系统管理员、Linux 操作系统和 UNIX shell 编程培训师。他服务来自全球的客户和不同的行业,包括 IT 、教育、防务和空间探索、还有非营利组织。你可以在 TwitterFacebookGoogle+ 上面关注他。


via: https://www.cyberciti.biz/tips/spice-up-your-unix-linux-shell-scripts.html

作者:Vivek Gite 译者:pygmalion666 校对:wxy

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

这篇文章是在我之前的博客中发表过的在 Ubuntu 16.04 上配置 MSMTP 的一个副本。我再次发表是为了后续,我并不知道它是否能在更高版本上工作。由于我没有再托管自己的 Ubuntu/MSMTP 服务器了,所以我现在看不到有需要更新的地方,但是如果我需要重新设置,我会创建一个更新的帖子!无论如何,这是我现有的。

我之前写了一篇在 Ubuntu 12.04 上配置 msmtp 的文章,但是正如我在之前的文章中暗示的那样,当我升级到 Ubuntu 16.04 后出现了一些问题。接下来的内容基本上是一样的,但 16.04 有一些小的更新。和以前一样,这里假定你使用 Apache 作为 Web 服务器,但是我相信如果你选择其他的 Web 服务器,也应该相差不多。

我使用 msmtp 发送来自这个博客的邮件俩通知我评论和更新等。这里我会记录如何配置它通过 Google Apps 帐户发送电子邮件,虽然这应该与标准的 Google 帐户一样。

首先,我们需要安装 3 个软件包:

sudo apt-get install msmtp msmtp-mta ca-certificates

安装完成后,就需要一个默认配置。默认情况下,msmtp 会在 /etc/msmtprc 中查找,所以我使用 vim 创建了这个文件,尽管任何文本编辑器都可以做到这一点。这个文件看起来像这样:

# Set defaults.
defaults
# Enable or disable TLS/SSL encryption.
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
# Setup WP account's settings.
account GMAIL
host smtp.gmail.com
port 587
auth login
user YOUR USERNAME
password YOUR PASSWORD
from FROM@ADDRESS
logfile /var/log/msmtp/msmtp.log

account default :

任何大写选项都是需要替换为你特定的配置。日志文件是一个例外,当然你也可以将活动/警告/错误放在任何你想要的地方。

文件保存后,我们将更新上述配置文件的权限 ,如果该文件的权限过于开放,msmtp 将不会运行,并且创建日志文件的目录。

sudo mkdir /var/log/msmtp
sudo chown -R www-data:adm /var/log/msmtp
sudo chmod 0600 /etc/msmtprc

接下来,我选择为 msmtp 日志配置 logrotate,以确保日志文件不会太大并让日志目录更加整洁。为此,我们创建 /etc/logrotate.d/msmtp 并使用按以下内容配置。请注意,这是可选的,你可以选择不这样做,或者你可以选择以不同方式配置日志。

/var/log/msmtp/*.log {
    rotate 12
    monthly
    compress
    missingok
    notifempty
}

现在配置了日志,我们需要通过编辑 /etc/php/7.0/apache2/php.ini 告诉 PHP 使用 msmtp,并将 sendmail 路径从

sendmail_path =

变成

sendmail_path = "/usr/bin/msmtp -C /etc/msmtprc -a -t"

这里我遇到了一个问题,即使我指定了帐户名称,但是当我测试它时,它并没有正确发送电子邮件。这就是为什么 account default : 这行被放在 msmtp 配置文件的末尾。要测试配置,请确保 PHP 文件已保存并运行 sudo service apache2 restart,然后运行 php -a 并执行以下命令

mail ('[email protected]', 'Test Subject', 'Test body text');
exit();

此时发生的任何错误都将显示在输出中,因此错误诊断会相对容易。如果一切顺利,你现在应该可以使用 PHP sendmail(至少 WordPress 可以)中用 Gmail(或 Google Apps)从 Ubuntu 服务器发送电子邮件。

我没有说这是最安全的配置,所以当你看到并且意识要这个非常不安全,或者有其他严重的错误,请让我知道,我会相应地更新。


via: https://codingproductivity.wordpress.com/2018/01/18/configuring-msmtp-on-ubuntu-16-04-again/

作者:JOE 译者:geekpi 校对:wxy

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

最近 Linux 容器很火,我们中的大多数人甚至已经在使用它,同时一些人也开始学习它。

我们已经介绍了有名的 GUI(用户图形界面) 工具如 Portainer 和 Rancher 。这将会有助于我们通过 GUI 管理容器。

这篇指南将会通过 cTop 命令帮助我们理解和监控 Linux 容器。它是一个类似 top 命令的命令行工具。

什么是 cTop

ctop 为多个容器提供了一个简洁凝练的实时指标概览。它是一个类 top 的针对容器指标的界面。

它展示了容器指标比如 CPU 利用率、内存利用率、磁盘 I/O 读写、进程 ID(PID)和网络发送(TX - 从此服务器发送)以及接受(RX - 此服务器接受)。

ctop 带有对 Docker 和 runc 的内建支持;对其他容器和集群系统的连接计划在未来版本中推出。

它不需要任何参数并且默认使用 Docker 主机变量。

建议阅读:

如何安装 cTop

开发者提供了一个简单的 shell 脚本来帮助我们直接使用 ctop。我们要做的,只是在 /bin 目录下下载 ctop shell 文件来保证全局访问。最后给予 ctop 脚本文件执行权限。

/usr/local/bin 目录下下载 ctop shell 脚本。

$ sudo wget https://github.com/bcicen/ctop/releases/download/v0.7/ctop-0.7-linux-amd64 -O /usr/local/bin/ctop

ctop shell 脚本设置执行权限。

$ sudo chmod +x /usr/local/bin/ctop

另外你可以通过 docker 来安装和运行 ctop。在此之前先确保你已经安装过 docker。为了安装 docker,参考以下链接。

建议阅读:

$ docker run --rm -ti \
 --name=ctop \
 -v /var/run/docker.sock:/var/run/docker.sock \
 quay.io/vektorlab/ctop:latest

如何使用 cTop

直接启动 ctop 程序而不用任何参数。默认它绑定的 a 键用来展示所有容器(运行的和没运行的)。

ctop 头部显示你的系统时间和容器的总数。

$ ctop

你可能得到以下类似输出。

如何管理容器

你可以使用 ctop 来管理容器。选择一个你想要管理的容器然后按下回车键,选择所需选项如 startstopremove 等。

如何给容器排序

默认 ctop 使用 state 字段来给容器排序。按下 s 键来按不同的方面给容器排序。

如何查看容器指标

如何你想要查看关于容器的更多细节和指标,只用选择你想要查看的相应容器然后按 o 键。

如何查看容器日志

选择你想要查看日志的相应容器然后按 l 键。

仅显示活动容器

使用 -a 选项运行 ctop 命令来仅显示活动容器

打开帮助对话框

运行 ctop,只需按 h 键来打开帮助部分。


via: https://www.2daygeek.com/ctop-a-command-line-tool-for-container-monitoring-and-management-in-linux/

作者:2DAYGEEK 译者:kimii 校对:wxy

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

~ 更新于 2017-11-02 ~

什么是 BPF?

BPF,及 伯克利包过滤器 B erkeley P acket F ilter ,最初构想提出于 1992 年,其目的是为了提供一种过滤包的方法,并且要避免从内核空间到用户空间的无用的数据包复制行为。它最初是由从用户空间注入到内核的一个简单的字节码构成,它在那个位置利用一个校验器进行检查 —— 以避免内核崩溃或者安全问题 —— 并附着到一个套接字上,接着在每个接收到的包上运行。几年后它被移植到 Linux 上,并且应用于一小部分应用程序上(例如,tcpdump)。其简化的语言以及存在于内核中的即时编译器(JIT),使 BPF 成为一个性能卓越的工具。

然后,在 2013 年,Alexei Starovoitov 对 BPF 进行彻底地改造,并增加了新的功能,改善了它的性能。这个新版本被命名为 eBPF (意思是 “extended BPF”),与此同时,将以前的 BPF 变成 cBPF(意思是 “classic” BPF)。新版本出现了如映射和 尾调用 tail call 这样的新特性,并且 JIT 编译器也被重写了。新的语言比 cBPF 更接近于原生机器语言。并且,在内核中创建了新的附着点。

感谢那些新的钩子,eBPF 程序才可以被设计用于各种各样的情形下,其分为两个应用领域。其中一个应用领域是内核跟踪和事件监控。BPF 程序可以被附着到探针(kprobe),而且它与其它跟踪模式相比,有很多的优点(有时也有一些缺点)。

另外一个应用领域是网络编程。除了套接字过滤器外,eBPF 程序还可以附加到 tc(Linux 流量控制工具)的入站或者出站接口上,以一种很高效的方式去执行各种包处理任务。这种使用方式在这个领域开创了一个新的天地。

并且 eBPF 通过使用为 IO Visor 项目开发的技术,使它的性能进一步得到提升:也为 XDP(“eXpress Data Path”)添加了新的钩子,XDP 是不久前添加到内核中的一种新式快速路径。XDP 与 Linux 栈组合,然后使用 BPF ,使包处理的速度更快。

甚至一些项目,如 P4、Open vSwitch,考虑 或者开始去接洽使用 BPF。其它的一些,如 CETH、Cilium,则是完全基于它的。BPF 是如此流行,因此,我们可以预计,不久之后,将围绕它有更多工具和项目出现 …

深入理解字节码

就像我一样:我的一些工作(包括 BEBA)是非常依赖 eBPF 的,并且在这个网站上以后的几篇文章将关注于这个主题。按理说,在深入到细节之前,我应该以某种方式去介绍 BPF —— 我的意思是,真正的介绍,在第一节所提供的简要介绍上更多地介绍在 BPF 上开发的新功能:什么是 BPF 映射?尾调用?内部结构是什么样子?等等。但是,在这个网站上已经有很多这个主题的介绍了,而且,我也不希望去写另一篇 “BPF 介绍” 的重复文章。

毕竟,我花费了很多的时间去阅读和学习关于 BPF 的知识,因此,在这里我们将要做什么呢,我收集了非常多的关于 BPF 的阅读材料:介绍、文档,也有教程或者示例。这里有很多的材料可以去阅读,但是,为了去阅读它,首先要去 找到 它。因此,为了能够帮助更多想去学习和使用 BPF 的人,现在的这篇文章给出了一个资源清单。这里有各种阅读材料,它可以帮你深入理解内核字节码的机制。

资源

简介

这篇文章中下面的链接提供了 BPF 的基本概述,或者,一些与它密切相关的一些主题。如果你对 BPF 非常陌生,你可以在这些介绍文章中挑选出一篇你喜欢的文章去阅读。如果你已经理解了 BPF,你可以针对特定的主题去阅读,下面是阅读清单。

关于 BPF

关于 eBPF 的常规介绍

BPF 内部结构

IO Visor 博客 有一些关于 BPF 的值得关注技术文章。它们中的一些包含了一点营销讨论。

内核跟踪:总结了所有的已有的方法,包括 BPF:

  • 邂逅 eBPF 和内核跟踪 (Viller Hsiao, July 2016):
    Kprobes、uprobes、ftrace
  • Linux 内核跟踪(Viller Hsiao, July 2016):
    Systemtap、Kernelshark、trace-cmd、LTTng、perf-tool、ftrace、hist-trigger、perf、function tracer、tracepoint、kprobe/uprobe …

关于 事件跟踪和监视,Brendan Gregg 大量使用了 eBPF,并且就其使用 eBPFR 的一些案例写了极好的文档。如果你正在做一些内核跟踪方面的工作,你应该去看一下他的关于 eBPF 和火焰图相关的博客文章。其中的大多数都可以 从这篇文章中 访问,或者浏览他的博客。

介绍 BPF,也介绍 Linux 网络的一般概念

硬件 卸载 offload (LCTT 译注:“卸载”是指原本由软件来处理的一些操作交由硬件来完成,以提升吞吐量,降低 CPU 负荷。):

  • eBPF 与 tc 或者 XDP 一起支持硬件卸载,开始于 Linux 内核版本 4.9,是由 Netronome 提出的。这里是关于这个特性的介绍:eBPF/XDP 硬件卸载到 SmartNICs(Jakub Kicinski 和 Nic Viljoen, netdev 1.2, Tokyo, October 2016)
  • 一年后出现的更新版:
    综合 XDP 卸载——处理边界案例(Jakub Kicinski 和 Nic Viljoen,netdev 2.2 ,Seoul,November 2017)
  • 我现在有一个简短的,但是在 2018 年的 FOSDEM 上有一个更新版:
    XDP 硬件卸载的挑战(Quentin Monnet,FOSDEM 2018,Brussels,February 2018)

关于 cBPF

关于 XDP

  • 在 IO Visor 网站上的 XDP 概述
  • eXpress Data Path (XDP) (Tom Herbert, Alexei Starovoitov, March 2016):
    这是第一个关于 XDP 的演讲。
  • BoF - BPF 能为你做什么? (Brenden Blanco, LinuxCon, Toronto, August 2016)。
  • eXpress Data Path (Brenden Blanco, Linux Meetup at Santa Clara, July 2016):
    包含一些(有点营销的意思?)基准测试结果!使用单一核心:
+ ip 路由丢弃: ~3.6 百万包每秒(Mpps)
+ 使用 BPF,tc(使用 clsact qdisc)丢弃: ~4.2 Mpps
+ 使用 BPF,XDP 丢弃:20 Mpps (CPU 利用率 < 10%)
+ XDP 重写转发(在端口上它接收到的包):10 Mpps(测试是用 mlx4 驱动程序执行的)。
  • Jesper Dangaard Brouer 有几个非常好的幻灯片,它可以从本质上去理解 XDP 的内部结构。

    • XDP − eXpress Data Path,介绍及将来的用法 (September 2016):
      “Linux 内核与 DPDK 的斗争” 。未来的计划(在写这篇文章时)它用 XDP 和 DPDK 进行比较。
    • 网络性能研讨 (netdev 1.2, Tokyo, October 2016):
      关于 XDP 内部结构和预期演化的附加提示。
    • XDP – eXpress Data Path, 可用于 DDoS 防护 (OpenSourceDays, March 2017):
      包含了关于 XDP 的详细情况和使用案例,以及 性能测试性能测试结果代码片断,以及使用 eBPF/XDP(基于一个 IP 黑名单模式)的用于 基本的 DDoS 防护
    • 内存 vs. 网络,激发和修复内存瓶颈 (LSF Memory Management Summit, March 2017):
      提供了许多 XDP 开发者当前所面对 内存问题 的许多细节。不要从这一个开始,但如果你已经理解了 XDP,并且想去了解它在页面分配方面的真实工作方式,这是一个非常有用的资源。
    • XDP 能为其它人做什么(netdev 2.1, Montreal, April 2017),及 Andy Gospodarek:
      普通人怎么开始使用 eBPF 和 XDP。这个演讲也由 Julia Evans 在 她的博客 上做了总结。
    • XDP 能为其它人做什么,第二版(netdev 2.2, Seoul, November 2017),同一个作者:
      该演讲的修订版本,包含了新的内容。

(Jesper 也创建了并且尝试去扩展了有关 eBPF 和 XDP 的一些文档,查看 相关节。)

  • XDP 研讨 — 介绍、体验和未来发展(Tom Herbert, netdev 1.2, Tokyo, October 2016)
    在这篇文章中,只有视频可用,我不知道是否有幻灯片。
  • 在 Linux 上进行高速包过滤 (Gilberto Bertin, DEF CON 25, Las Vegas, July 2017)
    在 Linux 上的最先进的包过滤的介绍,面向 DDoS 的保护、讨论了关于在内核中进行包处理、内核旁通、XDP 和 eBPF。

关于 基于 eBPF 或者 eBPF 相关的其它组件

  • 在边界上的 P4 (John Fastabend, May 2016):
    提出了使用 P4,一个包处理的描述语言,使用 BPF 去创建一个高性能的可编程交换机。
  • 如果你喜欢音频的演讲,这里有一个相关的 OvS Orbit 片断(#11),叫做 在边界上的 P4,日期是 2016 年 8 月。OvS Orbit 是对 Ben Pfaff 的访谈,它是 Open vSwitch 的其中一个核心维护者。在这个场景中,John Fastabend 是被访谈者。
  • P4, EBPF 和 Linux TC 卸载 (Dinan Gunawardena 和 Jakub Kicinski, August 2016):
    另一个 P4 的演讲,一些有关于 Netronome 的 NFP(网络流处理器)架构上的 eBPF 硬件卸载的因素。
  • Cilium 是一个由 Cisco 最先发起的技术,它依赖 BPF 和 XDP 去提供 “基于 eBPF 程序即时生成的,用于容器的快速内核强制的网络和安全策略”。这个项目的代码 在 GitHub 上可以访问到。Thomas Graf 对这个主题做了很多的演讲:

  • 这里也有一个关于 Cilium 的播客节目:一个是 OvS Orbit episode (#4),它是 Ben Pfaff 访谈 Thomas Graf (2016 年 5 月),和 另外一个 Ivan Pepelnjak 的播客,仍然是 Thomas Graf 关于 eBPF、P4、XDP 和 Cilium 方面的(2016 年 10 月)。
  • Open vSwitch (OvS),它是 Open Virtual Network(OVN,一个开源的网络虚拟化解决方案)相关的项目,正在考虑在不同的层次上使用 eBPF,它已经实现了几个概念验证原型:

    • 使用 eBPF 卸载 OVS 流处理器 (William (Cheng-Chun) Tu, OvS conference, San Jose, November 2016)
    • 将 OVN 的灵活性与 IOVisor 的高效率相结合 (Fulvio Risso, Matteo Bertrone 和 Mauricio Vasquez Bernal, OvS conference, San Jose, November 2016)据我所知,这些 eBPF 的使用案例看上去仅处于提议阶段(并没有合并到 OvS 的主分支中),但是,看它带来了什么将是非常值得关注的事情。
  • XDP 的设计对分布式拒绝访问(DDoS)攻击是非常有用的。越来越多的演讲都关注于它。例如,在 2017 年 4 月加拿大蒙特利尔举办的 netdev 2.1 会议上,来自 Cloudflare 的人们的讲话(XDP 实践:将 XDP 集成到我们的 DDoS 缓解管道)或者来自 Facebook 的(Droplet:由 BPF + XDP 驱动的 DDoS 对策)都存在这样的很多使用案例。
  • Kubernetes 可以用很多种方式与 eBPF 交互。这里有一篇关于 在 Kubernetes 中使用 eBPF 的文章,它解释了现有的产品(Cilium、Weave Scope)如何支持 eBPF 与 Kubernetes 一起工作,并且进一步描述了,在容器部署环境中,eBPF 感兴趣的交互内容是什么。
  • CETH for XDP (Yan Chan 和 Yunsong Lu、Linux Meetup、Santa Clara、July 2016):
    CETH,是由 Mellanox 发起的,为实现更快的网络 I/O 而主张的通用以太网驱动程序架构。
  • VALE 交换机,另一个虚拟交换机,它可以与 netmap 框架结合,有 一个 BPF 扩展模块
  • Suricata,一个开源的入侵检测系统,它的旁路捕获旁特性依赖于 XDP。有一些关于它的资源:

  • InKeV:对于 DCN 的内核中分布式网络虚拟化 (Z. Ahmed, M. H. Alizai 和 A. A. Syed, SIGCOMM, August 2016):
    InKeV 是一个基于 eBPF 的虚拟网络、目标数据中心网络的数据路径架构。它最初由 PLUMgrid 提出,并且声称相比基于 OvS 的 OpenStack 解决方案可以获得更好的性能。
  • gobpf - 在 Go 中使用 eBPF (Michael Schubert, fosdem17, Brussels, Belgium, February 2017):
    “一个来自 Go 库,可以去创建、加载和使用 eBPF 程序”
  • ply 是为 Linux 实现的一个小而灵活的开源动态 跟踪器,它的一些特性非常类似于 bcc 工具,是受 awk 和 dtrace 启发,但使用一个更简单的语言。它是由 Tobias Waldekranz 写的。
  • 如果你读过我以前的文章,你可能对我在这篇文章中的讨论感兴趣,使用 eBPF 实现 OpenState 接口,关于包状态处理,在 fosdem17 中。

文档

一旦你对 BPF 是做什么的有一个大体的理解。你可以抛开一般的演讲而深入到文档中了。下面是 BPF 的规范和功能的最全面的文档,按你的需要挑一个开始阅读吧!

关于 BPF

  • BPF 的规范(包含 classic 和 extended 版本)可以在 Linux 内核的文档中,和特定的文件 linux/Documentation/networking/filter.txt 中找到。BPF 使用以及它的内部结构也被记录在那里。此外,当加载 BPF 代码失败时,在这里可以找到 被校验器抛出的错误信息,这有助于你排除不明确的错误信息。
  • 此外,在内核树中,在 eBPF 那里有一个关于 常见问答 的文档,它在文件 linux/Documentation/bpf/bpf\_design\_QA.txt 中。
  • … 但是,内核文档是非常难懂的,并且非常不容易阅读。如果你只是去查找一个简单的 eBPF 语言的描述,可以去 IO Visor 的 GitHub 仓库,那儿有 它的概括性描述
  • 顺便说一下,IO Visor 项目收集了许多 关于 BPF 的资源。大部分分别在 bcc 仓库的 文档目录 中,和 bpf-docs 仓库 的整个内容中,它们都在 GitHub 上。注意,这个非常好的 BPF 参考指南 包含一个详细的 BPF C 和 bcc Python 的 helper 的描述。
  • 想深入到 BPF,那里有一些必要的 Linux 手册页。第一个是 bpf(2) man 页面 关于 bpf() 系统调用,它用于从用户空间去管理 BPF 程序和映射。它也包含一个 BPF 高级特性的描述(程序类型、映射等等)。第二个是主要是处理希望附加到 tc 接口的 BPF 程序:它是 tc-bpf(8) man 页面,是 使用 BPF 和 tc 的一个参考,并且包含一些示例命令和参考代码。
  • Jesper Dangaard Brouer 发起了一个 更新 eBPF Linux 文档 的尝试,包含 不同的映射他有一个草案,欢迎去贡献。一旦完成,这个文档将被合并进 man 页面并且进入到内核文档。
  • Cilium 项目也有一个非常好的 BPF 和 XDP 参考指南,它是由核心的 eBPF 开发者写的,它被证明对于 eBPF 开发者是极其有用的。
  • David Miller 在 xdp-newbies 邮件列表中发了几封关于 eBPF/XDP 内部结构的富有启发性的电子邮件。我找不到一个单独的地方收集它们的链接,因此,这里是一个列表:

  • Ferris Ellis 发布的 一个关于 eBPF 的系列博客文章。作为我写的这个短文,第一篇文章是关于 eBPF 的历史背景和未来期望。接下来的文章将更多的是技术方面,和前景展望。
  • 每个内核版本的 BPF 特性列表 在 bcc 仓库中可以找到。如果你想去知道运行一个给定的特性所要求的最小的内核版本,它是非常有用的。我贡献和添加了链接到提交中,它介绍了每个特性,因此,你也可以从那里很容易地去访问提交历史。

关于 tc

当为了网络目的结合使用 BPF 与 tc (Linux 流量控制 t raffic c ontrol 工具)时,它可用于收集 tc 的常规功能的信息。这里有几个关于它的资源。

关于 XDP

  • 对于 XDP 的一些 进展中的文档(包括规范) 已经由 Jesper Dangaard Brouer 启动,并且意味着将成为一个协作工作。正在推进的(2016 年 9 月):你期望它去改变,并且或许在一些节点上移动(Jesper 称为贡献,如果你想去改善它)。
  • 自来 Cilium 项目的 BPF 和 XDP 参考指南 … 好吧,这个名字已经说明了一切。

关于 P4 和 BPF

P4 是一个用于指定交换机行为的语言。它可以为多种目标硬件或软件编译。因此,你可能猜到了,这些目标中的一个就是 BPF … 仅部分支持的:一些 P4 特性并不能被转化到 BPF 中,并且,用类似的方法,BPF 可以做的事情,而使用 P4 却不能表达出现。不过,P4 与 BPF 使用 的相关文档,被隐藏在 bcc 仓库中。这个改变在 P4\_16 版本中,p4c 引用的编辑器包含 一个 eBPF 后端

教程

Brendan Gregg 为想要 使用 bcc 工具 跟踪和监视内核中的事件的人制作了一个非常好的 教程第一个教程是关于如何使用 bcc 工具,它有许多章节,可以教你去理解怎么去使用已有的工具,而 针对 Python 开发者的一篇 专注于开发新工具,它总共有十七节 “课程”。

Sasha Goldshtein 也有一些 Linux 跟踪研究材料 涉及到使用几个 BPF 工具进行跟踪。

Jean-Tiare Le Bigot 的另一篇文章提供了一个详细的(和有指导意义的)使用 perf 和 eBPF 去设置一个低级的跟踪器 的示例。

对于网络相关的 eBPF 使用案例也有几个教程。有一些值得关注的文档,包括一篇 eBPF 卸载入门指南,是关于在 Open NFP 平台上用 Netronome 操作的。其它的那些,来自 Jesper 的演讲,XDP 能为其它人做什么(及其第二版),可能是 XDP 入门的最好的方法之一。

示例

有示例是非常好的。看看它们是如何工作的。但是 BPF 程序示例是分散在几个项目中的,因此,我列出了我所知道的所有的示例。示例并不是总是使用相同的 helper(例如,tc 和 bcc 都有一套它们自己的 helper,使它可以很容易地去用 C 语言写 BPF 程序)

来自内核的示例

内核中包含了大多数类型的程序:过滤器绑定到套接字或者 tc 接口、事件跟踪/监视、甚至是 XDP。你可以在 linux/samples/bpf/ 目录中找到这些示例。

现在,更多的示例已经作为单元测试被添加到 linux/tools/testing/selftests/bpf 目录下,这里面包含对硬件卸载的测试或者对于 libbpf 的测试。

Jesper 的 Dangaard Brouer 在他的 prototype-kernel 仓库中也维护了一套专门的示例。 这些示例与那些内核中提供的示例非常类似,但是它们可以脱离内核架构(Makefile 和头文件)编译。

也不要忘记去看一下 git 相关的提交历史,它们介绍了一些特定的特性,也许包含了一些特性的详细示例。

来自包 iproute2 的示例

iproute2 包也提供了几个示例。它们都很明显地偏向网络编程,因此,这个程序是附着到 tc 入站或者出站接口上。这些示例在 iproute2/examples/bpf/ 目录中。

来自 bcc 工具集的示例

许多示例都是 与 bcc 一起提供的

  • 一些网络的示例放在相关的目录下面。它们包括套接字过滤器、tc 过滤器、和一个 XDP 程序。
  • tracing 目录包含许多 跟踪编程 的示例。前面的教程中提到的都在那里。那些程序涉及了很大部分的事件监视功能,并且,它们中的一些是面向生产系统的。注意,某些 Linux 发行版(至少是 Debian、Ubuntu、Fedora、Arch Linux)、这些程序已经被 打包了 并且可以很 “容易地” 通过比如 # apt install bcc-tools 进行安装。但是在写这篇文章的时候(除了 Arch Linux),首先要求安装 IO Visor 的包仓库。
  • 也有一些 使用 Lua 作为一个不同的 BPF 后端(那是因为 BPF 程序是用 Lua 写的,它是 C 语言的一个子集,它允许为前端和后端使用相同的语言)的一些示例,它在第三个目录中。
  • 当然,bcc 工具 自身就是 eBPF 程序使用案例的值得关注示例。

手册页面

虽然 bcc 一般很容易在内核中去注入和运行一个 BPF 程序,将程序附着到 tc 接口也能通过 tc 工具自己完成。因此,如果你打算将 BPF 与 tc 一起使用,你可以在 tc-bpf(8) 手册页面 中找到一些调用示例。

代码

有时候,BPF 文档或者示例并不够,而且你只想在你喜欢的文本编辑器(它当然应该是 Vim)中去显示代码并去阅读它。或者,你可能想深入到代码中去做一个补丁程序或者为机器增加一些新特性。因此,这里对有关的文件的几个建议,找到你想要的函数只取决于你自己!

在内核中的 BPF 代码

  • 文件 linux/include/linux/bpf.h 及其相对的 linux/include/uapi/bpf.h 包含有关 eBPF 的 定义,它们分别用在内核中和用户空间程序的接口。
  • 相同的方式,文件 linux/include/linux/filter.hlinux/include/uapi/filter.h 包含了用于 运行 BPF 程序 的信息。
  • BPF 相关的 主要的代码片断linux/kernel/bpf/ 目录下面。系统调用的不同操作许可,比如,程序加载或者映射管理是在文件 syscall.c 中实现,而 core.c 包含了 解析器。其它文件的命名显而易见:verifier.c 包含 校验器(不是开玩笑的),arraymap.c 的代码用于与数组类型的 映射 交互,等等。
  • 有几个与网络(及 tc、XDP )相关的函数和 helpers 是用户可用,其实现在 linux/net/core/filter.c 中。它也包含了移植 cBPF 字节码到 eBPF 的代码(因为在运行之前,内核中的所有的 cBPF 程序被转换成 eBPF)。
  • 相关于 事件跟踪 的函数和 helpers 都在 linux/kernel/trace/bpf\_trace.c 中。
  • JIT 编译器 在它们各自的架构目录下面,比如,x86 架构的在 linux/arch/x86/net/bpfjitcomp.c 中。例外是用于硬件卸载的 JIT 编译器,它们放在它们的驱动程序下,例如 Netronome NFP 网卡的就放在 linux/drivers/net/ethernet/netronome/nfp/bpf/jit.c
  • linux/net/sched/ 目录下,你可以找到 tc 的 BPF 组件 相关的代码,尤其是在文件 act_bpf.c (action)和 cls_bpf.c(filter)中。
  • 我并没有在 BPF 上深入到 事件跟踪 中,因此,我并不真正了解这些程序的钩子。在 linux/kernel/trace/bpf\_trace.c 那里有一些东西。如果你对它感 兴趣,并且想去了解更多,你可以在 Brendan Gregg 的演示或者博客文章上去深入挖掘。
  • 我也没有使用过 seccomp-BPF,不过你能在 linux/kernel/seccomp.c 找到它的代码,并且可以在 linux/tools/testing/selftests/seccomp/seccomp\_bpf.c 中找到一些它的使用示例。

XDP 钩子代码

一旦装载进内核的 BPF 虚拟机,由一个 Netlink 命令将 XDP 程序从用户空间钩入到内核网络路径中。接收它的是在 linux/net/core/dev.c 文件中的 dev_change_xdp_fd() 函数,它被调用并设置一个 XDP 钩子。钩子被放在支持的网卡的驱动程序中。例如,用于 Netronome 硬件钩子的 ntp 驱动程序实现放在 drivers/net/ethernet/netronome/nfp/ 中。文件 nfp_net_common.c 接受 Netlink 命令,并调用 nfp_net_xdp_setup(),它会转而调用 nfp_net_xdp_setup_drv() 实例来安装该程序。

在 bcc 中的 BPF 逻辑

在 bcc 的 GitHub 仓库 能找到的 bcc 工具集的代码。其 Python 代码,包含在 BPF 类中,最初它在文件 bcc/src/python/bcc/\_\_init\_\_.py 中。但是许多我觉得有意思的东西,比如,加载 BPF 程序到内核中,出现在 libbcc 的 C 库中。

使用 tc 去管理 BPF 的代码

当然,这些代码与 iproute2 包中的 tc 中的 BPF 相关。其中的一些在 iproute2/tc/ 目录中。文件 f_bpf.cm_bpf.c(和 e_bpf.c)各自用于处理 BPF 的过滤器和动作的(和 tc exec 命令,等等)。文件 q_clsact.c 定义了为 BPF 特别创建的 clsact qdisc。但是,大多数的 BPF 用户空间逻辑 是在 iproute2/lib/bpf.c 库中实现的,因此,如果你想去使用 BPF 和 tc,这里可能是会将你搞混乱的地方(它是从文件 iproute2/tc/tc\_bpf.c 中移动而来的,你也可以在旧版本的包中找到相同的代码)。

BPF 实用工具

内核中也带有 BPF 相关的三个工具的源代码(bpf_asm.cbpf_dbg.cbpf_jit_disasm.c),根据你的版本不同,在 linux/tools/net/ (直到 Linux 4.14)或者 linux/tools/bpf/ 目录下面:

  • bpf_asm 是一个极小的 cBPF 汇编程序。
  • bpf_dbg 是一个很小的 cBPF 程序调试器。
  • bpf_jit_disasm 对于两种 BPF 都是通用的,并且对于 JIT 调试来说非常有用。
  • bpftool 是由 Jakub Kicinski 写的通用工具,它可以与 eBPF 程序交互并从用户空间的映射,例如,去展示、转储、pin 程序、或者去展示、创建、pin、更新、删除映射。

阅读在源文件顶部的注释可以得到一个它们使用方法的概述。

与 eBPF 一起工作的其它必需的文件是来自内核树的两个用户空间库,它们可以用于管理 eBPF 程序或者映射来自外部的程序。这个函数可以通过 linux/tools/lib/bpf/ 目录中的头文件 bpf.hlibbpf.h(更高层面封装)来访问。比如,工具 bpftool 主要依赖这些库。

其它值得关注的部分

如果你对关于 BPF 的不常见的语言的使用感兴趣,bcc 包含 一个 BPF 目标的 P4 编译器以及 一个 Lua 前端,它可以被用以代替 C 的一个子集,并且(用 Lua )替代 Python 工具。

LLVM 后端

这个 BPF 后端用于 clang / LLVM 将 C 编译到 eBPF ,是在 这个提交 中添加到 LLVM 源代码的(也可以在 这个 GitHub 镜像 上访问)。

在用户空间中运行

到目前为止,我知道那里有至少两种 eBPF 用户空间实现。第一个是 uBPF,它是用 C 写的。它包含一个解析器、一个 x86\_64 架构的 JIT 编译器、一个汇编器和一个反汇编器。

uBPF 的代码似乎被重用来产生了一个 通用实现,其声称支持 FreeBSD 内核、FreeBSD 用户空间、Linux 内核、Linux 用户空间和 Mac OSX 用户空间。它被 VALE 交换机的 BPF 扩展模块使用。

其它用户空间的实现是我做的:rbpf,基于 uBPF,但是用 Rust 写的。写了解析器和 JIT 编译器 (Linux 下两个都有,Mac OSX 和 Windows 下仅有解析器),以后可能会有更多。

提交日志

正如前面所说的,如果你希望得到更多的关于一些特定的 BPF 特性的信息,不要犹豫,去看一些提交日志。你可以在许多地方搜索日志,比如,在 git.kernel.org在 GitHub 上、或者如果你克隆过它还有你的本地仓库中。如果你不熟悉 git,你可以尝试像这些去做 git blame <file> 去看看介绍特定代码行的提交内容,然后,git show <commit> 去看详细情况(或者在 git log 的结果中按关键字搜索,但是这样做通常比较单调乏味)也可以看在 bcc 仓库中的 按内核版本区分的 eBPF 特性列表,它链接到相关的提交上。

排错

对 eBPF 的追捧是最近的事情,因此,到目前为止我还找不到许多关于怎么去排错的资源。所以这里只有几个,是我在使用 BPF 进行工作的时候,对自己遇到的问题进行的记录。

编译时的错误

  • 确保你有一个最新的 Linux 内核版本(也可以看 这个文档)。
  • 如果你自己编译内核:确保你安装了所有正确的组件,包括内核镜像、头文件和 libc。
  • 当使用 tc-bpf(用于去编译 C 代码到 BPF 中)的 man 页面提供的 bcc shell 函数时:我曾经必须添加包含 clang 调用的头文件:
__bcc() {
        clang -O2 -I "/usr/src/linux-headers-$(uname -r)/include/" \
                  -I "/usr/src/linux-headers-$(uname -r)/arch/x86/include/" \
                -emit-llvm -c $1 -o - | \
        llc -march=bpf -filetype=obj -o "`basename $1 .c`.o"
}

(现在似乎修复了)。

  • 对于使用 bcc 的其它问题,不要忘了去看一看这个工具集的 答疑
  • 如果你从一个并不精确匹配你的内核版本的 iproute2 包中下载了示例,可能会由于在文件中包含的头文件触发一些错误。这些示例片断都假设安装在你的系统中内核的头文件与 iproute2 包是相同版本的。如果不是这种情况,下载正确的 iproute2 版本,或者编辑示例中包含的文件的路径,指向到 iproute2 中包含的头文件上(在运行时一些问题可能或者不可能发生,取决于你使用的特性)。

在加载和运行时的错误

  • 使用 tc 去加载一个程序,确保你使用了一个与使用中的内核版本等价的 iproute2 中的 tc 二进制文件。
  • 使用 bcc 去加载一个程序,确保在你的系统上安装了 bcc(仅下载源代码去运行 Python 脚本是不够的)。
  • 使用 tc,如果 BPF 程序不能返回一个预期值,检查调用它的方式:过滤器,或者动作,或者使用 “直传” 模式的过滤器。
  • 还是 tc,注意不使用过滤器,动作不会直接附着到 qdiscs 或者接口。
  • 通过内核校验器抛出错误到解析器可能很难。内核文档或许可以提供帮助,因此,可以 参考指南 或者,万不得一的情况下,可以去看源代码(祝你好运!)。记住,校验器 不运行 程序,对于这种类型的错误,记住这点是非常重要的。如果你得到一个关于无效内存访问或者关于未初始化的数据的错误,它并不意味着那些问题真实发生了(或者有时候是,它们完全有可能发生)。它意味着你的程序是以校验器预计可能发生错误的方式写的,并且因此而拒绝这个程序。
  • 注意 tc 工具有一个 verbose 模式,它与 BPF 一起工作的很好:在你的命令行尾部尝试追加一个 verbose
  • bcc 也有一个 verbose 选项:BPF 类有一个 debug 参数,它可以带 DEBUG_LLVM_IRDEBUG_BPFDEBUG_PREPROCESSOR 三个标志中任何组合(详细情况在 源文件中)。 为调试该代码,它甚至嵌入了 一些条件去打印输出代码
  • LLVM v4.0+ 为 eBPF 程序 嵌入一个反汇编器。因此,如果你用 clang 编译你的程序,在编译时添加 -g 标志允许你通过内核校验器去以人类可读的格式去转储你的程序。处理转储文件,使用:
$ llvm-objdump -S -no-show-raw-insn bpf_program.o
  • 使用映射?你应该去看看 bpf-map,这是一个为 Cilium 项目而用 Go 创建的非常有用的工具,它可以用于去转储内核中 eBPF 映射的内容。也有一个用 Rust 开发的 克隆
  • StackOverflow 上有个旧的 bpf 标签,但是,在这篇文章中从没用过它(并且那里几乎没有与新版本的 eBPF 相关的东西)。如果你是一位来自未来的阅读者,你可能想去看看在这方面是否有更多的活动(LCTT 译注:意即只有旧东西)。

更多!

请经常会回到这篇博客中,来看一看 关于 BPF 有没有新的文章!

特别感谢 Daniel Borkmann 指引我找到了 更多的文档,因此我才完成了这个合集。


via: https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-bpf/

作者:Quentin Monnet 译者:qhwdw 校对:wxy

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

学习如何在 Apache 上托管你自己的网站,这是一个可靠、流行且易于配置的 Web 服务器。

我托管自己的网站已经有很多年了。自从 20 多年前从 OS/2 切换到 Linux 以来,我一直将 Apache 作为我的服务器软件。Apache 是可靠、流行的,且基本的安装配置也很容易。对于更复杂的设置(比如多个网站)也并不是那么困难。

Apache Web 服务器的安装和配置必须以 root 身份执行。 防火墙的配置也需要以 root 身份执行。 使用浏览器查看安装配置的结果应该以非 root 用户的身份完成。 (我在我的虚拟主机上使用 student 这个用户。)

安装

注意:我使用的实验环境是安装有 Fedora 27 的虚拟机,Apache 版本为 2.4.29。 如果您使用的是不同的发行版或不同版本的 Fedora,您的命令以及配置文件的位置和内容可能会有所不同。 但是,您需要修改的配置行是相同的。

Apache Web 服务器非常容易安装。 在我的 CentOS 6.x 服务器上,它只需要一个简单的 yum 命令。 它会安装所有必要的依赖(如果需要的话)。 我在我的 Fedora 虚拟机上使用了下面的 dnf 命令。 除了命令本身的名称之外, dnfyum 的语法是相同的。

dnf -y install httpd

这个虚拟机是个非常基础的桌面环境,我正在使用它作为编写书籍的测试平台。 即使在这个系统上,也只安装了六个依赖项,用了一分钟。

Apache 的所有配置文件都位于 /etc/httpd/conf/etc/httpd/conf.d 。网站的数据默认位于 /var/www,但如果你愿意,你可以改变它。

配置

Apache 主要的配置文件是 /etc/httpd/conf/httpd.conf 。 它包含许多在基本安装中不需要更改的配置。 实际上,只需对此文件进行一些更改即可启动并运行一个简单的网站。 该文件非常大,因此,我不会将这篇文章与大量不必要的东西混淆起来,而只会显示那些需要更改的指令。

首先,花点时间熟悉一下 httpd.conf 文件。我喜欢 Red Hat 的一个原因是它的配置文件注释非常的详细。 httpd.conf 文件也不例外,因为它有很好的注释。可以使用这些注释来了解文件的配置。

第一个要修改的是 Listen 配置项,它定义了 Apache 要监听页面请求的 IP 地址和端口。 现在,你只需要使这个网站可以从本地访问,所以使用 localhost 地址。 完成后,该行应该看起来像这样:( LCTT 译注:localhost 的 IP 地址是 127.0.0.180 是端口)

Listen 127.0.0.1:80

通过将此配置项设置为 localhost的 IP 地址,Apache 将只侦听来自本地主机的连接。 如果您希望 Web 服务器侦听来自远程主机的连接,则可以使用主机的外部 IP 地址。

DocumentRoot 配置项指定组成网站页面的 HTML 文件的位置。 该配置项不需要更改,因为它已经指向标准位置。 该行应该看起来像这样:

DocumentRoot "/var/www/html"

Apache 安装包会创建 /var/www 目录。 如果您想更改存储网站文件的位置,则使用此配置项来完成此操作。 例如,您可能想要为 www 目录使用不同的名称,以更明确地识别网站。 这可以是这样的:

DocumentRoot "/var/mywebsite/html"

这些是创建一个简单网站需要唯一修改的 Apache 配置项。 对于这个小练习,只对 httpd.conf 文件(Listen 配置项)进行了一些修改。 其它的配置项对于一个简单的 Web 服务器暂时无需配置。

另一个需要改变的地方是:在我们的防火墙中打开端口 80。 我使用 iptables 作为我的防火墙,因此我更改 /etc/sysconfig/iptables 文件以添加允许使用 HTTP 协议。 整个文件看起来像这样:

# sample configuration for iptables service
# you can edit this manually or use system-config-firewall
# please do not ask us to add additional ports/services to this default configuration
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT

我在文件的倒数第三行上添加了一个新行,它允许在端口 80 上输入流量。现在我重新加载 iptables 配置文件。

[root@testvm1 ~]# cd /etc/sysconfig/ ; iptables-restore iptables

创建 index.html 文件

index.html 文件是你使用域名访问网站而不是访问特定网页时的默认文件。在 /var/www/html中,创建一个名字为 index.html 的文件,在其中添加字符串 Hello World 。你不需要添加任何的 HTML 标志去完成这项工作。web 服务器的唯一任务是提供文本数据流,服务器不知道数据是什么,也不知道如何呈现它。它只是将数据流传输给请求主机。

保存文件后,将所有权设置为 apache.apache

[root@testvm1 html]# chown apache.apache index.html

启动 Apache

Apache 很容易启动。 当前版本的 Fedora 使用 systemd 。 运行以下命令启动它,然后检查服务器的状态:(LCTT 译注:systemctl 是一个 systemd 工具)

[root@testvm1 ~]# systemctl start httpd
[root@testvm1 ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2018-02-08 13:18:54 EST; 5s ago
     Docs: man:httpd.service(8)
 Main PID: 27107 (httpd)
   Status: "Processing requests..."
    Tasks: 213 (limit: 4915)
   CGroup: /system.slice/httpd.service
           ├─27107 /usr/sbin/httpd -DFOREGROUND
           ├─27108 /usr/sbin/httpd -DFOREGROUND
           ├─27109 /usr/sbin/httpd -DFOREGROUND
           ├─27110 /usr/sbin/httpd -DFOREGROUND
           └─27111 /usr/sbin/httpd -DFOREGROUND

Feb 08 13:18:54 testvm1 systemd[1]: Starting The Apache HTTP Server...
Feb 08 13:18:54 testvm1 systemd[1]: Started The Apache HTTP Server.

您的服务器上的命令可能不同。在使用 SystemV 启动脚本的 Linux 系统上,命令如下:

[root@testvm1 ~]# service httpd start
Starting httpd: [Fri Feb 09 08:18:07 2018]          [  OK  ]
[root@testvm1 ~]# service httpd status
httpd (pid  14649) is running...

如果您的主机上有像 Firefox 或 Chrome 这样的浏览器,您可以在浏览器的 URL 行上使用 URL localhost 来显示您的 web 页面,尽管看起来很简单。您还可以使用像 Lynx 这样的文本模式 web 浏览器来查看 web 页面。首先,安装 Lynx (如果它还没有被安装)。

[root@testvm1 ~]# dnf -y install lynx

然后使用下面的命令来显示网页。

[root@testvm1 ~]# lynx localhost

结果在我的终端中是这样的。我已经删除了页面上的很多空白。

  Hello World

<snip>


Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back.
  Arrow keys: Up and Down to move.  Right to follow a link; Left to go back.
 H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list```

接下来,编辑您的 index.html 文件并添加一些 HTML 标记,使其看起来像这样:

<h1>Hello World</h1>

现在刷新浏览器。对于 Lynx,使用组合键 Ctrl + R 。 结果看起来有点不同。如果你的终端支持彩色的话文本是彩色显示的,Lynx 会显示标题,现在它处于居中状态。 在 GUI 浏览器中,文本将以大字体显示。

                                   Hello World

<snip>


Commands: Use arrow keys to move, '?' for help, 'q' to quit, '<-' to go back.
  Arrow keys: Up and Down to move.  Right to follow a link; Left to go back.
 H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list

后记

从这个小练习中可以看到,建立一个 Apache Web 服务器很容易。 具体情况取决于您的发行版和该发行版提供的 Apache 版本。 在我的环境中,这是一个非常简单的练习。

但不仅仅如此,因为 Apache 非常灵活强大。下个月,我将讨论使用单个 Apache 托管多个网站。


via: https://opensource.com/article/18/2/how-configure-apache-web-server

作者:David Both 译者:amwps290 校对:wxy

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

我们大多数人都熟悉代理如何工作,但在基于容器的环境中有什么不同?让我们来看看有什么改变。

内联、 侧臂 side-arm 、反向和前向。这些曾经是我们用来描述网络代理架构布局的术语。

如今,容器使用一些相同的术语,但它们正在引入新的东西。这对我是个机会来阐述我最爱的所有主题:代理。

云的主要驱动之一(我们曾经有过成本控制的白日梦)就是可扩展性。在过去五年中,扩展在各种调查中面临着敏捷性的挑战(有时甚至获胜),因为这是机构在云计算环境中部署应用的最大追求。

这在一定程度上是因为在(我们现在运营的)数字经济中,应用已经成为像实体店的“营业/休息”的标牌和导购一样的东西。缓慢、无响应的应用如同商店关灯或缺少营业人员一样。

应用需要随时可用且能够满足需求。扩展是实现这一业务目标的技术响应。云不仅提供了扩展的能力,而且还提供了自动扩展的能力。要做到这一点,需要一个负载均衡器。因为这就是我们扩展应用程序的方式 :使用代理来负载均衡流量/请求。

容器在扩展上与预期没有什么不同。容器必须进行扩展(并自动扩展)这意味着使用负载均衡器(代理)。

如果你使用的是原有的代理机制,那就是采用基于 TCP/UDP 进行基本的负载平衡。一般来说,基于容器的代理的实现在 HTTP 或其他应用层协议中并不流畅,并不能在旧式的负载均衡(POLB)之外提供其他功能。这通常足够了,因为容器扩展是在一个克隆的、假定水平扩展的环境中进行的:要扩展一个应用程序,就添加另一个副本并在其上分发请求。在入口处(在入口控制器和 API 网关中)可以找到第 7 层(HTTP)路由功能,并且可以使用尽可能多(或更多)的应用路由来扩展应用程序。

然而,在某些情况下,这还不够。如果你希望(或需要)更多以应用程序为中心的扩展或插入其他服务的能力,那么你就可以获得更健壮的产品,可提供可编程性或以应用程序为中心的可伸缩性,或者两者兼而有之。

这意味着插入代理。你正在使用的容器编排环境在很大程度上决定了代理的部署模型,无论它是反向代理还是前向代理。更有趣的是,还有第三个模型挎斗模式 ,这是由新兴的服务网格实现支持的可扩展性的基础。

反向代理

反向代理最接近于传统模型,在这种模型中,虚拟服务器接受所有传入请求,并将其分发到资源池(服务器中心、集群)中。

每个“应用程序”有一个代理。任何想要连接到应用程序的客户端都连接到代理,代理然后选择并转发请求到适当的实例。如果绿色应用想要与蓝色应用通信,它会向蓝色代理发送请求,蓝色代理会确定蓝色应用的两个实例中的哪一个应该响应该请求。

在这个模型中,代理只关心它正在管理的应用程序。蓝色代理不关心与橙色代理关联的实例,反之亦然。

前向代理

这种模式更接近传统的出站防火墙的模式。

在这个模型中,每个容器 节点 都有一个关联的代理。如果客户端想要连接到特定的应用程序或服务,它将连接到正在运行的客户端所在的容器节点的本地代理。代理然后选择一个适当的应用实例,并转发客户端的请求。

橙色和蓝色的应用连接到与其节点相关的同一个代理。代理然后确定所请求的应用实例的哪个实例应该响应。

在这个模型中,每个代理必须知道每个应用,以确保它可以将请求转发给适当的实例。

挎斗代理

这种模型也被称为服务网格路由。在这个模型中,每个容器都有自己的代理。

如果客户想要连接到一个应用,它将连接到挎斗代理,它会选择一个合适的应用程序实例并转发客户端的请求。此行为与前向代理模型相同。

挎斗代理和前向代理之间的区别在于,挎斗代理不需要修改容器编排环境。例如,为了插入一个前向代理到 k8s,你需要代理一个 kube-proxy 的替代。挎斗代理不需要这种修改,因为应用会自动连接到 “挎斗” 代理而不是通过代理路由。

总结

每种模式都有其优点和缺点。三者共同依赖环境数据(远程监控和配置变化),以及融入生态系统的需求。有些模型是根据你选择的环境预先确定的,因此需要仔细考虑将来的需求(服务插入、安全性、网络复杂性)在建立模型之前需要进行评估。

在容器及其在企业中的发展方面,我们还处于早期阶段。随着它们继续延伸到生产环境中,了解容器化环境发布的应用程序的需求以及它们在代理模型实现上的差异是非常重要的。

这篇文章是匆匆写就的。现在就这么多。


via: https://dzone.com/articles/proxy-models-in-container-environments

作者:Lori MacVittie 译者:geekpi 校对:wxy

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