Docker基本概念及安裝(圖文詳解)
一、Docker概述
- Docker是一個開源的應用引擎,基於go語言開發並遵循apache2.0協議開源。
- Docker是在linux容器裡執行應用的開源工具,是一種輕量級的虛擬機器。
- Docker的容器技術可以在一臺主機上輕鬆的為任何應用建立一個輕量級的、可移植的、自給自足的容器‘
Docker的Logo設計為藍色鯨魚,拖著許多集裝箱
鯨魚可看作為宿主機,集裝箱可理解為相互隔離的容器,每個集裝箱中都包含自己的應用程式
1.Docker的設計宗旨:
Build,Ship and Run Any App,Anywhere,
即通過對應用元件的封裝、釋出、部署、執行等生命週期的管理,達到應用元件級別的“一次封裝,到處執行”的目的。這裡的元件,既可以是一個應用,也可以是一套服務,甚至是一個完整的作業系統。
2.容器化越來越受歡迎,因為容器是:
- 靈活:即使是最複雜的應用也可以集裝箱化。
- 輕量級:容器利用並共享主機核心。
- 可互換:可以即時部署更新和升級。
- 行動式:可以在本地構建,部署到雲,並在任何地方執行。
- 可擴充套件:可以增加並自動分發容器副本。
- 可堆疊:可以垂直和即時堆疊服務。
- 容器是在linux上本機執行,並與其他容器共享主機的核心,它執行的是一個獨立的程序,不佔用其他任何可執行檔案的記憶體,非常輕量
- 虛擬機器執行的是一個完成的作業系統,通過虛擬機器管理程式對主機資源進行虛擬訪問,相比之下需要的資源更多
3.Docker與虛擬機器的區別:
特性 Docker容器 虛擬機器 啟動速度 秒級 分鐘級 計算能力 損耗幾乎無損耗 50%左右 效能 接近原生 弱於 系統支援量(單機) 上千個 幾十個 隔離性 資源隔離/限制 完全隔離
4.容器在核心中支援2種重要技術:
docker本質就是宿主機的一個程序,docker是通過namespace實現資源隔離,通過cgroup實現資源限制,通過寫時複製技術(copy-on-write)實現了高效的檔案操作(類似虛擬機器的磁碟比如分配500g並不是實際佔用物理磁碟500g)
二.Docker核心概念
- 映象
Docker的映象是建立容器的基礎,類似虛擬機器的快照,可以理解為一個面向 Docker 容器引擎的只讀模板
通過映象啟動一個容器,一個映象是一個可執行的包,其中包括執行應用程式所需要的所有內容包含程式碼,執行時間,庫、環境變數、和配置檔案
- 容器
Docker的容器是從映象建立的執行例項,它可以被啟動、停止和刪除。所建立的每一個容器都是相互隔離、互不可見,以保證平臺的安全性
可以把容器看做是要給簡易版的linux環境(包括root使用者許可權、映象空間、使用者空間和網路空間等)和執行在其中的應用程式。
- 倉庫
Docker倉庫是用來集中儲存映象的地方,當建立了自己的映象之後,可以使用push命令將它上傳到公有倉庫(Public)或者私有倉庫(Private)。當下次要在另外一臺機器上使用這個映象時,只需從倉庫獲取
Docker 的映象、容器、日誌等內容全部都預設儲存在 /var/lib/docker 目錄下。
三.安裝 Docker
目前 Docker 只能支援 64 位系統。 systemctl stop firewalld.service setenforce 0 #安裝依賴包 yum install -y yum-utils device-mapper-persistent-data lvm2 -------------------------------------------------------------------------------------------- yum-utils:提供了 yum-config-manager 工具。 device mapper: 是Linux核心中支援邏輯卷管理的通用裝置對映機制,它為實現用於儲存資源管理的塊裝置驅動提供了一個高度模組化的核心架構。 device mapper儲存驅動程式需要 device-mapper-persistent-data 和 lvm2。 -------------------------------------------------------------------------------------------- #設定阿里雲映象源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #安裝 Docker-CE並設定為開機自動啟動 yum install -y docker-ce systemctl start docker.service systemctl enable docker.service #檢視 docker 版本資訊 docker version
注:使用線上源安裝
四.Docker 映象操作
#搜尋映象 格式:docker search 關鍵字 docker search nginx #獲取映象 格式:docker pull 倉庫名稱[:標籤] #如果下載映象時不指定標籤,則預設會下載倉庫中最新版本的映象,即選擇標籤為 latest 標籤。 docker pull nginx #映象加速下載 瀏覽器訪問 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 獲取映象加速器配置 mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker #檢視映象資訊 映象下載後存放在 /var/lib/docker #檢視下載的映象檔案資訊 cat /var/lib/docker/image/overlay2/repositories.json #檢視下載到本地的所有映象 docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest ae2feff98a0c 9 days ago 133MB -------------------------------------------------------------------------------------------- REPOSITORY:映象屬於的倉庫; TAG:映象的標籤資訊,標記同一個倉庫中的不同映象; IMAGE ID:映象的唯一ID 號,唯一標識一個映象; CREATED:映象建立時間; VIRTUAL SIZE:映象大小; -------------------------------------------------------------------------------------------- #根據映象的唯一標識 ID 號,獲取映象詳細資訊 格式:docker inspect 映象ID號 docker inspect ae2feff98a0c #為本地的映象新增新的標籤 格式:docker tag 名稱:[標籤] 新名稱:[新標籤] docker tag nginx:latest nginx:web docker images | grep nginx #刪除映象 格式: docker rmi 倉庫名稱:標籤 #當一個映象有多個標籤時,只是刪除其中指定的標籤 或者 docker rmi 映象ID號 #會徹底刪除該映象 注意:如果該映象已經被容器使用,正確的做法是先刪除依賴該映象的所有容器,再去刪除映象。 docker rmi nginx:web #存出鏡像:將映象儲存成為本地檔案 格式:docker save -o 儲存檔名 儲存的映象 docker save -o nginx nginx:latest #存出鏡像命名為nginx存在當前目錄下 ls -lh #載入映象:將映象檔案匯入到映象庫中 格式: docker load < 存出的檔案 或者 docker load -i 存出的檔案 docker load < nginx #上傳映象 預設上傳到 docker Hub 官方公共倉庫,需要註冊使用公共倉庫的賬號。https://hub.docker.com 可以使用 docker login 命令來輸入使用者名稱、密碼和郵箱來完成註冊和登入。 在上傳映象之前,還需要先對本地映象新增新的標籤,然後再使用 docker push 命令進行上傳。 docker tag nginx:latest nginx:web #新增新的標籤 docker login #登入公共倉庫 Username: password: docker push wl/nginx:web #上傳映象
注:此步驟 往往也是排查映象問題的良方
rmi後面加映象ID號 阿靜徹底刪除該映象
五.Docker 容器操作
#容器建立:就是將映象載入到容器的過程。 新建立的容器預設處於停止狀態,不執行任何程式,需要在其中發起一個程序來啟動容器。 格式:docker create [選項] 映象 常用選項: -i:讓容器的輸入保持開啟 -t:讓 Docker 分配一個偽終端 docker create -it nginx:latest /bin/bash #檢視容器的執行狀態 docker ps -a #-a 選項可以顯示所有的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8b0a7be0ff58 nginx:latest "/docker-entrypoint.…" 57 seconds ago Created inspiring_swanson 容器的ID號 載入的映象 執行的程式 建立時間 當前的狀態 埠對映 名稱 #啟動容器 格式:docker start 容器的ID/名稱 docker start 8b0a7be0ff58 docker ps -a #建立並啟動容器 可以直接執行 docker run 命令, 等同於先執行 docker create 命令,再執行 docker start 命令。 注意:容器是一個與其中執行的 shell 命令共存亡的終端,命令執行容器執行, 命令結束容器退出。 當利用 docker run 來建立容器時, Docker 在後臺的標準執行過程是: (1)檢查本地是否存在指定的映象。當映象不存在時,會從公有倉庫下載; (2)利用映象建立並啟動一個容器; (3)分配一個檔案系統給容器,在只讀的映象層外面掛載一層可讀寫層; (4)從宿主主機配置的網橋介面中橋接一個虛擬機器介面到容器中; (5)分配一個地址池中的 IP 地址給容器; (6)執行使用者指定的應用程式,執行完畢後容器被終止執行。 docker run centos:7 /usr/bin/bash -c ls / docker ps -a #會發現建立了一個新容器並啟動執行一條 shell 命令,之後就停止了 #在後臺持續執行 docker run 建立的容器 需要在 docker run 命令之後新增 -d 選項讓 Docker 容器以守護形式在後臺執行。並且容器所執行的程式不能結束。 docker run -d centos:7 /usr/bin/bash -c "while true;do echo hello;done" docker ps -a #可以看出容器始終處於 UP,執行狀態 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2592d3fad0fb centos:7 "/usr/bin/bash -c 'w…" 2 seconds ago Up 2 seconds peaceful_chatelet docker run -itd --name test1 centos:7 /bin/bash #終止容器執行 格式:docker stop 容器的ID/名稱 docker stop 2592d3fad0fb docker ps -a #容器的進入 需要進入容器進行命令操作時,可以使用 docker exec 命令進入執行著的容器。 格式:docker exec -it 容器ID/名稱 /bin/bash -i 選項表示讓容器的輸入保持開啟; -t 選項表示讓 Docker 分配一個偽終端。 docker start 2592d3fad0fb #進入容器前,確保容器正在執行 docker exec -it 2592d3fad0fb /bin/bash ls exit #退出容器後,容器仍在執行 docker ps -a #容器的匯出與匯入 使用者可以將任何一個 Docker 容器從一臺機器遷移到另一臺機器。在遷移過程中,可以使用docker export 命令將已經建立好的容器匯出為檔案,無論這個容器是處於執行狀態還是停止狀態均可匯出。可將匯出檔案傳輸到其他機器,通過相應的匯入命令實現容器的遷移。 #匯出格式:docker export 容器ID/名稱 > 檔名 docker export 2592d3fad0fb > centos7tar #匯入格式:cat 檔名 | docker import – 映象名稱:標籤 cat centos7tar | docker import - centos7:test #匯入後會生成映象,但不會建立容器 #刪除容器 格式:docker rm [-f] 容器ID/名稱 docker stop 2592d3fad0fb docker rm 2592d3fad0fb #刪除已經終止狀態的容器 docker rm -f 2592d3fad0fb #強制刪除正在執行的容器 docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash #批量停止容器 docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash #批量刪除所有容器 docker images | awk 'NR>=2{print "docker rmi "$3}' | bash #批量刪除映象
六.Docker 網路
1.Docker網路的實現原理
- Docker使用Linux橋接,在宿主機虛擬一個Docker容器網橋(docker0),Docker啟動一個容器時會根據Docker網橋的網段分配給容器一個IP地址,稱為Container-IP,同時Docker網橋是每個容器的預設閘道器。因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的 Container-IP 直接通訊。
- Docker網橋是宿主機虛擬出來的,並不是真實存在的網路裝置,外部網路是無法定址到的,這也意味著外部網路無法直接通過 Container-IP 訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過對映容器埠到宿主主機(埠對映),即 docker run 建立容器時候通過 -p 或 -P 引數來啟用,訪問容器的時候就通過[宿主機IP]:[容器埠]訪問容器。
docker run -d --name test1 -P nginx #隨機對映埠( 從32768開始) docker run -d --name test2 -p 43000:80 nginx #指定對映埠 docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9d3c04f57a68 nginx "/docker-entrypoin...." 4 seconds ago Up 3 seconds 0.0.0.0: 43000->80/tcp test2 b04895f870e5 nginx " /docker-entrypoi..." 17 seconds ago Up 15 seconds 0.0.0.0: 49170->80/ tcp test1 瀏覽器訪問: http://192.168.80.10;43000 、 http://192.168.80.10:49170
2.Docker 的網路模式
●Host:容器將不會虛擬出自己的網絡卡,配置自己的IP等,而是使用宿主機的IP和埠。 ●Container:建立的容器不會建立自己的網絡卡,配置自己的IP,而是和一個指定的容器共享IP、埠範圍。 ●None:該模式關閉了容器的網路功能。 ●Bridge:預設為該模式,此模式會為每一個容器分配、設定IP等,並將容器連線到一個docker0虛擬網橋,通過docker0網橋以及iptables nat 表配置與宿主機通訊。 ●自定義網路
Host:
Container:
Bridge:
#使用docker run建立Docker容器時,可以用 --net 或 --network 選項指定容器的網路模式 ●host模式:使用 --net=host 指定。 ●none模式:使用 --net=none 指定。 ●container模式:使用 --net=container:NAME_or_ID 指定。 ●bridge模式:使用 --net=bridge 指定,預設設定,可省略。
安裝Docker時,它會自動建立三個網路,bridge(建立容器預設連線到此網路)、 none 、host
docker network ls #檢視docker網路列表 NETWORK ID NAME DRIVER SCOPE 2b4359d229c6 bridge bridge local 0fa580365d39 host host local cc13aa84a223 none null local
3.網路模式詳解
1.host模式 相當於Vmware中的橋接模式,與宿主機在同一個網路中,但沒有獨立IP地址。 Docker使用了Linux的Namespaces技術來進行資源隔離,如PID Namespace隔離程序,Mount Namespace隔離檔案系統,Network Namespace隔離網路等。 一個Network Namespace提供了一份獨立的網路環境,包括網絡卡、路由、iptable規則等都與其他的Network Namespace隔離。 一個Docker容器一般會分配一個獨立的Network Namespace。 但如果啟動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace, 而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網絡卡、配置自己的IP等,而是使用宿主機的IP和埠。 2.container模式 在理解了host模式後,這個模式也就好理解了。這個模式指定新建立的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新建立的容器不會建立自己的網絡卡,配置自己的IP,而是和一個指定的容器共享IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過lo網絡卡裝置通訊。 docker run -itd --name test1 centos:7 /bin/bash #--name 選項可以給容器建立一個友好的自定義名稱 docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3ed82355f811 centos:7 "/bin/bash" 5 days ago Up 6 hours test1 docker inspect -f '{{.State.Pid}}' 3ed82355f811 #檢視容器程序號 25945 ls -l /proc/25495/ns #檢視容器的程序、 網路、檔案系統等名稱空間編號 lrwxrwxrwx 1 root root 0 1月 7 11:29 ipc -> ipc:[4026532572] lrwxrwxrwx 1 root root 0 1月 7 11:29 mnt -> mnt:[4026532569] lrwxrwxrwx 1 root root 0 1月 7 11:27 net -> net:[4026532575] lrwxrwxrwx 1 root root 0 1月 7 11:29 pid -> pid:[4026532573] lrwxrwxrwx 1 root root 0 1月 7 12:22 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 1月 7 11:29 uts -> uts:[4026532570] docker run -itd --name test2 --net=container:3ed82355f811 centos:7 /bin/bash docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ff96bc43dd27 centos:7 "/bin/bash" 48 seconds ago Up 46 seconds test2 3ed82355f811 centos:7 "/bin/bash" 58 minutes ago Up 58 minutes test1 docker inspect -f '{{.State.Pid}}' ff96bc43dd27 27123 ls -l /proc/27123/ns #檢視可以發現兩個容器的 net namespace 編號相同 lrwxrwxrwx 1 root root 0 1月 7 12:27 ipc -> ipc:[4026532692] lrwxrwxrwx 1 root root 0 1月 7 12:27 mnt -> mnt:[4026532690] lrwxrwxrwx 1 root root 0 1月 7 12:27 net -> net:[4026532575] lrwxrwxrwx 1 root root 0 1月 7 12:27 pid -> pid:[4026532693] lrwxrwxrwx 1 root root 0 1月 7 12:27 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 1月 7 12:27 uts -> uts:[4026532691] 3.none模式 使用none模式,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。 也就是說,這個Docker容器沒有網絡卡、IP、路由等資訊。這種網路模式下容器只有lo迴環網路,沒有其他網絡卡。這種型別的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。 4.Bridge模式 bridge模式是docker的預設網路模式,不寫--net引數,就是bridge模式。 相當於Vmware中的 nat 模式,容器使用獨立network Namespace,並連線到docker0虛擬網絡卡。通過docker0網橋以及iptables nat表配置與宿主機通訊,此模式會為每一個容器分配Network Namespace、設定IP等,並將一個主機上的 Docker 容器連線到一個虛擬網橋上。 (1)當Docker程序啟動時,會在主機上建立一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。 (2)從docker0子網中分配一個IP給容器使用,並設定docker0的IP地址為容器的預設閘道器。在主機上建立一對虛擬網絡卡veth pair裝置。veth裝置總是成對出現的,它們組成了一個數據的通道,資料從一個裝置進入,就會從另一個裝置出來。因此,veth裝置常用來連線兩個網路裝置。 (3)Docker將veth pair 裝置的一端放在新建立的容器中,並命名為eth0(容器的網絡卡),另一端放在主機中, 以veth*這樣類似的名字命名,並將這個網路裝置加入到docker0網橋中。可以通過 brctl show 命令檢視。 (4)使用 docker run -p 時,docker實際是在iptables做了DNAT規則,實現埠轉發功能。可以使用iptables -t nat -vnL 檢視。 5.自定義網路 #直接使用bridge,無法支援指定IP執行docker docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:7 /bin/bash #可以先自定義網路,再使用指定IP執行docker docker network create --subnet=172.18.0.0/24 mynetwork docker run -itd --name test2 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash
七.資源控制
1.CPU 資源控制
cgroups,是一個非常強大的linux核心工具,他不僅可以限制被 namespace 隔離起來的資源, 還可以為資源設定權重、計算使用量、操控程序啟停等等。 所以 cgroups( Control groups) 實現了對資源的配額和度量。
2.cgroups四大功能:
- 資源限制:可以對任務使用的資源總額進行限制
- 優先順序分配:通過分配的cpu時間片數量以及磁碟IO頻寬大小,實際上相當於控制了任務執行優先順序
- 資源統計:可以統計系統的資源使用量,如cpu時長,記憶體用量等
- 任務控制:cgroup可以對任務執行掛起、恢復等操作
(1)設定CPU使用率上限 Linux 通過 CFS(Completely Fair Scheduler,完全公平排程器)來排程各個程序對 CPU 的使用。CFS 預設的排程週期是 100ms。 我們可以設定每個容器程序的排程週期,以及在這個週期內各個容器最多能使用多少 CPU 時間。 使用 --cpu-period 即可設定排程週期,使用 --cpu-quota 即可設定在每個週期內容器能使用的 CPU 時間。兩者可以配合使用。 CFS 週期的有效範圍是 1ms~1s,對應的 --cpu-period 的數值範圍是 1000~100000。 而容器的 CPU 配額必須不小於 1ms,即 --cpu-quota 的值必須 >= 1000。 docker run -itd --name test1 centos:7 /bin/bash docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3ed82355f811 centos:7 "/bin/bash" 5 days ago Up 6 hours test1 cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/ cat cpu.cfs_quota_us -1 cat cpu.cfs_period_us 100000 --------------------------------------------------------------------------------------------------------- #cpu.cfs_period_us:cpu分配的週期(微秒,所以檔名中用 us 表示),預設為100000。 #cpu.cfs_quota_us:表示該control group限制佔用的時間(微秒),預設為-1,表示不限制。 如果設為50000,表示佔用50000/100000=50%的CPU。 --------------------------------------------------------------------------------------------------------- #進行CPU壓力測試 docker exec -it 3ed82355f811 /bin/bash vim /cpu.sh #!/bin/bash i=0 while true do let i++ done chmod +x /cpu.sh ./cpu.sh exit top #可以看到這個指令碼佔了很多的cpu資源 #設定50%的比例分配CPU使用時間上限 docker run -itd --name test2 --cpu-quota 50000 centos:7 /bin/bash #可以重新建立一個容器並設定限額 或者 cd /sys/fs/cgroup/cpu/docker/3ed82355f81151c4568aaa6e7bc60ba6984201c119125360924bf7dfd6eaa42b/ echo 50000 > cpu.cfs_quota_us docker exec -it 3ed82355f811 /bin/bash ./cpu.sh exit top #可以看到cpu佔用率接近50%,cgroups對cpu的控制起了效果 (2)設定CPU資源佔用比(設定多個容器時才有效) Docker 通過--cpu-shares 指定 CPU 份額,預設值為1024,值為1024的倍數。 #建立兩個容器為 c1 和 c2,若只有這兩個容器,設定容器的權重,使得c1和c2的CPU資源佔比為1/3和2/3。 docker run -itd --name c1 --cpu-shares 512 centos:7 docker run -itd --name c2 --cpu-shares 1024 centos:7 #分別進入容器,進行壓力測試 yum install -y epel-release yum install stress -y stress -c 4 #產生四個程序,每個程序都反覆不停的計算隨機數的平方根 exit #檢視容器執行狀態(動態更新) docker stats CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS c3ee18e65852 c2 66.50% 5.5MiB / 976.3MiB 0.56% 20.4MB / 265kB 115MB / 14.2MB 4 bb02d3b345d8 c1 32.68% 2.625MiB / 976.3MiB 0.27% 20.4MB / 325kB 191MB / 12.7MB 4 (3)設定容器繫結指定的CPU #先分配虛擬機器4個CPU核數 docker run -itd --name test2 --cpuset-cpus 1,3 centos:7 /bin/bash #進入容器,進行壓力測試 yum install -y epel-release yum install stress -y stress -c 4 exit #退出容器,執行 top 命令再按 1 檢視CPU使用情況。
3.對磁碟IO配額控制(blkio)的限制
--device-read-bps:限制某個裝置上的讀速度bps(資料量),單位可以是kb、mb(M)或者gb。 例:docker run -itd --name test4 --device-read-bps /dev/sda:1M centos:7 /bin/bash --device-write-bps : 限制某個裝置上的寫速度bps(資料量),單位可以是kb、mb(M)或者gb。 例:docker run -itd --name test5 --device-write-bps /dev/sda:1mb centos:7 /bin/bash --device-read-iops :限制讀某個裝置的iops(次數) --device-write-iops :限制寫入某個裝置的iops(次數) #建立容器,並限制寫速度 docker run -it --name test5 --device-write-bps /dev/sda:1mb centos:7 /bin/bash #通過dd來驗證寫速度 dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct #新增oflag引數以規避掉檔案系統cache 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 10.0025 s, 1.0 MB/s