使用AFS, Active Directory和SSSD搭建用于集成电路设计的分布式存储系统 【十四】部署第一台 AFS 服务器 3

使用AFS, Active Directory和SSSD搭建用于集成电路设计的分布式存储系统 【十四】部署第一台 AFS 服务器 3

  • 安装和配置 Kerberos 客户端
    • 安装 Kerberos 客户端
    • 配置 Kerberos 客户端
    • 测试 Kerberos 客户端
  • 安装 AFS 程序
    • 两种安装方式
    • 配置 YUM 源
    • 安装依赖程序
    • 安装 OpenAFS RPM 程序包
  • 配置第一台 AFS 服务器:服务器端的配置
    • 检查和修剪 Long Term Key (Service Keytab)
    • 导入 Long Term Key
      • 为OpenAFS 1.6.x 导入密钥
      • 为OpenAFS 1.8.x 导入密钥
    • 启动 bosserver
    • 设定 Cell 名称
    • 告知 AFS 服务 Kerberos Realm 的名称
    • 配置和启动 Database 服务进程
    • 配置 System Control Machine 进程
    • 配置自动创建用户只读备份的 cron 进程
    • 创建 AFS 系统管理员账号
    • 配置和启动 File Server
    • 创建顶层目录对应的 AFS Volumes
    • 将AFS 服务绑定到指定的网口

安装和配置 Kerberos 客户端

在 AFS 的工作原理里我们已经介绍过,AFS 基于 Kerberos 协议对客户进行身份验证。我们也介绍过 Kerberos 协议的认证过程,我们强调过,在这个过程中,AFS 服务器并不需要和 KDC 进行实时通信,和 KDC 进行通信的是 AFS 客户端。既然如此,为什么需要在 AFS 服务器上安装和 KDC 通信用的 Kerberos 客户端呢?

因为我们同时需要在 AFS 服务器上安装 AFS 客户端(Cache Manager). 事实上这将是我们这个 Cell 的第一个客户端。之所以需要在 AFS 服务器上也安装 Cache Manager,我们也已经在前文解释过。既然客户端需要使用 Kerberos 对用户做身份验证,那么我们就需要安装和配置 Kerberos 客户端。

安装 Kerberos 客户端的另一个原因是我们可能会需要使用它提供的一些命令工具来查看和修改 Kerberos 密钥文件(keytab),比如 klistktutil 命令。我们在前文中也解释过,AFS 服务本身需要在 KDC 里注册一个 Long Term Key,并且我们已经在准备工作里描述过这个 Long Term Key 的导出过程。 当我们将这个 Long Term Key 拷贝到第一台 AFS 服务器上时,我们通常都需要查看和确认一下这个 Long Term Key 文件的内容是否符合需要,如果有必要,我们可能需要修剪一下这个文件的内容。这时 Kerberos 客户端提供的 klist 和 ktutil 命令就会十分方便。

安装 Kerberos 客户端

不同的操作系统有不同的方式来安装 Kerberos。比如 MacOS 就随系统自带 Kerberos的客户端实现。而对于很多 Linux 发行版,都可以从包管理软件里下载和安装 MIT Kerberos 或者 Heimdal Kerberos 的实现,或者直接下载和编译源代码。

对于 CentOS 7,可以使用如下命令安装 Kerberos 客户端:

[xmsguan@afsdb1 ~]$ sudo yum install krb5-workstation

配置 Kerberos 客户端

安装完成以后,我们需要配置这个客户端,至少我们需要告诉 Kerberos 客户端,我们的 Kerberos Realm 是什么名字,其 KDC 服务器在哪个地址。
和很多 Linux 程序一样,Kerberos 客户端的配置是通过修改一个配置文本文件的形式进行,这个文件的默认地址一般是:

/etc/krb5.conf

这个文件一般已经有默认的内容。我们需要修改的主要是 [realm],[domain_realm] 以及 [libdefaults] 里的参数值。对我们这个例子,这几个部分至少应该包含如下内容:

[libdefaults]
 default_realm = AD.COMPANY.COM
 dns_lookup_realm = true
 dns_lookup_kdc = true
 ticket_lifetime = 24h
 renew_lifetime = 31d
 forwardable = true
 default_ccache_name = KEYRING:persistent:%{uid}

[realms]
 AD.COMPANY.COM = {
  admin_server = ad.company.com
  kdc = ad.company.com
 }

[domain_realm]
 .ad.company.com = AD.COMPANY.COM
 ad.company.com = AD.COMPANY.COM

注意上面的参数中 ticket_lifetime 和 renew_lifetime 参数给出的是申请获得Kerberos ticket 的有效期。实际获得的有效期除了取决于此处客户端的设定,还取决于服务端 KDC 本身的设定。如果 KDC 本身只允许最多 8 小时的有效期,那么即使此处要求 24 小时的有效期,实际可以获得的 ticket 的有效期也只有 8 小时。

对于使用 Active Directory 作为 KDC 的情形,Kerberos ticket 有效期可以由域管理员在域的默认组策略里设定。

另外,Kerberos 默认使用 UDP 端口 88 进行通信。系统管理员应该确认服务器的防火墙设定允许其使用88端口向 KDC 发起 UDP 通信。

测试 Kerberos 客户端

安装和配置完成客户端后,应该使用 kinit 命令来确认是否可以从 KDC 获得身份验证 ticket,并确认 ticket 的加密算法和有效期是否符合预期。比如:

[xmsguan@afsdb1 ~]$ kinit xguan
Password for [email protected]:
[xmsguan@afsdb1 ~]$ klist -e
Ticket cache: KEYRING:persistent:1008:1008
Default principal: [email protected]

Valid starting       Expires              Service principal
05/20/2020 02:57:33  05/20/2020 20:57:33  krbtgt/[email protected]
        renew until 06/20/2020 02:57:29, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96
[xmsguan@afsdb1 ~]$

在上面这个例子里,我们以 Kerberos Principal 用户名 xguan 进行身份验证,在输入密码以后,我们用 klist 命令查看获得的 ticket。这个 ticket 的初始有效期有 18 个小时,但允许用户续期。每次续期可以再获得 18 个小时有效期,直至1个月为止。这个 ticket 是以 AES256 算法加密的。

至此 Kerberos 客户端就安装和配置好了。同样的过程可以用于其他所有 AFS 客户端和服务器的安装。

安装 AFS 程序

两种安装方式

和很多开源软件一样,OpenAFS 的安装大致可以遵循两种方式:

  • 从下载源代码进行编译和安装
  • 从Linux 发行版的包管理器下载和安装编译好的程序。

对于在 CentOS 7 上安装 OpenAFS,这两种方式的结果有一些区别

第一种方式是从 OpenAFS 的官方网站下载最新版本的源代码并编译安装。在本文成文的时代,OpenAFS 的主版本是 1.8, 同时传统的 1.6 版本仍然在更新。读者可以从其官方网站上下载相应的源代码包,阅读相应的编译安装说明来进行安装。另外,如果读者偏好先编译成 rpm 再进行安装,下面的连接提供了从源码编译 rpm 的说明
https://wiki.openafs.org/devel/HowToBuildOpenAfsRpmPackages/

第二种方式是使用 CentOS 携带的 YUM 包管理器从可以信赖的源站点下载已经提前编译好的 rpm 文件进行安装。University of Michigan 的系统程序开发员 Jonathan S. Billingsjsbillings)创建并维护着一个供 CentOS 和 Fedora 使用的 OpenAFS rpm 源。其地址如下:
https://copr.fedorainfracloud.org/coprs/jsbillings/openafs/

这是笔者推荐的安装方式。Jsbillings 在编译 OpenAFS 源码时采用了和开发者提供的 rpm spec 文件不一样的一份 spec。其结果是 RPM 安装的目录与直接编译源码得到的安装目录不一样。Jsbillings 设置的安装目录路径更符合 RHEL / CentOS 的习惯。比如,AFS 服务器端的配置文件存储目录在源代码方式下是

/usr/local/etc/openafs/server

或者更为传统的Transarc 路径

/usr/afs/etc

而在 jsbillings 提供的 RPM 包里,或者 Debian 源提供的安装包里,AFS 服务器端配置文件的存储目录是

/etc/openafs/server

又比如,AFS 客户端默认的缓冲区路径在源代码安装方式下是

/usr/vice/cache

而在 jsbillings 提供的 RPM包里,Cache Manager 的缓冲区默认路径是

/var/cache/openafs

在操作系统安装的介绍里,我们已经使用了 jsbillings 风格的路径来挂载缓冲区所需要的磁盘分区。

除了路径风格不一样,jsbillings 编译的 RPM 包还提供基于 DKMS 方式的客户端内核模块。使用这种方式安装内核模块初次花费的时间比较长,但好处是当系统升级内核时,不需要重新编译和安装 Cache Manager 的内核模块。

我们将使用 jsbillings 源提供的 RPM 包为例来说明 OpenAFS 的安装与配置。

配置 YUM 源

以 CentOS 7 为例,下载 jsbillings 提供的 YUM Repo 文件

https://copr.fedorainfracloud.org/coprs/jsbillings/openafs/repo/epel-7/jsbillings-openafs-epel-7.repo

并放置于YUM 的源目录下

/etc/yum.repos.d/

则系统将可以从该 YUM 源自动获得最新版本的 OpenAFS RPM 包。

安装依赖程序

OpenAFS 依赖于几个程序包。其中最主要的程序包含 dkms, kernel-devel 和 kernel-headers. kernel-devel 和kernel-headers 的版本号必须和当前系统运行的内核版本号严格一致。而dkms 可以从CentOS 的 epel-release 源获得。(在其他 Linux 发行版里这些程序包的名字可能略有不同。)

安装epel-release 源

[xmsguan@afsdb1 ~]$ wget https://copr.fedorainfracloud.org/coprs/jsbillings/openafs/repo/epel-7/jsbillings-openafs-epel-7.repo

[xmsguan@afsdb1 ~]$ sudo mv jsbillings-openafs-epel-7.repo /etc/yum.repos.d/

[xmsguan@afsdb1 ~]$ sudo yum install epel-release

然后安装 dkms

[xmsguan@afsdb1 ~]$ sudo yum install dkms

接着安装kernel-devel 和 kernel-headers

[xmsguan@afsdb1 ~]$ sudo yum install kernel-devel kernel-headers

需要注意的是,如果上述命令得到的版本号与当前系统使用的内核版本号(可以使用uname -r 查询获得)不一致,则必须手动指定与内核版本号一致的包安装。这可以使用下面命令来实现:

yum install "kernel-devel-uname-r == $(uname -r)"

安装 OpenAFS RPM 程序包

上述依赖程序都安装完成以后,就可以继续安装 AFS 服务端程序包和客户端程序包了。以下命令将同时安装这两类程序包:

[xmsguan@afsdb1 ~]$ sudo yum install dkms-openafs openafs openafs-client openafs-docs openafs-krb5 openafs-server

注意 dkms-openafs 是内核模块,其安装包含了编译过程,所以耗时较长,需要耐心等待。一切顺利的话,YUM 会报告安装完成。

安装过程中最常见的异常是缺少依赖包,这可以通过安装相应的依赖包解决。另一个异常是缺少 kernel-devel或者 kernel-headers 包,这往往是由于当前运行的内核版本和这两个包的版本不一致导致。

注意初次安装完上述程序包以后,Cache Manager 的内核模块只是安装到位,但还没有加载到当前内核中。为了验证内核模块的状态,读者可以使用以下命令来确认其DKMS模块已经安装到位,但当前加载的内核模块列表里还没有包含AFS:

[xmsguan@afsdb1 ~]$ dkms status
openafs, 1.8.3-1.el7, 3.10.0-957.21.3.el7.x86_64, x86_64: installed
[xmsguan@afsdb1 ~]$ lsmod |grep afs
[xmsguan@afsdb1 ~]$

当我们配置完 OpenAFS 客户端、将其 service 进程安排到启动加载列表里并重启系统以后,再执行上述命令时,lsmod 命令将显示openafs已经加载。不过在这之前,我们需要先配置 OpenAFS 服务器端。

配置第一台 AFS 服务器:服务器端的配置

在前文里我们已经介绍了第一台 AFS 服务器上将要运行的各类 AFS 服务进程,以及第一台 AFS 服务器所扮演的多重角色。现在我们已经安装了这些服务的可执行程序,到了配置这些服务的时候。

OpenAFS 的配置是构成部署挑战的一个障碍。从上一节可以看到,程序包的编译和安装本身并不困难。但是初次配置服务系统管理员却往往会遇到错误或异常。这主要由两种原因导致:

  1. OpenAFS 的各类服务是相互耦合、相互依赖的有机整体。从无到有配置这些服务时,系统管理员却不得不分出先后顺序。如果顺序选择不当,就可能出现服务找不到相应信息的异常和错误。这就好比要求系统管理员厘清先有鸡还是先有蛋的问题。本文介绍的顺序可以帮助系统管理员客服这个障碍。
  2. OpenAFS 的部署命令本身可能在特定时代或某个版本存在一些缺陷,导致按照官方说明配置 Cell 时仍然出现异常或错误。这是因为部署 OpenAFS 所需要的一些专用命令,比如 bos setcellname “年久失修”,比较少受到开发者的关注。究其主要原因,OpenAFS 从无到有的部署频率很少。就像笔者在前文提到的那样,由于OpenAFS 服务十分稳定且伸缩性极强,很少需要推倒重来。一个有经验的AFS 系统管理员在其职业生涯里可能都不会部署超过10次。由此带来的问题是用户社区很少有人会关注部署专用的那些命令,当版本演进功能升级时,这些命令出现异常的情况很少被发现,而发现以后也往往很少被反馈。

笔者建议读者在部署 AFS Cell 遇到异常或错误时,不要跳过去执行往后的步骤,而尽量当场解决问题。因为这些错误如果得不到解决,可能会在后续使用中带来意想不到的结果。当问题难以解决时,建议读者在 OpenAFS 邮件社区里提出问题,自然会有开发者或系统管理员帮助诊断和解决。

注意在下文里,我们将默认使用 jsbillings 提供的 RPM 程序包所指定的 OpenAFS 配置路径。比如

/etc/openafs/server

将包含涉及 AFS 服务端进程的配置文件。

如果读者采用了其他方式安装 OpenAFS,这些路径可能不一样。读者应该先确认配置文件所在的路径,再进行配置。

检查和修剪 Long Term Key (Service Keytab)

在前文里我们已经介绍了如何生成和导出 AFS 服务器需要使用的 Long Term Key,并且指出这个文件相当于 AFS 服务的密码,存储和拷贝需要十分小心。

我们假设读者已经找到一种安全的方式将这个文件 rxkad.keytab 拷贝到了 AFS 服务器上。下面我们需要告诉 AFS 服务进程使用这个文件包含的密钥来提供 AFS 服务,即将密钥导入 AFS 服务。

在导入密钥文件rxkad.keytab之前,读者应该检查一下密钥的基本内容。
一个密钥文件里可能包含多个密钥。如果读者严格采用了我们前文描述的密钥导出方式,即在执行ktpass命令时,将参数 /crypto 的值明确指定为AES256-SHA1,则导出的密钥文件只包含一个密钥,不需要额外的修剪操作。但是如果读者将 /crypto 参数指定为 all, 或者在 AES256-SHA1 以外增加了其他参数值,那么需要特别注意,密钥文件里不应该包含DES算法的密钥

在本文成文时,因为DES算法已经被认为不再安全,1.6 版本的 OpenAFS 在使用本文介绍的密钥导入流程过程中会检查密钥文件里是否包含了 DES算法的密钥,如果存在则会引起密钥文件导入失败。这个失败有时不会立刻出现在导入操作的结果里,而会在下一步设定 Cell 名称时出现(比如报错 ticket contained unknown key version number,参见 https://lists.openafs.org/pipermail/openafs-info/2014-January/040388.html)

检查密钥文件内容的另一个实际原因是我们需要确认导入密钥的版本号,英文称为 key version number, 缩写为 kvno. KDC (域控制器)数据库里的每一个账号都有一个 kvno,初始值为1。每当一个账号的密钥发生改变,该账号的 kvno就会自动增加1。密钥文件里的每一个密钥也都伴有该密钥导出时的 kvno,这个数字必须和 KDC (域控制器)数据库里保存的 kvno 一致。显然,密钥文件里的 kvno 需要和 KDC 里保存的 kvno一致,否则密钥就是老的,已经失效。在导入密钥时 AFS 需要知道 kvno 的值。因此如果读者在导出密钥时没有记录下文件里的 kvno,现在需要查看一下文件内容,获得 kvno 备用。

查看和修剪密钥文件的内容可以使用随 Kerberos 客户端一起安装的工具ktutil。使用以下命令启动ktutil:

# /usr/bin/ktutil

启动以后使用命令 read_kt 读入密钥文件:

ktutil: read_kt rxkad.keytab

然后使用命令 list 查看密钥文件里的所有密钥,这时每一个密钥的加密方式和 kvno 就会显示出来

ktutil: list -e
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1    6   host/[email protected] (aes256-cts-hmac-sha1-96)
   2    6   host/[email protected] (camellia256-cts-cmac)
   3    3   HTTP/[email protected] (aes256-cts-hmac-sha1-96)
   4    3   HTTP/[email protected] (camellia256-cts-cmac)

如果需要删除一个条目(比如 DES 算法的密钥),可以使用 delete_entry命令删除该条目,只需要指定要删除的 slot号:

ktutil: delete_entry 1
ktutil: list -e
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
   1    6   host/[email protected] (camellia256-cts-cmac)
   2    3   HTTP/[email protected] (aes256-cts-hmac-sha1-96)
   3    3   HTTP/[email protected] (camellia256-cts-cmac)

最后用命令 write_kt 将修剪完的密钥保存成文件

ktutil: write_kt rxkad.keytab
ktutil: quit

上面的例子里我们的密钥文件包含了其他各种算法的密钥。如果读者严格遵照我们之前的介绍导出了密钥文件,则只会看到一个密钥。此时应该记录下这个密钥的 kvno,我们即将使用。

导入 Long Term Key

取决于用户安装的 OpenAFS 版本,这个步骤略有不同。

为OpenAFS 1.6.x 导入密钥

如果用户安装的是 1.6.x 版本的 OpenAFS,则用户只需要将修剪完毕的密钥文件拷贝到

/etc/openafs/server 

目录下,并确认该文件的名字严格是 rxkad.keytab即可。OpenAFS 1.6.x 会自动侦测和使用该文件。

为OpenAFS 1.8.x 导入密钥

如果用户安装的是 1.8.x 版本的 OpenAFS,则传统的 asetkey命令重新恢复使用,用户需要用这个命令来导入 rxkad.keytab文件里的密钥。这里就可能出现前文提到的某些命令“年久失修”的问题。

在本文成文前不久(OpenAFS 1.8.3 及以前的 1.8.x版本),asetkey 命令仍然要求预先准备好另外两个Server端的配置文件,分别是

/etc/openafs/server 

下的 ThisCell 文件和 krb.conf 文件。如果这两个文件没有准备好, 导入密钥使用的 asetkey 命令会在执行时报错。

OpenAFS 推荐使用 bos setcellname 来创建和设定 ThisCell 文件的内容。但是执行 bos_setcellname 又要求密钥已经导入。这就造成了先有鸡还是先有蛋的死循环。

解决该问题并不困难。krb.conf 和 ThisCell 两个文件都是十分简单的文本文件,可以直接通过文本编辑器创建和修改。

krb.conf 文件的作用是告知 AFS 服务进程需要使用的 Kerberos Realm 的名字。这个文件只需要包含 Kerberos Realm 名称。如果该文件不存在,可以手动创建和填入文件内容。在我们的例子里,这个文件的内容就是:

[xmsguan@afsdb1 /etc/openafs/server]$ cat krb.conf
AD.COMPANY.COM
[xmsguan@afsdb1 /etc/openafs/server]$

另一个文件 ThisCell 的作用是设定 Cell 名称。如果该文件不存在,现在可以手动创建和填入文件内容,即 Cell 的名称。在前文里我们已经提到过,Cell 名称的选择是部署一个 AFS 系统最重要的决定之一。此时就是使用该名称的时候。将名称填入ThisCell文件以后可以确认文件内容:

[xmsguan@afsdb1 /etc/openafs/server]$ cat ThisCell
hq.company.com
[xmsguan@afsdb1 /etc/openafs/server]$

以上两个文件创建好以后,可以使用 asetkey 命令导入密钥了。asetkey 命令需要用户提供 kvno,还需要用户提供密钥的加密算法 etype 号. 读者在 ktutil 命令里已经得到密钥的加密算法,每一个允许的算法在 Kerberos 协议里都对应一个 etype 值,常用的值可以在下面链接提供的表格里查看,也可以查看 Kerberos 源代码的头文件获得。对于我们的情况,Active Directory 导出的 AES256 密钥的 etype 值一般是 18.

https://www.opencore.com/blog/2017/3/kerberos-encryption-types/

现在我们可以使用asetkey 命令来导入密钥

[xmsguan@afsdb1 ~]$ asetkey list
All done.
[xmsguan@afsdb1 ~]$ sudo asetkey add rxkad_krb5 4 18 ./rxkad.keytab afs/hq.company.com
[sudo] password for xmsguan:
[xmsguan@afsdb1 ~]$ ls /etc/openafs/server/
CellServDB  KeyFile  KeyFileExt  krb.conf  ThisCell  UserList
[xmsguan@afsdb1 ~]$

上面的例子里,我们的 kvno 是 4,读者应根据自己的实际 kvno 值替换这个数字。

注意在 OpenAFS 1.8.x版本里,命令正常执行以后会生成 KeyFileExt 文件。

密钥的导入是 OpenAFS 部署中关键的一步。系统管理员应该保证这一步正常完成以后再执行其他步骤。

启动 bosserver

完成密钥导入步骤以后,就可以启动第一个服务进程—— bosserver. 我们在前文已经介绍过,bosserver 进程类似 AFS 服务器上的大管家,它负责监视和协调其他 AFS 服务器进程。bosserver 守护进程启动以后,我们就可以执行主命令 bos 以下的子命令,其中就包括设定 Cell 名称的子命令 setcellname.

bosserver 启动时会检查其配置文件并根据配置文件来启动和安排其他服务进程。bosserver 的配置文件叫 BosConfig. 如果使用 jsbilling 编译的安装源,该文件的路径是

/etc/openafs/BosConfig

默认情况下这是一个空文件,bosserver 不会启动其他进程。我们在当前步骤就只需要 bosserver 本身。

有两种方式可以启动 bosserver,一是以 root 身份直接运行 bosserver 命令,二是以 root 身份启用 OpenAFS 服务器端的服务脚本,由该服务脚本启动 bosserver。在 CentOS 7或 RHEL 7 里,我们安装 OpenAFS 服务器软件包的过程中就会安装该服务脚本。

[xmsguan@afsdb1 ~]$ ls /usr/lib/systemd/system/openafs-*
/usr/lib/systemd/system/openafs-client.service  /usr/lib/systemd/system/openafs-server.service
[xmsguan@afsdb1 ~]$

在上面的例子里我们可以看到,随 OpenAFS 安装包安装的 systemd 服务脚本有两个,

  • 服务器端的单元文件 openafs-server.service,
  • 客户端的单元文件 openafs-client.service.

我们现在启用服务器端的脚本,以后服务器重启时就会自动启动bosserver,并由后者启动所有配置好的 AFS 服务进程。

[xmsguan@afsdb1 ~]$ sudo systemctl enable openafs-server.service
Created symlink from /etc/systemd/system/multi-user.target.wants/openafs-server.service to /usr/lib/systemd/system/openafs-server.service.
[xmsguan@afsdb1 ~]$ sudo systemctl start openafs-server.service
[xmsguan@afsdb1 ~]$

系统管理员应该使用 systemctl status 命令检查 openafs-server 的状态,确保服务已经正常启动。另外也可以直接检查进程列表,查看是否有 bosserver 进程在运行。

如果服务没能正常启动,应该检查密钥导入是否成功。另外如果 SELinux 没有设定成 Permissive 模式,也可能会导致 bosserver 启动失败。

设定 Cell 名称

我们在准备工作里已经介绍过,选择合适的 Cell 名称是系统管理员需要做出的最重要的决定之一。关于如何选取 Cell 名称,读者可以参考前文介绍。

如果安装的 OpenAFS 版本是 1.8.x ,在导入 Long Term Key的步骤里,已经手动设定了 ThisCell 文件的内容。如果安装的 OpenAFS 版本是 1.6.x, ThisCell 文件的内容还没有更新。

无论哪种情况,现在都到了正式设定 Cell 名称的时候。

执行这一步操作的前提是 bosserver 已经顺利启动。如果有任何原因导致 bosserver 没能正常启动,系统管理员应该止步于此,重新回到之前的步骤,检查和修改自己的环境,直到 bosserver 进程顺利启动。

如果bosserver 已经顺利启动,则现在可以使用 bos setcellname 来设定 Cell 名称,该命令会指使已经运行在后台的bosserver 进程更新

/etc/openafs/server/ThisCell 

文件和服务器端CellServDB文件

/etc/openafs/server/CellServDB

设定 Cell 名称这种操作显然是需要系统管理员权限才能执行的操作。但目前我们还没有配置 Protection Database Server 服务(ptserver),更不用谈创建系统管理员账户和获取 AFS token,如何向已经启动的bosserver 进程证明我们是系统管理员呢?这显然又是一个先有鸡还是先有蛋的问题。我们需要临时绕过该权限要求。

如何做到这一点呢?AFS 为所有的管理员命令提供了一种机制,允许系统管理员在不登录自己的 AFS 管理账号、没有获得 AFS token 的情况下执行管理操作。这个机制基于这样一个事实:正常情况下只有系统管理员才能成为 AFS 服务器的 root。而只有 AFS 服务器的 root 可以访问存储在 AFS 服务器本地硬盘的 /etc/openafs/server 目录下的密钥文件 KeyFile和KeyFileExt的内容。因此 AFS 为绝大部分管理操作设定了一个参数 -localauth。使用这个参数时,命令在执行期间会先从

/etc/openafs/server 

下抽取密钥文件的内容,并以此密钥文件向正在运行的 AFS 服务器进程证明自己的管理员身份。

显然,只有具有 AFS 服务器管理权限的人才能使用 -localauth 参数。一般的用户使用这个参数是无效的,因为他们没有访问 /etc/openafs/server 目录下任何文件的权限。

另外也很显然,-localauth 参数只能在登录到 AFS 服务器以后才能使用,一般的 AFS 客户端没有密钥文件,所以无法在普通 AFS 客户端上使用 -localauth 参数。因此,系统管理员可以通过登录到 AFS 服务器、获取 root 权限、并在执行命令时增加 -localauth 参数的方式,绕过 AFS token 的要求。

我们现在就是要在第一台刚刚导入 AFS 密钥的 AFS 服务器上使用 -localauth 参数来执行设定 Cell 名称这样的系统管理员操作。执行命令的过程如下:

[xmsguan@afsdb1 ~]$ sudo bos setcellname afsdb1.test.company.com hq.company.com -localauth
[sudo] password for xmsguan:
[xmsguan@afsdb1 ~]$ cat /etc/openafs/server/ThisCell
hq.company.com[xmsguan@afsdb1 ~]$ cat /etc/openafs/server/CellServDB
>hq.company.com        #Cell name
10.10.10.7    #afsdb1.test.company.com
[xmsguan@afsdb1 ~]$

可以看到, bos setcellname 命令的第一个参数是目标服务器的地址,第二个参数是 Cell 名称,第三个参数就是 -localauth。同时可以从上面的运行结果看到,在命令正常执行以后,

/etc/openafs/server/ThisCell
/etc/openafs/server/CellServDB

两个文件的内容都已经得到更新。

如果不使用该命令,则系统管理员需要手动更改这两个文件的内容来设定 Cell 名称。

手动修改 CellServDB 文件内容是 AFS 不提倡、不鼓励的行为,因为初学者很容易误解文件的格式。比如很多人会将上面这个例子里服务器 IP 地址一行 # 后的内容当作无关紧要的注释,或者忘记 Cellname前的大于号(>)。这些都是常见的错误。

我们推荐读者按照本步骤介绍的方式,以 bos setcellname 命令来设定 Cell 名称

此外,如果在执行命令过程中出现了下面例子里的错误,则有可能是因为 rxkad.keytab文件里包含了 DES 密钥,而读者安装的是 1.6.x 版本的 OpenAFS 的缘故。读者需要回到前面检查和修剪 Long Term Key的步骤,确认 rxkad.keytab 密钥文件里没有 DES 密钥。

[xmsguan@afsdb1 ~]$ sudo bos setcellname afsdb1.test.company.com hq.company.com -localauth
[sudo] password for xguan: 
bos: failed to set cell (ticket contained unknown key version number)

告知 AFS 服务 Kerberos Realm 的名称

设定完 Cell 名称以后,就该设定该 Cell 所使用的 Kerberos Realm 名称。这可以通过更新

/etc/openafs/server/krb.conf 

文件的内容来实现。如果系统管理员安装的是 OpenAFS 1.8.x 版本,可能在导入密钥时已经完成了该步骤。如果没有,则现在应该设定该文件的内容。

[xmsguan@afsdb1 ~]$ cat /etc/openafs/server/krb.conf
AD.COMPANY.COM
[xmsguan@afsdb1 ~]$

配置和启动 Database 服务进程

现在到了配置和启动 AFS Database 服务进程的时候。根据我们在准备阶段的介绍,这些进程包括 ptserver, vlserver, 以及 buserver. 至于 AFS Database 服务进程是什么,读者可以阅读前文关于 AFS 工作原理 的介绍来了解它们的作用。

我们通过更新 bosserver 的配置文件

/etc/openafs/BosConfig

来增添运行在 AFS 服务器上的各个进程。这个文件也有自己专用的格式,这个格式里,每一个服务进程或者服务进程组被称为一个 bnode.

学习和掌握 BosConfig 的格式虽然不难,但也需要时间和精力,另外手动修改 BosConfig 文件出现错误的机会也比较大,所以 AFS 开发者也提供了一个 bos 子命令来帮助系统管理员自动更新 BosConfig 的内容,这个命令是 bos create

类似于 bos setcellname 命令,bos create 命令也必须由系统管理员权限才能执行。因此该命令也提供 -localauth 参数。

在创建每一个服务进程时,我们可以为该进程设定参数,以优化每个服务进程的性能。在这里我们需要特别提到的参数是 -rxmaxmtu。 在前文里我们已经解释过路径 MTU 对 AFS 服务的影响。现在我们需要使用在准备工作中已经测得的 Path MTU 的数值,并用 -rxmaxmtu 参数来告知服务进程这个数值。

下面的例子里,我们使用 bos create 命令配置了上述三个Database 服务进程及它们的启动参数。

[xmsguan@afsdb1 ~]$ sudo bos create afsdb1.test.company.com ptserver simple “/usr/libexec/openafs/ptserver -rxmaxmtu 1344” -localauth

[xmsguan@afsdb1 ~]$ sudo bos create afsdb1.test.company.com vlserver simple “/usr/libexec/openafs/vlserver -rxmaxmtu 1344” -localauth

[xmsguan@afsdb1 ~]$ sudo bos create afsdb1.test.company.com buserver simple “/usr/libexec/openafs/buserver” -localauth

上述命令中, simple 参数指明我们要创建的 BosConfig 服务进程条目的类型是 simple 类型,即简单的单进程服务。除了 simple 类型的条目, BosConfig 还有两外两个类型的条目,分别是 fscron. 我们将在创建文件服务进程组和 cron 计划任务时使用这些类型。

系统管理员可以进一步阅读 BosConfig 的官方文档熟悉该配置文件的格式和内容,以便在记录创建以后进一步优化和调整每条记录的参数。
https://docs.openafs.org/Reference/5/BosConfig.html

配置 System Control Machine 进程

在前文里我们已经介绍过 System Control Machine 这个角色的功能。执行到这一步的读者应该可以看出

/etc/openafs/server

这个目录下包含的文件是所有 AFS 服务器都需要的配置信息,包括密钥文件,ThisCell 文件,krb.conf 文件以及服务器端的 CellServDB 文件。所以这个目录应该在所有 AFS 服务器之间保持同步。我们将第一台 AFS 服务器配置成这个目录的 System Control Machine,以后每增加一台 AFS 服务器时,我们就将其配置成从第一台 AFS 服务器上自动获取和更新这个目录的内容。

我们通过在第一台 AFS 服务器的 BosConfig 文件里增加一条 upserver 条目、在之后每一台新增的 AFS 服务器的 BosConfig 文件里增加一条 upclient 条目的方式来实现上述目的.

[xmsguan@afsdb1 ~]$ sudo bos create afsdb1.test.company.com upserver simple "/usr/libexec/openafs/upserver -crypt /etc/openafs/server" -localauth
[xmsguan@afsdb1 ~]$

值得注意的是我们要求 upserver 服务使用 -crypt 参数,即对

/etc/openafs/server

目录的分发和更新必须进行信源加密,以避免密钥文件的内容在进行分发时以明文的方式出现在网络里。

执行完本步以后,系统管理员可以使用 bos status 命令来查看已经创建的服务的运行情况:

[xmsguan@afsdb1 ~]$ bos status afsdb1.test.company.com
bos: running unauthenticated
Instance ptserver, currently running normally.
Instance vlserver, currently running normally.
Instance buserver, currently running normally.
Instance upserver, currently running normally.
[xmsguan@afsdb1 ~]$

系统管理员应该在此时确认以上服务都已正常启动。如果结果不是如此,则应该重新检查部署操作,直到得到以上结果以后再进行下面的步骤。

配置自动创建用户只读备份的 cron 进程

在前文里我们介绍过为用户个人目录的 AFS Volume 创建只读备份、并将其挂载在用户个人目录的

.OldFiles 

路径下的意义。

我们也已经介绍过 AFS 服务器上可以运行的 AFS Cron 服务进程。

现在我们假设所有的用户个人目录对应的 AFS Volume 的名称都包含前缀 user. 比如用户 xguan 的个人目录对应的 AFS Volume 的名称为 user.xguan。我们可以创建一个 AFS Cron 服务,在每天凌晨 4 点的时候,为所有前缀是 user 的 AFS Volumes 更新只读备份。我们同样通过增加 BosConfig 文件的条目的形式来实现,只是现在这个条目的类型不再是 simple, 而是 cron.

xmsguan@afsdb1 ~]$ sudo bos create afsdb1.test.company.com backupusers cron -cmd "vos backupsys -prefix user -localauth" "4:00" -localauth

可以看到,我们要定期执行的命令其实是 vos backupsys,而这个命令同样需要管理员权限。我们并不希望系统管理员每天凌晨 4 点都为这个命令的执行输入密码,所以使用了 -localauth 参数。这也意味着这样的 cron 服务进程只能配置在包含了密钥文件的 AFS 服务器上。

注意这个服务将按照服务器本地时区的时间来执行。如果用户不在一个时区,系统管理员可以考虑在每个时区的一台 AFS 服务器上部署一个 cron 进程,只为该时区的用户创建系统备份。比如只为前缀名是 user.cn 的用户创建系统备份。

需要指出的另一点是,虽然 cron 服务只配置在一台 AFS 服务器上,实际进行备份的服务器则可能有很多台。还以上面的例子进行说明。每天凌晨4点时,这台 AFS 服务器将代表系统管理员发出 vos backupsys 命令,而接到这个命令的每一台 AFS File Server 都会检查存储在本地的 AFS Volume,只要有 AFS Volume 的前缀名是 user, 则 AFS File Server 就会为其更新只读备份。我们的第一台 AFS 服务器只是扮演了发出命令和收集结果的角色,而不一定实际创建备份。我们也解释过,AFS 只读备份的创建和更新在每一台 AFS File Server上都是一个十分高效廉价的操作,并不包含实际的文件复制,更不包含文件通过网络的传输。所以上述 cron 服务进程虽然可能涉及很多台 AFS File Server,涵盖很多个 AFS Volume,但正常情况下其执行却可以很快完成。

创建 AFS 系统管理员账号

在配置和启动了 ptserver 服务进程以后,我们现在可以创建 AFS 系统管理员账号了。操作之前,我们提醒读者再次确认一下前文提到的准备条件是否已经做好,尤其是 AFS 系统管理员账号 (本例为xguanafsadmin)应该已经作为一个用户存在于 Active Directory 里。

系统管理员账号将是我们创建的第一个用户账号。在创建该账号之前,我们有一个预备工作需要完成,即将 AFS Protection Database 里的起始 AFS ID 从默认的1提高到2000。这样做的原因我们已经在前文介绍过。

查看当前起始 AFS ID的命令是 pts listmax,而修改这个值的命令是 pts setmax. 这是我们第一次使用 pts 主命令,故名思意,这个命令涉及的是和 Protection Database Server (ptserver)相关的操作。同样,这个命令支持 -localauth 参数。

[xmsguan@afsdb1 ~]$ sudo pts listmax -localauth
[sudo] password for xmsguan:
Max user id is 0 and max group id is -205.
[xmsguan@afsdb1 ~]$ sudo pts setmax -user 2000 -localauth
[xmsguan@afsdb1 ~]$ sudo pts listmax -localauth
Max user id is 2000 and max group id is -205.
[xmsguan@afsdb1 ~]$

以上操作完成以后,我们就可以使用 pts createuser 命令来创建我们的第一个 AFS 账号了。在我们这个例子里,这个账号的名字是 xguanafsadmin,读者可以使用其他账号名,前提是账号已经在 Active Directory 里创建完成。我们同样需要使用 -localauth 参数来临时获得管理员权限,否则这就是一个典型的先有鸡还是先有蛋的问题(创建管理员账号需要管理员权限,而获得管理员权限需要系统已经创建了管理员账号)。

[xmsguan@afsdb1 ~]$ sudo pts createuser -name xguanafsadmin -localauth
User xguanafsadmin has id 2001
[xmsguan@afsdb1 ~]$ sudo pts adduser xguanafsadmin system:administrators -localauth
[xmsguan@afsdb1 ~]$ sudo bos adduser afsdb1.test.company.com xguanafsadmin -localauth
[xmsguan@afsdb1 ~]$ sudo pts member system:administrators -localauth
Members of system:administrators (id: -204) are:
  xguanafsadmin
[xmsguan@afsdb1 ~]$ sudo cat /etc/openafs/server/UserList
xguanafsadmin
[xmsguan@afsdb1 ~]$

在上面的操作里,我们使用了 pts adduser 命令将新创建的账号加入了 system:administrators 这个组(关于这个组的意义我们在前文里已经介绍)。另外,我们还使用了 bos adduser 命令,将新创建的账号加入了文本配置文件 UserList.

一个用户自然人要成为完全意义上的 AFS 系统管理员,必须同时具备以下三个要件

  1. 拥有一个属于 system:administrators 组的 AFS 账号。
  2. 上述 AFS 账号在每一台 AFS 服务器里都列举在 UserList 文件里。
  3. 用户具有每一台 AFS 服务器的管理员权限(root 或者 sudo)。

上述操作实现了1、2两点,而系统管理员此时已经具备第3点,所以一个完全的 AFS 系统管理员账号就诞生了。

值得注意的是,UserList 文件也位于

/etc/openafs/server 

目录下,因为在前面的步骤里我们已经配置了 upserver 进程,所以这个文件会被自动分发和同步到其他 AFS 服务器上。将来如果需要添加或删除系统管理员,只需要修改 System Control Machine 即这台 AFS 服务器上的 UserList 文件,则其他 AFS 服务器会通过他们配置的 upclient 进程自动获得更新。

我们此时还不能使用刚刚创建的账号登录系统,因为我们还没有准备好 AFS 客户端,一旦第一个 AFS 客户端配置和启动完成,我们就可以使用上述账号登录 AFS,进行维护和管理操作。

配置和启动 File Server

我们介绍过,AFS Database Server 和 File Server 可以分别独立存在,一台 Database Server 可以不运行 File Server 服务进程而成为一个纯粹的 Database Server。但是在绝大多数情况下,作为第一台 AFS 服务器的Database Server 同时也应该被配置成第一台 AFS File Server。 原因很简单,我们在创建 Cell 时需要创建和初始化顶层目录。创建顶层目录的操作涉及创建两个最基本的 AFS Volume, 分别是 root.afsroot.cell . 如果没有 AFS File Server,我们就无法完成顶层目录的初始化,创建的工作就不算完成。所以我们现在需要配置和启动 File Server 相关的服务进程。

配置 File Server 同样是通过向 BosConfig 文件里增加记录来实现。有所不同的是,我们现在需要增加的是一组进程而不是单个进程,它们需要在一起协同工作。 BosConfig 文件为此专门定义了一个记录类型,即 fs 型记录,和前面提到的 simple 类型与 cron 类型的记录并列存在。

需要指出的是,dafileserver 进程作为文件服务的关键进程,其性能对 AFS 服务的质量具有重要意义。这个进程有很多优化参数,这些参数的具体取值随着时代的变迁和硬件的进步也不断改变。我们在这里提供一些适用于当前时代的比较典型的参数值。系统管理员可以进一步阅读 dafileserver的文档,结合自己的实践进一步优化这些参数。

我们仍然使用 bos create 命令来创建 File Server 服务进程组:

[xmsguan@afsdb1 ~]$ sudo bos create afsdb1.test.company.com \
> dafs dafs -cmd \
> "/usr/libexec/openafs/dafileserver -p 123 -L -busyat 200 -l 163840 -s 524288 -rxpck 2000 -cb 4000000 -vattachpar 128 -vlrumax 8 -vhashsize 20 -vc 1000 -b 600 -udpsize 16777216 -sendsize 2097152 -rxmaxmtu 1344" \
> "/usr/libexec/openafs/davolserver -p 64 -log" \
> "/usr/libexec/openafs/salvageserver" \
> "/usr/libexec/openafs/dasalvager -parallel all32" \
> -localauth
 [sudo] password for xmsguan:
[xmsguan@afsdb1 ~]$

另外指出一点,OpenAFS 1.8.2 版本的 dafileserver 对于参数 -vlruthreshold 的解析存在一个 bug,这个 bug 已经在之后的版本中修正。

以上命令执行完以后,应该再次使用 bos status 命令查看运行的 AFS 服务进程,确认操作正确完成:

[xmsguan@afsdb1 ~]$ sudo bos status afsdb1.test.company.com -localauth
Instance ptserver, currently running normally.
Instance vlserver, currently running normally.
Instance buserver, currently running normally.
Instance upserver, currently running normally.
Instance backupusers, currently running normally.
    Auxiliary status is: run next at Sun Jul 21 04:00:00 2019.
Instance dafs, currently running normally.
    Auxiliary status is: file server running.

注意需要保证新增的 dafs 进程组已经正常运行,如上所示。如果 File Server 服务进程没能正常启动,则系统管理员应该回头排查可能存在的问题,直到该进程启动正常为止。

File Server 进程启动以后会自动侦测和初始化之前创建的 /vicepa, /vicepb 等分区。现在这些分区从现在开始就完全置于 AFS 服务进程的控制之下。

创建顶层目录对应的 AFS Volumes

执行到这里, Volume Location Database Server 和 File Server 服务进程都已经启动,我们就可以创建最顶层目录对应的两个 AFS Volume 了。这两个 Volume 的名称不是任意的,而必须采用 AFS 规定的名称,分别是root.afsroot.cell,前者对应 /afs 目录,后者对应 /afs/hq.company.com 目录。

创建 AFS Volume 的命令是 vos create. 这是我们第一次手动使用 vos 主命令。故名思意,vos 处理的是所有和 AFS Volume 相关的操作。所有的 Volume 操作都需要 AFS 系统管理员权限,因此 vos 命令也都支持 -localauth 参数。我们现在还没有客户端,也就不能使用已经创建的 AFS 管理员账号登录,所以我们还是需要使用 -localauth 参数来获得足够的权限。

下面的示例显示了创建和查看这两个 AFS Volumes 的过程:

[root@afsdb1 logs]# vos create afsdb1.test.company.com a root.afs -localauth
Volume 536870912 created on partition /vicepa of afsdb1.test.company.com
[root@afsdb1 logs]# vos create afsdb1.test.company.com a root.cell -localauth
Volume 536870915 created on partition /vicepa of afsdb1.test.company.com
[root@afsdb1 logs]# vos listvol afsdb1.test.company.com -localauth
Total number of volumes on server afsdb1.test.company.com partition /vicepa: 2
root.afs                          536870912 RW          2 K On-line
root.cell                         536870915 RW          2 K On-line

Total volumes onLine 2 ; Total volumes offLine 0 ; Total busy 0

上面的示例里,我们使用了 vos listvol 命令来列举一台 AFS File Server 上的所有 AFS Volume. 除此以外 vos 还包括了很多强大的子命令,我们在前文里提到的很多 AFS 系统管理员最钟爱的命令—— vos move 也是 vos 主命令下的子命令。

将AFS 服务绑定到指定的网口

在前文里我们介绍过,很多服务器的网卡都有多个 Ethernet 接口,因而一台服务器可以得到多个 IP 地址。在默认情况下当一台服务器有多个 IP 地址时(multi-homed),AFS会同时服务于这多个 IP 地址。大多数情况下这不是我们需要的。AFS 允许系统管理员在一台多 IP 地址的服务器上指定一个或多个 IP 地址作为 AFS 服务的地址。这可以在部署时通过配置 NetInfoNetRestrict 这两个配置文件实现(https://docs.openafs.org/AdminGuide/HDRWQ138.html)。

如果第一台 AFS 服务器有多个 IP 地址,现在就应该将 AFS 服务绑定到指定的 IP. 这可以通过创建和编辑文本配置文件

/var/openafs/NetInfo 

来实现。在这个文件里,我们只列举提供 AFS 服务的 IP 地址。修改完成以后,可以确认其内容。比如以本文的例子,其内容是:

[root@afsdb1 openafs]# cat /var/openafs/NetInfo
10.10.10.7
[root@afsdb1 openafs]#

完成本步以后,系统管理员可以重启服务器。重启完成以后应该查看 openafs-server.service 服务是否已经正常启动,并使用 bos status 命令确认系统重启以后所有配置的 AFS 服务进程是否能够自动启动并正常运行。如果一切顺利,则第一台 AFS 服务器的服务器端配置就完成了。下面我们将对客户端进行简要配置,以便系统管理员登录到 AFS 客户端执行 Cell 初始化的相关维护与管理操作。

你可能感兴趣的:(AFS)