shell 命令行参数

命令行参数 $0 表示程序名。 $1 至 9则是位置参数。9则是位置参数。# 表示参数的个数。 \* 将所有参数当做一个整体来引用 @ 把每个参数作为一个字符串返回,可以使用for循环来遍历 ? 最近一个执行的命令的退出状态。0表示执行成功?最近一个执行的命令的退出状态。0表示执行成功_ 上一个命令的最后一个参数。使用快捷键 ESC+. 也是这个效果 位置参数 位置参数不止9个,更多的参数也是一样支持的。只是要使用${10}这样的形式引用。 $1 和 ${1}的效果是一样的。 不用花括号的话,$10 会被认为是 $1 和一个字符 0。 带空格的参数值 每个参数都是用空格分隔的。要在参数值中包含空格,必须要使用引号(单引号或双引号都可)。 将文本字符串作为参数传递时,引号并非数据的一部分。它们只是表明数据的起止位置。 获取脚本名 $0 表示脚本名,但是不同的调用方法返回的结果也是不同的。下面的脚本就是简单的打印$0的值:

使用 basename 命令 如果要使用脚本名称来进行判断,可以先用命令 basename 把路径的信息给过滤掉。命令的效果如下:

所以上面的脚本可以修改成这样:

测试参数 在脚本中使用参数要确保参数存在,否则运行时有可能会报错:

如果只是当做字符串引用,也不会报错。没有传参的参数默认都是空:

判断参数是否存在 在 shell 中利用 -n Read more…

kubespray安装

下载及导入镜像:

 

远程登录是自动运行 Screen

出处:http://taint.org/wk/RemoteLoginAutoScreen 在 ~/.bashrc 文件开头添加

  新建 ~/.screenrc 文件

  注: 如果你只想要自动运行 Screen 功能,中间的7行是最重要的部分; 如果愿意,您可能可以省略 “color X terminals” 和 “auto-log” 节,也即 ~/.screenrc 文件

  请教下screen滚走的怎么翻回去看? Ctrl + A,然后按一下 ESC,然后方向键

使用autossh实现反向SSH隧道

SSH隧道技术简介 首先看下图, 我们的办公电脑 在右上角, 通过公司带有防火墙功能的路由器接入互联网(当然还可能 有交换机什么的在中间连接着你和路由器, 但是在我们的问题中交换机并不起到什么关键性的作用), 或下脚的部分是一个服务器, 但是公司网络限制了登录, 右上角还有一台机器 , 是另一台可以直接办公内网登录的机器   这条通道可以用很多技术来建立 , 这里我们仅仅介绍如何使用SSH服务器来建立, 称为SSH隧道 情景1: 线路A –> B –> D 和 C –> D 是通的, 也就是笔记本可以直接登录d(172.1.2.3), 同时c(10.1.2.3)可以登录 到d(172.1.2.3), 但是A–>C和 D–>C不通,  因此我们可以利用一条已经连接好的C–>D方向的连接来完成 D–>C方向的访问. 通过机器 d建立一个通道 A –> B –> D –> C, 从而登录到c 解决办法是建立远程SSH隧道, 创建SSH反向隧道: 需要一台跳板服务器,这台服务器的SSH服务可通过公网直接访问 通过内网服务器执行SSH命令登录跳板服务器并形成反向隧道 使用SSH反向隧道: Read more…

从400错误看Nginx常见故障与修复

众所周知,Nginx是目前最流行的Web Server之一,也广泛应用于负载均衡、反向代理等服务,使用过程中可能因为对Nginx工作原理、变量含义、参数大小等问题的理解错误,导致Nginx工作异常。因此,本文将从一个Nginx错误代码400引发的故障入手,谈谈如何分析和修复常见的Nginx异常。 故障简述 小明某天中午在线优化一个敏感服务的Nginx配置时,发现5分钟内Nginx errorlog里出现了大量400错误,于是迅速回滚了Nginx配置。 故障详情 原来的Nginx配置存在重复或者需废弃的内容,于是在多次diff了新旧两份配置内容后,小明认为最新配置是不影响业务的,因此在线推送更新配置后,直接reload了Nginx,出于double check原则,在线观察了5分钟Nginx日志: 发现出现大量类似下面的400错误: 400错误的产生,很可能影响服务端或客户端的后续业务逻辑判断,因此需要引起重视。 处理过程 节点1 当时回滚配置后,小明先在搜索引擎查找了Nginx 400错误的可能原因和解决办法,初步确定有下面两种可能:1是空主机头,2是请求包头过大。 小明跟客户端同学确认了客户端请求方式,发现他们使用的是类似telnet的方式发起的http请求,类似下面的: 为了方便后续排查,小明参考线上环境临时搭建了一套Nginx测试环境,重现了故障: 后来小明了解到原来客户端不是从代码的http库调用, 而是按照上面的方式走TCP/telnet传递http参数来调用服务端http接口。但是为什么一样的客户端请求方式,旧配置完全ok,新配置则会出现大量400错误? 节点2至此,小明怀疑自己没有完全diff出新旧两份配置的差别,于是他使用vimdiff再次对比新旧两份配置。下面仅贴出关键配置: 旧配置: 新配置:   本次排查中,小明考虑的重点是新配置里遗漏了某些配置,于是他把location ~ (.*)的相关逻辑加上,发现问题依旧: 节点3 既然前面往缺失配置的思路走不通,下面就按照新增配置的思路排查,结果发现新配置增加了一些包头信息,小明怀疑是请求包过大,于是优先排查了Nginx针对包头大小的设置,其中有这么几个配置: client_header_buffer_size:默认是1k,所以header小于1k的话是不会出现问题的。 large_client_header_buffers:该命令用于设置客户端请求的Header头缓冲区的大小,默认值为4KB。 客户端请求行不能超过large_client_header_buffers指令设置的值,客户端请求的Header头信息不能大于large_client_header_buffers指令设置的缓冲区大小,否则会报“Request URL too large”(414)或者“Bad-request”(400)错误,如果客户端Cookie信息较大,则须增加缓冲区大小。于是小明将client_header_buffer_size和large_client_header_buffers都设置为128k。结果问题也重现了。 接下来,小明发现新配置中多了“proxy_set_header Host $http_host;”查找了Nginx官方文档发现跟$http_host类似功能的还有$server_name和$host等变量,在他将$http_host更换成$host后,问题修复了。 原因分析 根据Nginx官方文档介绍,400状态码含义如下: 上面是http1.1的rfc关于host部分的解释,从上面我们了解到如果一个http1.1的请求没有host域,那么server应该给client段发送400的状态码,表明这个请求server不能处理。而对于Nginx server来说,也遵循这样的方式,说明client发送了一个无效的请求,Nginx server无法处理,于是返回了400的状态码。 另外,关于$host和$http_host这两个变量的区别如下: 本次故障中,客户端的调用方式没有使用host 参数,传递了空的Host头给服务端,一旦Nginx设置了proxy_set_header Host $http_host,空Host头就传给了后端。然而,在http 1.1的规范中,Host只要出现空,就会返回400,所以出现了这个故障。而对于需要在Host字段里带上端口信息的,则仍需要配置proxy_set_header Host $http_host。 最后,需要注意的是,400错误不一样会影响业务,需要看具体的业务处理逻辑,比如使用nagios的check_tcp插件对Nginx Read more…

Ingress-Controller Troubleshooting

下午有个集群要做升级验证, 同事把developer-center的namespaces下的应用都删除重建了,后来发现paas平台打不开,查询nginx日志,应该是nginx-ingress出了问题 首先查看ingress-nginx-cotroller日志:

  可以修改deployment,使用  flag –v=XX来修改日志级别

–v=2 shows details using diff about the changes in the configuration in nginx –v=3 shows details about the service, Ingress rule, endpoint changes and it dumps the nginx configuration in JSON format –v=5 configures NGINX in debug mode 到api server的认证逻辑:

得确定下看是否是服务认证或kubeconfig导致的问题 ingress需要从 apiserver获得信息,是需要认证的,有两种认证方式: Service Account: This Read more…

Python算法

两数之和(two-sum) 这是LeetCode上一道十分经典的题目,存在多种解法,难度是简单,但后面难度更高的三数之和、四数之和,其实也是由这道题演变而来的。 题目 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/two-sum 解题 方法一: 暴力法 暴力法很逻辑很简单,采用两轮错位嵌循环,计算两个位置的数字之和是否等于目标值,因为题目中说明了只有两个整数的和是等于target,所以一旦找到直接 return 就行,十分简单粗暴。

这种写法很好理解,得益于Python语言的简洁,上面核心部分的代码甚至可以简化为一行:

因为是嵌套循环,所以时间复杂度是O(N^2N2),空间复杂度是O(1),提交了也没毛病,在所有 python 提交中击败了31.08%的用户,这种方法在运行效率上不是很高。面试时如果没有太好的思路,可以尝试用暴力法来解决。如果能在短时间内写出上面的代码,至少说明你对语言本身还是很熟练的,代码的功底也还可以。 方法二:哈希大法 正确的思路是采取空间换时间的办法,使用一个哈希表缓存。思路如下: 题目要求我们找出两个和为target的数,也就是 nums[i] Read more…

shell脚本kill掉占用cpu超过90%以上的程序

一个shell脚本,常驻登录节点,监控cpu占用率,如果某一进程占用cpu超过90%,且运行时间超过一分钟,就直接kill掉。shell脚本代码如下:

最后后台启动进程: nohup ./kill_high_cpu_proc.sh > cpucheck.log 2>&1 &

Python Django通过WebSSH操作Kubernetes Pod

通过Django调用k8s client来实现webssh登录: 涉及技术 Kubernetes Stream:接收数据执行,提供实时返回数据流 Django Channels:维持长连接,接收前端数据转给Kubernetes,同时将Kubernetes返回的数据发送给前端 xterm.js:一个前端终端组件,用于模拟Terminal的界面显示 基本的数据流向是:用户 –> xterm.js –> django channels –> kubernetes stream,接下来看看具体的代码实现 用到的模块:

关键文件: k8s.py:

consumer.py:

  出现问题: 窗口自适应的问题: cat有中文字符的文件,会卡住,报错:UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position… 原因:是k8s client python sdk的一个bug, 解决方式是修改/root/.py_env/.virtualenvs/ansible/lib/python3.9/site-packages/kubernetes/stream/ws_client.py, 修改第179行data = data.decode(“utf-8”)为:data = data.decode(“utf-8”, “replace”)  参考: https://github.com/kubernetes-client/python-base/issues/88 https://github.com/kubernetes-client/python-base/commit/15474efbaf906bf557c4a38392a0b06c95ce7841 打开webterminal页面后,容器所在机器的CPU负载会飙升,改成async异步也解决不了,官方sdk有个方法: /root/.py_env/.virtualenvs/ansible/lib/python3.9/site-packages/kubernetes/stream/ws_client.py: Read more…

定时清理垃圾进程

自动清除脚本: 具体是检测cron文件如果有修改并有此进程便进行清理