?歡迎訂閱《大廠面試突擊》專欄,面試10多家大廠總結出的高頻面試知識,免費階段大家趕快訂閱
?更多精品專欄簡介點這里
?更多java面試學習資料,請私信「資料」獲取
歲月無情,余生有涯,將生活扛在肩上,風雨兼程,
前言
哈嘍,大家好,我是一條,
《大廠面試突擊》專欄目前已發布三篇萬字總結,識訓500+的訂閱,感謝各位的支持,
面試10多家中大廠后的萬字總結——??集合篇??
面試10多家中大廠后的萬字總結——??JavaWeb篇??
面試10多家中大廠后的萬字總結——??java基礎篇??
但想成一個優秀的程式員,「演算法」+「八股文」只能讓你沖過第一關,隨著年限的增長,面試官會看重你技術的廣度和深度,更加注重你的經驗和解決問題的能力,
所以一條開了一個新的專欄《技術專家修煉》,內容如下:
- 企業實戰的講解
- 中間件微服務的介紹
- 作業中遇到的坑和總結
總之這是幫助你一步步封神的秘籍!
今天給大家帶來docker的萬字總結,雖說我們是開發,但docker不能不會,技術的廣度就在這里提現,
文章目錄
- 前言
- 安裝docker
- mac
- 命令列安裝
- dmg安裝
- windows
- 安裝 Hyper-V
- 開啟 Hyper-V
- 安裝 Docker Desktop for Windows
- 運行安裝檔案
- 阿里云(linux)
- 運行實體
- **鏡像加速**
- 通俗理解什么是docker?
- docker與虛擬機的對比
- docker三大概念
- docker作業流程
- docker命令
- 基本操作
- 入門案例
- 快速搭建wordpress博客
- 查看埠映射
- linux設定docker開機自啟
- 查看鏡像
- 運行鏡像
- 洗掉鏡像
- 復合命令
- 查看運行的容器
- docker compose
- 容器管理
- 進入容器
- 查看容器詳細資訊
- 鏡像特性
- 分層原理
- UFS(聯合檔案系統)
- 加載原理
- Docker File
- 容器->鏡像
- 撰寫docker file
- 指令講解
- docker file demo
- 網路通信
- 網路知識補充
- 網路模型
- 容器內部訪問
- 內外部通信
- 最后
安裝docker
鑒于同學們用的設備都不一樣,不能讓大家在第一步就被勸退,所以三個平臺的安裝方式都準備了,請自行選擇,
不推薦在
windows安裝
mac
命令列安裝
需要先安裝homebrew
homebrew國內鏡像
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
執行后選擇中科大的鏡像,即數字1
clone時間過長,約5-10分鐘,
安裝docker
brew install --cask --appdir=/Applications docker
Installing cask docker時請耐心等待,時間較長

dmg安裝
點擊鏈接下載安裝即可,并帶有可視化界面,但個人覺得并不好用,
https://download.docker.com/mac/edge/Docker.dmg

啟動docker服務
點擊圖示或者
open /Applications/Docker.app
windows
不推薦在windows安裝,如果實在沒有也可以裝,
教程參考:https://www.runoob.com/docker/windows-docker-install.html
Docker 并非是一個通用的容器工具,它依賴于已存在并運行的 Linux 內核環境,
Docker 實質上是在已經運行的 Linux 下制造了一個隔離的檔案環境,因此它執行的效率幾乎等同于所部署的 Linux 主機,
因此,Docker 必須部署在 Linux 內核的系統上,如果其他系統想部署 Docker 就必須安裝一個虛擬 Linux 環境,

在 Windows 上部署 Docker 的方法都是先安裝一個虛擬機,并在安裝 Linux 系統的的虛擬機中運行 Docker,
Docker Desktop 是 Docker 在 Windows 10 和 macOS 作業系統上的官方安裝方式,這個方法依然屬于先在虛擬機中安裝 Linux 然后再安裝 Docker 的方法,
Docker Desktop 官方下載地址: https://hub.docker.com/editions/community/docker-ce-desktop-windows
**注意:**此方法僅適用于 Windows 10 作業系統專業版、企業版、教育版和部分家庭版!
安裝 Hyper-V
Hyper-V 是微軟開發的虛擬機,類似于 VMWare 或 VirtualBox,僅適用于 Windows 10,這是 Docker Desktop for Windows 所使用的虛擬機,
但是,這個虛擬機一旦啟用,QEMU、VirtualBox 或 VMWare Workstation 15 及以下版本將無法使用!如果你必須在電腦上使用其他虛擬機(例如開發 Android 應用必須使用的模擬器),請不要使用 Hyper-V!
開啟 Hyper-V
右鍵開始選單并以管理員身份運行 PowerShell,執行以下命令:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
安裝 Docker Desktop for Windows
點擊 Get started with Docker Desktop,并下載 Windows 的版本,如果你還沒有登錄,會要求注冊登錄:

運行安裝檔案
雙擊下載的 Docker for Windows Installer 安裝檔案,一路 Next,點擊 Finish 完成安裝,

安裝完成后,Docker 會自動啟動,通知欄上會出現個小鯨魚的圖示
,這表示 Docker 正在運行,
我們可以在命令列執行 docker version 來查看版本號,
阿里云(linux)
基于阿里云服務器的安裝方式,推薦!
查看配置
# 內核版本查看
uname -r
系統版本:CentOS7
內核版本:3.10.0-514.26.2.el7.x86_64
安裝
安裝有兩種方式:
1.官方腳本安裝(本文講解)
2.手動安裝
安裝:此為國內鏡像,安裝完提示如果想在非root用戶使用,需將用命名加入組,并重啟,
curl -fsSL https://get.docker.com/ | sh
??如果報錯缺少deltarpm,執行下面命令
yum provides '*/applydeltarpm' #查看依賴包的位置
yum -y install deltarpm #安裝命令
啟動docker服務
service docker start
??本文以下全部講解均基于Linux系統??
運行實體
本著一切語言都是從
hello-world開始的原則,我們先運行官方的實體體驗一下,
官方提供了hello-world實體,運行前需要在官網注冊docker id并創建倉庫,
官網地址:https://hub.docker.com
注冊時注意id起的復雜一點,很容易重復,
啟動docker服務
systemctl start docker
拉取鏡像
docker pull hello-world
運行鏡像
docker run hello-world

查看容器
# -a 查看所有
docker ps -a
鏡像加速
如果剛才拉取鏡像時感覺速度過慢可以配置加速,速度正常可跳過此步,
鑒于國內網路問題,后續拉取 Docker 鏡像十分緩慢,我們可以需要配置加速器來解決,
網易的鏡像地址:http://hub-mirror.c.163.com,
在任務欄點擊 Docker for mac 應用圖示
Perferences... -> Daemon -> Registry mirrors
在串列中填寫加速器地址即可,
修改完成之后,點擊 Apply & Restart 按鈕,Docker 就會重啟并應用配置的鏡像地址了,
通俗理解什么是docker?
Docker的思想來自于集裝箱,集裝箱解決了什么問題?
在一艘大船上,可以把貨物規整的擺放起來,并且各種各樣的貨物被集裝箱標準化了,集裝箱和集裝箱之間不會互相影響,那么我就不需要專門運送水果的船和專門運送化學品的船了,只要這些貨物在集裝箱里封裝的好好的,那我就可以用一艘大船把他們都運走,
docker就是類似的理念,現在都流行云計算了,云計算就好比大貨輪,docker就是集裝箱,
-
不同的應用程式可能會有不同的應用環境,比如.net開發的網站和php開發的網站依賴的軟體就不一樣,如果把他們依賴的軟體都安裝在一個服務器上就要除錯很久,而且很麻煩,還會造成一些沖突,比如IIS和Apache訪問埠沖突,這個時候你就要隔離.net開發的網站和php開發的網站,常規來講,我們可以在服務器上創建不同的虛擬機在不同的虛擬機上放置不同的應用,但是虛擬機開銷比較高,docker可以實作虛擬機隔離應用環境的功能,并且開銷比虛擬機小,小就意味著省錢了,
-
你開發軟體的時候用的是Ubuntu,但是運維管理的都是centos,運維在把你的軟體從開發環境轉移到生產環境的時候就會遇到一些Ubuntu轉centos的問題,比如:有個特殊版本的資料庫,只有Ubuntu支持,centos不支持,在轉移的程序當中運維就得想辦法解決這樣的問題,這時候要是有docker你就可以把開發環境直接封裝轉移給運維,運維直接部署你給他的docker就可以了,而且部署速度快,
-
在服務器負載方面,如果你單獨開一個虛擬機,那么虛擬機會占用空閑記憶體的,docker部署的話,這些記憶體就會利用起來,
總之docker就是集裝箱原理,
docker與虛擬機的對比
物理機:別墅
虛擬機:樓房
docker:酒店式公寓
docker三大概念
庫:一個總的倉庫,包含所有的鏡像,使用時可以從庫拉取鏡像到本地,
鏡像:從庫中拉取下來的應用,比如mysql,
容器:鏡像運行之后就是容器,容器和鏡像可以互相轉換,
docker作業流程

docker命令
docker指令基本用法:
docker 命令關鍵字 -引數
基本操作
# 查看docker資訊
docker info
# docker版本
docker version
# 查找鏡像
docker search nginx
#拉取鏡像
docker pull nginx
入門案例
快速搭建wordpress博客
查找鏡像
docker search name
## wordpress
## mariadb

拉取鏡像
docker pull wordpress
# mariadb就是mysql
docker pull mariadb
運行鏡像
docker run --name db -p 3306:3306 --env MYSQL_ROOT_PASSWORD=root -d mariadb
docker run --name mywordpress --link db:mysql -p 8080:80 -d wordpress
運行成功,訪問wordpress
http://libiao:8080
根據提示配置資料庫資訊,一個個人博客網站就搭建好了

查看埠映射
docker ps
docker port CONTAINER_ID
舉例:xxjob的8080埠映射到宿主機的8089埠

linux設定docker開機自啟
systemctl enable docker
查看鏡像
docker images
#因為docker是分層,所以顯示的檔案大小要大于實際占用磁盤的大小
運行鏡像
docker run --name db -p 3306:3306 --env MYSQL_ROOT_PASSWORD=root -d mariadb
# --name 別名
# --env 環境變數
#-d 后臺執行
docker run --name mywordpress --link db:mysql -p 8080:80 -d wordpress
# --link ip映射
# -p 埠映射
docker logs -f 7a38a1ad55c6
# 像tail -f一樣查看容器內日志
docker top name
#查看容器內的行程
洗掉鏡像
docker rmi hello-world:latest
docker rmi id
# 4位即可
復合命令
docker rm -f $(docker ps -a -q)
#洗掉全部容器
查看運行的容器
docker ps
docker compose
一個方便維護多個容器的yaml檔案,docker認為一個容器對應一個行程,但一個應用會有多個行程,例如上面的mysql和wordpress,
個人覺得docker compose類似于shell腳本,但他實際都python實作,訪問的是docker的一些api,
Docker compose一般隨docker一起安裝,所以要求版本對應
docker version
docker-compose --version
在yaml檔案制定鏡像的名字,版本,埠映射后用 up -d 啟動
docker-compose.yaml up -d
查看日志
docker-compose logs
容器管理
進入容器
docker exec -it name /bin/sh
查看容器詳細資訊
容器的詳細資訊會以json的形式回傳,
# docker inspect name
[root@lib mysh]# docker inspect mywordpress
[
{
"Id": "6253e66959047c6f8de891abe1c661f7766fdef7407f00e07d1788310e0ea6a9",
"Created": "2021-08-04T20:11:43.649001354Z",
"Path": "docker-entrypoint.sh",
"Args": [
"apache2-foreground"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 28041,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-08-04T20:11:43.947511209Z",
"FinishedAt": "0001-01-01T00:00:00Z"
}
"Name": "/mywordpress",
......
容器啟停
docker start name
docker stop name
docker restart name
洗掉容器
# 洗掉時容器需要處于停止狀態
docker rm name
查看日志
# docker ps -a
docker logs container_Id
占用資源
docker stats name

鏡像特性
鏡像是一種輕量級、可執行的獨立軟體包,用來打包軟體運行環境和基于運行環境開發的軟體,他包含運行某個軟體所需的所有內容,包括代碼、運行時庫、環境變數和組態檔,將所有的應用和環境直接打包為docker鏡像,就可以直接運行,
鏡像名和版本號共同組成唯一標識,默認是最新版——lastest
分層原理
Docker的鏡像通過聯合檔案系統將將各層檔案系統疊加在一起,
引導方式
- bootfs:傳統作業系統,用于系統引導的檔案系統,包括BootLoader和kernel,容器啟動完成后會被卸載以節省記憶體資源,

- rootfs:位于bootfs之上,表現為docker容器的根檔案系統
- 傳統模式中,系統啟動時,內核首先掛載為”只讀“模式,完成全部自檢后掛載為”讀寫“模式,
- docker中,rootfs由內核掛載為”只讀“模式,而后通過UFS技術掛載一個”可寫“層,
??注意:已有的分層只能讀不能寫,上層鏡像優先級大于底層鏡像

當我們使用pull命令時,我們可以看到docker的鏡像是一層一層的在下載,這樣做最大的好處就是資源共享了,
比如多個鏡像都從Base鏡像構建而來,那么宿主機只需要在磁盤上保留一份base鏡像,同時記憶體中也只需要加載一份base鏡像,這樣就可以為所有的容器服務了,而且鏡像的每一層都可以被共享,查看鏡像分層的方式可以通過docker image inspect命令,
所有的Docker鏡像都起始于一個基礎鏡像,當進行修改或者增加新的內容時,就會在當前的鏡像層之上,創建新的鏡像層,在添加額外的鏡像層的同時,鏡像始終保持當前所有鏡像的組合,
Docker通過存盤引擎的方式來實作鏡像層堆疊,并保證多鏡像層對外展示為統一的檔案系統,
UFS(聯合檔案系統)
UFS時一種分層、輕量級并且高性能的檔案系統,
它支持對檔案系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統下,
UnionFS是Docker鏡像的基礎,鏡像可以通過分層來進行繼承,基于基礎鏡像,可以制作各種具體的應用鏡像,一次同時加載多個檔案系統,但從外面看起來,只能看到一個檔案系統,聯合加載會把各層檔案,系統疊加起來,這樣最終的檔案系統會包含所有底層的檔案和目錄,
加載原理
Linux剛啟動時會加載bootfs檔案系統,在Docker鏡像的最底層時bootfs,
當boot加載完成后整個內核就在記憶體中了,此時記憶體的使用權已由bootfs轉交給內核,此時系統也會卸載bootfs,rootfs在bootfs之上,rootfs包含的就是典型Linux系統中的/dev、/proc、/bin、/etc等目錄和檔案,rootfs就是各種不同的作業系統發行版,
Docker File
倉庫沒有的鏡像怎么辦?
可以自己創建鏡像嗎?
容器->鏡像
docker commit CID -t xx.xx.xx
???????? 作業在前臺的守護行程至少一個
網易蜂巢:開源鏡像倉庫

撰寫docker file
Dockerfile 是一個用來構建鏡像的文本檔案,文本內容包含了一條條構建鏡像所需的指令和說明,
指令講解
FROM
指定基礎鏡像,必須為第一個命令,有且只有一個
# FROM <image>
# FROM <image>:<tag>
# FROM <image>@<digest>
FROM mysql:5.6
MAINTAINER
創建者資訊
# MAINTAINER <name>
MAINTAINER yitiao
RUN
用于在鏡像容器中執行命令,其有以下兩種命令執行方式:
#shell執行
# RUN <command>
#exec執行
# RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
ADD
將本地檔案添加到容器中,tar型別檔案會自動解壓(網路壓縮資源不會被解壓),可以訪問網路資源,類似wget
# ADD <src>... <dest>
ADD hom?.txt /mydir/ # ? 替代一個單字符,例如:"home.txt"
COPY
功能類似ADD,但是是不會自動解壓檔案,也不能訪問網路資源
CMD
構建容器后呼叫,也就是在容器啟動時才進行呼叫,
# CMD command param1 param2 (執行shell內部命令)
CMD echo "This is a test." | wc -
#CMD不同于RUN,CMD用于指定在容器啟動時所要執行的命令,而RUN用于指定鏡像構建時所要執行的命令
ENTRYPOINT
配置容器,使其可執行化,配合CMD可省去"application",只使用引數,
# ENTRYPOINT ["executable", "param1", "param2"] (可執行檔案, 優先)
# ENTRYPOINT command param1 param2 (shell內部命令)FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
LABEL
用于為鏡像添加元資料
# LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL version="1.0" description="一條coding" by="一條"
ENV
設定環境變數
# ENV <key> <value>
# <key>之后的所有內容均會被視為其<value>的組成部分,因此,一次只能設定一個變數
# ENV <key>=<value> ...
# 可以設定多個變數,每個變數為一個"<key>=<value>"的鍵值對
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy
EXPOSE
指定于外界互動的埠
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注:
EXPOSE并不會讓容器的埠訪問到主機,要使其可訪問,需要在docker run運行容器時通過-p來發布這些埠,或通過-P引數來發布EXPOSE匯出的所有埠
VOLUME
用于指定持久化目錄
格式:
VOLUME ["/path/to/dir"]
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
注:
一個卷可以存在于一個或多個容器的指定目錄,該目錄可以繞過聯合檔案系統,并具有以下功能:
1 卷可以容器間共享和重用
2 容器并不一定要和其它容器共享卷
3 修改卷后會立即生效
4 對卷的修改不會對鏡像產生影響
5 卷會一直存在,直到沒有任何容器在使用它
WORKDIR
作業目錄,類似于cd命令
# WORKDIR /path/to/workdir
WORKDIR /a #(這時作業目錄為/a)
WORKDIR b #(這時作業目錄為/a/b)
WORKDIR c #(這時作業目錄為/a/b/c)
#通過WORKDIR設定作業目錄后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都會在#該目錄下執行,在使用docker run運行容器時,可以通過-w引數覆寫構建時所設定的作業目錄,
USER
指定運行容器時的用戶名或 UID,后續的 RUN 也會使用指定用戶,使用USER指定用戶時,可以使用用戶名、UID或GID,或是兩者的組合,當服務不需要管理員權限時,可以通過該命令指定運行用戶,并且可以在之前創建所需要的用戶,
使用USER指定用戶后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都將使用該用戶,鏡像構建完成后,通過docker run運行容器時,可以通過-u引數來覆寫所指定的用戶,
# USER user
# USER user:group
# USER uid
# USER uid:gid
USER www
ARG
用于指定傳遞給構建運行時的變數
# ARG <name>[=<default value>]
ARG site
ARG build_user=www
ONBUILD器
用于設定鏡像觸發
# ONBUILD [INSTRUCTION]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
#當所構建的鏡像被用做其它鏡像的基礎鏡像,該鏡像中的觸發器將會被鑰觸發
一圖理解,yyds

圖片源于網路
docker file demo
# 一條coding
# Version 1.0
# Base images 基礎鏡像
FROM centos
#MAINTAINER 維護者資訊
MAINTAINER tianfeiyu
#ENV 設定環境變數
ENV PATH /usr/local/nginx/sbin:$PATH
#ADD 檔案放在當前目錄下,拷過去會自動解壓
ADD nginx-1.8.0.tar.gz /usr/local/
ADD epel-release-latest-7.noarch.rpm /usr/local/
#RUN 執行以下命令
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www
#WORKDIR 相當于cd
WORKDIR /usr/local/nginx-1.8.0
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install
RUN echo "daemon off;" >> /etc/nginx.conf
#EXPOSE 映射埠
EXPOSE 80
#CMD 運行以下命令
CMD ["nginx"]
網路通信
docker是如何與內部和外部進行資料交換的?
- 容器內部
- 內部訪問外部
- 外部訪問內部
網路知識補充
eth0
eth0 物理網卡是指服務器上實際的網路介面設備,設備用于接收以太網資料介面,資料包在各個節點中轉發和路由,
veth
veth 顧名思義,veth-pair 是一對的虛擬設備介面,它都是成對出現的,
一端連著協議堆疊,一端彼此相連著,一個設備從協議堆疊讀取資料后,會將資料發送到另一個設備上去,
正因為有這個特性,它常常充當著一個橋梁,連接著各種虛擬網路設備,典型的例子像“兩個 namespace 之間的連接”,“Bridge、OVS 之間的連接”,“Docker 容器之間的連接” 等等,以此構建出非常復雜的虛擬網路結構,比如 OpenStack Neutron,
bridge
Bridge 設備是一種純軟體實作的虛擬交換機,可以實作交換機的二層轉發,與現實世界中的交換機功能相似,
與其他虛擬網路設備一樣,可以配置 IP、MAC,Bridge 的主要功能是在多個接入 Bridge 的網路介面間轉發資料包,
網路模型
我們在使用docker run創建Docker容器時,可以用--net選項指定容器的網路模式,Docker有以下4種網路模式:
-
host模式,使用–net=host指定,
-
container模式,使用–net=container:NAME_or_ID指定,
-
none模式,使用–net=none指定,
-
bridge模式,使用–net=bridge指定,默認設定,
除這四種基本的之外,還支持各種自定義模型,

容器內部訪問
通常情況下,docker使用網橋+NAT的方式進行通信,Bridge 模式會為容器創建獨立的網路 namespace ,擁有獨立的網卡等網格堆疊,
NAT:可以理解為網卡
Dcoker0:就是網橋,交換機,ifconfig可見

同一宿主機上,Bridge 模式創建的容器會通過 DHCP 鏈接到 docker0 上,通過 docker0 實作網路的互通,「容器之間都是連接掉docker0這個網橋上的,它作為虛擬交換機使容器可以相互通信」,
內外部通信
宿主機的 IP 地址與容器 veth pair 的 IP 地址不在同一個網段,宿主機外的網路無法主動發現容器的存在,不能直接進行容器通信,所以 Docker 提供了埠映射的方式,就是將宿主機上的埠流量映射轉發到容器內的埠上,
ok,至此docker的全部知識總結完成,作為java開發,掌握這些足以讓你如魚得水,
??可以三連收藏啦!!??
最后
?今天是堅持刷題更文的第45/100天
?各位的點贊、關注、收藏、評論、訂閱就是一條創作的最大動力
?更多干歡訓迎訂閱專欄《技術專家修煉》
為了回饋各位粉絲,禮尚往來,給大家準備了一條多年積累下來的優質資源,包括 學習視頻、面試資料、珍藏電子書等
需要的小伙伴請私信「資料」,記得先關注哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/296565.html
標籤:java
上一篇:基于Spring MVC + Spring + MyBatis的【醫院就診掛號系統】
下一篇:【 JavaSE 】 資料型別
