39-docker(一)

本章內(nèi)容

◆ Docker簡介
◆ Docker 鏡像與制作
◆ Docker 數(shù)據(jù)管理
◆ Docker 網(wǎng)絡
◆ Docker 倉庫之單機 Docker Registry
◆ docker 倉庫之分布式 Harbor
◆ 單機編排之 Docker Compose
◆ 補充-資源限制

一: 簡介

1.1: docker 簡介

1.1.1: Docker 是什么
  • 首先 Docker 是一個在 2013 年開源的應用程序并且是一個基于 go 語言編寫是一個開源的 PAAS 服務(Platform as a Service, 平臺即服務的縮寫), go 語言是由google 開發(fā), docker 公司最早叫 dotCloud 后由于 Docker 開源后大受歡迎就將公司改名為 Docker Inc, 總部位于美國加州的舊金山, Docker 是基于 linux 內(nèi)核實現(xiàn), Docker 最早采用 LXC 技術(shù)(LinuX Container 的簡寫, LXC 是 Linux 原生支持的容器技術(shù), 可以提供輕量級的虛擬化, 可以說 docker 就是基于 LXC 發(fā)展起來的,提供 LXC 的高級封裝,發(fā)展標準的配置方法), 而虛擬化技術(shù) KVM(Kernelbased Virtual Machine) 基于模塊實現(xiàn), Docker 后改為自己研發(fā)并開源的 runc 技術(shù)運行容器。

  • Docker 相比虛擬機的交付速度更快, 資源消耗更低, Docker 采用客戶端/服務端架構(gòu),使用遠程 API 來管理和創(chuàng)建 Docker 容器,其可以輕松的創(chuàng)建一個輕量級的、 可移植的、自給自足的容器, docker 的三大理念是 build(構(gòu)建)、ship(運輸)、 run(運行), Docker 遵從 apache 2.0 協(xié)議,并通過(namespace 及cgroup 等)來提供容器的資源隔離與安全保障等,所以 Docke 容器在運行時不需要類似虛擬機(空運行的虛擬機占用物理機 6-8%性能)的額外資源開銷,因此可以大幅提高資源利用率,總而言之 Docker 是一種用了新穎方式實現(xiàn)的輕量級虛擬機.類似于 VM 但是在原理和應用上和 VM 的差別還是很大的,并且 docker的專業(yè)叫法是應用容器(Application Container)。

1.1.2: Docker 的組成

https://docs.docker.com/engine/docker-overview/
Docker 主機(Host): 一個物理機或虛擬機,用于運行 Docker 服務進程和容器。
Docker 服務端(Server): Docker 守護進程, 運行 docker 容器。
Docker 客戶端(Client): 客戶端使用 docker 命令或其他工具調(diào)用 docker API。
Docker 倉庫(Registry): 保存鏡像的倉庫,類似于 git 或 svn 這樣的版本控制系
Docker 鏡像(Images): 鏡像可以理解為創(chuàng)建實例使用的模板。
Docker 容器(Container): 容器是從鏡像生成對外提供服務的一個或一組服務。
官方倉庫: https://hub.docker.com/

1.1.3: Docker 對比虛擬機

資源利用率更高: 一臺物理機可以運行數(shù)百個容器,但是一般只能運行數(shù)十個虛擬機。
開銷更?。?不需要啟動單獨的虛擬機占用硬件資源。
啟動速度更快: 可以在數(shù)秒內(nèi)完成啟動。

使用虛擬機是為了更好的實現(xiàn)服務運行環(huán)境隔離, 每個虛擬機都有獨立的內(nèi)核,虛擬化可以實現(xiàn)不同操作系統(tǒng)的虛擬機,但是通常一個虛擬機只運行一個服務, 很明顯資源利用率比較低且造成不必要的性能損耗, 我們創(chuàng)建虛擬機的目的是為了運行應用程序,比如 Nginx、 PHP、 Tomcat 等 web 程序, 使用虛擬機無疑帶來了一些不必要的資源開銷,但是容器技術(shù)則基于減少中間運行環(huán)節(jié)帶來較大的性能提升

多個容器帶來的以下問題怎么解決:
1.怎么樣保證每個容器都有不同的文件系統(tǒng)并且能互不影響?
2.一個 docker 主進程內(nèi)的各個容器都是其子進程,那么實現(xiàn)同一個主進程下不同類型的子進程? 各個進程間通信能相互訪問(內(nèi)存數(shù)據(jù))嗎?
3.每個容器怎么解決 IP 及端口分配的問題?
4.多個容器的主機名能一樣嗎?
5.每個容器都要不要有 root 用戶?怎么解決賬戶重名問題?
以上問題怎么解決?

1.1.4: Linux Namespace 技術(shù)

namespace 是 Linux 系統(tǒng)的底層概念, 在內(nèi)核層實現(xiàn),即有一些不同類型的命名空間被部署在核內(nèi), 各個 docker 容器運行在同一個 docker 主進程并且共用同一個宿主機系統(tǒng)內(nèi)核,各 docker 容器運行在宿主機的用戶空間, 每個容器都要有類似于虛擬機一樣的相互隔離的運行空間, 但是容器技術(shù)是在一個進程內(nèi)實現(xiàn)運行指定服務的運行環(huán)境, 并且還可以保護宿主機內(nèi)核不受其他進程的干擾和影響, 如文件系統(tǒng)空間、網(wǎng)絡空間、進程空間等,目前主要通過以下技術(shù)實現(xiàn)

容器運行空間的相互隔離:

隔離類型 功能 系統(tǒng)調(diào)用參數(shù) 內(nèi)核版本
MNT Namespace(mount) 提供磁盤掛載點和文件系統(tǒng)的隔離能力 CLONE_NEWNS Linux 2.4.19
IPC Namespace(Inter-Process Communication) 提供進程間通信的隔離能力 CLONE_NEWIPC Linux 2.6.19
UTS Namespace(UNIX Timesharing System) 提供主機名隔離能力 CLONE_NEWUTS Linux 2.6.19
PID Namespace(Process Identification) 提供進程隔離能力 CLONE_NEWPID Linux 2.6.24
Net Namespace(network) 提供網(wǎng)絡隔離能力 CLONE_NEWNET Linux 2.6.29
User Namespace(user) 提供用戶隔離能力 CLONE_NEWUSER Linux 3.8

1.1.4.1: MNT Namespace

每個容器都要有獨立的根文件系統(tǒng)有獨立的用戶空間, 以實現(xiàn)在容器里面啟動服務并且使用容器的運行環(huán)境,即一個宿主機是 ubuntu 的服務器,可以在里面啟動一個 centos 運行環(huán)境的容器并且在容器里面啟動一個 Nginx 服務,此 Nginx運行時使用的運行環(huán)境就是 centos 系統(tǒng)目錄的運行環(huán)境, 但是在容器里面是不能訪問宿主機的資源, 宿主機是使用了 chroot 技術(shù)把容器鎖定到一個指定的運行目錄里面。

例如: /var/lib/containerd/io.containerd.runtime.v1.linux/moby/容器 ID

啟動三個容器用于以下驗證過程:

Server: Docker Engine - Community
Engine:
Version: 18.09.7
API version: 1.39 (minimum version 1.12)
Go version: go1.10.8
Git commit: 2d0083d
Built: Thu Jun 27 17:26:28 2019
OS/Arch: linux/amd64
Experimental: false
# docker run -d --name nginx-1 -p 80:80 nginx
# docker run -d --name nginx-2 -p 81:80 nginx
# docker run -d --name nginx-3 -p 82:80 nginx

Debian 系統(tǒng)安裝基礎命令

# apt update
# apt install procps (top 命令)
# apt install iputils-ping (ping 命令)
# apt install net-tools (網(wǎng)絡工具)

驗證容器的根文件系統(tǒng)

image.png

1.1.4.2: IPC Namespace

一個容器內(nèi)的進程間通信, 允許一個容器內(nèi)的不同進程的(內(nèi)存、 緩存等)數(shù)據(jù)訪問,但是不能夸容器訪問其他容器的數(shù)據(jù)。

1.1.4.3: UTS Namespace

UTS namespace(UNIX Timesharing System 包含了運行內(nèi)核的名稱、版本、底層體系結(jié)構(gòu)類型等信息)用于系統(tǒng)標識, 其中包含了 hostname 和域名domainname , 它使得一個容器擁有屬于自己 hostname 標識,這個主機名標識獨立于宿主機系統(tǒng)和其上的其他容器。

image.png

1.1.4.4: PID Namespace

Linux 系統(tǒng)中,有一個 PID 為 1 的進程(init/systemd)是其他所有進程的父進程, 那么在每個容器內(nèi)也要有一個父進程來管理其下屬的子進程, 那么多個容器的進程通 PID namespace 進程隔離(比如 PID 編號重復、 器內(nèi)的主進程生成與回收子進程等)。
例如:下圖是在一個容器內(nèi)使用 top 命令看到的 PID 為 1 的進程是 nginx:

image.png

容器內(nèi)的 Nginx 主進程與工作進程:

image.png

那么宿主機的 PID 究竟與容器內(nèi)的 PID 是什么關(guān)系?

容器 PID 追蹤:

1.1.4.4.1: 查看宿主機上的 PID 信息

image.png

1.1.4.4.2: 查看容器中的 PID 信息

[圖片上傳失敗...(image-994f8-1594221009349)]

1.1.4.5: Net Namespace

每一個容器都類似于虛擬機一樣有自己的網(wǎng)卡、 監(jiān)聽端口、 TCP/IP 協(xié)議棧等,Docker 使用 network namespace 啟動一個 vethX 接口,這樣你的容器將擁有它自己的橋接 ip 地址,通常是 docker0,而 docker0 實質(zhì)就是 Linux 的虛擬網(wǎng)橋,網(wǎng)橋是在 OSI 七層模型的數(shù)據(jù)鏈路層的網(wǎng)絡設備,通過 mac 地址對網(wǎng)絡進行劃分,并且在不同網(wǎng)絡直接傳遞數(shù)據(jù)。

1.1.4.5.1: 查看宿主機的網(wǎng)卡信息

image.png

1.1.4.5.2: 查看宿主機橋接設備

通過 brctl show 命令查看橋接設備

image.png
image.png

1.1.4.5.3:實邏輯網(wǎng)絡圖

image.png

1.1.4.5.4: 宿主機 iptables 規(guī)則

image.png
image.png

1.1.4.6: User Namespace

各個容器內(nèi)可能會出現(xiàn)重名的用戶和用戶組名稱, 或重復的用戶 UID 或者GID, 那么怎么隔離各個容器內(nèi)的用戶空間呢?User Namespace 允許在各個宿主機的各個容器空間內(nèi)創(chuàng)建相同的用戶名以及相同的用戶 UID 和 GID, 只是會把用戶的作用范圍限制在每個容器內(nèi),即 A 容器和 B 容器可以有相同的用戶名稱和 ID 的賬戶,但是此用戶的有效范圍僅是當前容器內(nèi), 不能訪問另外一個容器內(nèi)的文件系統(tǒng),即相互隔離、互補影響、 永不相見。

[圖片上傳失敗...(image-49a06e-1594221009349)]

1.1.5: Linux control groups

1.1.5.1: 驗證系統(tǒng) cgroups:
Cgroups 在內(nèi)核層默認已經(jīng)開啟, 從 centos 和 ubuntu 對比結(jié)果來看, 顯然內(nèi)核
較新的 ubuntu 支持的功能更多。

1.1.5.1.1: Centos 7.6 cgroups

image.png

1.1.5.1.2: ubuntu cgroups

image.png

1.1.5.1.3: cgroups 中內(nèi)存模塊

# cat /boot/config-4.15.0-54-generic | grep MEM | grep CG
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
# CONFIG_MEMCG_SWAP_ENABLED is not set
CONFIG_SLUB_MEMCG_SYSFS_ON=y

1.1.5.1.4: cgroups 具體實現(xiàn)

blkio:塊設備 IO 限制。
cpu:使用調(diào)度程序為 cgroup 任務提供 cpu 的訪問。
cpuacct:產(chǎn)生 cgroup 任務的 cpu 資源報告。
cpuset:如果是多核心的 cpu,這個子系統(tǒng)會為 cgroup 任務分配單獨的 cpu
和內(nèi)存。
devices:允許或拒絕 cgroup 任務對設備的訪問。
freezer:暫停和恢復 cgroup 任務。
memory:設置每個 cgroup 的內(nèi)存限制以及產(chǎn)生內(nèi)存資源報告。
net_cls:標記每個網(wǎng)絡包以供 cgroup 方便使用。
ns:命名空間子系統(tǒng)。
perf_event:增加了對每 group 的監(jiān)測跟蹤的能力,可以監(jiān)測屬于某個特定的
group 的所有線程以及運行在特定 CPU 上的線程。

1.1.5.1.5:查看系統(tǒng) cgroups

[root@node1 ~]# ll /sys/fs/cgroup/
total 0
drwxr-xr-x 5 root root 0 Jun 30 18:12 blkio
lrwxrwxrwx 1 root root 11 Jun 30 18:12 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 Jun 30 18:12 cpuacct -> cpu,cpuacct
drwxr-xr-x 5 root root 0 Jun 30 18:12 cpu,cpuacct
drwxr-xr-x 3 root root 0 Jun 30 18:12 cpuset
drwxr-xr-x 5 root root 0 Jun 30 18:12 devices
drwxr-xr-x 3 root root 0 Jun 30 18:12 freezer
drwxr-xr-x 3 root root 0 Jun 30 18:12 hugetlb
drwxr-xr-x 5 root root 0 Jun 30 18:12 memory
drwxr-xr-x 3 root root 0 Jun 30 18:12 net_cls
drwxr-xr-x 3 root root 0 Jun 30 18:12 perf_event
drwxr-xr-x 5 root root 0 Jun 30 18:12 systemd

有了以上的 chroot、 namespace、 cgroups 就具備了基礎的容器運行環(huán)境,但是還需要有相應的容器創(chuàng)建與刪除的管理工具、 以及怎么樣把容器運行起來、容器數(shù)據(jù)怎么處理、怎么進行啟動與關(guān)閉等問題需要解決, 于是容器管理技術(shù)出
現(xiàn)了。

1.1.6: 容器管理工具

目前主要是使用 docker, 早期有使用 lxc。

1.1.6.1: lxc:

LXC: LXC 為 Linux Container 的簡寫??梢蕴峁┹p量級的虛擬化,以便隔離進程和資源, 官方網(wǎng)站: https://linuxcontainers.org/

Ubuntu 安裝 lxc:

root@s1:~# apt install lxc lxd
Reading package lists... Done
Building dependency tree
Reading state information... Done
lxd is already the newest version (3.0.3-0ubuntu1~18.04.1).
lxc is already the newest version (3.0.3-0ubuntu1~18.04.1).
root@s1:~# lxc-checkconfig #檢查內(nèi)核對 lcx 的支持狀況,必須全部為 lcx
root@s1:~# lxc-create -t 模板名稱 -n lcx-test
root@s1:~# lxc-create -t download --name alpine12 -- --dist alpine --release
3.9 --arch amd64
Setting up the GPG keyring
Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs

---
You just created an Alpinelinux 3.9 x86_64 (20190630_13:00) container.

root@s1:~# lxc-start alpine12 #啟動 lxc 容器
root@s1:~# lxc-attach alpine12 #進入 lxc 容器
~ # ifconfig
eth0 Link encap:Ethernet HWaddr 00:16:3E:DF:54:94
inet addr:10.0.3.115 Bcast:10.0.3.255 Mask:255.255.255.0
inet6 addr: fe80::216:3eff:fedf:5494/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:18 errors:0 dropped:0 overruns:0 frame:0
TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2102 (2.0 KiB) TX bytes:1796 (1.7 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

~ # uname -a
Linux alpine12 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018
x86_64 Linux
~ # cat /etc/issue
Welcome to Alpine Linux 3.9
Kernel \r on an \m (\l)

命令備注:
-t 模板: -t 選項后面跟的是模板,模式可以認為是一個原型,用來說明我們需要一個什么樣的容器(比如容器里面需不需要有 vim, apache 等軟件).模板實際上就是一個腳本文件(位于/usr/share/lxc/templates 目錄),我們這里指定download 模板(lxc-create 會調(diào)用 lxc-download 腳本,該腳本位于剛說的模板目錄中)是說明我們目前沒有自己模板,需要下載官方的模板
--name 容器名稱: 為創(chuàng)建的容器命名
-- : --用來說明后面的參數(shù)是傳遞給 download 腳本的,告訴腳本需要下載什么樣的模板
--dist 操作系統(tǒng)名稱:指定操作系統(tǒng)
--release 操作系統(tǒng): 指定操作系統(tǒng),可以是各種 Linux 的變種
--arch 架構(gòu): 指定架構(gòu),是 x86 還是 arm,是 32 位還是 64 位

lxc 啟動容器依賴于模板, 清華模板源:
https://mirrors.tuna.tsinghua.edu.cn/help/lxc-images/,但是做模板相對較難, 需要手動一步步創(chuàng)構(gòu)建文件系統(tǒng)、準備基礎目錄及可執(zhí)行程序等,而且在大規(guī)模使用容器的場景很難橫向擴展, 另外后期代碼升級也需要重新從頭構(gòu)建模板,基于以上種種原因便有了 docker。

1.1.6.2: docker

Docker 啟動一個容器也需要一個外部模板但是較多鏡像, docke 的鏡像可以保存在一個公共的地方共享使用, 只要把鏡像下載下來就可以使用,最主要的是可以在鏡像基礎之上做自定義配置并且可以再把其提交為一個鏡像,一個鏡像可以被啟動為多個容器。
Docker 的鏡像是分層的, 鏡像底層為庫文件且只讀層即不能寫入也不能刪除數(shù)據(jù),從鏡像加載啟動為一個容器后會生成一個可寫層,其寫入的數(shù)據(jù)會復制到容器目錄, 但是容器內(nèi)的數(shù)據(jù)在刪除容器后也會被隨之刪除。

1.1.6.3: pouch

https://www.infoq.cn/article/alibaba-pouch
https://github.com/alibaba/pouch

1.1.7: Docker 的優(yōu)勢

快速部署: 短時間內(nèi)可以部署成百上千個應用,更快速交付到線上。
高效虛擬化:不需要額外的 hypervisor 支持,直接基于 linux 實現(xiàn)應用虛擬化,相比虛擬機大幅提高性能和效率。
節(jié)省開支: 提高服務器利用率,降低 IT 支出。
簡化配置: 將運行環(huán)境打包保存至容器,使用時直接啟動即可。
快速遷移和擴展: 可夸平臺運行在物理機、虛擬機、公有云等環(huán)境, 良好的兼容性可以方便將應用從 A 宿主機遷移到 B 宿主機, 甚至是 A 平臺遷移到 B 平臺

1.1.8: Docker 的缺點

隔離性: 各應用之間的隔離不如虛擬機徹底。

小筆記:pouch安裝
cd /etc/yum.repos.d
wget https://mirrors.aliyun.com/pouch/centos7.repo
yum install pouch -y
systemctl start pouch
1.1.9: docker(容器)的核心技術(shù)

容器規(guī)范

容器技術(shù)除了的 docker 之外,還有 coreOS 的 rkt, 還有阿里的 Pouch, 為了保證容器生態(tài)的標準性和健康可持續(xù)發(fā)展, 包括 Linux 基金會、 Docker、微軟、紅帽谷歌和、 IBM、 等公司在 2015 年 6 月共同成立了一個叫 open container(OCI)的組織,其目的就是制定開放的標準的容器規(guī)范,目前 OCI 一共發(fā)布了兩個規(guī)范,分別是 runtime spec 和 image format spec,有了這兩個規(guī)范, 不同的容器公司開發(fā)的容器只要兼容這兩個規(guī)范,就可以保證容器的可移植性和相互可操作性。

容器 runtime:

runtime 是真正運行容器的地方,因此為了運行不同的容器 runtime 需要和操作系統(tǒng)內(nèi)核緊密合作相互在支持,以便為容器提供相應的運行環(huán)境。
目前主流的三種 runtime:
Lxc: linux 上早期的 runtime, Docker 早期就是采用 lxc 作為 runtime。
runc:目前 Docker 默認的 runtime, runc 遵守 OCI 規(guī)范,因此可以兼容 lxc。
rkt: 是 CoreOS 開發(fā)的容器 runtime,也符合 OCI 規(guī)范,所以使用 rktruntime 也可以運行 Docker 容器。

容器管理工具:

管理工具連接 runtime 與用戶,對用戶提供圖形或命令方式操作,然后管理工具將用戶操作傳遞給 runtime 執(zhí)行。
lxc 是 lxd 的管理工具。
Runc 的管理工具是 docker engine, docker engine 包含后臺 deamon 和 cli 兩部分,大家經(jīng)常提到的 Docker 就是指的 docker engine。
Rkt 的管理工具是 rkt cli。

容器定義工具:

容器定義工具允許用戶定義容器的屬性和內(nèi)容,以方便容器能夠被保存、共享和重建。
Docker image:是 docker 容器的模板, runtime 依據(jù) docker image 創(chuàng)建容器。
Dockerfile:包含 N 個命令的文本文件,通過 dockerfile 創(chuàng)建出 docker image。
ACI(App container image): 與 docker image 類似, 是 CoreOS 開發(fā)的 rkt 容器的鏡像格式。

Registry:

統(tǒng)一保存鏡像而且是多個不同鏡像版本的地方, 叫做鏡像倉庫。
Image registry: docker 官方提供的私有倉庫部署工具。
Docker hub: docker 官方的公共倉庫, 已經(jīng)保存了大量的常用鏡像,可以方便大家直接使用。
Harbor: vmware 提供的自帶 web 界面自帶認證功能的鏡像倉庫,目前有很多公司使用。

172.18.200.101/project/centos:7.2.1511
172.18.200.101/project/centos: latest
172.18.200.101/project/java-7.0.59:v1
172.18.200.101/project/java-7.0.59:v2

編排工具:

當多個容器在多個主機運行的時候, 單獨管理容器是相當復雜而且很容易出錯,而且也無法實現(xiàn)某一臺主機宕機后容器自動遷移到其他主機從而實現(xiàn)高可用的目的, 也無法實現(xiàn)動態(tài)伸縮的功能,因此需要有一種工具可以實現(xiàn)統(tǒng)一管理、動
態(tài)伸縮、故障自愈、 批量執(zhí)行等功能, 這就是容器編排引擎。
容器編排通常包括容器管理、調(diào)度、集群定義和服務發(fā)現(xiàn)等功能。
Docker swarm: docker 開發(fā)的容器編排引擎。
Kubernetes: google 領(lǐng)導開發(fā)的容器編排引擎,內(nèi)部項目為 Borg, 且其同時支持docker 和 CoreOS。
Mesos+Marathon: 通用的集群組員調(diào)度平臺, mesos(資源分配)與 marathon(容器編排平臺)一起提供容器編排引擎功能。

1.1.10: docker(容器)的依賴技術(shù)

容器網(wǎng)絡:
docker 自帶的網(wǎng)絡 docker network 僅支持管理單機上的容器網(wǎng)絡, 當多主機運行的時候需要使用第三方開源網(wǎng)絡,例如 calico、 flannel 等。

服務發(fā)現(xiàn):
容器的動態(tài)擴容特性決定了容器 IP 也會隨之變化, 因此需要有一種機制可以自動識別并將用戶請求動態(tài)轉(zhuǎn)發(fā)到新創(chuàng)建的容器上, kubernetes 自帶服務發(fā)現(xiàn)功能,需要結(jié)合 kube-dns 服務解析內(nèi)部域名。

容器監(jiān)控:
可以通過原生命令 docker ps/top/stats 查看容器運行狀態(tài),另外也可以使heapster/ Prometheus 等第三方監(jiān)控工具監(jiān)控容器的運行狀態(tài)。

數(shù)據(jù)管理:

容器的動態(tài)遷移會導致其在不同的 Host 之間遷移,因此如何保證與容器相關(guān)的數(shù)據(jù)也能隨之遷移或隨時訪問,可以使用邏輯卷/存儲掛載等方式解決。

日志收集:

docker 原生的日志查看工具 docker logs, 但是容器內(nèi)部的日志需要通過 ELK 等專門的日志收集分析和展示工具進行處理。

1.2: Docker 安裝及基礎命令介紹

官方網(wǎng)址: https://www.docker.com/
系統(tǒng)版本選擇:
Docker 目前已經(jīng)支持多種操作系統(tǒng)的安裝運行, 比如 Ubuntu、 CentOS、Redhat、 Debian、 Fedora,甚至是還支持了 Mac 和 Windows,在 linux 系統(tǒng)上需要內(nèi)核版本在 3.10 或以上, docker 版本號之前一直是 0.X 版本或 1.X 版本,但是從 2017 年 3 月 1 號開始改為每個季度發(fā)布一次穩(wěn)版,其版本號規(guī)則也統(tǒng)一變更為 YY.MM, 例如 17.09 表示是 2017 年 9 月份發(fā)布的, 本次演示的操作系統(tǒng)使用 Centos 7.5 為例。

Docker 版本選擇:
Docker 之前沒有區(qū)分版本,但是 2017 年初推出(將 docker 更名為)新的項目Moby, github 地址: https://github.com/moby/moby, Moby 項目屬于 Docker 項目的全新上游, Docker 將是一個隸屬于的 Moby 的子產(chǎn)品,而且之后的版本之后開始區(qū)分為 CE 版本(社區(qū)版本) 和 EE(企業(yè)收費版), CE 社區(qū)版本和 EE 企業(yè)版本都是每個季度發(fā)布一個新版本,但是 EE 版本提供后期安全維護 1 年, 而CE 版本是 4 個月, 本次演示的 Docker 版本為 18.03, 以下為官方原文:
https://blog.docker.com/2017/03/docker-enterprise-edition/

Docker CE and EE are released quarterly, and CE also has a monthly “Edge” option.
Each Docker EE release is supported and maintained for one year and receives
security and critical bugfixes during that period. We are also improving Docker CE
maintainability by maintaining each quarterly CE release for 4 months. That gets
Docker CE users a new 1-month window to update from one version to the next.

與 kubernetes 結(jié)合使用的時候,要安裝經(jīng)過 kubernetes 官方測試通過的 docker
版本, 避免出現(xiàn)不兼容等未知的及不可預估的問題發(fā)生, kubernetes 測試過的

docker 版本可以在 github 查詢, 具體如下:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md#external-dependencies

1.2.1: 下載 rpm 包安裝

官方 rpm 包下載地址:
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
二進制下載地址:
https://download.docker.com/
https://mirrors.aliyun.com/docker-ce/linux/static/stable/x86_64/
阿里鏡像下載地址:
https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/

1.2.2: 通過修改 yum 源安裝

[root@docker-server1 ~]# rm -rf /etc/yum.repos.d/*
[root@docker-server1 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo
http://mirrors.aliyun.com/repo/Centos-7.repo
[root@docker-server1 ~]# wget -O /etc/yum.repos.d/epel.repo
http://mirrors.aliyun.com/repo/epel-7.repo
[root@docker-server1 ~]# wget -O /etc/yum.repos.d/docker-ce.repo
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
[root@docker-server1 ~]# yum install docker-ce

1.2:3: ubuntu 安裝 docker、 啟動并驗證服務
root@docker-server1:~#apt-get install docker-ce-5:18.09.9~3-0~ubuntu-bionic
docker-ce-cli=5:18.09.9~3-0~ubuntu-bionic
root@docker-server1:~# systemctl start docker
root@docker-server1:~# systemctl enable docker
小筆記:安裝docker
#ubuntu18
# step 1: 安裝必要的一些系統(tǒng)工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安裝GPG證書
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 寫入軟件源信息
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安裝Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

# 安裝指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
apt-cache madison docker-ce
#docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
#docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# Step 2: 安裝指定版本的Docker-CE: (VERSION例如上面的17.03.1~ce-0~ubuntu-xenial)
sudo apt-get -y install docker-ce=[VERSION]

#centos7
# step 1: 安裝必要的一些系統(tǒng)工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加軟件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3: 更新并安裝Docker-CE
sudo yum makecache fast
sudo yum -y install docker-ce
# Step 4: 開啟Docker服務
sudo service docker start

# 注意:
# 官方軟件源默認啟用了最新的軟件,您可以通過編輯軟件源的方式獲取各個版本的軟件包。例如官方并沒有將測試版本的軟件源置為可用,您可以通過以下方式開啟。同理可以開啟各種測試版本等。
vim /etc/yum.repos.d/docker-ee.repo
#   將[docker-ce-test]下方的enabled=0修改為enabled=1
#
# 安裝指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
yum list docker-ce.x86_64 --showduplicates | sort -r
#   Loading mirror speeds from cached hostfile
#   Loaded plugins: branch, fastestmirror, langpacks
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
#   docker-ce.x86_64            17.03.1.ce-1.el7.centos            @docker-ce-stable
#   docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
#   Available Packages
# Step2: 安裝指定版本的Docker-CE: (VERSION例如上面的17.03.0.ce.1-1.el7.centos)
sudo yum -y install docker-ce-[VERSION]

#簡單使用
systemctl start docker
docker pull nginx:1.16.1        #下載nginx鏡像
docker run -d -p 80:80 nginx    #運行容器
docker ps                       #查看ID號
docker exec -it id bash         #進入容器
1.2.4: 驗證 docker 版本

docker version

1.2.5:驗證 docker0 網(wǎng)卡

在 docker 安裝啟動之后,默認會生成一個名稱為 docker0 的網(wǎng)卡并且默認 IP 地址為 172.17.0.1 的網(wǎng)卡。

1.2.6: 驗證 docker 信息
root@docker-server1:~# docker info
Containers: 2 #當前主機運行的容器總數(shù)
  Running: 1 #有幾個容器是正在運行的
  Paused: 0 #有幾個容器是暫停的
  Stopped: 1 #有幾個容器是停止的
Images: 3 #當前服務器的鏡像數(shù)
Server Version: 18.09.9 #服務端版本
Storage Driver: overlay2 #正在使用的存儲引擎
  Backing Filesystem: xfs #后端文件系統(tǒng),即服務器的磁盤文件系統(tǒng)
  Supports d_type: true #是否支持 d_type
  Native Overlay Diff: true #是否支持差異數(shù)據(jù)存儲
Logging Driver: json-file #日志類型
Cgroup Driver: cgroupfs #Cgroups 類型
Plugins: #插件
  Volume: local #卷
  Network: bridge host macvlan null overlay # overlay 夸主機通信
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog #日志類型
Swarm: inactive #是否支持 swarm
Runtimes: runc #已安裝的容器運行時
Default Runtime: runc #默認使用的容器運行時
Init Binary: docker-init #初始化容器的守護進程,即 pid 為 1 的進程
containerd version: 894b81a4b802e4eb2a91d1ce216b8817763c29fb #版本
runc version: 425e105d5a03fabd737a126ad93d62a9eeede87f # runc 版本
init version: fec3683 #init 版本
  Security Options: #安全選項
  Apparmor #安全模塊, https://docs.docker.com/engine/security/apparmor/
  seccomp #審計(操作), https://docs.docker.com/engine/security/seccomp/
Profile: default #默認的配置文件
Kernel Version: 4.15.0-55-generic #宿主機內(nèi)核版本
Operating System: Ubuntu 18.04.3 LTS #宿主機操作系統(tǒng)
OSType: linux #宿主機操作系統(tǒng)類型
Architecture: x86_64 #宿主機架構(gòu)
CPUs: 1 #宿主機 CPU 數(shù)量
Total Memory: 1.924GiB #宿主機總內(nèi)存
Name: docker-server1.magedu.net #宿主機 hostname
ID: ZFPD:UIA5:SR6E:Y6SS:52QL:5MPT:VDY3:ATVI:QMVG:HAFF:MN74:2HPD #宿主機ID
Docker Root Dir: /var/lib/docker #宿主機數(shù)據(jù)保存目錄
Debug Mode (client): false #client 端是否開啟 debug
Debug Mode (server): false #server 端是否開啟 debug
Registry: https://index.docker.io/v1/ #鏡像倉庫
Labels: #其他標簽
Experimental: false #是否測試版
Insecure Registries: #非安全的鏡像倉庫
  127.0.0.0/8
Live Restore Enabled: false #是否開啟活動重啟(重啟 docker-daemon 不關(guān)閉容器)
Product License: Community Engine #產(chǎn)品許可信息
WARNING: No swap limit support #系統(tǒng)警告信息(沒有開啟 swap 資源限制)
root@docker-server1:~#
1.2.7: 解決不支持 swap 限制警告
root@docker-server1:~# vim /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 cgroup_enable=memory"
swapaccount=1"
# update-grub
# reboot
1.2.8: docker 存儲引擎

目前 docker 的默認存儲引擎為 overlay2, 不同的存儲引擎需要相應的系統(tǒng)支持,如需要磁盤分區(qū)的時候傳遞 d-type 文件分層功能,即需要傳遞內(nèi)核參數(shù)開啟格式化磁盤的時候的指定功能。

歷史更新信息:
https://github.com/moby/moby/blob/master/CHANGELOG.md
官方文檔關(guān)于存儲引擎的選擇文檔:
https://docs.docker.com/storage/storagedriver/select-storage-driver/

存儲驅(qū)動類型

AUFS(AnotherUnionFS)是一種 Union FS,是文件級的存儲驅(qū)動。所謂 UnionFS就是把不同物理位置的目錄合并 mount 到同一個目錄中。簡單來說就是支持將不同目錄掛載到同一個虛擬文件系統(tǒng)下的文件系統(tǒng)。這種文件系統(tǒng)可以一層一層地疊加修改文件。無論底下有多少層都是只讀的,只有最上層的文件系統(tǒng)是可寫的。當需要修改一個文件時, AUFS 創(chuàng)建該文件的一個副本,使用 CoW 將文件從只讀層復制到可寫層進行修改,結(jié)果也保存在可寫層。在 Docker 中,底
下的只讀層就是 image,可寫層就是 Container,是 Docker 18.06 及更早版本的首選存儲驅(qū)動程序,在內(nèi)核 3.13 上運行 Ubuntu 14.04 時不支持 overlay2。

Overlay:一種 Union FS 文件系統(tǒng), Linux 內(nèi)核 3.18 后支持。

overlay2: Overlay 的升級版,到目前為止,所有 Linux 發(fā)行版推薦使用的存儲類
型。

devicemapper:是 CentOS 和 RHEL 的推薦存儲驅(qū)動程序,因為之前的內(nèi)核版本不支持 overlay2,但是當前較新版本的 CentOS 和 RHEL 現(xiàn)在已經(jīng)支持 overlay2,因此推薦使用 overlay2。

ZFS(Sun-2005)/btrfs(Oracle-2007):目前沒有廣泛使用。

vfs:用于測試環(huán)境,適用于無法使用 copy-on-write 文件系統(tǒng)的情況。 此存儲
驅(qū)動程序的性能很差,通常不建議用于生產(chǎn)。

Docker 官方推薦首選存儲引擎為 overlay2, devicemapper 存在使用空間方面的一些限制, 雖然可以通過后期配置解決,但是官方依然推薦使用 overlay2,以下是網(wǎng)上查到的部分資料:
https://www.cnblogs.com/youruncloud/p/5736718.html

image.png

如果 docker 數(shù)據(jù)目錄是一塊單獨的磁盤分區(qū)而且是 xfs 格式的, 那么需要在格式化的時候加上參數(shù)-n ftype=1, 否則后期在啟動容器的時候會報錯不支持 dtype。

image.png

Centos 7.2 報錯界面

image.png

Centos 7.3 已修復此問題

1.2.9: docker 服務進程

通過查看 docker 進程,了解 docker 的運行及工作方式

1.2.9.1: 查看宿主機進程樹

Docker 版本:
Server: Docker Engine - Community
 Engine:
  Version: 18.09.7
  API version: 1.39 (minimum version 1.12)
  Go version: go1.10.8
  Git commit: 2d0083d
  Built: Thu Jun 27 17:26:28 2019
  OS/Arch: linux/amd64
  Experimental: false
image.png

1.2.9.2:查看 containerd 進程關(guān)系

有四個進程:
dockerd: 被 client 直接訪問,其父進程為宿主機的 systemd 守護進程。
docker-proxy: 實現(xiàn)容器通信, 其父進程為 dockerd
containerd:被 dockerd 進程調(diào)用以實現(xiàn)與 runc 交互。
containerd-shim: 真正運行容器的載體, 其父進程為 containerd。

image.png

1.2.9.3: containerd-shim 命令使用

[root@node1 ~]# containerd-shim -h
Usage of containerd-shim:
-address string
grpc address back to main containerd
-containerd-binary containerd publish
path to containerd binary (used for containerd publish) (default "cont
-criu string
path to criu binary
-debug
enable debug output in logs
-namespace string
namespace that owns the shim
-runtime-root string
root directory for the runtime (default "/run/containerd/runc")
-socket string
abstract socket path to serve
-systemd-cgroup
set runtime to use systemd-cgroup
-workdir string
path used to storge large temporary data

1.2.9.4:容器的創(chuàng)建與管理過程

通信流程:
1.dockerd 通過 grpc 和 containerd 模塊通信(runc)交換, dockerd 和 containerd通信的 socket 文件: /run/containerd/containerd.sock。
2. containerd 在 dockerd 啟動時被啟動, 然后 containerd 啟動 grpc 請求監(jiān)聽,containerd 處理 grpc 請求,根據(jù)請求做相應動作。
/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
3. 若是創(chuàng)建容器, containerd 拉起一個 container-shim 容器進程 , 并進行相應的創(chuàng)建操作。
4. container-shim 被拉起后, start/exec/create 拉起 runC 進程,通過 exit、 control文件和 containerd 通信,通過父子進程關(guān)系和 SIGCHLD(信號)監(jiān)控容器中進程狀態(tài)。
5. 在整個容器生命周期中, containerd 通過 epoll 監(jiān)控容器文件,監(jiān)控容器事件。

1.2.9.5: grpc 簡介:
gRPC 是 Google 開發(fā)的一款高性能、開源和通用的 RPC 框架,支持眾多語言客戶端。
https://www.grpc.io/

1.3: docker 鏡像加速配置:

國內(nèi)下載國外的鏡像有時候會很慢,因此可以更改 docker 配置文件添加一個加速器, 可以通過加速器達到加速下載鏡像的目的。

1.3.1:獲取加速地址:

瀏覽器打開 http://cr.console.aliyun.com, 注冊或登錄阿里云賬號,點擊左側(cè)的鏡像加速器, 將會得到一個專屬的加速地址, 而且下面有使用配置說明:

[圖片上傳失敗...(image-ccd469-1594221009349)]

1.3.2:生成配置文件
[root@docker-server1 ~]# mkdir -p /etc/docker
[root@docker-server1 ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
> {
> "registry-mirrors": ["https://9916w1ow.mirror.aliyuncs.com"]
> }
> EOF
{
"registry-mirrors": ["https://9916w1ow.mirror.aliyuncs.com"]
}
[root@docker-server1 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://9916w1ow.mirror.aliyuncs.com"]
}

1.3.3: 重啟 docke 服務

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

1.4: Docker 鏡像管理

Docker 鏡像含有啟動容器所需要的文件系統(tǒng)及所需要的內(nèi)容, 因此鏡像主要用于創(chuàng)建并啟動 docker 容器。

Docker 鏡像含里面是一層層文件系統(tǒng),叫做 Union File System(Union FS 聯(lián)合文件系統(tǒng)), 2004 年由紐約州立大學石溪分校開發(fā),聯(lián)合文件系統(tǒng)可以將多個目錄掛載到一起從而形成一整個虛擬文件系統(tǒng),該虛擬文件系統(tǒng)的目錄結(jié)構(gòu)就像普通 linux 的目錄結(jié)構(gòu)一樣, docker 通過這些文件再加上宿主機的內(nèi)核提供了一個 linux 的虛擬環(huán)境,每一層文件系統(tǒng)我們叫做一層 layer,聯(lián)合文件系統(tǒng)可以對每一層文件系統(tǒng)設置三種權(quán)限,只讀(readonly)、讀寫(readwrite)和寫出whiteout-able),但是 docker 鏡像中每一層文件系統(tǒng)都是只讀的,構(gòu)建鏡像的時候,從一個最基本的操作系統(tǒng)開始,每個構(gòu)建的操作都相當于做一層的修改,增加了一層文件系統(tǒng),一層層往上疊加,上層的修改會覆蓋底層該位置的可見性,這也很容易理解,就像上層把底層遮住了一樣,當使用鏡像的時候,我們只會看到一個完全的整體,不知道里面有幾層也不需要知道里面有幾層,結(jié)構(gòu)如下:

image.png
# pwd
/usr/local/src
#mkdir a b system
#touch a/a.txt b/b.txt
#mount -t aufs -o dirs=./a:./b none ./system/
#tree system/
system/
├── a.txt
└── b.txt

0 directories, 2 file

一個典型的 Linux 文件系統(tǒng)由 bootfs 和 rootfs 兩部分組成, bootfs(boot filesystem) 主要包含 bootloader 和 kernel, bootloader 主要用于引導加載 kernel,當 kernel 被加載到內(nèi)存中后 bootfs 會被 umount 掉, rootfs (root file system) 包
含的就是典型 Linux 系統(tǒng)中的/dev, /proc, /bin, /etc 等標準目錄和文件, 下圖就是 docker image 中最基礎的兩層結(jié)構(gòu),不同的 linux 發(fā)行版(如 ubuntu和 CentOS ) 在 rootfs 這一層會有所區(qū)別。

但是對于 docker 鏡像通常都比較小, 官方提供的 centos 基礎鏡像在 200MB 左右,一些其他版本的鏡像甚至只有幾 MB, docker 鏡像直接調(diào)用宿主機的內(nèi)核,鏡像中只提供 rootfs,也就是只需要包括最基本的命令、工具和程序庫就可以
了, 比如 alpine 鏡像,在 5M 左右。

下圖就是有兩個不同的鏡像在一個宿主機內(nèi)核上實現(xiàn)不同的 rootfs。

image.png

容器、 鏡像父鏡像:

image.png
小筆記
#導出鏡像
docker save centos > /opt/centos.tar.gz

docker 命令是最常使用的 docker 客戶端命令,其后面可以加不同的參數(shù)以實現(xiàn)響應的功能,常用的命令如下:

1.4.1: 搜索鏡像:

在官方的 docker 倉庫中搜索指定名稱的 docker 鏡像, 也會有很多鏡像。

[root@docker-server1 ~]# docker search centos:7.2.1511 #帶指定版本號
[root@docker-server1 ~]# docker search centos #不帶版本號默認 latest
1.4.2: 下載鏡像

從 docker 倉庫將鏡像下載到本地, 命令格式如下:

# docker pull 倉庫服務器:端口/項目名稱/鏡像名稱:tag(版本)號
[root@docker-server1 ~]# docker pull alpine
[root@docker-server1 ~]# docker pull nginx
[root@docker-server1 ~]# docker pull hello-world
[root@docker-server1 ~]# docker pull centos
小筆記
#查看鏡像歷史
docker history centos
1.4.3: 查看本地鏡像:

#下載完成的鏡像比下載的大,因為下載完成后會解壓

[root@docker-server1 ~]# docker images  

REPOSITORY #鏡像所屬的倉庫名稱
TAG #鏡像版本號(標識符), 默認為 latest
IMAGE ID #鏡像唯一 ID 標示
CREATED #鏡像創(chuàng)建時間
VIRTUAL SIZE #鏡像的大小
1.4.4: 鏡像導出

可以將鏡像從本地導出為一個壓縮文件,然后復制到其他服務器進行導入使用。

#導出方法 1:  
[root@docker-server1 ~]# docker save centos -o /opt/centos.tar.gz
[root@docker-server1 ~]# ll /opt/centos.tar.gz
-rw------- 1 root root 205225472 Nov 1 03:52 /opt/centos.tar.gz
#導出方法 2:
[root@docker-server1 ~]# docker save centos > /opt/centos-1.tar.gz
[root@docker-server1 ~]# ll /opt/centos-1.tar.gz
-rw-r--r-- 1 root root 205225472 Nov 1 03:52 /opt/centos-1.tar.gz
#查看鏡像內(nèi)容:  
[root@docker-server1 ~]# cd /opt/
[root@docker-server1 opt]# tar xvf centos.tar.gz
[root@docker-server1 opt]# cat manifest.json #包含了鏡像的相關(guān)配置, 配置文件、分層
[{"Config":"196e0ce0c9fbb31da595b893dd39bc9fd4aa78a474bbdc21459a3ebe855b
7768.json","RepoTags":["docker.io/centos:latest"],"Layers":["892ebb5d1299cbf459f6
7aa070f29fdc6d83f4025c58c090e9a69bd4f7af436b/layer.tar"]}]
#分層為了方便文件的共用,即相同的文件可以共用  
[{"Config":" 配 置 文 件 .json","RepoTags":["docker.io/nginx:latest"],"Layers":[" 分 層
1/layer.tar","分層 2 /layer.tar","分層 3 /layer.tar"]}]
1.4.5: 鏡像導入
#將鏡像導入到 docker
[root@docker-server1 ~]# scp /opt/centos.tar.gz 192.168.10.206:/opt/
[root@docker-server2 ~]# docker load < /opt/centos.tar.gz

驗證鏡像

docker images
1.4.6:刪除鏡像
[root@docker-server1 opt]# docker rmi centos

#獲取運行參數(shù)幫助

[root@linux-docker opt]# docker daemon --help  

總結(jié): 企業(yè)使用鏡像及常見操作:
搜索、 下載、導出、導入、刪除

命令總結(jié):
# docker load -i centos-latest.tar.xz #導入本地鏡像
# docker save > /opt/centos.tar #centos #導出鏡像
# docker rmi 鏡像 ID/鏡像名稱 #刪除指定 ID 的鏡像,通過鏡像啟動容器的時
候鏡像不能被刪除,除非將容器全部關(guān)閉
# docker rm 容器 ID/容器名稱 #刪除容器
# docker rm 容器 ID/容器名-f #強制刪除正在運行的容器

1.5: 容器操作基礎命令

命令格式

docker run [選項] [鏡像名] [shell 命令] [參數(shù)]
docker run [參數(shù)選項] [鏡像名稱,必須在所有選項的后面] [/bin/echo 'hellowold'] #單次執(zhí)行,沒有自定義容器名稱
docker run centos /bin/echo 'hello wold' #啟動的容器在執(zhí)行完 shel 命令就退出了
1.5.1:從鏡像啟動一個容器

會直接進入到容器, 并隨機生成容器 ID 和名稱

[root@docker-server1 ~]# docker run -it docker.io/centos bash
[root@11445b3a84d3 /]#  

#退出容器不注銷
ctrl+p+q

1.5.2: 顯示正在運行的容器
[root@linux-docker ~]# docker ps  
1.5.3: 顯示所有容器:

包括當前正在運行以及已經(jīng)關(guān)閉的所有容器:

[root@linux-docker ~]# docker ps -a  
1.5.4: 刪除運行中的容器:

即使容正在運行當中, 也會被強制刪除掉

[root@docker-server1 ~]# docker rm -f 11445b3a84d3  
1.5.5: 隨機映射端口
[root@docker-server1 ~]# docker pull nginx #下載 nginx 鏡像
[root@docker-server1 ~]# docker run -P docker.io/nginx #前臺啟動并隨機映射本地端口到容器的 80  

前臺啟動的會話窗口無法進行其他操作,除非退出, 但是退出后容器也會退出

隨機端口映射, 其實是默認從 32768 開始

1.5.6: 指定端口映射
方式 1:本地端口 81 映射到容器 80 端口:
# docker run -p 81:80 --name nginx-test-port1 nginx
方式 2:本地 IP:本地端口:容器端口
# docker run -p 192.168.10.205:82:80 --name nginx-test-port2 docker.io/nginx
方式 3:本地 IP:本地隨機端口:容器端口
# docker run -p 192.168.10.205::80 --name nginx-test-port3 docker.io/nginx
方式 4:本機 ip:本地端口:容器端口/協(xié)議,默認為 tcp 協(xié)議
# docker run -p 192.168.10.205:83:80/udp --name nginx-test-port4
docker.io/nginx
方式 5:一次性映射多個端口+協(xié)議:
# docker run -p 86:80/tcp -p 443:443/tcp -p 53:53/udp --name nginx-test-port5
docker.io/nginx
1.5.7: 查看容器已經(jīng)映射的端口
[root@docker-server1 ~]# docker port nginx-test-port5  
1.5.8: 自定義容器名稱
[root@docker-server1 ~]# docker run -it --name nginx-test nginx  
1.5.9: 后臺啟動容器
[root@docker-server1 ~]# docker run -d -P --name nginx-test1 docker.io/nginx
9aaad776850bc06f516a770d42698e3b8f4ccce30d4b142f102ed3cb34399b31  
1.5.10:創(chuàng)建并進入容器:
[root@docker-server1 ~]# docker run -t -i --name test-centos2 docker.io/centos
/bin/bash
[root@a8fb69e71c73 /]# #創(chuàng)建容器后直接進入, 執(zhí)行 exit 退出后容器關(guān)閉  

[root@docker-server1 ~]# docker run -d --name centos-test1 docker.io/centos
2cbbec43ba939476d798a5e1c454dd62d4d893ee12a09b587556ba6395353152  
1.5.11:單次運行
#容器退出后自動刪除:
[root@linux-docker opt]# docker run -it --rm --name nginx-delete-test
docker.io/nginx
1.5.12: 傳遞運行命令

容器需要有一個前臺運行的進程才能保持容器的運行, 通過傳遞運行參數(shù)是一種方式, 另外也可以在構(gòu)建鏡像的時候指定容器啟動時運行的前臺命令。

[root@docker-server1 ~]# docker run -d centos /usr/bin/tail -f '/etc/hosts'
1.5.13:容器的啟動和關(guān)閉
[root@docker-server1 ~]# docker stop f821d0cd5a99
[root@docker-server1 ~]# docker start f821d0cd5a99

1.5.14: 進入到正在運行的容器

1.5.14.1:使用 attach 命令

使用方式為 docker attach 容器名, attach 類似于 vnc, 操作會在各個容器界面顯示, 所有使用此方式進入容器的操作都是同步顯示的且 exit 后容器將被關(guān)閉, 且使用 exit 退出后容器關(guān)閉,不推薦使用, 需要進入到有 shell 環(huán)境的容器,比如 centos 為例:

[root@s1 ~]# docker run -it centos bash
[root@63fbc2d5a3ec /]#
[root@s1 ~]# docker attach 63fbc2d5a3ec
[root@63fbc2d5a3ec /]#

在另外一個窗口啟動測試頁面是否同步

1.5.14.2:使用 exec 命令

執(zhí)行單次命令與進入容器,不是很推薦此方式, 雖然 exit 退出容器還在運行

1.5.14.3: 使用 nsenter 命令

推薦使用此方式, nsenter 命令需要通過 PID 進入到容器內(nèi)部,不過可以使用 docker inspect 獲取到容器的 PID:

[root@docker-server1 ~]# yum install util-linux #安裝 nsenter 命令
[root@docker-server1 ~]# docker inspect -f "{{.NetworkSettings.IPAddress}}" 91fc190cb538
172.17.0.2
[root@docker-server1 ~]# docker inspect -f "{{.State.Pid}}" mydocker #獲取到某個docker 容器的 PID,可以通過 PID 進入到容器內(nèi)
[root@docker-server1 ~]# docker inspect -f "{{.State.Pid}}" centos-test3
5892
[root@docker-server1 ~]# nsenter -t 5892 -m -u -i -n -p     
-m  掛載namespace
-u  uts
-i  ipc
-n  network
-p  pid
[root@66f511bb15af /]# ls

1.5.14.4: 腳本方式

將 nsenter 命令寫入到腳本進行調(diào)用,如下:

[root@docker-server1 ~]# cat docker-in.sh
#!/bin/bash
    docker_in(){
    NAME_ID=$1
    PID=$(docker inspect -f "{{.State.Pid}}" ${NAME_ID})
    nsenter -t ${PID} -m -u -i -n -p
}
docker_in $1

#測試腳本是否可以正常進入到容器且退出后仍然正常運行:
[root@docker-server1 ~]# chmod a+x docker-in.sh
[root@docker-server1 ~]# ./docker-in.sh centos-test3
[root@66f511bb15af /]# pwd
/
[root@66f511bb15af /]# exit
logout
[root@docker-server1 ~]# ./docker-in.sh centos-test3
[root@66f511bb15af /]# exit
Logout

1.5.15: 查看容器內(nèi)部的 hosts 文件

[root@docker-server1 ~]# docker run -i -t --name test-centos3 docker.io/centos
/bin/bash
[root@056bb4928b64 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4 056bb4928b64 #默認會將實例的 ID 添加到自己的 hosts 文件

1.5.16: 批量關(guān)閉正在運行的容器

[root@docker-server1 ~]# docker stop $(docker ps -a -q) #正常關(guān)閉所有運行中的容器

1.5.17: 批量強制關(guān)閉正在運行的容器

[root@docker-server1 ~]# docker kill $(docker ps -a -q) #強制關(guān)閉所有運行中的容器

1.5.18: 批量刪除已退出容器

[root@docker-server1 ~]# docker rm -f `docker ps -aq -f status=exited`

1.5.19:批量刪除所有容器

[root@docker-server1 ~]# docker rm -f $(docker ps -a -q)

1.5.20: 指定容器 DNS

Dns 服務,默認采用宿主機的 dns 地址
一是將 dns 地址配置在宿主機
二是將參數(shù)配置在 docker 啟動腳本里面 –dns=1.1.1.1

[root@docker-server1 ~]# docker run -it --rm --dns 223.6.6.6 centos bash
[root@afeb628bf074 /]# cat /etc/resolv.conf
nameserver 223.6.6.6

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

友情鏈接更多精彩內(nèi)容