安卓流程:java-----apk -----发布到应用商店-----张三使用apk-----安装即可用!
docker流程: java-jar(环境)-----打包项目帯上环境(镜像)-----( Docker仓库:商店)
总结:Docker解决了环境部署的问题
Docker的思想就来自于集装箱!
JRE – 多个应用(端口冲突) – 原来都是交叉的!
隔离:Docker核心思想!打包装箱!每个箱子是互相隔离的。
Docker通过隔离机制,可以将服务器利用到极致!
本质:所有的技术都是因为出现了一些问题,我们需要去解决,才去学习!
2010年,几个搞IT的年轻人,就在美国成立了一家公司 dotcloud
,做一些pass的云计算服务!LXC(Linux Container容器)有关的容器技术!他们将自己的技术(容器化技术)命名就是 Docker。Docker刚刚延生的时候,没有引起行业的注意!dotCloud
,就活不下去!然后他们就想到了一件事情,开源!
注:Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
开源
2013年,Docker开源!然后越来越多的人发现docker的优点!火了。Docker每个月都会更新一个版本!2014年4月9日,Docker1.0发布!
docker为什么这么火?十分的轻巧!
在容器技术出来之前,我们都是使用虚拟机技术!
虚拟机:在window中装一个VMware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重!
虚拟机也属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!
VMware : linux centos 原生镜像(一个电脑!) 隔离、需要开启多个虚拟机! 一般需要几个G 启动需要几分钟
docker: 隔离,镜像(最核心的环境 4m + jdk + mysql)十分的小巧,运行镜像就可以了!小巧! 几个M 秒级启动!
聊聊Docker
Docker基于Go语言开发的!开源项目!
docker官网:https://www.docker.com/
文档:https://docs.docker.com/ Docker的文档是超级详细的!
仓库:https://hub.docker.com/
app:我们的一些应用
lib:运行所需要的库
kernel:内核
一个整体大环境放很多应用
虚拟机技术缺点:
1、 资源占用十分多
2、 冗余步骤多
3、 启动很慢!
隔离机制:每个容器相互隔离,lib和app独立,充分利用服务器资源。还有如果单个的lib崩溃了,不会导致其他的app出问题。
比较Docker和虚拟机技术的不同:
DevOps也就是指的开发和运维,有四个重要的特点:
应用更快速的交付和部署
更便捷的升级和扩缩容
更简单的系统运维
更高效的计算资源利用
好好看图,注意线条,看流程
镜像(image):
容器(container):
仓库(repository):
[root@iZ2vc28obhvfham8wewhh0Z bin]# uname -r
4.18.0-193.14.2.el8_2.x86_64 # 内核版本,要求3.0以上
[root@iZ2vc28obhvfham8wewhh0Z bin]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="8"
帮助文档:https://docs.docker.com/engine/install/
#1.卸载老版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
#2.需要的安装包
yum install -y yum-utils
#3.设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo#默认是国外的,上面这个是国外的
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo#阿里云版,推荐
#选做:更新yum软件包索引
yum makecache fast
#4.安装docker, docker-ce 社区版 而ee是企业版
yum install docker-ce docker-ce-cli containerd.io
#5.启动docker(记住这个,不要忘记)
systemctl start docker
#6.使用docker version命令查看是否安装成功
docker version
#7.测试
docker run hello-world
#8.查看已经下载的镜像(从这里可以查看已有镜像的id)
[root@iZ2vc28obhvfham8wewhh0Z bin]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 3 months ago 13.3kB
注意看这里的hello-world,就是我们刚刚去下载的镜像
#1.删除依赖
yum remove docker-ce docker-ce-cli containerd.io
#2.删除资源和容器
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
#注:/var/lib/docker,是docker默认工作路径
#您必须手动删除任何已编辑的配置文件
登录阿里云找到容器镜像服务
现在镜像加速器,选择centos,然后复制命令
命令如下:
#1.新建目录
sudo mkdir -p /etc/docker
#2.在docker中的daemon.json里边配置了阿里云的地址
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://0k4g8w4k.mirror.aliyuncs.com"]
}
EOF
#3.重启镜像
sudo systemctl daemon-reload
#4.重启docker
sudo systemctl restart docker
docker run 流程分析图:
Docker是一个Client-Server(cs)结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问!
Docker-Server接收到Docker-Client的指令,就会执行这个命令!
在一个LInux服务器中,有许多的客户端,客户端会去连接到Docker的后台守护进程,通过守护进程去操作docker容器(可以把docker容器想成一个小的linux虚拟机,它也有许多的端口。所以说linux要去访问docker容器里边的东西,是需要再去做一个连通,之后讲解),docker容器会去获取资源。外边这个大的linux,和docker容器是相互隔离的。同时Docker在后台是一个特别大的服务
注意:看图中的VM中的App都是需要一个Guset OS的,而Docker中的App不需要
GuestOS: VM(虚拟机)里的的系统(OS)
HostOS:物理机里的系统(OS)
当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。避免引导、加载操作系统内核返个比较费时费资源的过程,
当新建一个虚拟机时,虚拟机软件需要加载GuestOS,返个新建过程是分钟级别的。
而docker由于直接利用宿主机的操作系统,则省略了这个复杂的过程,因此新建一个docker容器只需要几秒钟。
docker version #显示docker的版本信息。
docker info #显示docker的系统信息,包括镜像和容器的数量,更详细
docker 命令 --help #帮助命令
#例如:方便查看语法格式,可选参数等,十分爽到
docker images --help
docker search --help
docker pull --help
帮助文档的地址:https://docs.docker.com/reference/,查询相关命令
docker images #查看所有本地主机上的镜像 可以使用docker image ls代替
docker search #搜索镜像
docker pull #下载镜像 docker image pull
docker rmi #删除镜像 docker image rm
此命令可以查看所有本地的主机上的镜像
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 3 months ago 13.3kB
#1.解释
#REPOSITORY # 镜像的仓库源
#TAG # 镜像的标签(版本) ---lastest 表示最新版本
#IMAGE ID # 镜像的id
#CREATED # 镜像的创建时间
#SIZE # 镜像的大小
#2.可选项(常用的2个)
Options:
-a, --all Show all images (default hides intermediate images) #列出所有镜像
-q, --quiet Only show numeric IDs # 只显示镜像的id
#3.示例
# docker images -a #列出所有镜像详细信息
# docker images -aq #列出所有镜像的id
搜索镜像
比如搜索mysql
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker search mysql
#1.可选参数filter
Options:
-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
# --filter=STARS=3000 #过滤,搜索出来的镜像收藏STARS数量大于3000的
#2.示例:
# docker search mysql --filter=STARS=3000
下载镜像
# 下载镜像 docker pull 镜像名[:tag]
#上方的tag表示的是镜像的版本,如果不加就是默认下载的最新版
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker pull mysql
Using default tag: latest #下载的最新版
latest: Pulling from library/mysql
69692152171a: Pull complete #分层下载: docker image 的核心 联合文件系统
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
f7fddf10c2c2: Pull complete
16415d159dfb: Pull complete
0e530ffc6b73: Pull complete
b0a4a1a77178: Pull complete
cd90f92aa9ef: Pull complete
Digest: sha256:d50098d7fcb25b1fcb24e2d3247cae3fc55815d64fec640dc395840f8fa80969#签名,防伪标志
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest#真实地址
#知道真实地址:
#所以docker pull mysql等价于docker pull docker.io/library/mysql:latest
如要下载指定版本(tag的数据),在dockerhub上边一定要是可以查询到的
咱们尝试一下,下载mysql5.7
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
#看到没,下方显示的是已存在,这就是分层下载的好处
#由于我们之前安装过mysql,现在安装mysql5.7版本就只下载与之前不一样的部分即可
#极大的节省内存空间
69692152171a: Already exists
1651b0be3df3: Already exists
951da7386bc8: Already exists
0f86c95aa242: Already exists
37ba2d8bd4fe: Already exists
6d278bb05e94: Already exists
497efbd93a3e: Already exists
a023ae82eef5: Pull complete
e76c35f20ee7: Pull complete
e887524d2ef9: Pull complete
ccb65627e1c3: Pull complete
Digest: sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
此命令可以删除镜像
#1.首先我们查询出docker中的镜像
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 2c9028880e58 4 weeks ago 447MB
mysql latest c0cdc95609f1 4 weeks ago 556MB
hello-world latest d1165f221234 3 months ago 13.3kB
#2.删除镜像,可以通过REPOSITORY或者IMAGE ID来删除
docker rmi -f 镜像id #删除指定id的镜像
#咱们尝试通过mysql5.7的image id来删除它
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker rmi -f 2c9028880e58
Untagged: mysql:5.7
Untagged: mysql@sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Deleted: sha256:2c9028880e5814e8923c278d7e2059f9066d56608a21cd3f83a01e3337bacd68
Deleted: sha256:c49c5c776f1bc87cdfff451ef39ce16a1ef45829e10203f4d9a153a6889ec15e
Deleted: sha256:8345316eca77700e62470611446529113579712a787d356e5c8656a41c244aee
Deleted: sha256:8ae51b87111404bd3e3bde4115ea2fe3fd2bb2cf67158460423c361a24df156b
Deleted: sha256:9d5afda6f6dcf8dd59aef5c02099f1d3b3b0c9ae4f2bb7a61627613e8cdfe562
#3.了解删除全部镜像的命令
docker rmi -f $(docker images -aq) #删除全部的镜像
#通过docker images -aq查询出来的所有镜像进行删除
说明:我们有了镜像才可以创建容器,Linux,下载centos镜像来学习
docker pull centos
主要命令一览:
docker run 镜像id #新建容器并启动
docker ps 列出所有运行的容器 docker container list
docker rm 容器id #删除指定容器
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
主要命令介绍:
docker run [可选参数] image | docker container run [可选参数] image
#参书说明
--name="Name" #容器名字,比如:tomcat01 tomcat02 用来区分容器
-d #后台方式运行
-it #使用交互方式运行,进入容器查看内容
-p #指定容器的端口,-p 8080(宿主机):8080(容器)
#-p,这个是小写p。主要用法有几种:
#1.-p 主机端口:容器端口(常用)
#2.-p 容器端口
#3.容器端口
#4.-p ip:主机端口:容器端口
-P #随机指定端口
测试:
#一:测试:
#1.使用命令运行并进入容器,通过的是bash命令
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -it centos bin/bash
#2.注意看上方的主机名变为了7000b6708eea,其实这个就是centos的image id
[root@7000b6708eea /]#
#3.咱们尝试使用ls命令查看容器内部的centos,结果发现和主机的目录是相差无几
[root@7000b6708eea /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
#4.退出容器到主机
[root@7000b6708eea /]# exit
exit
[root@iZ2vc28obhvfham8wewhh0Z ~]#
主要命令介绍:
docker ps 命令 #列出当前正在运行的容器
-a, --all #列出当前正在运行的容器 + 历史运行过的容器
-n=?, --last int #列出最近创建的?个容器 ?为1则只列出最近创建的一个容器,为2则列出2个
-q, --quiet #只列出容器的编号
exit #容器直接退出
ctrl +P +Q #容器不停止退出 ---注意:这个很有用的操作
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf
docker rm -f $(docker ps -aq) #删除所有的容器,又是参数传递方式,搜出来的结果删
docker ps -a -q|xargs docker rm #删除所有的容器
#xargs命令也是一个个的删除,这里的|是管道符,学linux的时候提过
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器
# 命令 docker run -d 镜像名
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -it centos bin/bash
#测试:
#1.后台运行centos
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -d centos
dfec0e9a77be8a277779477dc0d5d74b2be42e182cd4cd62efa92547f6833b3a
#2.查看运行中的容器,发现没有
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 问题docker ps. 发现centos 停止了
# 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止。
#Docker容器后台运行,必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如运行ping,sleep),就是会自动退出的。
#(这样想docker发现启动了也提供不了服务,没有东西需要它就自己关闭了,即是快速开,快速关)
# 比如nginx,容器启动后,发现自己没有提供服务,就会立刻停止自杀,就是没有程序了
#1.查看
docker logs --help
#可选项,非常多啊
Options:
--details Show extra details provided to logs
* -f, --follow Follow log output
--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
* --tail string Number of lines to show from the end of the logs (default "all")
* -t, --timestamps Show timestamps
--until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
➜ ~ docker run -d centos /bin/sh -c "while true;do echo 6666;sleep 1;done" #模拟日志
#2.显示日志
-tf #显示日志信息(一直更新)
--tail number #需要显示日志条数
docker logs -t --tail n 容器id #查看n行日志
docker logs -ft 容器id #跟着日志
# 命令 docker top 容器id
# 命令
docker inspect 容器id
#查看元数据
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker inspect 0694e2e1032c
[
{
"Id": "0694e2e1032cc54a101e50adbab5f72a447525f5604b0201ac933e3800c2928d",
"Created": "2021-06-11T09:12:42.494496381Z",
"Path": "bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 2225148,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-06-11T09:12:43.695461095Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55",
"ResolvConfPath": "/var/lib/docker/containers/0694e2e1032cc54a101e50adbab5f72a447525f5604b0201ac933e3800c2928d/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/0694e2e1032cc54a101e50adbab5f72a447525f5604b0201ac933e3800c2928d/hostname",
"HostsPath": "/var/lib/docker/containers/0694e2e1032cc54a101e50adbab5f72a447525f5604b0201ac933e3800c2928d/hosts",
"LogPath": "/var/lib/docker/containers/0694e2e1032cc54a101e50adbab5f72a447525f5604b0201ac933e3800c2928d/0694e2e1032cc54a101e50adbab5f72a447525f5604b0201ac933e3800c2928d-json.log",
"Name": "/crazy_tereshkova",
"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,
"CgroupnsMode": "host",
"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/09513686c655ebe17e0790eb3d32108bd6b152427072c49bb9a3d561d76f9d54-init/diff:/var/lib/docker/overlay2/ad0b9110de723291fa2fb4bc89a3ab11dac79ed0f77dad963ac3e7d7ef35d837/diff",
"MergedDir": "/var/lib/docker/overlay2/09513686c655ebe17e0790eb3d32108bd6b152427072c49bb9a3d561d76f9d54/merged",
"UpperDir": "/var/lib/docker/overlay2/09513686c655ebe17e0790eb3d32108bd6b152427072c49bb9a3d561d76f9d54/diff",
"WorkDir": "/var/lib/docker/overlay2/09513686c655ebe17e0790eb3d32108bd6b152427072c49bb9a3d561d76f9d54/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "0694e2e1032c",
"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": "20201204",
"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": "ba1eb305552ee290cd4ecc492737310fca79864556f11e03c60e506652238a8e",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/ba1eb305552e",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "8a73cec4bec6a1d7e7e29754cca64cd046bb24f1f72243f97da44f26d90683da",
"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": "0324214c08ea6d191e80bea1165d5da073963b214d35d17423b9baedab404824",
"EndpointID": "8a73cec4bec6a1d7e7e29754cca64cd046bb24f1f72243f97da44f26d90683da",
"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
}
}
}
}
]
#我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
#====================方式一====================
#1.命令
docker exec -it 容器id bashshell
#2.测试
#进入容器
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it 0694e2e1032c bin/bash
#进入容器之后我们想干嘛干嘛,比如使用ls命令查看东西之类
[root@0694e2e1032c /]# ls
bin etc lib lost+found mnt proc run srv tmp var
dev home lib64 media opt root sbin sys usr
#====================方式二====================
#1.命令
docker attach 容器id
#2.测试
docker attach 0694e2e1032c
正在执行当前的代码...
#方式一喝方式二的区别
#docker exec #进入当前容器后开启一个新的终端,可以在里面操作。(常用)
#docker attach # 进入容器正在执行的终端,不会启动新的进程
#1.命令
docker cp 容器id:容器内路径(文件名) 主机目的路径
#2.测试
docker cp 0694e2e1032c:/hello.java /home
#将容器内部的/hello.java移动到主机的/home目录下,即使容器关闭了,也可以拷贝出来
#拷贝是一个手动过程,未来我们使用-v卷的技术,可以实现自动同步
图中的Container以及images的些许命令我们已经学过了,注意看图中的命令吧好多过了一遍了
命令大全
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
安装过程
#1. 搜索镜像 search 建议大家去docker搜索,可以看到帮助文档
docker search nginx
#2. 拉取下载镜像 pull
docker pull nginx
#3. 查看是否下载成功镜像
docker images
#4. 运行nginx
# -d 后台运行
# --name 给容器命名
# -p 宿主机端口:容器内部端口
docker run -d --name nginx01 -p 3344:80 nginx
#也就是说我们可以通过公网的3344,访问到docker的80
#5. 查看正在启动的镜像
docker ps
#6. 测试
#curl命令,利用URL规则在命令行下工作的文件传输工具
#如:curl http://www.linux.com,执行后,www.linux.com 的html就会显示在屏幕上了
#下方访问的是3344端口,显示的是nginx的网页代码,测试完毕
[root@iZ2vc28obhvfham8wewhh0Z ~]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#7. 进入容器,查看信息
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it nginx01 /bin/bash
root@8d0bb7bed5f2:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@8d0bb7bed5f2:/# cd /etc/nginx
root@8d0bb7bed5f2:/etc/nginx# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
#注意nginx.conf,就是配置文件
宿主机端口 和 容器内部端口 以及端口暴露:
外网:即是linux外部的网络
阿里云的安全组:阿里云的端口要从这里开放,比如开放了3344。
防火墙3344:是linux内部的防火墙开启了3344端口
-p 3344:80:通过这个操作,暴露端口,我们宿主机的3344就能访问到容器的80端口
现在有一个大大的linux,linux中有个防火墙开启了3344端口,docker服务里边有很多个容器,容器类似于一个独立的小的linux环境,所以有一个小的防火墙,开启了80端口。咱们是外网,先访问阿里云安全组的3344端口,看看端口有没有问题,没有就进入到linux的3344端口,然后通过-p 3344:80使得linux的3344端口可以访问到容器内部的80端口,最终到达Nginx。
测试一下3344端口:
**问题:**我们每次改动nginx配置文件,都需要进入容器内部?十分麻烦,我要是可以在容器外部提供一个映射路径,达到在容器外部修改文件,容器内部就可以自动修改?-v 数据卷 技术!(后面会讲到就是容器的文件目录挂载到宿主机实现数据的保存)
# 下载 tomcat9.0
# 命令:docker run -it --rm 镜像名,注意看命令中带有了--rm,表示用完就删除
# 之前的启动都是后台,停止了容器,容器还是可以查到还存在,一般是用来测试,用完就删除
#1. 下载tomcat最新版
docker pull tomcat
#2. 查看下载的镜像
docker images
#3. 以后台方式,暴露端口方式,启动运行
docker run -d -p 3355:8080 --name tomcat02 tomcat
#4. 测试访问有没有问题
curl localhost:3355 #测试没问题,但是外网访问的话是404,这个问题需要下面的第七步解决
#5. 根据容器id进入tomcat容器
docker exec -it 1c9d3fc1dac5 /bin/bash
#6. 其实这个tomcat是阉割版
# 发现问题:1、linux命令少了。 2.webapps目录为空
# 原因:阿里云镜像的原因,阿里云默认是最小的镜像,所以不必要的都剔除掉
# 保证最小可运行的环境!
# 解决方案:
# 将webapps.dist下的文件都拷贝到webapps下即可
#7. 将webapps.dist下的文件都拷贝到webapps下
#进入容器
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it 1c9d3fc1dac5 /bin/bash
#查看文件目录,含有webapps.dist
root@1c9d3fc1dac5:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
#将webapps.dist所有东西复制到webapps文件夹中
root@1c9d3fc1dac5:/usr/local/tomcat# cp -r webapps.dist/* webapps
问题:我们以后要部署项目,如果每次都要进入容器是不是十分麻烦?要是可以在容器外部提供一个映射路径,比如webapps,我们在外部放置项目,就自动同步内部就好了!
# 下方的命令是dockerhub上边的官方启动命令
#1. --net somenetwork,这个是网络配置,之后再讲
#2. -p 9200:9200 -p 9300:9300,暴露了9200和9300端口
#3. "discovery.type=single-node",这个是一个集群,表示单个节点
#4. :tag,最新的版本·
docker run -d --name elasticsearch --net somenetwork -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:tag
咱们开始操作:
#1. 使用简化版命令启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
#启动了很可能会卡,我们查看一下CPU的状态
docker stats
#也可以停止一些
docker stop 镜像id
#2. 测试一下es是否成功启动
[root@iZ2vc28obhvfham8wewhh0Z ~]# curl localhost:9200
{
"name" : "9e8f30f010b9",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "N_kPtsMqT4u0eYSeCtczJg",
"version" : {
"number" : "7.6.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
"build_date" : "2020-03-26T06:34:37.794943Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
#3. 测试成功就关掉elasticSearch,防止耗内存,正常来说要关半天,太卡了。后悔启动了草
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker stop 0694e2e1032c
0694e2e1032c
#测试成功就关掉elasticSearch,可以看出elasticsearch非常占内存,我们可以修改配置文件,进行限制内存使用#修改配置文件 -e 环境配置修改
# 在我们之前的启动命令中加入:-e ES_JAVA_OPTS="-Xms64m -Xmx512m",限定内存在64mb-512mb之间
docker run -d --name elasticsearch2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
#再次查看docker stats,发现变小了,非常爽到
作业三:使用kibana连接es (elasticSearch)?思考网络如何才能连接
现在elasticsearch容器和kibana容器都是相互隔离的,elasticsearch和kibana都有各自的内部地址。我们可以通过Linux的内网的ip作为一个中间商就可以实现elasticsearch到kibana访问,但是会涉及到Docker的网络相关的知识,在之后讲解。(请记住veth-pair)
portainer(先用这个,不是最佳选择)
# -v,挂载
# privileged,授权
docker run -d -p 8080:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Rancher(CI/CD再用)
Docker图形化界面管理工具!提供一个后台面板供我们操作!
使用命令启动portainer
# -v,挂载
# privileged,授权
docker run -d -p 8080:9000 \
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
外网访问8080端口(记得阿里云安全组打开8080端口),然后设置密码
选择本地
然后进入管理页面,可以查看相关信息(使用较少)
首先明确这个概念,然后我们下载的时候看到的一层层的就是这个
UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下( unite several directories into a single virtual filesystem)。
Union文件系统是 Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。接下来明确两个名词概念:
接下来我们看个图:
平时我们安装进虚拟机的Centos都是好几个G,为什么Docker这里只有200M?
对于一个精简的OS(操作系统),rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel(主机的内核),自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致的, rootfs会有差別,因此不同的发行版可以公用bootfs。所以说虚拟机是分钟级别,容器是秒级!
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载
思考:为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。
咱们使用docker image inspect tomcat,查看一下分层,主要看一下layers
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker image inspect tomcat
[...
"RootFS": {
"Type": "layers",
"Layers": [#以下的就相当于是一个个的记录,有10条,对应上方的10条pull complete
"sha256:688e187d6c79c46e8261890f0010fd5d178b8faa178959b0b46b2635aa1eeff3",
"sha256:00bcea93703b384ab61d2344d6e721c75b0e47198b7912136a86759d8d885711",
"sha256:ccb9b68523fdb47816f2a15d7590d06ff3d897dfdb3e0733e9c06a2bb79ebfc7",
"sha256:685934357c8993799eda4a6d71c2bb2d2c54b1138d6e037f675eeeeffc719f2d",
"sha256:3fc095fab4a2bec54616a8f5c20c43a9fe197ad06c2cf81385578dfe79aed238",
"sha256:6f770cdc9ebf757c2f2f6395c3cdb6f4298f5860727de340890a9a855e168e6e",
"sha256:15786a1cf1cbf50fea509d04227d327416c7c0c8b42b9488b56416095ba2f434",
"sha256:8f8b5acac684a1fb664c6301413fd28d50ac0f28c7fb8a01c24eee6cd4799739",
"sha256:3307ffa538c1bbc8f7d1cf8a5f0fbcd08634a7001dbf92c619e7720fb334df70",
"sha256:daf63ef0ddbb5fd50852b4bfc2f5f9fd0be4923819608d4f6051fc23809985c9"
]
}...
]
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或培加新的内容时,就会在当前镜像层之上,创建新的镜像层
举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而将这两个层进行打包之后,镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版
这种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中
下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图。
Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层(无法改变的,从远程pull的)!
相当于咱们pull的tomcat是只读的,然后我们要进行操作的话,也就是我们使用run命令去启动的时候,相当于新加了一层,新的这一层来进行操作。
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
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们我们使用虚拟机的快照。对应tag,因为tag可以自定义,以后我们可以自定义1.0版本或者2.0版本。
docker的理念是将应用和环境打包成一个镜像!
如果数据都在容器中,那么我们容器删除,数据就会丢失!所以我们就有需求:数据可以持久化
比如:安装了MySQL,容器删除了,相当于删库跑路!所以我们就有需求:MySQL数据可以存储在本地!
所以我们需要容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!说白了就是目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
将mysql容器内部的文件系统映射(挂载)到linux上边,实现数据的持久化和同步
#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部分,以后两个地址的内的数据可以相互同步的
#4. 测试文件是否相互同步,看图
#5. 再来测试!
1、停止容器
2、宿主机修改文件(修改之前的test.java文件,向内部添加“hello,linux update”)
3、再次启动容器
4、容器内的数据依旧是同步的
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
思考:MySQL的数据持久化的问题
#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端口,所以说我们本质还是访问到的容器
#4. 咱们测试一下本地创建数据库,远程能否生成
#4-1. 使用navicat创建数据库hahahaha
#4-2. 使用xshell进入/home/mysql/data目录查看
总结:通过这样的操作就可以一定程度上保证数据不会丢失,同时以后启动容器也可以使用此数据
理解概念:
#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"
}
]
所有的docker容器内的卷,没有指定目录的情况下都是在**/var/lib/docker/volumes/自定义的卷名/_data**下,咱们使用最多的也是具名挂载。
总结:
# 三种挂载: 匿名挂载、具名挂载、指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的
拓展:
# 通过 -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就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
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:内部内容如下:
# dockerfile1内部内容如下,每个命令就是一层:
FROM centos # 当前这个镜像是以centos为基础的
#这里与阿狂不同,不加斜杠死活运行不了
#VOLUME ["volume01","volume02"]
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
#5. 查看镜像,发现自己创建的镜像成功,名为xixi/centos
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
#看!haha/centos,创建完毕
xixi/centos latest 0db8611ac208 2 minutes ago 209MB
tomcat 9 6654503f1940 46 hours ago 667MB
mysql 5.7 09361feeb475 2 days ago 447MB
nginx latest d1a364dc548d 4 weeks ago 133MB
tomcat latest c43a65faae57 6 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
#6. 我们查看一下目录
这个卷一定和外部有一个同步的目录!咱们之前写的是匿名挂载,如图:
#7. 查看一下卷挂载的路径,如下图所示:
docker inspect 自定义的镜像名字
假设构建镜像时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
说白了就是利用容器去给其他容器进行共享数据
比如:多个MySQL同步数据!
测试:
#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中查看,如下图
#5. 继续测试,创建一个docker0003,继承于docker0001,然后创建一个文件去查看docker0001的变化
#直接说结论:
#1. docker0003创建的文件,docker0001可以查询到,说明容器之间的数据形成了共享(本质是双向拷贝)
#2. 此时删除或者停掉docker0001,我们查看docker0002和docker0003的数据依旧能够查询到,说明数据形成了共享(本质是双向拷贝,容器之间的相互数据拷贝)
#3. 只要有一个容器还在用这组数据就不会丢失,很nice
结论:
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
dockerfile
是用来构建docker镜像的文件!命令参数脚本!
构建步骤:
我们查看一下官方是怎么做的,每一个镜像都是dockerfile构建的
注意看下图中红框部分,全是命令,一个命令一层,还记得吗
很多官方镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像!比如:centos+jdk+tomcat+redis等等
官方既然可以制作镜像,那我们也可以!
基础知识:
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:
#1. 编写dockerfile文件
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# vim dockerfile-test-cmd
#dockerfile-test-cmd的内容如下:
#---------------------
FROM centos
CMD ["ls","-a"] # 启动后执行 ls -a 命令
#---------------------
#2. 构建镜像
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker build -f dockerfile-test-cmd -t cmd-test:0.1 .
#3. run命令执行,发现”ls -a“的命令生效
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker run cmd-test:0.1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
#4. 此时如果我们想追加一个"-l"命令,我们期望能实现"ls -al"的效果
# 动了小脑筋感觉可以这样写“docker run 镜像id -l”,但是这样写是会报错的
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker run cmd-test:0.1 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
#分析:在使用cmd的情况下“-l”替换了CMD的["ls","-a"]命令,但是“-l”不是命令,所以报错
#请带着这个问题去测试ENTRYPOINT
测试ENTRYPOINT:
#1. 编写dockerfile文件
vim dockerfile-test-entrypoint
#dockerfile-test-entrypoint的内容如下:
#---------------------
FROM centos
ENTRYPOINT ["ls","-a"] #这里与之前不一样哦(☆)
#---------------------
#2. 构建镜像
docker build -f dockerfile-test-entrypoint -t entrypoint-test:0.1 .
#3. 运行镜像
docker run entrypoint-test:0.1
#4. 然后重头戏来了,请对照之前的cmd
#我们的命令,是直接拼接在我们得ENTRYPOINT命令后面的
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker run entrypoint-test:0.1 -l
total 0
drwxr-xr-x 1 root root 6 Jun 27 13:13 .
drwxr-xr-x 1 root root 6 Jun 27 13:13 ..
-rwxr-xr-x 1 root root 0 Jun 27 13:13 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Jun 27 13:13 dev
drwxr-xr-x 1 root root 66 Jun 27 13:13 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 157 root root 0 Jun 27 13:13 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 13:13 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
总结:
#dockerfile-test-cmd的内容如下:
CMD ["ls","-a"]
#dockerfile-test-entrypoint的内容如下:
ENTRYPOINT ["ls","-a"]
#使用追加命令,CMD不行,ENTRYPOINT可以!
#ENTRYPOINT大胜利!!!
Dockerhub中99%的镜像都是由FROM scratch
开始的,然后配置需要的软件和配置来进行构建。
#1./home下新建dockerfile目录,并进入
[root@iZ2vc28obhvfham8wewhh0Z home]# mkdir dockerfile
[root@iZ2vc28obhvfham8wewhh0Z home]# cd dockerfile/
#2. dockerfile目录下新建mydockerfile-centos文件,填写内容如下:
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# vim mydockerfile-centos
mydockerfile-centos内容如下:
FROM centos # 基础镜像是官方原生的centos
MAINTAINER peng<951770031@qq.com> # 作者
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
#3. 通过mydockerfile-centos文件构建镜像
#语法:docker build -f dockerfile的文件路径 -t 镜像名:[tag] .
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker build -f mydockerfile-centos -t mycentos:0.1 .
#返回以下信息,表示创建成功
Successfully built f6d21f2d2179
Successfully tagged mycentos:0.1
#4. 查看我们构建的镜像
[root@iZ2vc28obhvfham8wewhh0Z dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 0.1 f6d21f2d2179 3 minutes ago 295MB
xixi/centos latest 6ce95e6fc524 2 hours ago 209MB
haha/centos latest 0db8611ac208 33 hours ago 209MB
#5. 使用run命令启动,发现可以使用vim以及ifconfig命令,与之前的阉割版centos完全不同(不再演示)
#6. 查看镜像的构建过程,看它如何一步步的构建的(不再演示)
#命令:docker history 镜像id
编写dockerfile文件:如果dockerfile的名称为"Dockerfile",build会自动找寻这个文件,不需要再去使用"-f"指定
#1. 创建Dockerfile文件,官方建议名称为Dockerfile
[root@iZ2vc28obhvfham8wewhh0Z hahapeng]# vim Dockerfile
#Dockerfile的内容如下:
#-----------------------------------
# 基础镜像centos
FROM centos
# 作者信息编写
MAINTAINER peng<951770031@qq.com>
# 复制当前目录下readme.txt文件,到容器/usr/local中
COPY readme.txt /usr/local/readme.txt
# 添加jdk,ADD 命令会自动解压到/usr/local目录
ADD jdk-8u291-linux-x64.tar.gz /usr/local/
# 添加tomcat,ADD 命令会自动解压到/usr/local目录
ADD apache-tomcat-9.0.46.tar.gz /usr/local/
# 安装 vim 命令
RUN yum -y install vim
# 设置MYPATH
ENV MYPATH /usr/local
# 工作目录,引用MYPATH
WORKDIR $MYPATH
# 配置环境变量:JAVA_HOME环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_291
# 配置CLASSPATH
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# 环境变量: tomcat环境变量
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.46
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.46
# 设置环境变量 分隔符是:
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 设置暴露的端口
EXPOSE 8080
# 设置默认命令,这里设置了启动指定目录下的startup.sh程序以及日志
CMD /usr/local/apache-tomcat-9.0.46/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.46/logs/catalina.out
#-----------------------------------
#2. 创建一个readme.txt的文件
touch readme.txt
构建镜像
# 因为我们之前用的"Dockerfile"作为名称,因此不用使用-f 指定文件
docker build -t hahatomcat:0.1 .
# 然后漫长的等待,直到返回如下信息:
Successfully built e40a2847610d
Successfully tagged hahatomcat:0.1
run镜像
# -d:后台运行 -p:暴露端口 --name:别名 -v:绑定路径(挂载)
docker run -d -p 8080:8080 --name tomcat01
-v /home/kuangshen/build/tomcat/test:/usr/local/apache-tomcat-9.0.46/webapps/test
-v /home/kuangshen/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.46/logs hahatomcat:0.1
#以后我们直接把写的项目复制到挂载的目录下,就自动的同步到容器中了,非常方便
访问测试
docker exec -it 自定义容器的id /bin/bash
cul localhost:8080
发布项目
由于做了卷挂载,我们直接在本地(挂载位置)编写项目就可以发布了!
发现:项目部署成功,可以直接访问!
我们以后开发的步骤:需要掌握Dockerfile的编写!我们之后的一切都是使用docker镜像来发布运行!
去dockerhub官方网站注册账号https://hub.docker.com/
确定此账号是可以登录的
在xshell里边进行登录:
#1. 输入登录命令
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker login -u lemonyuki
#2. 弹出提示输入密码,密码输入不会显示
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
#3. 登录成功
Login Succeeded
[root@iZ2vc28obhvfham8wewhh0Z ~]#
然后我们进行镜像的发布操作
#1. 查看镜像
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hahatomcat 0.1 e40a2847610d 18 hours ago 646MB
...
#2. 重命名镜像
# 一般来说我们采用“账号ID名字/镜像名字:[tag]”的格式,这样能保证不重名,docker就能发布成功
# 修改名称的语法:docker tag 原镜像名称:tag 新镜像名称:tag
#将hahatomcat修改为lemonyuki/hahatomcat
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker tag hahatomcat:0.1 lemonyuki/hahatomcat:0.1
#3. 再次查看镜像,发现名称修改成功(本质应该是新建镜像)
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
lemonyuki/hahatomcat 0.1 e40a2847610d 19 hours ago 646MB
hahatomcat 0.1 e40a2847610d 19 hours ago 646MB
...
#4. 我们再次push镜像,成功!
#吐槽:push了我一年草,太慢了,吃了个饭都没push好
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker push lemonyuki/hahatomcat:0.1
The push refers to repository [docker.io/lemonyuki/hahatomcat]
4210e5dcae85: Pushed
1016adb67e5a: Pushed
fe0df3a669d3: Pushed
7a2caadd01d0: Pushed
2653d992f4ef: Pushed
0.1: digest: sha256:384dc321b5bc31aabf5d1af8e7d5d10d49fcea85b1b97b10c44fe15313905967 size: 1373
直接上图,上传完毕
登录阿里云
找到容器镜像服务
如果有创建个人实例就创建,然后设置镜像仓库的密码
创建容器命名空间
创建镜像仓库,然后选择本地仓库即可
点击你创建的仓库,即可在阿里云官网看到使用方法
开始操作
#1. 首先咱们登录
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker login --username=长门只有a registry.cn-hangzhou.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
#2. 然后咱们push
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker tag e40a2847610d registry.cn-hangzhou.aliyuncs.com/lemonyuki/lemontest:0.1
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker push registry.cn-hangzhou.aliyuncs.com/lemonyuki/lemontest:0.1
发布成功后,会出现
现在看这个图,问题不大。图中的save和load是本地的镜像压缩备份,我们一般选择push直接上传到dockerhub或者阿里云
学习之前清空下前面的docker 镜像、容器
# 删除全部容器
$ docker rm -f $(docker ps -aq)
# 删除全部镜像
$ docker rmi -f $(docker images -aq)
测试:
这里有三个网络
问题: docker 是如何处理容器网络访问的?
比如现在有一个tomcat,它是如何连接到mysql的
#1. 咱们现在来启动一个tomcat
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -d -P --name tomcat01 tomcat
#启动完毕之后,我们思考一下能不能ping通
#2. 查看容器内部网络地址
#语法:docker exec -it 容器id ip addr
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it bb3980f7b3fb ip addr
#结果如下图所示:
#发现容器启动的时候会得到一个 eth0@if61 的ip地址,这个是docker分配的,每个容器都会有这样的一个地址!
#然后咱们思考:linux能不能ping通容器内部! 可以 容器内部可以ping通外界吗? 可以!
[root@iZ2vc28obhvfham8wewhh0Z ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.058 ms
我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0(桥接模式),使用的技术是veth-pair技术!
#我们发现这个容器带来网卡,都是一对对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
#情况一:路由器可以直接去访问容器
#情况二:容器之间的访问,比如Tomcat01去访问Tomcat02,路由器就是作为一个中间商
#Tomcat01和Tomcat02是共用的一个路由器,docker0
#所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0,如下图所示:
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(比如:内网传递文件)
只要容器删除,对应的网桥一对就没了!
思考一个场景:我们编写了一个微服务,我们以前连接数据库都是database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
# 1.发现问题:使用名字去ping,ping不通
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
#2. 我们再次启动一个tomcat03,但是使用一个"--link"命令与tomcat02连接启动
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
#3. 然后我们使用ping命令看看tomcat03和tomcat02之间能否ping通,成功!
#注意:我们是直接使用的名字去ping
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.086 ms
...
#4. tomcat02去ping tomcat02不能ping通,失败!
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
#1. 查看网络
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
a46c8b6812aa bridge bridge local
eb05dd76e396 host host local
f5d08c983d19 none null local
#2. 查看一下bridge的信息,如下图所示
#语法:docker network inspect 网络id
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker network inspect a46c8b6812aa
#3. 我们查看一下tomcat03的信息,如下:
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker inspect a49e4b731970
#4. 我们还可以去/etc/hosts查询到绑定的信息
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it tomcat03 cat /etc/hosts
-–link 本质就是在hosts配置中添加映射,现在使用Docker已经不建议使用–-link了!
我们现在需要高级的东西,即自定义网络,就不使用docker0了!因为docker0有问题:即不支持使用容器名连接访问!
查看所有的docker网络:
网络模式:
测试:
# 我们直接启动的命令 --net bridge,而这个就是我们的docker0
# bridge就是docker0
#"--net bridge"就是默认参数
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
#------------------------------------------------------
#------------------------------------------------------
#自定义网络:
#1. 清理环境,删除之前的容器
docker rm -f $(docker ps -aq)
#2. 创建一个子网为“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
#3. 查看创建的网络
docker network ls
#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
#发现容器使用的是我们配置的网络
#6. 我们再来ping容器
docker exec -it tomcat-net-01 ping tomcat-net-02
docker exec -it tomcat-net-01 ping 192.168.0.3
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
原理:
测试:
#语法:docker network connect [OPTIONS] NETWORK CONTAINER
#1. 之前删除的tomcat01和tomcat02创建好
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat02 tomcat
#2. 打通tomcat01和mynet
docker network connect mynet tomcat01
#3. 查看网络配置,如下图所示:
docker network inspect mynet
# 要将tomcat01 连通 tomcat—net-01 ,连通就是将 tomcat01加到 mynet网络
# 一个容器两个ip(tomcat01)
#4. 现在我们再ping一下
[root@iZ2vc28obhvfham8wewhh0Z ~]# docker exec -it tomcat01 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.101 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.083 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.079 ms
**结论:**假设要跨网络操作别人,就需要使用docker network connect 连通!
#1. 先移除之前的容器
docker rm -f $(docker ps -aq)
#2. 创建redis的网卡
docker network create redis --subnet 172.38.0.0/16
#3. 通过脚本去写配置文件
for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >> /mydata/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
#4. 通过脚本创建六个redis文件
for port in $(seq 1 6);\
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
#5. 然后依次运行
docker exec -it redis-1 /bin/sh
docker exec -it redis-2 /bin/sh
docker exec -it redis-3 /bin/sh
docker exec -it redis-4 /bin/sh
docker exec -it redis-5 /bin/sh
docker exec -it redis-6 /bin/sh
#6. 创建集群
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
#通过java8来构建基础镜像
FROM java:8
#将当前目录下的所有jar包拷贝到镜像根目录,并重新命名为app.jar
COPY *.jar /app.jar
CMD ["--server.port=8080"]
#暴露8080端口
EXPOSE 8080
#执行目录下的app.jar,这样我们的jar包就跑起来了
ENTRYPOINT ["java","-jar","app.jar"]
#1. 然后使用命令建立一个镜像
docker build -t xxxxx:xx .
#2. 运行镜像
docker run -d -P --name XXXX
#3. 然后直接访问即可
curl localhost:XXXX/hello
以后我们使用了Docker之后,给别人交付就是一个镜像即可!
预告:如果有很多镜像?100个镜像怎么办?难道还是一个个的去bulid和run吗