(給ImportNew加星標,提高Java技能)
本文總結了Docker常見的問題和坑,採用問答的形式,分享給大家
1.什麼是Docker?也可以這樣形象的比喻:
Docker 的Logo設計為藍色鯨魚,拖着許多集裝箱,鯨魚可以看作為宿主機,集裝箱可以理解為相互隔離的容器,每個集裝箱中都包含自己的應用程序。
2.Docker的應用場景有哪些?在這裡我重點介紹下Docker作為內部開發環境的場景
在容器技術出現之前,公司往往是通過為每個開發人員提供一台或者多台虛擬機來充當開發測試環境。開發測試環境一般負載較低,大量的系統資源都被浪費在虛擬機本身的進程上了。
Docker容器沒有任何CPU和內存上的額外開銷,很適合用來提供公司內部的開發測試環境。而且由於docker鏡像可以很方便的在公司內部分享,這對開發環境的規範性也有極大的幫助。
如果要把容器作為開發機使用,需要解決的是遠程登錄容器和容器內進程管理問題。雖然docker的初衷是為「微服務」架構設計的,但根據我們的實際使用經驗,在docker內運行多個程序,甚至sshd或者upstart也是可行的。
3.Docker的優點有哪些?容器化越來越受歡迎,Docker的容器有點總結如下:

Docker 是一個用於開發,交付和運行應用程序的開放平台。Docker 使您能夠將應用程序與基礎架構分開,從而可以快速交付軟件。藉助 Docker,您可以與管理應用程序相同的方式來管理基礎架構。通過利用 Docker 的方法來快速交付,測試和部署代碼,您可以大大減少編寫代碼和在生產環境中運行代碼之間的延遲。
4.Docker與虛擬機的區別是什麼?虛擬機通過添加Hypervisor層(虛擬化中間層),虛擬出網卡、內存、CPU等虛擬硬件,再在其上建立虛擬機,每個虛擬機都有自己的系統內核。而Docker容器則是通過隔離(namesapce)的方式,將文件系統、進程、設備、網絡等資源進行隔離,再對權限、CPU資源等進行控制(cgroup),最終讓容器之間互不影響,容器無法影響宿主機。
與虛擬機相比,容器資源損耗要少。同樣的宿主機下,能夠建立容器的數量要比虛擬機多
但是,虛擬機的安全性要比容器稍好,而docker容器與宿主機共享內核、文件系統等資源,更有可能對其他容器、宿主機產生影響。

Docker的鏡像是創建容器的基礎,類似虛擬機的快照,可以理解為一個面向Docker容器引擎的只讀模板。
通過鏡像啟動一個容器,一個鏡像是一個可執行的包,其中包括運行應用程序所需要的所有內容包含代碼,運行時間,庫、環境變量、和配置文件。
Docker鏡像也是一個壓縮包,只是這個壓縮包不只是可執行文件,環境部署腳本,它還包含了完整的操作系統。因為大部分的鏡像都是基於某個操作系統來構建,所以很輕鬆的就可以構建本地和遠端一樣的環境,這也是Docker鏡像的精髓。
容器Docker的容器是從鏡像創建的運行實例,它可以被啟動、停止和刪除。所創建的每一個容器都是相互隔離、互不可見,以保證平台的安全性。可以把容器看做是一個簡易版的linux環境(包括root用戶權限、鏡像空間、用戶空間和網絡空間等)和運行在其中的應用程序。
倉庫倉庫註冊服務器上往往存放着多個倉庫,每個倉庫中包含了多個鏡像,每個鏡像有不同標籤(tag)。
倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。
最大的公開倉庫是 Docker Hub:https://hub.docker.com,存放了數量龐大的鏡像供用戶下載。
國內的公開倉庫包括阿里雲 、網易雲等。
6.如何快速安裝Docker?執行以下安裝命令去安裝依賴包
yuminstall-yyum-utilsdevice-mapper-persistent-datalvm2sudoyum-config-manager–add-repohttps://download.docker.com/linux/centos/docker-ce.repo[root@centos7~]yum-yinstalldocker-cedocker-ce-clicontainerd.io[root@centos7~]#dockerps--查看docker
默認情況下 Docker的存放位置為:/var/lib/docker
可以通過命令查看具體位置:docker info | grep 「Docker Root Dir」
修改到其它目錄首先停掉 Docker 服務:
systemctlstopdocker然後移動整個/var/lib/docker 目錄到目的路徑
mkdir-p/root/data/dockermv/var/lib/docker/root/data/dockerln-s/root/data/docker/var/lib/docker--快捷方式8.Docker鏡像常用管理有哪些?快速檢索鏡像格式:docker search 關鍵字
獲取鏡像格式:docker pull 倉庫名稱[:標籤] 如果下載鏡像時不指定標籤,則默認會下載倉庫中最新版本的鏡像,即選擇標籤為 latest 標籤
查看鏡像信息鏡像下載後默認存放在 /var/lib/docker

格式:docker inspect 鏡像ID號
鏡像ID 號可以不用打全。

格式:docker tag 名稱:[ 標籤]
刪除鏡像格式1:docker rmi 倉庫名稱:標籤
當一個鏡像有多個標籤時,只是刪除其中指定的標籤
格式2: docker rmi 鏡像ID [-f]
如果該鏡像已經被容器使用,正確的做法是先刪除依賴該鏡像的所有容器,再去刪除鏡像
將鏡像保存為本地文件格式:docker save -o 存儲文件名 存儲的鏡像
[root@localhost~]#dockersave-o/opt/nginx.tarnginx:latest#將本地鏡像傳給另一台主機[root@localhost~]#scp/opt/nginx.tar192.168.1.54:/opt9.如何創建Docker容器?#dockerimages--鏡像dockerrun-d--namecentos7.8-hcentos7.8\-p220:22-p3387:3389\--privileged=true\centos:7.8.2003/usr/sbin/init#我想擁有一個linux8.2的環境dockerrun-d--namecentos8.2-hcentos8.2\-p230:22-p3386:3389\--privileged=true\daocloud.io/library/centos:8.2.2004init#進入容器dockerexec-itcentos7.8bashdockerexec-itcentos8.2bashcat/etc/redhat-release--查看系統版本10.Docker在後台的標準運行過程是什麼?當利用 docker run 來創建容器時, Docker 在後台的標準運行過程是:
host 模式 :使用 --net=host 指定
相當於VMware 中的橋接模式,與宿主機在同一個網絡中,但是沒有獨立IP地址
Docker 使用了Linux 的Namespace 技術來進行資源隔離,如PID Namespace隔離進程,Mount Namespace隔離文件系統,Network Namespace 隔離網絡等。
一個Network Namespace 提供了一份獨立的網絡環境,包括網卡,路由,iptable 規則等都與其他Network Namespace 隔離。
一個Docker 容器一般會分配一個獨立的Network Namespace
但是如果啟動容器的時候使用host 模式,那麼這個容器將不會獲得一個獨立的Network Namespace ,而是和宿主機共用一個Network Namespace 。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和端口.此時容器不再擁有隔離的、獨立的網絡棧。不擁有所有端口資源

container模式:使用–net=contatiner:NAME_or_ID 指定
這個模式指定新創建的容器和已經存在的一個容器共享一個Network Namespace,而不是和宿主機共享。新創建的容器不會創建自己的網卡,配置自己的IP,而是和一個指定的容器共享IP,端口範圍等。 可以在一定程度上節省網絡資源,容器內部依然不會擁有所有端口。
同樣,兩個容器除了網絡方面,其他的如文件系統,進程列表等還是隔離的。
兩個容器的進程可以通過lo網卡設備通信

none模式:使用 --net=none指定
使用none 模式,docker 容器有自己的network Namespace ,但是並不為Docker 容器進行任何網絡配置。也就是說,這個Docker 容器沒有網卡,ip, 路由等信息。
這種網絡模式下,容器只有lo 迴環網絡,沒有其他網卡。
這種類型沒有辦法聯網,但是封閉的網絡能很好的保證容器的安全性
該容器將完全獨立於網絡,用戶可以根據需要為容器添加網卡。此模式擁有所有端口。(none網絡模式配置網絡)特殊情況下才會用到,一般不用
bridge 模式相當於Vmware中的 nat 模式,容器使用獨立network Namespace,並連接到docker0虛擬網卡。通過docker0網橋以及iptables nat表配置與宿主機通信,此模式會為每一個容器分配Network Namespace、設置IP等,並將一個主機上的 Docker 容器連接到一個虛擬網橋上。
當Docker進程啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。
從docker0子網中分配一個IP給容器使用,並設置docker0的IP地址為容器的默認網關。在主機上創建一對虛擬網卡veth pair設備。veth設備總是成對出現的,它們組成了一個數據的通道,數據從一個設備進入,就會從另一個設備出來。因此,veth設備常用來連接兩個網絡設備。
Docker將veth pair 設備的一端放在新創建的容器中,並命名為eth0(容器的網卡),另一端放在主機中, 以veth*這樣類似的名字命名,並將這個網絡設備加入到docker0網橋中。可以通過 brctl show 命令查看。
容器之間通過veth pair進行訪問
使用 docker run -p 時,docker實際是在iptables做了DNAT規則,實現端口轉發功能。
可以使用iptables -t nat -vnL 查看。

數據卷是一個供容器使用的特殊目錄,位於容器中。可將宿主機的目錄掛載到數據卷上,對數據卷的修改操作立刻可見,並且更新數據不會影響鏡像,從而實現數據在宿主機與容器之間的遷移。數據卷的使用類似於Linux下對目錄進行的mount操作。
如果需要在容器之間共享一些數據,最簡單的方法就是使用數據卷容器。數據卷容器是一個普通的容器,專門提供數據卷給其他容器掛載使用。
容器互聯是通過容器的名稱在容器間建立一條專門的網絡通信隧道。簡單點說,就是會在源容器和接收容器之間建立一條隧道,接收容器可以看到源容器指定的信息
13.如何搭建Docker私有倉庫1.拉取私有倉庫鏡像
[root@jeames~]#dockerpullregistryUsingdefaulttag:latest2.啟動私有倉庫容器
dockerrun-di--nameregistry-p5000:5000registrydockerupdate--restart=alwaysregistry--開機自啟動dockerps-a--format"table{{.ID}}\t{{.Names}}\t{{.Status}}"訪問網址:http://192.168.1.54:5000/v2/_catalog
3.設置信任
[root@jeames~]#vi/etc/docker/daemon.json{"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"],"insecure-registries":["192.168.1.54:5000"]}[root@jeames~]#systemctlrestartdocker--重啟docker4.上傳本地鏡像
[root@jeames~]#dockerimages[root@jeames~]#dockertagpostgres:11192.168.1.54:5000/postgres[root@jeames~]#dockerpush192.168.1.54:5000/postgres5.重新拉取鏡像
[root@jeames~]#dockerrmi192.168.1.54:5000/postgres[root@jeames~]#dockerimages[root@jeames~]#dockerpull192.168.1.54:5000/postgres14.Docker如何遷移備份?1.容器保存為鏡像
[root@jeames~]#dockerimages[root@jeames~]#dockerps-adockerps-a--format"table{{.ID}}\t{{.Names}}\t{{.Status}}"[root@jeames~]#dockercommitredismyredis##使用新的鏡像創建容器dockerrun-di--namemyredismyredis2.鏡像的備份
[root@jeames~]#dockersave-omyredis.tarmyredis默認放到當前目錄
[root@jeames~]#ll[root@jeames~]#pwd3.恢復過程
##刪除容器dockerps--format"table{{.ID}}\t{{.Names}}\t{{.Status}}"dockerstopmyredisdockerrmmyredis##刪除鏡像dockerimagesdockerrmimyredis[root@jeames~]#dockerload-imyredis.tar15. Docker如何部署MySQL?1.下載鏡像https://hub.docker.com/中搜索mysql[root@jeames~]#dockerpullmysql:5.7.30[root@jeames~]#dockerpullmysql:8.0.202.安裝部署2.1 創建容器
mkdir-p/usr/local/mysql5730/mkdir-p/usr/local/mysql8020/dockerrun-d--namemysql5730-hmysql5730\-p3309:3306\-v/usr/local/mysql5730/conf:/etc/mysql/conf.d\-eMYSQL_ROOT_PASSWORD=root-eTZ=Asia/Shanghai\mysql:5.7.30dockerrun-d--namemysql8020-hmysql8020\-p3310:3306\-v/usr/local/mysql8020/conf:/etc/mysql/conf.d\-eMYSQL_ROOT_PASSWORD=root-eTZ=Asia/Shanghai\mysql:8.0.202.2 訪問Mysql
##登陸容器dockerexec-itmysql5730bashmysql-uroot-prootmysql>selectuser,hostfrommysql.user##遠程訪問mysql-uroot-proot-h192.168.59.220-P3309- EOF -
四種緩存的避坑總結
單體架構服務轉型至分布式的踩坑經歷
這12款idea插件,能讓你代碼飛起來!
看完本文有收穫?請轉發分享給更多人
關注「ImportNew」,提升Java技能
點讚和在看就是最大的支持❤️