1、openstack image list数据流回顾
OpenStack Yoga版安装笔记(七)通过Wireshark抓包、Mermaid绘图,解析了执行openstack image list的数据流,图示如下:
- 数据流1-4:user admin认证,并获得admin token认证令牌;
- 数据流5:user admin发送请求给glance,请求image list;
- 认证令牌验证:
- 数据流6-7:glance查询memcache,是否存在admin token
- 数据流8-11:user glance认证,并获得glance token;
- 数据流12-15:glance凭着glance token,验证admin token
- 数据流16-17:把admin token存储到memcache
- 数据流18-19:glance查询glance db
- 数据流20:返回image list
从执行openstack image list命令涉及的整个数据流,可以看出openstack具有相对复杂的认证流程:
1、用户认证:
- 用户首先需要通过 Keystone 服务进行认证。Keystone 是 OpenStack 的身份服务,负责管理用户、项目、角色和权限。
- 用户通过提供用户名、密码和项目信息等凭证,获取一个认证令牌(Token)。
2、API 请求:
- 用户通过 openstack 命令行工具发送 API 请求。这个请求包含认证令牌,确保请求是经过认证的。
3、认证令牌验证:
- Glance API 服务接收到请求后,首先验证请求中的认证令牌。(首先到memcache去验证,如果没有该令牌,则到keystone去验证,keystone验证通过后,还会保存一份到memcache。)
- 认证令牌包含了用户的身份信息和权限信息,Glance API 服务会检查这些信息,确保用户有权执行请求的操作。(glance到keystone验证认证令牌之前,首先要到keystone认证自己的身份,获得自己的认证令牌)
4、权限检查:
- 在认证通过后,Glance API 服务还会检查用户是否有权限执行请求的操作。这通常涉及到检查用户的角色和项目信息。
- 例如,只有管理员或具有特定角色的用户才能列出所有镜像,而普通用户可能只能看到他们自己创建的镜像。
5、数据访问:
- 如果认证和授权都通过,Glance API 服务会查询数据库以获取镜像的元数据信息。
6、数据返回:
- Glance API 服务将查询到的镜像信息返回给用户,用户可以在命令行界面中看到这些信息。
7、进一步操作:
- 用户可以继续使用认证令牌进行其他操作,如查看镜像详细信息、创建新镜像等。
整个流程确保了只有经过认证和授权的用户才能访问和操作镜像,从而保护了系统的安全性。这种复杂的认证流程是 OpenStack 系统设计的一部分,旨在提供灵活且安全的用户访问控制。
2、openstack image save数据流练习
2.1 练习说明
镜像服务(即image service,代号为glance)主要由两部分组成:镜像元数据存储于glance数据库中,执行openstack image list命令时会查询该数据库;而实际的镜像文件则存储在glance指定的后端存储系统中,比如在这里glance服务指定的后端存储为本地文件系统。
本次练习将执行openstack image save命令,读取后端存储(在本练习中为本地文件系统),通过Wireshark抓包,观察数据流。
2.2 虚机说明
本次练习将继续在OpenStack Yoga版安装笔记(七)的controller node虚机上执行:
2.3 glance进程跟踪说明
Glance通过其内部API与本地文件系统进行交互,执行文件的创建、读取、更新和删除操作,这些操作由Glance的文件存储驱动程序处理。
可以使用strace
工具来跟踪Glance进程的系统调用,以了解它是如何与文件系统进行交互的。strace
是一个强大的命令行工具,它可以显示一个进程执行的所有系统调用及其参数和返回值,这对于调试和分析程序的行为非常有用。
1、找到Glance进程ID:
root@controller:~# ps -aux | grep glance
glance 1204 1.1 1.4 168648 121024 ? Ss 13:24 0:09 /usr/bin/python3 /usr/bin/glance-api --config-file=/etc/glance/glance-api.conf --config-dir=/etc/glance/ --log-file=/var/log/glance/glance-api.log
glance 1216 0.0 1.3 168648 105236 ? S 13:24 0:00 /usr/bin/python3 /usr/bin/glance-api --config-file=/etc/glance/glance-api.conf --config-dir=/etc/glance/ --log-file=/var/log/glance/glance-api.log
glance 1217 0.0 1.3 168648 105236 ? S 13:24 0:00 /usr/bin/python3 /usr/bin/glance-api --config-file=/etc/glance/glance-api.conf --config-dir=/etc/glance/ --log-file=/var/log/glance/glance-api.log
glance 1218 0.0 1.3 168648 105240 ? S 13:24 0:00 /usr/bin/python3 /usr/bin/glance-api --config-file=/etc/glance/glance-api.conf --config-dir=/etc/glance/ --log-file=/var/log/glance/glance-api.log
glance 1219 0.0 1.3 168648 105240 ? S 13:24 0:00 /usr/bin/python3 /usr/bin/glance-api --config-file=/etc/glance/glance-api.conf --config-dir=/etc/glance/ --log-file=/var/log/glance/glance-api.log
root 1958 0.0 0.0 4024 2100 pts/0 S+ 13:37 0:00 grep --color=auto glance
2、使用strace跟踪进程:
strace -p 1216 -o h1 &
strace -p 1217 -o h2 &
strace -p 1218 -o h3 &
strace -p 1219 -o h4 &
3、结束跟踪:
killall -9 strace
3、抓包分析
3.1 Wireshark抓包说明
1、在controller node跟踪glance进程(方法如2.3 glance进程跟踪说明)
2、建议使用MobaXterm,root登录controller node(10.0.20.11),执行:
wireshark &
抓取ens33端口的数据包,这部分主要抓取OpenStackClient和keystone、glance交互的数据包。
3、建议使用MobaXterm,root登录controller node(10.0.20.11),执行:
wireshark &
抓取lo: <loopback>端口的数据包,这部分主要抓取glance和keystone、memcache,以及glance、keystone和数据库交互的数据包。
4、在OpenStackClient(10.0.20.100)执行openstack image save命令:
ubcode@osclient ~(admin/amdin)$ openstack image save --file cirros1 cirros
ubcode@osclient ~(admin/amdin)$ ls -l cirros1
-rw-rw-r-- 1 ubcode ubcode 12716032 Jul 21 23:41 cirros1 <--已成功下载镜像
5、结束strace跟踪。将两个端口的抓包文件下载到本地电脑(前面提到win11,ip address为10.0.20.1),用本地wireshark将抓包文件进行合并(wireshar:文件->合并);将strace输出的文件h1~h4也下载到本地电脑。
3.2 抓包结果
为了方便观察数据流,可以过滤掉大量的keystone和keystone db,以及glance和glance db的MySql数据包,仅保留每次登录信息和每次的最后一个响应包(参见下面的过滤条件:mysql.user == "keystone" or mysql.user == "glance" or frame.number == 22200 or frame.number == 28304 or frame.number == 32030 or frame.number == 32613)。
OpenStackClient、keystone api、glance api之间的主要信息传输都是通过http进行的,因此可以过滤掉大量维护tcp连接的数据包。
同时,也截取了部分镜像传输的数据包(参见下面的过滤条件:!(frame.number > 32706 and frame.number < 33497))。
filter: (http or tcp.port == 11211 or tcp.port == 9292 or mysql.user == "keystone" or mysql.user == "glance" or frame.number == 22200 or frame.number == 28304 or frame.number == 32030 or frame.number == 32613) and ! (frame.number > 32706 and frame.number <33497)
3.3 抓包的流量图
3.4 glance和本地文件系统交互信息
查看strace(见2.3 glance进程跟踪说明)中的输出文件的部分内容:
openat(AT_FDCWD, "/var/lib/glance/images/429decdd-9230-49c0-b735-70364c226eb5", O_RDONLY|O_CLOEXEC) = 9
newfstatat(9, "", {st_mode=S_IFREG|0640, st_size=12716032, ...}, AT_EMPTY_PATH) = 0
ioctl(9, TCGETS, 0x7fffbe0f1c30) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(9, 0, SEEK_CUR) = 0
read(9, "QFI\373\0\0\0\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20\0\0\0\0\2\300\0\0"..., 65536) = 65536
sendto(5, "HTTP/1.1 200 OK\r\nContent-Type: a"..., 259, 0, NULL, 0) = 259
sendto(5, "QFI\373\0\0\0\3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20\0\0\0\0\2\300\0\0"..., 65536, 0, NULL, 0) = 65536
read(9, "\0\0\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
sendto(5, "\0\0\0\0\0\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536, 0, NULL, 0) = 43064
openat(AT_FDCWD, "/var/lib/glance/images/429decdd-9230-49c0-b735-70364c226eb5"解释:openat
函数被用来打开 /var/lib/glance/images/429decdd-9230-49c0-b735-70364c226eb5
这个路径的文件(即镜像文件cirros)。openat
函数调用返回了9,这意味着它成功地以指定的模式打开了文件,并且返回的文件描述符是9。这个文件描述符可以用于后续的文件操作,比如读取文件内容等。
3.5 Mermaid绘制时序图
可以用mermaid绘制时序图,方便查看:
附mermaid code:
sequenceDiagram
autonumber
participant C as OpenStackClient
participant K as keystone
participant KD as keystone DB
participant G as glance
participant GD as glance DB
participant M as memcached
participant F as Local File System
C ->> K: user admin scope to project admin, 发送username:admin/password:xxxx
Note left of C: 命令行中输入: <br/> openstack image save
K ->> KD: Keystone 查询user admin的身份
KD ->> K: ok
K ->> C: user admin身份验证成功,Keystone生成admin token
C ->> G: user admin向 glance service请求image信息,请求中包含之前从 Keystone 获取的admin token
G ->> M: glance服务接收到请求,去memcache检查请求中的admin token
Note right of M: 先检查memcached是否有admin token
M ->> G: 没有,继续去keystone检查
G ->> K: user glance scope to project service,发送username:glance/password:xxxx
Note right of G: glance首先要认证自己的身份!
K ->> KD: Keystone 查询user glance的身份
KD ->> K: ok
K ->> G: glance的身份验证成功,Keystone 生成glance token
G ->> K: glance服务将admin token发送回 Keystone,请求验证admin token的有效性,请求中包含之前从 Keystone 获取的glance token
Note right of G: glance拿着自己的token,去验证admin token
K ->> KD: Keystone 查询admin token
KD ->> K: ok
K ->> G: admin token有效,Keystone 返回给glance service
G ->> M: please store admin token
Note right of M: 保存一份到memcache
M ->> G: stored
G ->> GD: glance service根据用户的权限和角色,检索glance db
GD ->> G: 返回镜像元数据
C ->> G: 请求镜像元数据(GET /v2/images?name=cirros HTTP/1.1)
G ->> M: 验证admin token
M ->> G: 验证通过
Note right of M: Memcache已经有admin token,<br/>可以承担验证admin token的工作
G ->> C: 返回镜像元数据
C ->> G: 发出image save请求(GET /v2/images/429decdd-9230-49c0-b735-70364c226eb5/file HTTP/1.1)
G ->> M: 验证admin token
M ->> G: 验证通过
G ->> F: openat(AT_FDCWD, "/var/lib/glance/images/429decdd-9230-49c0-b735-70364c226eb5"
Note right of F: 打开镜像文件cirros
G -->> F: read镜像文件
G -->> C: 传输cirros镜像
G ->> C: 传输完成(HTTP/1.1 200 OK)