Docker資源控制與TLS加密通訊

2020-09-28 10:01:04


()

Docker資源控制

  • Docker通過Cgroup 來控制容器使用的資源配額,包括CPU、記憶體、磁碟三大方面,基本覆蓋了常見的資源配額和使用量控制。

  • Cgroup是Control Groups的縮寫,是Lnux核心提供的一種可以限制、記錄、隔離行程群組所使用的物理資源(如CPU、記憶體、磁碟IO等等)的機制,

這些具體的資源管理功能稱為Cgroup子系統,有以下幾大子系統實現:

  • **blkio:**設定限制每個塊裝置的輸入輸出控制。例如:磁碟,光碟以及usb等

  • **CPU:**使用排程程式為cgroup任務提供CPU的存取。

  • **cpuacct:**產生cgroup任務的CPU 資源報告。

  • cpuset:如果是多核心的CPU,這個子系統會為cgroup任務分配單獨的CPU和記憶體。

  • **devices:**允許或拒絕cgroup任務對裝置的存取。

  • **freezer:**暫停和恢復cgroup任務。

  • memory:設定每個cgroup的記憶體限制以及產生記憶體資源報告。

  • **net_cls:**標記每個網路包以供cgroup方便使用。

  • **ns:**名稱空間子系統。

  • **perf_event:**增加了對每個group的監測跟蹤的能力,可以監測屬於某個特定的group的所有執行緒以及執行在特定CPU上的執行緒。

    下面開始利用stress壓力測試工具來測試CPU 和記憶體使用狀況。

使用stress工作測試cpu和記憶體

使用Dockerfile來建立一個基於Centos的stress的工作映象

[root@localhost opt]# mkdir stress
[root@localhost opt]# cd stress
[root@localhost stress]# vim Dockerfile
FROM centos:7
MAINTAINER chen "zhang@kgc.com"
RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum install -y stress

執行指令碼

[root@localhost stress]# docker build -t centos:stress .

使用下面命令建立容器,命令中–cpu-shares引數不能保證獲得1個VCPU或多個CPU資源,它僅僅是一個彈性加權值

docker run -itd --cpu-shares 100 centos:stress

1:說明:說明:預設情況下,每個Docker容器的CPU份額都是1024。單獨一個容器的份額是沒有意義的。只有在同時執行多個容器時,容器的CPU加權的效果

2:例如,兩個容器AB的CPU份額分別為1000和500,在CPU進行時間片分配的時候,容器A比容器B多一倍的機會獲得CPU的時間片。分配的結果取決於當時主機和其他容器的執行狀態,實際上也無法保證容器A一定能獲得CPU時間片。比如容器A的程序一直是空閒的,那麼容器B是可以獲取比容器A更多的CPU時間片的。極端情況下,例如主機上只執行了一個容器,即使它的CPU份額只有50,它也可以獨佔整個主機

建立容器

docker run -tid --name cpu512 --cpu-shares 512 centos:stress stress -c 10

stress -c 10:容器產生10個子函數程序

進入容器

 docker exec -it 0aa895961d13  bash

輸入top檢視我們已經建立了10個程序(1master帶10個程序)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-A8dj6B7q-1601091015533)(C:\Users\19437\AppData\Roaming\Typora\typora-user-images\image-20200925141652979.png)]

再開一臺終端容器做比較

docker run -tid --name cpu1024 --cpu-shares 1024 centos:stress stress -c 10

進入容器

 docker exec -it f5f6dac70fa2 bash

兩臺cpu對比,我們可以看到%CPU份額是另一臺的一半(使用top對比兩個的%CPU,比例是1:2)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-dmEIV7nk-1601091015536)(C:\Users\19437\AppData\Roaming\Typora\typora-user-images\image-20200925142320995.png)]

cup週期限制

Docker提供了–cpu-period、–cpu-quota兩個引數控制容器可以分配到的CPU時鐘週期。

  • –cpu-period是用來指定容器對CPU的使用要在多長時間內做一次重新分配.
  • --cpu-quota是用來指定在這個週期內,最多可以有多少時間用來跑這個容器。與–cpu-shares 不同的是,這種設定是指定一個絕對值,容器對CPU資源的使用絕對不會超過設定的值。
  • cpu-period和cpu-quota 的單位為微秒(us). cpu-period的最小值為1000微秒,最大值為1秒(10^6 us),預設值為0.1秒(10000 us)cpu-quota的值預設為-1,表示不做控制。cpu-period和cpu-quota引數一般聯合使用。
  • 例如:容器程序需要每1秒使用單個CPU的0.2秒時間,可以將cpu-period設定為1000000 (即1秒),cpu-quota設定為20000(0.2秒)當然,在多核情況下,如果允許容器程序完全佔用兩個CPU,則可以將cpu-period 設定為100000(即0.1秒),cpu-quota設定為200000 (0.2)

我麼先把前面的容器停止

停止容器
[root@localhost stress]# docker stop f5f6dac70fa2  
f5f6dac70fa2
[root@localhost stress]# docker stop b69f01e20458

下面我們設定容器名字為cuptest 資源分配100000秒,cpu配額為200000,針對 centos:stress映象

docker run -itd --name cuptest --cpu-period 100000 --cpu-quota 200000 centos:stress

進入容器

[root@localhost stress]# docker exec -it 6078e84e4b6c bash

檢視資源分配,cpu配額

[root@6078e84e4b6c /]# cat /sys/fs/cgroup/cpu/cpu.cfs_period_us 
100000
[root@6078e84e4b6c /]# cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us 
200000

修改記憶體8G核心數4

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-YGeEadC1-1601091015539)(C:\Users\19437\AppData\Roaming\Typora\typora-user-images\image-20200925145253849.png)]

CPU Core 控制

對多核CPU的服務,Docker還可以控制容器執行使用哪些CPU核心,即使用–cpuuset-cpus引數。這對具多CPU的伺服器尤其有用,可以對需要高效能運算進行效能最優的設定

docker run -itd --name cpu1 --cpuset-cpus 0-1 centos:stress 

ps:以上命令需要宿主機為雙核,表示建立容器只可以用0,1兩核心

進入容器

[root@localhost ~]# docker exec -it 9cdded9c10de bash
檢視cpu
[root@9cdded9c10de /]# cat /sys/fs/cgroup/cpuset/cpuset.cpus
0-1

下面指令可以看到容器中程序與cpu核心的繫結關係,達到繫結CPU核心的目的

[root@localhost ~]# docker exec c0ffab515796 taskset -c -p 1

壓測測試

[root@localhost ~]# docker exec -it 9cdded9c10de  bash
[root@9cdded9c10de /]# stress -c 10

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-OiPVAam9-1601091015543)(C:\Users\19437\AppData\Roaming\Typora\typora-user-images\image-20200925150343544.png)]

cpu配額控制引數的混合使用

通過cpuset-cpus引數指定容器A使用CPU核心0,容器B只是用CPU核心1.
在主機上只有這兩個容器使用對應CPU核心的情況,它們各自佔用全部的核心資源,cpu-shares沒有明顯效果。
cpuset-cpus、cpuset-mems引數只在多核、多記憶體節點上的伺服器上有效,並且必須與實際的物理設定匹配。否則也無法達到資源控制的目的。
在系統具有多個CPU核心的情況下,需要通過cpuset-cpus引數為設定容器CPU核心才能方便地進行測試。

[root@localhost ~]# docker run -tid --name cpu3 --cpuset-cpus 1 --cpu-shares 512 centos:stress stress -c 1 

進入檢視資源

[root@localhost ~]# docker exec -it af8b5f7b10fb bash

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-EwgLBN8t-1601091015547)(C:\Users\19437\AppData\Roaming\Typora\typora-user-images\image-20200925152433169.png)]

在開一臺

[root@localhost ~]# docker run -tid --name cpu4 --cpuset-cpus 3 --cpu-shares 1024 centos:stress stress -c 1

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ZfHgiVUV-1601091015549)(C:\Users\19437\AppData\Roaming\Typora\typora-user-images\image-20200925152955199.png)]

總結:上面的centos:stress映象安裝了stress工具,用來測試CPU和記憶體的負載。通過在兩個容器上分別執行stress -c1命令,會給系統一個隨機負載,產生1個程序。這個程序都反覆不停的計算由rand()產生亂數的平方根,直到資源耗盡。察到宿主機上的CPU使用率,第三個核心的使用率接近100%,並且一批程序的CPU使用率明視訊記憶體在2:1的使用比例的對比。

記憶體限額

與作業系統類似,容器可使用的記憶體包括兩部分:實體記憶體和Swap.
Docker通過下面兩組引數來控制容器記憶體的使用量。
-m或–memory:設定記憶體的使用限額,例如10OM、1024M.
–memory-swap:設定記憶體+swap的使甩限額。

執行如下命令允許該容器最多使用20OM的記憶體和30OM的swap.

[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M

–vm 1:啟動1個記憶體工作執行緒。
–vm-bvtes 280M:每個執行緒分配28OM記憶體。

如果讓工作執行緒分配的記憶體超過300M,分配的記憶體超過限額,stress執行緒報錯,容器退出。

[root@localhost stress]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 310M

IO限制

預設情況下,所有容器能平等地讀寫磁碟,可以通過設定–blkio-weight引數來改變容器block lO的優先順序。
–blkio-weight與–cpu-shares類似。設定的是相對權重值,預設為500。
在下面的例子中,容器A讀寫磁碟的頻寬是容器B的兩倍。

[root@localhost ~]# docker run -idt --name container_A --blkio-weight 600 centos:stress
[root@localhost ~]# docker exec -it f1eff11d5926 bash
[root@f1eff11d5926 /]# cat /sys/fs/cgroup/blkio/blkio.weight
600

在建立一個權重為300的

[root@localhost ~]# docker run -idt --name container_B --blkio-weight 300 centos:stress
[root@localhost ~]# docker  exec -it a9799eb70c64 bash
[root@a9799eb70c64 /]# cat /sys/fs/cgroup/blkio/blkio.weight
300

總結600的讀寫更快

bps和iops的限制

  • bps是byte per second,每秒讀寫的資料量。
  • ops是io per second.每秒IO的次數。
    通過以下引數控制客器的bps和iops:
  • -device-read-bps。限制讀某個裝置的bps.
  • -device-write-bps,限制寫某個裝置的bps.
  • -device-read-iops,限制讀某個裝置的iops.
  • -device-write-iops,限制寫某個裝置的iops.

面的範例是限制容器寫/dev/sda的速率為5MB/s.

docker run -it --device-write-bps /dev/sda:5MB centos:stress

先容器中不停的讀寫(我們發現寫的很慢)

[root@24ce8fee6b6a /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct

1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 204.806 s, 5.2 MB/s

我們不設定限制(發現很快就好了)

[root@localhost ~]# docker run -it centos:stress

[root@ef487c7c1cee /]# dd if=/dev/zero of=test bs=1M count=1024 oflag=direct
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 1.89416 s, 567 MB/s

Docker-TLS加密通訊

安全傳輸層協定(TLS)用於在兩個通訊應用程式之間提供保密性和資料完整性。

該協定由兩層組成: TLS 記錄協定(TLS Record)和 TLS(TLS Handshake)。

  • 對稱:DES 3DES AES 長度不同 長度越長安全越高,解密速度越慢
  • 非對稱:RSA公鑰,私鑰 ,公鑰:所有人可知(鎖)私鑰 (鑰匙)個人身份資訊,不可抵賴。
  • 證書:個人資訊,金鑰,有效期
  • ca:證書頒發機構 ca證書

實驗過程;

建立ca金鑰>>建立ca證書

建立伺服器私鑰>>簽名金鑰>>使用ca證書與私鑰證書籤名

生成使用者端金鑰>>簽名使用者端>>使用ca證書與客戶簽名證書

實驗需求

使用需要服務2臺服務去,一臺設定證書:一臺實驗對接

centos7:192.168.136.90

centos7:192.168.136.81

設定master主機名

[root@localhost ~]# hostnamectl set-hostname master

設定解析(在另一臺也配上為了名稱對應地址)

[root@ef487c7c1cee /]# vim /etc/hosts
192.168.136.90 master

設定步驟

建立ca金鑰
[root@master ~]# openssl genrsa -aes256 -out ca-key.pem 4096

輸入密碼:123123

建立ca證書
 openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem


建立伺服器私鑰
 openssl genrsa -out server-key.pem 4096

簽名金鑰

openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr

使用ca證書與私鑰證書籤名,輸入123123

openssl x509 -req -days 1000 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out  server-cert.pem

生成使用者端金鑰
 openssl genrsa -out key.pem 4096

簽名使用者端
 openssl req -subj "/CN=client" -new -key key.pem -out client.csr


建立組態檔
echo extendedKeyUsage=clientAuth > extfile.cnf

簽名證書,輸入123123(需要簽名使用者端,ca證書,ca金鑰)
openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

刪除多餘檔案
[root@localhost ~]# rm -rf ca.srl client.csr server.csr extfile.cnf 

設定docker證書

[root@localhost ~]# vim /lib/systemd/system/docker.service 
14行加#號
15 ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/tls/ca.pem --tlscert=/tls/server-cert.pem --tlskey=/tls/server-key.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-yXVBV2Lt-1601091015551)(C:\Users\19437\AppData\Roaming\Typora\typora-user-images\image-20200925163645642.png)]

建立證書目錄

[root@localhost ~]# mkdir /tls
[root@localhost ~]# mv *.pem /tls/

重新啟動服務

[root@localhost ~]# systemctl daemon-reload 
[root@localhost ~]# systemctl restart docker

檢視埠

[root@master ~]#  netstat -ntap | grep 2376
tcp6       0      0 :::2376                 :::*                    LISTEN      13907/dockerd

本地驗證(檢視docker版本)

[root@master tls]# cd /tls/
[root@localhost docker]#docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://master:2376 version

遠端連線docker

開啟使用者端192.168.136.81

伺服器端複製證書給使用者端

[root@maseter tls]# scp ca.pem root@192.168.136.81:/etc/docker
[root@maseter tls]# scp cert.pem root@192.168.136.81:/etc/docker
[root@maseter tls]# scp key.pem root@192.168.136.81:/etc/docker

在使用者端檢視檢視docker版本

[root@localhost docker]# cd /etc/docker/
[root@localhost docker]#docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://master:2376 version