【taskset詳解】
taskset設置cpu親和力,taskset能夠將一個或者多個進程綁定到一個或者多個處理器上運行
參數:
選項:
 -a, --all-tasks 在給定 pid 的所有任務(線程)上操作
 -p, --pid 在給定 pid 上操作
 -c, --cpu-list 以列表格式顯示和指定 CPU
 -h, --help 顯示此幫助
 -V, --version 輸出版本信息
案例:設置nginx cpu親合力
在conf/nginx.conf中,
worker_processes 4;用來配置 nginx啟動幾個工作進程 的,默認為1,而nginx還支持一個名為worker_cpu_affinity的配置項,也就是說nhinx可以為每個工作進程綁定CPU,
worker_cpu_affinity 00000001 00000010 00000100 00001000 ;
這里0001,0010, 0100, 01000是掩碼,分別代表第1,2,3,4等四顆cpu核心;
如果要想綁定nginx進程的cpu,首先要查看nginx的進程ID,隨后將對應的ID取出來,通過taskset -cp 指定cpu核心數以及進程號即可
# ps -ef | grep nginx    查看nginx的主進程ID號
root 2304 1 0 13:07 ? 00:00:00 nginx: master process nginx
[root@nginx-web02 ~]# taskset -cp 0,2 2304       #設置cpu親和力,讓nginx的主進程跑cpu1和cpu3上面
pid 2304's current affinity list: 0-3     #未綁定之前是跑在所有1-4個cpu上面
pid 2304's new affinity list: 0,2          #綁定之后,只跑在cpu1和cpu3上面
另外我們可以通過taskset -cp 【進程號】查看某服務的進程ID跑在拿個CPU上面,如下所示

【設置docker容器cpu親和力】
# docker run -itd --name centosv2 --cpuset-cpus 1-2 49f7960eb7e4 #通過“--cpuset-cpus“參數,讓一個容器進程只在cpu2-3上面運行
我們可以在"/sys/fs/cgroup/system.slice/"這個目錄查看docker容器生成的綁定cpu核心數
#cat /sys/fs/cgroup/cpuset/system.slice/docker-e5ea5af23654a142518c3076395ff02a6ff2869708b59852abaf84614a70d665.scope/cpuset.cpus 
1-2
進程容器測試
可以通過docker exec (容器ID或者名稱)taskset -cp (1容器內部第一個編號一般為1),可以看到容器進程與CPU綁定關系,可以認為達到了綁定CPU內核的目的
# docker exec centosv2 taskset -cp 1
pid 1's current affinity list: 1,2
【cpu配額控制參數的混合使用】
在上面的參數中,cpu-shares控制只發生在容器競爭同一個CPU內核上,如果通過cpuset-cpus制定容器A使用內核0,容器B使用內核1,在主機上只有這兩個容器使用對應內核情況,那么cpu-share沒有明顯效果
cpu-period,cpu-quota這兩個參數聯合使用,在單核情況下或者的通過cpuset-cpus強制容器使用一個cpu內核的情況下,即使cpu-quota超過cpu-period,也不會讓容器使用更多的cpu資源
cpuset-cpus,cpuset-mems只在多核,多內存節點上的服務器有效,並且必須要與實際 的物理配置匹配嗎否則無法達到資源控制的目的
例子:測試cpuset-cpus和cpu-shares混合使用運行效果,就需要一個壓力測試工具stress來讓容器把實例cpu跑滿
工具安裝部分
stress是linux系統壓力測試軟件,stress可以測試linux系統cpu,menory,IO,disk的負載
wget http://people.seas.harvard.edu/~apw/stress/stress-1.0.4.tar.gz
tar zxvf stress-1.0.4.tar.gzcd stress-1.0.4
./configure --prefix=/usr/local/stress
make
make install
stress參數詳解: -? 顯示幫助信息 -v 顯示版本號 -q 不顯示運行版本 -n 顯示已完成的指令情況 -t --timeout N 指定運行 N秒后停止 --backoff N 等待N微妙后開始運行 -c 產生n個進程,每個進程都會反復不停的計算隨機數的平方根,測試CPU -i 產生n個進程,每個進程反復調用sync(),sync()用於將內存上面的內容寫到硬盤上面,測試硬盤磁盤IO -m --vm n產生N個進程,每個進程不斷調用內存分配malloc和內存釋放free 測試內存 --vm-bytes B 指定malloc時內存的字節數(默認256MB) --vm-hang N 指定在free棧的秒數 -d -hadd n產生n個執行write和unlink函數的進程 -hadd-bytes B 指定寫的字節數 --hadd-noclean 不 unlink
# cd /usr/local/stress/
# ./bin/stress -c 2 -i 2 --verbose --timeout 20s #2個進程,2個IO進程,20秒后停止
[Docker容器cpu資源隔離和限制]---重點內容
實例1:測試cpuset-cpus和cpus-shares混合使用運行效果,通過stress壓力測試容器,將cpu跑滿,當cpu跑滿后,會不會去其他cpu上去運行呢?如果第一顆cpu跑滿后,沒有轉移到第二顆cpu,那么,說明cgroup資源隔離成功

# docker run -itd --name centosv1 --cpuset-cpus 0,1 --cpu-shares 512 49f7960eb7e4 /bin/bash
# docker run -itd --name centosv2 --cpuset-cpus 0,1 --cpu-shares 1024 49f7960eb7e4 /bin/bash
首先分別在容器內部安裝scp命令,以便將宿主機的stress工具拷貝進來,在內部壓測,例如進入centosv2進行壓力測試,先測試一下cpu資源是夠隔離,
[root@b4577f900fcc /]# yum install -y openssh-clients #在容器安裝scp命令
[root@b4577f900fcc /]# scp -r root@192.168.2.151:/usr/local/stress ./ #將宿主機的stress路徑拷貝到centosv2容器中,以便進行壓力測試
[root@b4577f900fcc /]# ./stress/bin/stress -c 2 --verbose --timeout 10m #指定兩個容器內部進程
tar xvf stress-1.0.4.tar.gz cd stress-1.0.4 ./config --prefix=/usr/local/stress make && make install ln -s /usr/local/bin/stress /usr/bin/stress
nohup stress -c 2 --verbose --timeout 10m #可在后台運行stress命令,方面查看cpu限制以及配額

ok~上述圖中,我們可以看到CPU0和cpu2已經跑滿了,只在cpu0和cpu1上面,並未在cpu 2和cpu3運行,說明cpu資源隔離成功
2)下面同時運行centosv1和centosv2兩個容器,當時通過--cpuset-cpus設置兩個容器只運行在cpu0-1上面,隨后通過--cpu-shares進行cpu份額,也就是 centosv2的cpu使用率量是centosv1的兩倍,我們可以很清晰的看到,兩個容器使用情況,centosv2使用率為66.x%,而centosv1使用量是v2的一半,也就是33.x%,說明--cpu-shares資源限制成功
 
例子2:動態修改,比如說,我現在想將兩個容器的cpu份額平均下來,,只需將centosv2的--cpu.shares 1024改成與centosv1相同的512即可
# docker ps | grep centosv2
b4577f900fcc         49f7960eb7e4  "/bin/bash"          2  hours ago  Up  2 hours
# cat /sys/fs/cgroup/cpu,cpuacct/system.slice/docker-b4577f900fcce0451af030dc3fce8f71916a26d59c642a3336ceaee45e5aee22.scope/cpu.shares 
1024
將“512”寫入cpu.shares中即可,無需重啟centosv2容器生效,如果找不到cpu.shares這個文件存放在那個路徑,可以通過find / --name “cpu.shares”查看
[root@nginx-web ~]# echo "512" > /sys/fs/cgroup/cpu,cpuacct/system.slice/docker-b4577f900fcce0451af030dc3fce8f71916a26d59c642a3336ceaee45e5aee22.scope/cpu.shares
 
【Docker內存限制】
docker提供了參數-m ,--memory=“”限制容器內存使用量
例子:允許docker容器使用的內存上線為128M

# cat /sys/fs/cgroup/memory/system.slice/docker-6e014a7e2101b87c84a2b400032e7d2fdbd42035ed2d78742e3f7347409a5a42.scope/memory.limit_in_bytes
134217728
【DockerI/O限制】
限制硬盤的讀寫速度
例子:設置容器硬盤的最高讀寫速度為1MB/s
# docker run -itd --name centosv4 --device-write-bps /dev/sda:1mb 49f7960eb7e4
[root@8bbdbfca2722 /]# time $(dd if=/dev/zero of=f1.txt bs=1M count=1024 &&sync)
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 2.92801 s, 367 MB/s
real 0m11.933s     #使用11s左右。1秒93M左右
user 0m0.002s
sys 0m1.616s

【Docker磁盤配額】
docker容器默認啟動虛擬機,會占用宿主機的資源,默認有兩種驅動方式,即DeviceMapper和Overlay2,容器應哦按的rootfs根分區空間是整個宿主機的空間大小;我們都知道,docker共享這宿主機的硬盤空間,有的時候,docker所在的宿主機還有其他的應用服務,也共享者空間,如果docker占用空間無限制的占用宿主機,那么勢必會影響該宿主機其他的應用,此時,我們需要對docker的數據所占用的空間進行限制,也就是設置docker磁盤配額
在這里,只有xfs文件系統才能支持目錄界級別的磁盤配額功能
# mkfs.xfs -f /dev/sdb
# mount -o uquota,prjquota /dev/sdb /data/
# xfs_quota -x -c 'limit bsoft=10M bhard=10M user_test' /data/ #設置user_test用戶為對/data目錄的使用空間限制

測試,切換普通用戶user_test,使用dd進行磁盤讀寫測試,寫入查過10M的數據文件,看是否限制~

下面used表示用戶對/data目錄已使用的空間大小

接下來對docker容器的配額~
#vim /etc/sysconfig/docker
OPTIONS='--storage-opt overlay2.size=10G'
# mkfs.xfs -f /dev/sdb
# mount -o uquota,prjquota /dev/sdb /data/
# cd /var/lib/
# mv docker docker.back/
#ln -s /data_directory/docker/ /var/lib/

#docker pull docker.io/lemonbar/centos6-ssh
#docker run -itd --name test02 --privileged efd998bd6817


