Centos8 Docker+Nginx部署Asp.Net CoreNginx正向代理与反向代理负载均衡实现无状态更新

Centos8 Docker+Nginx部署Asp.Net CoreNginx正向代理与反向代理负载均衡实现无状态更新,第1张

Centos8 Docker+Nginx部署Asp.Net Core Nginx正向代理与反向代理 负载均衡实现无状态更新 首先了解Nginx 相关介绍(正向代理和反向代理区别)

所谓代理就是一个代表、一个渠道;

此时就涉及到两个角色,一个是被代理角色,一个是目标角色,被代理角色通过这个代理访问目标角色完成一些任务的过程称为代理 *** 作过程;如同生活中的专卖店~客人到adidas专卖店买了一双鞋,这个专卖店就是代理,被代理角色就是adidas厂家,目标角色就是用户。


正向代理

我们如果由于技术需要要去访问国外的某些网站,此时你会发现位于国外的某网站我们通过浏览器是没有办法访问的,此时大家可能都会用一个代理进行访问,代理的方式主要是找到一个可以访问国外网站的代理服务器,我们将请求发送给代理服务器,代理服务器去访问国外的网站,然后将访问到的数据传递给我们!

上述这样的代理模式称为正向代理,正向代理最大的特点是客户端非常明确要访问的服务器地址;服务器只清楚请求来自哪个代理服务器,而不清楚来自哪个具体的客户端;

反向代理

例如我大天朝的某宝网站,每天同时连接到网站的访问人数已经爆表,单个服务器远远不能满足人民日益增长的购买欲望了,此时就出现了一个大家耳熟能详的名词:分布式部署;

通过上述的图解大家就可以看清楚了,多个客户端给服务器发送的请求,Nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。


此时~请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,Nginx扮演的就是一个反向代理角色。


客户端是无感知代理的存在的,反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。


因为客户端不需要任何配置就可以访问。


反向代理,"它代理的是服务端",主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。


反向代理的作用:

(1)保证内网的安全,通常将反向代理作为公网访问地址,Web服务器是内网

(2)负载均衡,通过反向代理服务器来优化网站的负载

项目场景

通常情况下,我们在实际项目 *** 作时,正向代理和反向代理很有可能会存在在一个应用场景中,正向代理代理客户端的请求去访问目标服务器,目标服务器是一个反向代理服务器,反向代理了多台真实的业务处理服务器。


具体的拓扑图如下

图解:

在正向代理中,Proxy和Client同属于一个LAN(图中方框内),隐藏了客户端信息;

在反向代理中,Proxy和Server同属于一个LAN(图中方框内),隐藏了服务端信息;

实际上,Proxy在两种代理中做的事情都是替服务器代为收发请求和响应,不过从结构上看正好左右互换了一下,所以把后出现的那种代理方式称为反向代理了。


负载均衡

Nginx扮演了反向代理服务器的角色,它是以依据什么样的规则进行请求分发的呢?不同的项目应用场景,分发的规则是否可以控制呢?

这里提到的客户端发送的、Nginx反向代理服务器接收到的请求数量,就是我们说的负载量。


请求数量按照一定的规则进行分发到不同的服务器处理的规则,就是一种均衡规则。


所以~将服务器接收到的请求按照规则分发的过程,称为负载均衡。


.Nginx在负载均衡的作用(直观点看,相当于客户端的请求是发到Nginx上的,然后由Nginx决定到底调用哪一个服务器):

在上一篇以及配置过的/etc/nginx nginx.conf修改一下

优先级 可以实现不停止更新 设置最高的 然后分别更新

upstream WebApi{
#nginx默认轮询下面的服务实例
  server localhost:8001 weight=1;
  server localhost:8002 weight=2;
  server localhost:8003 weight=3;
}

 Docker 部署


一、准备工具

Win 10

Centos 8

Visual Studio 2019

Docker Desktop  下载地址:https://www.docker.com/products/docker-desktop 默认安装就行

windows要启用Hyper-V

docker安装完毕后可能会提示安装Linux 内核更新包 https://docs.microsoft.com/zh-cn/windows/wsl/wsl2-kernel

打开vs会提示d出cmd

注意 :安装完毕之后重启容器


二、Cenos 8安装docker

1、安装

1、安装依赖项
sudo yum install -y yum-utils //官方:地址在国外,很慢
//sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 2、设置阿里云镜像源
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 3、安装docker
sudo yum install docker-ce docker-ce-cli containerd.io //如果报错了
//package docker-ce-3:19.03.8-3.el7.x86_64 requires containerd.io >= 1.2.2-3, but none of the providers can be installed
//解决方法:
//进入阿里云镜像地址:https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/找到你想要的或者最新的containerd.io包,拼接在阿里云地址后面,
//如下:
yum install -y https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.13-3.1.el7.x86_64.rpm
//然后再执行
yum install docker-ce docker-ce-cli containerd.io 4、启动 docker
sudo systemctl start docker 5、测试容器
sudo docker run hello-world 6、设置 docker 自启
sudo systemctl enable docker 7、检查自启状态
systemctl list-unit-files | grep docker 8、添加 docker hub 镜像源
//这里使用的是 阿里云提供的镜像加速https://cr.console.aliyun.com/#/accelerator ,登录并且设置密码之后在左侧的 Docker Hub 镜像站点(镜像加速) 可以找到专属加速地址,复制下来。


sudo mkdir -p /etc/docker //命令
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["你的加速地址"]
}
EOF //重新启动服务
sudo systemctl daemon-reload
sudo systemctl restart docker
//直接执行上面命令就行 或者 进入daemon.json 没有就直接建一个就ok了 9、重新加载配置,并且重启 Docker 服务
systemctl daemon-reload
systemctl restart docker 10、图形化管理 这里推荐使用 Portainer 作为容器的 GUI 管理方案
//官方地址:https://portainer.io/install.html
//安装命令:
docker volume create portainer_data
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer //访问你的 IP:9000 即可进入容器管理页面

2、检查

 docker -v

 发布项目

如果说创建项目的时候,没有勾选“启用Docker支持”,我们也可以在项目创建完成以后在添加Dockerfile文件,在项目上右键,选择“添加”选项下面的“Docker支持”,如下图所示:选择Linux。


自动生成的Dockerfile  可以看到这里有build和publish命令,自动生成的Dockerfile文件可能会有一些错误,所以我们自己编写一份Dockerfile文件,修改后的Dockerfile文件如下:


# 引入镜像,低版本 docker 去掉 AS base

# 换成别人做的阿里镜像

# FROM registry.cn-hangzhou.aliyuncs.com/newbe36524

# 使用运行时镜像 这里就是.net 3.1 SDK

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base

# 配置工作目录 相当于cd

WORKDIR /app


# 暴露容器端口,此端口与程序运行路径一致,(可以不写,因为我们具体映射的端口可以在运行的时候指定)

EXPOSE 1031

# 把目录下的内容都复制到当前目录下 (. .代表当前目录)

COPY . .

# ENV :配置系统环境变量,比如程序环境环境等在这里配置(开发、预发、线上环境)

# 这里是配置程序运行端口,如果程序不使用默认的80端口这里一定要设置(程序运行端口)  (可以不写)

ENV ASPNETCORE_URLS http://+:1031

# 设置时间为中国上海,默认为UTC时间  (可以不写)

ENV TZ=Asia/Shanghai

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 启动程序 运行镜像入口命令和可执行文件名称

ENTRYPOINT ["dotnet", "NetLock.Presentation.Api.dll"]

注意:将Dockerfile文件属性改为:始终复制。


随后发布

生成镜像

首先发布程序,程序发布成功以后,进入到发布目录publish,就可以生成镜像

这里在window使用cmd。


使用下面的命令生成镜像: 其中 netlockdocker 是镜像名称。


docker build -t netlockdocker .

镜像生成成功了。


我们查看本地的镜像:

docker images

将镜像推送Docker Hub 仓库

既然咱们有了镜像,如果每次使用都要build,肯定是不对的,咱们可以统一推送到Hub仓库里。


首先去官网建立一个仓库

服务器镜像推送  首先登录

docker login

然后推送 docker images 查看镜像ID:

#docker  tag  镜像id  要推入仓库的用户名/要推入的仓库名:新定义的tag
docker tag a301245c4177 netlocks/netlock:mytest #docker push 要推入仓库的用户名/要推入的仓库名:镜像标签(上面定义的tag)
docker push netlocks/netlock:mytest

我们登录管理后台,查看结果

可以看到已经成功推送了,这样的话,我们就可以在任何的地方使用我的镜像啦。


docker pull netlocks/netlock:mytest

将容器生成镜像 比如包含Nginx netcore3.1 打包成一个镜像

//-m是描述  -a 是作者  都可以不写  容器ID  远程仓库
docker commit -m "add hub" -a "netlock" 8c48ef63a412 netlocks/nethub //推送到远程仓库 这样一个镜像就弄好了 剩下步骤参照上面
docker push netlocks/nethub //默认仓库的标签就是latest 可以改 参照上面

拉去下来就运行容器

运行容器

执行下面命令运行生成的容器,需要注意一下几点:

  • 挂载目录,映射容器内目录到宿主机,如文件下载、上传等
  • 端口,宿主机与容器内端口号映射,容器内端口号要保证与Dockerfile文件内一致 1031就是程序的url  1020访问
  • 自动重启,设置restart属性为always,防止宿主机或者docker重启后容器停止
  • --name :指定容器名称。


  • --p :指定容器端口。


  • --d :指定容器后台运行
  • netlocks/netlock:mytest  镜像名
  • --restart :防止停止
# 启动容器
docker run --restart=always --name=netlockdocker -p 1020:1031 -d netlocks/netlock:mytest

镜像运行成功。


可以使用下面的命令查看正在运行的容器:

docker ps

验证

如果发现请求不了,多半是下面两种情况:

对外映射的端口没开启。


//查询端口号XXX 是否开启
firewall-cmd --query-port=XXX/tcp
//开启端口
firewall-cmd --zone=public --add-port=XXX/tcp --permanent
//重启防火墙
firewall-cmd --reload

创建运行容器时监听的端口弄错了

1 //查看容器运行日志
2 docker logs 容器ID

相关命令

//查看所有容器
docker ps 或者 docker ps -aq
//查看容器运行日志
docker logs 容器名称/容器ID
//停止运行容器
docker stop 容器名称/容器ID
//删除容器
docker rm 容器名称/容器ID
//重启容器服务
systemctl restart docker
//查看所有镜像
docker images
//删除指定ID的镜像 如果镜像正在被容器使用需要先停止 并强制删除镜像 加-f
docker rmi 镜像ID 或者 docker image rm -f 镜像ID //强制删除

docker卸载

yum remove docker-ce docker-ce-cli containerd.io

rm -rf /var/lib/docker

 更新镜像

停止容器-删除容器-删除镜像-重新构建镜像-重新提交远程仓库覆盖-重新拉取-重新运行容器

Nginx反向代理

我们一般会设置反向代理,用来屏蔽应用程序真实的IP和端口号。


在Linux系统上最常用的反向代理就是Nginx

获取Nginx镜像

要运行容器,首先需要有相应的镜像,使用下面的命令拉取NGINX镜像:

docker pull nginx
运行Nginx容器

获取Nginx镜像之后,我们就可以根据镜像来运行容器

docker run --name=nginx -d -p 1010:80 nginx

上面命令的解释如下:

  1. --name:设置容器的名称。


  2. -d:表示在后台运行容器。


  3. -p:指定端口映射。


    1010是宿主机的端口(外部访问),80是Nginx容器内部的端口。


  4. nginx:表示根据nginx镜像运行容器。


如图所示

然后在浏览器里面访问:

出现上面的截图,就说明Nginx容器运行成功。


设置反向代理

在上面的步骤中,我们分别运行了nginx容器和ASP.NET Core应用程序的容器,并且都可以在浏览器里面访问,下面我们来设置反向代理。


反向代理实现如下的效果:在浏览器里面访问1010端口的时候跳转到1020端口,浏览器显示ASP.NET Core应用程序。


配置反向代理,我们需要修改Nginx的配置文件。


在Nginx的配置文件里面设置反向代理的HTTP地址。


提供两种方法  第二种还没成功 没时间搞了 应该也是可以的

第一种 不在容器种装vi 直接用docker把配置文件复制出来修改 然后在放进去

1.我已经启动了一个nginx容器 然后你想修改 容器内 /etc/nginx/conf.d 文件夹内的conf 文件

把  nginx 容器内的   /etc/nginx/conf.d  文件夹 拷贝到宿主机的  /home/conf.d

docker cp nginx:/etc/nginx/conf.d /home/conf.d  

2.把现在的nginx容器先删除掉 因为这里我们只拷贝文件 所以这个容器删了

docker rm -f nginx

3.修改 /home/conf.d/default.conf  配置 用vim  xftp都可以 我这里用xftp

4.将conf文件替换成下面的

upstream demos{
server 45.32.58.20:1020 weight=1; #负载均衡,目前单主机,前面填上需要指向的服务器地址跟端口 可以设置多个
}
server {
listen 1050; #监听的端口 也就是网站程序将来要使用点端口 location / {
proxy_pass http://demos; #上面负载地址
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

5.最后再重新运行个容器,通过 -v 把 /home/conf.d 映射到  容器内部的/etc/nginx/conf.d,也就是说 宿主机上的conf文件和容器内的conf是同一个,改完重启nginx容器就行了啊

docker run -it -p 1010:1050  -d --name nginx -v /home/conf.d:/etc/nginx/conf.d nginx #1010就是外网 1050就是上面监听的 这样就把文件复制过去了

我们可以使用下面的命令检查一下修改后的配置文件是否有错:

进入nginx容器

docker exec -it nginx /bin/bash
nginx -t

6.如果修改的配置文件没有错误 如上图所示,则退出容器exit

docker stop nginx
docker start nginx

7.可以访问了

第二种 用vi

要修改Nginx的配置文件,首先需要进入Nginx容器里面,使用下面的命令进入容器里面

docker exec -it nginx /bin/bash

上面命令的解释说明:

  1. -it:表示分配一个伪终端。


  2. nginx:表示容器的名称,这里也可以使用容器ID。


  3. /bin/bash:表示对容器执行bash *** 作。


执行过程如图所示

上面的截图中,我们使用ls查看,发现里面其实就是一个Linux *** 作系统。


Nginx默认会安装在etc目录下面  cd etc

然后进入nginx目录 cd nginx   在输入ls查看

我们看到了nginx.conf配置文件,需要在这个配置文件里面设置反向代理。


我们使用vim命令编辑nginx.conf文件: vim nginx.conf

尴尬的是容器里是没有vi命令的,我们就要贯彻我们的核心价值观,安装之...

apt-get update
apt-get install vim

然后update 就报错 因为因为没网  解决办法:指定网络模式为主机网络

docker rm -f nginx //删除nginx容器 重新构建
docker run --restart=always  --net=host  --name=nginx  -d  nginx

一句话总结,加了--net=host以后就不需要再做端口映射了.比如docker容器内在8080端口起了一个web server.不加的话需要把本机的某个port比如7979和docker内的8080做一个映射关系,访问的时候访问7979. 加了net=host则直接访问8080.  -p就不要了

//重启容器服务
systemctl restart docker

我们看最后红框里面的内容,表示使用的是conf.d目录下面的conf文件进行配置。


我们进入conf.d目录下面,然后编辑default.conf文件。


cd conf.d  然后 vim  default.conf

要配置反向代理,我们首先需要知道要代理的程序的IP地址,所以在修改配置之前,我们首先需要获取另一个容器的IP地址。


使用这个命令 需要先退出hash  输入 exit 即可 进入呢 需要在输入docker exec -it nginx /bin/bash

docker inspect 容器ID###输出容器的详细信息,需要逐行查看寻找ip,也可以配合grep等过滤,下面语句可以直接显示ip

docker inspect --format '{{ .NetworkSettings.IPAddress }}' 容器ID

如图所示

上面那个语句就会看到很多信息

获取到了容器的IP地址以后,我们就可以配置反向代理了。


default.conf文件 vim  default.conf 

因为容器是内部访问,所以设置的端口是80,而不是运行容器时设置的9020端口。


 修改完成之后保存退出。


我们可以使用下面的命令检查一下修改后的配置文件是否有错:

nginx -t

如图所示

如果修改的配置文件没有错误,则退出容器。


如果修改的配置文件有错误,要改正错误,然后退出容器。


由于我们修改了配置,所以需要重新运行容器,以便配置生效。


然后我们在浏览器里面访问4030端口

其他命令 及可能出现的问题

宿主机开启路由转发 注意的就是内核转发这个,一定不要忘了!配置方法如下

root@dell-PC:~# echo -e "net.ipv4.ip_forward = 1\nnet.ipv4.conf.default.rp_filter = 0 \nnet.ipv4.conf.all.rp_filter = 0" >> /etc/sysctl.conf
root@dell-PC:~# sysctl -p
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
root@dell-PC:~#
Docker容器内不能联网

1.使用–net:host选项

sudo docker run --net:host --name ubuntu_bash -i -t ubuntu:latest /bin/bash

2.使用–dns选项

sudo docker run --dns 8.8.8.8 --dns 8.8.4.4 --name ubuntu_bash -i -t ubuntu:latest /bin/bash

3.改dns server

vi /etc/default/docker
去掉“docker_OPTS="–dns 8.8.8.8 --dns 8.8.4.4"”前的#号

4.不用dnsmasq

vi /etc/NetworkManager/NetworkManager.conf
在dns=dnsmasq前加个#号注释掉

5.重建docker0网络 

pkill docker             #终止进程
iptables -t nat -F #清空nat表的所有链
ifconfig docker0 down #停止docker默认网桥
brctl delbr docker0 #删除网桥
docker -d

如果上面出现brctl 无法找到命令,需要安装brctl命令

yum install bridge-utils

Docker容器互访三种方式

我们都知道docker容器之间是互相隔离的,不能互相访问,但如果有些依赖关系的服务要怎么办呢。


下面介绍三种方法解决容器互访问题。


方式

一、虚拟ip访问

就是上面的获取容器Ip  ping

[root@33fcf82ab4dd /]# ping 172.17.0.7
PING 172.17.0.7 (172.17.0.7) 56(84) bytes of data.
64 bytes from 172.17.0.7: icmp_seq=1 ttl=64 time=0.205 ms
64 bytes from 172.17.0.7: icmp_seq=2 ttl=64 time=0.119 ms
64 bytes from 172.17.0.7: icmp_seq=3 ttl=64 time=0.118 ms
64 bytes from 172.17.0.7: icmp_seq=4 ttl=64 time=0.101 ms

这种方式必须知道每个容器的ip,在实际使用中并不实用

方式

二、link

运行容器的时候加上参数link

 docker run -it --name centos-2 --link centos-1:centos-1 docker.io/centos:latest

--link:参数中第一个centos-1是容器名,第二个centos-1是定义的容器别名(使用别名访问容器),为了方便使用,一般别名默认容器名。


[root@e0841aa13c5b /]# ping centos-1
PING centos-1 (172.17.0.7) 56(84) bytes of data.
64 bytes from centos-1 (172.17.0.7): icmp_seq=1 ttl=64 time=0.210 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=2 ttl=64 time=0.116 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=3 ttl=64 time=0.112 ms
64 bytes from centos-1 (172.17.0.7): icmp_seq=4 ttl=64 time=0.114 ms

此方法对容器创建的顺序有要求,如果集群内部多个容器要互访,使用就不太方便。


方式

三、创建bridge网络

1.安装好docker后,运行如下命令创建bridge网络:docker network create testnet  查询到新创建的bridge testnet。


2.运行容器连接到testnet网络。


使用方法:docker run -it --name <容器名> ---network <bridge> --network-alias <网络别名> <镜像名>

docker run -it --name centos-1 --network testnet --network-alias centos-1 docker.io/centos:latest
docker run -it --name centos-2 --network testnet --network-alias centos-2 docker.io/centos:latest

3.从一个容器ping另外一个容器,测试结果如下:

[root@fafe2622f2af /]# ping centos-1
PING centos-1 (172.20.0.2) 56(84) bytes of data.
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=1 ttl=64 time=0.158 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=2 ttl=64 time=0.108 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=3 ttl=64 time=0.112 ms
64 bytes from centos-1.testnet (172.20.0.2): icmp_seq=4 ttl=64 time=0.113 ms

4.若访问容器中服务,可以使用这用方式访问 <网络别名>:<服务端口号>

推荐使用这种方法,自定义网络,因为使用的是网络别名,可以不用顾虑ip是否变动,只要连接到docker内部bright网络即可互访。


bridge也可以建立多个,隔离在不同的网段。


Docker:4种网络模式详解

当你安装Docker时,它会自动创建三个网络。


你可以使用以下docker network ls命令列出这些网络:

Docker内置这三个网络,运行容器时,你可以使用该--network标志来指定容器应连接到哪些网络。


该bridge网络代表docker0所有Docker安装中存在的网络。


除非你使用该docker run --network=<NETWORK>选项指定,否则Docker守护程序默认将容器连接到此网络。


我们在使用docker run创建Docker容器时,可以用 --net 选项指定容器的网络模式,Docker可以有以下4种网络模式:

host模式:使用 --net=host 指定。


none模式:使用 --net=none 指定。


bridge模式:使用 --net=bridge 指定,默认设置。


container模式:使用 --net=container:NAME_or_ID 指定。


下面分别介绍一下Docker的各个网络模式。


host

docker run --name=nginx_host --net=host  -d nginx

一句话总结,加了--net=host以后就不需要再做端口映射了.比如docker容器内在8080端口起了一个web server.不加的话需要把本机的某个port比如7979和docker内的8080做一个映射关系,访问的时候访问7979. 加了net=host则直接访问8080.

参考文章

https://www.cnblogs.com/dotnet261010/p/12596185.html

https://www.cnblogs.com/star8521/p/13097294.html

https://www.cnblogs.com/qwfy-y/p/13461828.html

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/587995.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-12
下一篇 2022-04-12

发表评论

登录后才能评论

评论列表(0条)

保存