当前位置: 首页> 游戏> 攻略 > 程序员培训多少钱_装修设计网站排名_推广专员是做什么的_营销推广策略

程序员培训多少钱_装修设计网站排名_推广专员是做什么的_营销推广策略

时间:2025/8/2 11:18:57来源:https://blog.csdn.net/2301_79469341/article/details/146247829 浏览次数:2次
程序员培训多少钱_装修设计网站排名_推广专员是做什么的_营销推广策略

基本结构

在这里插入图片描述

镜像(image):
docker镜像可以当作一个模板,通过这个模板可以创建多个容器。

例如一个tomcat镜像=>运行=>容器(提供服务)

容器(container):
docker利用容器技术,可以独立运行一个或一组应用(容器间相互隔离)

docker容器通过镜像来创建,即容器中的进程依赖于镜像中的文件。

docker容器类似于虚拟机,可以启动,停止,删除等。可以把docker当作一个简易的Linux系统。

仓库(repository):
存放镜像的地方。分为公有仓库和私有仓库。

默认是使用国外的仓库docker hub。

流程及原理

流程:
以第一层docker run hello-world为例

在本机寻找镜像–>判断是否有该镜像
如果有该镜像–>直接运行
如果没有这个镜像–>去所设置的源中寻找这个镜像–>下载–>运行

原理:
docker是一个CS结构系统,docker的守护进程在主机上。通过socket从客户端访问,docker-server接收到docker-client指令,就好执行该命令。

常用命令

帮助命令
docker version  #查看docker版本信息
docker info    #显示docker系统信息,比version更相信
docker 命令 --help   #docker --help直接查看帮助信息

docker官方文档:https://docs.docker.com/engine/reference/commandline

镜像命令

docker images 查看所有本地主机上的镜像

root@VM-4-17-ubuntu:/home/ubuntu# docker images
REPOSITORY    TAG                        IMAGE ID       CREATED         SIZE
tophant/arl   v2.6.1                     658157563173   10 months ago   1.19GB
hello-world   latest                     d2c94e258dcb   18 months ago   13.3kB#解释
REPOSITORY  镜像的仓库源
TAG         镜像标签
IMAGE ID    镜像id
CREATED     镜像创建时间
SIZE        镜像大小#可选项
docker images --help #查看可选项
-a, -all  #列出所有镜像
-q, -quiet #只显示镜像id
-f, --filter filter(过滤器)   filter可以是dangling=true(悬空镜像)--format string(格式化字符串)   string可以是json table等
也可以直接docker images 后面跟上镜像的名称 搜索指定镜像

docker search 搜索镜像(如果配置的是国内的镜像源会超时)

docker search images(写镜像名称即可)

docker pull 下载镜像

docker pull 镜像名称(默认是最新版本)
docker pull 镜像名称[:tag]  #指定版本root@VM-4-17-ubuntu:/home/ubuntu# docker pull mysql
Using default tag: latest   #如果不写,默认就是latest
latest: Pulling from library/mysql
f1a9f94fc2db: Pull complete   #分层下载
f98254a2b688: Pull complete 
6ad83e89f981: Pull complete 
a42d733ea779: Pull complete 
6fd1af2601dd: Pull complete 
0233a63dc5cd: Pull complete 
5f31e56c9bea: Pull complete 
c0fb96d14e5b: Pull complete 
d57074c62694: Pull complete 
7030c241d9b8: Pull complete 
Digest: sha256:2be51594eba5983f47e67ff5cb87d666a223e309c6c64450f30b5c59a788ea40 #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest   #真实地址docker pull mysql 等价于 docker pull  docker.io/library/mysql:latest
docker pull mysql:5.7 #下载指定5.7版本的mysql

docker rmi -f 删除镜像

docker rmi -f 镜像名称或ID  
docker rmi -f $(docker images)  #批量删除所有镜像

docker commit 提交镜像

docker commit 提交容器成为一个新副本
#与git类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名[:tag]
容器命令

有镜像才能创建容器,下载一个centos镜像来测试

docker pull centos  #下载centos镜像

新建容器,并启动

docker run [可选项] image 使用的shell#参数
--name='Name'  #容器名字
-d			   #后台方式运行
-it			   #使用交互方式运行,进入容器查看内容
-p			   #指定容器端口-p 主机端口:容器端口 (常用)-p ip:主机端口:容器端口-p 容器端口
-P 			   #随机指定端口
-e             #环境配置
#启动并且进入容器,以/bin/bash启动交互
root@VM-4-17-ubuntu:/home/ubuntu# docker run -it centos /bin/bash
#此时已经进入centos
[root@edcaca222a0c /]# 
[root@edcaca222a0c /]# exit 
退出容器

docker ps 查看正则运行的容器

docker ps#可选项
-a    #查看历史运行过的容器
-n=#显示最近创建的容器
-q    #只显示编号

exit 退出容器

exit  #直接停止容器并退出
Ctrl+P+Q #容器不停止,但退出

docker rm 删除容器

docker rm 容器id  #删除所有容器(正在运行的容器不能删除)
docker rm -d 容器id #强制删除
docker rm -f $(docker ps -sq)  #删除全部容器

启动和停止容器

docker start 容器id   #启动容器
docker restart 容器id #重启容器
docker stop 容器id    #停止容器
docker kill 容器id    #强制停止容器
其他命令

后台启动容器

docker run -d centos #后台运行centos
但是会停止,因为容器使用后台时,需要有一个前台进程,docker发现没有应用,就会自动停止

查看日志

docker logs #可选项
--details    #详细显示    
-f    --follow         --since string   
-n--tail number #要显示的日志的条数   
-t    #显示时间戳--timestamps      --until例:
docker logs -f -t --tail 10 bdc75926ba54  #查看容器id为bdc75926ba54的近十条日志
#自己写一段脚本
docker run -d centos /bin/bash -c "while true;do echo success;sleep 1;done"
docker ps

查看容器中的进程信息

docker top 容器ID   

查看进程源数据

docker inspect 容器ID   #很详细的信息
root@VM-4-17-ubuntu:/home/ubuntu# docker inspect bdc75926ba54
[{"Id": "bdc75926ba5407e16b35c9bc7f3ae0458f42760de6cd4438b5241107ca45cd07","Created": "2024-11-18T12:42:53.59866176Z","Path": "/bin/bash","Args": ["-c","while true;do echo success;sleep 1;done"],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 3288327,"ExitCode": 0,"Error": "","StartedAt": "2024-11-18T12:42:53.709853768Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6","ResolvConfPath": "/var/lib/docker/containers/bdc75926ba5407e16b35c9bc7f3ae0458f42760de6cd4438b5241107ca45cd07/resolv.conf","HostnamePath": "/var/lib/docker/containers/bdc75926ba5407e16b35c9bc7f3ae0458f42760de6cd4438b5241107ca45cd07/hostname","HostsPath": "/var/lib/docker/containers/bdc75926ba5407e16b35c9bc7f3ae0458f42760de6cd4438b5241107ca45cd07/hosts","LogPath": "/var/lib/docker/containers/bdc75926ba5407e16b35c9bc7f3ae0458f42760de6cd4438b5241107ca45cd07/bdc75926ba5407e16b35c9bc7f3ae0458f42760de6cd4438b5241107ca45cd07-json.log","Name": "/nervous_hamilton","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "docker-default","ExecIDs": null,"HostConfig": {"Binds": null,"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "bridge","PortBindings": {},"RestartPolicy": {"Name": "no","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"ConsoleSize": [23,168],"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","Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": [],"BlkioDeviceWriteBps": [],"BlkioDeviceReadIOps": [],"BlkioDeviceWriteIOps": [],"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": [],"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","/sys/devices/virtual/powercap"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/e1f14591fd92ea633340505f56178f100b15e4b3c3d5c99d4cd6fdce7b45f0fb-init/diff:/var/lib/docker/overlay2/d3b747475083e2e4f9f55fdbd0bfcb7014302c609b6e78e71285b3cbc167ada9/diff","MergedDir": "/var/lib/docker/overlay2/e1f14591fd92ea633340505f56178f100b15e4b3c3d5c99d4cd6fdce7b45f0fb/merged","UpperDir": "/var/lib/docker/overlay2/e1f14591fd92ea633340505f56178f100b15e4b3c3d5c99d4cd6fdce7b45f0fb/diff","WorkDir": "/var/lib/docker/overlay2/e1f14591fd92ea633340505f56178f100b15e4b3c3d5c99d4cd6fdce7b45f0fb/work"},"Name": "overlay2"},"Mounts": [],"Config": {"Hostname": "bdc75926ba54","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": ["/bin/bash","-c","while true;do echo success;sleep 1;done"],"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": "f917fe5b9d9b12a387c0839145d48519157f1cc1de48ff5946de78dadb34e7f2","SandboxKey": "/var/run/docker/netns/f917fe5b9d9b","Ports": {},"HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "4c25273ed065481b657a6b4878f81d5edcd6d82054d34a5fb197908f75765a3c","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.3","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:03","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"MacAddress": "02:42:ac:11:00:03","DriverOpts": null,"NetworkID": "1d4a3714574bf3de87a9553dfc005fad8166af95134e91e3b2bb80c9ac3a65b5","EndpointID": "4c25273ed065481b657a6b4878f81d5edcd6d82054d34a5fb197908f75765a3c","Gateway": "172.17.0.1","IPAddress": "172.17.0.3","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"DNSNames": null}}}}
]

进入正在运行的容器
外面平时使用的容器通常都是后台方式运行的

方式一(进入容器后开启一个新的终端)
docker exec -it 容器ID 要使用的shell
例:
docker exec -it bdc75926ba54 /bin/bash方式二(进入容器正在执行的终端,不会启动新的进程)
docker attach 容器ID
例:
docker attach bdc75926ba54

从容器拷贝文件到主机上

docker cp 容器ID:容器内文件路径 目的主机路径
例: #将容器内的test.txt文件拷贝到主机的/root目录下
docker cp 6b627de01b09:/home/test.txt /root

查看docker的cpu状态

docker stats

练习

部署nginx
1、搜索镜像   search  (最好去docker hub网站上搜索)
2、下载镜像   pull
3、运行测试   run
docker pull nginx #拉取镜像docker run -d --name nginx01 -p 3456:80 nginx
#以后台方式运行该镜像,起名为nginx01,3333为主机端口,80为容器地址
curl localhost:3456
#本机自测一下,可以通过root@VM-4-17-ubuntu:/home/ubuntu# docker exec -it nginx01 /bin/bash
root@b4b82f2c26a3:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@b4b82f2c26a3:/# cd /etc/nginx
root@b4b82f2c26a3:/etc/nginx# ls
conf.d  fastcgi_params  mime.types  modules  nginx.conf  scgi_params  uwsgi_params
部署tomcat
#官方使用
docker run -it --rm tomcat:9.0 #用完即删,一般用于测试#正常下载启动
docker pull tomcat #拉取镜像
docker run -d -p 3457:8080 --name tomcat01 tomcat
#和上面部署nginx一样,此时可以访问,但不是完整的(是一个阉割版)root@VM-4-17-ubuntu:/home/ubuntu# docker exec -it tomcat01 /bin/bash
root@cd322dbdf282:/usr/local/tomcat# ls
bin  BUILDING.txt  conf  CONTRIBUTING.md  lib  LICENSE  logs  native-jni-lib  NOTICE  README.md  RELEASE-NOTES  RUNNING.txt  temp  webapps  webapps.dist  work
root@cd322dbdf282:/usr/local/tomcat# cd webapps   #应用一般放在这个webap ps文件夹中
root@cd322dbdf282:/usr/local/tomcat/webapps# ls   #但是webapps里面什么都没有
#里面没有完整的linux命令、没有webapps,因为他只提供最小可运行的环境
root@cd322dbdf282:/usr/local/tomcat# cd webapps.dist
root@cd322dbdf282:/usr/local/tomcat/webapps.dist# ls
docs  examples  host-manager  manager  ROOT
#可以看到webapps.dist文件夹下有内容,将这个里面内容拷贝到webapps目录下
root@cd322dbdf282:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@cd322dbdf282:/usr/local/tomcat# ls webapps
docs  examples  host-manager  manager  ROOT
#此时再次刷新网页,即可正常显示

在这里插入图片描述

部署ES+Kibana

es和kibana之间需要进行网络通信,首先要创建一个虚拟网络

docker network create es-net

部署es

#ES暴露的端口很多,ES很耗内存!!!,且ES的数据一般需要放置到安全目录挂载
#下载启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2#由于十分耗内存,内存小可能无法启动,这里使用-e参数修改环境配置
docker run -d --name elasticsearch02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
#docker stats 查看docker的cpu状态,可以发现内存很小了,
#curl localhost:9200 发现web页面也可以正常访问了

在这里插入图片描述

部署kibana(要于es的版本一致)

docker pull kibana:7.6.2 #用的国内的源,无法下载最新的
#启动(如果遇到Kibana server is not ready yet等一会就可以了)
docker run -d --name kibana02 -e ELASTICSEARCH_HOSTS=http://4554b397a6f3:9200 --net=es-net -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" -p 5601:5601 kibana:7.6.2
#第一个-e是设置es的节点地址,如果用容器ID不好使就换成服务器ip
#将es的容器ID替换成服务器的ip也可以

成功进入
在这里插入图片描述

镜像原理

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、库、环境变量、配置文件。

加载原理

联合文件系统(UnionFS):一种分成、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下

docker的镜像是机械上由一层一层的文件系统组成,这种层级文件系统被称为联合文件系统。

bootfs(boot file system):是docker镜像的最底层,主要包含boot加载器和kernel内核,而boot加载器用来引导加载kernel。

linux启动时会加载bootfs系统,加载完之后内存的使用权就由bootfs交给内核了,系统此时也会卸载bootfs

rootfs(root file system):是在bootfs之上一层的文件系统,包含linux系统中的dev/ /proc /bin /etr标准目录和文件。是一个小型的虚拟环境

rootfs就是各种操作系统的发行版,如centos、bunut等

在这里插入图片描述

分层原理

所有docker镜像都起始于一个基础镜像层,当修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。

例如下载镜像时候,第一层相同,直接复用,其他几层分层下载

afb6ec6fdc1c: Already exists 
608641ee4c3f: Pull complete 
668ab9e1f4bc: Pull complete 
78a12698914e: Pull complete 
d056855f4300: Pull complete 
618fdf7d0dec: Pull complete 

举一个例子:例如创建一个ubuntu镜像,这是该镜像的第一层。如果添加了一个python环境包,就会在基础镜像层上创建第二个镜像层。如果继续添加一个补丁,就好创建第三个镜像层。
在这里插入图片描述

在额外添加镜像时,镜像始终保持当前镜像的组合。
例如:镜像包含了来自两个镜像层的6个文件,每个镜像层有三个文件。
在这里插入图片描述

如果变成三层镜像,其中文件7是文件5的更新版本,上层镜像层中的文件会覆盖底层镜像层中的文件。
在这里插入图片描述

所有镜像层合并,对外统一视图仍为6个文件
在这里插入图片描述

docker镜像都是只读的,当容器启动时,一个新的可写层被加=加载到镜像的顶部。(这一层被称为容器层,容器层之下都被称为镜像层)!

commit镜像
docker commit 提交容器成为一个新副本
#与git类似
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名[:tag]

例:

# 1、启动一个默认的tomcat
docker run -d -p 8080:8080 tomcat
# 2、这个默认的tomcat是没有webapps应用,官方的镜像默认webapps下面是没有文件的
docker exec -it 容器id
# 3、拷贝文件进去
cp -r webapps.dist/* webapps
# 4、将操作过的容器通过commit提交为一个镜像。
docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]
docker commit -a="jess" -m="add webapps app" 容器id tomcat02:1.0

容器数据卷

场景:如果数据存储在容器中,删除容器数据就会被删除。
需求:数据可以持久化。例如:mysql的数据保存在本地
在这里插入图片描述

容器之间都数据共享技术。docker产生的数据同步到本地,这就是卷技术。本质上就是目录的挂载,将容器中的目录挂载到我们的主机系统上。
总结:容器的同步操作和持久化,容器间也可以数据共享。

使用数据卷

主要使用-v参数

docker run -it --name centos01 -v 主机目录:容器目录 容器ID 使用的shell

这里以centos镜像为例

docker run -it --name centos01 -v /home/test:/home centos /bin/bash

此时主机的/home/test目录与容器中的/home目录中的所有内容都互通。
无论在哪一端修改,里面的内容都会同步

使用inspect命令查看是否挂载成功

#docker inspect 14309fc52d5d
回显内容包括以下内容即挂载成功
"Mounts": [{"Type": "bind","Source": "/root/test","Destination": "/home","Mode": "","RW": true,"Propagation": "rprivate"}],

前面说的修改nginx配置文件很麻烦,每次都要进入容器内部才能修改。
但是通过-v容器卷挂载,在容器外部提供一个映射路径,就可以解决这个问题了。

实战:mysql同步数据
 #启动mysql时需要设置密码
docker run -d --name mysql01 -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql

使用Navicat连接,这里的主机名改为自己的服务器ip即可。

在这里插入图片描述

连接成功,并新建一个数据库,名为test
在这里插入图片描述

可以看到在主机的/home/docke/data文件夹下也生成了test文件
在这里插入图片描述

将mysql容器删除,再次查看该文件夹,发现文件仍存在。这就达到了使用容器数据卷挂载的目的。
在这里插入图片描述

具名挂载、匿名挂载
匿名挂载:当使用-v参数不指定主机目录时
docker run -d --name nginx03 -P -v /etc/nginx nginx
#-P随机映射端口
具名挂载:卷名/容器内目录  #这里的卷名不带路径’/‘
docker run -d -P --name nginx04 -v juming-nginx:/etc/nginx nginx
docker volume ls #查看所有的卷

可以看到这两个卷,那么这两个卷在哪里呢
在这里插入图片描述

docker volume inspect juming-nginx #查找卷的路径
#可以看到,不指定目录的情况下,都会保存在/var/lib/docker/volumes目录下
[{"CreatedAt": "2024-11-20T19:11:24+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data","Name": "juming-nginx","Options": null,"Scope": "local"}
]
总结:
-v 容器内路径           #匿名挂载
-v 卷名:容器内路径      #具名挂载(比指定路径少一个/)
-v /主机路径:容器内路径 #指定路径挂载
拓展:还可以通过-v参数设置读写权限,但是一旦设置之后就不能修改
ro #readonly只读
rw #readwrite可读可写
docker run -d -P --name nginx04 -v juming-nginx:/etc/nginx:ro nginx  #只读
docker run -d -P --name nginx04 -v juming-nginx:/etc/nginx:rw nginx  #可读可写
如果看到ro,说明这个路径只能通过主机操作,容器内无法操作
容器间数据同步

使用--volumes-from参数实现容器间数据共享(可以当作备份、拷贝)

docker run -it --name docker01 centos_plus /bin/bashdocker run -it --name docker02 --volumes-from docker01 centos_plus /bin/bashdocker run -it --name docker03 --volumes-from docker02 centos_plus /bin/bash

操作其中一个容器,其他容器也会随之改变。
如果删除其中一个容器,其他容器中的文件还会在,数据卷容器的生命周期一直会持续到没有容器使用为止。

如果持久化到本地,本地的数据是不会删除的。

Dockerfile

简介及构建DockerFile方式

DockerFile就是用来构建docker镜像的构建文件(可以看作命令脚本,通过这个脚本可以生成镜像)

基础知识:
1、每个保留关键字(指令)都要大写
2、执行命令从上到下执行
3、#表注释
4、每个指令都会创建提交一个新的镜像层并提交

DockerFile:构建文件,定义了一切的步骤、源代码

DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品

Docker容器:容器就是镜像运行起来提供服务器

构建步骤
1、编写DockerFile文件
2、docker build构建镜像
3、docker run运行镜像
4、docker push发布镜像

#一个小例子,命名为file1
FROM centosVOLUME ["volume01","volume02"]  #匿名挂载CMD echo "----end----"CMD /bin/bash
docker build -f file1 -t centos_test .
-f参数 指定文件
-t参数 指定生成的镜像名
DockerFile指令
FROM        #基础镜像,一切从这里开始构建
MAINTAINER  #镜像是谁写的
RUN         #镜像构建时需要运行的命令
ADD  		#添加内容。以构建tomcat镜像为例,这是tomcat压缩包
WORKDIR     #镜像的工作目录
VOLUME		#挂载的目录
EXPOSE      #暴露端口配置 相当于-p
CMD			#指定这个容器启动时要运行的命令,但只有最后一个会生效,可以被替代
ENTRYPOINT  #与CMD类似,但可以追加命令
ONBUILD     #当构建一个被继承的DockerFile时,就会运行ONBUILD指令
COPY		#类似ADD,将文件拷贝到镜像中
ENV			#构建时,设置环境变量  -e

CMD与ENTRYPOINT的区别

CMD

#dockerfile文件
FROM centos:7
CMD ["ls","-a"]

build成功之后,run该容器时会执行该命令。

docker run 3608c6aac6fd -l     #会报错
docker run 3608c6aac6fd ls -al #会执行最后一个命令ls -al
docker run 3608c6aac6fd pwd    #只会执行pwd命令

说明CMD命令不能拼接命令,且只能执行最后一个命令(最后的命令会覆盖前面的命令)

ENTRYPOINT

FROM cnetos:7
ENTRYPOINT ["ls","-a"]

build成功之后

docker run 6beb6f712117 -l #会执行这两个参数,即ls -al

说明ENTRYPOINT可以进行拼接命令

实战:构建自己的centos

Docker Hub中绝大多数镜像都是在FROM scratch这个基础镜像之上构建的,然后配置需要的软件和配置来构建。

注意dockerifle文件中,最好不要有注释,构建之后会很难看

#编写dockerfile文件内容
FROM centos:7
MAINTAINER clockwise  #声明作者ENV MYPATH /usr/local 
WORKDIR $MYPATH   #定义工作目录,进入直接会进入该目录
#这里换成阿里云的centos7镜像
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
#基础镜像命令也是不全的,这里进行安装vim和ifconfig命令
RUN yum -y install vim
RUN yum -y install net-toolsEXPOSE 80  #暴露80端口CMD echo $MYPATH
CMD echo "end"
CMD /bin/bash
#通过dockerfile构建镜像
docker build -f file1 -t mycentos:1.0 .
#运行镜像
docker run -it mycentos:1.0

进入之后会发现当前的目录就是上面定义的/usr/local
vim命令和ifconfig命令也可以使用。

#使用history命令查看变更历史
docker history 6bc730024d72

可以看到镜像的制作过程命令(说明命令是一条一条进行编译的)

在这里插入图片描述

实战:构建自己的tomcat镜像

1、首先准备镜像文件:tomacat压缩包和jdk压缩包

2、构建DockerFile,官方命名为Dockerfile,使用该命名就不需要指定路径了

FROM centos:7
MAINTAINER clockwise
#通过ADD命令添加会自动解析
ADD jdk-8u201-linux-x64.tar.gz /usr/local/    
ADD apache-tomcat-9.0.12-src.tar.gz /usr/local/RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum -y install vimENV MYPATH /usr/local
WORKDIR $MYPATHENV JAVA_HOME /usr/local/jdk1.8.0_201
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.12-src
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.12-src
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080CMD /usr/local/apache-tomcat-9.0.12-src/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.12/bin/logs/catalina.out
docker run -d -p 9090:8080 --name mytomcat -v /root/tomcat_test/test:/usr/local/apache-tomcat-9.0.12-src/webapps/test -v /root/tomcat_test/logs:/usr/local/apache-tomcat-9.0.12-src/logs smalltomcat

docker网络

理解docker 0

这里服务器内网ip为192.168.12.87。

root@hcss-ecs-2214:/# 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 foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether fa:16:3e:a5:09:54 brd ff:ff:ff:ff:ff:ffinet 192.168.12.87/20 brd 192.168.15.255 scope global dynamic noprefixroute eth0valid_lft 315275508sec preferred_lft 315275508secinet6 fe80::f816:3eff:fea5:954/64 scope link valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:e2:20:15:88 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:e2ff:fe20:1588/64 scope link valid_lft forever preferred_lft forever#1、lo为本机回环地址
#2、为服务器内网地址
#3、docker0地址

这里使用tomcat进行测试,由于tomcat镜像过于精简,不带iproute2功能,这里需要自己新建一个镜像

#Dockerfile文件
FROM tomcat:latest
RUN apt update && apt install -y iproute2  #添加ip addr命令
RUN apt install -y iputils-ping  #添加ping命令
docker build -t newtomcat  #自己新建一个镜像起名为newtomcat

测试主机和容器之间的通信:

docker run -d -P --name tomcat01 newtomcatdocker exec -it tomcat01 ip addr

在这里插入图片描述

可以看到一个是回环地址127.0.0.1,一个是eth0@if123(docker自动分配的地址)的地址172.17.0.2

主机ping这个ip,发现可以Ping通。进入容器ping主机ip,发现也可以ping通。
说明主机和docker之间可以进行通信。

原理:

当启动docker容器时,docker会自动给docker容器分配一个ip,只要安装了docker就会有一个网卡docker0桥接模式,使用的技术是evth-pair技术

当只有一个容器的时候,在主机使用ip add命令查看网卡
在这里插入图片描述

可以看到主机中有一个·vethbdd6727@if122

此时,再建立一个容器命名为tomcat02,再去查看主机网卡
在这里插入图片描述

发现多了一个vethf99a830@if124

这说明docker容器生成的网卡都是一对一对的。
evth-pair就是一对的虚拟设备接口,他们是成对出现的,一段连接着协议,一段彼此相连。
由于这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备
OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术

测试容器之间的通信:

使用tomcat02去ping tomcat01的ip
docker exec -it tomcat02 ping 172.17.0.2
#可以ping通的

tomcat01和tomcat02都是共用一个路由器–docker0

所有容器不指定网络的情况下,都是由docker0给容器分配一个默认可用的ip。

虚拟网络接口的转发效率高

–link

通过--link,不通过网络、地址,容器之间通过容器名ping通。(–link只有构建容器时才可以使用)

docker exec -it tomcat02 ping tomcat01
#ping: tomcat01: Name or service not knowndocker run -d -P --name tomcat03 --link tomcat02 newtomcat
docker exec -it tomcat03 ping tomcat02
#tomcat03可以ping通tomcat02
#但是tomcat02不能ping通tomcat03

那么如何才能让tomcat02ping通tomcat03?

可以通过docker network inspect查看一下bridge中的网卡信息

root@hcss-ecs-2214:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
0d149ac9fdda   bridge    bridge    local
d5280ca25d4b   host      host      local
6855cd3d7f31   none      null      local
root@hcss-ecs-2214:~# docker network inspect 0d149ac9fdda
[{"Name": "bridge","Id": "0d149ac9fddafe29418226287d8450e5016bb5a120a57f0a3726f5dbca5079e6","Created": "2024-11-20T18:01:30.899264891+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{"Subnet": "172.17.0.0/16","Gateway": "172.17.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"37bcfb2c3a5ee8a6990d962654fd928803d7dcca75ce95019101875242116e44": {"Name": "tomcat03","EndpointID": "9c295d4859973080e89c835997fa3f5afa592c22028bc71509cb3a044a8bf202","MacAddress": "02:42:ac:11:00:04","IPv4Address": "172.17.0.4/16","IPv6Address": ""},"4e3107cadc5e7984d7cb500b9a3d6dd121d597a35ba3c03ed48386379072db59": {"Name": "tomcat01","EndpointID": "b10e9a3b00226b66013239f18121f0f1c71f317d84eee0f923ffbe5a5c0c9eaf","MacAddress": "02:42:ac:11:00:02","IPv4Address": "172.17.0.2/16","IPv6Address": ""},"65aca855c46bc57e730842cff5a1cabb2ca14633b8ddc20536e6ad9ee69b13b2": {"Name": "tomcat02","EndpointID": "0e81426b6c74065dd90036b6d9911f8b6cf136d653625144ca2e320543527ce8","MacAddress": "02:42:ac:11:00:03","IPv4Address": "172.17.0.3/16","IPv6Address": ""}},"Options": {"com.docker.network.bridge.default_bridge": "true","com.docker.network.bridge.enable_icc": "true","com.docker.network.bridge.enable_ip_masquerade": "true","com.docker.network.bridge.host_binding_ipv4": "0.0.0.0","com.docker.network.bridge.name": "docker0","com.docker.network.driver.mtu": "1500"},"Labels": {}}
]

然后查看tomcat03的hosts文件可以看到在tomcat03本地已经配置了tomcat02的地址

docker exec -it tomcat03 cat /etc/hosts
root@hcss-ecs-2214:~# 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 65aca855c46b
172.17.0.4      37bcfb2c3a5e

由于docker0不支持容器名访问等问题,因此出现了自定义网络

自定义网络
docker network --help查看docker网络相关命令

查看所有docker网络

docker network ls 
root@hcss-ecs-2214:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
0d149ac9fdda   bridge    bridge    local
d5280ca25d4b   host      host      local
6855cd3d7f31   none      null      local

桥接模式:

bridge:桥接docker

none:不配置网络

host:和宿主机共享网络

container:容器内网络连通(用的少)

#平时启动容器时,默认使用--net bridge
docker run -d -P --name tomcat01 newtomcat
docker run -d -P --name tomcat01 --net bridge newtomcat#自定义网络
docker network create --help #查看相关命令
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
#--driver bridge 桥接模式
#--gateway参数设置网关,家庭路由器默认就是192.168.0.1#使用inspect命令查看
docker network inspect mynet

可以看到已经创建成功
在这里插入图片描述

#启动两个容器测试一下
docker run -d -P --name tomcat01 --net mynet newtomcat
docker run -d -P --name tomcat02 --net mynet newtomcat

inspect查看一下mynet,可以看到成功指定该网络
在这里插入图片描述

#现在使用容器名和ID都可以互相ping通过了
docker exec -it tomcat01 ping tomcat02 
网络连通

在这里插入图片描述

docker run -d -P --name tomcat-net-01 --net mynet tomcat-net
docker run -d -P --name tomcat-net-02 --net mynet tomcat-netdocker run -d -P --name tomcat-01 tomcat-net
docker run -d -P --name tomcat-02 tomcat-net

测试tomcat-01和mynet打通(tomcat-02同理)

docker network connect mynet tomcat-01
然后使用inspect查看
docker network inspect mynet

在这里插入图片描述

发现成功将tomcat-01放到mynet网络下。(即一个容器两个地址)
之后在该mynet网络下的容器就可以互相通信了。

实战:Redis集群部署
#创建redis网卡
docker network create redis --subnet 172.38.0.0/16#通过脚本创建(之间复制到命令行即可)
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
#执行完可以看到在/mydata/redis目录下生成了6个node-目录docker run -p 6371:7379 -p 16371: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; \
#这是第一个,以此类推,写六个
docker run -p 6371:7379 -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 --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
#这是第二个
docker run -p 6372:7379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

在这里插入图片描述

进入第一个容器(这里没有/bin/bash,要用/bin/sh)

docker exec -it redis-1 /bin/sh
#创建集群
redis-cli --cluster create 172.38.0.11:6371 172.38.0.12:6372 172.38.0.13:6373 172.38.0.14:6374 172.38.0.15:6375 172.38.0.16:6376 --cluster-replicas 1
关键字:程序员培训多少钱_装修设计网站排名_推广专员是做什么的_营销推广策略

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: