一、Docker部署
1.1 安裝docker
1.1.1 準(zhǔn)備
安裝相關(guān)依賴
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
國(guó)內(nèi)源
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
1.1.2 安裝
安裝docker
sudo yum -y install docker-ce
服務(wù)自啟動(dòng)
systemctl enable docker
1.1.3 服務(wù)啟動(dòng)和優(yōu)化
設(shè)置國(guó)內(nèi)鏡像
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://hub-mirror.c.163.com","http://f1361db2.m.daocloud.io"]
}
EOF
啟動(dòng)服務(wù)
sudo systemctl daemon-reload
sudo systemctl restart docker
查看docker信息
docker info
找到如下信息表示鏡像加速器生效:
Registry Mirrors: https://4bj4rdum.mirror.aliyuncs.com/
1.2 刪除docker
查詢所有docker安裝
yum list installed | grep docker
刪除查詢到的所有安裝
yum remove -y xxxxx
刪除鏡像和容器
rm -rf /var/lib/docker
查找所有的docker文件
find / -name docker
刪除所有的docker文件
rm -rf xxx
二、Docker使用
2.1 Docker相關(guān)概念
2.1.1 Docker鏡像
Docker 的鏡像實(shí)際上由一層一層的文件系統(tǒng)組成,這種層級(jí)的文件系統(tǒng)就是聯(lián)合文件系統(tǒng)(UnionFS)。
- bootfs(引導(dǎo)文件系統(tǒng))主要包含bootloader和kernel,其中boot加載器主要是用來引導(dǎo)加載內(nèi)核。Linux剛啟動(dòng)時(shí)會(huì)加載bootfs,在Docker鏡像的最底層是bootfs。當(dāng)boot加載完成之后整個(gè)內(nèi)核就存在內(nèi)存中了,此時(shí)內(nèi)存的使用權(quán)已由bootfs(boot文件系統(tǒng))轉(zhuǎn)交給內(nèi)核,此時(shí)系統(tǒng)就會(huì)卸載bootfs(boot文件系統(tǒng))。
- roorfs(root文件系統(tǒng))在bootfs(boot文件系統(tǒng))之上。包含的就是典型Linux系統(tǒng)中的 /dev ,/proc,/bin ,/etc 等標(biāo)準(zhǔn)的目錄和文件??梢允且环N或多種操作系統(tǒng),先以只讀方式加載,引導(dǎo)結(jié)束完整性檢查。
- Base Image是基礎(chǔ)鏡像
- Image是子鏡像
- Container是可寫層,docker中運(yùn)行的程序在這一層執(zhí)行;Docker第一次啟動(dòng)時(shí)初始可寫層為空。運(yùn)行時(shí)從鏡像中讀取數(shù)據(jù)(寫時(shí)復(fù)制),并屏蔽鏡像中的更改數(shù)據(jù)。

2.1.2 網(wǎng)絡(luò)模式
| Docker網(wǎng)絡(luò)模式 | 配置 | 說明 |
|---|---|---|
| bridge模式 | --net=bridge | 默認(rèn)網(wǎng)絡(luò),docker啟動(dòng)后創(chuàng)建一個(gè)docker0網(wǎng)橋,默認(rèn)創(chuàng)建的容器也是添加到這個(gè)網(wǎng)橋中,IP地址為172.17.0.0/16 |
| host模式 | --net=host | 容器不會(huì)獲得一個(gè)獨(dú)立的network namespace,而是與宿主機(jī)共用一個(gè) |
| container模式 | --net=container:NAME_or_ID | 與指定的容器使用同一個(gè)network namespace,網(wǎng)卡配置也都是相同的。 kubernetes中的pod就是多個(gè)容器共享一個(gè)Network namespace。 |
| none模式 | --net=none | 容器有獨(dú)立的Network namespace,但并沒有對(duì)其進(jìn)行任何網(wǎng)絡(luò)設(shè)置,如分配veth pair 和網(wǎng)橋連接,配置IP等。 |
查看網(wǎng)絡(luò)相關(guān)信息:
- ifconfig 查看所有的網(wǎng)卡
- brctl show 查看所有的網(wǎng)橋(需要先安裝工具 yum install -y bridge-utils)
- docker network ls 查看網(wǎng)絡(luò)模式
2.1.2.1 Bridge模式
原理:創(chuàng)建一個(gè)docker0默認(rèn)網(wǎng)橋,使用veth-pair技術(shù)創(chuàng)建一對(duì)虛擬網(wǎng)卡,一端放到新建的容器中,并重命名為eth0,另一端放到宿主機(jī)中,以veth+隨機(jī)7個(gè)字符串命名,并將這個(gè)網(wǎng)絡(luò)設(shè)備加入到docker0網(wǎng)橋中,網(wǎng)橋自動(dòng)為容器分配一個(gè)IP,并設(shè)置docker0的IP為容器默認(rèn)網(wǎng)關(guān)。
所以容器默認(rèn)網(wǎng)絡(luò)都加入了這個(gè)網(wǎng)橋,因此都可以彼此通信。同時(shí)在iptables添加SNAT轉(zhuǎn)換網(wǎng)絡(luò)段IP,以便容器訪問外網(wǎng)。
容器的命名空間和宿主機(jī)的命名空間相互隔離,宿主機(jī)的命名空間中的網(wǎng)卡veth可以發(fā)送到容器的命名空間的網(wǎng)卡eth0。

例:
當(dāng)我們未啟動(dòng)容器時(shí),使用ip addr命令查看網(wǎng)卡,與docker相關(guān)的只有一張docker0網(wǎng)卡。當(dāng)我們啟動(dòng)一個(gè)容器后,使用ip addr查看發(fā)現(xiàn)多了一張網(wǎng)卡如下:
26: veth7dc0e4f@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether b2:17:ec:b5:72:a1 brd ff:ff:ff:ff:ff:ff link-netnsid 3
inet6 fe80::b017:ecff:feb5:72a1/64 scope link
valid_lft forever preferred_lft forever
然后我們?cè)谌萜髦胁榭淳W(wǎng)卡
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
25: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
總結(jié):我們每安裝一個(gè)容器,docker就會(huì)給容器分配一個(gè)ip,使用veth-pair技術(shù)在宿主機(jī)和容器中創(chuàng)建的兩張?zhí)摂M網(wǎng)卡。veth-pair就是一對(duì)的虛擬設(shè)備接口,他們都是成對(duì)出現(xiàn)的,一端接著協(xié)議,一端彼此連接。正因?yàn)橛羞@個(gè)特性,evth-pair充當(dāng)一個(gè)橋梁,連接各種虛擬網(wǎng)絡(luò)設(shè)備。
我們可以查看docker0網(wǎng)卡的詳細(xì)信息,執(zhí)行命令docker network inspect bridge
[root@cos-bigdata-mysql ~]# docker network inspect bridge
[
{
"Name": "bridge",
"Id": "f09103f08695050dd23f900f96ccfc04716435b12c0866cfd7e4c16095cf1d7f",
"Created": "2021-07-21T11:09:15.718636023+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,
"Containers": {
"723532d51bf32422282b04b5e5274d164cf49ecc880a201975658387c90f0a04": {
"Name": "openldap",
"EndpointID": "64f100c3fdd10f0dc85e5dbd6cc19d9e7549dfd00a99dc06d933d900bf4c0ca1",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"ea68b9dc02f652711e07a930ca65de2793e5c37952eb1f61e8f8decd7bd5762a": {
"Name": "redis",
"EndpointID": "d584f5caf9d2e5634b918e091ab27ec6607de815cbc92968b9720c064b4bbd18",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}
},
"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": {}
}
]
可以發(fā)現(xiàn)docker0的網(wǎng)關(guān)是172.17.0.1,網(wǎng)段是172.0.0.1/16,這個(gè)網(wǎng)段可以分配的ip數(shù)量是2^16-2。在啟動(dòng)新的容器后, 會(huì)為該容器分配改網(wǎng)段上的IP地址。
容器之間通訊流程:
- 容器1通過容器中的虛擬網(wǎng)卡eth0@if26與宿主機(jī)上的對(duì)應(yīng)網(wǎng)卡veth7dc0e4f@if25進(jìn)行通訊。
- 而docker0網(wǎng)卡相當(dāng)于路由器,當(dāng)veth7dc0e4f@if25網(wǎng)卡會(huì)與路由器進(jìn)行通訊,路由器會(huì)將veth7dc0e4f@if25網(wǎng)卡的IP地址記錄到路由表中,然后準(zhǔn)備將消息發(fā)送到目標(biāo)IP。
- 路由器通過尋找路由表或進(jìn)行廣播的方式找到目標(biāo)ip的網(wǎng)卡,然后講消息發(fā)送到目標(biāo)網(wǎng)卡,該網(wǎng)卡再與其對(duì)應(yīng)的網(wǎng)卡進(jìn)行通訊,將消息發(fā)送到目標(biāo)容器中。
自定義網(wǎng)卡
除了使用默認(rèn)的docker0,我們可以創(chuàng)建自己的bridge網(wǎng)絡(luò),容器中可以通過其他容器名進(jìn)行訪問。創(chuàng)建容器的時(shí)候指定網(wǎng)絡(luò)為mynet并指定ip即可。
優(yōu)點(diǎn)
- 自定義網(wǎng)卡相比docker0進(jìn)行了很多功能的完善,如自動(dòng)實(shí)現(xiàn)了--link功能。
- 不同集群使用不同網(wǎng)絡(luò),互相隔離,保證集群是安全和健康的。
創(chuàng)建一個(gè)新的bridge網(wǎng)絡(luò)(創(chuàng)建虛擬網(wǎng)卡,注意網(wǎng)段不能與其他網(wǎng)卡沖突)
docker network create --driver bridge --subnet=192.168.1.0/16 --gateway=192.168.1.1 mynet
刪除虛擬網(wǎng)卡
docker network rm mynet
查看網(wǎng)絡(luò)信息
docker network inspect mynet
創(chuàng)建容器并指定容器ip
docker run -e TZ="Asia/Shanghai" --privileged -itd -h hadoop01.com --name hadoop01 --network=mynet --ip 172.18.12.1 centos /usr/sbin/init
打通不同網(wǎng)段下的容器的網(wǎng)絡(luò)(即將容器加入到網(wǎng)絡(luò)中)
如我們創(chuàng)建了上述的新的bridge網(wǎng)絡(luò)mynet,并創(chuàng)建了一個(gè)容器,容器IP地址為192.168.1.12,那么該容器與docker0網(wǎng)絡(luò)中的IP為172.17.0.3的redis容器就不再一個(gè)網(wǎng)絡(luò)中,所以這兩個(gè)容器是網(wǎng)絡(luò)隔離的。那么我們可以使用如下命令將連個(gè)容器的網(wǎng)絡(luò)進(jìn)行打通。
docker network connect mynet redis
執(zhí)行該命令后再次查看mynet網(wǎng)絡(luò)的詳細(xì)信息
docker network inspect mynet
可以發(fā)現(xiàn)該命令將redis容器加入到了mynet的網(wǎng)絡(luò)中,并給該容器添加了一個(gè)新的IP地址
[root@cos-bigdata-mysql ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "95a5db07a2b21b4a94fcce482dc944c772cf79435515b6bf4d2fd172bcf2cbfa",
"Created": "2021-07-21T11:14:24.600592551+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.12.0/16",
"Gateway": "172.18.1.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {
"5e9d26990618c952b2bd27644996987cc6d09618f3e2166e56a0be9c759d3632": {
"Name": "mysql57",
"EndpointID": "a31825bb5d9379054fe7343efbcd9f4d9aeb17ff3fe9899becbe4ee99ed4c730",
"MacAddress": "02:42:ac:12:0c:02",
"IPv4Address": "172.18.12.2/16",
"IPv6Address": ""
},
"ea68b9dc02f652711e07a930ca65de2793e5c37952eb1f61e8f8decd7bd5762a": {
"Name": "redis",
"EndpointID": "8f8aa18b307f01cede808d4572d8fff71a9ca6b3dc759f71dfee8318447edb26",
"MacAddress": "02:42:ac:12:00:01",
"IPv4Address": "172.18.0.1/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
這樣mynet網(wǎng)絡(luò)中的容器可以和原本是docker0網(wǎng)絡(luò)中的redis容器進(jìn)行通訊。
2.1.2.2 Host模式
如果啟動(dòng)容器的時(shí)候使用host模式,那么這個(gè)容器將不會(huì)獲得一個(gè)獨(dú)立的Network Namespace,而是和宿主機(jī)共用一個(gè)Network Namespace。容器將不會(huì)虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口。但是,容器的其他方面,如文件系統(tǒng)、進(jìn)程列表等還是和宿主機(jī)隔離的。

2.1.2.3 Container模式
這個(gè)模式指定新創(chuàng)建的容器和已經(jīng)存在的一個(gè)容器共享一個(gè) Network Namespace,而不是和宿主機(jī)共享。新創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡,配置自己的 IP,而是和一個(gè)指定的容器共享 IP、端口范圍等。同樣,兩個(gè)容器除了網(wǎng)絡(luò)方面,其他的如文件系統(tǒng)、進(jìn)程列表等還是隔離的。兩個(gè)容器的進(jìn)程可以通過 lo 網(wǎng)卡設(shè)備通信。

2.1.2.4 None模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置。也就是說,這個(gè)Docker容器沒有網(wǎng)卡、IP、路由等信息。需要我們自己為Docker容器添加網(wǎng)卡、配置IP等。
這種網(wǎng)絡(luò)模式下容器只有l(wèi)o回環(huán)網(wǎng)絡(luò),沒有其他網(wǎng)卡。none模式可以在容器創(chuàng)建時(shí)通過--network=none來指定。這種類型的網(wǎng)絡(luò)沒有辦法聯(lián)網(wǎng),封閉的網(wǎng)絡(luò)能很好的保證容器的安全性。
2.1.3 數(shù)據(jù)卷
數(shù)據(jù)卷是經(jīng)過特別設(shè)計(jì)的目錄,可以繞過聯(lián)合文件系統(tǒng)(UFS)為一個(gè)或多個(gè)容器提供訪問。設(shè)計(jì)目的是為了數(shù)據(jù)的持久化,獨(dú)立于容器的生命周期,因此Docker不會(huì)在刪除容器時(shí),刪除掛載的數(shù)據(jù)卷,也不會(huì)存在類似的垃圾回收機(jī)制,對(duì)容器引用的數(shù)據(jù)卷進(jìn)行處理。
2.2 Docker容器啟動(dòng)
基本啟動(dòng)容器命令如下:
docker run -itd mysql:5.6
可以添加的參數(shù)如下:
- 指定容器端口映射: -p 8080:8080
- 指定容器數(shù)據(jù)卷: -v /root/docker/redis/data:/data
- 指定容器名稱: --name nginx
- 指定環(huán)境變量: -e SEATA_IP=192.168.32.128
-
指定容器自動(dòng)重啟: --restart=always
- --restart=always :容器總是會(huì)重啟
- --restart=on-failure:在容器非正常退出時(shí)(推出狀態(tài)為0),才會(huì)重啟容器
- --restart=unless-stopped:在容器退出時(shí)總是重啟容器,但是 docker 守護(hù)進(jìn)程啟動(dòng)之前就已經(jīng)停止運(yùn)行的容器不算在內(nèi)。
- --restart=no :
- 指定容器網(wǎng)絡(luò)環(huán)境: --net=host
- 指定容器時(shí)區(qū): -e TZ='Asia/Shanghai'
- 指定pid: --pid="host"
- 指定容器的hostname: -h "mars"
- 在容器的host文件中添加映射: --add-host updates.jenkins-ci.org:192.168.101.128
- 讓容器獲取宿主機(jī)root權(quán)限: --privileged=true
- 關(guān)聯(lián)另一個(gè)容器的容器名,與--add-host類似: --link=[]
- 開放一個(gè)端口或一組端口: --expose=[]
- 指定容器使用的DNS服務(wù)器(默認(rèn)和宿主一致): --dns 8.8.8.8
- 指定容器DNS搜索域名,默認(rèn)和宿主一致: --dns-search example.com
-
指定運(yùn)行內(nèi)存:
-m,--memory 內(nèi)存限制,格式是數(shù)字加單位,單位可以為 b,k,m,g。最小為 4M
--memory-swap 內(nèi)存+交換分區(qū)大小總限制。格式同上。必須必-m設(shè)置的大
--memory-reservation 內(nèi)存的軟性限制。格式同上
--oom-kill-disable 是否阻止 OOM killer 殺死容器,默認(rèn)沒設(shè)置
--oom-score-adj 容器被 OOM killer 殺死的優(yōu)先級(jí),范圍是[-1000, 1000],默認(rèn)為 0
--memory-swappiness 用于設(shè)置容器的虛擬內(nèi)存控制行為。值為 0~100 之間的整數(shù)
--kernel-memory 核心內(nèi)存限制。格式同上,最小為 4M -
指定CPU:
--cpuset="0-2" or --cpuset="0,1,2" 綁定容器到指定CPU運(yùn)行;
--vm 1 啟動(dòng) 1 個(gè)內(nèi)存工作線程
--vm-bytes 280M 每個(gè)線程分配 280M 內(nèi)存
2.3 Docker常用命令
查看幫助文檔
man docker-run/docker-logs/docker-top/docker-exec
簡(jiǎn)單命令
docker info
docker images
docker pull [用戶名][倉(cāng)庫(kù)名]:[版本號(hào)]
docker rmi [imageId/imageName]
docker ps -a -l
docker start/restart/stop/kill/rm [containId/containName]
docker port [containId/containName] #查看容器端口
docker top [containId/containName] # 查看運(yùn)行中容器的進(jìn)程
docker stats # 查看運(yùn)行中容器的資源占用
進(jìn)入容器
docker exec -ti ceff85e1747d /bin/bash
docker exec -ti ceff85e1747d /bin/sh
在容器中執(zhí)行命令
docker exec nginx bash -c 'nginx -s reload'
容器文件復(fù)制
docker cp dev_smartcook.sql mysql:/tmp
docker cp mysql:/tmp/dev_smartcook.sql /root
查看容器日志
顯示最近5分鐘的日志
docker logs --since 5m -f [dockerName]
顯示最近100條日志
docker logs --tail 100 -f [dockerName]
修改容器參數(shù)
docker container update --restart=always 容器名字
清除無效數(shù)據(jù)
docker system prune
docker container prune
docker network prune
docker images prune 清除
數(shù)據(jù)卷操作
docker volume create --name redis01 # 創(chuàng)建別名為redis01的數(shù)據(jù)卷
docker volume rm redis01 # 刪除名為redis01的數(shù)據(jù)卷
docker volume ls # 查看所有的數(shù)據(jù)卷
docker volume inspect [volume_name] # 查看數(shù)據(jù)卷的詳細(xì)信息
docker volume prune # 刪除所有未使用的數(shù)據(jù)卷
docker run -it --name mysql2 --volumes-from mysql1 mysql:5.6 # 啟動(dòng)mysql2容器并共享mysql1的數(shù)據(jù)卷
inspect命令
docker inspect是docker客戶端的原生命令,用于查看docker對(duì)象的底層基礎(chǔ)信息。包括容器的id、創(chuàng)建時(shí)間、運(yùn)行狀態(tài)、啟動(dòng)參數(shù)、目錄掛載、網(wǎng)路配置等等。
docker inspect [imageId] # 查看鏡像的詳細(xì)信息
docker inspect [containId] # 查看容器的詳細(xì)信息
docker inspect [volumeName] # 查看數(shù)據(jù)卷的詳細(xì)信息
docker network inspect [networkName] # 查看網(wǎng)絡(luò)信息
--format,-f:Format the output using the given Go template
--size,-s:Display total file sizes if the type is container
--type: Return JSON for specified type
構(gòu)建鏡像
docker build -t [tagname] [path/url]
查看容器占用內(nèi)存
找到容器對(duì)應(yīng)的進(jìn)程:
ps -ef [containID]
獲得容器對(duì)應(yīng)的pid后,就可以使用top、pmap、ps等查看進(jìn)程內(nèi)存的命令查看容器的內(nèi)存占用情況了。
①使用top命令查看進(jìn)程的內(nèi)存占用:
top -p 5140
按e可切換內(nèi)存單位。按大寫P可以按CPU占用大小逆序排序,大寫M可以按內(nèi)存占用大小逆序排序。
內(nèi)容解釋:
PID:進(jìn)程的ID
USER:進(jìn)程所有者
PR:進(jìn)程的優(yōu)先級(jí)別,越小越優(yōu)先被執(zhí)行
NInice:值
VIRT:進(jìn)程占用的虛擬內(nèi)存
RES:進(jìn)程占用的物理內(nèi)存
SHR:進(jìn)程使用的共享內(nèi)存
S:進(jìn)程的狀態(tài)。S表示休眠,R表示正在運(yùn)行,Z表示僵死狀態(tài),N表示>該進(jìn)程優(yōu)先值為負(fù)數(shù)
%CPU:進(jìn)程占用CPU的使用率
%MEM:進(jìn)程使用的物理內(nèi)存和總內(nèi)存的百分比
TIME+:該進(jìn)程啟動(dòng)后占用的總的CPU時(shí)間,即占用CPU使用時(shí)間的累加值。
COMMAND:進(jìn)程啟動(dòng)命令名稱
②使用pmap命令
pmap -d 5140
③使用ps命令
ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid' | grep 5140
其中rsz為實(shí)際內(nèi)存
image.png
2.4 Docker不常用命令
簡(jiǎn)單命令
docker search [name] # 查找鏡像
上傳鏡像
①登陸到dockerhub
docker login
②標(biāo)記鏡像后
docker tag [鏡像名] [用戶名][倉(cāng)庫(kù)名]:[版本號(hào)]
③上傳
docker push [用戶名][倉(cāng)庫(kù)名]:[版本號(hào)]
2.5 Dockerfile
- ENV:用于為鏡像定義所需的環(huán)境變量,并可被kockerfile文件位于其后的其他指令所調(diào)用
- RUN:run指令是在構(gòu)建鏡像時(shí)運(yùn)行的命令,創(chuàng)建Docker鏡像的步驟,也就是docker bulid中執(zhí)行的,其實(shí)就是順著Dockerfile文件的指令順序運(yùn)行。
- CMD:CMD命令是當(dāng)Docker鏡像被啟動(dòng)后Docker容器將會(huì)默認(rèn)執(zhí)行的命令。一個(gè)Dockerfile中只能有一個(gè)CMD命令,如果指定了多條命令,只有最后一條會(huì)被執(zhí)行。
- ENTRYPOINT:ENTRYPOINT 允許你把你的容器啟動(dòng)時(shí)候去執(zhí)行某件事情,讓你的容器變成可執(zhí)行的。
CMD與ENTRYPOINT的區(qū)別:CMD命令設(shè)置容器啟動(dòng)后默認(rèn)執(zhí)行的命令及其參數(shù),但CMD設(shè)置的命令能夠被docker run命令后面的命令行參數(shù)替換ENTRYPOINT配置容器啟動(dòng)時(shí)的執(zhí)行命令(不會(huì)被忽略,一定會(huì)被執(zhí)行,即使運(yùn)行 docker run時(shí)指定了其他命令) - ADD:高級(jí)復(fù)制文件??梢允荱RL路徑,把你指定的文件下載到本地,并打包進(jìn)鏡像中。
- WORKDIR:用于為Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY、ADD指定設(shè)定工作目錄。
如:WORKDIR /usr/local;nginx-1.19.2.tar.gz ./其中./表示的路徑是 /usr/local; - VOLUME:指定容器的掛載點(diǎn)目錄,不支持宿主機(jī)的掛載點(diǎn)目錄;
- EXPOSE:因?yàn)槲覀儾荒艽_定鏡像啟動(dòng)的容器運(yùn)行在哪個(gè)宿主機(jī),因此無法指定綁定地址,并且宿主機(jī)的空閑端口也是不確定,我們只能指定鏡像暴露的端口,在啟動(dòng)后去動(dòng)態(tài)綁定至宿主機(jī)的隨機(jī)端口和所有地址。
也就是說我們寫在dockerfile文件的暴露端口并不能直接暴露,只能說是可以暴露,在“ docker run -P ”的時(shí)候才會(huì)去暴露所有的端口。 - FROM:說明在哪個(gè)鏡像的基礎(chǔ)上構(gòu)造鏡像,必須在第一個(gè)非注釋行,為后續(xù)命令提供運(yùn)行環(huán)境;
- MAINTAINER:已過時(shí)
- LABEL:用于為鏡像添加元數(shù)據(jù)。使用LABEL指定元數(shù)據(jù)時(shí),一條LABEL指定可以指定一或多條元數(shù)據(jù),指定多條元數(shù)據(jù)時(shí)不同元數(shù)據(jù)之間通過空格分隔。推薦將所有的元數(shù)據(jù)通過一條LABEL指令指定,以免生成過多的中間鏡像。如
LABEL version=“1.0” description=“這是一個(gè)Web服務(wù)器” by=“IT筆錄” - COPY:從宿主機(jī)復(fù)制文件或目錄到容器內(nèi)的指定路徑,容器內(nèi)的路徑必須存在,不能自動(dòng)創(chuàng)建
2.6 Docker容器遷移
①?gòu)娜萜鲃?chuàng)建一個(gè)新的鏡像
docker commit -a "cj" -m "openldap" openldap openldap:cj
-a :提交的鏡像作者;
-c :使用Dockerfile指令來創(chuàng)建鏡像;
-m :提交時(shí)的說明文字;
-p :在commit時(shí),將容器暫停。
②打包鏡像
docker save -o openldap.tar openldap:cj
-o :輸出到的文件
③拷貝到目標(biāo)服務(wù)器
rsync openldap.tar root@192.168.101.174:`pwd`
兩臺(tái)服務(wù)器上都需要安裝rsync,不安裝的話也可以通過scp命令來傳輸。
④新服務(wù)器載入鏡像
執(zhí)行如下命令將打包后的鏡像導(dǎo)入
docker load --input openldap.tar
--input , -i : 指定導(dǎo)入的文件,代替 STDIN
--quiet , -q : 精簡(jiǎn)輸出信息。
⑤運(yùn)行容器
docker run -d -p 389:389 -p 636:636 --name openldap --env LDAP_ORGANISATION="se" --env LDAP_DOMAIN="ldap.chenjie.asia" --env LDAP_ADMIN_PASSWORD="abc123" osixia/openldap
三、docker-compose
3.1 概念
docker-compose是一個(gè)編排多容器分布式部署的工具,提供命令集管理容器化應(yīng)用的完整開發(fā)周期,包括服務(wù)構(gòu)建,啟動(dòng)和停止。
1.利用Dockerfile定義運(yùn)行環(huán)境鏡像
2.使用docker-compose.yml定義組成應(yīng)用的各服務(wù)
3.運(yùn)行docker-compose up啟動(dòng)應(yīng)用
3.2 docker-compose安裝
①下載編譯好的二進(jìn)制包,安裝到linux系統(tǒng)中
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
②修改可執(zhí)行權(quán)限 chmod +x /usr/local/bin/docker-compose
③查看版本 docker-compose -version
3.3 配置文件
- image:指定服務(wù)的鏡像名稱或鏡像 ID。如果鏡像在本地不存在,Compose 將會(huì)嘗試?yán)∵@個(gè)鏡像。
- build:服務(wù)除了可以基于指定的鏡像,還可以基于一份 Dockerfile,在使用 up 啟動(dòng)之時(shí)執(zhí)行構(gòu)建任務(wù),這個(gè)構(gòu)建標(biāo)簽就是 build,它可以指定 Dockerfile 所在文件夾的路徑。Compose 將會(huì)利用它自動(dòng)構(gòu)建這個(gè)鏡像,然后使用這個(gè)鏡像啟動(dòng)服務(wù)容器。
如果你同時(shí)指定了 image 和 build 兩個(gè)標(biāo)簽,那么 Compose 會(huì)構(gòu)建鏡像并且把鏡像命名為 image 后面的那個(gè)名字。
build: /path/to/build/dir
# 如果你要指定 Dockerfile 文件需要在 build 標(biāo)簽的子級(jí)標(biāo)簽中使用 dockerfile 標(biāo)簽指定
build:
context: ../
dockerfile: path/of/Dockerfile
# 可以在構(gòu)建過程中指定環(huán)境變量,但是在構(gòu)建成功后取消
build:
context: .
args:
- buildno=1
- password=secret
- command:使用 command 可以覆蓋容器啟動(dòng)后默認(rèn)執(zhí)行的命令。
command: bundle exec thin -p 3000
# 或
command: [bundle, exec, thin, -p, 3000]
4.container_name:容器的命名
5.depends_on:指定容器的啟動(dòng)先后順序。
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意的是,默認(rèn)情況下使用 docker-compose up web 這樣的方式啟動(dòng) web 服務(wù)時(shí),也會(huì)啟動(dòng) redis 和 db 兩個(gè)服務(wù),因?yàn)樵谂渲梦募卸x了依賴關(guān)系。
- environment
environment:
- MYSQL_ROOT_PASSWORD=hxr
- external_links:在使用Docker過程中,我們會(huì)有許多單獨(dú)使用docker run啟動(dòng)的容器,為了使Compose能夠連接這些不在docker-compose.yml中定義的容器,我們需要一個(gè)特殊的標(biāo)簽,就是external_links,它可以讓Compose項(xiàng)目里面的容器連接到那些項(xiàng)目配置外部的容器(前提是外部容器中必須至少有一個(gè)容器是連接到與項(xiàng)目?jī)?nèi)的服務(wù)的同一個(gè)網(wǎng)絡(luò)里面)。
格式如下:
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
- extra_hosts:添加主機(jī)名的標(biāo)簽,就是往/etc/hosts文件中添加一些記錄,與Docker client的--add-host類似:
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
- links:還記得上面的depends_on吧,那個(gè)標(biāo)簽解決的是啟動(dòng)順序問題,這個(gè)標(biāo)簽解決的是容器連接問題,與Docker client的--link一樣效果,會(huì)連接到其它服務(wù)中的容器。
格式如下:
links:
- db
- db:database
- redis
使用的別名將會(huì)自動(dòng)在服務(wù)容器中的/etc/hosts里創(chuàng)建。例如:
172.12.2.186 db
172.12.2.186 database
172.12.2.187 redis
相應(yīng)的環(huán)境變量也將被創(chuàng)建。
- pid:將PID模式設(shè)置為主機(jī)PID模式,跟主機(jī)系統(tǒng)共享進(jìn)程命名空間。容器使用這個(gè)標(biāo)簽將能夠訪問和操縱其他容器和宿主機(jī)的名稱空間。
pid: "host"
- ports:映射端口的標(biāo)簽。
- volumes:掛載一個(gè)目錄或者一個(gè)已存在的數(shù)據(jù)卷容器。
- volumes_from:從其它容器或者服務(wù)掛載數(shù)據(jù)卷,可選的參數(shù)是 :ro或者 :rw,前者表示容器只讀,后者表示容器對(duì)數(shù)據(jù)卷是可讀可寫的。默認(rèn)情況下是可讀可寫的。
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw
- network_mode:網(wǎng)絡(luò)模式,與Docker client的--net參數(shù)類似,只是相對(duì)多了一個(gè)service:[service name] 的格式。
例如:
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
- networks:加入指定網(wǎng)絡(luò)。
- env_file:在其中定義環(huán)境變量,如
MYSQL_ROOT_PASSWORD=hxr
MYSQL_DATABASE=typecho
MYSQL_USER=username
MYSQL_PASSWORD=password
效果同 environment 。
3.4 compose文件
version: '3' # 文件的版本號(hào)
services: # 需要啟動(dòng)的所有服務(wù)
nginx01: # 啟動(dòng)的服務(wù)名為nginx
container_name: nginx01 # 指定容器名
image: nginx # 需要啟動(dòng)的鏡像名稱和版本
restart: always
ports:
- 80:80 # 端口映射
links:
- app # 當(dāng)前容器可以訪問或掛載到的項(xiàng)目名
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d # 數(shù)據(jù)卷
- nginxvolume:/etc/nginx/conf.d # 此處使用的卷名前會(huì)將加上項(xiàng)目名(所在文件夾名),需要和創(chuàng)建的卷名對(duì)應(yīng)
networks: # 代表當(dāng)前服務(wù)使用哪個(gè)網(wǎng)絡(luò)橋
- hello
nginx02: # 啟動(dòng)的服務(wù)名為nginx
container_name: nginx01 # 指定容器名
image: nginx # 需要啟動(dòng)的鏡像名稱和版本
restart: always
ports:
- 81:80 # 端口映射
links:
- app # 當(dāng)前容器可以訪問或掛載到的項(xiàng)目名
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d # 數(shù)據(jù)卷
- nginxvolume:/etc/nginx/conf.d # 此處使用的卷名前會(huì)將加上項(xiàng)目名(所在文件夾名),需要和創(chuàng)建的卷名對(duì)應(yīng)
networks: # 代表當(dāng)前服務(wù)使用哪個(gè)網(wǎng)絡(luò)橋
- hello
mysql:
container_name: mysql
image: mysql:5.7.32
restart: always
ports:
- 3306:3306
volumes:
- /root/mysql/conf:/etc/mysql
- /root/mysql/log:/var/log/mysql
- /root/mysql/data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=hxr
networks:
- hello
volumes: # 如果綁定到數(shù)據(jù)卷,需要另外定義該卷名
nginxvolume: # 聲明指令的卷名 compose自動(dòng)創(chuàng)建該卷名但是會(huì)在之前加入項(xiàng)目名
external:
false # false表示創(chuàng)建的卷會(huì)添加上項(xiàng)目名,如果是true表示創(chuàng)建的卷不加項(xiàng)目名。
network: # 定義服務(wù)用到的橋
hello: # 定義橋的名稱,默認(rèn)創(chuàng)建的就是 bridge。
external:
false # false表示創(chuàng)建添加上項(xiàng)目名的網(wǎng)橋,如果是true表示使用外部已存在的網(wǎng)橋。
通過 docker-compose up -d 指令在后臺(tái)啟動(dòng)所有容器,如果不加-d參數(shù),會(huì)在當(dāng)前對(duì)話中啟動(dòng)服務(wù)。默認(rèn)啟動(dòng)docker-compose.yml,可以-f指定啟動(dòng)文件。
http://www.itdecent.cn/p/2217cfed29d7
四、Docker部署
4.1 jar包部署
創(chuàng)建dockerfile文件
FROM java:8/openjdk:8-jdk-alpine
VOLUME /tmp
ADD asrs-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8764
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
構(gòu)建鏡像
docker build -t newworkhourbackend .
啟動(dòng)容器
docker run -p 8764:8764 -d newworkhourbackend
備注:
1.-Djava.security.egd=file:/dev/./urandom 用于jvm高效的產(chǎn)生隨機(jī)數(shù)。
2.可以通過制定--restart參數(shù)讓容器關(guān)閉后重啟:docker run-m 512m--memory-swap1G-it-p6379:6379--restart=always--name redis-d redis
參數(shù)為①no - 容器退出時(shí),不重啟容器②on-failure - 只有在非0狀態(tài)退出時(shí)才從新啟動(dòng)容器③always - 無論退出狀態(tài)是如何,都重啟容器
如果創(chuàng)建時(shí)未指定 --restart=always ,可通過 update 命令:docker update --restart=always xxx
4.使用docker exec -it name/id /bin/bash進(jìn)入容器中,一般不使用docker attach name/id進(jìn)入容器中。(如果沒有/bin/bash指令,則使用/bin/sh)
5.如果容器中沒有vim命令,執(zhí)行apt-get install vim安裝vim;如果安裝命令出錯(cuò),需要先執(zhí)行更新命令apt-get update。
4.2 常見中間件部署
Redis
docker run -d --privileged=true -p 6379:6379 --restart always -v /root/docker/redis/conf/redis.conf:/etc/redis/redis.conf -v /root/docker/redis/data:/data --name myredis redis redis-server /etc/redis/redis.conf --appendonly yes
--restart always -> 開機(jī)啟動(dòng)
--privileged=true -> 提升容器內(nèi)權(quán)限
-v /root/docker/redis/conf:/etc/redis/redis.conf -> 映射配置文件
-v /root/docker/redis/data:/data -> 映射數(shù)據(jù)目錄
--appendonly yes -> 開啟數(shù)據(jù)持久化
RabbitMQ
docker pull rabbitmq:management
docker run -d -p 5672:5672 -p 15672:15672 --name rabbitmq rabbitmq:management
ES可視化組件 elasticsearch-head
docker pull mobz/elasticsearch-head:5
docker run -d -p 9100:9100 --name es-head mobz/elasticsearch-head:5
MySQL
docker run -d --restart always --name mysql -p 3306:3306 -v /root/docker/mysql/conf:/etc/mysql -v /root/docker/mysql/log:/var/log/mysql -v /root/docker/mysql/lib:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=cj mysql:5.7
/etc/mysql :默認(rèn)存放配置文件的路徑
/var/lib/mysql :默認(rèn)存放binlog日志的路徑
Tomcat
docker run --name tomcat -p 8080:8080 -v /root/docker/tomcat/conf:/conf -v /root/docker/tomcat/logs:/logs -v /root/docker/tomcat/webapps:/usr/local/tomcat/webapps -d tomcat:8.5.78-jre8-temurin-focal
