廈門(mén)網(wǎng)站建設(shè)哪家強(qiáng)農(nóng)產(chǎn)品網(wǎng)絡(luò)營(yíng)銷(xiāo)
Dockerfile的構(gòu)建過(guò)程
- 每條保留字段必須為大寫(xiě)字母。
- Dockerfile每行只支持一條指令,但是每條指令可以帶多個(gè)參數(shù),并且每條保留字指令后面至少要帶有一個(gè)參數(shù)。
- 從上到下依次執(zhí)行。
- 每條指令都會(huì)創(chuàng)建一個(gè)新的鏡像層,并提交新的鏡像。
大致流程:
- docker從基礎(chǔ)鏡像運(yùn)行一個(gè)容器
- 執(zhí)行一條指令并對(duì)容器作出修改
- 執(zhí)行提交操作,提交一個(gè)新的鏡像層
- 執(zhí)行dockerfile的下一條指令
Dockerfile的保留字指令
Docker Compose
我們使用一個(gè)超長(zhǎng)的命令來(lái)去看一下MySQL能不能部署成功:
docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
部署成功了,但是這個(gè)命令太過(guò)于長(zhǎng)了,而且一次只能部署一個(gè)容器,所以我們提出了docker-compose。
我們寫(xiě)一個(gè)docker-compose文件然后運(yùn)行docker-compose up
,結(jié)果報(bào)錯(cuò)了。
這個(gè)報(bào)錯(cuò)非常的坑:
ERROR: yaml.scanner.ScannerError: while scanning for the next token
found character '\t' that cannot start any tokenin "./docker-compose.yaml", line 4, column 1
意思就是yaml必須打2個(gè)空格,不能打\t。然后最終看起來(lái)是一樣的,但是會(huì)無(wú)法識(shí)別。
1 version: '3.1'2 3 services:4 5 db:6 image: mysql # 鏡像的名稱(chēng)7 command: # 對(duì)應(yīng)我上面那個(gè)巨長(zhǎng)的命令的--8 --character-set-server=utf8mb49 --collation-server=utf8mb4_unicode_ci10 restart: always # 如果宕機(jī)了,重啟的策略11 environment: # 對(duì)應(yīng)上面的-e配置環(huán)境12 MYSQL_ROOT_PASSWORD: 12345613 volumes: 對(duì)應(yīng)上面的 -v 掛載數(shù)據(jù)14 - /my/own/datadir:/var/lib/mysql15 ports: 對(duì)應(yīng)上面的 -p 端口映射16 - 3306:330617 18 adminer:19 image: adminer20 restart: always21 ports:22 - 8080:8080
然后
docker-compose up -d
在后臺(tái)啟動(dòng)我的docker容器。
這個(gè)admin是一個(gè)MySQL的管理系統(tǒng)。
停止容器的運(yùn)行
條件:在docker-compose的目錄下
docker-compose stop/start #只是停止/運(yùn)行這個(gè)容器
docker-compose down #直接把這個(gè)容器刪了
但是如果我的這個(gè)yml文件不叫docker-compose文件呢?
docker-compose -f mysql.yaml up -d
-f強(qiáng)行指定姓名就可以了。
看日志
docker-compose logs
這樣的話就是名字叫做docker-compose.yaml的日志。
docker-compose -f mysql.yaml logs
這樣就是查看名字叫做mysql.yaml
的日志。
docker-compose -f mysql.yaml logs -f
這樣就是查看名字叫做mysql.yaml
的日志,并且滾動(dòng)更新日志。
Docker容器網(wǎng)絡(luò)基礎(chǔ)
Bridge網(wǎng)絡(luò)
我們先使用一個(gè)命令查看Docker的一些網(wǎng)絡(luò)信息:
[root@k8smaster mysql]# docker network ls
NETWORK ID NAME DRIVER SCOPE
0192785adb20 bridge bridge local
6265d41f9cbc host host local
1076f6955d43 mysql_default bridge local
7bd9dd6a93a5 none null local
可以看到又一個(gè)bridge,網(wǎng)橋網(wǎng)絡(luò)。
在網(wǎng)絡(luò)方面,橋接網(wǎng)絡(luò)是在網(wǎng)段之間轉(zhuǎn)發(fā)流量的鏈路層設(shè)備。橋可以是在主機(jī)內(nèi)核中運(yùn)行的硬件設(shè)備或者軟件設(shè)備。
docker0(默認(rèn)bridge)
docker run -d --name tomcat1 tomcat
我們先來(lái)啟動(dòng)兩個(gè)tomcat容器。
docker inspect tomcat1
查看tomcat1容器的相關(guān)信息。
我們來(lái)看一下結(jié)果:
[{"Id": "89435df83bcb0f8c5d685f4ad7a0d06b01a14b182c3f2eedd48aace0fc8539b6","Created": "2023-02-15T10:41:23.32460978Z","Path": "catalina.sh","Args": ["run"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 52447,"ExitCode": 0,"Error": "","StartedAt": "2023-02-15T10:41:23.665177066Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:fb5657adc892ed15910445588404c798b57f741e9921ff3c1f1abe01dbb56906","ResolvConfPath": "/var/lib/docker/containers/89435df83bcb0f8c5d685f4ad7a0d06b01a14b182c3f2eedd48aace0fc8539b6/resolv.conf","HostnamePath": "/var/lib/docker/containers/89435df83bcb0f8c5d685f4ad7a0d06b01a14b182c3f2eedd48aace0fc8539b6/hostname","HostsPath": "/var/lib/docker/containers/89435df83bcb0f8c5d685f4ad7a0d06b01a14b182c3f2eedd48aace0fc8539b6/hosts","LogPath": "/var/lib/docker/containers/89435df83bcb0f8c5d685f4ad7a0d06b01a14b182c3f2eedd48aace0fc8539b6/89435df83bcb0f8c5d685f4ad7a0d06b01a14b182c3f2eedd48aace0fc8539b6-json.log","Name": "/tomcat1","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {"max-size": "100m"}},"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/7eadc53b492791389b9375565b5e9d8f521b247aaec55e14c5694fde8cb262ed-init/diff:/var/lib/docker/overlay2/5d15c4c9c3c9d33bce87d6c6d4fe6cd9a1659fae0f1606fb538066e645ed91c7/diff:/var/lib/docker/overlay2/0a467022e79f75c4fc6bbc155b4deb858bf3e17c41a00144c3fd63fdf94ec0bc/diff:/var/lib/docker/overlay2/4871abe01045d7cd11c8bcda554285ed9881067ed31bad1ef9e13d6f43bdc0cd/diff:/var/lib/docker/overlay2/8645d7f0b517edd1e5ad42be66d166d643756ed3dd26c72a6e69ac2ede924f76/diff:/var/lib/docker/overlay2/eb8d5dd01d3f3bb1b83e73d8276505fcb6b799c70820e792c6b0c2e17e3f38fd/diff:/var/lib/docker/overlay2/2714615f68373bde97f4eed08063f25d441d70a09f2cbab8223305fd099cab27/diff:/var/lib/docker/overlay2/65f27c74105575dcf023693c9f437f2e10165b6a85d9f76a76520d7bf0353483/diff:/var/lib/docker/overlay2/a52375516fb2e071a95f2c633bc23bc5d774311287a88f1e534a61bfd76a164a/diff:/var/lib/docker/overlay2/03545b9f89cf397d82c6effb7d924f1a901a5e02f023eec1509b11f4a5bb5adc/diff:/var/lib/docker/overlay2/8a92f9978f8dc817792c00c70433e91809d369cd7dabfbd40e75d583f46dffb9/diff","MergedDir": "/var/lib/docker/overlay2/7eadc53b492791389b9375565b5e9d8f521b247aaec55e14c5694fde8cb262ed/merged","UpperDir": "/var/lib/docker/overlay2/7eadc53b492791389b9375565b5e9d8f521b247aaec55e14c5694fde8cb262ed/diff","WorkDir": "/var/lib/docker/overlay2/7eadc53b492791389b9375565b5e9d8f521b247aaec55e14c5694fde8cb262ed/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "89435df83bcb","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"ExposedPorts": {"8080/tcp": {}},"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/tomcat/bin:/usr/local/openjdk-11/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","JAVA_HOME=/usr/local/openjdk-11","LANG=C.UTF-8","JAVA_VERSION=11.0.13","CATALINA_HOME=/usr/local/tomcat","TOMCAT_NATIVE_LIBDIR=/usr/local/tomcat/native-jni-lib","LD_LIBRARY_PATH=/usr/local/tomcat/native-jni-lib","GPG_KEYS=A9C5DF4D22E99998D9875A5110C01C5A2F6059E7","TOMCAT_MAJOR=10","TOMCAT_VERSION=10.0.14","TOMCAT_SHA512=c2d2ad5ed17f7284e3aac5415774a8ef35434f14dbd9a87bc7230d8bfdbe9aa1258b97a59fa5c4030e4c973e4d93d29d20e40b6254347dbb66fae269ff4a61a5"],"Cmd": ["catalina.sh","run"],"Image": "tomcat","Volumes": null,"WorkingDir": "/usr/local/tomcat","Entrypoint": null,"OnBuild": null,"Labels": {}},"NetworkSettings": {"Bridge": "","SandboxID": "22a9286beec475133639bbde1edc2d07c1b1e0d95fcd4eec6a4e7beba42d34c4","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {"8080/tcp": null},"SandboxKey": "/var/run/docker/netns/22a9286beec4","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "dea491b6061874ceefd394d819009d84a564ad08c4782f0279706660caf246af","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": "0192785adb20f46e2f13c2fcfe6131d43b7b965eb03b39f55fe292c6196ae2ea","EndpointID": "dea491b6061874ceefd394d819009d84a564ad08c4782f0279706660caf246af","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}}}}
]
可以看到network那個(gè)地方是橋接。
Bridge網(wǎng)絡(luò)模型圖
設(shè)備上網(wǎng)是需要一張網(wǎng)卡的。
veth相當(dāng)于是一個(gè)虛擬網(wǎng)卡。
我們手動(dòng)創(chuàng)建兩個(gè)網(wǎng)橋:
docker network create br0
br0和br1。然后我們來(lái)看一下:
[root@VM-24-15-centos ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
e3e87ce572f5 br0 bridge local
4cf4d0ebbd73 br1 bridge local
7891479a5509 bridge bridge local
dd1c10816481 etcdnet bridge local
c1c1565931b6 host host local
cadd4c7e1fe9 none null local
可以發(fā)現(xiàn)確實(shí)是成功的。
docker network connect br0 tomcat1
觀察一下tomcat1的狀態(tài):
"Networks": {"br0": {"IPAMConfig": {},"Links": null,"Aliases": ["7c7fbf222981"],"NetworkID": "e3e87ce572f5870e73ad1f37f700f597cd7748b1a40fc46e260ee14f99be4468","EndpointID": "29a5954e817f89ecf33c00520e84fe41e91875203ac96ca0f71fab26e470373c","Gateway": "172.19.0.1","IPAddress": "172.19.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:13:00:02","DriverOpts": {}},"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "7891479a5509f9cfb69ac4db4452a4a3b9d8fd28b175cf750f53a79ded798671","EndpointID": "bf73381f0a91920258c6780aa75b8d11846838547dff83e9af8ca260257794ef","Gateway": "172.17.0.1","IPAddress": "172.17.0.4","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:04","DriverOpts": null}}
可以看到確實(shí)連接成功了,但是舊的bridge沒(méi)有被刪除。
就像是一個(gè)機(jī)器可以連接多個(gè)網(wǎng)卡一樣。
我們把bridge去掉。
docker network disconnect bridge tomcat1
然后就可以看到網(wǎng)橋網(wǎng)絡(luò)確實(shí)被刪除掉了!!!
有些例如數(shù)據(jù)庫(kù)這樣的東西,我們可以把數(shù)據(jù)庫(kù)放在一個(gè)網(wǎng)橋上。然后不對(duì)外暴露端口。
Host網(wǎng)絡(luò)
Host模式并沒(méi)有為容器創(chuàng)建一個(gè)隔離的網(wǎng)絡(luò)環(huán)境。而之所以被稱(chēng)之為host模型,是因?yàn)樵撃J较碌腄ocker容器會(huì)和host宿主機(jī)共享同一個(gè)網(wǎng)絡(luò)namespace,故Docker Container的IP地址即為宿主機(jī)eth0的IP地址。其特點(diǎn)包括:
- 這種模式下的容器沒(méi)有隔離的
network namespace
。 - 容器的IP地址同Docker host的IP地址。
- host模式可以與其他模式共存
- 容器中的服務(wù)的端口號(hào)不能與Docker host上已經(jīng)使用的端口號(hào)沖突。
考慮到安全問(wèn)題,Host網(wǎng)絡(luò)用的比較少
None網(wǎng)絡(luò)
網(wǎng)絡(luò)模式為none,即不為Docker容器構(gòu)造任何網(wǎng)絡(luò)環(huán)境。一旦Docker容器采用了none網(wǎng)絡(luò)模式,那么容器內(nèi)部就只能使用loopback(lo)網(wǎng)絡(luò)設(shè)備,不會(huì)再有其他的網(wǎng)絡(luò)資源。Docker Container的none網(wǎng)絡(luò)模式意味著不給該容器創(chuàng)建任何網(wǎng)絡(luò)環(huán)境,容器只能使用127.0.0.1的本地網(wǎng)絡(luò)。
Container模式
Container網(wǎng)絡(luò)模式是Docker中一種比較特殊的網(wǎng)絡(luò)模式。處于這個(gè)模式下的Docker容器共享其他容器的網(wǎng)絡(luò)環(huán)境,因此至少這兩個(gè)容器之間不存在網(wǎng)絡(luò)隔離,而這兩個(gè)容器又與宿主機(jī)以及除此之外的其他的容器存在網(wǎng)絡(luò)隔離。
我們先啟動(dòng)一個(gè)my-nginx2的容器,網(wǎng)絡(luò)在默認(rèn)的bridge網(wǎng)橋上。
然后啟動(dòng)一個(gè)tomcat3容器,并且使用Container網(wǎng)絡(luò)與my-nginx2共享網(wǎng)絡(luò)。
docker run -d --name tomcat3 --network container:my-nginx2 tomcat
我們inspect一下tomcat3,發(fā)現(xiàn)壓根沒(méi)有網(wǎng)絡(luò)設(shè)置。
我們?cè)趇nspect返回的結(jié)果里面查看一下網(wǎng)絡(luò)設(shè)置:
"NetworkMode": "container:33d777b8b7c5158174ba5d10ffbbca289a45e416e152c1b933e5acfbc65bab4a",
可以看到是Container模式,并且連接到33d777b8b7c5158174ba5d10ffbbca289a45e416e152c1b933e5acfbc65bab4a
這個(gè)容器。
我們要注意一點(diǎn),我們兩個(gè)容器暴露的端口肯定不能一樣。
我們現(xiàn)在有tomcat1已經(jīng)啟動(dòng)了,然后我們?cè)俅蝿?chuàng)建一個(gè)tomcat4,并且使用Container模式于tomcat1。
然后就報(bào)錯(cuò)了:
java.net.BindException: Address already in use (Bind failed)
端口已經(jīng)綁定了,這很正常,原因前面已經(jīng)講解過(guò)了。綁定的端口沖突了,因?yàn)槲覀冞\(yùn)行的都是tomcat容器,所以綁定的端口是一樣的。