作者:ChenZhen
博客地址:https://www.chenzhen.space/
版權(quán):來(lái)自b站視頻
【SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系統(tǒng)詳解springcloud微服務(wù)技術(shù)棧課程|黑馬程序員Java微服務(wù)】因?yàn)楹隈R的課件ppt做的實(shí)在是太好了,基本就是原樣copy過(guò)來(lái)整理一下。
如果對(duì)你有幫助,請(qǐng)給一個(gè)小小的star?
為了部署我的一個(gè)項(xiàng)目,專門學(xué)了docker的使用。
基于docker的隔離性容器機(jī)制,能夠無(wú)視linux版本的和各種依賴版本的差距進(jìn)行部署。不用再去鼓搗一些依賴和版本,我的項(xiàng)目也是部署成功了。不過(guò)可能要是不學(xué)docker,我的項(xiàng)目早就部署完了??。
1.1.什么是Docker
微服務(wù)雖然具備各種各樣的優(yōu)勢(shì),但服務(wù)的拆分通用給部署帶來(lái)了很大的麻煩。
- 分布式系統(tǒng)中,依賴的組件非常多,不同組件之間部署時(shí)往往會(huì)產(chǎn)生一些沖突。
- 在數(shù)百上千臺(tái)服務(wù)中重復(fù)部署,環(huán)境不一定一致,會(huì)遇到各種問題
1.1.1.應(yīng)用部署的環(huán)境問題
大型項(xiàng)目組件較多,運(yùn)行環(huán)境也較為復(fù)雜,部署時(shí)會(huì)碰到一些問題:
-
依賴關(guān)系復(fù)雜,容易出現(xiàn)兼容性問題
-
開發(fā)、測(cè)試、生產(chǎn)環(huán)境有差異
例如一個(gè)項(xiàng)目中,部署時(shí)需要依賴于node.js、Redis、RabbitMQ、MySQL等,這些服務(wù)部署時(shí)所需要的函數(shù)庫(kù)、依賴項(xiàng)各不相同,甚至?xí)袥_突。給部署帶來(lái)了極大的困難。
1.1.2.Docker解決依賴兼容問題
而Docker確巧妙的解決了這些問題,Docker是如何實(shí)現(xiàn)的呢?
Docker為了解決依賴的兼容問題的,采用了兩個(gè)手段:
-
將應(yīng)用的Libs(函數(shù)庫(kù))、Deps(依賴)、配置與應(yīng)用一起打包
-
將每個(gè)應(yīng)用放到一個(gè)隔離容器去運(yùn)行,避免互相干擾
這樣打包好的應(yīng)用包中,既包含應(yīng)用本身,也保護(hù)應(yīng)用所需要的Libs、Deps,無(wú)需再操作系統(tǒng)上安裝這些,自然就不存在不同應(yīng)用之間的兼容問題了。
雖然解決了不同應(yīng)用的兼容問題,但是開發(fā)、測(cè)試等環(huán)境會(huì)存在差異,操作系統(tǒng)版本也會(huì)有差異,怎么解決這些問題呢?
1.1.3.Docker解決操作系統(tǒng)環(huán)境差異
要解決不同操作系統(tǒng)環(huán)境差異問題,必須先了解操作系統(tǒng)結(jié)構(gòu)。以一個(gè)Ubuntu操作系統(tǒng)為例,結(jié)構(gòu)如下:
- 計(jì)算機(jī)硬件:例如CPU、內(nèi)存、磁盤等
- 系統(tǒng)內(nèi)核:所有Linux發(fā)行版的內(nèi)核都是Linux,例如CentOS、Ubuntu、Fedora等。內(nèi)核可以與計(jì)算機(jī)硬件交互,對(duì)外提供內(nèi)核指令,用于操作計(jì)算機(jī)硬件。
- 系統(tǒng)應(yīng)用:操作系統(tǒng)本身提供的應(yīng)用、函數(shù)庫(kù)。這些函數(shù)庫(kù)是對(duì)內(nèi)核指令的封裝,使用更加方便。
應(yīng)用于計(jì)算機(jī)交互的流程如下:
1)應(yīng)用調(diào)用操作系統(tǒng)應(yīng)用(函數(shù)庫(kù)),實(shí)現(xiàn)各種功能
2)系統(tǒng)函數(shù)庫(kù)是對(duì)內(nèi)核指令集的封裝,會(huì)調(diào)用內(nèi)核指令
3)內(nèi)核指令操作計(jì)算機(jī)硬件
Ubuntu和CentOSpringBoot都是基于Linux內(nèi)核,無(wú)非是系統(tǒng)應(yīng)用不同,提供的函數(shù)庫(kù)有差異:
此時(shí),如果將一個(gè)Ubuntu版本的MySQL應(yīng)用安裝到CentOS系統(tǒng),MySQL在調(diào)用Ubuntu函數(shù)庫(kù)時(shí),會(huì)發(fā)現(xiàn)找不到或者不匹配,就會(huì)報(bào)錯(cuò)了:
Docker如何解決不同系統(tǒng)環(huán)境的問題?
- Docker將用戶程序與所需要調(diào)用的系統(tǒng)(比如Ubuntu)函數(shù)庫(kù)一起打包
- Docker運(yùn)行到不同操作系統(tǒng)時(shí),直接基于打包的函數(shù)庫(kù),借助于操作系統(tǒng)的Linux內(nèi)核來(lái)運(yùn)行
1.1.4.小結(jié)
Docker如何解決大型項(xiàng)目依賴關(guān)系復(fù)雜,不同組件依賴的兼容性問題?
- Docker允許開發(fā)中將應(yīng)用、依賴、函數(shù)庫(kù)、配置一起打包,形成可移植鏡像
- Docker應(yīng)用運(yùn)行在容器中,使用沙箱機(jī)制,相互隔離
Docker如何解決開發(fā)、測(cè)試、生產(chǎn)環(huán)境有差異的問題?
- Docker鏡像中包含完整運(yùn)行環(huán)境,包括系統(tǒng)函數(shù)庫(kù),僅依賴系統(tǒng)的Linux內(nèi)核,因此可以在任意Linux操作系統(tǒng)上運(yùn)行
Docker是一個(gè)快速交付應(yīng)用、運(yùn)行應(yīng)用的技術(shù),具備下列優(yōu)勢(shì):
- 可以將程序及其依賴、運(yùn)行環(huán)境一起打包為一個(gè)鏡像,可以遷移到任意Linux操作系統(tǒng)
- 運(yùn)行時(shí)利用沙箱機(jī)制形成隔離容器,各個(gè)應(yīng)用互不干擾
- 啟動(dòng)、移除都可以通過(guò)一行命令完成,方便快捷
安裝Docker
Docker 分為 CE 和 EE 兩大版本。CE 即社區(qū)版(免費(fèi),支持周期 7 個(gè)月),EE 即企業(yè)版,強(qiáng)調(diào)安全,付費(fèi)使用,支持周期 24 個(gè)月。
Docker CE 分為 stable
test
和 nightly
三個(gè)更新頻道。
官方網(wǎng)站上有各種環(huán)境下的 安裝指南,這里主要介紹 Docker CE 在 CentOS上的安裝。
1.CentOS安裝Docker
Docker CE 支持 64 位版本 CentOS 7,并且要求內(nèi)核版本不低于 3.10, CentOS 7 滿足最低內(nèi)核的要求,所以我們?cè)贑entOS 7安裝Docker。
1.1.卸載(可選)
如果之前安裝過(guò)舊版本的Docker,可以使用下面命令卸載:
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine \
docker-ce
1.2.安裝docker
首先需要大家虛擬機(jī)聯(lián)網(wǎng),安裝yum工具
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2 --skip-broken
然后更新本地鏡像源:
# 設(shè)置docker鏡像源
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
yum makecache fast
然后輸入命令:
yum install -y docker-ce
docker-ce為社區(qū)免費(fèi)版本。稍等片刻,docker即可安裝成功。
1.3.啟動(dòng)docker
Docker應(yīng)用需要用到各種端口,逐一去修改防火墻設(shè)置。非常麻煩,因此建議大家直接關(guān)閉防火墻!
# 關(guān)閉
systemctl stop firewalld
# 禁止開機(jī)啟動(dòng)防火墻
systemctl disable firewalld
通過(guò)命令啟動(dòng)docker:
systemctl start docker # 啟動(dòng)docker服務(wù)
systemctl stop docker # 停止docker服務(wù)
systemctl restart docker # 重啟docker服務(wù)
然后輸入命令,可以查看docker版本:
docker -v
1.4.配置鏡像加速
docker官方鏡像倉(cāng)庫(kù)網(wǎng)速較差,我們需要設(shè)置國(guó)內(nèi)鏡像服務(wù):
參考阿里云的鏡像加速文檔:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
鏡像加速器
加速器地址 | https://ih82vvk5.mirror.aliyuncs.com |
---|
CentOS
-
安裝/升級(jí)Docker客戶端
推薦安裝1.10.0以上版本的Docker客戶端,參考文檔docker-ce -
配置鏡像加速器
針對(duì)Docker客戶端版本大于 1.10.0 的用戶您可以通過(guò)修改daemon配置文件/etc/docker/daemon.json來(lái)使用加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ih82vvk5.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2.Docker的基本操作
2.1.鏡像操作
2.1.1.鏡像名稱
首先來(lái)看下鏡像的名稱組成:
- 鏡名稱一般分兩部分組成:[repository]:[tag]。
- 在沒有指定tag時(shí),默認(rèn)是latest,代表最新版本的鏡像
如圖:
這里的mysql就是repository,5.7就是tag,合一起就是鏡像名稱,代表5.7版本的MySQL鏡像。
2.1.2.鏡像命令
常見的鏡像操作命令如圖:
2.1.3.案例1-拉取、查看鏡像
需求:從DockerHub中拉取一個(gè)nginx鏡像并查看
1)首先去鏡像倉(cāng)庫(kù)搜索nginx鏡像,比如DockerHub:
2)根據(jù)查看到的鏡像名稱,拉取自己需要的鏡像,通過(guò)命令:docker pull nginx
3)通過(guò)命令:docker images 查看拉取到的鏡像
2.1.4.案例2-保存、導(dǎo)入鏡像
需求:利用docker save將nginx鏡像導(dǎo)出磁盤,然后再通過(guò)load加載回來(lái)
1)利用docker xx --help命令查看docker save和docker load的語(yǔ)法
例如,查看save命令用法,可以輸入命令:
docker save --help
結(jié)果:
命令格式:
docker save -o [保存的目標(biāo)文件名稱] [鏡像名稱]
2)使用docker save導(dǎo)出鏡像到磁盤
運(yùn)行命令:
docker save -o nginx.tar nginx:latest
3)使用docker load加載鏡像
先刪除本地的nginx鏡像:
docker rmi nginx:latest
然后運(yùn)行命令,加載本地文件:
docker load -i nginx.tar
2.2.容器操作
2.2.1.容器相關(guān)命令
容器操作的命令如圖:
容器保護(hù)三個(gè)狀態(tài):
- 運(yùn)行:進(jìn)程正常運(yùn)行
- 暫停:進(jìn)程暫停,CPU不再運(yùn)行,并不釋放內(nèi)存
- 停止:進(jìn)程終止,回收進(jìn)程占用的內(nèi)存、CPU等資源
其中:
-
docker run:創(chuàng)建并運(yùn)行一個(gè)容器,處于運(yùn)行狀態(tài)
-
docker pause:讓一個(gè)運(yùn)行的容器暫停
-
docker unpause:讓一個(gè)容器從暫停狀態(tài)恢復(fù)運(yùn)行
-
docker stop:停止一個(gè)運(yùn)行的容器
-
docker start:讓一個(gè)停止的容器再次運(yùn)行
-
docker rm:刪除一個(gè)容器
2.2.2.案例-創(chuàng)建并運(yùn)行一個(gè)容器
創(chuàng)建并運(yùn)行nginx容器的命令:
docker run --name containerName -p 80:80 -d nginx
命令解讀:
- docker run :創(chuàng)建并運(yùn)行一個(gè)容器
- –name : 給容器起一個(gè)名字,比如叫做mn
- -p :將宿主機(jī)端口與容器端口映射,冒號(hào)左側(cè)是宿主機(jī)端口,右側(cè)是容器端口
- -d:后臺(tái)運(yùn)行容器
- nginx:鏡像名稱,例如nginx
這里的-p
參數(shù),是將容器端口映射到宿主機(jī)端口。
默認(rèn)情況下,容器是隔離環(huán)境,我們直接訪問宿主機(jī)的80端口,肯定訪問不到容器中的nginx。
現(xiàn)在,將容器的80與宿主機(jī)的80關(guān)聯(lián)起來(lái),當(dāng)我們?cè)L問宿主機(jī)的80端口時(shí),就會(huì)被映射到容器的80,這樣就能訪問到nginx了:
2.2.3.案例-進(jìn)入容器,修改文件
需求:進(jìn)入Nginx容器,修改HTML文件內(nèi)容,添加“傳智教育歡迎您”
提示:進(jìn)入容器要用到docker exec命令。
步驟:
1)進(jìn)入容器。進(jìn)入我們剛剛創(chuàng)建的nginx容器的命令為:
docker exec -it mn bash
命令解讀:
-
docker exec :進(jìn)入容器內(nèi)部,執(zhí)行一個(gè)命令
-
-it : 給當(dāng)前進(jìn)入的容器創(chuàng)建一個(gè)標(biāo)準(zhǔn)輸入、輸出終端,允許我們與容器交互
-
mn :要進(jìn)入的容器的名稱
-
bash:進(jìn)入容器后執(zhí)行的命令,bash是一個(gè)linux終端交互命令
2)進(jìn)入nginx的HTML所在目錄 /usr/share/nginx/html
容器內(nèi)部會(huì)模擬一個(gè)獨(dú)立的Linux文件系統(tǒng),看起來(lái)如同一個(gè)linux服務(wù)器一樣:
nginx的環(huán)境、配置、運(yùn)行文件全部都在這個(gè)文件系統(tǒng)中,包括我們要修改的html文件。
查看DockerHub網(wǎng)站中的nginx頁(yè)面,可以知道nginx的html目錄位置在/usr/share/nginx/html
我們執(zhí)行命令,進(jìn)入該目錄:
cd /usr/share/nginx/html
查看目錄下文件:
3)修改index.html的內(nèi)容
容器內(nèi)沒有vi命令,無(wú)法直接修改,我們用下面的命令來(lái)修改:
sed -i -e 's#Welcome to nginx#傳智教育歡迎您#g' -e 's#<head>#<head><meta charset="utf-8">#g' index.html
在瀏覽器訪問自己的虛擬機(jī)地址,例如我的是:http://192.168.150.101,即可看到結(jié)果:
2.2.4.小結(jié)
docker run命令的常見參數(shù)有哪些?
- –name:指定容器名稱
- -p:指定端口映射
- -d:讓容器后臺(tái)運(yùn)行
查看容器日志的命令:
- docker logs 容器名
- 添加 -f 參數(shù)可以持續(xù)查看日志
查看容器狀態(tài):
- docker ps
- docker ps -a 查看所有容器,包括已經(jīng)停止的
2.3.數(shù)據(jù)卷(容器數(shù)據(jù)管理)
在之前的nginx案例中,修改nginx的html頁(yè)面時(shí),需要進(jìn)入nginx內(nèi)部。并且因?yàn)闆]有編輯器,修改文件也很麻煩。
這就是因?yàn)槿萜髋c數(shù)據(jù)(容器內(nèi)文件)耦合帶來(lái)的后果。
要解決這個(gè)問題,必須將數(shù)據(jù)與容器解耦,這就要用到數(shù)據(jù)卷了。
2.3.1.什么是數(shù)據(jù)卷
**數(shù)據(jù)卷(volume)**是一個(gè)虛擬目錄,指向宿主機(jī)文件系統(tǒng)中的某個(gè)目錄。
一旦完成數(shù)據(jù)卷掛載,對(duì)容器的一切操作都會(huì)作用在數(shù)據(jù)卷對(duì)應(yīng)的宿主機(jī)目錄了。
這樣,我們操作宿主機(jī)的/var/lib/docker/volumes/html目錄,就等于操作容器內(nèi)的/usr/share/nginx/html目錄了
2.3.2.數(shù)據(jù)集操作命令
數(shù)據(jù)卷操作的基本語(yǔ)法如下:
docker volume [COMMAND]
docker volume命令是數(shù)據(jù)卷操作,根據(jù)命令后跟隨的command來(lái)確定下一步的操作:
- create 創(chuàng)建一個(gè)volume
- inspect 顯示一個(gè)或多個(gè)volume的信息
- ls 列出所有的volume
- prune 刪除未使用的volume
- rm 刪除一個(gè)或多個(gè)指定的volume
2.3.3.創(chuàng)建和查看數(shù)據(jù)卷
需求:創(chuàng)建一個(gè)數(shù)據(jù)卷,并查看數(shù)據(jù)卷在宿主機(jī)的目錄位置
① 創(chuàng)建數(shù)據(jù)卷
docker volume create html
② 查看所有數(shù)據(jù)
docker volume ls
③ 查看數(shù)據(jù)卷詳細(xì)信息卷
docker volume inspect html
數(shù)據(jù)卷操作:
- docker volume create:創(chuàng)建數(shù)據(jù)卷
- docker volume ls:查看所有數(shù)據(jù)卷
- docker volume inspect:查看數(shù)據(jù)卷詳細(xì)信息,包括關(guān)聯(lián)的宿主機(jī)目錄位置
- docker volume rm:刪除指定數(shù)據(jù)卷
- docker volume prune:刪除所有未使用的數(shù)據(jù)卷
2.3.4.掛載數(shù)據(jù)卷
我們?cè)趧?chuàng)建容器時(shí),可以通過(guò) -v 參數(shù)來(lái)掛載一個(gè)數(shù)據(jù)卷到某個(gè)容器內(nèi)目錄,命令格式如下:
docker run \
--name mn \
-v html:/root/html \
-p 8080:80
nginx \
這里的-v就是掛載數(shù)據(jù)卷的命令:
-
-v html:/root/htm
:把html數(shù)據(jù)卷掛載到容器內(nèi)的/root/html這個(gè)目錄中
2.3.5.案例-給nginx掛載數(shù)據(jù)卷
需求:創(chuàng)建一個(gè)nginx容器,修改容器內(nèi)的html目錄內(nèi)的index.html內(nèi)容
分析:上個(gè)案例中,我們進(jìn)入nginx容器內(nèi)部,已經(jīng)知道nginx的html目錄所在位置/usr/share/nginx/html ,我們需要把這個(gè)目錄掛載到html這個(gè)數(shù)據(jù)卷上,方便操作其中的內(nèi)容。
提示:運(yùn)行容器時(shí)使用 -v 參數(shù)掛載數(shù)據(jù)卷
步驟:
① 創(chuàng)建容器并掛載數(shù)據(jù)卷到容器內(nèi)的HTML目錄
docker run --name mn -v html:/usr/share/nginx/html -p 80:80 -d nginx
② 進(jìn)入html數(shù)據(jù)卷所在位置,并修改HTML內(nèi)容
# 查看html數(shù)據(jù)卷的位置
docker volume inspect html
# 進(jìn)入該目錄
cd /var/lib/docker/volumes/html/_data
# 修改文件
vi index.html
2.3.6.案例-給MySQL掛載本地目錄
容器不僅僅可以掛載數(shù)據(jù)卷,也可以直接掛載到宿主機(jī)目錄上。關(guān)聯(lián)關(guān)系如下:
- 帶數(shù)據(jù)卷模式:宿主機(jī)目錄 --> 數(shù)據(jù)卷 —> 容器內(nèi)目錄
- 直接掛載模式:宿主機(jī)目錄 —> 容器內(nèi)目錄
如圖:
語(yǔ)法:
目錄掛載與數(shù)據(jù)卷掛載的語(yǔ)法是類似的:
- -v [宿主機(jī)目錄]:[容器內(nèi)目錄]
- -v [宿主機(jī)文件]:[容器內(nèi)文件]
需求:創(chuàng)建并運(yùn)行一個(gè)MySQL容器,將宿主機(jī)目錄直接掛載到容器
實(shí)現(xiàn)思路如下:
1)在將課前資料中的mysql.tar文件上傳到虛擬機(jī),通過(guò)load命令加載為鏡像
2)創(chuàng)建目錄/tmp/mysql/data
3)創(chuàng)建目錄/tmp/mysql/conf,將課前資料提供的hmy.cnf文件上傳到/tmp/mysql/conf
4)去DockerHub查閱資料,創(chuàng)建并運(yùn)行MySQL容器,要求:
① 掛載/tmp/mysql/data到mysql容器內(nèi)數(shù)據(jù)存儲(chǔ)目錄
② 掛載/tmp/mysql/conf/hmy.cnf到mysql容器的配置文件
③ 設(shè)置MySQL密碼
2.3.7.小結(jié)
docker run的命令中通過(guò) -v 參數(shù)掛載文件或目錄到容器中:
- -v volume名稱:容器內(nèi)目錄
- -v 宿主機(jī)文件:容器內(nèi)文
- -v 宿主機(jī)目錄:容器內(nèi)目錄
數(shù)據(jù)卷掛載與目錄直接掛載的
- 數(shù)據(jù)卷掛載耦合度低,由docker來(lái)管理目錄,但是目錄較深,不好找
- 目錄掛載耦合度高,需要我們自己管理目錄,不過(guò)目錄容易尋找查看
3.Dockerfile自定義鏡像
常見的鏡像在DockerHub就能找到,但是我們自己寫的項(xiàng)目就必須自己構(gòu)建鏡像了。
而要自定義鏡像,就必須先了解鏡像的結(jié)構(gòu)才行。
3.1.鏡像結(jié)構(gòu)
鏡像是將應(yīng)用程序及其需要的系統(tǒng)函數(shù)庫(kù)、環(huán)境、配置、依賴打包而成。
我們以MySQL為例,來(lái)看看鏡像的組成結(jié)構(gòu):
簡(jiǎn)單來(lái)說(shuō),鏡像就是在系統(tǒng)函數(shù)庫(kù)、運(yùn)行環(huán)境基礎(chǔ)上,添加應(yīng)用程序文件、配置文件、依賴文件等組合,然后編寫好啟動(dòng)腳本打包在一起形成的文件。
我們要構(gòu)建鏡像,其實(shí)就是實(shí)現(xiàn)上述打包的過(guò)程。
3.2.Dockerfile語(yǔ)法
構(gòu)建自定義的鏡像時(shí),并不需要一個(gè)個(gè)文件去拷貝,打包。
我們只需要告訴Docker,我們的鏡像的組成,需要哪些BaseImage、需要拷貝什么文件、需要安裝什么依賴、啟動(dòng)腳本是什么,將來(lái)Docker會(huì)幫助我們構(gòu)建鏡像。
而描述上述信息的文件就是Dockerfile文件。
Dockerfile就是一個(gè)文本文件,其中包含一個(gè)個(gè)的指令(Instruction),用指令來(lái)說(shuō)明要執(zhí)行什么操作來(lái)構(gòu)建鏡像。每一個(gè)指令都會(huì)形成一層Layer。
更新詳細(xì)語(yǔ)法說(shuō)明,請(qǐng)參考官網(wǎng)文檔: https://docs.docker.com/engine/reference/builder
3.3.構(gòu)建Java項(xiàng)目
3.3.1.基于Ubuntu構(gòu)建Java項(xiàng)目
-
步驟1:新建一個(gè)空文件夾docker-demo
-
步驟2:拷貝docker-demo.jar文件到docker-demo這個(gè)目錄
-
步驟3:拷貝jdk8.tar.gz文件到docker-demo這個(gè)目錄
-
步驟4:拷貝Dockerfile到docker-demo這個(gè)目錄
-
其中的內(nèi)容如下:
# 指定基礎(chǔ)鏡像 FROM ubuntu:16.04 # 配置環(huán)境變量,JDK的安裝目錄 ENV JAVA_DIR=/usr/local # 拷貝jdk和java項(xiàng)目的包 COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo.jar /tmp/app.jar # 安裝JDK RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8 # 配置環(huán)境變量 ENV JAVA_HOME=$JAVA_DIR/java8 ENV PATH=$PATH:$JAVA_HOME/bin # 暴露端口 EXPOSE 8090 # 入口,java項(xiàng)目的啟動(dòng)命令 ENTRYPOINT java -jar /tmp/app.jar
-
步驟5:進(jìn)入docker-demo
將準(zhǔn)備好的docker-demo上傳到虛擬機(jī)任意目錄,然后進(jìn)入docker-demo目錄下
-
步驟6:運(yùn)行命令:
docker build -t javaweb:1.0 .
最后訪問 http://192.168.150.101:8090/hello/count,其中的ip改成你的虛擬機(jī)ip
docker build 命令用于從 Dockerfile 構(gòu)建 Docker 鏡像。它有以下常用參數(shù):
- -t, --tag :給構(gòu)建的鏡像打標(biāo)簽,格式為 name:tag 或 name,默認(rèn)latest標(biāo)簽。
- –no-cache : 構(gòu)建鏡像過(guò)程不使用緩存,獲取最新內(nèi)容。
- -p, --pull : 構(gòu)建鏡像過(guò)程中拉取父鏡像,獲取最新版父鏡像。
- .:指定要構(gòu)建的 Dockerfile 文件所在的路徑(默認(rèn)路徑)。
3.3.2.基于java8構(gòu)建Java項(xiàng)目
雖然我們可以基于Ubuntu基礎(chǔ)鏡像,添加任意自己需要的安裝包,構(gòu)建鏡像,但是卻比較麻煩。所以大多數(shù)情況下,我們都可以在一些安裝了部分軟件的基礎(chǔ)鏡像上做改造。
例如,構(gòu)建java項(xiàng)目的鏡像,可以在已經(jīng)準(zhǔn)備了JDK的基礎(chǔ)鏡像基礎(chǔ)上構(gòu)建。
需求:基于java:8-alpine鏡像,將一個(gè)Java項(xiàng)目構(gòu)建為鏡像
實(shí)現(xiàn)思路如下:
-
① 新建一個(gè)空的目錄,然后在目錄中新建一個(gè)文件,命名為Dockerfile
-
② 拷貝課前資料提供的docker-demo.jar到這個(gè)目錄中
-
③ 編寫Dockerfile文件:
-
a )基于java:8-alpine作為基礎(chǔ)鏡像
-
b )將app.jar拷貝到鏡像中
-
c )暴露端口
-
d )編寫入口ENTRYPOINT
內(nèi)容如下:
FROM java:8-alpine COPY ./app.jar /tmp/app.jar EXPOSE 8090 ENTRYPOINT java -jar /tmp/app.jar
-
-
④ 使用docker build命令構(gòu)建鏡像
-
⑤ 使用docker run創(chuàng)建容器并運(yùn)行
容器遷移
如果您想將現(xiàn)有的容器遷移到另一臺(tái)服務(wù)器上運(yùn)行,可以考慮以下幾種方法:
- 導(dǎo)出和導(dǎo)入容器:使用 docker export 命令將容器導(dǎo)出為一個(gè) tar 歸檔文件,然后將該文件傳輸?shù)侥繕?biāo)服務(wù)器,并使用 docker import 命令將歸檔文件導(dǎo)入為鏡像。最后,在目標(biāo)服務(wù)器上使用導(dǎo)入的鏡像創(chuàng)建和運(yùn)行新容器。
導(dǎo)出容器:
docker export -o container.tar container_id
導(dǎo)入容器:
docker import container.tar image_name:tag
在目標(biāo)服務(wù)器上創(chuàng)建并運(yùn)行容器:
docker run -d --name new_container -p host_port:container_port image_name:tag
這種方法的缺點(diǎn)是容器的歷史記錄和元數(shù)據(jù)將丟失。
- Docker 鏡像倉(cāng)庫(kù):將容器推送到 Docker 鏡像倉(cāng)庫(kù)(如 Docker Hub)中,并在目標(biāo)服務(wù)器上使用 docker pull 命令從鏡像倉(cāng)庫(kù)拉取鏡像。確保在目標(biāo)服務(wù)器上已經(jīng)安裝 Docker,并且可以訪問所使用的鏡像倉(cāng)庫(kù)。
推送鏡像到倉(cāng)庫(kù):
docker login
docker tag image_name:tag username/repository:tag
docker push username/repository:tag
在目標(biāo)服務(wù)器上拉取并運(yùn)行容器:
docker login
docker pull username/repository:tag
docker run -d --name new_container -p host_port:container_port username/repository:tag
通過(guò)使用 Docker 鏡像倉(cāng)庫(kù),您可以輕松地在不同的服務(wù)器上共享和部署容器鏡像。
選擇哪種方法取決于您的具體需求和環(huán)境。請(qǐng)確保在遷移容器之前備份重要的數(shù)據(jù),并在目標(biāo)服務(wù)器上驗(yàn)證容器的正確運(yùn)行。
3.4.小結(jié)
小結(jié):
-
Dockerfile的本質(zhì)是一個(gè)文件,通過(guò)指令描述鏡像的構(gòu)建過(guò)程
-
Dockerfile的第一行必須是FROM,從一個(gè)基礎(chǔ)鏡像來(lái)構(gòu)建
-
基礎(chǔ)鏡像可以是基本操作系統(tǒng),如Ubuntu。也可以是其他人制作好的鏡像,例如:java:8-alpine
3.5 一個(gè)具體的例子
這個(gè)dockerfile是我部署一個(gè)python的Flask項(xiàng)目的文件,docker可以看做一臺(tái)獨(dú)立的電腦。
我們基于3.10.7版本的python來(lái)構(gòu)建容器,這個(gè)鏡像的大小是一個(gè)多G,原因不僅只是python也包含了其他的依賴。我們可以先去從網(wǎng)上把鏡像下載到本地,當(dāng)然不下載的話,執(zhí)行FROM的時(shí)候也會(huì)自動(dòng)到網(wǎng)上下載
FROM python:3.10.7
# 在容器中創(chuàng)建一個(gè)工作目錄
WORKDIR /app
# 復(fù)制項(xiàng)目文件到容器中
COPY . /app
# 其中-r指定的是txt文件的位置
RUN pip install -r requirements.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
# RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8083
WORKDIR /app/chatgpt-embedding
# 啟動(dòng)應(yīng)用
CMD ["python", "application.py"]
3.6 部署github上熱門的chatgpt網(wǎng)頁(yè)ui
https://github.com/mckaywrigley/chatbot-ui
該項(xiàng)目也是提供了docker容器的部署方式,我們直接執(zhí)行下面的語(yǔ)句即可
docker run --name chatgpt-ui \
-e OPENAI_API_HOST=https://xxxxx.com \
-e OPENAI_API_KEY=sk-xxxxxxxxxxxx \
-p 3000:3000 \
-d ghcr.io/mckaywrigley/chatbot-ui:main
該語(yǔ)句運(yùn)行一個(gè)ghcr.io/mckaywrigley/chatbot-ui:main鏡像,鏡像名稱的結(jié)構(gòu)通常是 <倉(cāng)庫(kù)>/<鏡像>:<標(biāo)簽>,其中倉(cāng)庫(kù)指定了鏡像所在的位置,鏡像指定了具體的鏡像文件,標(biāo)簽指定了鏡像的版本或標(biāo)識(shí)符。
因此,ghcr.io/mckaywrigley/chatbot-ui:main 表示您要拉取 mckaywrigley 用戶的 chatbot-ui 倉(cāng)庫(kù)中 main 分支的鏡像。
當(dāng)然你的服務(wù)器上應(yīng)該沒有下載該鏡像,所以它會(huì)自己去網(wǎng)上找對(duì)應(yīng)的資源下載
–name :是給該容器取別名,這里取了chatgpt-ui作為別名
-e :這將在容器中設(shè)置OPENAI_API_HOST和OPENAI_API_KEY環(huán)境變量,其他環(huán)境變量可以參考作者github
-p :開發(fā)端口映射3000->3000
-d :后臺(tái)運(yùn)行
環(huán)境變量中:
OPENAI_API_HOST要填你的代理服務(wù)器的域名或者IP,國(guó)內(nèi)由于種種原因是無(wú)法訪問chatgpt服務(wù)器的,所有必須要有代理服務(wù)器,至于怎么搭建代理服務(wù)器,可以去找我的早期文章
OPENAI_API_KEY填你的openai的apikey
理論上運(yùn)行這一句代碼之后,就能在端口3000上訪問到服務(wù)了
3.7 部署mysql8數(shù)據(jù)庫(kù)
我們先將mysql8的鏡像從網(wǎng)絡(luò)拉取到本地
docker pull mysql:8.0.11
啟動(dòng) MySQL 實(shí)例可以使用下面的命令:
docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD=<your_password> \
-v /root/mydata/mysql/log:/var/log/mysql \
-v /root/mydata/mysql/data:/var/lib/mysql \
-v /root/mydata/mysql/conf:/etc/mysql \
-p 3306:3306 \
mysql:8.0.11
docker run -d \
--name mysql2 \
-e MYSQL_ROOT_PASSWORD=MIIEpAIBAAKMIIASDSDAAK \
-v /root/mydata/mysql/log:/var/log/mysql \
-v /root/mydata/mysql/data:/var/lib/mysql \
-v /root/mydata/mysql/conf:/etc/mysql \
-v /root/mydata/mysql/mysql-files:/var/lib/mysql-files \
-p 9276:3306 \
mysql2:8.0.11
這是一個(gè)用于在Docker容器中運(yùn)行MySQL數(shù)據(jù)庫(kù)的Docker運(yùn)行命令,以下是各個(gè)參數(shù)的解釋:
-
docker run
: 運(yùn)行Docker容器的命令。 -
-d
: 這是一個(gè)選項(xiàng),表示在后臺(tái)運(yùn)行容器(以分離模式)。這意味著容器會(huì)在后臺(tái)運(yùn)行,并且不會(huì)占用你的終端。 -
--name mysql
: 使用這個(gè)選項(xiàng)來(lái)指定容器的名稱,這里將容器命名為"mysql",以便稍后使用容器名稱來(lái)管理它。 -
-e MYSQL_ROOT_PASSWORD=<your_password>
: 使用-e
選項(xiàng)設(shè)置環(huán)境變量。用于指定MySQL的root用戶密碼。請(qǐng)將<your_password>
替換為你想要設(shè)置的實(shí)際密碼。 -
-v /root/mydata/mysql/log:/var/log/mysql
: 使用-v
選項(xiàng)將主機(jī)文件系統(tǒng)的目錄/root/mydata/mysql/log
掛載到容器內(nèi)的/var/log/mysql
目錄。這樣做是為了將MySQL的日志文件存儲(chǔ)到主機(jī)上,以便以后查看或備份。 -
-v /root/mydata/mysql/data:/var/lib/mysql
: 同樣使用-v
選項(xiàng)將主機(jī)文件系統(tǒng)的目錄/root/mydata/mysql/data
掛載到容器內(nèi)的/var/lib/mysql
目錄。這是為了將MySQL的數(shù)據(jù)文件存儲(chǔ)到主機(jī)上,以便數(shù)據(jù)持久化。 -
-v /root/mydata/mysql/conf:/etc/mysql
: 使用-v
選項(xiàng)將主機(jī)文件系統(tǒng)的目錄/root/mydata/mysql/conf
掛載到容器內(nèi)的/etc/mysql
目錄。這是為了將MySQL的配置文件存儲(chǔ)到主機(jī)上,以便自定義MySQL的配置。 -
-v /root/mydata/mysql/mysql-files:/var/lib/mysql-files
當(dāng)指定了外部配置文件與外部存儲(chǔ)路徑時(shí),也需要指定/var/lib/mysql-files
的外部目錄 -
-p 3306:3306
: 使用-p
選項(xiàng)將主機(jī)的端口3306
映射到容器內(nèi)的端口3306
。MySQL默認(rèn)使用端口3306
來(lái)監(jiān)聽連接請(qǐng)求,這個(gè)映射允許你通過(guò)主機(jī)的3306
端口訪問MySQL服務(wù)器。(前者是主機(jī)端口,后者是docker容器端口)一般我們會(huì)把端口映射到3306以外的端口號(hào),防止黑客攻擊。 -
mysql:8.0.11
: 這是要運(yùn)行的Docker鏡像的名稱和版本標(biāo)簽。在這里,使用了MySQL 8.0.11的官方Docker鏡像。
運(yùn)行之后我用遠(yuǎn)程軟件進(jìn)行連接,本以為一切順利的,但是出現(xiàn)了以下問題
這個(gè)錯(cuò)誤出現(xiàn)的原因是從MySQL8.x版本開始, 身份驗(yàn)證插件改為了caching_sha2_password, 而之前的版本為mysql_native_password. 我們現(xiàn)在用的很多MySQL客戶端暫時(shí)還不支持新的身份驗(yàn)證插件. 對(duì)了, IDEA是支持的, 所以用IDEA連接MySQL 8.x數(shù)據(jù)庫(kù)沒有這個(gè)問題.
解決辦法:
進(jìn)入容器內(nèi)部操作:
這里的mysql8是我在前面給容器起的名字,你們換成自己的名字即可
docker exec -it mysql8 bash
進(jìn)入 MySQL 命令行
mysql -uroot -p
然后,系統(tǒng)將提示您輸入密碼。
成功進(jìn)入
查詢
SELECT user, host, plugin from mysql.user;
可以看到默認(rèn)的驗(yàn)證器插件為 caching_sha2_password
, 改回mysql_native_password
即可:
alter user 'root'@'%' identified with mysql_native_password by '123456';
用于更改名為 ‘root’,在任何主機(jī)上都可訪問的用戶的認(rèn)證方式為 mysql_native_password
,并將其密碼設(shè)置為 ‘123456’。這意味著該用戶可以從任何主機(jī)連接到 MySQL,并且需要使用 MySQL 原生密碼進(jìn)行認(rèn)證。
請(qǐng)注意,您需要將 ‘root’ 替換為要更改的實(shí)際用戶名,并將 ‘123456’ 替換為你自己的密碼。
修改完畢后刷新一下
FLUSH PRIVILEGES;
看看是否生效:
SELECT User, Host, plugin from mysql.user;
重新連接成功!文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-756410.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-756410.html
到了這里,關(guān)于Docker的使用教程、學(xué)習(xí)筆記,附實(shí)戰(zhàn):部署chatgpt網(wǎng)頁(yè)版ui,部署mysql8數(shù)據(jù)庫(kù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!