Docker 完整版教程
Docker 安裝
一、安裝前必讀
在安裝 Docker 之前,先說一下配置,我這裡是Centos7 Linux 內核:官方建議 3.10 以上,3.8以上貌似也可。
注意:本文的命令使用的是 root 用戶登錄執行,不是 root 的話所有命令前面要加 sudo
1.查看當前的內核版本
uname -r
複製
我這裡是3.10 ,滿足條件。
2.使用 root 許可權更新 yum 包(生產環境中此步操作需慎重,看自己情況,學習的話隨便搞)
yum -y update
複製
這個命令不是必須執行的,看個人情況,後面出現不兼容的情況的話就必須update了
注意
yum -y update:升級所有包同時也升級軟體和系統內核;
yum -y upgrade:只升級所有包,不升級軟體和系統內核
複製
3.卸載舊版本(如果之前安裝過的話)
yum remove docker docker-common docker-selinux docker-engine
複製
二、安裝Docker的詳細步驟
1.安裝需要的軟體包, yum-util 提供yum-config-manager功能,另兩個是devicemapper驅動依賴
yum install -y yum-utils device-mapper-persistent-data lvm2
複製
2.設置 yum 源
設置一個yum源,下面兩個都可用
yum-config-manager --add-repo //download.docker.com/linux/centos/docker-ce.repo(中央倉庫)
yum-config-manager --add-repo //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo(阿里倉庫)
複製
3.選擇docker版本並安裝 (1)查看可用版本有哪些
yum list docker-ce --showduplicates | sort -r
複製,查看裡面的版本號
(2)選擇一個版本並安裝:yum install docker-ce-版本號
yum -y install docker-ce-20.10.4
複製
出現下圖說明安裝成功
4.啟動 Docker 並設置開機自啟
systemctl start docker
systemctl enable docker
複製
Docker 基礎
HelloWorld鏡像背後原理
底層原理
底層
Docker Engine是一個客戶端-伺服器應用程式,具有以下主要組件:
- 一個伺服器,它是一種長期運行的程式,稱為守護進程(dockerd命令)
- 一個REST API,它指定程式可以用來與守護進程對話並指示它做什麼的介面。
Docker是一個Client Server結構的系統,Docker守護進程運行在主機上,然後通過Socket連接從客戶 端訪問,守護進程從客戶端接受命令並管理運行在主機上的容器。容器,是一個運行時環境就是我們所說的集裝箱。
Docker 為什麼比 VM 快
- docker有著比虛擬機更少的抽象層。由於docker不需要Hypervisor實現硬體資源虛擬化,運行在docker容器上的程式直接使用的都是實際物理機的硬體資源。因此在CPU、記憶體利用率上docker將會在效率上有明顯優勢。
- docker利用的是宿主機的內核,而不需要Guest OS。因此,當新建一個 容器時,docker不需要和虛擬機一樣重新載入一個作業系統內核。仍而避免引尋、載入作業系統內核返個比較費時費資源的過程,當新建一個虛擬機時,虛擬機軟體需要載入GuestOS,返個新建過程是分鐘級別的。而docker由於直接利用宿主機的作業系統,則省略了返個過程,因此新建一個docker容器只需要幾秒鐘。
Docker 常用命令
幫助文檔:參考文檔|Docker 文檔
VM 安裝 Docker 執行命令會有點小問題
問題如下:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "//%2Fvar%2Frun%2Fdocker.sock/v1.24/version": dial unix /var/run/docker.sock: connect: permission denied
解決方式
切換 root 許可權即可
su root su的解釋(switch user)
幫助命令
docker version # docker版本資訊
docker info # 系統級別的資訊,包括鏡像和容器的數量
docker 命令 --help
鏡像命令
docker images 查看所有本地主機上的鏡像
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 7 months ago 13.3kB
# 解釋
REPOSITORY # 鏡像的倉庫
TAG # 鏡像的標籤
IMAGE ID # 鏡像的ID
CREATED # 鏡像的創建時間
SIZE # 鏡像的大小
# 可選項
--all , -a # 列出所有鏡像
--quiet , -q # 只顯示鏡像的id
docker search 查找鏡像
- –filter=STARS=3000 搜素出來的鏡像就是STARS大於3000的
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9822 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3586 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 719 [OK]
# 可選項
--filter=STARS=3000 # 搜素出來的鏡像就是STARS大於3000的
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 9822 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3586 [OK]
- 過濾 STARS 的數量
docker pull 下拉鏡像
- 如果不寫tag,默認就是latest
- 版本去 Docker 官網搜索查看
- 查詢地址:tomcat Tags | Docker Hub
# 下載鏡像,docker pull 鏡像名[:tag]
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker pull mysql
Using default tag: latest # 如果不寫tag,默認就是latest
latest: Pulling from library/mysql
bf5952930446: Pull complete # 分層下載,dockerimages的核心,聯合文件系統
8254623a9871: Pull complete
938e3e06dac4: Pull complete
ea28ebf28884: Pull complete
f3cef38785c2: Pull complete
894f9792565a: Pull complete
1d8a57523420: Pull complete
6c676912929f: Pull complete
ff39fdb566b4: Pull complete
fff872988aba: Pull complete
4d34e365ae68: Pull complete
7886ee20621e: Pull complete
Digest: sha256:c358e72e100ab493a0304bda35e6f239db2ec8c9bb836d8a427ac34307d074ed # 簽名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真實地址
# 等價於
docker pull mysql
docker pull docker.io/library/mysql:latest
# 指定版本下載
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
bf5952930446: Already exists
8254623a9871: Already exists
938e3e06dac4: Already exists
ea28ebf28884: Already exists
f3cef38785c2: Already exists
894f9792565a: Already exists
1d8a57523420: Already exists
5f09bf1d31c1: Pull complete
1b6ff254abe7: Pull complete
74310a0bf42d: Pull complete
d398726627fd: Pull complete
Digest: sha256:da58f943b94721d46e87d5de208dc07302a8b13e638cd1d24285d222376d6d84
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
# 查看本地鏡像
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 718a6da099d8 6 days ago 448MB
mysql latest 0d64f46acfd1 6 days ago 544MB
hello-world latest bf756fb1ae65 7 months ago 13.3kB
docker rmi 刪除鏡像
- i 是鏡像
- docker images 查詢 ID ,然後刪除
- docker rmi -f $(docker images -aq) 刪除所有
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID # 刪除指定鏡像
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f IMAGE ID1 IMAGE ID2 IMAGE ID3 # 刪除多個鏡像,中間空格隔開
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker rmi -f $(docker images -aq) # 刪除所有鏡像
容器命令
說明: 我們有了鏡像才可創建容器,linux,下載一個centos鏡像來測試學習
docker pull centos
新建容器啟動
$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
docker run [可選參數] image[:tag]
# 參數說明
--name=「Name」 容器名字 tomcat01 tomcat02 用來區分容器
-d 後台方式運行
-it 使用交互方式運行,進入容器查看內容
-p 指定容器的埠 -p 8080:8080
-p ip:主機埠:容器埠
-p 主機埠:容器埠(常用)
-p 容器埠
容器埠
-p 隨機指定埠
# 測試,啟動並進入容器
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker run -it centos /bin/bash
[root@74e82b7980e7 /]# ls # 查看容器內的centos,基礎版本,很多命令是不完善的
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
# 從容器中退回主機,這個是退出關閉容器
[root@77969f5dcbf9 /]# exit
exit
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# ls
bin dev fanfan lib lost+found mnt proc run srv tmp var
boot etc home lib64 media opt root sbin sys usr
退出容器
exit # 直接退出容器並關閉
Ctrl + P + Q # 容器不關閉退出
退出之後又想重新進入
docker exec -it 容器id bash (新的終端)
docker attach 容器id(通過ps獲取) (原來的)
attach 和 exec的區別
- 用docker exec -it命令進入容器如果輸入exit命令直接退出container,但是不會使得container停止,平時我用這個命令比較多。
- docker attach可以attach到一個已經運行的容器的stdin,然後進行命令執行的動作。但是需要注意的是,如果從這個stdin中exit,會導致容器的停止。
列出所有的運行的容器
# docker ps 命令
# 列出當前正在運行的容器
-a # 列出正在運行的容器包括歷史容器
-n=? # 顯示最近創建的容器
-q # 只顯示當前容器的編號
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77969f5dcbf9 centos "/bin/bash" 5 minutes ago Exited (0) 5 minutes ago xenodochial_bose
74e82b7980e7 centos "/bin/bash" 16 minutes ago Exited (0) 6 minutes ago silly_cori
a57250395804 bf756fb1ae65 "/hello" 7 hours ago Exited (0) 7 hours ago elated_nash
392d674f4f18 bf756fb1ae65 "/hello" 8 hours ago Exited (0) 8 hours ago distracted_mcnulty
571d1bc0e8e8 bf756fb1ae65 "/hello" 23 hours ago Exited (0) 23 hours ago magical_burnell
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps -qa
77969f5dcbf9
74e82b7980e7
a57250395804
392d674f4f18
571d1bc0e8e8
刪除容器
docker rm -f 容器id # 刪除指定容器
docker rm -f $(docker ps -aq) # 刪除所有容器
docker ps -a -q|xargs docker rm -f # 刪除所有的容器
啟動和停止容器的操作
docker start 容器id # 啟動容器
docker restart 容器id # 重啟容器
docker stop 容器id # 停止當前正在運行的容器
docker kill 容器id # 強制停止當前的容器
- 刪除容器和鏡像沒有太大的關係
常用的其他命令
後台啟動
-
docker 容器使用後台運行, 就必須要有一個前台進程,docker發現沒有應用,就會自動停止
-
docker run -dit centos (後台啟動,不會關閉)
# 命令 docker run -d 鏡像名[:tag]
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos
# 問題 docker ps, 發現centos停止了
# 常見的坑, docker 容器使用後台運行, 就必須要有一個前台進程,docker發現沒有應用,就會自動停止
# nginx, 容器啟動後,發現自己沒有提供服務,就會立即停止,就是沒有程式了
查看日誌
docker logs -tf --tail number 容器id
# 顯示日誌
-tf # 顯示日誌
--tail number # 顯示日誌條數
docker logs -tf --tail number 容器id
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 1 8d1621e09bff
2020-08-11T10:53:15.987702897Z [root@8d1621e09bff /]# exit # 日誌輸出
# 自己編寫一段shell腳本
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker run -d centos /bin/sh -c "while true;do echo xiaofan;sleep 1;done"
a0d580a21251da97bc050763cf2d5692a455c228fa2a711c3609872008e654c2
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a0d580a21251 centos "/bin/sh -c 'while t…" 3 seconds ago Up 1 second lucid_black
# 顯示日誌
-tf # 顯示日誌
--tail number # 顯示日誌條數
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker logs -tf --tail 10 a0d580a21251
查看容器中進程資訊ps
# 命令 docker top 容器id
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker top df358bc06b17
UID PID PPID C STIME TTY
root 28498 28482 0 19:38 ?
查看鏡像的元數據
# 命令
docker inspect 容器id
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker inspect df358bc06b17
[
{
"Id": "df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3",
"Created": "2020-08-11T11:38:34.935048603Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 28498,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-08-11T11:38:35.216616071Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:0d120b6ccaa8c5e149176798b3501d4dd1885f961922497cd0abef155c869566",
"ResolvConfPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hostname",
"HostsPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/hosts",
"LogPath": "/var/lib/docker/containers/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3/df358bc06b17ef44f215d35d9f46336b28981853069a3739edfc6bd400f99bf3-json.log",
"Name": "/hungry_heisenberg",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Capabilities": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360-init/diff:/var/lib/docker/overlay2/62926d498bd9d1a6684bb2f9920fb77a2f88896098e66ef93c4b74fcb19f29b6/diff",
"MergedDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/merged",
"UpperDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/diff",
"WorkDir": "/var/lib/docker/overlay2/5af8a2aadbdba9e1e066331ff4bce56398617710a22ef906f9ce4d58bde2d360/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "df358bc06b17",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/bash"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20200809",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "4822f9ac2058e8415ebefbfa73f05424fe20cc8280a5720ad3708fa6e80cdb08",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/4822f9ac2058",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "30d6017888627cb565618b1639fecf8fc97e1ae4df5a9fd5ddb046d8fb02b565",
"EndpointID": "5fd269c0a28227241e40cd30658e3ffe8ad6cc3e6514917c867d89d36a31d605",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
從容器中拷貝文件到主機
docker cp 容器id:容器內路徑 目的地主機路徑
[root@iZ2zeg4ytp0whqtmxbsqiiZ /]# docker cp 7af535f807e0:/home/Test.java /home
小結
attach Attach local standard input, output, and error streams to a running container
#當前shell下 attach連接指定運行的鏡像
build Build an image from a Dockerfile # 通過Dockerfile訂製鏡像
commit Create a new image from a container's changes #提交當前容器為新的鏡像
cp Copy files/folders between a container and the local filesystem #拷貝文件
create Create a new container #創建一個新的容器
diff Inspect changes to files or directories on a container's filesystem
#查看docker容器的變化
events Get real time events from the server # 從服務獲取容器實時時間
exec Run a command in a running container # 在運行中的容器上運行命令
export Export a container's filesystem as a tar archive
#導出容器文件系統作為一個tar歸檔文件[對應import]
history Show the history of an image # 展示一個鏡像形成歷史
images List images #列出系統當前的鏡像
import Import the contents from a tarball to create a filesystem image #從tar包中導入內容創建一個文件系統鏡像
info Display system-wide information # 顯示全系統資訊
inspect Return low-level information on Docker objects #查看容器詳細資訊
kill Kill one or more running containers # kill指定docker容器
load Load an image from a tar archive or STDIN #從一個tar包或標準輸入中載入一個鏡像[對應save]
login Log in to a Docker registry #
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
鏡像下載
Elasticsearch
- 首先es有諸多不足,咱們要想辦法解決:
- es 暴露的埠很多!
- es 十分耗記憶體
- es 的數據一般需要放置到安全目錄!掛載
#測試成功就關掉elasticSearch,可以看出elasticsearch非常占記憶體,我們可以修改配置文件,進行限制記憶體使用#修改配置文件 -e 環境配置修改
# 在我們之前的啟動命令中加入:-e ES_JAVA_OPTS="-Xms64m -Xmx512m",限定記憶體在64mb-512mb之間
#1. --net somenetwork,這個是網路配置,之後再講
#2. -p 9200:9200 -p 9300:9300,暴露了9200和9300埠
#3. "discovery.type=single-node",這個是一個集群,表示單個節點
docker run -d --name elasticsearch2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.10.1
#再次查看docker stats,發現變小了,非常爽到
使用kibana連接es (elasticSearch)
現在elasticsearch容器和kibana容器都是相互隔離的,elasticsearch和kibana都有各自的內部地址。我們可以通過Linux的內網的ip作為一個中間商就可以實現elasticsearch到kibana訪問,但是會涉及到Docker的網路相關的知識,在之後講解。(請記住veth-pair)
鏡像原理
鏡像載入原理和分層
參考:(95條消息) ⚡️狂神Docker學習筆記_Lemonyuki的部落格-CSDN部落格
commit鏡像(提交自己的鏡像)
docker commit 提交容器成為一個新的副本
# 命令和git原理類似
docker commit -m="描述資訊" -a="作者名字" 容器id 目標鏡像名:[版本TAG]
#1. 啟動一個默認的tomcat
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -it -p 8080:8080 tomcat
#2. 發現這個默認的tomcat 是沒有webapps應用,官方的鏡像默認webapps下面是沒有文件的!
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it 079f8174730f /bin/bash
#3. 將webapps.dist里的所有東西拷貝文件進webapps,並查看
root@079f8174730f:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@079f8174730f:/usr/local/tomcat# cd webapps
root@079f8174730f:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
#4. 操作過的容器通過commit調教為一個鏡像!我們以後就使用我們修改過的鏡像即可,而不需要每次都重新拷貝webapps.dist下的文件到webapps了,這就是我們自己的一個修改的鏡像。
docker commit -m="描述資訊" -a="作者" 容器id 目標鏡像名:[TAG]
docker commit -a="peng" -m="add webapps app" 容器id tomcat02:1.0
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker commit -a="haha" -m="add webapps app" 079f8174730f tomcat02:1.0
sha256:b0a602f7e277d044ec71dbc36450609a0652f316e06c51fdcc82338de792793e
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
#看下方這個tomcat02.1.0就是我們創建的鏡像,發布之後再說
tomcat02.1.0 1 b0a602f7e277 About a minute ago 672MB
tomcat 9 6654503f1940 7 hours ago 667MB
nginx latest d1a364dc548d 4 weeks ago 133MB
tomcat latest c43a65faae57 5 weeks ago 667MB
mysql latest c0cdc95609f1 6 weeks ago 556MB
portainer/portainer latest 580c0e4e98b0 3 months ago 79.1MB
hello-world latest d1165f221234 3 months ago 13.3kB
centos latest 300e315adb2f 6 months ago 209MB
elasticsearch 7.6.2 f29a1ee41030 15 months ago 791MB
容器數據卷
什麼是容器數據卷:
docker的理念是將應用和環境打包成一個鏡像!
如果數據都在容器中,那麼我們容器刪除,數據就會丟失!所以我們就有需求:數據可以持久化
比如:安裝了MySQL,容器刪除了,相當於刪庫跑路!所以我們就有需求:MySQL數據可以存儲在本地!
所以我們需要容器之間可以有一個數據共享的技術!Docker容器中產生的數據,同步到本地!
這就是卷技術!說白了就是目錄的掛載,將我們容器內的目錄,掛載到Linux上面!
總結一句話:容器的持久化和同步操作!容器間也是可以數據共享的!
將mysql容器內部的文件系統映射(掛載)到linux上邊,實現數據的持久化和同步
# 涉及命令
docker volume --help
使用方式1
#1. 語法:主要是這個-v
docker run -it -v 主機目錄:容器內目錄 -p 主機埠:容器內埠
#2. run一個centos容器,並使用目錄掛載
# /home/ceshi:主機home目錄下的ceshi文件夾 映射:centos容器中的/home
# 將容器裡邊的home目錄掛載到linux的home下邊的ceshi目錄
docker run -it -v /home/ceshi:/home centos /bin/bash
#3. docker inspect 容器id 查看是否掛載成功
[root@iZ2vc28obhvfham8wewhh0Z /]# docker inspect 54db68df3d7f
#具體看下圖的Mounts部分,以後兩個地址的內的數據可以相互同步的
數據是雙向的,以後修改只需要在本地修改即可,容器內會自動同步!,刪除容器數據依舊還在
實戰:安裝MySQL
# 選擇密碼連接
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#1. 獲取mysql鏡像
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker pull mysql:5.7
#2. 運行容器的時候需要做數據掛載,此處我們掛載了配置文件以及數據目錄(有兩個哦),同時咱們也配置了mysql的密碼
-d 後台運行
-p 埠映射
-v 卷掛載
-e 環境配置
-- name 容器名字
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
#3. 啟動成功之後,我們可以在本地去連接上伺服器的mysql,如下圖所示
#咱們走的是3310埠,3310埠映射了容器的3306埠,所以說我們本質還是訪問到的容器
- 可以使用工具測試連接
- 創建資料庫可以同步過來
具名和匿名掛載
掛載方式
# 三種掛載: 匿名掛載、具名掛載、指定路徑掛載
-v 容器內路徑 #匿名掛載
-v 卷名:容器內路徑 #具名掛載,前面沒有帶/
-v /宿主機路徑:容器內路徑 #指定路徑掛載 docker volume ls 是查看不到的
#1. 匿名掛載
-v 容器內路徑!,這裡我們沒有寫主機的路徑,那麼它就會自動的生成一個目錄
#1-1. 使用命令匿名掛載
docker run -d -P --name nginx01 -v /etc/nginx nginx
#1-1. 查看所有volume(卷)的情況
[root@iZ2vc28obhvfham8wewhh0Z data]# docker volume ls
DRIVER VOLUME NAME(卷名字,這個一串亂碼其實是真實存在的目錄)
local dd3decdb4e2533d16d216ba19d8797c2ad95b4a2a1b6a90f87eb98bbed3b3758
# 註:這裡發現,這種就是匿名掛載,我們在 -v只寫了容器內的路徑,沒有寫容器外的路徑!
#2. 具名掛載
#2-1. 使用命令具名掛載
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
# 注1:juming-nginx:/etc/nginx,給/etc/nginx命名為juming-nginx,並沒有寫主機地址哈
# 注2:說白了就是 -v 卷名:容器內路徑
#2-2. 查看一下這個卷
[root@iZ2vc28obhvfham8wewhh0Z data]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2021-06-25T20:18:22+08:00",
"Driver": "local",
"Labels": null,
#注意看這兒:下方就是我們掛載到主機的具體路徑了
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
- 位置和一些資訊
- 只讀和讀寫
# 通過 -v 容器內路徑: ro rw 改變讀寫許可權
ro #readonly 只讀
rw #readwrite 可讀可寫
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
$ docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx
# ro 只要看到ro就說明這個路徑只能通過宿主機來操作,容器內部是無法操作!
- 掛載的位置和主機的映射位置
[root@localhost haha]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
835a85158acd nginx:1.20.2 "/docker-entrypoint.…" 21 minutes ago Up 21 minutes 80/tcp nginx-01
[root@localhost haha]# docker inspect 835a85158acd
使用方式2
Dockerfile 就是用來構建docker鏡像的構建文件!它即是命令腳本!先體驗一下!
通過這個腳本可以生成鏡像,鏡像是一層一層的,腳本是一個個的命令,每個命令都是一層!
#1. 在主機/home目錄下創建一個dockerfile文件,名字可以隨便,這裡建議dockerfile
[root@iZ2vc28obhvfham8wewhh0Z home]# mkdir dockerfile
#2. 然後進入dockerfile文件夾
[root@iZ2vc28obhvfham8wewhh0Z home]# cd dockerfile/
#3. 我們在dockerfile文件夾裡邊寫一個腳本文件
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# vim dockerfile1
# dockerfile1內部內容如下,每個命令就是一層:
FROM centos # 當前這個鏡像是以centos為基礎的
#這裡與阿狂不同,不加斜杠死活運行不了
VOLUME ["volume01","volume02"] # 掛載卷的卷目錄列表(多個目錄),記得空格
CMD echo "-----end-----" # 輸出一下用於測試
CMD /bin/bash # 默認走bash控制台
#4. 使用腳本去創建自己的鏡像
# 命令解釋:
-f dockerfile1 # f代表file,指這個當前文件的地址(這裡是當前目錄下的dockerfile1)
-t caoshipeng/centos # t就代表target,指目標目錄(注意caoshipeng鏡像名前不能加斜杠『/』)
. # 表示生成在當前目錄下
#--------------------------------------------------------------
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker build -f dockerfile1 -t xixi/centos .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos #我們自己寫的
---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"] #我們自己寫的
---> Running in f2d6c4400114
Removing intermediate container f2d6c4400114
---> 060cfd84e017
Step 3/4 : CMD echo "-----end-----" #我們自己寫的
---> Running in 871b9a8bb9c0
Removing intermediate container 871b9a8bb9c0
---> 4c71c64c5cc6
Step 4/4 : CMD /bin/bash #我們自己寫的
---> Running in 1f30a125b5ff
Removing intermediate container 1f30a125b5ff
---> 0db8611ac208
Successfully built 0db8611ac208
Successfully tagged haha/centos:latest
- 查看映射文件夾位置
查看一下卷掛載的路徑,如下圖所示:
docker inspect 自定義的鏡像名字
數據卷容器
- 容器之間的數據映射
-
父容器:A去掛載B,那麼B就是A的父容器
-
數據卷容器:被掛載的容器
-
使用 run 命令
#1. 測試 啟動3個容器,通過剛才自己寫的鏡像啟動
# 啟動第一個centos,注意版本如果不寫默認是找最新版
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker run -it --name docker0001 6ce95e6fc524
[root@d07b05bae720 /]# ls -l
total 0
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Jun 27 10:58 dev
drwxr-xr-x 1 root root 66 Jun 27 10:58 etc
drwxr-xr-x 2 root root 6 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 6 Dec 4 2020 lost+found
drwxr-xr-x 2 root root 6 Nov 3 2020 media
drwxr-xr-x 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x 156 root root 0 Jun 27 10:58 proc
dr-xr-x--- 2 root root 162 Dec 4 2020 root
drwxr-xr-x 11 root root 163 Dec 4 2020 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Jun 27 10:58 sys
drwxrwxrwt 7 root root 145 Dec 4 2020 tmp
drwxr-xr-x 12 root root 144 Dec 4 2020 usr
drwxr-xr-x 20 root root 262 Dec 4 2020 var
# 容器數據卷在此
drwxr-xr-x 2 root root 6 Jun 27 10:58 volume01
drwxr-xr-x 2 root root 6 Jun 27 10:58 volume02
#2. ctrl+p+q退出容器
#3. 創建第二個容器docker0002,繼承docker0001
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker run -it --name docker0002 --volumes-from docker0001 xixi/centos
[root@77e4999257f6 /]# ls -l
total 0
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 360 Jun 27 11:02 dev
drwxr-xr-x 1 root root 66 Jun 27 11:02 etc
drwxr-xr-x 2 root root 6 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------ 2 root root 6 Dec 4 2020 lost+found
drwxr-xr-x 2 root root 6 Nov 3 2020 media
drwxr-xr-x 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x 158 root root 0 Jun 27 11:02 proc
dr-xr-x--- 2 root root 162 Dec 4 2020 root
drwxr-xr-x 11 root root 163 Dec 4 2020 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Jun 27 11:02 sys
drwxrwxrwt 7 root root 145 Dec 4 2020 tmp
drwxr-xr-x 12 root root 144 Dec 4 2020 usr
drwxr-xr-x 20 root root 262 Dec 4 2020 var
drwxr-xr-x 2 root root 6 Jun 27 10:58 volume01
drwxr-xr-x 2 root root 6 Jun 27 10:58 volume02
#4. 在docker0001中的volume01中創建文件,然後在docker0002中的volume01中查看,如下圖
結論:
#1. docker0003創建的文件,docker0001可以查詢到,說明容器之間的數據形成了共享(本質是雙向拷貝)
#2. 此時刪除或者停掉docker0001,我們查看docker0002和docker0003的數據依舊能夠查詢到,說明數據形成了共享(本質是雙向拷貝,容器之間的相互數據拷貝)
#3. 只要有一個容器還在用這組數據就不會丟失,很nice
DockerFile
指令
FROM # from:基礎鏡像,一切從這裡開始構建
MAINTAINER # maintainer:鏡像是誰寫的, 姓名+郵箱
RUN # run:鏡像構建的時候需要運行的命令
ADD # add:步驟,tomcat鏡像,這個tomcat壓縮包!添加內容 添加同目錄
WORKDIR # workdir:鏡像的工作目錄
VOLUME # volume:掛載的目錄位置
EXPOSE # expose:暴露埠配置
CMD # cmd:指定這個容器啟動的時候要運行的命令,只有最後一個會生效,可被替代
ENTRYPOINT # entrypoint:指定這個容器啟動的時候要運行的命令,可以追加命令
ONBUILD # onbuild:當構建一個被繼承DockerFile這個時候就會運行onbuild的指令,是觸髮指令
COPY # copy:類似ADD,將我們文件拷貝到鏡像中
ENV # env:構建的時候設置環境變數!
CMD和ENTRYPOINT命令的區別
區別
CMD # 指定這個容器啟動的時候要運行的命令,只有最後一個會生效,可被替代。
ENTRYPOINT # 指定這個容器啟動的時候要運行的命令,可以追加命令
腳本
FROM centos
ENTRYPOINT ["ls","-a"] #這裡與之前不一樣哦(☆)
docker run cmd-test:0.1
執行時,CMD如果執行docker run cmd-test:0.1 -l 會報錯,他是替換了,執行 -l 命令,肯定報錯
ENTRYPOINT不會
追加後成為 ls -al
構建 Centos
#1./home下新建dockerfile目錄,並進入
[root@iZ2vc28obhvfham8wewhh0Z home]# mkdir dockerfile
[root@iZ2vc28obhvfham8wewhh0Z home]# cd dockerfile/
#2. dockerfile目錄下新建mydockerfile-centos文件,填寫內容如下:
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# vim mydockerfile-centos
- 記得指定 Centos 版本
- 注釋寫上面
FROM centos:7 # 基礎鏡像是官方原生的centos
MAINTAINER peng<[email protected]> # 作者
ENV MYPATH /usr/local # 配置環境變數的目錄
WORKDIR $MYPATH # 將工作目錄設置為 MYPATH
RUN yum -y install vim # 給官方原生的centos 增加 vim指令
RUN yum -y install net-tools # 給官方原生的centos 增加 ifconfig命令
EXPOSE 80 # 暴露埠號為80
CMD echo $MYPATH # 輸出下 MYPATH 路徑
CMD echo "-----end----"
CMD /bin/bash # 啟動後進入 /bin/bash
- 查看鏡像的構建過程,看它如何一步步的構建的
docker history 鏡像id
Docker 網路
原理:
我們每啟動一個docker容器,docker就會給docker容器分配一個ip,我們只要安裝了docker,就會有一個網卡docker0(橋接模式),使用的技術是 veth-pair 技術!
#我們發現這個容器帶來網卡,都是一對對的
# veth-pair 就是一對的虛擬設備介面,他們都是成對出現的,一端連著協議,一端彼此相連
# 正因為有這個特性 veth-pair 充當一個橋樑,連接各種虛擬網路設備的
# OpenStac,Docker容器之間的連接,OVS的連接,都是使用evth-pair技術
容器和容器之間的連接
小結
Docker使用的是Linux的橋接,宿主機是一個Docker容器的網橋 docker0,如下圖所示:
Docker中所有網路介面都是虛擬的,虛擬的轉發效率高(比如:內網傳遞文件)
只要容器刪除,對應的網橋一對就沒了!
自定義網路
思考:我們編寫了一個微服務,我們以前連接資料庫都是database url=ip: 項目不重啟,數據ip換了,我們希望可以處理這個問題,可以通過名字來進行訪問容器?
方法1
使用 –link
docker run -d -P --name tomcat03 --link tomcat02 tomcat
-
上面是 tomcat03 連接到 tomcat02,本質是添加了映射關係,相當於 hosts 映射
-
3 可以通過名字 ping 通 2 ,但是相反不能,因為 2 沒有添加映射關係
探究
docker exec -it tomcat03 cat /etc/hosts
方法2
使用自定義網路
網路模式:
- bridge :橋接 docker(默認,自己創建也是用bridge模式)
- none :不配置網路,一般不用
- host :和宿主機共享網路
- container :容器網路連通(用得少!局限很大)
- 創建自定義網路
. 創建一個子網為「192.168.0.0/16」,網關(路由)為「192.168.0.1」,網路名字為「mynet」的網路
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
- 創建2個使用自定義網路的容器
#4. 創建兩個個tomcat使用我們自定義的網路
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat
#5. 然後查看我們自定義的網路,如下圖所示
docker network inspect 56505443b59d
#發現容器使用的是我們配置的網路
我們自定義的網路docker當我們維護好了對應的關係,推薦我們平時這樣使用網路!
好處:
- redis -不同的集群使用不同的網路,可以保證集群是安全和健康的
- mysql-不同的集群使用不同的網路,可以保證集群是安全和健康的
Docker 實戰
設置容器自啟動
- 查看已啟動的服務
systemctl list-units --type=service
- 查看是否設置開機啟動
systemctl list-unit-files | grep enable
- 設置開機啟動
systemctl enable docker.service
- 啟動時加 –restart=always
docker run -tid --name isaler_v0.0.11 -p 8081:8080 --restart=always -v /alidata/iDocker/run/projectImages/isaler/v0.0.11/log:/usr/local/tomcat/logs isaler_v0.0.11
Flag Description
no 不自動重啟容器. (默認value)
on-failure 容器發生error而退出(容器退出狀態不為0)重啟容器
unless-stopped 在容器已經stop掉或Docker stoped/restarted的時候才重啟容器
always 在容器已經stop掉或Docker stoped/restarted的時候才重啟容器
- 已經啟動的項目
如果已經啟動的項目,則使用update更新:
docker update --restart=always isaler_v0.0.11
啟動常用的容器
1.1.安裝Docker
yum install -y yum-utils device-mapper-persistent-data lvm2 //安裝必要工具
yum-config-manager --add-repo //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo //設置yum源
yum install -y docker-ce //下載docker
systemctl start docker //啟動docker
1.2.安裝MySQL
docker pull mysql //下載MySQL鏡像
docker run --name mysql --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=密碼 -d mysql //啟動MySQL
docker run --name mysql --restart=always -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456789 -d mysql:8.0
1.3.安裝Redis
docker pull redis //下載Redis鏡像
docker run --name redis --restart=always -p 6379:6379 -d redis --requirepass "密碼" //啟動Redis
docker run --name redis --restart=always -p 6379:6379 -d redis --requirepass "123456789"
1.4.安裝nginx(請先部署項目再啟動)
docker pull nginx //下載nginx鏡像
docker run --name nginx --restart=always -p 80:80 -p 443:443 -d -v /usr/local/nginx/nginx.conf:/etc/nginx/nginx.conf -v /usr/local/vue:/usr/local/vue -v /usr/local/upload:/usr/local/upload nginx //啟動nginx,映射本地配置文件
1.5.安裝RabbitMQ
docker pull rabbitmq:management //下載RabbitMQ鏡像
docker run --name rabbitmq --restart=always -p 15672:15672 -p 5672:5672 -d rabbitmq:management //啟動RabbitMQ,默認guest用戶,密碼也是guest。
安裝插件
docker exec -it rabbitmq rabbitmq-plugins enable rabbitmq_management
1.6.安裝elasticsearch
# 下載elasticsearch鏡像
docker pull elasticsearch:7.9.2
# //啟動elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.9.2
# //進入elasticsearch容器
docker exec -it elasticsearch /bin/bash
# 安裝ik分詞器
./bin/elasticsearch-plugin install //github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.9.2/elasticsearch-an
docker pull zendesk/maxwell //下載MaxWell鏡像
docker run --name maxwell --restart=always -d zendesk/maxwell bin/maxwell --user='資料庫用戶名' --password='資料庫密碼' --host='IP地址' --producer=rabbitmq --rabbitmq_user='MQ用戶名' --rabbitmq_pass='MQ密碼' --rabbitmq_host='IP地址' --rabbitmq_port='5672' --rabbitmq_exchange='maxwell_exchange' --rabbitmq_exchange_type='fanout' --rabbitmq_exchange_durable='true' --filter='exclude: *.*, include: blog.tb_article.article_title = *, include: blog.tb_article.article_content = *, include: blog.tb_article.is_delete = *, include: blog.tb_article.status = *' //運行MaxWell
docker run --name maxwell --rm -it zendesk/maxwell bin/maxwell --user='root' --password='123456789' --host='192.168.80.80' --producer=rabbitmq --rabbitmq_user='guest' --rabbitmq_pass='guest' --rabbitmq_host='192.168.80.80' --rabbitmq_port='5672' --rabbitmq_exchange='maxwell_exchange' --rabbitmq_exchange_type='fanout' --rabbitmq_exchange_durable='true' --filter='exclude: *.*, include: blog-github.tb_article.article_title = *, include: blog-github.tb_article.article_content = *, include: blog-github.tb_article.is_delete = *, include: blog-github.tb_article.status = *' --producer=stdout
//運行MaxWell
docker run --name maxwell --rm -it zendesk/maxwell bin/maxwell --user='root' --password='123456789' --host='192.168.80.80' --filter='exclude: *.*, include: blog-github.tb_article.article_title = *, include: blog-github.tb_article.article_content = *, include: blog-github.tb_article.is_delete = *, include: blog-github.tb_article.status = *' --producer=stdout
Docker Compose
簡介
-
Compose是Docker官方的開源項目。需要安裝!
作用:
- DockerFile build run手動操作,單個容器!
微服務。100個微服務!依賴關係。
Docker Compose 來輕鬆高效的管理容器。
概念:
Compose是一個用於定義和運行多容器Docker應用程式的工具。
使用Compose,您可以使用yaml文件配置應用程式的服務。然後,使用一個命令,從配置中創建並啟動所有服務
使用Compose基本上是一個三步過程:
- 使用 定義應用的環境,以便可以在任何位置重現它。Dockerfile
- 定義構成應用的服務,以便它們可以在隔離的環境中一起運行。docker-compose.yml
- 運行,Docker 撰寫命令將啟動並運行整個應用。您也可以使用 docker-compose 二進位文件運行
docker-compose.yml (yaml配置文件)示列:
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
從上面的配置文件可以看出:
- 服務services: 容器。應用。(web、redis、mysql…)
- 項目project: 一組關聯的容器。部落格、web網站
安裝和卸載
安裝:
- 記得匹配 docker 的版本 Compose file version 3 reference | Docker Documentation
sudo curl -L //get.daocloud.io/docker/compose/releases/download/1.29.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
卸載:
rm /usr/local/bin/docker-compose
快速開始
看官網開始:開始使用 Docker Compose |Docker 文檔
- 官網是一個計數器
細節
- 官網的實例 Redis 和 Web 在同一個網路下
- 注意下面的 Host ,這樣重啟服務,ip 會改變,但是他們在同一個網路,可以使用名字 Ping 通
版本問題
Buster、Alpine、Stretch
redis:alpine 體積小
Docker的幾種精簡版本Buster、Alpine、Stretch比較, – 知乎 (zhihu.com)
Docker小結
- Docker鏡像,run =>容器
- DockerFile 構建鏡像(服務打包)
- Docker-composer
- Docker網路
yaml 規則
官網:Compose file version 3 reference | Docker Documentation
- 依賴關係,web 依賴 Redis 和 db ,所以有一個先後關係
version: "3"
services:
web:
build: # 構建鏡像
context: ./ # 上下文環境
dockerfile: ./compose/node/Dockerfile # Dockerfile路徑
ports:
- "3000:3000"
volumes:
- static:/code/static # 使用前面聲明的static掛在容器/code/static
restart: always # 總是重啟
nginx:
build:
context: ./
dockerfile: ./compose/nginx/Dockerfile
ports:
- "80:80"
volumes:
- static:/code/static
restart: always
mysql:
image: mysql:5.7 # 直接使用鏡像構建
env_file: .env # 環境變數env,我們寫入到了配置文件里,避免密碼泄漏
volumes:
- db:/var/lib/mysql
ports:
- "3306:3306"
restart: always
volumes:
static: # 數據卷名稱
db: # 數據卷名稱
實戰
-
編寫一個 springboot 程式
-
創建 Dockerfile 構建鏡像
FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app.jar"]
-
創建 docker-compose.yml 編排項目
version '3.8' services: xiaofanapp: build: . image: xiaofanapp depends_on: - redis ports: - "8080:8080" redis: image: "library/redis:alpine" # alpine 是輕小版
docker-compose up # 啟動容器
docker-compose down # 關閉容器
docker-compose up --build # 重新構建(出現問題可以重構一下)
IDEA 使用插件連接遠程 Docker
測試地址
//github.com/Rain-with-me/JavaStudyCode/tree/main/2-springboot-docker
插件使用
- 下載插件
依賴
-
版本
<properties> <java.version>1.8</java.version> <docker.host>//192.168.80.80:2375</docker.host> <docker.maven.plugin.version>0.40.0</docker.maven.plugin.version> </properties>
-
插件
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.maven.plugin.version}</version>
<!-- <executions>-->
<!-- <!–如果想在項目打包時構建鏡像添加–>-->
<!-- <execution>-->
<!-- <id>build-image</id>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>build</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<configuration>
<!-- Docker 遠程管理地址-->
<dockerHost>${docker.host}</dockerHost>
<images>
<image>
<!--定義鏡像名稱-->
<name>mall-tiny/${project.name}:${project.version}</name>
<!--定義鏡像構建行為-->
<build>
<!--定義基礎鏡像-->
<from>java:8</from>
<args>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</args>
<!--定義哪些文件拷貝到容器中-->
<assembly>
<!--定義拷貝到容器的目錄-->
<targetDir>/</targetDir>
<!--只拷貝生成的jar包-->
<descriptorRef>artifact</descriptorRef>
</assembly>
<!--定義容器啟動命令-->
<entryPoint>["java", "-jar","/${project.build.finalName}.jar"]</entryPoint>
<!--定義維護者-->
<maintainer>macrozheng</maintainer>
</build>
</image>
</images>
</configuration>
</plugin>
Dockerfile 部署項目
- IDEA 使用插件
登錄遠程主機,更改 Docker 配置
## 修改docker服務文件
vi /lib/systemd/system/docker.service
## 將原來的ExecStart前面加上#號注釋掉,然後再下面追加一行
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
## 重新載入配置
systemctl daemon-reload
## 重啟docker服務
systemctl restart docker.service
-
打開IDEA底部的
Services
面板,雙擊 Docker 圖標進行連接,可以對遠程伺服器上的Docker容器和鏡像進行管理
- 隨便搞個小 Demo 測試即可
注意:java:8 已經被棄用
- 創建 Dockerfile
# 該鏡像需要依賴的基礎鏡像
FROM openjdk:8
# 將當前目錄下的jar包複製到docker容器的/目錄下
COPY ./demo-0.0.1-SNAPSHOT.jar /test/demo-0.0.1-SNAPSHOT.jar
# 聲明服務運行在8080埠
EXPOSE 8080
# 指定docker容器啟動時運行jar包
ENTRYPOINT ["java", "-jar","/test/demo-0.0.1-SNAPSHOT.jar"]
# 指定維護者的名字
MAINTAINER haha
- 打開配置,記得配置下面設置,不然無法訪問
-
配置成功的樣子
-
運行之後更改下面的配置,然後執行配置即可
可以參考:
也可以去參考 mall 的配置
對照下之前使用的docker run
命令,大概就能知道這些配置的作用了;
docker run -p 8080:8080 --name mall-tiny \
--link mysql:db \
--link redis:redis \
-e 'spring.profiles.active'=prod \
-v /etc/localtime:/etc/localtime \
-v /mydata/app/mall-tiny/logs:/var/logs \
-d mall-tiny/mall-tiny:1.0.0-SNAPSHOT
-
查看日誌,成功就可以直接訪問
docker logs 容器
Docker Compose 部署
-
這玩意有點玄學,有時就報錯,重啟即可
-
IDEA 找到 docker-compose.exe 文件