资源分组与URL设计

在开始之前,我们先观察一下我们已经非常熟悉的Linux的文件系统的路径是如何设计的。比如

/etc/rc.d/rc.local

Linux中从根目录开始,一层一层的检索想要获取的文件。根目录的名字是 “/”,他是固定不变的,在根目录后面是根目录中的文件名称,这里的名称是rc.d/,然后以此类推,直到最终要访问的文件。

现在我需要问你一个问题,文件的名字是保存在哪里的?很多人一直以为文件的名字是保存在文件中的,但是实际上,文件仅仅保存了文件的内容,跟文件相关的其他属性都没有保存在文件中。其实文件的名字是保存在它所在的目录中的,也就是说目录其实也是文件,只是比较特殊,目录的内容就是目录中包含的文件的信息。

实际上我们计算机到硬盘中去取文件的时候根本不需要知道文件的名字或者路径,而是使用文件在硬盘上保存的位置,这个位置信息也保存在目录中。也就是说,我们在取文件的时候,首先到固定的位置获取根目录的内容,根目录中保存着根目录下的文件的名字和保存位置的映射关系,Linux通过文件名字确定第二级目录的保存位置,然后再取第二级目录的位置,直到成功获取最终文件。

通常,一个文件只会保存在一个目录下,但是,实际上,一个文件是可以同时保存在多个目录下的,这样我们可以通过多个路径对同一个文件进行操作。

因为按照路径索引需要通过文件在目录中的名字获取它的保存位置,所以同一个目录下不能有两个同名的文件,这样我们才能在一个目录下唯一的确认一个文件。

但是按照目录索引还有一个很大的缺点,那就是因为不能直接获取文件的保存位置,想要检索某个文件就变得比较困难,如果你不知道你要查找的文件的完整路径,那么计算机只能通过依次在每个目录中检查你要检索的文件是否存在来帮助你了。而搜索文件的这个过程是十分漫长的。

但是,如果你记住了每个文件的保存位置,你可以直接通过这个保存位置来获取文件,这样可以跳过所有的目录层级,直接读取文件,这比使用路径访问文件还要快,但是这样会有更大的麻烦,没有人会记住他要是用的所有文件的保存位置。

但是,我们可以两种方式都使用,我们可以先使用层级目录的方式获得文件的保存位置,如果我们需要频繁的访问这个文件,我们可以把文件的位置记录下来,下次需要访问的时候直接使用这个保存位置操作文件。

理解了上面的内容对设计URL有哪些帮助呢?

  1. 文件的路径是文件名称的层级连接
  2. 文件的保存位置在硬盘上是唯一的

借助上面两条概念,我们在设计URL的时候也可以采取同样的措施,资源的名称不再是保存在文件的记录中,而是保存在父级资源组中,这样一个URL就变成了

/根资源组名称/次级资源组名称/…./资源名称

不过这样会有另外一个问题,文件系统中只有两种文件,目录和普通文件,而URL中,每一层资源组实际上都是一种资源,而不单单是为了组成索引。所以我们会需要看到URL就能知道每一层资源组具体对应着什么,比如

/某某公司/某某部门/某某办公室/某某人

我们需要在名字上直接说明资源组的类型,这样显然是浪费口舌,还有一种办法,就是把资源组先创建普通的组再添加到上级资源组中。比如

/公司/某某/部门/某某/办公室/某某/人/某某

这样,我们认为所有的公司在同一资源组中,而所有的公司在的组在根目录下。这样我们就可以轻松的了解资源组的性质,而且不需要为所有的资源组的名字加上资源组的类型。

不过还有一个问题,就是同一级目录中不能有两个重名的资源,如果我们在根目录下放了一个资源,他的名字就叫公司,这样和公司这个资源组会冲突。所以我们在起名字的时候就会更容易重名。不过我相信不会有人傻到犯这样的错误。

先将某种类型的资源放在这种类型的资源组成的组里再将这个组添加到父级资源组中,这样目录的层级就更加深了,就需要更多次的跳转了。如果目录的层级是固定的,比如部门一定是在公司下面的,那么我们可以通过他们的关系简化这个这种跳转。在层级是固定的情况下,如果你不在乎浏览者看到URL时会困惑的话,你也可以直接使用之前的方法,省略资源名称上的类型说明,直接使用

/某某/某某/某某/某某

这种索引方式。

但是最好的办法还是直接使用资源的保存位置来获取资源,在设计URL时,这个保存位置就是资源的ID,不过不同的资源往往是保存在不同的表中的,我们需要先说明资源所在的表,通常表名和资源类型是有对应关系的,也就是说

/人/ID

可以直接说明我们要找的是谁。如果你不是特别在意资源的层级关系,这样检索还好,但是如果你同时希望原来的层级检索方式还可以用,这样的表达方式就会有歧义。

我们是要找一个资源类型为人,保存位置为ID的资源,还是在根目录下找一个类型为人,名字为ID的资源组?

我们可以通过在根目录下创建两个不同名字的目录来区别

/Indirect/公司/某某/部门/某某/办公室/某某/人/某某

/Direct/人/ID

很显然上面两种路径表示的意思是不一样的。

如果你觉得Indirect和Direct会让你的访问者困惑,你也可以通过URL参数来指定索引

/公司/某某/部门/某某/办公室/某某/人/某某

/人?id=ID

后者的目录在根目录下只有一层,很明显不是按照层级查找的。

当然你也可以混合着两种模式

/公司/不确定/部门/某某/办公室/某某/人/某某?公司id=ID

或者

/公司/某某/部门/某某/办公室/某某/人?人id=ID

甚至

/人/某某?办公室id=办公室ID

当然,这样的索引即难写又难读,不推荐混合使用。

既然我们可以使用id来所有,那么使用名字搜索其实也不是不可以

/公司/某某/部门/某某/办公室/某某/人?name=Name

这样的表示方式和

/公司/某某/部门/某某/办公室/某某/人/某某

检索的结果一样,反而描述更加复杂了,似乎没有什么必要,但是我们可以这样检索

/公司/某某/人?name=Name

很明显,这样得到的应该是某某公司里所有名字为Name的人。原来的表达方式是没法完成这样的操作的。除了要实现这样的接口,你还必须把某某公司所有的人组成一个资源组并添加到某某公司下面,当然你的接口自动按照层级依次检索也没有什么问题,只是那样要执行的操作就太多了。

使用Cobbler配置PXE服务器

之前我介绍过如何手动配置一个PXE服务器,但是手动配置PXE服务器步骤太过繁琐,而且有太多配置文件需要设置,很容易发生遗漏。幸好已经有大神帮我们解决了这个问题(我本来想写一个简单的Web代理程序,之前我在github上寻找过这样的程序,但是没有找到)。本篇文章我将尝试使用Cobbler解决手动配置PXE服务器的麻烦问题,Cobbler是一个PXE管理程序,可以用来管理镜像和kickstart配置文件等。 Cobbler 最初由 Michael DeHaan 编写,现在项目主导人是 James Cammarata, 他目前在 Ansible 公司工作。(所以我们后面还会介绍ansible的使用。)

本文使用的是CentOS 7系统,依照Cobbler官网的 quick start 进行部署,不同的系统会有少许区别,Cobbler对 red hat系的系统更加友好。

首先安装cobbler, CentOS7 原生库中没有Cobbler,可以安装epel-release库。

yum install -y epel-release

然后安装cobbler

yum install -y cobbler

请留意虽然cobbler会帮助安装tftp和httpd,但是并不会帮助安装dhcp,所以安装完成cobbler后还需要手动安装dhcp。

yum install -y dhcp

安装完成后需要进行一些必要的配置,配置文件是/etc/cobbler/settings,使用yaml格式。

1.部署后的默认密码,default_password_crypted:”$1$bfI7WLZz$PxXetL97LkScqJFxnW7KS1″

这里配置的密码是加密后的密码,你可以使用openssl passwd -1输入密码并得到加密后的密码,然后将得到的密码配置到这里。

2.server和next_server地址,server地址指的是cobbler server使用的地址,next_server地址指的是DHCP/PXE和TFTP服务器使用的地址。

3.DHCP管理和DHCP服务器模板

通过修改manage_dhcp设置是否由cobbler管理dhcp服务器,cobbler是通过生成dhcpd.conf管理dhcp服务器的,所以我们需要自行安装dhcp服务。

dhcpd.conf依据模板生成,模板文件是/etc/cobbler/dhcp.template,我们可以自定义template的内容。

cobbler将镜像保存在/var/www/cobbler/ks_mirror目录中,所以对/var目录的空间依赖很重,请确保/var目录有足够的空间。

启动Cobbler和设置自启动

使用命令

systemctl start cobblerd.service启动cobbler服务,

使用

systemctl enable cobblerd.service设置cobbler开机启动。

使用

systemctl status cobblerd.service查看cobbler服务状态。

启动cobblerd服务之前首先启动httpd服务,否则使用cobbler check检查时会报错。

systemctl start httpd

然后执行systemctl start cobblerd

cobbler check会为配置pxe服务器提供进一步的建议,你需要依照建议依次解决这些问题。处理完成后重启cobblerd服务。

systemctl restart cobblerd

反复检查并解决后,使用cobbler sync命令初始化cobbler服务。

看到任务完成后cobbler的部署就算完成了,但是不要忘了允许TFTP和HTTP通过防火墙,如果你是用firewalld防火墙,允许他们通过的操作相对简单。

firewall-cmd --add-service=tftp --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd reload

当然也不要忘了保证dhcpd tftp httpd 的正常运行。

下面我们需要添加镜像,来使用cobbler。

首先下载需要的镜像,比如我是用CentOS 7 minimal镜像

将镜像挂载到合适的目录

mount -t iso9660 -o loop,ro CentOS-7-x86_64-Minimal-1708.iso /mnt                                                                                                                                                                                                                                                                                                       

然后使用cobbler import 命令添加镜像。

cobbler import --name=CentOS7 --arch=x86_64 --path=/mnt

添加完成会可以使用cobbler distro list 查看所有发行版,使用cobbler profile list 查看所有描述。

更详细的报告使用cobbler distro report –name=CentOS7-x86_64查看。

现在我们已经可以使用PXE启动了。

但是创建system object 可以使用cobbler更多的特征。使用命令

cobbler system add –name=test –profile=CentOS7-x86_64创建systemobject。

使用cobbler system list查看列表。

使用system 可以配置更多的信息。我现在还没有用到就不做介绍了,更多内容可以到cobbler官网查看。