Docker进阶实战
文章目錄
- 前言
- 一、容器數據卷
- 1.數據卷介紹
- 2.數據卷使用
- 2.1 數據卷的常用命令
- 3.MySql在Docker中的持久化問題
- 4. 匿名和具名掛載
- 4.1 匿名掛載
- 4.2 具名掛載
- 4.3 掛載信息查看與權限寫入
- 二、DockerFile
- 1. 概述
- 2. 構建過程
- 2.1 基礎知識
- 2.2 DockerFile 指令
- 3. 實戰
- 3.1 構建centos 鏡像
- 3.2 構建tomcat 鏡像
- 三、DockerNet
- 1. 認識網絡模式
- 2. 默認網絡
- 2.1 Host
- 2.2 Container
- 2.3 None
- 2.4 Bridge
- 3. Docker:網絡模式詳解
- 3.1 Bridge模式的拓撲
- 3.2 Docker:網絡模式詳解
- 3.3 容器聯通
- 4. 自定義網絡
- 4.1 查看默認的網橋信息
- 4.2 自定義網絡
- 4.3 自定義網絡的好處
- 5.網絡連通
- 6. Redis集群部署實戰
- 7. SpringBoot微服務打包發布
- 四、Docker Compose
- 1. Compose 簡介
- 2. Compose 安裝
- 3. 使用
- 3.1 準備
- 3.2 創建 Dockerfile 文件
- 3.3 創建 docker-compose.yml
- 4 .使用 Compose 部署前后分離項目實戰
- 4.1 打包前后端項目
- 4.2 編寫DockerFile
- 4.3 編寫docker-compose.yaml
- 4.4 啟動部署
- 五、Docker Machine
- 六、Docker Swarm
- 總結
前言
Dokcer 進階
如果還沒想清楚,就用 蠻力算法 。——Ken Thompson
一、容器數據卷
1.數據卷介紹
Docker將運用與運行的環境打包形成容器運行, Docker容器產生的數據,如果不通過docker commit生成新的鏡像,使得數據做為鏡像的一部分保存下來, 那么當容器刪除后,數據自然也就沒有了。 為了能保存數據在Docker中我們使用卷。|
卷就是目錄或文件,存在于一個或多個容器中,由Docker掛載到容器,但卷不屬于聯合文件系統(Union FileSystem),因此能夠繞過聯合文件系統提供一些用于持續存儲或共享數據的特性:。
卷的設計目的就是數據的持久化,完全獨立于容器的生存周期,因此Docker不會在容器刪除時刪除其掛載的數據卷。
數據卷的特點:
1. 數據卷可在容器之間共享或重用數據
2. 卷中的更改可以直接生效
3. 數據卷中的更改不會包含在鏡像的更新中
4. 數據卷的生命周期一直持續到沒有容器使用它為止
容器之間的數據共享技術,Dokcer容器中產生的數據,同步到本地。核心就是目錄的掛載,講容器內部的目錄,掛載到Linux上面
小結:容器的持久化和同步操作!容器也是可以數據共享的!
2.數據卷使用
直接使用命令方式來掛載 -v # docker run -it -v 主機目錄/容器目錄 測試 # docker run -it -v /home/test:/home cnetos /bin/bash 啟動之后查看容器詳細信息 # docker inspect <容器id> > Mounts 掛載信息 > Type 類型 > Source 主機內地址 > Destination docker容器內地址
雙向綁定數據。數據互通。在本地主機修改即可,無需進入docker容器中。
2.1 數據卷的常用命令
1.創建數據卷 # docker volume create <卷名稱> 2.查看所有數據集 # docker volume ls 3.查看指定的數據卷信息 # docker volume inspect <卷名稱> { "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/my-vol/_data", "Name": "my-vol", "Options": {}, "Scope": "local" } 4.刪除數據卷 # docker volume rm <卷名稱> 5.刪除容器的時候刪除與之相關的數據卷 # docker rm -v ... > 數據卷是被設計用來持久化數據的,它的生命周期獨立于容器,Docker 不會在容器被刪除后自動刪除數據卷。 > 并且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的數據卷 。如果需要在刪除容器的同時移除數據卷。 > 可以在刪除容器的時候使用 docker rm -v 這個命令。 6.無主的數據卷可能會占據很多空間,要清理請使用以下命令 # docker volume prune使用 --mount創建數據卷掛載一個主機目錄作為數據卷
使用 --mount 標記可以指定掛載一個本地主機的目錄到容器中去。
上面的命令掛載主機的/src/webapp目錄到容器的/opt/webapp目錄。用戶可以放置一些程序到本地目錄中,來查看容器是否正常工作。本地目錄的路徑必須是絕對路徑,如果目錄不存在 Docker 會自動為你創建它。
Docker 掛載主機目錄的默認權限是讀寫 ,用戶也可以通過添加readonly 參數指定為只讀 。
$ docker run -d -P \ --name web \ # -v /src/webapp:/opt/webapp:ro \ --mount type=bind,source=/src/webapp,target=/opt/webapp,readonly \ training/webapp \ python app.py 加了readonly之后,就掛載為只讀了。如果你在容器內/src/webapp目錄新建文件,會顯示如下錯誤 /src/webapp # touch new.txt touch: new.txt: Read-only file system3.MySql在Docker中的持久化問題
實例
安裝MySql,MySql的數據持久化問題
4. 匿名和具名掛載
我們使用Docker與宿主機做關聯時,常常是要進行掛載數據和配置文件的,那么Dokcer中就提供了兩種掛載方式,分別是具名掛載與匿名掛載。顧名思義,具名就是有具體名稱的掛載方式,而匿名就是沒有名字,或者說沒有指定名字,而被系統隨機分配名字的方式。
掛載命令
匿名掛載,具名掛載,指定路徑掛載的命令區別如下:
-v 容器內路徑 #匿名掛載
-v 卷名:容器內路徑 #具名掛載
-v /宿主機路徑:容器內路徑 #指定路徑掛載
4.1 匿名掛載
如下運行并匿名掛載Nginx容器:
匿名掛載命令格式 # docker run -d -P --name nginx01 -v /etc/nginx nginx查看所有的數據卷volume的情況, VOLUME NAME這里的值是真實存在的目錄。
# docker volume ls DRIVER VOLUME NAME local 198f39c04b7705350088ad8f9ab6072068da3547db375f99bb305cbf92abdb9f local 10913c9dbecc738bf7ce2614bca085d23d8ea57998051e1967ab865476d7a845 local ba800c642e0e295b2a275e0d3809ddc6bd2d1f11565b4741dfea506fd6e0e4f6 local fc1eccb2b19c84dd769c572a0389658fefc3248b19b9bbe3573c3cd299fa28a0這種隨機名稱的掛載即為匿名掛載
4.2 具名掛載
如下運行并具名掛載Nginx容器:
具名掛載 # docker run -d -P --name nginx02 -v <具體名稱>:/etc/nginx nginx # docker volume ls DRIVER VOLUME NAME local 0cd45ab893fc13971219ac5127f9c0b02491635d76d94183b0261953bdb52d26 local 668a94251e562612880a2fdb03944d67d1acdbbdae6ef7c94bee8685644f2956 local e605f3dc4bf11ab693972592b55fb6911e5bf2083425fd58869c5f574998a09a local juming-nginx4.3 掛載信息查看與權限寫入
查看指定的數據卷信息的命令:docker volume inspect數據卷名稱
查看掛載信息 # docker volume inspect <卷名稱> [{"CreatedAt": "2022-05-14T21:45:11+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/liusiqi/_data","Name": "nginx","Options": null,"Scope": "local"} ] > 可以看到Mountpoint參數即為掛載路徑 url:/var/lib/docker/volumes/liusiqi/_data > Docker所有的數據卷默認在/var/lib/docker/volumes/ 目錄下權限寫入
指定數據卷映射的相關參數:
ro —— readonly 只讀。設置了只讀則只能操作宿主機的路徑,不能操作容器中的對應路徑。
rw ----- readwrite 可讀可寫
二、DockerFile
1. 概述
DockerFile 就是用來構建dokcer鏡像的文件!命令參數腳本。
構建步驟:
例子:centos7的官方構筑
FROM centos:7 ENV container docker RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ systemd-tmpfiles-setup.service ] || rm -f $i; done); \ rm -f /lib/systemd/system/multi-user.target.wants/*;\ rm -f /etc/systemd/system/*.wants/*;\ rm -f /lib/systemd/system/local-fs.target.wants/*; \ rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ rm -f /lib/systemd/system/basic.target.wants/*;\ rm -f /lib/systemd/system/anaconda.target.wants/*; VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"]
關系圖
解析過程圖
2. 構建過程
2.1 基礎知識
dockerfile面向開發的,發布項目,作鏡像就需要編寫dockerfile文件。
DockerFile:構建文件,定義步驟,類似源代碼
DockerImages: 通過 DockerFile 構建生成鏡像,最終發布和運行產品
Docker容器: 容器就是鏡像進行運行來提供服務的
2.2 DockerFile 指令
| FROM | 指定基礎鏡像 |
| MAINTAINER | 鏡像是誰寫的,姓名+郵箱 |
| RUN | 鏡像構建的時候需要運行的命令 |
| ADD | 將本地文件添加到容器中,tar類型文件會自動解壓(網絡壓縮資源不會被解壓),可以訪問網絡資源,類似wget |
| WORKDIR | 鏡像的工作目錄 |
| VOLUME | 掛載的目錄 |
| EXPOSE | 保留端口配置 |
| CMD | 指定這個容器啟動的時候要運行的命令(只有最后一個會生效) |
| EMTRYPOINT | 指定這個容器啟動的時候要運行的命令,可以追加命令 |
| ONBUILD | 當構建一個被繼承DockerFile,這個時候就會運行ONBUILD的指令,觸發指令 |
| COPY | 功能類似ADD,但是是不會自動解壓文件,也不能訪問網絡資源 |
| ENV | 構建的時候設置環境變量 |
CMD 和 ENTRYPOINT 區別
CMD : 指定這個容器啟動的時候要運行的命令,職業最后一個會生效,可被替代
ENTRYPOINT: 指定這個容器啟動的時候要運行的命令,可以追加命令
3. 實戰
3.1 構建centos 鏡像
自定義一個帶有vim 和net-tools 的centos并進行發布
例:
nginx 編譯歷史
tomcat 編譯歷史
IMAGE CREATED CREATED BY SIZE COMMENT 6a1271dfce51 3 days ago /bin/sh -c #(nop) CMD ["catalina.sh" "run"] 0B <missing> 3 days ago /bin/sh -c #(nop) EXPOSE 8080 0B <missing> 3 days ago /bin/sh -c set -eux; nativeLines="$(catalin… 0B <missing> 3 days ago /bin/sh -c set -eux; savedAptMark="$(apt-m… 20.2MB <missing> 3 days ago /bin/sh -c #(nop) ENV TOMCAT_SHA512=53bfdba… 0B <missing> 3 days ago /bin/sh -c #(nop) ENV TOMCAT_VERSION=10.0.20 0B <missing> 3 days ago /bin/sh -c #(nop) ENV TOMCAT_MAJOR=10 0B <missing> 3 days ago /bin/sh -c #(nop) ENV GPG_KEYS=A9C5DF4D22E9… 0B <missing> 3 days ago /bin/sh -c #(nop) ENV LD_LIBRARY_PATH=/usr/… 0B <missing> 3 days ago /bin/sh -c #(nop) ENV TOMCAT_NATIVE_LIBDIR=… 0B <missing> 3 days ago /bin/sh -c #(nop) WORKDIR /usr/local/tomcat 0B <missing> 3 days ago /bin/sh -c mkdir -p "$CATALINA_HOME" 0B <missing> 3 days ago /bin/sh -c #(nop) ENV PATH=/usr/local/tomca… 0B <missing> 3 days ago /bin/sh -c #(nop) ENV CATALINA_HOME=/usr/lo… 0B <missing> 4 days ago /bin/sh -c #(nop) CMD ["jshell"] 0B <missing> 4 days ago /bin/sh -c set -eux; arch="$(dpkg --print-… 343MB <missing> 4 days ago /bin/sh -c #(nop) ENV JAVA_VERSION=11.0.15 0B <missing> 4 days ago /bin/sh -c #(nop) ENV LANG=C.UTF-8 0B <missing> 4 days ago /bin/sh -c #(nop) ENV PATH=/usr/local/openj… 0B <missing> 4 days ago /bin/sh -c { echo '#/bin/sh'; echo 'echo "$J… 27B <missing> 4 days ago /bin/sh -c #(nop) ENV JAVA_HOME=/usr/local/… 0B <missing> 4 days ago /bin/sh -c set -eux; apt-get update; apt-g… 11.3MB <missing> 4 days ago /bin/sh -c apt-get update && apt-get install… 152MB <missing> 4 days ago /bin/sh -c set -ex; if ! command -v gpg > /… 19MB <missing> 4 days ago /bin/sh -c set -eux; apt-get update; apt-g… 10.7MB <missing> 4 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 4 days ago /bin/sh -c #(nop) ADD file:68a5d7d0db5926251… 124MB3.2 構建tomcat 鏡像
通過ftp傳入服務器上
建議: 本地編輯ftp傳入服務或者,拷貝
在網頁中輸入ip+端口 注意要加上/test
三、DockerNet
1. 認識網絡模式
查看Dokcer的所有網絡:
# docker network ls
Docker自身的4種網絡工作方式,和一些自定義網絡模式
安裝Docker時,它會自動創建三個網絡,bridge(創建容器默認連接到此網絡)、 none 、host
host:容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口。
Container:創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、端口范圍。
None:該模式關閉了容器的網絡功能。
Bridge:此模式會為每一個容器分配、設置IP等,并將容器連接到一個docker0虛擬網橋,通過docker0網橋以及Iptables nat表配置與宿主機通信。
以上都是不用動手的,真正需要配置的是自定義網絡。
DockerComposeDocker內置這三個網絡,運行容器時,你可以使用該–network標志來指定容器應連接到哪些網絡。
該bridge網絡代表docker0所有Docker安裝中存在的網絡。除非你使用該
docker run --network= < NETWORK>
選項指定,否則Docker守護程序默認將容器連接到此網絡。
我們在使用docker run創建Docker容器時,可以用 --net 選項指定容器的網絡模式,Docker可以有以下4種網絡模式:
host模式:使用 --net=host 指定。none模式:使用 --net=none 指定。bridge模式:使用 --net=bridge 指定,默認設置。container模式:使用 --net=container:NAME_or_ID 指定。2. 默認網絡
2.1 Host
2.2 Container
2.3 None
2.4 Bridge
3. Docker:網絡模式詳解
3.1 Bridge模式的拓撲
當Docker server啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。接下來就要為容器分配IP了,Docker會從RFC1918所定義的私有IP網段中,選擇一個和宿主機不同的IP地址和子網分配給docker0,連接到docker0的容器就從這個子網中選擇一個未占用的IP使用。如一般Docker會使用172.17.0.0/16這個網段,并將172.17.0.1/16分配給docker0網橋(在主機上使用ifconfig命令是可以看到docker0的,可以認為它是網橋的管理接口,在宿主機上作為一塊虛擬網卡使用)。單機環境下的網絡拓撲如下,主機地址為10.10.0.186/24。
3.2 Docker:網絡模式詳解
Docker容器完成bridge網絡配置的過程如下:
Docker 利用 veth-pair技術實現橋接:
Docker中的所有的網絡接口都是虛擬的。只要容器停止或者刪除,容器對應的網橋也會刪除。
3.3 容器聯通
在微服務部署的場景下,注冊中心是使用服務名來唯一識別微服務的,而我們上線部署的時候微服務對應的IP地址可能會改動,所以我們需要使用容器名來配置容器間的網絡連接。使用–link可以完成這個功能。
== --link 功能已經是過去的技術了,這里做一個了解,真實項目使用場景中拋棄這種方式 ==
我們看到這種link方式直接使用容器名稱就可以ping通了。
但是反過來容器Tomcat01通過容器名Tomcat04直接ping容器Tomcat04是不行的。這是因為 –link的底層操作是修改容器的hosts文件達到ip地址與容器名稱映射的。
4. 自定義網絡
建議使用自定義的網橋來控制哪些容器可以相互通信,還可以自動DNS解析容器名稱到IP地址。Docker提供了創建這些網絡的默認網絡驅動程序,你可以創建一個新的Bridge網絡,Overlay或Macvlan網絡。你還可以創建一個網絡插件或遠程網絡進行完整的自定義和控制。
你可以根據需要創建任意數量的網絡,并且可以在任何給定時間將容器連接到這些網絡中的零個或多個網絡。此外,您可以連接并斷開網絡中的運行容器,而無需重新啟動容器。當容器連接到多個網絡時,其外部連接通過第一個非內部網絡以詞法順序提供。
4.1 查看默認的網橋信息
# docker network inspect bridge無容器純凈的網絡信息
[{"Name": "bridge","Id": "e83d01603ae8672ded8b5c7ef7e82c0cb900341f4290c70db5a6be4796d29850","Created": "2022-05-13T18:39:19.710131055+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{"Subnet": "172.17.0.0/16","Gateway": "172.17.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {},"Options": {"com.docker.network.bridge.default_bridge": "true","com.docker.network.bridge.enable_icc": "true","com.docker.network.bridge.enable_ip_masquerade": "true","com.docker.network.bridge.host_binding_ipv4": "0.0.0.0","com.docker.network.bridge.name": "docker0","com.docker.network.driver.mtu": "1500"},"Labels": {}} ]我們可以看到子網掩碼和網關的值,這就是網絡的基礎配置
“Subnet”: “172.17.0.0/16”,
“Gateway”: “172.17.0.1”
4.2 自定義網絡
# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet| –driver bridge | 指定bridge驅動程序來管理網絡 |
| –subnet 192.168.0.0/16 | 指定網段的CIDR格式的子網 |
| –gateway 192.168.0.1 | 指定主子網的IPv4或IPv6網關 |
查看自定義網絡信息
# docker network inspect mynet這就是我們自定義網絡的信息,發現子網掩碼和網關的值就是我們自定義的"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "192.168.0.0/16","Gateway": "192.168.0.1"}]},4.3 自定義網絡的好處
在我們的自定義網絡下,容器之間既可以通過容器名也可以通過ip地址進行網絡通信。 我們自定義的網絡默認已經幫我們維護了容器間的網絡通信問題,這是實現網絡互聯的推薦方式。
發現不用配置 --link 也可以實現直接用容器名稱ping通網絡
5.網絡連通
不同網絡直接不可以直接ping通,這時候就需要進行網絡連接。圖中,net01 與 net02 屬于mynet 網絡,想要tomcat01 直接ping通 net01 。
發現在mynet 的網絡信息中多了tomcat01 的信息。可以看到給容器tomcat-01分配了一個ip地址,這樣就可以實現不同網絡的互聯。
6. Redis集群部署實戰
7. SpringBoot微服務打包發布
四、Docker Compose
1. Compose 簡介
Compose 是用于定義和運行多容器 Docker 應用程序的工具。通過 Compose,您可以使用 YML 文件來配置應用程序需要的所有服務。然后,使用一個命令,就可以從 YML 文件配置中創建并啟動所有服務。
如果你還不了解 YML 文件配置,可以先閱讀 YAML 入門教程。
Compose 使用的三個步驟:
docker-compose.yml 的配置案例如下(配置參數參考下文):
# yaml 配置實例 version: '3' services:web:build: .ports:- "5000:5000"volumes:- .:/code- logvolume01:/var/loglinks:- redisredis:image: redis volumes:logvolume01: {}2. Compose 安裝
Linux 上我們可以從 Github 上下載它的二進制包來使用,最新發行的版本地址:https://github.com/docker/compose/releases。
運行以下命令以下載 Docker Compose 的當前穩定版本:
要安裝其他版本的 Compose,請替換 v2.2.2。
Docker Compose 存放在 GitHub,不太穩定。
你可以也通過執行下面的命令,高速安裝 Docker Compose。
將可執行權限應用于二進制文件:
$ sudo chmod +x /usr/local/bin/docker-compose創建軟鏈:
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose測試是否安裝成功:
$ docker-compose --version cker-compose version 1.24.1, build 4667896b3. 使用
步驟來源于官網,可移步官網。 官網地址
3.1 準備
創建一個測試目錄:
# mkdir composetest # cd composetest在測試目錄中創建一個名為 app.py 的文件,并復制粘貼以下內容:
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count():retries = 5while True:try:return cache.incr('hits')except redis.exceptions.ConnectionError as exc:if retries == 0:raise excretries -= 1time.sleep(0.5) @app.route('/') def hello():count = get_hit_count()return 'Hello World! I have been seen {} times.\n'.format(count)在此示例中,redis 是應用程序網絡上的 redis 容器的主機名,該主機使用的端口為 6379。
在 composetest 目錄中創建另一個名為 requirements.txt 的文件,內容如下:
3.2 創建 Dockerfile 文件
在 composetest 目錄中,創建一個名為 Dockerfile 的文件,內容如下:
FROM python:3.7-alpine //從 Python 3.7 映像開始構建鏡像。 WORKDIR /code //將工作目錄設置為 /code。 ENV FLASK_APP app.py //設置 flask 命令使用的環境變量。 ENV FLASK_RUN_HOST 0.0.0.0 //設置 flask 命令使用的環境變量。 RUN apk add --no-cache gcc musl-dev linux-headers //安裝 gcc,以便諸如 MarkupSafe 和 SQLAlchemy 之類的 Python 包可以編譯加速。 COPY requirements.txt requirements.txt RUN pip install -r requirements.txt //復制 requirements.txt 并安裝 Python 依賴項。 COPY . . // 將 . 項目中的當前目錄復制到 . 鏡像中的工作目錄。 CMD ["flask", "run"] //容器提供默認的執行命令為:flask run。鏡像下載比較慢,推薦切換國內鏡像
3.3 創建 docker-compose.yml
在測試目錄中創建一個名為 docker-compose.yml 的文件,然后粘貼以下內容:
# yaml 配置 version: '3' services:web:build: .ports:- "5000:5000"redis:image: "redis:alpine"該 Compose 文件定義了兩個服務:web 和 redis。
在測試目錄中,執行以下命令來啟動應用程序:
# docker-compose up # docker-compose up -d //后臺運行小結:
4 .使用 Compose 部署前后分離項目實戰
采用SpringBoot + Vue + mysql
4.1 打包前后端項目
4.2 編寫DockerFile
4.3 編寫docker-compose.yaml
4.4 啟動部署
五、Docker Machine
待更新
六、Docker Swarm
待更新
總結
你的無畏源于無知。 — 三體
總結
以上是生活随笔為你收集整理的Docker进阶实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 视频分享网站首页:主体框架完成
- 下一篇: 微型计算机三包_买卖合同与“三包”规定