1. 程式人生 > 實用技巧 >Docker倉庫管理及資源限制

Docker倉庫管理及資源限制

Docker倉庫管理及資源限制

Docker倉庫,類似於yum倉庫,是用來儲存映象的倉庫。為了方便的管理和使用docker映象,可以將映象集中儲存至Docker倉庫中,將製作好的映象push到倉庫集中儲存,在需要映象時,從倉庫中pull映象即可。

Docker 倉庫分為公有云倉庫和私有云倉庫

公有云倉庫: 由網際網路公司對外公開的倉庫

私有云倉庫: 組織內部搭建的倉庫,一般只為組織內部使用,常使用下面軟體搭建倉庫

  • docker registory

  • docker harbor

Docker私有云倉庫之分散式倉庫Harbor

Harbor是一個用於儲存和分發Docker映象的企業級Registry伺服器,由VMware開源,其通過新增一些企業必需的功能特性,例如安全、標識和管理等,擴充套件了開源 Docker Distribution。作為一個企業級私有Registry伺服器,Harbor 提供了更好的效能和安全。提升使用者使用Registry構建和執行環境傳輸映象的效率。Harbor支援安裝在多個Registry節點的映象資源複製,映象全部儲存在私有 Registry 中,確保資料和智慧財產權在公司內部網路中管控,另外,Harbor也提供了高階的安全特性,諸如使用者管理,訪問控制和活動審計等

vmware 官方開源服務: https://vmware.github.io/

harbor 官方github 地址: https://github.com/vmware/harbor

harbor 官方網址: https://goharbor.io/

harbor 官方文件: https://goharbor.io/docs/

github文件: https://github.com/goharbor/harbor/tree/master/docs

Harbor功能官方介紹

  • 基於角色的訪問控制: 使用者與Docker映象倉庫通過“專案”進行組織管理,一個使用者可以對多個映象倉庫在同一名稱空間(project)裡有不同的許可權

  • 映象複製: 映象可在多個Registry例項中複製(同步)。尤其適合於負載均衡,高可用,混合雲和多雲的場景

  • 圖形化使用者介面: 使用者可以通過瀏覽器來瀏覽,檢索當前Docker映象倉庫,管理專案和名稱空間

  • AD/LDAP 支: Harbor可以整合企業內部已有的AD/LDAP,用於鑑權認證管理

  • 審計管理: 所有針對映象倉庫的操作都可以被記錄追溯,用於審計管理

  • 國際化: 已擁有英文、中文、德文、日文和俄文的本地化版本。更多的語言將會新增進來

  • RESTful API: 提供給管理員對於Harbor更多的操控, 使得與其它管理軟體整合變得更容易

  • 部署簡單: 提供線上和離線兩種安裝工具, 也可以安裝到vSphere平臺(OVA方式)虛擬裝置

Harbor組成

  • Proxy: 對應啟動元件nginx。它是一個nginx反向代理,代理Notary client(映象認證)、Docker client(映象上傳下載等)和瀏覽器的訪問請求(Core Service)給後端的各服務

  • UI(Core Service): 對應啟動元件harbor-ui。底層資料儲存使用mysql資料庫,主要提供了四個子功能:

    • UI: 一個web管理頁面ui

    • API: Harbor暴露的API服務

    • Auth: 使用者認證服務,decode後的token中的使用者資訊在這裡進行認證;auth後端可以接 db、ldap、uaa三種認證實現

    • Token服務(上圖中未體現): 負責根據使用者在每個project中的role來為每一個docker push/pull命令釋出一個token,如果從docker client傳送給registry的請求沒有帶token, registry會重定向請求到token服務建立token

  • Registry: 對應啟動元件registry。負責儲存映象檔案,和處理映象的pull/push命令。Harbor對鏡 像進行強制的訪問控制,Registry會將客戶端的每個pull、push請求轉發到token服務來獲取有效 的token

  • Admin Service: 對應啟動元件harbor-adminserver。是系統的配置管理中心附帶檢查儲存用量, ui和jobserver啟動時候需要載入adminserver的配置

  • Job Sevice: 對應啟動元件harbor-jobservice。負責映象複製工作的,他和registry通訊,從一個 registry pull映象然後push到另一個registry,並記錄job_log

  • Log Collector: 對應啟動元件harbor-log。日誌彙總元件,通過docker的log-driver把日誌彙總到 一起

  • DB: 對應啟動元件harbor-db,負責儲存project、 user、 role、replication、image_scan、 access等的metadata資料

安裝harbor

先安裝docker 》 再安裝docker compose 》 最後安裝Harbor

#一鍵安裝harbor指令碼

#!/bin/bash
#
#********************************************************************
#Author: wei
#QQ:
#Date: 2020-11-14
#FileName: install_harbor.sh
#URL:
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
. /etc/init.d/functions


set -e
COLOR="echo -e \\E[1;32m"
COLOR1="echo -e \\E[1;31m"
END="\\E[0m"


#ubuntu依賴包
ubuntu_page="
wget
apt-transport-https
ca-certificates
curl
software-properties-common
python3-pip
"
#centos依賴包
centos_page="
wget
yum-utils
device-mapper-persistent-data
lvm2
"
harbor_version=harbor-offline-installer-v1.10.4.tgz

#centos7安裝
install_centos7() {
${COLOR}"開始安裝 Docker....."${END}
#安裝依賴包
for PAGE in ${centos_page};do
rpm -q $PAGE &> /dev/null || yum -y -q install $PAGE
done

#新增源資訊
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo && action "新增源資訊成功!" || { action "新增源資訊失敗,請檢查命令!" false ; exit; }

#更新安裝docker-ce
yum makecache fast &> /dev/null
yum -y install docker-ce &> /dev/null

#配置映象加速器
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://jcbawuya.mirror.aliyuncs.com"]
}
EOF

#過載配置檔案
systemctl daemon-reload

#啟動服務
${COLOR}"正在啟動 Docker....."${END}
sleep 2
systemctl start docker && action "docker啟動成功!" || action "docker啟動失敗,請檢查配置檔案!" false
}

#centos8安裝
install_centos8() {
${COLOR}"開始安裝 Docker....."${END}
#安裝依賴包
for PAGE in ${centos_page};do
rpm -q $PAGE &> /dev/null || yum -y -q install $PAGE
done
yum -y install https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm &> /dev/null
#新增源資訊
cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name=docker
gpgcheck=0
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/
EOF

#更新安裝docker-ce
yum clean all &> /dev/null
yum -y install docker-ce &> /dev/null && action "docker安裝完成!" || action "docker按照失敗!請檢查網路及Yum源!" false

#配置映象加速器
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://jcbawuya.mirror.aliyuncs.com"]
}
EOF

#過載配置檔案
systemctl daemon-reload

#啟動服務
${COLOR}"正在啟動 Docker....."${END}
sleep 2
systemctl start docker && action "docker啟動成功!" || action "docker啟動失敗,請檢查配置檔案!" false
}

#ubuntu安裝
install_ubuntu() {
${COLOR}"開始安裝 Docker....."${END}
#更新源及安裝依賴包
apt-get update &> /dev/null
for PAGE in ${ubuntu_page};do
dpkg -s $PAGE &> /dev/null || apt -y install $PAGE &> /dev/null
done

#安裝GPG證書
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

#寫入軟體源資訊
echo 'deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable' >> /etc/apt/sources.list
#更新源資訊
apt -y update &> /dev/null

#配置映象加速器
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://jcbawuya.mirror.aliyuncs.com"]
}
EOF

#安裝docker-ce
${COLOR}"正在安裝Docker,請稍等...."${END}
apt-get -y install docker-ce &> /dev/null && ${COLOR}"docker啟動成功!"${END} || ${COLOR1}"docker啟動失敗,請檢查配置檔案!"${END}
}

#ubuntu安裝harbor
install_harbor_ubuntu(){
mulu=`pwd`
myip=`hostname -I | awk '{print $1}'`
harbor_passwd=123456
[ -d /apps ] || mkdir -p /apps
[ -f /root/${harbor_version} ] || { ${COLOR1}"harbor安裝包不存在,請檢查!"${END}; exit; }
[[ $mulu == "/root" ]] && tar xf $harbor_version -C /apps/ || { cd; tar xf $harbor_version -C /apps/ ; }
#修改配置檔案
sed -i "s#reg.mydomain.com#${myip}#" /apps/harbor/harbor.yml
sed -i "s#Harbor12345#${harbor_passwd}#" /apps/harbor/harbor.yml
sed -i "s/https:/#https/" /apps/harbor/harbor.yml
sed -i "s/port: 443/#port: 443/" /apps/harbor/harbor.yml
/apps/harbor/install.sh

#配置服務檔案
cat > /lib/systemd/system/harbor.service <<EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF
#設定開機啟動
systemctl daemon-reload
systemctl enable harbar.service
}


#centos安裝harbor
install_harbor_centos(){
mulu=`pwd`
myip=`hostname -I | awk '{print $1}'`
harbor_passwd=123456
#建立harbor的目錄
[ -d /apps ] || mkdir -p /apps
[ -f /root/${harbor_version} ] || { ${COLOR1}"harbor安裝包不存在,請檢查!"${END}; exit; }
[[ $mulu == "/root" ]] && tar xf $harbor_version -C /apps/ || { cd; tar xf $harbor_version -C /apps/ ; }
#修改配置檔案
sed -i "s#reg.mydomain.com#${myip}#" /apps/harbor/harbor.yml
sed -i "s#Harbor12345#${harbor_passwd}#" /apps/harbor/harbor.yml
sed -i "s/https:/#https/" /apps/harbor/harbor.yml
sed -i "s/port: 443/#port: 443/" /apps/harbor/harbor.yml
/apps/harbor/install.sh && ${COLOR}"harbor安裝成功"$END || ${COLOR1}"harbor安裝失敗"$END

#配置服務檔案
cat > /lib/systemd/system/harbor.service <<EOF
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target
EOF
#設定開機啟動
systemctl daemon-reload
systemctl enable harbar.service
}

#安裝docker-compose
install_compose(){
#安裝docker-compose,需實現安裝python3-pip,利用pip庫安裝harbor
rpm -q python3 &> /dev/null || yum -y install python3
rpm -q python3-pip &> /dev/null || yum -y install python3-pip
pip3 install docker-compose -i https://mirrors.aliyun.com/pypi/simple
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
}

#系統型別
ostype1=`awk -F'"' '/^VERSION_ID/{print $2}' /etc/os-release`
ostype2=`awk -F'"' '/^NAME/{print $2}' /etc/os-release`
if [[ $ostype2 == "CentOS Linux" ]];then
if [ $ostype1 = 8 ];then
rpm -q docker-ce &> /dev/null && action "Docker已安裝" || install_centos8
elif [ $ostype1 = 7 ];then
rpm -q docker-ce &> /dev/null && action "Docker已安裝" || install_centos7
fi
elif [[ $ostype2 == "Ubuntu" ]];then
dpkg -s docker-ce &> /dev/null && ${COLOR}"Docker已安裝"$END || install_ubuntu
fi

#判斷compose是否安裝
docker-compose --version && ${COLOR}"Docker Compose已安裝"${END} || install_compose

#harbor安裝判斷
if [[ $ostype2 == "Ubuntu" ]];then
if [ -e /lib/systemd/system/harbar.service ];then
${COLOR}"harbor已安裝"${END};exit
else
install_harbor_ubuntu && ${COLOR}"harbor安裝完成,已開機啟動!"${END}
fi
elif [[ $ostype2 == "CentOS Linux" ]];then
if [ -e /lib/systemd/system/harbar.service ];then
${COLOR}"harbor已安裝"${END};exit
else
install_harbor_centos
fi
fi

編輯配置檔案 harbor.cfg

最新文件: https://github.com/goharbor/harbor/blob/master/docs/install-config/configure-yml-file.md

 [root@ubuntu1804 ~]#vim /apps/harbor/harbor.cfg
#只需要修改下面兩行
hostname = 10.0.0.101  #指向當前主機IP 或 FQDN
ui_url_protocol = http #如果修改為https,需要指定下面證書路徑
ssl_cert = /data/cert/server.crt #https時,需指定下面證書檔案路徑
ss_cert_key = /data/cert/server.key   #https時,需指定下面私鑰檔案路徑
harbor_admin_password = 123456 #指定harbor登入使用者admin的密碼,預設使用者/密碼:admin/Harbor12345

實現開機自動啟動 harbor

#方法一:通過service檔案實現
[root@harbor ~]#vim /lib/systemd/system/harbor.service
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor

[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /apps/harbor/docker-compose.yml down

[Install]
WantedBy=multi-user.target

[root@harbor ~]#systemctl daemon-reload 
[root@harbor ~]#systemctl enable harbor

#方法二:通過rc.local實現
[root@harbor ~]#cat /etc/rc.local 
#!/bin/bash
cd /apps/harbor
/usr/bin/docker-compose up 

[root@harbor ~]#chmod +x /etc/rc.local

實現harbor高可用

harbor支援基於策略Docker映象複製功能,這類似於MYSQL的主從同步。其可以實現不同的資料中心、不同 的執行環境之間同步映象,並提供友好的管理介面,大大的簡化了實際運維中的映象管理工作,已經有很多網際網路公司使用harbor搭建內網docker倉庫的案例,並且還實現了雙向複製功能

單機編排之Docker compose

當在宿主機啟動較多的容器時候,如果都是手動操作會覺得比較麻煩而且容易出錯,此時推薦使用 docker 單機編排工具 docker-compose

docker-compose 是 docker 容器的一種單機編排服務,docker-compose 是一個管理多個容器的工 具,比如: 可以解決容器之間的依賴關係,就像啟動一個nginx 前端服務的時候會呼叫後端的tomcat, 那就得先啟動tomcat,但是啟動tomcat 容器還需要依賴資料庫,那就還得先啟動資料庫,dockercompose 可以用來解決這樣的巢狀依賴關係,並且可以替代docker命令對容器進行建立、啟動和停止 等手工的操作

因此,如果說docker命令就像linux的命令,docker compse就像shell指令碼,可以自動的執行容器批量 操作,從而實現自動化的容器管理,或者說docker命令相當於ansible命令,那麼docker compose文 件,就相當於ansible-playbook的yaml檔案

docker-compose 專案是Docker 官方的開源專案,負責實現對Docker 容器叢集的快速編排,dockercompose 將所管理的容器分為三層,分別是工程(project),服務(service)以及容器 (container)

github地址: https://github.com/docker/compose

官方地址: https://docs.docker.com/compose/

檢視配置和格式檢查

[root@ubuntu1804 docker-compose]#docker-compose config
services:
 service-nginx-web:
   container_name: nginx-web
   expose:
    - 80
    - 443
   image: 10.0.0.102/example/nginx-centos7-base:1.6.1
   network_mode: bridge
   ports:
    - 80:80/tcp
    - 443:443/tcp
version: '2.1'

[root@ubuntu1804 docker-compose]#docker-compose config -q

docker的資源限制

官方文件: https://docs.docker.com/config/containers/resource_constraints/

預設情況下,容器沒有資源的使用限制,可以使用主機核心排程程式允許的儘可能多的資源

Docker 提供了控制容器使用資源的方法,可以限制容器使用多少記憶體或 CPU等, 在docker run 命令的執行時配置標誌實現資源限制功能。

其中許多功能都要求宿主機的核心支援,要檢查是否支援這些功能,可以使用docker info 命令 ,如果核心中禁用了某項功能可能會在輸出結尾處看到警告, 如,WARNING: No swap limit support:

可通過修改核心引數消除以上警告

官方文件: https://docs.docker.com/install/linux/linux-postinstall/#your-kernel-does-not-support-cgroup-swap-limit-capabilities

 [root@ubuntu1804 ~]#vim /etc/default/grub
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1 net.ifnames=0"
[root@ubuntu1804 ~]#update-grub
[root@ubuntu1804 ~]#reboot

容器記憶體限制

Docker 可以強制執行硬性記憶體限制,即只允許容器使用給定的記憶體大小

Docker 也可以執行非硬性記憶體限制,即容器可以使用盡可能多的記憶體,除非核心檢測到主機上的記憶體不夠用了

官文文件: https://docs.docker.com/config/containers/resource_constraints/

swap限制

--memory-swap #只有在設定了 --memory 後才會有意義。使用 Swap,可以讓容器將超出限制部分的記憶體置換到磁碟上,WARNING: 經常將記憶體交換到磁碟的應用程式會降低效能

-memory-swap #值為正數, 那麼--memory 和--memory-swap 都必須要設定,--memory-swap 表示你能使用的記憶體和 swap 分割槽大小的總和,例如:   --memory=300m, --memory-swap=1g, 那麼該容器能夠使用 300m 實體記憶體和 700m swap,即--memory 是實際實體記憶體大小值不變,而 swap 的實際大小計算方式為(--memory-swap)-(--memory)=容器可用 swap

--memory-swap #如果設定為 0,則忽略該設定,並將該值視為未設定,即未設定交換分割槽

--memory-swap #如果等於--memory 的值,並且--memory 設定為正整數,容器無權訪問 swap 

-memory-swap #如果未設定,如果宿主機開啟了 swap,則實際容器的swap 值最大為 2x( --memory),即兩倍於物理記憶體大小,例如,如果--memory="300m"與--memory-swap沒有設定,該容器可以使用300m總的記憶體和600m交撒空間,但是並不準確(在容器中使用free 命令所看到的 swap 空間並不精確,畢竟每個容器都可以看到具體大小,宿主機的 swap 是有上限的,而且不是所有容器看到的累計大小)

--memory-swap #如果設定為-1,如果宿主機開啟了 swap,則容器可以使用主機上 swap 的最大空間

注: 在容器中執行free命令看到的是宿主機的記憶體和swap使用,而非容器自身的swap使用情況

stress-ng壓力測試工具

stress-ng是一個壓力測試工具,可以通過軟體倉庫進行安裝也提供了docker版本的容器

容器CPU限制

官方文件說明: https://docs.docker.com/config/containers/resource_constraints/

一個宿主機,有幾十個核心的CPU,但是宿主機上可以同時執行成百上千個不同的程序用以處理不同的 任務,多程序共用一個 CPU 的核心為可壓縮資源,即一個核心的 CPU 可以通過排程而執行多個程序, 但是同一個單位時間內只能有一個程序在 CPU 上執行,那麼這麼多的程序怎麼在 CPU 上執行和排程的 呢?

Linux kernel 程序的排程基於CFS(Completely Fair Scheduler),完全公平排程

伺服器資源密集型

  • CPU 密集型的場景: 優先順序越低越好,計算密集型任務的特點是要進行大量的計算,消耗CPU 資 源,比如計算圓周率、資料處理、對視訊進行高清解碼等等,全靠CPU 的運算能力。

  • IO 密集型的場景: 優先順序值高點,涉及到網路、磁碟IO 的任務都是IO 密集型任務,這類任務的特 點是 CPU 消耗很少,任務的大部分時間都在等待 IO 操作完成(因為 IO 的速度遠遠低於 CPU 和 記憶體的速度),比如 Web 應用,高併發,資料量大的動態網站來說,資料庫應該為IO 密集型

CFS原理

cfs定義了程序排程的新模型,它給cfs_rq(cfs的run queue)中的每一個程序安排一個虛擬時鐘 vruntime。如果一個程序得以執行,隨著時間的增長,其vruntime將不斷增大。沒有得到執行的程序 vruntime不變, 而排程器總是選擇vruntime跑得最慢的那個程序來執行。這就是所謂的“完全公平”。為 了區別不同優先順序的程序,優先順序高的程序vruntime增長得慢,以至於它可能得到更多的執行機會。 CFS的意義在於, 在一個混雜著大量計算型程序和IO互動程序的系統中,CFS排程器相對其它排程器在 對待IO互動程序要更加友善和公平

視覺化圖形工具Portainer

Portainer是一個視覺化的容器映象的圖形化管理工具,利用Portainer可以輕鬆構建,管理和維護Docker環境。而且完全免費,基於容器化的安裝形式,方便高效部署

官方站點: https://www.portainer.io/

官方安裝說明: https://www.portainer.io/installation/