当前位置: 首页 > news >正文

Docker基础入门:Docker网络与微服务项目发布

Docker基础入门:Docker网络与微服务项目发布

  • 一、前言
  • 二、Docker0理解
    • 2.1 ip a查看当前网络环境
    • 2.2 实战--启动一个tomact01容器(查看网络环境)
    • 2.3 实战--启动一个tomact02容器(查看网络环境)
    • 2.4 容器与容器之间的通信
    • 2.5 总结
    • 2.6 容器间通过服务名通信
  • 三、自定义网络(User-defined Network)
    • 3.1 查看所有docker网络
    • 3.2 使用 Docker 创建自定义网络的步骤
    • 3.3 总结
    • 3.4 容器之间进行网络连通
  • 四、 实战--部署redis集群(3主3从)
  • 五、打包发布运行spring-boot微服务项目
    • 5.1 SpringBoot 项目创建
    • 5.2 创建 Dockerfile
    • 5.3 上传文件
    • 5.4 构建 Docker 镜像
    • 5.5 运行 Docker 容器
    • 5.6 测试访问
    • 5.7 再次运行 Docker 容器
    • 5.8 再次测试访问


💖The Begin💖点点关注,收藏不迷路💖

在这里插入图片描述

一、前言

Docker是当今最流行的容器化平台之一,它提供了一个轻量级、可移植和可扩展的应用环境。

而在Docker中,网络是构建容器化应用的关键组成部分之一。本文将深入探讨Docker网络,构建高效、可扩展的应用容器化网络架构。

二、Docker0理解

在 Docker 中,“docker0” 是一个虚拟以太网桥接口,用于连接主机与运行的容器之间的通信。

当在主机上安装 Docker 时,它会自动创建 “docker0” 网络接口。它具有一个默认的 IP 地址(通常是 172.17.0.1)和一个子网掩码。Docker 容器启动时,会自动分配一个 IP 地址,并连接到 “docker0” 网桥。

通过 “docker0” 网桥,容器可以相互之间进行通信,也可以与主机进行通信。还可以通过端口映射将容器内部的服务暴露给主机或外部网络。

“docker0” 是 Docker 默认的网络配置,还可以使用其他网络驱动程序和网络模式来创建不同类型的网络,以满足不同的应用需求。

2.1 ip a查看当前网络环境

在这里插入图片描述

问题:docker 是如何处理容器网络访问的???
在这里插入图片描述

2.2 实战–启动一个tomact01容器(查看网络环境)

1、启动一个tomact容器
docker run -d -P --name tomact01 tomcat
2、查看容器的内部网络地址  ip addr
[root@zyl-server ~]# docker exec -it tomcat01 ip a
OCI runtime exec failed: exec failed: unable to start container process: exec: "ip": executable file not found in $PATH: unknown

报错:

OCI runtime exec failed: exec failed: unable to start container process: exec: "ip": executable file not found in $PATH: unknown

因为该容器的镜像时精简版,内部缺少iproute2导致无法使用ip命令。

报错解决:

进入容器docker exec -it 容器名 /bin/bash进入后:##更新aptapt-get update##安装iproute2apt install -y iproute2##安装完以后退出exit##检查
docker exec -it 容器名 ip addr

在这里插入图片描述
在这里插入图片描述

3、容器启动后会得到一个eth0@if7的地址(docker分配的地址)[root@zyl-server ~]# docker exec -it tomcat01 ip a
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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group defaultlink/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
[root@zyl-server ~]#
4、思考:在主机能不能ping通容器内部这个docker分配的地址???ping <容器IP地址>

在这里插入图片描述

原理:

当Docker容器启动时,它会被分配一个IP地址,并且默认情况下会与主机上的"docker0"网桥接口相连。通过主机上的网络栈,可以使用分配给容器的IP地址与容器进行通信。

5、再次ip addr 查看,发现又多了一对网卡(vethbd9e5f4@if6 ,vethbd9e5f4@if8),和tomcat容器的网卡( eth0@if7)相似原因:veth-pair充当了一个桥梁,连接了各种虚拟网络设备。"veth" 接口工作在不同的网络命名空间中,其中一个端口连接到主机上的"docker0"网桥,而另一个端口连接到容器内部的网络栈(例如"eth0")。通过这样的网络配置,容器可以使用独立的IP地址和网络设置与其他容器或主机进行通信,同时保持网络隔离和安全性。

在这里插入图片描述

2.3 实战–启动一个tomact02容器(查看网络环境)

6、再次启动一个tomcat02,思考:tomcat02与tomcat01之间是否可以ping通???
[root@zyl-server ~]# docker run -d -P --name tomcat02 tomcat[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                         NAMES
60014b1a25c2   tomcat    "catalina.sh run"   38 minutes ago   Up 38 minutes   0.0.0.0:32769->8080/tcp, :::32769->8080/tcp   tomcat02
732466647cdc   tomcat    "catalina.sh run"   39 minutes ago   Up 39 minutes   0.0.0.0:32768->8080/tcp, :::32768->8080/tcp   tomcat01
[root@zyl-server ~]#
7、测试tomcat02与tomcat01之间的通信docker exec -it tomcat02 ping 172.17.0.2

报错:


[root@zyl-server ~]# docker exec -it tomcat02 ping 172.17.0.2
OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown
[root@zyl-server ~]#

解决:

// 进入容器内部
[root@zyl-server ~]# docker exec -it tomcat01 /bin/bash
[root@zyl-server ~]# docker exec -it tomcat02 /bin/bash// tomcat02与tomcat01安装iputils-pingapt install -y iputils-ping
8、再次测试(tomcat02 ping 172.17.0.2[root@zyl-server ~]# docker exec -it tomcat02 ping 172.17.0.2(tomcat01 ping 172.17.0.3[root@zyl-server ~]# docker exec -it tomcat01 ping 172.17.0.3

在这里插入图片描述

2.4 容器与容器之间的通信

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

如:tomcat01与tomcat02之间共用一个路由器(docker0)。

在这里插入图片描述

2.5 总结

Docker 默认使用桥接(Bridge)网络模式

在桥接网络模式下,Docker 会创建一个名为 “docker0” 的虚拟以太网桥接口,并为每个容器分配一个虚拟网络接口(veth pair)-----转发效率高。容器的网络流量会通过这个虚拟网络接口与主机上的 “docker0” 桥接口相连。

通过桥接网络,不同的容器可以彼此通信,也可以与主机进行通信,同时它们共享主机的网络连接。默认情况下,Docker 容器会自动分配一个 IP 地址,并且可以通过主机或其他容器的 IP 地址进行访问。

在这里插入图片描述
只要容器删除,对应的网桥对就没了!!!

2.6 容器间通过服务名通信

前面tomcat01与tomcat02之间是通过IP通信的,怎么实现通过服务名通信???

[root@zyl-server ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
[root@zyl-server ~]#

问题思考:假如一个微服务场景,database url=ip:xxx,项目不重启,数据库ip变了,如何解决这个问题,怎么实现通过服务名通信???

解决:

1、再启动一个tomcat03,使用--link##--link tomcat02:将容器 "tomcat02" 与新创建的 "tomcat03" 容器进行链接(连接)[root@zyl-server ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
5dd7eba42a5c236b272dac6ef4624da6eed564325af8b8491b451d16418a884e
[root@zyl-server ~]#2、测试(tomcat03 ping tomcat02),使用服务名通信
[root@zyl-server ~]# docker exec -it tomcat03 ping tomcat02

在这里插入图片描述

3、反向则不能ping通(tomcat02 ping tomcat03)[root@zyl-server ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known
[root@zyl-server ~]#

探究原因

[root@zyl-server ~]# 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 60014b1a25c2
172.17.0.4      5dd7eba42a5c
[root@zyl-server ~]#

其实–link 就是在hosts配置中增加了一个

172.17.0.3      tomcat02 60014b1a25c2

在这里插入图片描述

–link 选项在容器中添加了一个条目到 /etc/hosts 文件中,以便容器可以通过服务名称进行相互访问。

使用 --link 命令将两个容器连接在一起时,Docker 会自动修改容器的 /etc/hosts 文件,将被链接的容器的 IP 地址和服务名称映射为条目。

这样,“tomcat03” 容器就可以通过使用服务名称 “tomcat02” 访问到 “tomcat02” 容器。

不过需要注意的是,–link 选项已经过时,推荐使用 自定义网络(User-defined Network)来实现容器间的连接和通信。用户自定义网络提供更灵活和可持续的解决方案,更好地管理容器之间的关系和网络配置。

三、自定义网络(User-defined Network)

Docker 提供了用户自定义网络(User-defined Network)的功能,它允许您在 Docker 环境中创建自己的网络,并在这个网络上运行容器。使用用户自定义网络可以更好地管理容器之间的关系和网络配置。

3.1 查看所有docker网络

要列出 Docker 中的所有网络,可以使用 docker network ls 命令。该命令将显示当前 Docker 环境中的所有网络及其详细信息。

列出 Docker 中的所有网络:

[root@zyl-server ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
8290ad5ab9f8   bridge    bridge    local
fe8aa9233f89   host      host      local
7ae86ca33507   none      null      local
[root@zyl-server ~]#NETWORK ID:网络的唯一标识符。
NAME:网络的名称。
DRIVER:网络驱动程序类型。
SCOPE:网络的范围(local 表示仅限本地)

其中包含了几个常见的网络,如默认的 bridge 网络(桥接)、用户自定义的 mynetwork 网络,以及其他特殊网络如 host(和宿主机共享网络)和 none(不配置网络)。

3.2 使用 Docker 创建自定义网络的步骤

1、创建一个名为 "mynetwork" 的用户自定义网络:
[root@zyl-server ~]# docker network create --driver bridge  --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynetwork
da1bb471897eeb1d7e3e867fe7124d29d806da6b06e05cd2c9fd86580ac55486
[root@zyl-server ~]#驱动程序(Driver):通过 --driver bridge 参数指定了网络驱动程序为 bridge,这意味着创建的网络将采用桥接模式。桥接模式是 Docker 默认的网络模式,使得容器可以通过网络桥接与宿主机和其他容器相连。子网(Subnet):通过 --subnet 192.168.0.0/16 参数指定了网络的子网。这意味着创建的网络将包含在以 192.168.0.0 为起始地址、子网掩码为 /16(即 255.255.0.0)的子网中。这个子网范围内的 IP 地址将被分配给容器。网关(Gateway):通过 --gateway 192.168.0.1 参数指定了网络的网关地址。该地址将作为网络的出口地址,用于容器与外部网络之间的通信。[root@zyl-server ~]# docker network ls
NETWORK ID     NAME        DRIVER    SCOPE
8290ad5ab9f8   bridge      bridge    local
fe8aa9233f89   host        host      local
da1bb471897e   mynetwork   bridge    local
7ae86ca33507   none        null      local
[root@zyl-server ~]#[root@zyl-server ~]# docker network inspect mynetwork
[{"Name": "mynetwork","Id": "da1bb471897eeb1d7e3e867fe7124d29d806da6b06e05cd2c9fd86580ac55486","Created": "2023-08-31T00:01:02.667263189+08: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": {},"Options": {},"Labels": {}}
]
[root@zyl-server ~]#

在这里插入图片描述

2、运行容器并将其连接到用户自定义网络:
docker run -d --name container1 --network mynetwork image1
docker run -d --name container2 --network mynetwork image2如:还是启动两个tomcat:
docker run -d -P --name tomcat-mynet-01 --network mynetwork tomcat
docker run -d -P --name tomcat-mynet-02 --network mynetwork tomcat我们创建了两个tomcat容器,并将它们连接到 "mynetwork" 网络。这样,这两个容器就可以通过服务名称进行通信,而无需使用 IP 地址。请注意,--network 参数用于指定容器要连接到的网络(用户自定义网络 mynetwork )。

在这里插入图片描述

3、进入容器docker exec -it 容器名 /bin/bash进入后:##更新aptapt-get update##安装iproute2apt install -y iproute2##安装iputils-ping
apt install -y iputils-ping

报错:
在apt-get update的时候出现了如下异常。

Err:1 http://deb.debian.org/debian bullseye InRelease   Temporary failure resolving 'deb.debian.org' Err:2 http://security.debian.org/debian-security bullseye-security InRelease   Temporary failure resolving 'security.debian.org'

解决:

原因在于DNS服务解析异常,解决的方法也很简单,只需要修改/etc/docker/daemon.json加入如下内容即可(如果没有这个文件则创建

 "dns": ["8.8.8.8", "114.114.114.114"]

在这里插入图片描述

最后重启docker服务,系统即可正常解析镜像网站并运行

systemctl restart docker

在这里插入图片描述

删除tomcat-mynet-01、tomcat-mynet-02,再次执行步骤二、步骤三。启动两个tomcat。

4、容器间通信:
现在,使用容器名称进行容器间的通信。在容器内部,可以使用服务名称或容器名称作为主机名来访问其他容器。例如,在 tomcat-mynet-01 内部,可以通过服务名称 tomcat-mynet-01 访问 tomcat-mynet-01:ping tomcat-mynet-02同样,在 tomcat-mynet-02 内部,可以通过服务名称 tomcat-mynet-02 访问 tomcat-mynet-01:ping tomcat-mynet-01示例:[root@zyl-server ~]#  docker exec -it tomcat-mynet-02 /bin/bash
root@7ff9f7a73f15:/usr/local/tomcat# ping tomcat-mynet-01
PING tomcat-mynet-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-mynet-01.mynetwork (192.168.0.2): icmp_seq=1 ttl=64 time=0.103 ms
64 bytes from tomcat-mynet-01.mynetwork (192.168.0.2): icmp_seq=2 ttl=64 time=0.127 ms
64 bytes from tomcat-mynet-01.mynetwork (192.168.0.2): icmp_seq=3 ttl=64 time=0.161 ms
^C
--- tomcat-mynet-01 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.103/0.130/0.161/0.023 ms
root@7ff9f7a73f15:/usr/local/tomcat#或者:[root@zyl-server ~]# docker exec -it tomcat-mynet-01 ping tomcat-mynet-02
PING tomcat-mynet-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-mynet-02.mynetwork (192.168.0.3): icmp_seq=1 ttl=64 time=0.134 ms
64 bytes from tomcat-mynet-02.mynetwork (192.168.0.3): icmp_seq=2 ttl=64 time=0.137 ms
64 bytes from tomcat-mynet-02.mynetwork (192.168.0.3): icmp_seq=3 ttl=64 time=0.131 ms
64 bytes from tomcat-mynet-02.mynetwork (192.168.0.3): icmp_seq=4 ttl=64 time=0.148 ms
^C
--- tomcat-mynet-02 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
rtt min/avg/max/mdev = 0.131/0.137/0.148/0.006 ms
[root@zyl-server ~]#

在这里插入图片描述

在这里插入图片描述

3.3 总结

在这里插入图片描述

1、启动一个tomcat04[root@zyl-server ~]# docker run -d -P --name tomcat04  tomcat2、测试,tomcat04 ping tomcat-mynet-02[root@zyl-server ~]# docker exec -it tomcat04 ping tomcat-mynet-02
ping: tomcat-mynet-02: Name or service not known
[root@zyl-server ~]#

使用用户自定义网络可以提供更好的容器间通信方式,而不仅仅依赖于 --link 命令。用户自定义网络还可以提供更多高级功能,如容器发现、DNS 名称解析、子网划分等。

3.4 容器之间进行网络连通

在3.3 基础上,引出了网络连通(思考:如果容器A ping 容器D能否ping通)。

[root@zyl-server ~]# docker network --helpUsage:  docker network COMMANDManage networksCommands:connect     Connect a container to a networkcreate      Create a networkdisconnect  Disconnect a container from a networkinspect     Display detailed information on one or more networksls          List networksprune       Remove all unused networksrm          Remove one or more networksRun 'docker network COMMAND --help' for more information on a command.
[root@zyl-server ~]#
docker network子命令:docker network create <network-name>:创建一个自定义网络。
docker network ls:列出所有网络。
docker network inspect <network-name>:显示指定网络的详细信息。
docker network connect <network-name> <container-name>:将指定容器连接到指定的网络。
docker network disconnect <network-name> <container-name>:将指定容器从指定的网络中断开连接。
docker network rm <network-name>:删除指定的网络。
可以通过运行docker network <command> --help来获取特定命令的更详细的帮助信息,例如docker network connect --help[root@zyl-server ~]# docker network connect --helpUsage:  docker network connect [OPTIONS] NETWORK CONTAINERConnect a container to a networkOptions:--alias strings           Add network-scoped alias for the container--driver-opt strings      driver options for the network--ip string               IPv4 address (e.g., "172.30.100.104")--ip6 string              IPv6 address (e.g., "2001:db8::33")--link list               Add link to another container--link-local-ip strings   Add a link-local address for the container
[root@zyl-server ~]#选项和参数:NETWORK:要连接的网络的名称或ID。
CONTAINER:要连接到网络的容器的名称或ID。
可选选项:--alias:为容器添加一个网络范围的别名。可以指定多个别名,使用空格分隔。
--driver-opt:指定网络驱动选项,用于配置网络驱动程序。
--ip:指定容器的IPv4地址。
--ipv6-address:指定容器的IPv6地址。
--link-local-ip:为容器添加一个链路本地地址(IPv4)。可以指定多个地址,使用空格分隔。
--link-local-ipv6-address:为容器添加一个链路本地IPv6地址。

测试,解决3.3 tomcat04 ping tomcat-mynet-02问题

1、将名为tomcat04的容器连接到名为mynetwork的网络docker network connect mynetwork tomcat042、docker inspect 检查mynetwork的网络详细信息docker inspect mynetwork

在这里插入图片描述

结论:(一个容器两个IP,如:阿里云服务器:一个公网IP,一个私网IP)

3、验证:tomcat04 ping tomcat-mynet-02[root@zyl-server ~]# docker exec -it tomcat04 ping tomcat-mynet-02

在这里插入图片描述

四、 实战–部署redis集群(3主3从)

清空docker环境(非测试环境慎用):

 docker stop $(docker ps -aq) 会停止所有正在运行的容器。docker rm $(docker ps -aq) 会删除所有容器。
[root@zyl-server ~]# docker stop $(docker ps -aq)
[root@zyl-server ~]# docker rm $(docker ps -aq)

Redis 集群是一种用于高可用性和扩展性的 Redis 解决方案。基于 Docker 容器化部署 Redis 集群可以简化整个过程,并提供更好的灵活性和可移植性。

3 主 3 从的 Redis 集群:

提供高可用性:当一个主节点发生故障时,通过自动故障转移机制,从节点可以自动晋升为新的主节点,从而保证 Redis 集群的可用性。

提高读写性能:通过路由算法,对键值进行分片存储,使得 Redis 集群能够处理更大的数据集并提高读写性能。

提供容错性:节点之间的数据复制和同步确保了数据的多重备份,从而增强了 Redis 集群的容错能力。

方便管理和部署:采用 Docker 容器化部署 Redis 集群,可以更方便地管理和部署 Redis 环境,提高了生产环境中的运维效率。

部署 Redis 集群可以为企业的业务提供更高的可用性和性能,并增强了应用的容错能力,也可以减少运维的工作量和风险。

在这里插入图片描述
Redis 集群搭建步骤:

1、创建网络:
[root@zyl-server ~]# docker network create redis-network --subnet 172.19.0.0/16
e1aea82ce159a3e39aacee7a2c5f97b0673dd6d3062337f0878169d8418b1a77
[root@zyl-server ~]#2# 通过脚本创建六个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.19.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done3# 启动6个redis容器
for port in $(seq 1 6); \
do
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis-network --ip 172.19.0.1${port} redis redis-server /etc/redis/redis.conf
done

在这里插入图片描述
在这里插入图片描述

4、获取名为 "redis" 的容器的 IP 地址
[root@zyl-server ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-1
172.19.0.11
[root@zyl-server ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-2
172.19.0.12
[root@zyl-server ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-3
172.19.0.13
[root@zyl-server ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-4
172.19.0.14
[root@zyl-server ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-5
172.19.0.15
[root@zyl-server ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-6
172.19.0.16
[root@zyl-server ~]#

在这里插入图片描述

5# 或者 单个启动
docker 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 --net redis --ip 172.19.0.11 redis redis-server /etc/redis/redis.conf# 进入redis-1(主节点)
docker exec -it redis-1 sh# 创建一个包含主节点和从节点的 Redis 集群
redis-cli --cluster create 172.19.0.11:6379 172.19.0.12:6379 172.19.0.13:6379 172.19.0.14:6379 172.19.0.15:6379 172.19.0.16:6379 --cluster-replicas 1--cluster-replicas 1 表示每个主节点都会有一个从节点。你可以根据实际需求调整从节点数量。

在这里插入图片描述

6、检查集群状态:
# 连接redis集群
redis-cli -c# 集群信息
cluster info# 当前连接节点所属集群的配置信息
cluster nodes# 查看集群信息,节点的 IP 地址和端口号
redis-cli --cluster check ip:port示例:
#  redis-cli --cluster check 172.19.0.15:6379
172.19.0.12:6379 (eeb57961...) -> 0 keys | 5462 slots | 1 slaves.
172.19.0.11:6379 (f8f1ff36...) -> 0 keys | 5461 slots | 1 slaves.
172.19.0.13:6379 (63dc2e88...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 172.19.0.15:6379)
S: 30b9739795dbe2b684422d5e26b3af9233abcc09 172.19.0.15:6379slots: (0 slots) slavereplicates f8f1ff368512219bc1175f9437cf66bfc312b162
S: b83a04599b536842ea1a4be7df2a295ffa2c12a2 172.19.0.16:6379slots: (0 slots) slavereplicates eeb57961e87268137f766f85eb4b314d356e8e20
S: d508d0102f96efd3c4849efa72c42d57ea097eda 172.19.0.14:6379slots: (0 slots) slavereplicates 63dc2e880044e44994a3384828b3cc9d4651b383
M: eeb57961e87268137f766f85eb4b314d356e8e20 172.19.0.12:6379slots:[5461-10922] (5462 slots) master1 additional replica(s)
M: f8f1ff368512219bc1175f9437cf66bfc312b162 172.19.0.11:6379slots:[0-5460] (5461 slots) master1 additional replica(s)
M: 63dc2e880044e44994a3384828b3cc9d4651b383 172.19.0.13:6379slots:[10923-16383] (5461 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
#运行这个命令后,Redis 集群会自动执行状态检查并报告集群中的任何错误或不一致的情况。如果一切正常,它将显示类似于 "All 16384 slots covered" 的消息,表示所有槽已被正确分配。

在这里插入图片描述

7、测试:7.1 插入数据k1 v1# redis-cli -c
127.0.0.1:6379> set k1 v1
-> Redirected to slot [12706] located at 172.19.0.13:6379
OK
172.19.0.13:6379>Redis 返回了一条信息指示该命令已被重定向到槽位 [12706],该槽位位于 IP 地址为 172.19.0.13 的节点上的端口 6379 上。可以看到当前处理数据的是172.19.0.13(redis-3),接下来停止172.19.0.13(redis-3),172.19.0.14(redis-4)自动替代主节点,----》达到高可用。7.2  停止172.19.0.13(redis-3[root@zyl-server ~]# docker stop redis-3
redis-3
[root@zyl-server ~]#7.3  停止172.19.0.13(redis-3),get  刚才set的 k1 v1,可以看到172.19.0.14(redis-4)自动替代主节点(redis-3),----》达到高可用。# redis-cli -c
127.0.0.1:6379> get k1
-> Redirected to slot [12706] located at 172.19.0.14:6379
"v1"
172.19.0.14:6379>

在这里插入图片描述

五、打包发布运行spring-boot微服务项目

5.1 SpringBoot 项目创建

在这里插入图片描述
HelloController.java文件:

package com.example.demo.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@RequestMapping("/hello")public String hello(){return "Hello 醉颜凉!!!!!!!!!!";}
}

运行SpringBoot 项目:
在这里插入图片描述
打包SpringBoot 项目:
在这里插入图片描述

5.2 创建 Dockerfile

FROM java:8COPY *.jar /app.jarLABEL authors="zyl"CMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["java", "-jar","/app.jar"]
 Dockerfile 中使用了 java 作为基础镜像,并将构建的目录设置为 / 。然后,将构建产物(在这里是demo1-0.0.1-SNAPSHOT.jarr)复制到镜像中的 / 目录。最后,暴露容器的 8080 端口,并在容器启动时执行 java -jar 命令来启动 Spring Boot 应用。

5.3 上传文件

上传文件jar包与 Dockerfile 文件至 /home/zyl/projectsdemo1-0.0.1-SNAPSHOT.jar
Dockerfile

在这里插入图片描述

5.4 构建 Docker 镜像

进入到 Dockerfile 所在的目录,并运行以下命令来构建 Docker 镜像。

docker build -t my-spring-boot-app .

在这里插入图片描述

5.5 运行 Docker 容器

使用以下命令来运行刚才构建的 Docker 镜像:
docker run -d -P --name zyl-spring-boot-app2 my-spring-boot-app

[root@zyl-server projects]# docker run -d -p 8080:8080 --name  zyl-spring-boot-app my-spring-boot-app
e719e38bb18dbb6c1fe88522bd77c0523f2a9045d4f0dbfa89d3269382c11485
[root@zyl-server projects]#

现在, Spring Boot 微服务项目已经使用 Docker 打包、发布并在容器中运行起来了。可以通过访问 http://localhost:端口来访问运行在 Docker 容器中的应用程序。

5.6 测试访问

用docker run指令启动容器返回了容器id,但是用docker ps指令却不显示刚才启动的容器。

[root@zyl-server projects]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@zyl-server projects]# docker ps -a
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS                     PORTS     NAMES
ba6429acfdee   my-spring-boot-app   "java -jar /app.jar …"   4 minutes ago   Exited (1) 4 minutes ago             zyl-spring-boot-app2
e719e38bb18d   my-spring-boot-app   "java -jar /app.jar …"   7 minutes ago   Exited (1) 7 minutes ago             zyl-spring-boot-app
[root@zyl-server projects]#

解决:

容器状态是Exited,用docker logs contenterid指令查看容器启动日志。


[root@zyl-server projects]# docker logs -f e719e38bb18d
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: org/springframework/boot/loader/JarLauncher has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0at java.lang.ClassLoader.defineClass1(Native Method)at java.lang.ClassLoader.defineClass(ClassLoader.java:763)at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)at java.net.URLClassLoader.access$100(URLClassLoader.java:73)at java.net.URLClassLoader$1.run(URLClassLoader.java:368)at java.net.URLClassLoader$1.run(URLClassLoader.java:362)at java.security.AccessController.doPrivileged(Native Method)at java.net.URLClassLoader.findClass(URLClassLoader.java:361)at java.lang.ClassLoader.loadClass(ClassLoader.java:424)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)at java.lang.ClassLoader.loadClass(ClassLoader.java:357)at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
[root@zyl-server projects]#

修改Dockerfile文件,重新build:

官方Docker弃用了Java镜像。

将java:8替换为openjdk:17,idea打包用的是17。

FROM openjdk:17COPY *.jar /app.jarLABEL authors="zyl"CMD ["--server.port=8080"]EXPOSE 8080ENTRYPOINT ["java", "-jar","/app.jar"]

在这里插入图片描述

5.7 再次运行 Docker 容器

[root@zyl-server projects]# docker run -d -P --name  zyl-spring-boot-app my-spring-boot-app
2273c7aa7597fc6b5e841a1cbdf985c3b3591da47555460a0b0aa4a51322768a
[root@zyl-server projects]# docker ps
CONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS                                         NAMES
2273c7aa7597   my-spring-boot-app   "java -jar /app.jar …"   5 seconds ago   Up 3 seconds   0.0.0.0:32773->8080/tcp, :::32773->8080/tcp   zyl-spring-boot-app
[root@zyl-server projects]#

5.8 再次测试访问

[root@zyl-server projects]# curl localhost:32773/hello
Hello 醉颜凉!!!!!!!!!![root@zyl-server projects]#

在这里插入图片描述


💖The End💖点点关注,收藏不迷路💖

相关文章:

Docker基础入门:Docker网络与微服务项目发布

Docker基础入门&#xff1a;Docker网络与微服务项目发布 一、前言二、Docker0理解2.1 ip a查看当前网络环境2.2 实战--启动一个tomact01容器&#xff08;查看网络环境&#xff09;2.3 实战--启动一个tomact02容器&#xff08;查看网络环境&#xff09;2.4 容器与容器之间的通信…...

Docker安装详细步骤

Docker安装详细步骤 1、安装环境准备 主机&#xff1a;192.168.40.5 zch01 设置主机名 # hostnamectl set-hostname zch01 && bash 配置hosts文件 [root ~]# vi /etc/hosts 添加如下内容&#xff1a; 192.168.40.5 zch01 关闭防火墙 [rootzch01 ~]# systemct…...

十六、pikachu之SSRF

文章目录 1、SSRF概述2、SSRF&#xff08;URL&#xff09;3、SSRF&#xff08;file_get_content&#xff09; 1、SSRF概述 SSRF(Server-Side Request Forgery&#xff1a;服务器端请求伪造)&#xff1a;其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能&…...

最新PHP短网址生成系统/短链接生成系统/URL缩短器系统源码

全新PHP短网址系统URL缩短器平台&#xff0c;它使您可以轻松地缩短链接&#xff0c;根据受众群体的位置或平台来定位受众&#xff0c;并为缩短的链接提供分析见解。 系统使用了Laravel框架编写&#xff0c;前后台双语言使用&#xff0c;可以设置多域名&#xff0c;还可以开设套…...

漱玉平民大药房:多元化药店变革的前夜

作者 | 王聪彬 编辑 | 舞春秋 来源 | 至顶网 本文介绍了漱玉平民大药房在药品零售领域的数字化转型和发展历程。通过技术创新&#xff0c; 漱玉平民 建设了覆盖医药全生命周期的大健康生态圈&#xff0c;采用混合云架构和国产分布式数据库 TiDB&#xff0c;应对庞大的会员数据处…...

如何实现AI的矢量数据库

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建3D应用场景 然而&#xff0c;人工智能模型有点像美食厨师。他们可以创造奇迹&#xff0c;但他们需要优质的成分。人工智能模型在大多数输入上都做得很好&#xff0c;但如果它们以最优化的格式接收输入&#xff0c;它们就会真正…...

Java与Modbus-TCP/IP网络通讯

1.需求样例 举例5&#xff1a;浮点数参数读取&#xff08;读取温度测量值&#xff09;查看参数列表&#xff0c;温度测量值地址为320&#xff0c;根据Modbus协议&#xff0c;读取参数地址转换为16进制为&#xff1a;00H A0H&#xff0c;读取长度为2个字&#xff1a;00H 02H。 …...

音视频 ffmpeg命令图片与视频互转

截取一张图片 ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.jpg ffmpeg -i test.mp4 -y -f image2 -ss 00:00:02 -vframes 1 -s 640x360 test.bmp -i 输入 -y 覆盖 -f 格式 image2 一种格式 -ss 起始值 -vframes 帧 如果大于1 那么 输出加%03d t…...

C++的基类和派生类构造函数

基类的成员函数可以被继承&#xff0c;可以通过派生类的对象访问&#xff0c;但这仅仅指的是普通的成员函数&#xff0c;类的构造函数不能被继承。构造函数不能被继承是有道理的&#xff0c;因为即使继承了&#xff0c;它的名字和派生类的名字也不一样&#xff0c;不能成为派生…...

C语言中对json格式数据的解析和封装

首先需要调库&#xff1a;#include <cJSON.h> Json的数据结构介绍&#xff1a; /* The cJSON structure: */ typedef struct cJSON { /*next/prev允许您遍历数组/对象链。或者&#xff0c;使用GetArraySize/GetArrayItem/GetObjectItem */ struct cJSON *next; struct c…...

RT-Thread自动初始化机制

自动初始化机制是指初始化函数不需要被显示调用&#xff0c;只需要在函数定义处通过宏定义的方式进行申明&#xff0c;就会在系统启动过程中被执行。 int rt_hw_usart_init(void) {rt_hw_serial_register(&serial1, "uart1",RT_DEVICE_FLAG_RDWR | RT_DEVICE_FL…...

在本地搭建Jellyfin影音服务器,支持公网远程访问影音库的方法分享

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…...

强盛集团面试题实战(持续更新)

目录 第一章、面试题1.1&#xff09;王:8月301.2&#xff09;1.3&#xff09; 第二章、2.1&#xff09;2.2&#xff09;2.3&#xff09; 第三章、3.1&#xff09;3.2&#xff09;3.3&#xff09; 第四章、4.1&#xff09;4.2&#xff09;4.3&#xff09; 友情提醒&#xff1a;先…...

golang 协程的实现原理

核心概念 要理解协程的实现, 首先需要了解go中的三个非常重要的概念, 它们分别是G, M和P, 没有看过golang源代码的可能会对它们感到陌生, 这三项是协程最主要的组成部分, 它们在golang的源代码中无处不在. G (goroutine) G是goroutine的头文字, goroutine可以解释为受管理的…...

go gin 参数绑定常用验证器

https://pkg.go.dev/github.com/go-playground/validator/v10#readme-baked-in-validations min 最小max 最大len 长度限制gt 大于eq 等于ne 不等于eqfield 与某个字段值一样nefield 与某个字段值不一样oneof 枚举 ,以空格分开startswithendswithdive 数组 package mainimpor…...

多用户商城系统常见的安全性和数据保护措施有哪些?

电子商务的迅速发展&#xff0c;越来越多的企业选择搭建多用户商城系统来扩展业务。然而&#xff0c;随之而来的是对数据安全和保护的日益关注。在选择多用户商城系统时&#xff0c;我们需要考虑一系列的安全性和数据保护措施&#xff0c;以确保商城系统的稳定性和用户数据的完…...

如何在WSL上导入任何Linux发行版

文章目录 一、准备1. 开启WSL相关功能2. 升级WSL3. 设置默认的wsl版本 二、通过 Microsoft Store 安装 Linux1. 查看 Microsoft Store 有哪些可安装的 Linux 发行版2. 安装 Linux 发行版3. 查看已安装的 Linux 发行版4. 启动Linux发行版 三、通过Linux发行商提供的tar文件安装1…...

汽车自适应巡航系统车距控制策略研究

1 引言 自适应巡航控制( Adaptive Cruise Control&#xff0c;ACC) 是汽车驾驶辅助系统的重要组成部分&#xff0c;其作用是根据车距传感器探测到本车( ACC 车辆) 与主目标车辆( 前车) 之间的相对位置和相对速度信息&#xff0c;自动调节ACC 车辆的节气门开度或部分制动力矩( 即…...

鸿蒙系列-如何更好地使用 ArkUI 的 Image 组件?

如何使用好 ArkUI 的 Image 组件&#xff1f; 开发者经常需要在应用中显示一些图片&#xff0c;例如&#xff1a;按钮中的logo、网络图片、本地图片等。在应用中显示图片需要使用 Image 组件实现&#xff0c;Image支持多种图片格式&#xff0c;包括png、jpg、bmp、svg和gif&am…...

机器学习简介[01/2]:简单线性回归

Python 中的机器学习简介&#xff1a;简单线性回归 一、说明 简单线性回归为机器学习提供了优雅的介绍。它可用于标识自变量和因变量之间的关系。使用梯度下降&#xff0c;可以训练基本模型以拟合一组点以供未来预测。 二、技术背景 这是涵盖回归、梯度下降、分类和机器学习的其…...

Kubernetes技术--k8s核心技术yaml资源编排

(1).引入 我们可以使用kubectl实现单行指令的操作,但是这样做的坏处是不复用,所以为了更好的实现对一系列资源的编排工作。kuberntes中使用一种叫做资源清单文件(yaml)来实现对资源管理和资源对象编排部署。 (2).概述 yaml是一种标记语言。为了强调这种语言以数据做为中心,而…...

clickhouse-配置解释

详细内容看官网文档 一、全局服务配置 1.配置详解 名称含义默认值allow_use_jemalloc_memory允许使用 jemalloc 内存1&#xff08;布尔&#xff09;asynchronous_heavy_metrics_update_period_s更新异步指标的时间段&#xff08;以秒为单位&#xff09;120asynchronous_metr…...

基于亚马逊云科技无服务器服务快速搭建电商平台——性能篇

使用 Serverless 构建独立站的优势 在传统架构模式下&#xff0c;如果需要进行电商大促需要提前预置计算资源以支撑高并发访问&#xff0c;会造成计算资源浪费并且增加运维工作量。本文介绍一种新的部署方式&#xff0c;将 WordPress 和 WooCommerce 部署在 Amazon Lambda 中。…...

LINQ详解(查询表达式)

什么是LINQ&#xff1f; LINQ(语言集成查询)是将查询功能直接集成到C#中。数据查询表示简单的字符串&#xff0c;在编译时不会进行类型检查和IntelliSense(代码补全辅助工具)支持。 在开发中&#xff0c;通常需要对不同类型的数据源了解不同的查询语句&#xff0c;如SQL数据库…...

【DEVOPS】现状篇

0. 目录 1. 前言2. 现状2.1 需求管理2.2 开发流程2.3 测试流程2.4 部署流程2.5 维护阶段 3. 后记4. 相关 1. 前言 一直以来&#xff0c;深感内部工程化能力欠缺&#xff0c;急于将事情向前推进&#xff0c;总是希望能够向前走几步&#xff0c;再走几步。 可惜的是&#xff0c…...

Linux文件管理知识:查找文件(第二篇)

Linux文件管理知识:查找文件&#xff08;第二篇&#xff09; 上篇文章详细介绍了linux系统中查找文件的工具或者命令程序locate和find命令的基本操作。那么&#xff0c;今天这篇文章紧接着查找文件相关操作内容介绍。 Find命令所属操作列表中的条目&#xff0c;有助于我们想要…...

医疗小程序:让服务更高效,用户体验更优化

随着移动互联网的快速发展&#xff0c;小程序已经成为了一个热门的开发方向。医疗健康类小程序也不例外&#xff0c;拥有广泛的市场需求和前景。本文将为你提供一份完整的医疗健康类小程序开发攻略&#xff0c;帮助你快速开发上线一个专业成熟的小程序商城。 一、选择合适的小程…...

C++11 std::transform函数使用说明

std::transform是C标准库中的一个算法&#xff0c;它用于对输入范围内的元素进行操作&#xff0c;并将结果存储在输出范围内。这个算法特别适合于将一种数据类型转换为另一种数据类型。 函数定义在头文件algorithm中 std::transform的基本语法如下&#xff1a; std::transfor…...

JavaScript-DOM查询

获取元素节点 获取元素节点的子节点 元素节点的属性 节点的修改 JavaScript中的DOM&#xff08;文档对象模型&#xff09;是一种编程接口&#xff0c;它允许JavaScript与HTML文档交互。创建DOM查询&#xff0c;可以使用多种方法. 获取元素节点 1. getElementById() – 通…...

大数据-玩转数据-Flink 水印

一、Flink 中的水印 在Flink的流式操作中, 会涉及不同的时间概念&#xff1a; 1.1 处理时间 是指的执行操作的各个设备的时间&#xff0c;对于运行在处理时间上的流程序, 所有的基于时间的操作(比如时间窗口)都是使用的设备时钟。比如, 一个长度为1个小时的窗口将会包含设备…...