一、Docker 介绍
1. 下载 Dcoker 依的赖环境
想安装Docker,需要先将依赖的环境全部下载下来,就像Maven依赖JDK一样
yum -y install yum-utils device-mapper-persistent-data lvm22. 指定 Docker 镜像源
默认下载Docker会去国外服务器下载,速度较慢,可以设置为阿里云镜像源,速度更快
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo3. 安装 Docker
yum makecache fast
yum -y install docker-ce4. 启动 Docker 并测试
安装成功后,需要手动启动,设置为开机启动,并测试一下 Docker
#启动docker服务
systemctl start docker
#设置开机自动启动
systemctl enable docker
#测试
docker run hello-world二、Docker 的中央仓库
1.Docker官方的中央仓库:这个仓库是镜像最全的,但是下载速度较慢。
https://hub.docker.com/
2.国内的镜像网站:网易蜂巢,daoCloud等,下载速度快,但是镜像相对不全。
https://c.163yun.com/hub#/home
http://hub.daocloud.io/ (推荐使用)
3.在公司内部会采用私服的方式拉取镜像(添加配置)
#需要创建 /etc/docker/daemon.json,并添加如下内容
{
"registry-mirrors":\["https://registry.docker-cn.com"\],
"insecure-registries":\["ip:port"\]
}
#重启两个服务
systemctl daemon-reload
systemctl restart docker三、镜像的操作

底层原理
docker怎么工作的?
Docker是个C-S结构系统,Docker守护进程运行在主机上。通过Socket从客户端访问。
Docker server 接收Docker-Client指令,就会执行命令。
Docker为什么比虚拟机快
- Docker有着比虚拟机更少的抽象层。
- docker用宿主机的内核,vm需要GUEST OS

1. 拉取镜像
从中央仓库拉取镜像到本地
docker pull 镜像名称\[:tag\]
#举个栗子:docker pull daocloud.io/library/tomcat:8.5.15-jre8
# 如果不写tag默认latest
# 分层下载2. 查看本地全部镜像
查看本地已经安装过的镜像信息,包含标识,名称,版本,更新时间,大小
docker images
#可选项
-a --all # 显示所有镜像
-q --quiet # 只显示镜像id3. 删除本地镜像
镜像会占用磁盘空间,可以直接手动删除,标识通过查看获取
docker rmi 镜像的标识
docker rmi $(docker image -qa)4. 镜像的导入导出
如果因为网络原因可以通过硬盘的方式传输镜像,虽然不规范,但是有效,但是这种方式导出的镜像名称和版本都是null,需要手动修改
#将本地的镜像导出
docker save -o 导出的路径 镜像id
#加载本地的镜像文件
docker load -i 镜像文件
#修改镜像文件
docker tag 镜像id 新镜像名称:版本
# 帮助命令
docker version #显示版本信息
docker info # docker 系统信息,包括镜像和容器数量
docker 命令 --help
docker tag : 标记本地镜像,将其归入某一仓库。
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
[root@localhost ~]$ docker tag centos centos:v1
[root@localhost ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 1e1148e4cc2c 2 weeks ago 202MB
centos v1 1e1148e4cc2c 2 weeks ago 202MB
# 搜索镜像
docker search 名字
D:\workspace\redis\composetest> docker search python
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
python Python is an interpreted, interactive, objec… 5448 [OK]
django Django is a free web application framework, … 991 [OK]
pypy PyPy is a fast, compliant alternative implem… 249 [OK]
#可选项
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
D:\workspace\redis\composetest> docker search python --filter=STARS=3000 #star 3000 以上
四、容器的操作
1. 运行容器
运行容器需要定制具体镜像,如果镜像不存在,会直接下载
#简单操作
docker run 镜像的标识|镜像的名称\[:tag\]
#常用的参数
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像的标识|镜像名称\[:tag\]
#-d:代表后台运行容器
#-p 宿主机端口:容器端口:为了映射当前Linux的端口和容器的端口
#--name 容器名称:指定容器的名称
# -it 交互方式运行# 显示日志
-tf # 显示日志
--tail number # 要显示日志条数
docker logs -tf --tail 10 容器id#查看容器内部的进程信息
D:\redis\docker-slave> docker top 728
PID USER TIME COMMAND
56518 999 0:00 redis-server *:6379# 查看容器元数据
docker inspect 容器id
[
{
"Id": "7280041d5b930c77b4e9f2280af60b86ade396bed9a34bece6ce61c270aa21fd",
"Created": "2020-08-29T01:43:12.373345412Z",
"Path": "docker-entrypoint.sh",
"Args": [
"redis-server"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 56518,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-08-29T01:43:13.930533126Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:7eed8df88d3b3574ed937381f06e715d1b73be03ffed6acca58a6fa9f6ff3d64",
"ResolvConfPath": "/var/lib/docker/containers/7280041d5b930c77b4e9f2280af60b86ade396bed9a34bece6ce61c270aa21fd/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/7280041d5b930c77b4e9f2280af60b86ade396bed9a34bece6ce61c270aa21fd/hostname",
"HostsPath": "/var/lib/docker/containers/7280041d5b930c77b4e9f2280af60b86ade396bed9a34bece6ce61c270aa21fd/hosts",
"LogPath": "/var/lib/docker/containers/7280041d5b930c77b4e9f2280af60b86ade396bed9a34bece6ce61c270aa21fd/7280041d5b930c77b4e9f2280af60b86ade396bed9a34bece6ce61c270aa21fd-json.log",
"Name": "/nifty_curran",
"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": [
50,
164
],
"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/5055750f20f49cd3f5684a5b7388ed2ecff79b3c641de99017c6e4665cfa9d0c-init/diff:/var/lib/docker/overlay2/13911871e4b70ed520838d895cfafc2175ea94db980ed05d498da9396bef0cde/diff:/var/lib/docker/overlay2/f1b8cff2012374f1cfeb461acd64c07a5d7b1e2174a0afe90c60b92fac22d06e/diff:/var/lib/docker/overlay2/1a17bb8a0244a0fde7e4cd7d37f906b46672d701a70660f9cdf46df740c4a18a/diff:/var/lib/docker/overlay2/dae503da0441e4788b1e8347e1508bffcf8baefb12aede97fd290f007c45503a/diff:/var/lib/docker/overlay2/f6a29e2348b308c119e123d842b35f0c6b76004d2290097fde3bd54196bfc9d3/diff:/var/lib/docker/overlay2/80e99d6b63b85ad48523ae8625e5ce027b81a2da790683185649081ada1a85f3/diff",
"MergedDir": "/var/lib/docker/overlay2/5055750f20f49cd3f5684a5b7388ed2ecff79b3c641de99017c6e4665cfa9d0c/merged",
"UpperDir": "/var/lib/docker/overlay2/5055750f20f49cd3f5684a5b7388ed2ecff79b3c641de99017c6e4665cfa9d0c/diff",
"WorkDir": "/var/lib/docker/overlay2/5055750f20f49cd3f5684a5b7388ed2ecff79b3c641de99017c6e4665cfa9d0c/work"
},
"Name": "overlay2"
},
"SizeRw": 0,
"SizeRootFs": 98205103,
"Mounts": [
{
"Type": "volume",
"Name": "1a6c8df98c1ecc6ed763c633f6ebac8e4115271e58f8923344f8a47aa925ff35",
"Source": "/var/lib/docker/volumes/1a6c8df98c1ecc6ed763c633f6ebac8e4115271e58f8923344f8a47aa925ff35/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "7280041d5b93",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"ExposedPorts": {
"6379/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"GOSU_VERSION=1.11",
"REDIS_VERSION=5.0.7",
"REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-5.0.7.tar.gz",
"REDIS_DOWNLOAD_SHA=61db74eabf6801f057fd24b590232f2f337d422280fd19486eca03be87d3a82b"
],
"Cmd": [
"redis-server"
],
"Image": "7ee",
"Volumes": {
"/data": {}
},
"WorkingDir": "/data",
"Entrypoint": [
"docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "74e1dff4096ff21f20db24123f48110791308905ea8395538bc7db826ffc86d0",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"6379/tcp": null
},
"SandboxKey": "/var/run/docker/netns/74e1dff4096f",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "2de94cf420fb02075021db2727e23f7beb813f202b468336cdba7ca00c62ea2d",
"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": "5e4593468809d742a56eaeb8b9459a62f8c065e61496a6b4a2548edb314dbba0",
"EndpointID": "2de94cf420fb02075021db2727e23f7beb813f202b468336cdba7ca00c62ea2d",
"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
}
}
}
}
]2. 查看正在运行的容器
查看全部正在运行的容器信息
docker ps \[-qa\]
#-a 查看全部的容器,包括没有运行
#-q 只查看容器的标识
#-n=? 显示最近的容器3. 查看容器日志
查看容器日志,以查看容器运行的信息
docker logs -f 容器id
#-f:可以滚动查看日志的最后几行4. 进入容器的内部
通常容器都是后台方式运行,需要进入容器修改配置
方式一命令
docker exec -it 容器id bash
进入容器后开启新的终端,可以在里面操作
方式二
docker attach 容器 id
进入容器正在执行的终端,不会启动新的进程5. 复制内容到容器
将宿主机的文件复制到容器内部的指定目录
docker cp 文件名称 容器id:容器内部路径
将容器内的文件copy出
docker cp 容器id:容器内部路径 文件路径6. 重启 & 启动 & 停止 & 删除容器
退出容器 exit
容器不停止退出容器 ctrl+P+Q
容器的启动,停止,删除等操作,后续会经常使用到
#重新启动容器
docker restart 容器id
#启动停止运行的容器
docker start 容器id
#停止指定的容器(删除容器前,需要先停止容器)
docker stop 容器id
#强制停止当前容器
docker kill 容器id
#停止全部容器
docker stop $(docker ps -qa)
#删除指定容器
docker rm 容器id
#删除全部容器
docker rm $(docker ps -qa)
docker ps -a -q | xargs docker rm


五、Docker 应用
nginx
# nginx
1. 搜索镜像 docker search 镜像那么
2. 获取镜像 docker pull 镜像
3. 运行参数:docker run -d --name nginx1 -p 3366:80 nginx
4. 测试:
linux:curl localhost:3366
windows: $R = Invoke-WebRequest -URI http://localhost:3366
进入容器:
D:\redis\docker-slave> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a160b0ef6749 nginx "/docker-entrypoint.…" 18 minutes ago Up 18 minutes 0.0.0.0:6666->80/tcp nginx1
PS D:\redis\docker-slave> docker exec -it a16 bash
root@a160b0ef6749:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@a160b0ef6749:/# cd /etc/nginx
root@a160b0ef6749:/etc/nginx# ls
conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utfpowershell中使用curl
#请求地址 - Uri $uri #添加header -Headers @{"content-type"="application/json";"authorization"="bearer token"} #指定Method -Method Get #将获取到的content输出到文件 -OutFile 'c:\Users\rmiao\temp\content.txt'C:\Users\wweim> get-help invoke-webrequest 名称 Invoke-WebRequest 语法 Invoke-WebRequest [-Uri] <uri> [<CommonParameters>] 别名 iwr wget curl 备注 Get-Help 在此计算机上找不到该 cmdlet 的帮助文件。它仅显示部分帮助。 -- 若要下载并安装包含此 cmdlet 的模块的帮助文件,请使用 Update-Help。 -- 若要联机查看此 cmdlet 的帮助主题,请键入: "Get-Help Invoke-WebRequest -Online" 或 转到 https://go.microsoft.com/fwlink/?LinkID=217035。 C:\Users\wweim> $R = Invoke-WebRequest -URI http://www.bing.com?q=how+many+feet+in+a+mile C:\Users\wweim> $R StatusCode : 200 StatusDescription : OK Content : <!DOCTYPE html><html lang="zh" xml:lang="zh" RawContent : HTTP/1.1 200 OK ParsedHtml : mshtml.HTMLDocumentClass RawContentLength : 118264 ...... # 省略n多字符
tomcat
docker run -it --rm tomcat:9.0
# 用完即删容器,一般用来测试
docker pull tomcat:9.0
docker run -d -p 3355:8080 --name tomcat1 2ae
docker exec -it tomcat1 bash
//webapps 缺少命令
方式一:cp -r ./webapps.dist/* ./webapps/
es+kibana
# es 暴露端口多,十分耗内存,数据一般放在安全目录挂载
# --net somenetwork 网络配置
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
#es 耗内存,1.xG
# 查看 docker stats
# 通过-e进行配置,限制内存
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64n -Xmx512m" elasticsearch:7.6.2可视化
portainer docker图形化管理工具
docker run -d -p 9000:9000 --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
--name prtainer-test \
docker.io/portainer/portainer
Rancher(CI/CD)
Docker镜像讲解
镜像是轻量级可独立运行的软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的内容,包括代码、运行时的库、环境变量和配置文件
所有的应用直接打包docker镜像,可直接运行
Docker镜像加载原理
UnionFS(联合文件系统)
union文件系统是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一虚拟文件系统下。Union文件系统是docke镜像基础。镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次加载多个文件系统,但从外面只看到一个文件系统,联合加载会把各层文件系统累加起来,这样最终的文件系统会包含所有底层的文件
Docker镜像加载原理
docker的镜像实际上是由一层一层的文件系统构成,这种层级的文件系统UnionFS。
- bootfs(boot file system) 主要包含bootloader和kernel, bpotloader 主要是引导加载kernel,当我们加载镜像的时候,会通过bootloader加载kernal,Docker镜像最底层是bootfs,当boot加载完成后整个kernal内核都在内存中了,bootfs也就可以卸载,值得注意的是,bootfs是被所有镜像共用的,许多镜像images都是在base image(rootfs)基础上叠加的
- rootfs (root file system),在bootfs之 上.包含的就是典型Linux系统中的/dev, /proc, /bin, /etc等标准目录和文件。rootfs就是 各种不同的操作系统发行版,比如Ubuntu, Centos等等 。
主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器内核。当boot加载完之后整个内核就都在内存中了,此时内存的使用权已经由bootfs交给内核了,此时系统也会卸载bootfs
对以一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就行,因为底层直接用host和kernel,自己只需要提供rootfs就行。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
分层理解
共享资源
比如:有多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也需要加载一份base镜像,就可以为所有服务器服务了。而且镜像的每一层都可以被共享。
docker镜像都是只读的
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下都叫“镜像层
commit镜像
docker commit 提交容器成为一个新副本
# 命令和git原理类似
# 将我们操作过的容器提交为一个镜像
docker commit -m="提交描述信息" -a="作者" 容器id 目标镜像名:[Tag]
#docker commit -a="xian" -m="add webapps app" eda09906a31c tomcat02:1.0六、数据卷
docker理念:将应用和环境打包成一个镜像
数据?如果在容器里,容器删除,数据将会丢失 需求:数据持久化
容器持久化和同步操作,容器间也可以共享数据
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录 -p 主机端口:容器端口 --name 容器名称 容器id
# windows
docker run -d -v D:\workspace\securityplanform\securityplatform\数据库\redis\pro:/home -p 3355:8080 --name tomcat2 9422
为了部署 SSM 的工程,需要使用到 cp 的命令将宿主机内的 ssm.war 文件复制到容器内部。
数据卷:将宿主机的一个目录映射到容器的一个目录中。
可以在宿主机中操作目录中的内容,那么容器内部映射的文件,也会跟着一起改变。
1. 创建数据卷
#创建数据卷后,默认会存放在一个目录下/var/lib/docker/volumes/数据卷名称/\_data
docker volume create 数据卷名称2. 查看全部数据卷
#查看全部数据卷信息
docker volume ls3. 查看数据卷详情
#查看数据卷的详细信息,可以查询到存放的路径,创建时间等等
docker volume inspect 数据卷名称4. 删除数据卷
#删除指定的数据卷
docker volume rm 数据卷名称5. 容器映射数据卷
#通过数据卷名称映射,如果数据卷不存在。Docker会帮你自动创建,会将容器内部自带的文件,存储在默认的存放路径中。
docker run -d -p 8080:8080 --name tomcat -v 数据卷名称:容器内部的路径 镜像id
#通过路径映射数据卷,直接指定一个路径作为数据卷的存放位置。但是这个路径下是空的。
docker run -d -p 8080:8080 --name tomcat -v 路径(/root/自己创建的文件夹):容器内部的路径 镜像id实战msql
mysql 数据持久化
映射的data目录中不能有文件
docker pull mysql:5.7
docker run -d -p 3310:3306 -v D:\workspace\securityplanform\securityplatform\数据库\redis\pro\mysql\data:/etc/mysql/conf.d -v D:\workspace\securityplanform\securityplatform\数据库\redis\pro\mysql\data:/var/lib/mysql -e MSQL_ROOT_PASSWORD=666 --name mysql1 mysql具名挂载和匿名挂载
匿名挂载:即在进行数据卷挂载的时候不指定宿主机的数据卷目录
-v 容器路径
docker run -d -P --name nginx1 -v /etc/nginx nginx
D:\workspace\securityplanform\securityplatform\数据库\redis\pro> docker volume ls
DRIVER VOLUME NAME
local 1a6c8df98c1ecc6ed763c633f6ebac8e4115271e58f8923344f8a47aa925ff35
具名挂载:
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
docker volumn inspect juming-nginx所有docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/XXX
docker volumn ls 查看所有的卷都在这个位置/var/lib/docker/volumns
如何确定是匿名挂载还是具名挂载呢?
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
拓展
(1)通过 -v 容器内路径:ro rw 改变读写权限
ro readonly #只读
rw readwrite #可读可写
(2)一旦这个设定了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
(3)ro
只要看到ro就说明这个路径只能通过宿主机来改变,容器内部是无法操作的
数据卷容器
多个mysql同步数据
docker run -it --name docker01 zs:1.0
docker run -it -d --name docker03 --volumes-from docker01
docker run -it -d --name docker03 --volumes-from docker02
移除己挂载卷的容器,无论是最初的dbstore容器,还是其后的db1或db2容器,卷都不会被移除。要将卷从硬盘上移除,必须使用docker rm -v命令删除最后一个引用了该卷的容器。七、Dockerfile 自定义镜像
dockerfile 是用来构建docker镜像文件!命令参数脚本
构建步骤:
1、编写一个dockerfile文件
2、docker build 构建成为一个镜像
3、docker run 运行镜像
4、docker push 发布镜像(Docker hub、阿里云)
FROM scratch
ADD centos-7-x86_64-docker.tar.xz /
LABEL \
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image" \
org.label-schema.vendor="CentOS" \
org.label-schema.license="GPLv2" \
org.label-schema.build-date="20200809" \
org.opencontainers.image.title="CentOS Base Image" \
org.opencontainers.image.vendor="CentOS" \
org.opencontainers.image.licenses="GPL-2.0-only" \
org.opencontainers.image.created="2020-08-09 00:00:00+01:00"
CMD ["/bin/bash"]dockerfile基础知识:
1、每个保留关键字(指令)都必须是大写字母
2、执行从上到下顺序
3、# 注释
4、每个指令都会提交一个新的镜像层
1.Dockerfile:构建文件
DockerImage:通过Dockerfile构建生成的镜像,最终发布和运行的产品。
DockerContainer:运行起来的镜像,提供服务。
FROM: 基础镜像,
MAINTAINER: 姓名+邮箱,谁写的
RUN:执行的命令,可以编写多个
ADD:类似copy,可自动解压
WORKDIR:声明镜像的默认工作目录
VOLUME:挂载目录
EXPOSE:暴露端口
COPY:将相对路径下的内容复制到自定义镜像中
CMD:指定容器启动要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT:指定容器启动要运行的命令,可以追加命令
ONBUILD:当构建一个被继承Dockerfile,会运行onbuild,触发指令
ENV :构建时设置环境变量# 创建一个自己的Dockerfile
FROM centos
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "____end____"
CMD /bin/bash
#通过命令自己构建镜像
#docker build -f dockerfile 文件路径 -t镜像名:版本号
docker build -f Dockerfile -t mycentos:1.0 .
#列出镜像变更历史
docker history 
CMD 和 ENTRYPOINT
#Dockerfile
FROM centos
CMD ["ls","-a"]
D:\workspace\docker> docker build -f Dockerfile1 -t mycentos:2.0 .
D:\workspace\docker> docker run 8df .
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
PS D:\workspace\docker> docker run 8df -l docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.
# cmd的清理下,-l替换了cmd命令["ls","-a"],-l不是命令所以报错
# ENTRYPOINT 可以追加命令
FROM centos
ENTRYPOINT ["ls","-a"]
docker run 135 -l total 56
drwxr-xr-x 1 root root 4096 Aug 29 14:12 .
drwxr-xr-x 1 root root 4096 Aug 29 14:12 ..
-rwxr-xr-x 1 root root 0 Aug 29 14:12 .dockerenv
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 340 Aug 29 14:12 dev
drwxr-xr-x 1 root root 4096 Aug 29 14:12 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64
drwx------ 2 root root 4096 Aug 9 21:40 lost+found
drwxr-xr-x 2 root root 4096 May 11 2019 media
drwxr-xr-x 2 root root 4096 May 11 2019 mnt
drwxr-xr-x 2 root root 4096 May 11 2019 opt
dr-xr-xr-x 124 root root 0 Aug 29 14:12 proc
dr-xr-x--- 2 root root 4096 Aug 9 21:40 root
drwxr-xr-x 11 root root 4096 Aug 9 21:40 run
lrwxrwxrwx 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 May 11 2019 srv
dr-xr-xr-x 12 root root 0 Aug 29 14:12 sys
drwxrwxrwt 7 root root 4096 Aug 9 21:40 tmp
drwxr-xr-x 12 root root 4096 Aug 9 21:40 usr
drwxr-xr-x 20 root root 4096 Aug 9 21:40 var
发布镜像
DockerHub
- 注册账号
- 登录 docker login -u name
- docker push
小结

Docker网络
理解Docker0
# 查看容器内部网络地址 ip addr,容器启动会得到一个eth0@if583 ip地址,docker分配的
PS D:\workspace\docker> docker exec -it tomacat01 ip addr
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
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
link/tunnel6 :: brd ::
582: eth0@if583: <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 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# linux能不能ping通(windows 需要设置)原理
1、每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装docker就会有个网卡docker0桥接模式,使用veth-pair技术。
veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。一端连着协议栈,一端彼此相连着
2、容器之间可以ping通

结论:tomcat01和tomcat02是公用一个路由器docker0.
所有容器不指定网络的情况下都是通过docker0路由,docker会给容器分配默认可用IP
Docker用的是linux桥接,docker所有的网络接口都是虚拟的,虚拟转发效率高(内部传递文件)
只要容器删除,对应网桥一对就没了
--link
如果编写一个微服务,database url=ip;项目不重启,数据库ip换了,可以用名字访问容器吗
PS D:\workspace\docker> docker exec -it tomacat02 ping tomacat01
ping: tomacat01: Name or service not known
#
PS D:\workspace\docker> docker run -d -P --name tomacat03 --link tomacat02 tomcat
1a951a3dd6341bda935f1d1feef6973d50d30126319a67acab6e344bf1de7fb6
# 通过--link
PS D:\workspace\docker> docker exec -it tomacat03 ping tomacat02
PING tomacat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomacat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from tomacat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from tomacat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.042 ms
# 反向ping不行
PS D:\workspace\docker> docker exec -it tomacat02 ping tomacat03
ping: tomacat03: Name or service not known
PS D:\workspace\docker> docker network ls
NETWORK ID NAME DRIVER SCOPE
5e4593468809 bridge bridge local
f68af27aa78c composetest_default bridge local
387f0fb5be1a host host local
51a0d05b7a14 none null local
2da31029bce4 scms-promotion-plan-management_default bridge local
PS D:\workspace\docker> docker inspect network 5e4
[
{
"Name": "bridge",
"Id": "5e4593468809d742a56eaeb8b9459a62f8c065e61496a6b4a2548edb314dbba0",
"Created": "2020-08-17T10:27:33.045795472Z",
"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,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"1a951a3dd6341bda935f1d1feef6973d50d30126319a67acab6e344bf1de7fb6": {
"Name": "tomacat03",
"EndpointID": "9337b23669e73d74878b86487dc4c79861378f87ad326ec9727a55ee1923a1bb",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
},
"281ca3daf0e2c87f2dfbe982b62d1a258d3842e28fe1b6baedc2c0abc108088c": {
"Name": "tomacat01",
"EndpointID": "c2d72c0712778ad2f6f7ac2177f00d987281ce0481827b30039bf87618eba1ec",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"9646a8851e1df53c7e4716c1a6a5c7178e7bcfe0a7ced226735191fc57888fb4": {
"Name": "tomacat02",
"EndpointID": "b391a9d421b4006c9bf76041cea1cfcd026bd5be5d49af8e0bd4d19006456905",
"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": {}
}
]
# 查看host配置
PS D:\workspace\docker> docker exec -it tomacat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 tomacat02 9646a8851e1d
172.17.0.4 1a951a3dd634
本质探究: --link就是在hosts中加了一个映射
自定义网络不适用docker0
docker0问题:不支持容器名连接访问自定义网络

查看所有docker网络
网络模式
bridge: 桥接docker(默认)
none: 不配置网络
host: 和宿主机共享网络
container:容器内网络联通(用的少,局限很大)
测试
# 我们直接启动的命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 --net bridge tomcat
#docker0 默认,域名不能访问 --link可以连接
#可自定义网络
D:\workspace\docker> docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by
Network driver (default map[])
--config-from string The network from which copying the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a
network segment
# 创建自定义为网络
# --driver bridge
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1
D:\workspace\docker> docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
63e20b3b606c0cb98d8904f68c9a066664ccc1f8b979051cdb0a95c5dc6ccb8a
PS D:\workspace\docker> docker network ls
NETWORK ID NAME DRIVER SCOPE
5e4593468809 bridge bridge local
f68af27aa78c composetest_default bridge local
387f0fb5be1a host host local
63e20b3b606c mynet bridge local
# 查看自己创建的网络
PS D:\workspace\docker> docker network inspect mynet
[
{
"Name": "mynet",
"Id": "63e20b3b606c0cb98d8904f68c9a066664ccc1f8b979051cdb0a95c5dc6ccb8a",
"Created": "2020-08-30T08:03:45.734311737Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
PS D:\workspace\docker> docker run -d -P --name tomcat-net-01 --net mynet tomcat
bd409a23f48669cff91f3b7f37b75820bd7a294f134ad130b23b5cc6e0694c23
PS D:\workspace\docker> docker run -d -P --name tomcat-net-02 --net mynet tomcat
638347bc00a706b39a381514da67f9fcdb253ae8bf69c38ca7961fb658533a46
PS D:\workspace\docker> docker network inspect mynet
[
{
"Name": "mynet",
"Id": "63e20b3b606c0cb98d8904f68c9a066664ccc1f8b979051cdb0a95c5dc6ccb8a",
"Created": "2020-08-30T08:03:45.734311737Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
# 自己的网络多了几个容器
"Containers": {
"638347bc00a706b39a381514da67f9fcdb253ae8bf69c38ca7961fb658533a46": {
"Name": "tomcat-net-02",
"EndpointID": "69d1c5df2cd71bbbb80bf234be69ca11b58db5753df22df6cee75c1f0168b8e5",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"bd409a23f48669cff91f3b7f37b75820bd7a294f134ad130b23b5cc6e0694c23": {
"Name": "tomcat-net-01",
"EndpointID": "de361dfba548fbf32d08701c458b278a36c150825ea304532afc08f999e1a6e8",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
# 再次测试,不使用--link也可以连接
PS D:\workspace\docker> docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.151 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.101 ms自定义网络docker已经维护了对应关系,推荐!
好处:不同集群使用不同网络,保证集群的安全和健康
网络联通


PS D:\workspace\docker> docker run -d -P --name tomcat01 tomcat
29a3dfc4017d32a9549d1702db543ca9438a79ce9014f650e2a0d0007722f6fd
PS D:\workspace\docker> docker run -d -P --name tomcat02 tomcat
7bb3e11e1360fc26d582072c403a123dcc38eaa07f0e942163bcfc8db55371c5
# 测试打通 tomcat01 到 mynet
PS D:\workspace\docker> docker network connect mynet tomcat01
# 一个容器两个ip地址
部署redis集群
shell 脚本
# 创建脚本
docker network create redis --subnet 172.38.0.0/16
#通过脚本创建6个redis配置
for port in $(seq 1 6):
do \
mkdir -p ./redis/node${port}/conf
touch ./redis/node${port}/conf/redis.conf
cat << EOF >./redis/node${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
#启动集群
docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v D:\workspace\docker\redis/node1/data:/data -v D:\workspace\docker\redis/node1/conf/redis.conf:/etc/redis/redis.conf
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#redis 集群使用sh进入
PS D:\workspace\docker> docker exec -it redis-1 sh
# 创建集群配置
/data # redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
# -c 是进入集群
/data # redis-cli -c
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:136
cluster_stats_messages_pong_sent:139
cluster_stats_messages_sent:275
cluster_stats_messages_ping_received:134
cluster_stats_messages_pong_received:136
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:275
127.0.0.1:6379> cluster nodes
ec65883b496e004ecde689d8ea61c6e4c148f753 172.38.0.14:6379@16379 slave c220031b9b01129114530f5587f7b9a11f4c70a4 0 1598779805000 4 connected
b443c1c7a7a9461022036df358127a4daee553c1 172.38.0.16:6379@16379 slave 00845f2012af8c700ae6f4314391f0cf0b14b34a 0 1598779805598 6 connected
dbbb01b6c43cc1b2ddbb9729757ea8e9221259c9 172.38.0.15:6379@16379 slave 023b067527c89690e947d6ea6b1f3f8dddc377c8 0 1598779805598 5 connected
00845f2012af8c700ae6f4314391f0cf0b14b34a 172.38.0.12:6379@16379 master - 0 1598779805096 2 connected 5461-10922
c220031b9b01129114530f5587f7b9a11f4c70a4 172.38.0.13:6379@16379 master - 0 1598779805598 3 connected 10923-16383
023b067527c89690e947d6ea6b1f3f8dddc377c8 172.38.0.11:6379@16379 myself,master - 0 1598779804000 1 connected 0-5460
127.0.0.1:6379>八、Docker-Compose
1. 下载并安装 Docker-Compose
定义、运行多个容器
YAML file 配置文件
命令
三步骤:
- Dockerfile保证我们的项目在任何地方可以运行
- docker-compose.yml services
- 启动项目 docker-compose up
作用:批量容器编排
compose是官方开源项目,需要自己安装
Compose:重要概念。
- 服务services,容器、应用。(web、redis、mysql)
- 项目project。一组关联的容器


新盘 上车集合 留下 我要发发 立马进裙
2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
新车首发,新的一年,只带想赚米的人coinsrore.com
新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
新车上路,只带前10个人coinsrore.com
新盘首开 新盘首开 征召客户!!!coinsrore.com
新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
新车即将上线 真正的项目,期待你的参与coinsrore.com
新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com
东方明珠客服开户联系方式【182-8836-2750—】?μ- cxs20250806
东方明珠客服电话联系方式【182-8836-2750—】?- cxs20250806】
东方明珠开户流程【182-8836-2750—】?薇- cxs20250806】
东方明珠客服怎么联系【182-8836-2750—】?薇- cxs20250806】
华纳圣淘沙公司开户新手教程
零基础学会(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户
华纳圣淘沙公司开户保姆级教程(183-8890-9465薇-STS5099)
一步步教你开通华纳圣淘沙公司账户(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户分步图解
首次开户必看:(183-8890-9465薇-STS5099)
华纳圣淘沙全攻略
华纳圣淘沙公司开户实操手册(183-8890-9465薇-STS5099)
华纳圣淘沙开户流程视频教程
手把手教学:(183-8890-9465薇-STS5099)
华纳圣淘沙公司开户
华纳圣淘沙公司开户完全指南(183-8890-9465薇-STS5099)