每一次故障排查都是一笔财富, 各种狗血经过不表, 解决问题之后的那种满足是不可替代的.
背景
发布系统架构图简化如下:
管理员通过 Jenkins 调用 "发布程序 (代号 varian, 以下简称 varian)", 发布程序会进行一系列的初始化操作, 完成后生成 Docker 镜像上传到 Docker 仓库, 容器集群更新镜像, 用户通过负载均衡访问我们的容器集群.
老的 varian 采用 shell+python 开发, 配合 Jenkins(jdk1.7) 进行发布, 因内部项目较多, 写了很多兼容脚本, 代码比较乱. 我们计划对 varian 进行重构, 完全采用 python 开发, 各个功能模块化, 不同类型的项目用乐高的思想拼装模块部署发布, 降低耦合. 并将 jenkins 升级到最新版本, jdk 同样升级到 1.8. 新的 varian 已经开发完成, 现在开始部署测试了, 故事就由此开始.
为了降低对现有项目的影响决定重新部署一套新的环境, 完全测试通过后将老环境废弃, 直接启用新环境, 新环境信息如下:
系统: Debian8
语言: Python3.4
JDK1.8 + Jenkins2.134
故障处理过程
解决 nginx 访问 403 的问题
通过 Jenkins 调用 varian 正常部署了一个静态项目 (纯 html,CSS,js 等静态资源), 通过负载均衡访问容器集群 (参考上边架构图), 发现页面样式无法加载, 浏览器按 F12 调出控制台发现个 CSS 文件返回 403 状态
web 服务用的 nginx, 脑海里迅速过了一遍什么情况下 nginx 会返回 403:
nginx 配置了白名单, client 端访问的 IP 不在白名单内
- allow 192.168.0.152;
- deny all;
访问的路径是个目录, 而 nginx 配置了禁止列目录
- #nginx 中这个配置默认就是 off, 改成 on 当访问的路径是目录时, 可以列出目录中的内容
- autoindex off;
访问的路径是个文件, 但 nginx 服务配置的用户和用户组对文件没有读取权限
- #nginx 中这个配置指定 nginx 服务的用户和用户组
- user www-data www-data;
目录索引 index 配置错误, 例如你的目录下只有 index.html, 你却配置了 index.shmtl 或 index.php 等等
index index.shtml index.php;
常见的有以上问题会导致 nginx 返回 403, 迅速排查了一下, 发现就是权限的问题导致的, nginx 配置的用户和用户组为 www-data, 而 css 文件的属主属组都是 root, 且其他用户没有任何权限
- # cat /etc/nginx/nginx.conf
- user www-data www-data;
- # ls -lh csl.css
- -rw-r----- 1 root root 7.9K Jul 24 12:34 csl.css
这里再详细讲解下 linux 下的文件权限, 以上边的 csl.css 文件为例:
-rw-r----- 1 root root 7.9K Jul 24 12:34 csl.css
以空格分割
第一段 - rw-r-----10 个字符定义了文件的权限
第一个字符, 这里为 - 代表这是一个文件, 还会看到像 d 代表目录, l 代表连接
剩下九个字符, 每三个一组, 第 2-4 个字符代表属主权限, 第 5-7 个字符代表属组权限, 第 8-10 个字符代表其他用户的权限
其中每一组三个字符分别为 r,w,x, 用数字表示 r=4,w=2,x=1, 分别代表读, 写, 执行权限, 如果这个字符有值表明有这个权限, 例如上边 css 文件的权限就为属主有 rw 读写权限, 属组只有 r 权限, 其他用户没有权限
第二段为一个数字, 表示文件的连接数
第三段 root 表示用户的属主为 root
第四段 root 表示用户的属组也为 root
第五段则表示文件大小
后边三段为修改时间
最后一段为文件名
好了, 接着上边的故障说, 已经找到了是因为文件权限的问题导致的 403, 那么修改了文件的权限为 644(其他用户有读取权限), 再次访问顺利返回正常状态了. 问题就这么结束了吗? 当然不能, 仔细想想为啥其他的文件权限都 ok, 就这个文件权限不对? 接着找原因
tomcat8 UMASK
经过反复测试, 发现我直接在 linux 下通过控制台执行 python 脚本的方式发布部署最终文件权限正常, 但是同样的脚本经过 Jenkins 执行后权限就不对了.
控制台执行跟 Jenkins 执行有什么区别? 账号不一样啊, 遂把 jenkins 项目, tomcat 文件都改成属主属组都为 root 重新执行, 发现还是一样的结果.
再想想还有哪里不对, 这个 css 文件是程序生成的, 生成的文件权限不对, umask! 这个词突然蹦出来, 对, 应该就是 umask, 他控制了生成新文件的权限.
简单介绍下什么是 umask:
umask 值用来设置用户在创建文件时的默认权限, 跟设置文件权限命令 chmod 是相对的, 总共四位, 不过我们通常只用后三位, 同样对应属主属组以及其他用户的权限, 例如你的账号 umask 值为 0022(可直接通过 umask 命令查看), 此时你创建的文件权限默认为 644(文件初始的最高权限为 666,umask 设置为 022, 那么最终的权限为: 6-0,6-2,6-2=644. 当然有人说文件的权限最高是 777, 是的没错, 但我们说的是默认权限, 默认权限是由 umask 决定的, umask 设置为 000 时文件的权限就是 666, 文件夹权限 777), 此时创建的目录权限为 755(目录的最高权限为 777,umask 设置为 022, 那么最终的权限为 7-0,7-2,7-2=755)
- - -
查了 root 用户的 umask,jenkins 用户的 umask, 都为 0022, 没问题呀, 并且登录这两个账号创建了新文件权限也都正常, 就剩下一种情况了 Jenkins!
Jenkins 没有地方可以给配置 UMASK,Jenkins 跑在 tomcat 容器里, 老版本的 varian 也有相似的处理逻辑一直没问题, 本次升级了 tomcat8, 难道 tomcat8 更新了 UMASK? 半信半疑的看了下, 果然! tomcat8 的 umask 默认改成了 0027, 麻溜的改成了 0022, 问题顺利解决
- # vi tomcat/bin/catalina.sh
- if [ -z "$UMASK" ]; then
- UMASK="0027"
- fi
来源: https://www.cnblogs.com/37Y37/p/9361470.html