Docker 容器 通信 .Net Core Web应用 连接 redis

前言

两个容器:
Web应用容器(基于.Net Core开发)
Redis容器

实现:
.Net Core应用容器能够访问Redis容器.

方式1.Web应用连接Redis.IP地址

#查看redis容器{rds01}的IP地址
[root@VM-0-12-centos ~]# docker inspect rds01
#"IPAddress": "172.18.0.3",

修改Web应用的配置文件{appsettings.json}

  "RedisConfig": {
    "WriteHosts": "172.18.0.3",
    "ReadHosts": "172.18.0.3"
  }

再次生成Web应用镜像,运行容器,

#生成Web应用的镜像
[root@VM-0-12-centos ~]# docker build -t dns01 .
#运行Web引用的容器,宿主机端口设置为8101
[root@VM-0-12-centos ~]# docker run --name dnsc01 -p 8101:8001 -itd dns01

访问.Net Core的api,
测试是否成功在Redis中添加了数据...

可以在"Redis Desktop Manager"中查看是否成功.

这种方式的优缺点
这种方式连接的流程,
1.获取redis容器的ip地址,
2.再去根据redis容器的ip地址修改web应用的配置文件...

如果我想同时进行,我直接运行这2个容器就可以通信,
感觉这样会更好一点...

当然也可以修改容器的IP,但是我感觉修改容器的IP更繁琐点...

总之条条大路通罗马,大家选一个适用自己场景,相对简单实现的就行了.

方式2.Web应用连接Redis.名称和端口号

这种方式不用先查看redis容器的IP地址了,(但是要先确定redis容器的名称)
所以可以先修改Web服务的配置文件

1.Web服务准备配置文件

"RedisConfig": {
"WriteHosts": "rds03",
"ReadHosts": "rds03"
}

这个容器{rds03},现在还没有创建,
但是这是我计划Web服务容器要连接的redis容器的名称和端口.

因为redis的默认端口"6379"已经被我的一个redis容器给占用了,
所以我准备让Redis容器.{rds03}使用端口"6380"


2.网络.新建一个网络
新建的网络用于Web服务容器和Redis容器通信

[root@VM-0-12-centos ~]# docker network create -d bridge nw03

3.镜像.准备

#镜像.生成.Web应用
[root@VM-0-12-centos ~]# docker build -t dnsc03 /home/zhangfan/dockersample/
#镜像.拉取.Redis
[root@VM-0-12-centos ~]# docker pull redis

3.[网络/容器].将容器和网络关联起来

#容器.{rds03}=>关联=>网络.{nw03}
[root@VM-0-12-centos ~]# docker run -itd --name rds03 --network nw03 -p 6380:6380 redis

#容器.{dnsci03}=>关联=>网络.{nw03}
[root@VM-0-12-centos ~]# docker run -itd --name dnsci03 --network nw03 -p 8102:8002 dnsc03

3.1.[网络/容器].验证.Web应用容器是否启动成功
访问"http://x.x.x.x:8102"竟然提示'无法访问此网站'
仔细又梳理了一下,Web应用的端口,
发现Web应用的只能访问8001端口...

#容器.{dnsci03}=>关联=>网络.{nw03}
[root@VM-0-12-centos ~]# docker run -itd --name dnsci03 --network nw03 -p 8102:8001 dnsc03

重新修改Web应用

//Program.cs
public static IHostBuilder CreateHostBuilder
(string[] args) =>
Host.CreateDefaultBuilder(args)
	.ConfigureWebHostDefaults
	(
		webBuilder =>
		{
        //增加几个端口...
			webBuilder.UseStartup<Startup>().UseUrls("http://*:8001", "http://*:8002", "http://*:8003", "http://*:8004");
		}
	);

重新生成镜像=>启动容器=>访问"http://x.x.x.x:8102"竟然提示'无法访问此网站'

#在服务器上查看本地的端口,是正常的,防火墙?
[root@VM-0-12-centos ~]# curl localhost:8102/weatherforecast
[{"date":"2020-10-22T05:38:15.2172063+00:00","temperatureC":27,"temperatureF":80,"summary":"Freezing"},{"date":"2020-10-23T05:38:15.2189284+00:00","temperatureC":33,"temperatureF":91,"summary":"Bracing"},{"date":"2020-10-24T05:38:15.2189586+00:00","temperatureC":-2,"temperatureF":29,"summary":"Balmy"},{"date":"2020-10-25T05:38:15.2189591+00:00","temperatureC":36,"temperatureF":96,"summary":"Bracing"},{"date":"2020-10-26T05:38:15.2189593+00:00","temperatureC":-20,"temperatureF":-3,"summary":"Hot"}]

后来发现只要将api地址输入完全即可...

由于我的api地址"http://x.x.x.x:8102/weatherforecast"
我在火狐浏览器上访问"http://x.x.x.x:8102"显示空白,这个我可以接受...
但是谷歌浏览器上访问"http://x.x.x.x:8102",显示"无法访问此网站,49.234.141.178 拒绝了我们的连接请求",这个就让我以为没有部署成功...

3.1.[网络/容器].验证.Redis容器是否启动成功
使用"Redis Desktop Manager",
连接"x.x.x.x:6380",
结果提示:"Cannot connect to server 'x.x.x.x:6380'. Check log for details."

root@VM-0-12-centos ~]# docker exec -it rds03 /bin/bash
root@fe4122947481:/data# redis-cli
127.0.0.1:6379> set name zf
OK

结果发现redis客户端."127.0.0.1:6379".端口并不是6380,还是6379 ... ?

#验证6380端口是否能连接上
[root@VM-0-12-centos ~]# docker exec -it rds03 /bin/bash
root@fe4122947481:/data# redis-cli -p 6380
Could not connect to Redis at 127.0.0.1:6380: Connection refused

后来发现是在启动redis容器的时候,容器端口写错了.
不管外网端口是多少,容器端口一直是"6379"就行了...

[root@VM-0-12-centos ~]# docker run -itd --name rds6382 -p 6382:6379 redis

测试.容器间.是否可以通信

测试Web应用容器和redis容器,
是否可以通信,
使用ping命令

先进入Web应用容器

[root@VM-0-12-centos ~]# docker exec -it dcc03 /bin/bash

梳理步骤

前提:
网站单独的是否可以访问?
Redis单独的是否可以访问?

坑.No.1.各个步骤都需要验证

就像看一本书,
书上的每个字都认识,作者写成书的话,
有的看起来就费劲了.

每一个步骤都会,

[
".Net Core创建Web应用",
"Docker新建网络",
"Docker部署Web应用容器",
"Docker部署Redis容器",
"..."
]

但是连起来的话,刚开始有点不知所措...
总结了一下,一个关键点就是:
1.分步骤,一步一步来,
2.如何验证每一个步骤都跑通了...

我觉得比较重要的3个点↓:
1.Redis是否部署成功
可以在"Redis Desktop Manager"中查看是否成功.

2.Web应用是否部署成功
刚开始死活在外网上访问不了这个端口,
一直认为是Web应用部署失败了,
后来发现只是我的腾讯云服务器没有开放这个端口...

可以先在服务器上,测试下这个端口,
如果服务器上端口是通的,
但是外网访问不行,很可能就是因为安全问题,端口没有开放...

[root@VM-0-12-centos ~]# curl localhost:8104/Weather/china/20201118/20
{"isSuccess":false,"errorCode":"","message":"Object reference not set to an instance of an object.","httpStatus":0,"data":null}[root@VM-0-12-centos ~]#

2.Web应用容器&Redis容器是否通信成功
在Web应用容器中安装一个ping工具,
用于测试是否可以连接到Redis容器.

[root@VM-0-12-centos ~]# docker exec -ti ng01 /bin/bash
#安装

root@b3a95a492740:/# apt-get update
#apt-get update...执行好几分钟...

root@b3a95a492740:/# apt install iputils-ping
#省略N行...
root@b3a95a492740:/# ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.041 ms
#省略N行...
root@b3a95a492740:/# ping rds03

坑.No.2.redis容器端口问题

出错的脚本↓

#错误示范>>容器.{rds03}=>关联=>网络.{nw03}
[root@VM-0-12-centos ~]# docker run -itd --name rds03 --network nw03 -p 6380:6380 redis

刚开始以为Docker内,6379端口已经另外一个Redis容器占用了,
所以我再启动一个Redis容器的话,我想更换一个容器端口,
结果导致我的Redis容器,一直在外网是访问不到的.

其中我还试图修改Redis容器的端口号,

"Docker服务停用"=>"修改配置文件"=>"Docker服务.重启"...
#依然不行...

其实就是端口的问题,
端口映射的话,启动N个Redis容器,容器的端口都是可以设置为"6379"...
正确的命令↓

#容器.{rds03}=>关联=>网络.{nw03}
[root@VM-0-12-centos ~]# docker run -itd --name rds03 --network nw03 -p 6380:6379 redis

坑.No.3.配置appsettings.json是否需要带端口

如果redis容器的名称为."rds04",端口为."6381"
并且Web应用容器和.{rds04}在同一个网络中,
看到网上有个同学将.{appsettings.json}配置如下

"RedisConfig": {
"WriteHosts": "rds04:6381",
"ReadHosts": "rds04:6381"
}

我亲自试了一下,我这里这样配置是不行的,
将.{appsettings.json}配置去掉端口修改为↓即可.

"RedisConfig": {
"WriteHosts": "rds04",
"ReadHosts": "rds04"
}

测试流程所用到脚本↓

#1.修改配置文件
#2.镜像.生成.Web应用
[root@VM-0-12-centos ~]# docker build -t dci04 /home/zhangfan/dockersample/
#3.容器.启动.Redis.{rds04},端口为6381
[root@VM-0-12-centos ~]# docker run -itd --name rds04 --network nw03 -p 6381:6379 redis
#4.容器.启动.Web应用.{dcc04},端口为8104
[root@VM-0-12-centos ~]# docker run -itd --name dcc04 --network nw03 -p 8104:8001 dci04
#5.测试向Redis中插入数据
[root@VM-0-12-centos ~]# curl localhost:8104/Weather/china/20201118/20
{"isSuccess":false,"errorCode":"","message":"Object reference not set to an instance of an object.","httpStatus":0,"data":null}

脚本列表.appsettings.json重新配置生成镜像,容器

因为刚开始需要反复修改配置文件,生成验证...↓

"修改appsettings.json" => "重新生成Web应用镜像" =>
"启动Web应用容器" => "验证(如果不行)" => "修改appsettings.json" ...

所以搞了这么一个命令列表,用于测试...

#1.修改{appsettings.json}

#移除镜像&容器
docker rm -f dcc03
#docker rm -f rds03
docker rmi -f dci03

#镜像生成
docker build -t dci03 /home/zhangfan/dockersample/

#确保已经有一个redis镜像
#如果已经有一个redis容器,网络连接到.{nw03},这一步可以省略
#docker run -itd --name rds03 --network nw03 -p 6380:6379 redis
docker run -itd --name dcc03 --network nw03 -p 8103:8001 dci03

结尾

其实不仅"纸上得来终觉浅",
"得来纸上亦觉浅"(自己学到了一些东西,事后总结起来也感觉挺简单的...)
很明显的,开始搞就感觉难的翻白眼,一搞完就感觉:"就这?"...

摘抄文档

posted @ 2020-10-26 00:06  zh89233  阅读(535)  评论(2编辑  收藏  举报