docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]

docker学习大纲

  • docker概述

  • docker安装

  • docker命令

    • 镜像命令

    • 容器命令

    • 操作命令

  • docker镜像

  • 容器数据卷

  • dockerfile

  • docker网络原理

  • IDEA整合docker

  • docker compose

  • docker swarm

  • CI\CD Jenkins

1.docker概述

docker为什么会出现?

一款产品: 开发–上线 两套环境! 应用环境,应用配置

开发----运维 (我在我的电脑上可以运行)

环境配置麻烦,每一台机器要部署环境(集群redis,es,hadoop…)!费时费力

发布一个项目(jar + (redis mysql es)),项目+环境一起打包!

传统 : 开发jar包,运维来做

现在 : 开发打包部署上线,一套流程完成,不需要运维!

java —apk ----发布 (应用商店)—下载安装即可用

java —jar(环境) —打包项目带上环境(镜像) —docker仓库 : 商店 下载镜像—直接运行

docker总体上就是避免了环境造成的影响

docker思想来自于集装箱!

jre —多个应用(端口冲突) —原来都是交叉的!

隔离 : docker核心思想!打包装箱!每个箱子是互相隔离的! docker通过隔离机制,可以将服务器利用到极致!

docker的官方地址:https://www.docker.com/ 文档 : https://docs.docker.com/

docker仓库地址: https://hub.docker.com/

2.docker能干什么

之前的虚拟机技术

虚拟机技术缺点:

  1. 资源占用多
  2. 冗余步骤多
  3. 启动很慢

容器化技术:

容器化技术不是模拟的一个完成的操作系统!

比较docker和虚拟机技术的不同:

  • 传统虚拟机,虚拟出一条硬件,运行一个完成的操作系统,然后再这个系统上安装和运行软件
  • 容器内的应用直接运行在宿主机上的内核上,容器是没有自己的内核的,也没有虚拟硬件,所以也就轻便
  • 每个容器间都是互相隔离的,每个容器内都有一个属于自己的文件系统,互不影响

DevOps (开发,运维)

更快速的交付和部署

传统 : 一堆帮助文件 , 安装程序

docker : 打包镜像,发布测试,一键运行

更便捷的升级和扩缩容

使用docker之后,我们部署应用就和搭积木一样!

项目打包为一个镜像,扩展服务器A 服务器B (水平扩展,负载均衡)

更简单的系统运维

在容器化后,我们开发,测试都是高度一致的.

更高效的计算资源利用

docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例!服务器的性能可以被压榨到极致.

3.docker安装

3.1docker的基本组成

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第1张图片

镜像(image) :

docker镜像就好比一个模板,可以通过这个模板来创建容器服务,tomcat镜像===>run===>tomcat01容器(提供服务)

,通过一个镜像可以创建多个容器(最终服务运行或者项目运行在容器中)

容器(container):

docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建容器

启动,停止,删除,基本命令

容器就是一个简易的linux系统

仓库(repository):

仓库就是存放镜像的地方!仓库分为共有仓库和私有仓库

docker hub

阿里云 配置国内镜像加速

3.2安装命令

环境查看

# 系统内核
[root@localhost /]# uname -r
3.10.0-862.el7.x86_64
# 系统版本
[root@localhost /]# cat /etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

安装 官方文档: https://docs.docker.com/engine/install/centos/

# 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 国外
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 阿里云
    
# 更新软件包索引
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
# 7.测试
docker run hello-world   # 一般是没有当前镜像
# 8.卸载docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker # docker默认的工作资源路径
rm -rf /var/lib/containerd   

3.3配置阿里云镜像加速

mkdir -p /etc/docker

vim /etc/docker/daemon.json 
{
	"registry-mirrors": ["https://9cpn8tt6.mirror.aliyuncs.com"]
}

systemctl daemon-reload
systemctl restart docker

docker run 的运行原理图

docker底层原理

docker是如何工作的?

docker是一个client-server结构的系统,docker的守护进程运行在主机上,通过Socket从客户端访问!dockerserver 接收到docker-client的指令,就会执行这个命令.

docker为什么比虚拟机快?

  1. docker有比虚拟机更少的抽象层
  2. docker利用的是宿主机的内核,vm需要guest os.
docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第2张图片

所以说,新建一个容器时,docker不需要像虚拟机一样重新加载一个操作系统内核.vm是分钟级别的,docker是利用宿主机的操作系统,省略这一过程,docker是秒级的.

3.3镜像命令

帮助命令

docker version
docker info	   #显示docker的系统信息,镜像和容器信息
docker --help / docker 命令 --help  #当前命令的细节使用,万能命令

# 如
[root@localhost ~]# docker images --help

Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show image IDs

帮助文档地址: 进入官网,找doc找reference

镜像命令

docker images #查看所有本机镜像

docker search #搜索镜像
docker search mysql 
docker search --filter=stars=3000 # 3000以上(stars,收藏数)

docker pull #下载镜像
docker pull mysql # 默认最新的版本,分层下载,docker images的核心 联合文件系统:实际中,下载过的就不					 会重复下载,极大的节省内存
docker pull 镜像名[:tag] # docker pull mysql:5.7

docker rmi #删除镜像
docker rmi  镜像id/镜像名称   # docker rmi -f(全删) 
docker rmi  $(docker images -aq) # 删除所有镜像

容器命令

说明: 我们有了镜像才可以创建容器

启动镜像

docker run # 启动镜像

# 参数说明
--name="name" 容器名称
-d 			  后台运行
-it			  交互方式运行,进入容器查看内容
-p		  	  指定容器端口,主机映射	
	-p ip:主机端口:容器端口
	-p 主机端口:容器端口
	-p 容器端口
	容器端口
-P 			  随机指定端口

3.4容器命令

查看容器

docker ps # 运行中的容器
docker ps -a # 所有容器
docker ps -n=?  # 显示最近创建的容器 ?是个数
docker ps -q   # 只显示容器的编号  -aq就是所有

退出容器

exit # 容器停止退出
Ctrl + p + q # 容器不停止退出

删除容器

docker rm 容器id # 删除指定容器,不能删除正在运行的容器,强制删除 加 -f
docker rm -f $(docker ps -aq) # 删除所有的容器
docker ps -a -q|xargs docker rm # 删除所有的容器

启动,停止和重启容器

docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id # 强制停止当前容器 stop报错时用

例如

docker run -it centos /bin/bash  # 交互启动,并进入容器控制台
exit # 退出容器

3.5常用其他命令

后台启动容器

# 命令 docker run -d 镜像名/id 后台运行容器

# 问题docker ps 时发现当前容器停止了

# docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
# 如nginx,容器启动后,发现自己没有提供服务,就会立即停止(自杀)

查看日志

docker logs -f -t [--tail 日志条数] [容器id]  # 容器,没有日志

docker run -d [容器名称/id] -c "while true;do echo kuangshen;sleep 1;done"

显示日志
-tf     # 显示日志
--tail number # 显示多少条日志

查看容器的进程信息

docker top 容器id

查看镜像的元数据

# docker inspect 容器id

[root@localhost ~]# docker inspect dea069283958
[
    {
        "Id": "dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f",
        "Created": "2022-03-14T02:28:55.599139597Z",
        "Path": "-c",
        "Args": [
            "while true;do echo lipengg;sleep 1;done"
        ],
        "State": {
            "Status": "created",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 127,
            "Error": "OCI runtime create failed: container_linux.go:380: starting container process caused: exec: \"-c\": executable file not found in $PATH: unknown",
            "StartedAt": "0001-01-01T00:00:00Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412",
        "ResolvConfPath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/hostname",
        "HostsPath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/hosts",
        "LogPath": "/var/lib/docker/containers/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f/dea069283958af9d524185fd0bca1e8a5b86ea3a5f14cef43d69209915592d2f-json.log",
        "Name": "/vigilant_engelbart",
        "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/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24-init/diff:/var/lib/docker/overlay2/7be1ddf0bbc549ea7f722c77e9ae046ea9a317d8f41061cea21d6a567c8ca9cd/diff",
                "MergedDir": "/var/lib/docker/overlay2/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24/merged",
                "UpperDir": "/var/lib/docker/overlay2/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24/diff",
                "WorkDir": "/var/lib/docker/overlay2/3d1718c9efecc2a64d836fb45b2a14cb36b791f2d950e46936d8574b9cfe0e24/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],		# 挂载,就是做数据卷映射的时候的一些信息
        "Config": {
            "Hostname": "dea069283958",
            "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": [
                "-c",
                "while true;do echo lipengg;sleep 1;done"
            ],
            "Image": "feb5d9fea6a5",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "a4a3e343b2a2d696266f046afb3ffae1543b51a5ff85148b0fa4219e28b54600",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/a4a3e343b2a2",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "82e66b0d7cbbba16fc6e02714ea5f315bb2a9e2d9a2cbc5f4177f17cd8f1ce99",
                    "EndpointID": "",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }
        }
    }
]

进入当前正在运行的容器

# 我们通常容器都是采用后台方法运行的,需要进入容器,修改一些配置
docker exec -it 容器id [/bin/bash]

# docker
docker ps -it 

#docker attach 容器id

# docker exec  # 进入容器开启个新的终端,可以在里面进行操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程. 

3.6从容器内拷贝文件到主机上

# 命令 docker cp 容器id:容器内路径	目的路径
# 进入docker容器内部
docker attach b12343556

# 新建之后,退出容器
touch test.java

docker cp b12343556:/home/test.java /home

# 拷贝是一个手动的过程,使用数据卷 -v ,实现自动cp

3.7导入导出镜像

# 将pull下来的镜像打包成压缩包文件
 docker save 镜像id -o /home/local_centos.tar		
 docker export 容器id -o /home/local_centos.tar	
# 将本地镜像加载到docker
 docker load 镜像压缩包  # 和 save共用
 docker import 镜像压缩包  # 和 export共有
 
 特别注意:两种方法不可混用。如果使用 import 导入 save 产生的文件,虽然导入不提示错误,但是启动容器时会提示失败,会出现类似"docker: Error response from daemon: Container command not found or does not exist"的错误。
 
 1,文件大小不同
export 导出的镜像文件体积小于 save 保存的镜像
 
2,是否可以对镜像重命名
docker import 可以为镜像指定新名称
docker load 不能对载入的镜像重命名
 

3,是否可以同时将多个镜像打包到一个文件中
docker export 不支持
docker save 支持
 

4,是否包含镜像历史
export 导出(import 导入)是根据容器拿到的镜像,再导入时会丢失镜像所有的历史记录和元数据信息(即仅保存容器当时的快照状态),所以无法进行回滚操作。
而 save 保存(load 加载)的镜像,没有丢失镜像的历史,可以回滚到之前的层(layer)。
 
5,应用场景不同
docker export 的应用场景:主要用来制作基础镜像,比如我们从一个 ubuntu 镜像启动一个容器,然后安装一些软件和进行一些设置后,使用 docker export 保存为一个基础镜像。然后,把这个镜像分发给其他人使用,比如作为基础的开发环境。
docker save 的应用场景:如果我们的应用是使用 docker-compose.yml 编排的多个镜像组合,但我们要部署的客户服务器并不能连外网。这时就可以使用 docker save 将用到的镜像打个包,然后拷贝到客户服务器上使用 docker load 载入。


详细见
https://www.cnblogs.com/cj1698/p/15534197.html

练习

一.docker 安装 nginx
1.搜索镜像 
docker search nginx
2.下载镜像
docker pull nginx
3.运行启动镜像
docker run -d --name nginx -p 3344:80 nginx/nginx的id
4.本地测试
curl localhost:3344

5.进入nginx
docker exec -it nginx /bin/bash 
6.查看位置
whereis nginx

思考问题: 我们每次改动nginx配置文件,都需要进入容器内部,十分麻烦,我要是可以在容器外部提供一个映射路径,达到在容器外修改配置文件,就可以在文件内部自动修改 ? 因此,有了数据卷!

二.安装 tomcat
# 官方文档
docker run -it --rm tomcat:9.0
# 我们之前启动都是后台,停止了容器之后,容器依然存在, docker run -it --rm,一般用来测试,用完就删除.

# ...下载镜像

# 启动运行
docker run -d -p 3355:8080 --name tomcat01 tomcat
# 测试访问
404
# 进入容器
docker exec -it tomcat01 /bin/bash
# 发现问题.1.linux命令少了.2.没有webapps,阿里云镜像的原因,默认是最小的镜像,所有不必要的都已经剔除.
# 保证最小可运行环境
三.安装 es+kibana
# es 暴露的端口很多
# es 十分的耗内存
# es 的数据一般需要放置到安全目录!挂载
# --net somenetwork ? 网络配置

# 启动 elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2 

# 启动了 linux就卡住了  docker status 查看cpu的状态

#一般启动es之前增加内存限制,修改配置文件 -e 环境配置修改
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_java_opts="-Xms64m --Xmx512m" elasticsearch:7.6.2 

kibana + es

3.7可视化

  • portainer(先用)
docker run -d -p 8088: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 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

访问测试 :

4.docker镜像

特点 : docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!

这一层就是我们通常说的容器层,容器层之下都叫镜像层!

如何提交一个自己的镜像?

4.1commit镜像

docker commit 提交容器成为一个新的副本

# 命令和git原理相同

docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[tag(版本)]

实战操作

#启动一个默认的tomcat
docker run -it -p 8080:8080
#发现这个默认的tomcat 是没有webapps应用,镜像的原因,官方的镜像默认webapps下是没有内容的!
#自己需要cp文件到webapps
cp webapps.dict/* webapps
#将修改后的容器,通过commit提交为一个新的镜像,这样以后我们使用这个新镜像就避免可上述操作
docker commit -m="add webapps app" -a="lpg" 容器id tomcat02:1.0

如此就相当于保存了当前容器的状态,获得一个镜像

就好比虚拟机的快照!

容器数据卷,dockerfile,Docker网络才是docker的精髓所在

5.容器数据卷

5.1什么是容器数据卷?

数据?如果在容器当中,那么容器被删除,数据也就会丢失 ! 需求 : 数据可以持久化

mysql,容器删了,删库跑路 ! 需求 : mysql数据可以存储在本地 !

所以需要,容器之间可以有一个数据共享的技术 ! docker容器中产生的数据 , 同步到本地 !

如此,便是卷技术 ! 目录的挂载 ,将我们容器内的目录挂载到linux上面

好处 : 我们以后修改只需要在本地修改即可,因为容器内会自动同步

总结 : 卷,就是容器的持久化和同步操作 ! 容器间也是可以数据共享的(多个容器映射一个目录)

5.2使用数据卷

方式一 : 直接使用命令来挂载 -v

docker run -it -v 主机目录:容器内目录 
docker run -it -v /home/test:/home/test centos /bin/bash

# 查看容器的详细信息
docker inspect 容器id 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dSFW00UQ-1655110483997)(D:\后端养成记\笔记\docker\docker_images\image-20220318104320617.png)]

5.3实战,安装mysql

思考:mysql的数据持久化问题?

# 拉取mysql5.7版本的镜像
docker pull mysql:5.7
# 启动运行加数据卷 -v 映射多个  配置 数据 , -e表示环境配置
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 mysql5.7
# 将容器删除,我们宿主机的数据还在,数据并没有丢失,这就是mysql的数据持久化功能!
docker rm -f mysql01

5.4具名挂载和匿名挂载

# 匿名挂载 -P 随机指定端口
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看所有的 volume 的情况
docker volume ls
local     53484a4631971e8cc46af7217d046a63eae7105d2a572dcfffc7c6107aa3ae77
# 这里发现,这种就是匿名挂载,我们在 -v 只写了容器内的路径,没有写容器外的路径!

# 具名挂载
-v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
docker volume ls

local juming-nginx
# 通过 -v 卷名:容器内路径

所有docker容器内的卷,没有指定目录的情况下都在 /var/lib/docker/volumes/xxxx/_data

我们通过具名挂载可以方便的找到一个卷,大多数情况都使用具名挂载

# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径  #匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v 宿主机路径:容器内路径 #指定路径挂载

拓展

# 通过 -v 容器内路径:ro 或 rw 改变读写权限
# ro readOnly  只读   	只能通过宿主机改变,容器内部无法改变内容
# rw readWrite 可读可写    默认

# 一旦设置了容器权限,容器对我们挂载出的内容即有了限制!
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

5.5初始dockerfile

dockerfile 就是用来构建 docker 镜像的构建文件 ! 本质就是一个命令脚本 !

通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,所以,一个命令就是一层!

# 在/home/下建立一个新的文件
touch dockerfile1
# vi 进入文件编辑脚本 	指令都是大写!
FROM tomcat8.0
VOLUME ["volume01","volume02"]	# 在生成镜像时就挂自动载   匿名挂载
CMD echo "---end---"
CMD /bin/bash
# 运行生成新镜像 -f dockerfile的路径  -t生成镜像的名称和版本  最后的空格 + 点 表示在当前目录下生成
docker build -f /home/dockerfile1 -t lipengg-tomcat:1.0 .

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uuxpXCbC-1655110483999)(D:\后端养成记\笔记\docker\docker_images\image-20220318163803251.png)]

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第3张图片 docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第4张图片

总结 : 这种方式我们未来使用的十分多,因为我们通常会构造自己的镜像 !

假设构建镜像时没有挂载卷,则需要手动镜像挂载 -v 卷名:容器内路径

5.5数据卷容器

容器间的数据共享

例如 , 两个或多个mysql同步数据 !

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第5张图片
# 启动三个容器,测试是否同步  使用镜像id好一点,用name在volumes-from时还是有问题
docker run -it --name docker01 lipengg-tomcat:01	# 交互式进入,此时可以使用ctrl+p+q退出
docker run -it --name docker02 --volumes-from docker01 lipengg-tomcat:01
docker run -it --name docker03 --volumes-from docker01 lipengg-tomcat:01

利用指针指向,docker02和docker03都指向了宿主机的地址,所以删除了docker1也没有问题.

此时,在没有docker01的情况下,docker02和docker03之间还是数据同步的

用docker inspect检查三个容器会发现其实都映射到了宿主机的相同目录

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第6张图片

用docker inspect检查三个容器会发现其实都映射到了宿主机的相同目录

多个mysql实现数据共享

docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/con.f -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

docker run -d -p 3311:3306 -v /home/mysql/conf:/etc/mysql/con.f -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

# 匿名
docker run -d -p 3310:3306 -v /etc/mysql/con.f -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

结论 :

容器之间配置信息的传递 , 数据卷容器的生命周期一致持续到没有容器使用为止 !

但是一旦你持久化到本地, -v到本地 ,就算容器都没有了,数据依然存在 !

6.dockerfile

6.1dockerfile介绍

dockerfile是用来构建docker镜像的命令 ! 命令参数脚本 !

构建步骤 :

1.编写一个dockerfile文件

2.docker build构建成为一个镜像

3.docker run运行生成的镜像

4.docker push发布镜像(dockerHub , 阿里云镜像仓库)

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第7张图片

很多官方镜像都是基础包 , 很多功能没有,我们通常会自己搭建自己的镜像 !

6.2dockerfile的构建过程

基础知识:

  1. 每个保留字(指令)都必须是大写
  2. 从上到下执行
  3. “#” 表示注释
  4. 每一个命令都会创建提交一个新的镜像 , 并提交 !
docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第8张图片

dockerfile是面向开发的 , 我们以后发布项目 , 做镜像 , 就需要编写dockerfile文件 !

docker镜像逐渐成为企业交付的标准 , 必须掌握 !

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

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

dockerContainer : 容器就是镜像运行起来提供的服务器 !

6.3dockerfile的指令

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第9张图片 docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第10张图片

6.4实战测试

docker hub 中99%的镜像都是FROM scratch镜像来的

创建一个自己的centos镜像

touch mydockerfile-centos
# 1.编写dockerfile文件
FROM centos
MAINTAINER lipengg<12345678@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH    # 工作目录

# 加运行的命令
RUN yum -y install vim	
RUN yum -y install net-tools

EXPOSE 80

CMD echo MYPATH		# 输出
CMD echo "---end---"
CMD /bin/bash  # 最终进入/bin/bash

# 2.通过文件构建镜像
# docker build -f 文件路径+文件 -t 镜像名:版本 .是当前目录下生成
docker build -f mydockerfile-centos -t mycentos:0.1 .

# 3.测试
docker run -it mycentos:0.1   # 直接进入工作目录,且vim和ipconfig命令也可以用

# 4.查看镜像的构建历史
docker history 镜像id

CMD和ENTRYPOINT的区别

CMD		   # 指定这个容器启动时候要运行的命令,只有最后一个会生效(run成功后,打印出来),可被替代
ENTRYPOINT  # 指定这个容器启动时候要运行的命令,可以追加命令
# 构建cmd测试文件
touch centos-cmd-test

FROM centos
CMD ["ls","-a"]

# build镜像
# run执行
docker run 镜像
成功,打印出ls -a的信息
# 想追加一个命令
docker run 镜像 -l  # 预想是执行ls -al 显示详细信息,实际报错
# 原因 : cmd的最后一个命令是l,l不是命令 
# 构建entrypoint测试文件,追加命令
touch centos-entrypoint-test

FROM centos
ENTRYPOINT ["ls","-a"]

# build镜像
# run执行
docker run 镜像
成功,打印出ls -a的信息
# 想追加一个命令
docker run 镜像 -l  
执行成功    # 实际是执行了ls -al,追加了命令

6.5实战 : Tomcat镜像

1.准备镜像文件tomcat , jdk 压缩包

2.编写Dockerfile文件,官方命令Dockerfile,build命令会自动寻找这个文件 , 也就不需要 -f 进行指定了 !

FROM centos
MAINTAINER lipengg<12345678@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD apache-tomcat-8.5.70.tar.gz  /usr/local/	# ADD 命令会自动解压
ADD jdk-8u152-linux-x64.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local4
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.0_152
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar    # 冒号就是将两个路径隔开
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.70
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.70
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$CATALINA_HOME/lib

EXPOSE 8080

CMD /usr/local/apache-tomcat-8.5.70/bin/startup.sh && tail -f /usr/local/apache-tomcat-8.5.70/bin/logs/catalina.out

3.构建镜像

docker build -t diytomcat .

4.启动镜像

docker run -d -p 9090:8080 --name lipenggtomcat -v /home/tomcat/test:/usr/local/apache-tomcat-8.5.70/webapps/test -v /home/tomcat/tomcatlogs:/usr/local/apache-tomcat-8.5.70/logs diytomcat

5.访问测试

curl localhost:9090

6.发布项目 (做了卷挂载,我们直接在本地编写项目就可以发布)

# 我们的tomcat挂载到了/home/tomcat/test 目录
# 进入到该目录
mkdir WEB-INF
cd WEB-INF
vim web.xml  # 写入下面的web.xml文件内容

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
    
</web-app>

# cd 到test目录
vim index.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>首页</title>
</head>
<body>
<%
System.out.println("-----hello world------");
%>
</body>
</html>

6.6 发布自己的镜像

再议

docker小结

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第11张图片

7.docker网络

铺垫,容器编排,集群部署!

7.1理解docker0

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第12张图片
# 问 : docker是如何处理网络访问的 ?
# 例如 ,tomcat如何连接到mysql

# 先启动一个tomcat
docker run -d -P --name mytomcat01 tomcat
# 查看容器内部的网络 
docker exec -it mytomcat01 ip addr
docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第13张图片
# 思考 ,linux本地能否ping通容器内部 ?
[root@localhost ~]# 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.220 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.085 ms

原理

  1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip ,我们只要安装了docker ,就会有一个网卡docker0

而docker0使用的是桥接模式 ,桥接模式使用的技术就是evth-pair技术 !

当启动容器之后 ip addr

43: veth4ae83a6@if42: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 56:8b:84:25:86:4f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::548b:84ff:fe25:864f/64 scope link 
    valid_lft forever preferred_lft forever
  1. 在启动一个容器之后,就会再增加一个

而且 ,本地ip addr和容器内部ip addr后会发现

本地 : 43: veth4ae83a6@if42

容器内部 : 42: eth0@if43

二者是成对出现的

再启动一个容器后 ,就会是44和45

本地 : 45: veth995d510@if44:

容器内部 : 44: eth0@if45:

# evth-pair 技术 ,就是网卡的出现都是成对的
# 一对网卡就是一对虚拟设备接口 ,它们都是成对出现的 ,一端连接协议 ,一端彼此相连.
# 正因为有这个特性 ,evth-pair充当一个桥梁 ,连接各种虚拟网络设备
# openStac ,docker容器之间的连接 ,ovs的连接 ,都是使用evth-pair技术 
docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第14张图片

问 : 此时容器之间是否可以相互ping通 ?

[root@localhost ~]# docker exec -it mytomcat01 ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.571 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.133 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.131 ms

[root@localhost ~]# docker exec -it mytomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.126 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.128 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.133 ms

结论 : 容器与容器之间是可以ping通的

注意 : 容器之间实际通信并不是直连的

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第15张图片

docker中所有的网络接口都是虚拟的 ,虚拟的转发效率高 ! (内网传递文件 !)

只要容器删除 ,对应的evth-pair网桥对就消失

思考 : 我们编写一个微服务 ,datavaseUrl = ip:端口 ,如果用docker启动 , 每次ip发生变化 ,则此url失效

此时 , 我们应该如何去处理 ?

参考微服务springCloud , feign的存在 , 帮助我们使用服务名去访问 !

docker提供了–link

7.2容器互联–link

# 在原来的基础行 ,我们改用容器名ping
[root@localhost ~]# docker exec -it mytomcat01 ping mytomcat02
ping: unknown host

# 使用link去连接mytomcat02容器
[root@localhost ~]# docker run -d -P --name mytomcat03 --link mytomcat02 b8dfe9ade316
[root@localhost ~]# docker exec -it mytomcat03 ping mytomcat02
PING mytomcat02 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.109 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.130 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.131 ms
[root@localhost ~]# docker exec -it mytomcat02 ping mytomcat03
ping: unknown host

# 此时我们发现通过--link进行绑定的容器名和ip,并不是双向的 !

探究docker网络

# docker当前网络
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e7a83f201666   bridge    bridge    local
c289a29e595b   host      host      local
3bdca47b627d   none      null      local
# inspectdocker0的网络信息 ,bridge
[root@localhost ~]# docker network inspect e7a83f201666
[
    {
        "Name": "bridge",
        "Id": "e7a83f201666cc2db85a133e2fe857369c8b9a44fb67c82ad3190272818d5032",
        "Created": "2022-03-25T15:08:34.025252475+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"			# docker0 路由
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "02b08f62e4aa41d12cef3cac005316144b6926d95c96197d4cafedb815ef3403": {
                "Name": "mytomcat03",
                "EndpointID": "09c706a5e4b5800c0e80b1029514b0e5095780671cf18f6cf9e5d64bffb41b5a",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",			# docker0自动分配
                "IPv6Address": ""
            },
            "1cdbd7eb3cdf3e92e4dac9404a813fc3190534d570f4a78c8f5d711a5030b001": {
                "Name": "mytomcat02",
                "EndpointID": "5bab48d6b1e30bb03e6b18d5d43d19f045c639c4fb48ea8a8b4e8b18d4961e1c",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",			# docker0自动分配
                "IPv6Address": ""
            },
            "95d4c2a7ca777c58483ecdd05c69f555ca01bf6503200b1b11dff4233e0ac04d": {
                "Name": "mytomcat01",
                "EndpointID": "6d98c0d3cfa15e95f94f12818e825b3cbbdb2e5737712e452b2cc5de7ebfefd9",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",			# docker0自动分配
                "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": {}
    }
]

# 进入tomcat02/03  查看host配置
[root@localhost ~]# docker exec -it mytomcat03 /bin/bash
root@02b08f62e4aa:/# cat /etc/hosts			也可以一步 docker exec -it mytomcat03 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      mytomcat02 1cdbd7eb3cdf     # 发现在tomcat03中增加了tomcat02的映射配置
172.17.0.4      02b08f62e4aa

在docker中已经不建议使用 --link !

自定义网络 ! 不适用docker0 !

docker0问题 : 不支持容器名访问 !

7.3自定义网络(重点)

查看所有的docker网络

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第16张图片

网络模式

bridge : 桥接 docker(默认)

none : 不配置网络

host : 和宿主机共享网络

container : 容器内网络连通 (用的少 ! 局限性很大 !)

测试

# 我们直接启动的命令   --net bridge默认就有 ,不需要手动加 ,而这个就是我们的docker0叫bridge
docker run -d -P --name tomcat01 [--net bridge] tomcat

# docker0特点 : 默认 ,不能通过名称访问 . 但可以用 --link可以打通连接

# 我们可以自定义一个网络
# --driver bridge 网络模式 (不指定默认是bridge)
# --subnet 192.168.0.0/16 子网
# --gateway 192.168.0.1 网关(路由)
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
7607be71142d4724944a6b9dd114006b6e96a2fe58b3cb384449e87d2f245f0e
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
e7a83f201666   bridge    bridge    local
c289a29e595b   host      host      local
7607be71142d   mynet     bridge    local
3bdca47b627d   none      null      local
docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第17张图片

在自己的网络中启动容器

[root@localhost ~]# docker run -d -P --name tomcat-mynet-01 --network mynet b8dfe9ade316
3d5eb9483fc3bdf1bfe4ceff313034084ac98ec14c1f68fc66732b0d8adf7587
[root@localhost ~]# docker run -d -P --name tomcat-mynet-02 --network mynet b8dfe9ade316
3c7b8235eab8888a33b39e76fb2dbf8be9deab8e5d424368618d61e1dc662128
[root@localhost ~]# docker network inspect mynet 
...
"Containers": {
            "3c7b8235eab8888a33b39e76fb2dbf8be9deab8e5d424368618d61e1dc662128": {
                "Name": "tomcat-mynet-02",
                "EndpointID": "d1cc522577f52f8183ee0866711447edb5ceabd6a50a45fd3449110e69499beb",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "3d5eb9483fc3bdf1bfe4ceff313034084ac98ec14c1f68fc66732b0d8adf7587": {
                "Name": "tomcat-mynet-01",
                "EndpointID": "6f403d72f49a6ca88c9594cb0437963920eb3c0305c5f663df2c2adbd5f58c57",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },

...

# 此时测试能够ping通
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.182 ms
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.135 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.091 ms
^C--- 192.168.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.091/0.136/0.182/0.037 ms
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping tomcat-mynet-02
PING tomcat-mynet-02 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.052 ms
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.223 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.133 ms

# 发现,在自定义网络中,不仅可以通过ip ping,而且 ,在没有--link的情况下 ,也可以通过容器名称 ping

结论 : 我们自定义网络docker都已经帮我们维护好了对应的关系 ,推荐使用自定义网络 !

好处 : 当我们在搭建redis,mysql集群时,使用自定义网络,因为都有不同的子网,保证了集群的安全与健康

7.4网络连通

如何在docker中连通两个在不同网段的容器

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第18张图片

问 : tomcat01如何可以ping通tomcat-mynet-01 ?

# docker network的connect命令
[root@localhost ~]# docker network --help
Commands:
  connect     Connect a container to a network

#将tomcat01加入到mynet网络中
[root@localhost ~]# docker network connect mynet tomcat01
[root@localhost ~]# docker network inspect mynet
...
            "b6bc62f9fbcd8e469e1de9473438035eadb9ab1f68bf09d29df8562c5e01141e": {
                "Name": "tomcat01",
                "EndpointID": "ede2eea516ffa923ea1eafc52be3180e735c95419c9822c05426e22dc79ed263",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
...

# 此时去ping ,双向都通
[root@localhost ~]# docker exec -it tomcat01 ping tomcat-mynet-01
PING tomcat-mynet-01 (192.168.0.2): 56 data bytes
64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=0.705 ms
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.117 ms
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping tomcat01
PING tomcat01 (192.168.0.4): 56 data bytes
64 bytes from 192.168.0.4: icmp_seq=0 ttl=64 time=0.114 ms
64 bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=0.133 ms

# 连通之后就是将tomcat01放到了mynet网络中
# 一个容器两个ip地址 !
# 阿里云服务 ,一个公网, 一个私网 !

# 此时02依旧连不通 ,和网络不同的是 ,并不会自动暴露 !
# 实际网络应该是,主机ip注册到路由,互联的路由之间通过某种方式进行路由表的交换 !
[root@localhost ~]# docker exec -it tomcat-mynet-01 ping tomcat02
ping: unknown host

一个容器两个ip

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第19张图片

想要在docker中跨网络操作别人 ,就需要使用docker network connect 连通 !

7.5实战 : 部署redis集群

docker入门,镜像,容器,数据卷,dockerfile,docker网络,springboot微服务打包docker镜像[狂神yyds]_第20张图片
# 建立redis网络
docker network create redis-net --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
done

# 启动redis服务
docker run -d -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/redis.conf:/etc/redis/redis.conf \
--net redis-net --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 一次启动(可以试试,不用6次)
docker run -d -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/redis.conf:/etc/redis/redis.conf \
--net redis-net --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf;\


# 随便进入一个redis(没有bash)
docker exec -it redis-1 /bin/sh
# 创建集群
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

# 连接集群
redis-cli -c    # -c才是连接集群,要不然就是单机
cluster info 	# 集群信息
cluster nodes	# redis集群节点

8.springboot微服务打包docker镜像

1.构建springboot项目

2.打包应用 打包成jar包

3.编写dockerfile文件

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

4.构建镜像 docker build -t xxx .

5.启动运行 启动docker镜像

企业实战

docker compose

docker swarm

CI/CD jenkins 流水线
ata/redis/node- p o r t / c o n f / r e d i s . c o n f c a t < < E O F > / m y d a t a / r e d i s / n o d e − {port}/conf/redis.conf cat << EOF >/mydata/redis/node- port/conf/redis.confcat<<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

启动redis服务

docker run -d -p 6371:6379 -p 16371:16379 --name redis-1
-v /mydata/redis/node-1/data:/data
-v /mydata/redis/node-1/redis.conf:/etc/redis/redis.conf
–net redis-net --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

一次启动(可以试试,不用6次)

docker run -d -p 637 p o r t : 6379 − p 1637 {port}:6379 -p 1637 port:6379p1637{port}:16379 --name redis-KaTeX parse error: Undefined control sequence: \ at position 8: {port} \̲ ̲-v /mydata/redi…{port}/data:/data
-v /mydata/redis/node-KaTeX parse error: Undefined control sequence: \ at position 41: …dis/redis.conf \̲ ̲--net redis-net…{port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf;\

随便进入一个redis(没有bash)

docker exec -it redis-1 /bin/sh

创建集群

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

连接集群

redis-cli -c # -c才是连接集群,要不然就是单机
cluster info # 集群信息
cluster nodes # redis集群节点


## 8.springboot微服务打包docker镜像

1.构建springboot项目

2.打包应用		==打包成jar包==

3.编写dockerfile文件

```dockerfile
FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

4.构建镜像 docker build -t xxx .

5.启动运行 启动docker镜像

企业实战

docker compose

docker swarm

CI/CD jenkins 流水线

你可能感兴趣的:(docker,Java,docker,网络,spring,boot)