Docker概述及使用
Docker入门
Docker概述
为什么会出现Docker?
*两套环境,配置繁琐,集群搭错一个地方只有推倒重来,重复工作太多*
Docker的思想就是隔离。
JRE–多个应用(端口冲突)----原来都是交叉的!
隔离:Docker核心思想!打包装箱!每个箱子都是互相隔离的。
Docker通过隔离机制,可以将服务器利用到极致!
本质:所有的技术的出现都是因为产生了问题,去解决问题才出现的。
虚拟机:在windows中装一个VMware,通过这个软件我们可以虚拟出来一台或地平台电脑!笨重!
虚拟机是属于悉尼话技术,Docker容器技术,也是一种虚拟化技术!
VM: linux centos原生镜像(一台电脑)隔离,需要开机多个虚拟机! 最小几个G,开机要几分钟
docker:隔离,镜像(只要最核心的环境,最小为4M,在此基础上装所需要的软件+jdk+mysql)十分的小巧,运行镜像就可以启动! 最小几M,秒级启动
Docker是基于Go语言开发的!,开源项目!
Docker文档地址:https://docs.docker.com/
Docker仓库地址:https://hub.docker.com/
Docker能干嘛
虚拟机技术:这里的lib是运行所需要的库,可以更改
虚拟机缺点:
资源占用十分多(因为是一个电脑一个电脑的虚拟)
冗余步骤多
启动慢
容器化技术
容器化技术不是模拟的一个完整的操作系统
比较虚拟机和Docker的不同
传统虚拟机,虚拟出一整套硬件,运行一个完整的操作系统,然后再这个系统上安装和运行软件
容器是的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟的硬件,所以就轻便了,每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
Docker的基本组成
*镜像(image):*
Docker镜像就好比是一个模板,通过这个模板来创建容器服务,tomcat镜像===>run===>tomcat01容器(提供服务器),通过这个镜像可以创造多个容器(最终服务运行或项目运行就是在容器中)
*容器(container)*
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的。
启动,停止,删除,基本命令。
目前就开源把这个容器理解为就是一个简易的Linux系统
*仓库(repository):*
仓库就是存放镜像的地方。
仓库分为公有仓库和私有仓库
Docker Hub(默认是国外的下载镜像很慢)
阿里云…都有容器服务器(配置镜像加速)
总结:从仓库远程拉取一个镜像到本地,run镜像启动一个容器
底层原理
Docker是怎么工作的?
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socket客户端访问!
DockerServer接受到Docker-Client的指令,就会执行这个命令
Docker为什么比VM快?
1.Docker比VM有更少的抽象层
2.Docker利用宿主机的内核,VM是需要Guest OS(再搭建一个这样的环境)
所以说,新建一个容器的时候,docker不需要像虚拟机一样重新加载一个操作系统内核,避免引导,虚拟机加载的是Guest OS,分钟级别的,而Docker是利用宿主机的操作系统,省略了这个复杂的过程,秒级!
Docker安装
内核是3.10以上的
uname -r
- 卸载旧的版本(粘贴,复制)
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
- 需要安装包
yum install -y yum-utils
- 设置镜像的仓库,这里的镜像地址更换为了阿里云
yum-config-manager \--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum makecache fast #更新索引再去安装
- 安装docker相关的内容,docker-ce 社区版 ee企业版
yum install docker-ce docker-ce-cli containerd.io
- 启动Docker
systemctl start docker
- 查看是否安装成功
docker versiondocker run hello-world
- 查看下载的镜像
docker images
卸载Docker:
- 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
- 删除目录
rm -rf /var/lib/docker
1.配置阿里云镜像加速器
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
2.配置使用
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF'{ "registry-mirrors": ["https://u4yijdry.mirror.aliyuncs.com"]}EOFsudo systemctl daemon-reloadsudo systemctl restart docker
Docker的常用命令:
帮助命令:
docker version #显示docker的版本信息docker info #显示docker的系统信息,包括镜像和容器的数量docker 命令 --help
镜像命令
[root@docker ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEhello-world latest bf756fb1ae65 5 months ago 13.3kB
#解释
REPOSITORY 镜像的仓库
TAG 镜像的标签
IMAGE ID 镜像的ID
CREATED 镜像的创建时间
SIZE 镜像的大小
#可选项
-a --all #列出所有镜像-q --quiet #只显示镜像的IDdocker search 镜像 #搜索镜像
#下载镜像*
docker pull mysql[:tag]
[root@docker ~]# docker pull mysqlUsing default tag: latest #如果不写tag,默认就是latestlatest: Pulling from library/mysql 8559a31e96f4: Pull complete #分层下载,docker image的核心,联合文件系统d51ce1c2e575: Pull complete c2344adc4858: Pull complete fcf3ceff18fc: Pull complete 16da0c38dc5b: Pull complete b905d1797e97: Pull complete 4b50d1c6b05c: Pull complete c75914a65ca2: Pull complete 1ae8042bdd09: Pull complete 453ac13c00a3: Pull complete 9e680cd72f08: Pull complete a6b5dc864b6c: Pull complete Digest: sha256:8b7b328a7ff6de46ef96bcf83af048cb00a1c86282bfca0cb119c84568b4caf6 #签名Status: Downloaded newer image for mysql:latestdocker.io/library/mysql:latest #真实地址# 两者相同
docker pull mysqldocker pull docker.io/library/mysql:latest
指定版本下载:
docker pull mysql:5.7docker rmi -f 镜像id #删除指定镜像docker rmi -f 镜像id 镜像id 镜像id #删除多个镜像docker rmi -f $(docker images -aq) #删除全部镜像
容器命令
docker pull centos #下载一个最新的centos镜像
docker run [可选参数] image\#参数说明--name=”Name” 容器名字,tomcat01,tomcat02 ,用来区分容器-d 后台方式运行-it 使用交互方式运行,进入容器查看内容-p 指定容器的端口 -p 8080:8080-p ip:主机端口:容器端口-p 主机端口:容器端口-p 容器端口-P 随机指定端口\#测试,启动并进入容器docker run -it 容器id/镜像名 /bin/bash
*退出容器*
[root@4bb285138de4 /]# exit #直接停止容器并退出
[root@docker ~]#
ctrl+P+Q #容器不停止退出
列出所有运行的容器
# docker ps 命令 # 列出当前正在运行的容器-a # 列出当前正在运行的容器+历史上运行过的容器-n=? # 显示最近创建的容器-q # 显示容器的编号
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bb285138de4 831691599b88 “/bin/bash” 8 minutes ago Exited (0) 5 minutes ago musing_ganguly
c5dc2112d9a9 bf756fb1ae65 “/hello” 3 hours ago Exited (0) 3 hours ago vibrant_wescoff
5b97245a8bc3 bf756fb1ae65 “/hello” 3 hours ago Exited (0) 3 hours ago vigilant_hertz
[root@docker ~]# docker ps -qa
4bb285138de4
c5dc2112d9a9
5b97245a8bc3
删除容器
docker rm 容器id #删除指定容器,不能删除正在运行的容器docker rm -f $(docker ps -aq) #删除全部容器
启动和停止容器的操作
docker start 容器id #启动容器docker restart 容器id #重启容器docker stop 容器id #停止当前正在运行的容器docker kill 容器id #强制停止当前容器
查看日志
docker logs -tf 容器id #显示日志docker logs -tf --tail number 容器id #显示日志条数,这里用number控制条数docker logs -tf --tail 10 dce7b8628bf
查看容器中的进程信息
[root@docker ~]# docker top 4bb285138de4
UID PID PPID C STIME TTY TIME CMD
root 8900 8884 1 22:36 pts/0 00:00:00 /bin/bash
查看镜像源数据
# 命令
docker inspect 容器id
#测试
[root@docker ~]# docker inspect 4bb285138de4[{ "Id": "4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04", "Created": "2020-06-29T10:18:02.112722322Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 8900, "ExitCode": 0, "Error": "", "StartedAt": "2020-06-30T02:36:03.304931826Z", "FinishedAt": "2020-06-29T10:20:35.269240929Z" }, "Image": "sha256:831691599b88ad6cc2a4abbd0e89661a121aff14cfa289ad840fd3946f274f1f", "ResolvConfPath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/resolv.conf", "HostnamePath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/hostname", "HostsPath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/hosts", "LogPath": "/var/lib/docker/containers/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04/4bb285138de45ed2dda34546ef8547d74fb5d5922acd3624ea9e3b93f53ded04-json.log", "Name": "/musing_ganguly", "RestartCount": 0, "Driver": "overlay2", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": {}, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "Capabilities": null, "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "private", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": null, "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DeviceRequests": null, "KernelMemory": 0, "KernelMemoryTCP": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": null, "OomKillDisable": false, "PidsLimit": null, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0, "MaskedPaths": [ "/proc/asound", "/proc/acpi", "/proc/kcore", "/proc/keys", "/proc/latency_stats", "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", "/proc/scsi", "/sys/firmware" ], "ReadonlyPaths": [ "/proc/bus", "/proc/fs", "/proc/irq", "/proc/sys", "/proc/sysrq-trigger" ] }, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2-init/diff:/var/lib/docker/overlay2/40b38560c9a02a744c2d0872ab2f4f93333ad65b400eb47b3fbb438b37aee7e1/diff", "MergedDir": "/var/lib/docker/overlay2/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2/merged", "UpperDir": "/var/lib/docker/overlay2/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2/diff", "WorkDir": "/var/lib/docker/overlay2/e4e3e63ccccc35fdca2128c7744aec95e5d9781177edcc86d47b43f543f67ef2/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "4bb285138de4", "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": "831691599b88", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20200611", "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": "6f0dae1a8a16719e2bda8f89811f3b71b43427286cd8b19cc7b65d5be420db15", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/6f0dae1a8a16", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "437e8b8ebf9b331a8ae0135dba22bb9d477bebff6ef8c52a2b6d7dcdd42bcd6e", "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": "2dc48a480bde9e7b163036eb12d8553dc6ed036754db8b16c9d9641631a51951", "EndpointID": "437e8b8ebf9b331a8ae0135dba22bb9d477bebff6ef8c52a2b6d7dcdd42bcd6e", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } }}]
进入当前正在运行的容器
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
#方法一:
#命令
docker exec -it 容器id /bin/bash
#测试
[root@docker ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES4bb285138de4 831691599b88 /bin/bash" 17 hours ago Up15minutes musing_ganguly[root@docker ~]# docker exec -it 4bb285138de4 /bin/bash[root@4bb285138de4 /]# ps -efUID PID PPID C STIME TTY TIME CMDroot 1 0 0 02:36 pts/0 00:00:00 /bin/bashroot 14 0 0 02:51 pts/1 00:00:00 /bin/bashroot 28 14 0 02:52 pts/1 00:00:00 ps -ef
#方法二:
docker attach 容器id
#测试
[root@docker ~]# docker attach 4bb285138de4
[root@4bb285138de4 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
docker exec #进入容器后开启一个新的终端,可以在里面操作(常用)dockers attach #进入容器正在执行的终端,不会启动新的进程!
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的主机路径
### #进入文件内部
[root@docker ~]# docker attach 4bb285138de4
\#在容器内新建一个文件
[root@4bb285138de4 home]# touch php
[root@4bb285138de4 home]# ls
php
[root@4bb285138de4 home]# exit
exit
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\#将文件拷贝出来到主机上
[root@docker ~]# docker cp 4bb285138de4:/home/php /home/
[root@docker ~]# cd /home/
[root@docker home]# ll
total 0
-rw-r--r--. 1 root root 0 Jun 29 23:02 java
-rw-r--r--. 1 root root 0 Jun 29 23:03 php
小结命令:
实战练习(命令)
1. Docker安装nginx
#1.搜索镜像 search 可以去官网看帮助文档
#2.下载镜像 pull
#3.运行测试
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
684d9e6fe265 nginx "/docker-entrypoint.…" 12 seconds ago Up 11 seconds 80/tcp nginx_02
ea6c5880e382 centos "/bin/bash" 4 hours ago Up 4 hours festive_curie
[root@docker ~]# docker stop 684d9e6fe265
684d9e6fe265
# -d 后台运行
# --name 给容器取名字
# -p 宿主机端口:容器内部端口
[root@docker ~]# docker run -d --name nginx_03 -p 3333:80 nginx
ee42a7ca71c3abdac85d57c0dfb8628ad05ff04c97fef13ab3e0a1b03797d225
[root@docker ~]# curl localhost:3333<!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>
# 进入容器
[root@docker ~]# docker exec -it nginx_03 /bin/bash
root@ee42a7ca71c3:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@ee42a7ca71c3:/# cd /etc/nginx/
root@ee42a7ca71c3:/etc/nginx# ls
conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf
2. 安装tomcat
# 官方的使用
docker run -it --rm tomcat:9.0
#我们之前的启动都是后台,停止了之后,容器还是可以查到 docker run -it --rm,一般用来测试,用完就删除,有点像闪照,看了就删除照片那种# 下载启动
docker run -d -p 3355:8080 --name tomcat01 tomcat# 测试访问没有问题
[root@docker ~]# docker run -d -p 3355:8080 --name tomcat2 tomcat
027d4e9990ef8d5121de2830acd8a86a82827987aa32ad5b9a3868644c6d823e
[root@docker ~]# docker exec -it tomcat2 /bin/bash404
# 发现问题:1.Linux命令少了 2.没有webapps,阿里云镜像的原因,默认是最小的镜像,所以不必要的都剔除掉了
# 保证最小可运行环境!解决:将webapps.dist目录下的文件copy到webapps或者将webapps.dist改名为webapps
问题
[root@docker ~]# docker run -d -p 3355:8080 --name tomcat1 tomcat
f667afe1fd92ccc511a718c4b785ea0759aeb95320379d2eca94c2d78460d156
docker: Error response from daemon: driver failed programming external connectivity on endpoint tomcat1 (d1bf00f22f86648a1a301376da8b802eece1d8727c981d2a267a33febf357215): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 3355 -j DNAT --to-destination 172.17.0.3:8080 ! -i docker0: iptables: No chain/target/match
解决办法:自定义docker连接断掉了,重启一下docker服务
3. 部署ES+kibana
# es 暴露的端口很多!
# es 十分的耗内存
# es 数据一般需要放置到安全目录!挂载
--net somenetwork ? 是一个网络配置#下载启动es
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2# 启动了 linux就卡住了 es是非常消耗内存的#查看cpu负载 docker stats (图在下面)# 测试一下es是否成功[root@docker ~]# curl localhost:9200
{"name" : "d0334d25bbef","cluster_name" : "docker-cluster","cluster_uuid" : "ag11yTCjQQGzAlWFhEbpHQ","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"
}
# LIMIT:总共内存# MEN USAGE:容器占用内存,可以看到es是占用的非常高了# 增加内存的限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPS="-Xms64m -Xmx512m" elasticsearch:7.6.2
作业:使用kibana连接es?思考网络是如何连接的?
可视化
portainer(先用这个)
docker run -d -p 8080:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Rancher(CI/CD再用)
什么是Portainer?
Docker图形化界面管理工具!提供一个后台面板供我们操作!
docker run -d -p 8080:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer# 访问测试# 浏览器访问 192.168.0.104:8080
选择本地
Docker镜像
镜像是什么?
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码,运行时,库,环境变量和配置文件
如何得到镜像
·从远程仓库下载
·朋友拷贝给你
·自己制作一个镜像DockerFile
Docker镜像加载原理
UnioFS(联合文件系统)
我们下载的时候看到的一层层就是这个东西(layer层)!
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS
bootfs主要包含bootloader(系统开机引导文件)kernel(内核)bootloader主要是引导加载kernel,Linux刚启动会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器的内核。当bootfs加载完成之后整个内核就都在内存中了,此时内存的使用权已经由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs,在bootfs之上,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件,rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等
对于精简的OS,rootfs可以很小,只需要报刊最基本的命令,工具和库就可以了,因为底层直接用Host的Kernel,自己只需要提供rootfs就可以了,由此课件对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs!!!
虚拟机是分钟级,容器是秒级启动!!!
层级:最底层是bootfs引导加载操作系统->rootfs加载操作系统发行版基础镜像(base image)->应用镜像(只读,多层)->容器层(可写)
分层理解
[root@docker ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
8559a31e96f4: Already exists
85a6a5c53ff0: Pull complete
b69876b7abed: Pull complete
a72d84b9df6a: Pull complete
5ce7b314b19c: Pull complete
04c4bfb0b023: Pull complete
Digest: sha256:800f2587bf3376cb01e6307afe599ddce9439deafbd4fb8562829da96085c9c5
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
思考:为什么Docker要采用这种分层结构呢?
最大的好处,莫过于是资源共享了!比如有多个镜像都从相同的Base镜像构建出来,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样久可以为所有的容器服务了,而且镜像的每一次都可以被共享,
查询镜像分层的方式可以通过docker image inspect 命令来查看!
[root@docker ~]# docker inspect redis:latest//..."RootFS": {"Type": "layers","Layers": ["sha256:13cb14c2acd34e45446a50af25cb05095a17624678dbafbcc9e26086547c1d74","sha256:e6b49c7dcaac7a2ec2acc379da5f5b1bcc6a5d3badd72814fe945296216557bd","sha256:cdaf0fb0082b74223a224c39c2d2ea886c32f53b7e1d5b872d5354aae0df56b8","sha256:72d3a7e6fe022824ee2f852ca132030e22c644fbaf8287f4ea8044268abe40b7","sha256:67c707dbd847d8310d3b988c3e3d9d9eb53387ede0de472e36a15abbcb6c719c","sha256:7b9c5be81844318508f57a5b0574822dabaaed3dc25ee35d960feec3a9e941c4"]},
分层特点:
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下都叫镜像层!
如何提交一个自己的镜像
commit镜像
docker commit 提交容器成为一个新的副本# 命令和git原理类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
实战测试:
# 1.启动一个默认的tomcat# 2.发现这个默认的tomcat是没用webapps应用,镜像的原因,官方的镜像默认webapps下面是没有文件的!# 3.我自己拷贝进去了基本的文件# 4.将我们操作过的容器通过commit提交为一个镜像!我们以后就是同我们修改过的镜像即可,这就是我们自己的镜像
如果你想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像,就好比我们学习VM的时候,快照!
Docker进阶
容器数据卷
docker的理念回顾
将应用和环境打包成一个镜像!
**问题:**数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!
需求:数据可以持久化
Mysql,容器删了,删库跑路!需求:Mysql数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录# 测试 绑定宿主机的/home/test与容器的/home目录
[root@docker home]# docker run -it -v /home/test:/home centos /bin/bash
# 容器中新建文件
[root@00cefe7f7e9d home]# touch test.java
[root@00cefe7f7e9d home]# ls
test.java
# 进入本地目录查看文件内容是否同步过来
[root@docker home]# cd test/
[root@docker ceshi]# ls
test.java
启动起来的时候我们可以通过命令:docker inspect 容器id
查看挂载情况
再来测试(本地修改文件,数据同步到容器中)!
1.停止容器
2.宿主机上修改文件内容
3.启动容器
4.容器内的数据依旧是同步的!!!
好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
实战:安装MySql
# 获取镜像
[root@docker ~]# docker pull mysql:5.7#运行容器,需要做数据挂载! # 安装启动mysql,需要配置密码,这是注意要点!!!# 官方测试: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag# 启动我们的mysql容器
-d 后台运行
-p 宿主机端口:容器端口 设置访问宿主机的段端口就能能访问到容器内的端口
-v 卷挂载
-e 环境配置 这里配置了mysql的密码
--name 容器的名字
[root@docker ~]# 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# 启动成功之后,我们在本地使用sqlyog来测试一下
#sqlyog-连接到服务器的3310 --- 3310和容器内的3306映射,这个时候我们就可以连接上了!# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
假设我们将容器删除
发现,我们挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能!
具名和匿名挂载
# 匿名挂载
-v 容器内路径! #这里不写主机的目录
docker run -it -d -P --name nginx_05 -v /etc/nginx nginx
-P 随机指定端口#查看所有volume的情况
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local 0bed872eb81e37b10092f6164471a50fdf84cc038bbc89801e7cb05b0a89535e
local 07de8b0bb6aaa72ff8b9c1cbe5552e6ecd4f54b0c9f5f2728c65d2463c1392bf# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外(宿主机)的路径!# 具名挂载 (通过 -v 卷名:容器内路径)
[root@docker ~]# docker run -d -it --name nginx_06 -P -v jvming-nginx:/etc/nginx nginx
# 列出所有的卷
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local jvming-nginx# 查看一下这个卷详细信息
所有docker容器内的卷,没有指定目录情况下都是在 /var/lib/docker/volume/[卷名]/_data
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用具名挂载
# 如何却是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器路径 #匿名挂载
-v 卷名:容器路径 #具名挂载 (数据存储在默认路径/var/lib/docker/volume/)
-v /宿主机路径:容器内路径 #指定路径挂载
拓展:
# 通过 -v 容器内路径:ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写# 一旦这个设置了容器权限,容器对我们挂载出来的内容就又限定了!
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的[root@docker ~]# docker run -d -it --name nginx_06 -P -v jvming-nginx:/etc/nginx:ro nginx
[root@docker ~]# docker run -d -it --name nginx_06 -P -v jvming-nginx:/etc/nginx:rw nginx
初始DockerFile
DockerFile是用来构建docker镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像,镜像一层一层的,脚本一个个的命令,每个命令都是一层!
# 创建一个dockerfile文件,名字可以随机 建议Dockerfile
# 文件中的内容 指令(大写) 参数
FROM centosVOLUME ["volume01","volume02"]CMD echo "-----end-----"
CMD /bin/bash# 这里的每个命令,就是镜像的一层!
docker build -f [Dockerfile文件路径] -t [镜像名称:tag] .
[root@docker docker-test-volume]# docker run -d -it bridge/centos:1.0 /bin/bash
查看一下卷挂载的路径 docker inspect 容器id
测试一下刚才的文件是否同步出去了
在容器挂载的目录volume01中添加文件test.txt
在本地的卷目录下查看文件是否同步
这种方法我们未来用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像的时候没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径!
数据卷容器
是容器之间的挂载!!
思考:多个mysql同步数据实现共享
[root@docker ~]# docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql:5.7[root@docker ~]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=mysql02 --volumes-from mysql01 mysql:5.7#这个时候,可以实现两个容器数据同步!
# 启动三个容器,通过我们自己写的镜像
# 测试:可以删除docker01,查看一下docker02和docker03是否还可以继续访问
# 测试依旧可以访问
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的
DockerFile介绍
dockerfile是用来构建docker镜像的文件!命令参数脚本!构建步骤:
1.编写一个dockerfile文件
2.docker build构建成为一个镜像
3.docker run运行镜像
4.docker push发布镜像(DockerHub.阿里云镜像仓库!)
很多官方镜像都是基础包,很多功能没有,我们通常会用自己搭建自己的镜像
官方既然可以制作镜像,那我们也可以!
DockerFile构建步骤
基础知识:
1.每个保留关键字(指令)都是必须是大写字母
2.执行从上到下顺序执行
3.# 表示注释
4.每一个指令都会创建提交一个新的镜像层,并提交!
DockerFile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockerfile文件,这个文件十分简单!
Docker镜像逐渐成为了企业交付的标准
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品,原来是jar war包
Docker容器:容器就是镜像运行起来提供服务的
DockerFile的指令
FROM # 基础镜像,一切从这里开始
MAINTAINER # 镜像是谁写的,姓名+邮箱
RUN # 镜像构建的时候运行的命令
ADD # 步骤:tomcat镜像,这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录,进入容器后的默认目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口的位置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个命令会生效,可被替代
ENTYRPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承Dockerfile这个时候就会运行ONBUILD的指令,出发指令
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量#下图EXPOESE 应为 EXPOSE
实战测试
Docker Hub中99%镜像都是从这个基础镜像过来的FROM scratch
创建一个自己的centos
# 构建一个适合自己的镜像
[root@docker dockerfile]# cat mydockerfile
FROM centos
MAINTAINER Bridge<master_cy@126.com>ENV MYPATH /usr/loacl
WORKDIR $MYPATHRUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80CMD echo $MYPATH
CMD echo "----end-----"
CMD /bin/bash# 使用构建的镜像来运行容器,千万别忘记最后的点
# 命令 docker build -f dockerfile文件路径 -t 镜像名:[tag] .
Successfully built 5cce4b4a2953
Successfully tagged mycentos:1.0# 测试运行 发现vim和ifconfig都可以使用了,工作目录更改为/usr/local
[root@docker dockerfile]# docker run -it mycentos:1.0
[root@3b0e4a7d2aeb loacl]# ls
[root@3b0e4a7d2aeb loacl]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)RX packets 7 bytes 586 (586.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536inet 127.0.0.1 netmask 255.0.0.0loop txqueuelen 1000 (Local Loopback)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
我们可以列出本地镜像的变更历史
docker history 镜像id/名称:tag
--查看镜像构建的过程
我们平时拿到一个镜像,可以研究它是怎么做的?
CMD和ENTRYPOINT的区别
CMD # 指定这个容器启动的适合要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT # 指定这个容器启动的适合要运行的命令,可以追加命令
测试CMD
#编写dockerfile文件
[root@docker home]# cat dockerfile1
FROM centos
CMD ["ls","-a"]# 构建镜像
[root@docker home]# docker build -f dockerfile1 -t mycentos:2.0 .
Sending build context to Docker daemon 207.1MB
Step 1/2 : FROM centos---> 831691599b88
Step 2/2 : CMD ["ls","-a"]---> Running in bcb31410ceed
Removing intermediate container bcb31410ceed---> 2522d09261a4
Successfully built 2522d09261a4
Successfully tagged mycentos:2.0
# 运行镜像,发现ls -a命令生效了
[root@docker home]# docker run -it mycentos:2.0
. .dockerenv dev home lib64 media opt root sbin sys usr
.. bin etc lib lost+found mnt proc run srv tmp var# 想追加一个命令 -l ls -al
[root@docker home]# docker run 2522d09261a4 -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.
ERRO[0000] error waiting for container: context canceled # cmd的情况下 -l参数 替换了CMD["ls","-a"]的命令,而-l 不算命令,所以报错!
测试ENTRYPOIN
# 我们追加命令,是直接拼接在外面的ENTRYPOINT命令的后面!
[root@docker home]# docker run mycentos:3.0 -l
total 0
drwxr-xr-x. 1 root root 6 Jul 2 15:32 .
drwxr-xr-x. 1 root root 6 Jul 2 15:32 ..
-rwxr-xr-x. 1 root root 0 Jul 2 15:32 .dockerenv
lrwxrwxrwx. 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x. 5 root root 340 Jul 2 15:32 dev
drwxr-xr-x. 1 root root 66 Jul 2 15:32 etc
drwxr-xr-x. 2 root root 6 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 6 Jun 11 02:35 lost+found
drwxr-xr-x. 2 root root 6 May 11 2019 media
drwxr-xr-x. 2 root root 6 May 11 2019 mnt
drwxr-xr-x. 2 root root 6 May 11 2019 opt
dr-xr-xr-x. 206 root root 0 Jul 2 15:32 proc
dr-xr-x---. 2 root root 162 Jun 11 02:35 root
drwxr-xr-x. 11 root root 163 Jun 11 02:35 run
lrwxrwxrwx. 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 May 11 2019 srv
dr-xr-xr-x. 13 root root 0 Jul 2 02:41 sys
drwxrwxrwt. 7 root root 145 Jun 11 02:35 tmp
drwxr-xr-x. 12 root root 144 Jun 11 02:35 usr
drwxr-xr-x. 20 root root 262 Jun 11 02:35 var
DockerFile中许多命令都十分的相似,我们需要了解他们的区别,我们最好的学习就是对比他们,然后测试效果!
实战测试2:Tomcat镜像
1.准备镜像文件tomcat压缩包,jdk压缩包!
2.编写Dockerfiel文件,官方命令Dockerfile,build会自动构建这个文件
[root@docker tomcat]# vim Dockerfile
FROM centos
MAINTAINER Bridge<master_cy@126.com>COPY readme.txt /usr/local/readme/txtADD jdk-8u181-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/RUN yum -y install vimENV MYPATH /usr/local
WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
3.构建镜像
# docker build -t diytomcat .
4.启动镜像
# 项目挂载在本地/home/build/tomcat/test目录下,直接在test中做修改就可以直接发布。日志也挂载出来了,本地可以查看
# docker run -d -p 9090:8080 --name bridgetomcat -v /home/build/tomcat/test:/usr/local/apache-tomcat-9.0.22/webapps/test -v /home/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.22/logs diytomcat
5.测试访问
6.发布项目(由于做了卷挂载,我们直接在本地编写项目就可以发布了)
发布自己的镜像
发布到Docker.Hub
Docker.Hub
1.地址https://hub.docker.com/ 注册自己的账号
2.确定这个账号可以登录
3.在我们服务器上提交自己的镜像
[root@docker ~]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:-p, --password string Password--password-stdin Take the password from stdin-u, --username string Username
4.录完毕后就可以提交镜像了,就是一步 docker push
# push 自己的镜像到服务器上
[root@docker ~]# docker push dirtomcat03
The push refers to repository [docker.io/library/dirtomcat03]
6eabbc12bc8b: Preparing
efcfd5ec54aa: Preparing
f73de6d323b0: Preparing
bc4da657b4da: Preparing
eb29745b8228: Preparing
denied: requested access to the resource is denied #拒绝# push镜像的问题?
[root@docker ~]# docker push dirtomcat03
The push refers to repository [docker.io/bridge/dirtomcat03]
An image does not exist locally with the tag: bridge/dirtomcat03#解决办法:增加一个tag,tag的意思是重新给镜像取个名字
# 想要上传的容器id(这里的容器id为dirtomcat03的,) chao123456e 为DockerHub账号,这里一定要和DockerHub上账号对应,不然不能上传 chao123456e/tomcat:2.0 为新镜像名称
[root@docker ~]# docker tag 2c30f06d63c3 chao123456e/tomcat:2.0# 表示正在上传,已经配置成功
[root@docker ~]# docker push chao123456e/tomcat:2.0
The push refers to repository [docker.io/chao123456e/tomcat]
6eabbc12bc8b: Pushing [===========================> ] 31.89MB/57.22MB
efcfd5ec54aa: Pushed
f73de6d323b0: Pushing [================> ] 128.7MB/381.7MB
bc4da657b4da: Pushed
eb29745b8228: Pushing [==============================> ] 132.7MB/215.3MB
# 提交的时候可以看出也是按层级提交的
发布到阿里云镜像服务上
1.登录阿里云
2.找到容器镜像服务
3.创建命名空间
4.创建容器镜像
5.浏览阿里云
# push上去阿里云镜像
docker push chao123456e/tomcat:2.0
小结:
Docker 网络
理解Docker0
测试
三个网络
# 问题: docker是如何处理容器网络访问的
# [root@docker ~]# docker run -d -P --name tomcat01 tomcat# 查看容器的内部网络地址 ip addr
[root@docker ~]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
4: eth0@if5: <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 0inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever#Linux 可以ping通docker容器内部
原理:
1.我们每启动一个docker容器mdocker就会给docker容器分配一个ip,只要安装了docker,就会有一个网卡docker0,桥接模式,使用的技术是veth-pair技术!
再次测试:ip addr
2.再启动一个容器测试,发现又多了以一对网卡!
# 我们发现这个容器带来网卡,都是一堆堆的
# veth-pair 就是以低于的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连# 比如上图的本地机的 5:veth if 对应的就是tomcat01的 4:veth if5 所以说他们是成对出现,# 正因为有这个特性,veth-pair充当一个桥梁,连接各种虚拟网络设备的
# oPenStac ,Docker容器之间的连接,OVS的连接,都是使用veth-pair技术
3.测试tomcat01和tomcat02是否可以ping通!
[root@docker ~]# docker exec -it tomcat01 ping 172.17.0.2# 结论:容器和容器之间是可以互相ping通的
结论:tomcat01和tomcat02是公用的一个路由器,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP
小结
Docker使用的是Linux的桥接,宿主机中是一个Docker容器的网桥docker0
Docker中所有的网络接口都是虚拟的,虚拟的转发效率高(内网传递文件!)
只要容器删除,对应网桥一对就没了!
思考
我们编写了一个微服务,database url=ip;项目不重启,数据库IP换掉了,我们希望可以处理这个问题,可以通过名字来进行访问服务
–Link
[root@docker ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known#如何解决上面的问题呢?
# 通过 --link 即可以解决了网络连通问题
[root@docker ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
[root@docker ~]# 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.168 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.070 ms# 反向可以ping通吗?
[root@docker ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: No address associated with hostname
其实这个tomcat03就是在本地配置了tomcat02的配置?
[root@docker ~]# docker exec -it tomcat03 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 tomcat02 60b035aed160
172.17.0.4 bb26ed7d467d
本质探究:–link就是在我们hosts文件中配置了172.17.0.3 tomcat02 60b035aed160
wm 现在玩Docker已经不建议使用–link了!
自定义网络!不适用docker0!
docker0问题:它不支持容器名连接访问!
自定义网络
查看所有的docker网络
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c657cfee5244 bridge bridge local
afd6d3641e4f host host local
edc909beaf2e none null local
网络模式
bridge: 桥接 docker(默认,自己创建也使用bridge模式)
none: 不配置网络
host: 和宿主机共享网络
container:容器网络联通!(用的少!让容器直接互联,局限性大!!)
# 我们直接启动的命令, --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name --net bridge tomcat#docker0特点: 默认,域名不能访问,--link可以连通# 我们可以自定义一个网络!
# --driver 默认是bridge网络
# --subnet 192.168.0.0/16
# --gateway 192.168.0.1[root@docker ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
[root@docker ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
c657cfee5244 bridge bridge local
afd6d3641e4f host host local
370471f6a056 mynet bridge local
edc909beaf2e none null local
[root@docker ~]# docker run -d -P --name tomcat02 --network mynet tomcat
18c523b7a4f04e706175d72a7850339b442d6f562b492c497c4cd73cbc71bb58
[root@docker ~]# docker run -d -P --name tomcat03 --network mynet tomcat
59a7491cc124402428b25954528090316d16cbc2b8936b96478447f69be8ff29
[root@docker ~]# docker network inspect mynet
[{"Name": "mynet","Id": "370471f6a0566a37a8e698d6da6e7f3a7dfa8517363beb22cf6b9e46b8f14961","Created": "2020-07-06T21:32:34.873713447-04:00","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": {"18c523b7a4f04e706175d72a7850339b442d6f562b492c497c4cd73cbc71bb58": {"Name": "tomcat02","EndpointID": "118c5e9b7ca2191dd31d1c05422845009b357b916e5a6acf42bd1e4333c9e747","MacAddress": "02:42:c0:a8:00:02","IPv4Address": "192.168.0.2/16","IPv6Address": ""},"59a7491cc124402428b25954528090316d16cbc2b8936b96478447f69be8ff29": {"Name": "tomcat03","EndpointID": "b00fcc708a073466f0844d7aaf308dafdee3c0d78f022a60a3ee69ef501ce249","MacAddress": "02:42:c0:a8:00:03","IPv4Address": "192.168.0.3/16","IPv6Address": ""}},"Options": {},"Labels": {}}
]# 再次测试ping连接
[root@docker ~]# docker exec -it tomcat02 ping tomcat03
PING tomcat03 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat03.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.173 ms
64 bytes from tomcat03.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.070 ms
^C
--- tomcat03 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1ms
rtt min/avg/max/mdev = 0.070/0.121/0.173/0.052 ms#现在不使用--link也可以ping名字了!
[root@docker ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.067 ms
64 bytes from tomcat02.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.073 ms
^C
--- tomcat02 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2ms
rtt min/avg/max/mdev = 0.063/0.067/0.073/0.010 ms
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
# 测试打通 tomcat01 - mynet 容器和网络来打通
[root@docker ~]# docker network connect mynet tomcat01# 连通之后就是将 tomcat01 放到了mynet网络下!# 一个容器两个ip地址!
# 阿里云服务: 公网ip 私网ip
结论:假设要跨网络操作别人,就需要使用docker network connect连通!
实战:部署Redis集群
# 创建网卡
docker network create redis --subnet 172.38.0.0/16# 通过脚本创建六个redis配置
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
donedocker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --network redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
SpringBoot微服务打包Docker镜像
构建SpringBoot项目
打包install
编写Dockerfile文件
FROM java:8MAINTAINER jacky(dapeng@163.com)COPY *.jar /app.jarCMD ["--server.port=8080"]EXPOSE 8080CMD ["java","-jar","app.jar"]
构建镜像(上传jar包和Dockerfile文件后)
docker build -t jacky-springboot .
发布运行
docker run -d --name springboot-web -p 3300:8080 jacky-springboot# 测试访问
curl localhost:3300 --返回404页面curl localhost:3300/hello --访问hello接口,返回字符串
Docker概述及使用相关推荐
- 【1】Docker概述
Docker概述 关键词 docker 是一个开源的应用容器引擎,是一个软件 打包应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上 容器性能开销极低 docker基 ...
- Docker学习篇(一)Docker概述、安装和常用命令
Docker概述 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化.容器是完 ...
- Docker概述与基本使用
Docker概述 一.介绍 1.1.Docker 介绍: Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从Apache2.0协议开源,可以轻松的为任何应用创建一个轻量级的.可移植的.自给 ...
- Docker概述、安装及基础命令
Docker概述.安装及基础命令 一.Docker概述 1. docker是什么 2. docker与虚拟机的区别 3. docker使用场景 4. docker核心概念 5. docker引擎 6. ...
- Docker概述(二)(标贝科技)
标贝科技 https://ai.data-baker.com/#/?source=qwer12 填写邀请码fwwqgs,每日免费调用量还可以翻倍 Docker概述(二) 文章目录 Docker概述(二 ...
- 【docker】docker概述及基础入门
docker概述及基础入门 前言: docker是近年来非常火的一个容器化技术,相比传统的vmware虚拟化技术有着非常大的优势,(vm:小伙子你不讲武德),对于开发人员.测试人员.运维人员,再往上走 ...
- Docker概述和安装部署
概述 Docker产生的背景 一款产品从开发到上线,从操作系统,到运行环境,再到应用配置.作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后 ...
- 搭建Docker环境---Docker概述
Docker 包括三个基本概念: 镜像(Image) 容器(Container) 仓库(Repository) 这三部分组成了Docker的整个生命周期,如下图所示,容器是由镜像实例化而来的,这和我们 ...
- Docker之Docker概述
Docker容器虚拟化平台 1. Docker 的概念 1.1 Docker 为什么会出现? 1.3 Docker 的作用 1.2 Docker 的历史 2. Docker 容器技术与虚拟机的区别 3 ...
最新文章
- linux 启动nacos报错_nacos在Linux上的搭建启动报错
- 3G手机Android应用开发视频教程_黎活明老师的视频(第三天课程)总共有八天课程...
- (17)System Verilog禁止类中所有变量随机属性
- 莫比乌斯反演习题总结
- java 全角半角符号转换_java 字符串全角半角转换
- 计算机的排除故障的方法,计算机产生故障的原因和排除故障的方法
- LINUX下Android NDK下载并配置
- 关于在IDEA中Tomcat乱码的解决办法
- 基于matlab的谐波处理及无功功率补偿源码,谐波抑制和无功功率补偿(第3版) pdf epub mobi txt 下载...
- Microsoft Office Word一打开文档就弹出样式小窗口
- IP 点分十进制表示法
- NS3使用Eclipse配置
- MathType批量修改公式字体和大小
- Unity Shader 学习笔记(33) 全局光照(GI)、反射探针、线性空间和伽马空间、高动态范围(HDR)
- 新入职如何快速的熟悉项目
- 小程序源码:修复登录接口仿抽奖助手-多玩法安装简单
- mysql zombodb_zombodb安装试用
- word两幅图并排并且插入题注不会乱
- 搜狗音乐盒1.2单文件
- java中workFlowEvent_关于WorkFlow的使用以及例子