技术标签: 读书笔记 linux namespace docker
Namespace其实就是一种隔离机制
,主要目的是隔离运行在同一个宿主机上的容器,让这些容器之间不能访问彼此的资源。隔离的作用:
# CentOS Linux release 8.2.2004 (Core)
$ ls -la /sbin/init
lrwxrwxrwx 1 root root 22 Jul 21 2020 /sbin/init -> ../lib/systemd/systemd
信号:Linux收到的一个通知.Ctrl+C SIGINT(2)
进程收到信号之后的处理:
特权信号【SIGKILL和SIGSTOP】就是 Linux 为 kernel 和超级用户去删除任意进程所保留的,不能被忽略也不能被捕获。那么进程一旦收到 SIGKILL,就要退出。
容器里 1 号进程对信号处理的两个要点,这也是这一讲里我想让你记住的两句话:
在容器中,1 号进程永远不会响应 SIGKILL 和 SIGSTOP 这两个特权信号;
对于其他的信号,如果用户自己注册了 handler,1 号进程可以响应。
进程限制:内核进程数限制:/proc/sys/kernel/pid_max
# 容器进程限制
/sys/fs/cgroup/pids/docker/2cfdc5833a8d07f1739978239b6d7d647b67e5b3e6cee1739239f30a210c1aee
echo 1002 > pids.max # 进程数限制
每一个 Linux 进程在退出的时候都会进入一个僵尸状态(EXIT_ZOMBIE);
僵尸进程一定需要父进程调用 wait() 或者 waitpid() 系统调用来清理,这也是容器中 init 进程必须具备的一个功能。
Containerd 在停止容器的时候,就会向容器的 init 进程发送一个 SIGTERM 信号。我们会发现,在 init 进程退出之后,容器内的其他进程也都立刻退出了。不过不同的是,init 进程收到的是 SIGTERM 信号,而其他进程收到的是 SIGKILL 信号
。
cpu限制
每个进程的 CPU Usage 只包含用户态(us 或 ni)和内核态(sy)两部分,其他的系统 CPU 开销并不包含在进程的CPU使用中,而CPU Cgroup只是对进程的 CPU 使用做了限制。
cpu.cfs_quota_us(一个调度周期里这个控制组被允许的运行时间)除以 cpu.cfs_period_us(用于设置调度周期)得到的这个值决定了CPU Cgroup每个控制组中 CPU 使用的上限值。
cpu.shares 参数,正是这个值决定了CPU Cgroup子系统下控制组可用CPU的相对比例,当系统上 CPU 完全被占满的时候,这个比例才会在各个控制组间起效。
Kubernetes中,Limit CPU 就是容器所在Cgroup控制组中的CPU上限值,Request CPU的值就是控制组中的cpu.shares的值。
CPU利用率计算
对于top命令来说,它只能显示整个节点中各项CPU的使用率,不能显示单个容器的各项 CPU 的使用率
load average:Linux进程调度器中可运行队列(Running Queue)的进程平均数和休眠队列(Sleeping Queue)里的一段时间的TASK_UNINTERRUPTIBLE状态下的进程平均数之和。
如果只考虑CPU的资源,load Average等于单位时间内正在运行的进程加上可运行队列的进程
当进程处于TASK_UNINTERRUPTIBLE状态时[D]时,此时资源(磁盘I/O、信号量等)处于竞争状态,如果很多进程处于这个等待状态,这会在应用程序的最终性能上体现出来,也就是说用户会发觉应用的性能下降了。
Cgroups 更多的是以进程为单位进行隔离,而D状态进程是内核中系统全局资源引入的,所以Cgroups影响不了它。 所以我们可以做的是,在生产环境中监控容器的宿主机节点里D状态的进程数量,然后对D状态进程数目异常的节点进行分析,比如磁盘硬件出现问题引起D状态进程数目增加,这时就需要更换硬盘。
在linux中,swappiness的取值范围在0到100,值为100的时候系统平等回收匿名内存和Page Cache内存;一般缺省值为60,就是优先回收Page Cache;即使swappiness为0,也不能完全禁止Swap分区的使用,就是说在内存紧张的时候,也会使用Swap来回收匿名内存。
在容器中,当memory.swappiness=0的时候,对匿名页的回收是始终禁止的,也就是始终都不会使用Swap空间
。[1217562.233709] Memory cgroup out of memory: Killed process 3017715 (mem_alloc)
total-vm:2060328kB, anon-rss:497240kB, file-rss:1008kB, shmem-rss:0kB, UID:0
[1217562.296557] oom_reaper: reaped process 3017715 (mem_alloc), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
#!/bin/bash
umount ./merged
rm upper lower merged work -r
mkdir upper lower merged work
echo "I'm from lower!" > lower/in_lower.txt
echo "I'm from upper!" > upper/in_upper.txt
# `in_both` is in both directories
echo "I'm from lower!" > lower/in_both.txt
echo "I'm from upper!" > upper/in_both.txt
sudo mount -t overlay overlay \
-o lowerdir=./lower,upperdir=./upper,workdir=./work \
./merged
“merged” ,它是挂载点(mount point)目录,也是用户看到的目录,用户的实际文件操作在这里进行。
“work/”,这个目录没有在这个图里,它只是一个存放临时文件的目录,OverlayFS中如果有文件修改,就会在中间过程中临时存放文件到这里。
upper的in_both.txt会覆盖lower的in_both.txt
在merged/中操作
磁盘限制容量:采用文件系统提供的quota特性。
fdisk /dev/sdb # 生成磁盘/dev/sdb1
mkfs.xfs /dev/sdb1 # 初始化文件系统
mkdir /mnt/sdb1 # 创建挂载点
mount -o pquota /dev/sdb1 /mnt/sdb1 # 挂载文件系统 一定要加上pquota标签
cat /proc/mounts|grep prj
# /dev/sdb1 /mnt/sdb1 xfs rw,seclabel,relatime,attr2,inode64,logbufs=8,logbsize=32k,prjquota 0 0
mkdir /mnt/sdb1/xfs_prjquota # 创建限制容量文件夹
xfs_quota -x -c 'project -s -p /mnt/sdb1/xfs_prjquota 101' /mnt/sdb1 # 给文件夹打上101的Project ID标记
xfs_quota -x -c 'limit -p bhard=10m 101' /mnt/sdb1 # 限制容量
dd if=/dev/zero of=/mnt/sdb1/xfs_prjquota/test.file bs=1024 count=20000 # 写入20M测试,只成功了10M
# -rw-r--r--. 1 root root 10M Jun 22 09:18 test.file
ext4不行
docker run --storage-opt size=10M -it centos bash
磁盘性能:衡量磁盘性能的两个常见的指标IOPS和吞吐量(Throughput)
dirty page:/proc/sys/vm
# docker run -d --name net_para --sysctl net.ipv4.tcp_keepalive_time=600 centos:8.1.1911 sleep 3600
7efed88a44d64400ff5a6d38fdcc73f2a74a7bdc3dbc7161060f2f7d0be170d1
# docker exec net_para cat /proc/sys/net/ipv4/tcp_keepalive_time
600
docker run -d --name if-test --network none centos:8.1.1911 sleep 36000
docker exec -it if-test ip addr
pid=$(ps -ef | grep "sleep 36000" | grep -v grep | awk '{print $2}')
echo $pid
# 在"/var/run/netns/"的目录下建立一个符号链接,指向这个容器的 Network Namespace。
# 完成这步操作之后,在后面的"ip netns"操作里,就可以用 pid 的值作为这个容器的 Network Namesapce 的标识了。
mkdir -p /var/run/netns
ln -s /proc/$pid/ns/net /var/run/netns/$pid
# Create a pair of veth interfaces
ip link add name veth_host type veth peer name veth_container
# Put one of them in the new net ns
ip link set veth_container netns $pid
# In the container, setup veth_container
ip netns exec $pid ip link set veth_container name eth0
ip netns exec $pid ip addr add 172.17.1.2/16 dev eth0
ip netns exec $pid ip link set eth0 up
ip netns exec $pid ip route add default via 172.17.1.1
# In the host, set veth_host up
ip link set veth_host up
ip addr add 172.17.1.1/16 dev veth_host
# ip addr delete 172.17.1.1/16 dev veth_host
ip link set veth_host master docker0
iptables -P FORWARD ACCEPT
# 抓包
# 容器eth0
ip netns exec $pid tcpdump -i eth0 host 39.106.233.176 -nn
# veth_host:
tcpdump -i veth_host host 39.106.233.176 -nn
# docker0
tcpdump -i docker0 host 39.106.233.176 -nn
# host eth0:
tcpdump -i eth0 host 39.106.233.176 -nn
./netperf -H 192.168.0.194 -t TCP_RR
docker run --init --name lat-test-1 --network none -d registry/latency-test:v1 sleep 36000
pid1=$(docker inspect lat-test-1 | grep -i Pid | head -n 1 | awk '{print $2}' | awk -F "," '{print $1}')
echo $pid1
ln -s /proc/$pid1/ns/net /var/run/netns/$pid1
ip link add link eth0 ipvt1 type ipvlan mode l2
ip link set dev ipvt1 netns $pid1
ip netns exec $pid1 ip link set ipvt1 name eth0
ip netns exec $pid1 ip addr add 172.17.3.2/16 dev eth0
ip netns exec $pid1 ip link set eth0 up
perf record -a -g -- sleep 60
perf script > out.perf
git clone --depth 1 https://github.com/brendangregg/FlameGraph.git
FlameGraph/stackcollapse-perf.pl out.perf > out.folded
FlameGraph/flamegraph.pl out.folded > out.sv
docker run -itd --name perf-test2 --security-opt seccomp=unconfined centos bash
# 宿主机
echo -1 > /proc/sys/kernel/perf_event_paranoid
# tracefs /sys/kernel/debug/tracing tracefs rw,relatime 0 0
cat /proc/mounts | grep tracefs
# nop
cat current_tracer
# hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop
cat available_tracers
echo function > current_tracer
# function
cat current_tracer
cat trace | more
# set_ftrace_filter 只列出想看到的内核函数,或者通过 set_ftrace_pid 只列出想看到的进程。
echo nop > current_tracer
echo do_mount > set_ftrace_filter # 过滤函数
echo function > current_tracer
echo 1 > options/func_stack_trace # 展示完整的函数调用栈
# function_graph tracer 查看每个函数的执行时间
echo '!do_mount ' >> set_ftrace_filter ### 先把之前的do_mount filter给去掉。
echo kfree_skb > set_graph_function ### 设置kfree_skb()
echo nop > current_tracer ### 暂时把current_tracer设置为nop, 这样可以清空trace
echo function_graph > current_tracer ### 把current_tracer设置为function_graph
文章浏览阅读1.8k次,点赞4次,收藏6次。python简易爬虫v1.0作者:William Ma (the_CoderWM)进阶python的首秀,大部分童鞋肯定是做个简单的爬虫吧,众所周知,爬虫需要各种各样的第三方库,例如scrapy, bs4, requests, urllib3等等。此处,我们先从最简单的爬虫开始。首先,我们需要安装两个第三方库:requests和bs4。在cmd中输入以下代码:pip install requestspip install bs4等安装成功后,就可以进入pycharm来写爬虫了。爬
文章浏览阅读2.6k次。解决方法:解决方法可以去github重新下载一个pyflakes.vim。执行如下命令git clone --recursive git://github.com/kevinw/pyflakes-vim.git然后进入git克降目录,./pyflakes-vim/ftplugin,通过如下命令将python目录下的所有文件复制到~/.vim/ftplugin目录下即可。cp -R ...._freetorn.vim
文章浏览阅读210次,点赞7次,收藏3次。本文简述了hello.c源程序的预处理、编译、汇编、链接和运行的主要过程,以及hello程序的进程管理、存储管理与I/O管理,通过hello.c这一程序周期的描述,对程序的编译、加载、运行有了初步的了解。_hit csapp
文章浏览阅读1w次,点赞2次,收藏27次。来源:机器人小妹 很多时候企业拥有重复,乏味且困难的工作流程,这些流程往往会减慢生产速度并增加运营成本。为了降低生产成本,企业别无选择,只能自动化某些功能以降低生产成本。 通过数字化..._人工智能平台
文章浏览阅读2.2k次。热加载能够在每次保存修改的代码后自动刷新 electron 应用界面,而不必每次去手动操作重新运行,这极大的提升了开发效率。安装 electron 热加载插件热加载虽然很方便,但是不是每个 electron 项目必须的,所以想要舒服的开发 electron 就只能给 electron 项目单独的安装热加载插件[electron-reloader]:// 在项目的根目录下安装 electron-reloader,国内建议使用 cnpm 代替 npmnpm install electron-relo._electron-reloader
文章浏览阅读942次。在11.0 进行定制化开发,会根据需要去掉recovery模式的一些选项 就是在device.cpp去掉一些选项就可以了。_android recovery 删除 部分菜单
文章浏览阅读2.2k次,点赞2次,收藏6次。继续上次的echart博客,由于省会流向图是从echart画廊中直接取来的。所以直接上代码<!DOCTYPE html><html><head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /&_java+echart地图+物流跟踪
文章浏览阅读1.4k次。一、OSD模块简介1.1 消息封装:在OSD上发送和接收信息。cluster_messenger -与其它OSDs和monitors沟通client_messenger -与客户端沟通1.2 消息调度:Dispatcher类,主要负责消息分类1.3 工作队列:1.3.1 OpWQ: 处理ops(从客户端)和sub ops(从其他的OSD)。运行在op_tp线程池。1...._ceph 发送数据到其他副本的源码
文章浏览阅读7.9k次,点赞3次,收藏22次。一 定义这是最早出现的置换算法。该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。该算法实现简单,只需把一个进程已调入内存的页面,按先后次序链接成一个队列,并设置一个指针,称为替换指针,使它总是指向最老的页面。但该算法与进程实际运行的规律不相适应,因为在进程中,有些页面经常被访问,比如,含有全局变量、常用函数、例程等的页面,FIFO 算法并不能保证这些页面不被淘汰。这里,我_进程调度fifo算法代码
文章浏览阅读133次。rownum是oracle才有的写法,rownum在oracle中可以用于取第一条数据,或者批量写数据时限定批量写的数量等mysql取第一条数据写法SELECT * FROM t order by id LIMIT 1;oracle取第一条数据写法SELECT * FROM t where rownum =1 order by id;ok,上面是mysql和oracle取第一条数据的写法对比,不过..._mysql 替换@rownum的写法
文章浏览阅读790次,点赞3次,收藏4次。官网下载下载链接:http://www.eclipse.org/downloads/点击Download下载完成后双击运行我选择第2个,看自己需要(我选择企业级应用,如果只是单纯学习java选第一个就行)进入下一步后选择jre和安装路径修改jvm/jre的时候也可以选择本地的(点后面的文件夹进去),但是我们没有11版本的,所以还是用他的吧选择接受安装中安装过程中如果有其他界面弹出就点accept就行..._ecjelm
文章浏览阅读245次。原文链接:https://linux.cn/article-7801-1.htmlifconfigping <IP地址>:发送ICMP echo消息到某个主机traceroute <IP地址>:用于跟踪IP包的路由路由:netstat -r: 打印路由表route add :添加静态路由路径routed:控制动态路由的BSD守护程序。运行RIP路由协议gat..._ifconfig 删除vlan