Run的流程和Docker原理
底层原理
Docker为什么比VM快
Docker的常用命令
镜像命令
看官网的docker images或者使用docker images —help
搜索镜像
下载镜像
容器命令

测试:
启动并进入容器:docker run -it centos /bin/bash
列出所有的的运行容器
退出容器
删除容器
启动和停止容器的操作
常见的其他命令
后台启动器

容器使用后台运行,就必须要有一个前台进程,如果没有应用就会自动停止
查看日志
查看docker容器中进程信息
**查看镜像的元数据
#命令docker inspect 容器id#测试[root@izuf6jcfaz5u0nk3mdd3afz /]# docker inspect 23e92ab7b75f[{"Id": "23e92ab7b75f8d93364c3f15711c18d05cea7edc2accaa4eaf776f9a91e08009","Created": "2022-04-24T01:58:14.900699265Z","Path": "/bin/bash","Args": [],"State": {"Status": "exited","Running": false,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 0,"ExitCode": 0,"Error": "","StartedAt": "2022-04-24T01:58:15.395891639Z","FinishedAt": "2022-04-24T02:01:16.302299625Z"},"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6","ResolvConfPath": "/var/lib/docker/containers/23e92ab7b75f8d93364c3f15711c18d05cea7edc2accaa4eaf776f9a91e08009/resolv.conf","HostnamePath": "/var/lib/docker/containers/23e92ab7b75f8d93364c3f15711c18d05cea7edc2accaa4eaf776f9a91e08009/hostname","HostsPath": "/var/lib/docker/containers/23e92ab7b75f8d93364c3f15711c18d05cea7edc2accaa4eaf776f9a91e08009/hosts","LogPath": "/var/lib/docker/containers/23e92ab7b75f8d93364c3f15711c18d05cea7edc2accaa4eaf776f9a91e08009/23e92ab7b75f8d93364c3f15711c18d05cea7edc2accaa4eaf776f9a91e08009-json.log","Name": "/charming_easley","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/067499f2203aff7b8384c7765bdf53fc6f5a1af2b2dd1e666539f4c35fa89258-init/diff:/var/lib/docker/overlay2/49f9efa7a5d2175e919f6a132b999a9dc37c6227ecda0ba3415898eaf0a6e2a7/diff","MergedDir": "/var/lib/docker/overlay2/067499f2203aff7b8384c7765bdf53fc6f5a1af2b2dd1e666539f4c35fa89258/merged","UpperDir": "/var/lib/docker/overlay2/067499f2203aff7b8384c7765bdf53fc6f5a1af2b2dd1e666539f4c35fa89258/diff","WorkDir": "/var/lib/docker/overlay2/067499f2203aff7b8384c7765bdf53fc6f5a1af2b2dd1e666539f4c35fa89258/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "23e92ab7b75f","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": "20210915","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": "02870d62a71e06269d83ba89975ea7e8c7a2a799ba5782ce9d3d28d266656e8e","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {},"SandboxKey": "/var/run/docker/netns/02870d62a71e","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "","Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","MacAddress": "","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "48d11aaab9e610cf24fd86f6f69809fe5396f5b359c053c72a885dc1669d5c1b","EndpointID": "","Gateway": "","IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "","DriverOpts": null}}}}]
**进入当前正在运行的容器
#我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
#命令
docker exec -it 容器id bashShell
#测试
#方式一:
[root@izuf6jcfaz5u0nk3mdd3afz /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
23e92ab7b75f centos "/bin/bash" 4 hours ago Up 6 seconds charming_easley
[root@izuf6jcfaz5u0nk3mdd3afz /]# docker exec -it 23e92ab7b75f /bin/bash
[root@23e92ab7b75f /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@23e92ab7b75f /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 05:43 pts/0 00:00:00 /bin/bash
root 15 0 0 05:45 pts/1 00:00:00 /bin/bash
root 30 15 0 05:47 pts/1 00:00:00 ps -ef
#方式二:
docker attach 容器id
#测试
[root@izuf6jcfaz5u0nk3mdd3afz /]# docker attach 23e92ab7b75f
正在执行的代码...
#docker exec #进入容器后开启一个新的终端,可以在里面操作(常用)
#docker attch #进入容器正在执行的终端,不会启动新的进程!
从容器内拷贝文件到主机上
docker cp 容器id:容器内路径 目的的主机路径
练习
部署Nginx
hub.docker.com搜索,找对应版本号,alpine为瘦身版
#1.搜索镜像:
docker search+软件名字
#2.拉取镜像:
docker pull+软件名字
#3.运行测试
[root@izuf6jcfaz5u0nk3mdd3afz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest fa5269854a5e 6 days ago 141MB
mysql latest 667ee8fb158e 4 weeks ago 521MB
mysql 8.0.26 9da615fced53 6 months ago 514MB
hello-world latest feb5d9fea6a5 7 months ago 13.3kB
centos latest 5d0da3dc9764 7 months ago 231MB
#-d 后台运行
#--name 给容器命名
#-p 宿主机端口:容器内部端口
[root@izuf6jcfaz5u0nk3mdd3afz ~]# docker run -d --name nginx01 -p 3344:80 nginx
b5f373154600224c7479fa4ba6b05302a608a346874b3f3ad9ef844a9c83a508
[root@izuf6jcfaz5u0nk3mdd3afz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b5f373154600 nginx "/docker-entrypoint.…" 3 seconds ago Up 3 seconds 0.0.0.0:3344->80/tcp nginx01
23e92ab7b75f centos "/bin/bash" 3 days ago Up 2 days charming_easley
[root@izuf6jcfaz5u0nk3mdd3afz ~]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
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@izuf6jcfaz5u0nk3mdd3afz ~]# docker exec -it nginx01 /bin/bash
root@b5f373154600:/# where is nginx
bash: where: command not found
root@b5f373154600:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@b5f373154600:/# cd /etc/nginx
root@b5f373154600:/etc/nginx# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
端口暴露的概念
目前每一次改动nginx配置文件,都需要进入容器内部,十分麻烦,要是可以在容器外部提供一个映射路径,达到在容器修改文件名,容器内部就可以自动修改。后续就需要使用到数据卷技术。
部署tomcat
#下载再启动
docker pull tomcat
#启动运行
docker run -d --name tomcat01 -p 3355:8080 tomcat
#测试访问没有问题
#进入容器
docker exec -it tomcat01 /bin/bash
#发现问题:1.linux命令少了 2.没有webapps 阿里云镜像的原因,默认是最小的镜像,所有不必要的都剔除掉。
什么是镜像
Docker镜像加载原理
分层理解
Commit镜像
容器数据卷
使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
#测试
[root@izuf6jcfaz5u0nk3mdd3afz /]# docker run -it -v /home/ceshi:/home centos /bin/bash
#启动起来时候我们可以通过 docker inspect 容器id 查看具体的卷是怎么挂载的



好处:以后修改只需要在本地修改即可,容器内会自动同步
实战:安装MySQL
思考:MySQL的数据持久化的问题!
#获取镜像
#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 环境配置
--name 容器名字
[root@izuf6jcfaz5u0nk3mdd3afz ~]# 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=134679 --name mysql01 mysql:5.7
#启动成功后,我们在本地使用sqlyog 来测试一下
#sqlyog-连接到服务器的3310 --3310和容器内的 3306映射,这个时候我们就可以连接上了
#在本地测试创建一个数据库,查看一下我们映射的路径是否ok!
假设我们将容器删除
发现,我们本地的数据卷依旧没有丢失,这就实现了,容器数据持久化功能!
具名和匿名挂载



如何确定是具名挂载还是匿名挂载,还是指定路径挂载
初始DockerFile
Dockerfile就是用来构建docker镜像的构建文件,命令脚本
通过这个脚本可以生成一个镜像,镜像是一层一层的,脚本一个个的命令,每一个命令都是一层
#创建一个dockerfile文件,名字可以随意,建议Dockerfile
#文件中的内容 (指令大写)参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
#这里的每一条命令,就是镜像的一层

启动自己的容器
数据卷容器
多个mysql同步数据



测试,可以删除Docker01,查看一下docker02和docker03是否还可以访问这个文件 测试依旧可以访问


结论:
容器之间配置信息的传递,数据卷容器的声明周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的
Dockerfile
是用来构建docker镜像的文件,命令参数脚本。
构建步骤:
1、编写一个dockerfile文件
2、docker build构建一个镜像
3、docker run运行镜像
4、docker push 发布镜像(DockerHub、阿里云镜像仓库)
查看官方做法

Dockerfile构建过程
基础知识


dockerfile是面向开发的,以后我们要发布项目,做镜像就需要编写dockerfile文件,这个文件十分简单。
以前交付一个jar包,现在逐渐成为交付一个Docker镜像了
Dockerfile:构建文件,定义了一切的步骤,像是一个源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品
Docker容器:容器就是镜像运行起来提供服务器
实战测试
CMD和ENTRYPOINT区别

如
运行容器就会运行CMD的命令。
-l替换了ls -a,所以想要执行ls -al就需要在后面直接追加-al
测试ENTRYPOINT

总体感觉就是替换和追加的区别
总结
Docker网络
理解Docker0

问题:docker是如何处理容器网络访问的


原理
1、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用的技术是evth-pair技术!
再次测试ip addr
2、再启动一个容器测试,发现又多了一块网卡
#我们发现这个容器带来网卡,都是一对一对的
#evth-pair就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连
#正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的
#Openstac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
3、来测试一下tomcat01和tomcat02是否可以ping通
绘制一个网络模型图
结论:tomcat01和tomcat02是公用的一个路由器,即docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP
小结
Docker使用的是Linux的桥接,宿主机中是一个Docker容器的网桥 docker0
Docker中的所有的网络接口都是虚拟的,为什么是虚拟的?因为虚拟的转发效率高
只要容器删除,对应网桥一对就没了
—link


原本是两个容器之间直接是ping不通的

其实这个tomcat03就是本地配置了tomcat02的配置
配置探究:—link就是在我们的hosts配置中增加了一个172.18.0.3 tomcat 312857784cd4
现在已经不建议使用—link了,使用自定义网络,不使用docker0
docker0问题:他不支持容器名连接访问
自定义网络
查看所有的docker网络
网络模式
bridge:桥接 docker(默认,自己创建也使用桥接模式)
none:不配置网络
host:和宿主机共享网络
container:容器内网络联通(用得少,局限很大)
测试
#我们直接启动的命令 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 --net bridge tomcat
#docker0的特点:默认,域名不能访问, --link可以打通连接
#我们可以自定义一个网络
#--driver bridge
#--subnet 192.168.0.0/16 192.168.0.2 192.168.255.255
#--gateway 192.168.0.1



我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时使用网络。
加入到我们自定义的网络

这里的mynet就是自定义的网络
好处:
redis、mysql -不同的集群使用不同的网络,保证集群是安全和健康的
这种隔离情况也是可以打通的
Springboot微服务打包docker镜像
将当前目录下所有的jar包拷到项目下面,叫做app.jar






















