技术标签: 读书笔记 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
文章浏览阅读101次。4.class可以有⽆参的构造函数,struct不可以,必须是有参的构造函数,⽽且在有参的构造函数必须初始。2.Struct适⽤于作为经常使⽤的⼀些数据组合成的新类型,表示诸如点、矩形等主要⽤来存储数据的轻量。1.Class⽐较适合⼤的和复杂的数据,表现抽象和多级别的对象层次时。2.class允许继承、被继承,struct不允许,只能继承接⼝。3.Struct有性能优势,Class有⾯向对象的扩展优势。3.class可以初始化变量,struct不可以。1.class是引⽤类型,struct是值类型。
文章浏览阅读586次。想实现的功能是点击顶部按钮之后按关键字进行搜索,已经可以从服务器收到反馈的json信息,但从json信息的解析开始就会闪退,加载listview也不知道行不行public abstract class loadlistview{public ListView plv;public String js;public int listlength;public int listvisit;public..._rton转json为什么会闪退
文章浏览阅读219次。如何使用wordnet词典,得到英文句子的同义句_get_synonyms wordnet
文章浏览阅读521次。系统项目报表导出 导出任务队列表 + 定时扫描 + 多线程_积木报表 多线程
文章浏览阅读1.1k次,点赞9次,收藏9次。使用AJAX技术的好处之一是它能够提供更好的用户体验,因为它允许在不重新加载整个页面的情况下更新网页的某一部分。另外,AJAX还使得开发人员能够创建更复杂、更动态的Web应用程序,因为它们可以在后台与服务器进行通信,而不需要打断用户的浏览体验。在Web开发中,AJAX(Asynchronous JavaScript and XML)是一种常用的技术,用于在不重新加载整个页面的情况下,从服务器获取数据并更新网页的某一部分。使用AJAX,你可以创建异步请求,从而提供更快的响应和更好的用户体验。_ajax 获取http数据
文章浏览阅读2.8k次。登录退出、修改密码、关机重启_字符终端
文章浏览阅读3.8k次,点赞3次,收藏51次。前段时间看到一位发烧友制作的超声波雷达扫描神器,用到了Arduino和Processing,可惜啊,我不会Processing更看不懂人家的程序,咋办呢?嘿嘿,所以我就换了个思路解决,因为我会一点Python啊,那就动手吧!在做这个案例之前先要搞明白一个问题:怎么将Arduino通过超声波检测到的距离反馈到Python端?这个嘛,我首先想到了串行通信接口。没错!就是串口。只要Arduino将数据发送给COM口,然后Python能从COM口读取到这个数据就可以啦!我先写了一个测试程序试了一下,OK!搞定_超声波扫描建模 python库
文章浏览阅读4.2k次。端—端加密指信息由发送端自动加密,并且由TCP/IP进行数据包封装,然后作为不可阅读和不可识别的数据穿过互联网,当这些信息到达目的地,将被自动重组、解密,而成为可读的数据。不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密。2.使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。_凯撒加密
文章浏览阅读5.7k次。CIP报文解析常用到的几个字段:普通类型服务类型:[0x00], CIP对象:[0x02 Message Router], ioi segments:[XX]PCCC(带cmd和func)服务类型:[0x00], CIP对象:[0x02 Message Router], cmd:[0x101], fnc:[0x101]..._cip协议embedded_service_error
文章浏览阅读2.4k次,点赞9次,收藏13次。有时候我们在MFC项目开发过程中,需要用到一些微软已经提供的功能,如VC++使用EXCEL功能,这时候我们就能直接通过VS2019到如EXCEL.EXE方式,生成对应的OLE头文件,然后直接使用功能,那么,我们上篇文章中介绍了vs2017及以前的版本如何来添加。但由于微软某些方面考虑,这种方式已被放弃。从上图中可以看出,这一功能,在从vs2017版本15.9开始,后续版本已经删除了此功能。那么我们如果仍需要此功能,我们如何在新版本中添加呢。_vs添加mfc库
文章浏览阅读785次。用ac3编码,执行编码函数时报错入如下:[ac3 @ 0x7fed7800f200] frame_size (1536) was not respected for anon-last frame (avcodec_encode_audio2)用ac3编码时每次送入编码器的音频采样数应该是1536个采样,不然就会报上述错误。这个数字并非刻意固定,而是跟ac3内部的编码算法原理相关。全网找不到,国内音视频之路还有很长的路,音视频人一起加油吧~......_frame_size (1024) was not respected for a non-last frame
文章浏览阅读230次,点赞2次,收藏2次。创建Android应用程序一个项目里面可以有很多模块,而每一个模块就对应了一个应用程序。项目结构介绍_在安卓移动应用开发中要在活动类文件中声迷你一个复选框变量