Docker簡介
【1】Docker是一個開源的容器引擎,它有助于更快地交付應用, Docker可將應用程式和基礎設施層隔離,并且能將基礎設施當作程式一樣進行管理,使用 Docker可更快地打包、測驗以及部署應用程式,并可以縮短從撰寫到部署運行代碼的周期,
【2】Docker的優點:
1、簡化程式
Docker 讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發布到任何流行的 Linux 機器上,便可以實作虛擬化,Docker改變了虛擬化的方式,使開發者可以直接將自己的成果放入Docker中進行管理,方便快捷已經是 Docker的最大優勢,過去需要用數天乃至數周的任務,在Docker容器的處理下,只需要數秒就能完成,
2、便捷開發
Docker 鏡像中包含了運行環境和配置,所以 Docker 可以簡化部署多種應用實體作業,比如 Web 應用、后臺應用、資料庫應用、大資料應用比如 Hadoop 集群、訊息佇列等等都可以打包成一個鏡像部署,
3、節省開支
云計算時代到來,使開發者不必為了追求效果而配置高額的硬體,Docker 改變了高性能必然高價格的思維定勢,Docker 與云的結合,讓云空間得到更充分的利用,不僅解決了硬體管理的問題,也改變了虛擬化的方式,
Docker的架構
【1】圖示

【2】引數說明
1)Docker daemon( Docker守護行程)
Docker daemon是一個運行在宿主機( DOCKER-HOST)的后臺行程,可通過 Docker客戶端與之通信,
2)Client( Docker客戶端)
Docker客戶端是 Docker的用戶界面,它可以接受用戶命令和配置標識,并與 Docker daemon通信,圖中, docker build等都是 Docker的相關命令,
3)Images( Docker鏡像)
Docker鏡像是一個只讀模板,它包含創建 Docker容器的說明,它和系統安裝光碟有點像,使用系統安裝光碟可以安裝系統,同理,使用Docker鏡像可以運行 Docker鏡像中的程式,
4)Container(容器)
容器是鏡像的可運行實體,鏡像和容器的關系有點類似于面向物件中,類和物件的關系,可通過 Docker API或者 CLI命令來啟停、移動、洗掉容器,
5)Registry
Docker Registry是一個集中存盤與分發鏡像的服務,構建完 Docker鏡像后,就可在當前宿主機上運行,但如果想要在其他機器上運行這個鏡像,就需要手動復制,此時可借助 Docker Registry來避免鏡像的手動復制,
一個 Docker Registry可包含多個 Docker倉庫,每個倉庫可包含多個鏡像標簽,每個標簽對應一個 Docker鏡像,這跟 Maven的倉庫有點類似,如果把 Docker Registry比作 Maven倉庫的話,那么 Docker倉庫就可理解為某jar包的路徑,而鏡像標簽則可理解為jar包的版本號,
Docker Registry可分為公有Docker Registry和私有Docker Registry, 最常?的Docker Registry莫過于官?的Docker Hub, 這也是默認的Docker Registry, Docker Hub上存放著?量優秀的鏡像, 我們可使?Docker命令下載并使?,
Docker 的安裝(社區版)
【1】以CentOS為例:
1)Docker 要求 CentOS 系統的內核版本高于 3.10
通過 uname -r 命令查看你當前的內核版本
2)使用 root 權限登錄 Centos,確保 yum 包更新到最新,
yum -y update
3)卸載舊版本(如果安裝過舊版本的話)
sudo yum remove -y docker*
4)安裝需要的軟體包, yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的
yum install -y yum-utils
5)設定yum源,并更新 yum 的包索引
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum makecache fast
6)可以查看所有倉庫中所有docker版本,并選擇特定版本安裝
yum list docker-ce --showduplicates | sort -r
7)安裝docker
yum install -y docker-ce-3:19.03.9-3.el7.x86_64 # 這是指定版本安裝
8)啟動并加入開機啟動
systemctl start docker && systemctl enable docker
9)驗證安裝是否成功(有client和service兩部分表示docker安裝啟動都成功了)
docker version
10)配置docker鏡像加速器
1.借助阿里云的鏡像加速器,如圖

2.操作
cd /etc/docker //查看有沒有 daemon.json,這是docker默認的組態檔,如果沒有新建,如果有,則修改, vim daemon.json { "registry-mirrors": ["https://o9c4i52m.mirror.aliyuncs.com"] } //保存退出,重啟docker服務: systemctl daemon-reload systemctl restart docker
11)卸載docker
yum remove -y docker* rm -rf /etc/systemd/system/docker.service.d rm -rf /var/lib/docker rm -rf /var/run/docker
Docker常用命令
【1】鏡像相關命令
1)搜索鏡像
可使用 docker search命令搜索存放在 Docker Hub中的鏡像,執行該命令后, Docker就會在Docker Hub中搜索含有 java這個關鍵詞的鏡像倉庫,
docker search java
串列包含五列,含義如下:
- NAME:鏡像倉庫名稱,
- DESCRIPTION:鏡像倉庫描述,
- STARS:鏡像倉庫收藏數,表示該鏡像倉庫的受歡迎程度,類似于 GitHub的 stars0
- OFFICAL:表示是否為官方倉庫,該列標記為[0K]的鏡像均由各軟體的官方專案組創建和維護,
- AUTOMATED:表示是否是自動構建的鏡像倉庫,
2)下載鏡像
使用命令docker pull命令即可從 Docker Registry上下載鏡像,執行該命令后,Docker會從 Docker Hub中的 java倉庫下載最新版本的 Java鏡像,如果要下載指定版本則在java后面加冒號指定版本
docker pull java:8
3)列出鏡像
使用 docker images命令即可列出已下載的鏡像
docker images
串列含義如下
- REPOSITORY:鏡像所屬倉庫名稱,
- TAG:鏡像標簽,默認是 latest,表示最新,
- IMAGE ID:鏡像 ID,表示鏡像唯一標識,
- CREATED:鏡像創建時間,
- SIZE: 鏡像大小,
4)洗掉本地鏡像
使用 docker rmi命令即可洗掉指定鏡像【鏡像ID,鏡像名都可以】,強制洗掉加 -f
docker rmi java
洗掉所有鏡像
docker rmi $(docker images -q)
【2】容器相關命令
1)新建并啟動容器
使用以下docker run命令即可新建并啟動一個容器,該命令是最常用的命令,它有很多選項,下面將列舉一些常用的選項, -d選項:表示后臺運行 -P選項:隨機埠映射 -p選項:指定埠映射,有以下四種格式, -- ip:hostPort:containerPort -- ip::containerPort -- hostPort:containerPort -- containerPort --net選項:指定網路模式,該選項有以下可選引數: --net=bridge:默認選項,表示連接到默認的網橋, --net=host:容器使用宿主機的網路, --net=container:NAME-or-ID:告訴 Docker讓新建的容器使用已有容器的網路配置, --net=none:不配置該容器的網路,用戶可自定義網路配置, 示例:docker run -d -p 91:80 nginx 這樣就能啟動一個 Nginx容器,在本例中,為 docker run添加了兩個引數,含義如下: -d 后臺運行 -p 宿主機埠:容器埠 #開放容器埠到宿主機埠 訪問 http://Docker宿主機 IP:91/,將會看到nginx的主界面, 需要注意的是,使用 docker run命令創建容器時,會先檢查本地是否存在指定鏡像,如果本地不存在該名稱的鏡像, Docker就會自動從 Docker Hub下載鏡像并啟動一個 Docker容器,
2)列出容器
用 docker ps命令即可列出運行中的容器 docker ps 如需列出所有容器(包括已停止的容器),可使用-a引數,串列包含了7列,含義如下 - CONTAINER_ID:表示容器 ID, - IMAGE:表示鏡像名稱, - COMMAND:表示啟動容器時運行的命令, - CREATED:表示容器的創建時間, - STATUS:表示容器運行的狀態,UP表示運行中, Exited表示已停止, - PORTS:表示容器對外的埠號, - NAMES:表示容器名稱,該名稱默認由 Docker自動生成,也可使用 docker run命令的--name選項自行指定,
3)停止容器
使用 docker stop命令,即可停止容器
docker stop f0b1c8ab3633
其中f0b1c8ab3633是容器 ID,當然也可使用 docker stop容器名稱來停止指定容器
4)強制停止容器
可使用 docker kill命令發送 SIGKILL信號來強制停止容器
docker kill f0b1c8ab3633
5)啟動已停止的容器
使用docker run命令,即可新建并啟動一個容器,對于已停止的容器,可使用 docker start命令來啟動
docker start f0b1c8ab3633
6)查看容器所有資訊
docker inspect f0b1c8ab3633
7)查看容器日志
docker container logs f0b1c8ab3633
8)查看容器里的行程
docker top f0b1c8ab3633
9)容器與宿主機相互復制檔案
從容器里面拷檔案到宿主機: docker cp 容器id:要拷貝的檔案在容器里面的路徑 宿主機的相應路徑 如:docker cp 7aa5dc458f9d:/etc/nginx/nginx.conf /mydata/nginx 從宿主機拷檔案到容器里面: docker cp 要拷貝的宿主機檔案路徑 容器id:要拷貝到容器里面對應的路徑
10)進入容器
使用docker exec命令用于進入一個正在運行的docker容器,如果docker run命令運行容器的時候,沒有使用-it引數,就要用這個命令進入容器,一旦進入了容器,就可以在容器的 Shell 執行命令了
docker exec -it f0b1c8ab3633 /bin/bash (有的容器需要把 /bin/bash 換成 sh)
11)容器內安裝vim、ping、ifconfig等指令
apt-get update apt-get install vim #安裝vim apt-get install iputils-ping #安裝ping apt-get install net-tools #安裝ifconfig
12)洗掉容器
使用 docker rm命令即可洗掉指定容器 docker rm f0b1c8ab3633 該命令只能洗掉已停止的容器,如需洗掉正在運行的容器,可使用-f引數,強制洗掉所有容器 docker rm -f $(docker ps -a -q)
Docker的網路模式
【1】bridge模式:使用–net =bridge指定,默認設定;
1)bridge模式是Docker默認的網路設定,此模式會為每一個容器分配Network Namespace、設定IP等,并將并將一個主機上的Docker容器連接到一個虛擬網橋上,當Docker server啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上,虛擬網橋的作業方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中,接下來就要為容器分配IP了,Docker會從RFC1918所定義的私有IP網段中,選擇一個和宿主機不同的IP地址和子網分配給docker0,連接到docker0的容器就從這個子網中選擇一個未占用的IP使用,如一般Docker會使用172.17.0.0/16這個網段,并將172.17.42.1/16分配給docker0網橋(在主機上使用ifconfig命令是可以看到docker0的,可以認為它是網橋的管理埠,在宿主機上作為一塊虛擬網卡使用),
2)這種方式外網是訪問不了容器內部的,但是可以在宿主的服務器上對虛擬網段進行訪問,所以需要對宿主機上的埠與虛擬網段的埠進行映射,這樣外網訪問宿主機上的埠就會直接轉到虛擬網段的埠,
【2】host模式:使用–net =host指定;
1)如果啟動容器的時候使用host模式,那么這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace,容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和埠,
2)這種可以理解為宿主機和容器的埠全部映射的方式,如80對80.
【3】none模式:使用–net =none指定;
1)在none模式下,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網路配置,也就是說,這個Docker容器沒有網卡、IP、路由等資訊,需要我們自己為Docker容器添加網卡、配置IP等,
【4】container模式:使用–net =container:NAMEorID指定,
1)這個模式指定新創建的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享,新創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、埠范圍等,同樣,兩個容器除了網路方面,其他的如檔案系統、行程串列等還是隔離的,兩個容器的行程可以通過lo網卡設備通信,
使用Dockerfile構建Docker鏡像
【1】Dockerfile常用指令
| 命令 | 用途 |
| FROM | 基礎鏡像檔案 |
| RUN | 構建鏡像階段執行命令 |
| ADD | 添加檔案,從src目錄復制檔案到容器的dest,其中 src可以是 Dockerfile所在目錄的相對路徑,也可以是一個 URL,還可以是一個壓縮包 |
| COPY | 拷貝檔案,和ADD命令類似,但不支持URL和壓縮包 |
| CMD | 容器啟動后執行命令 |
| EXPOSE | 宣告容器在運行時對外提供的服務埠 |
| WORKDIR | 指定容器作業路徑 |
| ENV | 指定環境變數 |
| ENTRYPINT | 容器入口, ENTRYPOINT和 CMD指令的目的一樣,都是指定 Docker容器啟動時執行的命令,可多次設定,但只有最后一個有效, |
| USER | 該指令用于設定啟動鏡像時的用戶或者 UID,寫在該指令后的 RUN、 CMD以及 ENTRYPOINT指令都將使用該用戶執行命令, |
| VOLUME | 指定掛載點,該指令使容器中的一個目錄具有持久化存盤的功能,該目錄可被容器本身使用,也可共享給其他容器,當容器中的應用有持久化資料的需求時可以在 Dockerfile中使用該指令,格式為: VOLUME["/data"], |
注意事項:
1)RUN命令在 image 檔案的構建階段執行,執行結果都會打包進入 image 檔案;CMD命令則是在容器啟動后執行,另外,一個 Dockerfile 可以包含多個RUN命令,但是只能有一個CMD命令,
2)指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否則它會覆寫CMD命令,
【2】使用Dockerfile構建微服務鏡像【這里是以一個eureka的服務作為jar包】
1)將jar包上傳linux服務器/usr/local/docker-app/demo/eureka目錄【自己建的】,在jar包所在目錄創建名為Dockerfile的檔案
2)在Dockerfile中添加以下內容【如使用vim Dockerfile】
# 基于哪個鏡像 From java:8 # 復制檔案到容器 ADD mydemo-eureka-server-0.0.1-SNAPSHOT.jar /app.jar # 宣告需要暴露的埠 EXPOSE 8761 # 配置容器啟動后執行的命令 ENTRYPOINT java ${JAVA_OPTS} -jar /app.jar
3)使用docker build命令構建鏡像【使用-t選項指定了鏡像的標簽,啟動時使用標簽啟動】
# 格式: docker build -t 鏡像名稱:標簽 Dockerfile的相對位置
docker build -t mydemo-eureka-server:0.0.1 .
4)啟動鏡像
# --cap-add=SYS_PTRACE 這個引數是讓docker能支持在容器里能執行jdk自帶類似jinfo,jmap這些命令,如果不需要在容器里執行這些命令可以不加 docker run -e JAVA_OPTS='-Xms1028M -Xmx1028M -Xmn512M -Xss512K -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256M' --cap-add=SYS_PTRACE -d -p 8761:8761 -v /log:/container-log mydemo-eureka-server:0.0.1 說明: 加-d可在后臺啟動,如 docker run -d -p 8761:8761 mydemo-eureka-server:0.0.1 -v 可以掛載一個主機上的目錄到容器的目錄 -v /宿主機目錄:/容器目錄 注意:容器的記憶體使用最大限制默認可以接近宿主機的物理記憶體,可以通過"-m"引數限制容器可以使用的最大記憶體: docker run -m Xmx1028M mydemo-eureka-server:0.0.1 #限制容器的最大使用記憶體為500M
5)訪問http://Docker宿主機IP:8761/,可正常顯示
6)將微服務鏡像發布到遠程鏡像倉庫
(1)docker login命令登錄鏡像倉庫
(2)需要將鏡像前面加個分組名(一般就是docker hub的賬戶名)
docker tag mydemo-eureka-server:0.0.1 cgf/mydemo-eureka-server:0.0.1
(3)將鏡像推送到遠程倉庫
docker push cgf/mydemo-eureka-server:0.0.1
Docker虛擬化原理
【1】傳統虛擬化和容器技術結構比較:傳統虛擬化技術是在硬體層面實作虛擬化,增加了系統呼叫鏈路的環節,有性能損耗;容器虛擬化技術以共享宿主機Kernel的方式實作,幾乎沒有性能損耗,
【2】docker利用的是宿主機的內核,而不需要Guest OS,因此,當新建一個容器時,docker不需要和虛擬機一樣重新加載一個作業系統內核,避免了尋址、加載作業系統內核這些比較費時費資源的程序,當新建一個虛擬機時,虛擬機軟體需要加載Guest OS,這個新建程序是分鐘級別的,而docker由于直接利用宿主機的作業系統,則省略了這個程序,因此新建一個docker容器只需要幾秒鐘,
【3】如圖(官網上的):

核心問題
【1】Docker是如何將機器的資源進行隔離的?
0)答案是聯合檔案系統,常見的有AUFS、Overlay、devicemapper、BTRFS和ZFS等,
1)聯合檔案系統原理(以Overlay2舉例說明):
原理:overlayfs在linux主機上只有兩層,一個目錄在下層,用來保存鏡像(docker),另外一個目錄在上層,用來存盤容器資訊,在overlayfs中,底層的目錄叫做lowerdir,頂層的目錄稱之為upperdir,對外提供統一的檔案系統為merged,當需要修改一個檔案時,使用COW(Copy-on-write)將檔案從只讀的Lower復制到可寫的Upper進行修改,結果也保存在Upper層,在Docker中,底下的只讀層就是image,可寫層就是Container,
圖示:

2)寫時復制 (CoW) 技術
所有驅動都用到的技術—寫時復制,Cow全稱copy-on-write,表示只是在需要寫時才去復制,這個是針對已有檔案的修改場景,比如基于一個image啟動多個Container,如果每個Container都去分配一個image一樣的檔案系統,那么將會占用大量的磁盤空間,而CoW技術可以讓所有的容器共享image的檔案系統,所有資料都從image中讀取,只有當要對檔案進行寫操作時,才從image里把要寫的檔案復制到自己的檔案系統進行修改,所以無論有多少個容器共享一個image,所做的寫操作都是對從image中復制到自己的檔案系統的副本上進行,并不會修改image的源檔案,且多個容器操作同一個檔案,會在每個容器的檔案系統里生成一個副本,每個容器修改的都是自己的副本,互相隔離,互不影響,使用CoW可以有效的提高磁盤的利用率,所以容器占用的空間是很少的,
查看容器占用磁盤大小指令:
# 查看所有容器的大小 cd /var/lib/docker/containers # 進入docker容器存盤目錄 du -sh * # 查看所有容器的大小 du -sh <容器完整id> #查看某一個容器的大小
3)用時分配 (allocate-on-demand):
用時分配是針對原本沒有這個檔案的場景,只有在要新寫入一個檔案時才分配空間,這樣可以提高存盤資源的利用率,比如啟動一個容器,并不會因為這個容器分配一些磁盤空間,而是當有新檔案寫入時,才按需分配新空間,
【2】docker中的鏡像分層技術的原理是什么呢?
1)docker使用共享技術減少鏡像存盤空間,所有鏡像層和容器層都保存在宿主機的檔案系統/var/lib/docker/中,由存盤驅動進行管理,盡管存盤方式不盡相同,但在所有版本的Docker中都可以共享鏡像層,在下載鏡像時,Docker Daemon會檢查鏡像中的鏡像層與宿主機檔案系統中的鏡像層進行對比,如果存在則不下載,只下載不存在的鏡像層,這樣可以非常節約存盤空間,
查看容器資源使用情況的指令:
docker stats # 回傳容器資源的實時使用情況,1秒重繪一次
docker stats --no-stream # 回傳容器當時的資源使用情況
說明:
默認情況下,stats 命令會每隔 1 秒鐘重繪一次輸出的內容直到你按下 ctrl + c,下面是輸出的主要內容: [CONTAINER]:以短格式顯示容器的 ID, [CPU %]:CPU 的使用情況, [MEM USAGE / LIMIT]:當前使用的記憶體和最大可以使用的記憶體, [MEM %]:以百分比的形式顯示記憶體使用情況, [NET I/O]:網路 I/O 資料, [BLOCK I/O]:磁盤 I/O 資料, [PIDS]:PID 號,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/521817.html
標籤:其他
下一篇:JAVA常見基礎知識點
