10月 172017
 

有时候,我们为了安全,禁用root账号登录,需要root的话,在普通账号登录后再sudo;也有时候,我们期望vnc桌面的时候使用的是root账号,于是,我们在普通账号sudo(或sudo -s )后启动vncserver,于是问题来了,我们vnc看到的桌面是黑色的,而且里面的窗口是没有菜单的

解决办法:

  1. 要么直接root登录后启动vncserver
  2. 要么普通账号登录时,su后启动vncserver
 Posted by at 上午 10:29

虚拟机镜像操作

 kvm, Linux & Unix, openstack  虚拟机镜像操作已关闭评论
9月 292017
 

软件包: libguestfs-tools

这里的 guestfish 挺不错的

  1. 查看镜像分区及其使用情况:
  2. 查看镜像中的文件信息
  3. copy 文件到镜像
  4. 查看镜像中的文件
  5. 查看镜像中的文件系统分区信息: virt-filesystems –long –parts –blkdevs -h -a CentOS-7-x86_64-GenericCloud-1708.raw

virt-resize:  –shrink  并不能让镜像文件变的更小(反而变大了)

virt-sparsify  可以使得一个镜像文件变成一个稀疏文件,对于发布、存储镜像很有必要

 Posted by at 下午 2:35

resolv.conf 之options都有啥

 Linux & Unix  resolv.conf 之options都有啥已关闭评论
9月 282017
 
  1. 你没法通过options来禁用ipv6解析
  2. single-request: 用来指定分别执行A和AAAA解析;即,收到A记录解析的结果后在发送AAAA记录解析请求; 默认情况下,同时在一个连接上发送A和AAAA的解析,这样效率会高一倍;然而,有些dns server不能很好地处理这种请求方式,很可能不能正确地返回AAAA的响应,以至于请求会超时
  3. single-request-reopen:强制A和AAAA的解析在两个连接中处理(主要体现在连接的源端口不同)

参考:

http://man7.org/linux/man-pages/man5/resolv.conf.5.html

 Posted by at 上午 11:44

libcgroup相关命令

 Linux & Unix  libcgroup相关命令已关闭评论
9月 262017
 

lscgroup: 列出各cgroup及其挂载点; qemu 也是通过cgroup进行资源限制的

cgsnapshot  可以列出当前各cgroup子系统的配置信息

lssubsys  列出各子系统及其挂载点

 

 

 Posted by at 下午 5:13

dd 之速度实时统计

 Linux & Unix  dd 之速度实时统计已关闭评论
9月 132017
 

dd命令正常情况下,完成之后才显示完成了多少,速度是多少;如果你感觉dd时间很长了,想知道啥时候能完成,可咋办?

man 手册中有说明: 给dd一个 USR1 信号就会打印统计信息到标准错误

这里想强调一个问题: 不管学啥,要多看文档,养成看文档的好习惯;从文档上学到的是“系统化”的东西; 从百度、google看到的都是零碎的东西

dd查看磁盘的mbr:

 Posted by at 下午 3:27

cgroup 审计策略

 docker, Linux & Unix  cgroup 审计策略已关闭评论
9月 072017
 

内存子系统

场景:

当你把一个已经占用了1GB内存的进程转移到一个新的cgroup后,新的cgroup看到的该进程使用的内存大小会是多少呢?

memory.max_usage_in_bytes  和 memory.usage_in_bytes 都不会将这1GB计算在内的,只有该进程继续申请内存才会计算新申请的内存。

同样,如果把一个占用内存很多的进程从cgroup中移出来,memory.max_usage_in_bytes  和 memory.usage_in_bytes 应该也不会被更新

Process Number Controller

  1.  pids.current 可以大于 pids.max
    1. 当cgroup中进程数量达到最大时,cgroup并不“阻止”从其它cgroup中移动一个进程到该cgroup中;只是说不允许在该cgroup中fork、clone新的进程或线程
  2. pids.current包含所有子孙cgroup中的进程(和线程)
  3. 当cgroup对进程数量不限制时,pids.max 不是0(零)也不是-1,而是字符串max😓
 Posted by at 下午 6:33

关于mlock

 Linux & Unix  关于mlock已关闭评论
9月 062017
 

mlock可以锁住一部分内存,锁住干啥?

这里的锁住的真实含义是不让交换到swap上去。

用途:

  1. real-time Application
    1. 对于实时应用来讲,就是要反应迅速,所以,事件发生后才发现内存中的数据被交换到swap上去了,那就太耽误事了
  2. 出于安全考虑
    1. 安全信息只要落地了(哪怕是被swap出来的)就容易泄露,所以,敏感信息经常mlock
  3. 就是不想swap(管我呢)

限制:

ulimit可以限制允许mlock的内存大小

查看:

cat /proc/$pid/status |grep VmLck

 

参考:
 Posted by at 上午 11:43

docker之username space

 docker, Linux & Unix  docker之username space已关闭评论
9月 062017
 

usernamespace在docker中的用法:

  1. docker 中可以通过dockerd的 –userns-remap=$username 选项来指定用户映射,从文档上来看,该选项只能使用一次,也就是说,只能指定一个用户
  2. docker 参考的用户映射关系文件为 /etc/subuid  和 /etc/subgid ,文件格式大约为:

    其中:
    bozo: 是–userns-remap 指定的用户名
    100000:65536   以为着该用户可以映射到的容器外部的uid的范围为 100000 ~ (100000 + 65536)
  3. 目前来看,不同容器中相同用户映射到容器外面的uid是相同的
  4. docker文档 要求需要映射的用户必须在容器外面是真实存在的,至少在 /etc/passwd 中是需要存在的; 从uid映射来看,/etc/passwd 中定义的uid基本是被无视的
  5. 通过–userns-remap伪造的容器内部的root用户,虽然在容器外部就是个普通用户,但是在容器内部确实是有很大的特权的
  6. docker create的 –user选项和usernamespace没有关系,只是说用哪个用户启动容器内部的进程而已
  7. 参考: https://github.com/docker/labs/tree/master/security/userns

从上面分析来看,userns-remap使用起来是比较麻烦的、且功能太有限; 我们期望不需要太多配置的情况下,不同容器中所有进程、子进程的用户都能自动映射到外部单独的uid,可能实现这个确实比较麻烦(参考下面原理部分)

 

username space原理:

  1. User Namespace是Linux 3.8新增的一种namespace
  2. clone系统调用CLONE_NEWUSER
  3. /proc/$pid/uid_map  (对于支持user namespace的内核,都存在该文件,不明确设置就为空)
  4. 当我们通过CLONE_NEWUSER去clone一个进程(或线程)的话,进程的后续行为都会参考 /proc/$pid/uid_map 来决定用户的身份,那么该uid_map 文件必然要在clone之后才能写入了;为了避免我们clone出来的那个进程很快执行到用户代码而实现提权,则往往在clone后执行的是可控的代码,在准备工作完成后在execv()去执行用户的进程(注意: execv并不改变进程号,或者说不产生新的进程,而是在当前进程空间来执行用户的代码),用户代码中很可能会继续clone,那么后续的clone如果没有CLONE_NEWUSER的话,能否参考到上面的/proc/$pid/uid_map 呢?或者说,只参考该pid namespace中init进程下面的uid_map ? (稍后继续研究)
  5. http://man7.org/linux/man-pages/man7/user_namespaces.7.html

看个例子:

 

实际问题:

在没有使用–userns-map的情况下,很多容器都使用相同的镜像(所以,相同用户名的uid基本都一样),每个容器都可以通过容器中的sshd进行登录,sshd登录后都会有相应的limits限制,以单个用户最大进程数量为例,一般来讲,root都是没有限制的,其他用户都是有限制的,对于mysql用户,通常会产生很多线程,从容器的角度来看,该用户名下的进程数量确实不多,甚至整个容器都没有几个进程,这时候,启动mysql时却是失败的;原因在于:

  1. 启动进程这事儿归根结底还是内核干的
  2. ulimit资源限制最终是从进程属性上生效的,而不是直接从配置文件上生效的
  3. 容器外部和容器内部看到的uid是相同的
  4. 其他容器已经在没有ulimit限制(或者配额足够)的情况下启动了很多mysql进程(或线程)了
  5. 最后,在ulimit限制比较小的情况下启动mysql进程(或线程)自然就会失败的
  6. 所以,从用户级别的资源限制方面来讲,容器之间的相互影响是比较难以控制的
  7. docker本来不是让作为虚拟机使用的,所以,类似问题是不会被docker官方在意(和觉察)的,docker中的–userns-map 仅仅考虑了通常情况下单个容器中只有单个(被docker-containerd启动)的进程的场景
  8. 解决办法: 给用户足够的资源
  9. 我们可以限制单个容器的进程数量:
    1. https://segmentfault.com/a/1190000007468509   https://www.kernel.org/doc/Documentation/cgroup-v1/pids.txt
    2. 通过docker create 的 –pids-limit 选项进行配置
  10. dockerd 启动选项 –default-ulimit 可以设置默认的ulimit
  11. 目前,我们生产环境使用的docker容器都是通过docker exec 启动进程的,docker exec 进去后,ulimit如下:

     

问题:

  1. 如何从容器级别限制进程数量?

参考资料:

 Posted by at 上午 10:52