主頁 > .NET開發 > docker部署netcore專案 nginx負載均衡

docker部署netcore專案 nginx負載均衡

2020-09-14 09:19:41 .NET開發

前言:

本文主要內容是docker部署netcore應用以及docker運行nginx實作負載均衡,到目前為止感覺微軟在跨平臺的方面雖然有較大的進步,但是和linux比還是有一定的差距,在學習docker,nginx以及Netcore 程序中網上能查找參考的資料還是比較有限的,所以在此記錄下遇到的問題以及踩到的各種坑,希望避免再次走彎路,

一.新建NET Core應用程式;

1.添加Docker支持,由于到目前為止,nginx還不支持windows容器,為了便于本機測驗所以選用Linux容器,如下圖:

 

 

2.輸出請求處理,顯示當前請求IP以及埠號:

 

 

 3.編輯Dockerfile檔案

  dockerfile檔案指令說明:

  FROM -指定基礎鏡像(FROM是必備的指令,并且必須為第一條指令)

  WORKDIR-配置作業目錄

  EXPOSE-宣告鏡像內服務監聽的埠

  COPY-復制內容到鏡像

  ENTRYPOINT-啟動鏡像的默認人口命令

  ENV -設定環境變數

編輯后的dockerfile檔案如下:

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 8005
EXPOSE 443
ENV ASPNETCORE_URLS http://+:8005
COPY . .
ENTRYPOINT ["dotnet", "DockerDemo.dll"]

 右鍵屬性,選擇“如果較新則復制”

4.Docker發布,

Release生成解決方案,定位到reliease檔案夾,執行"docker build”指令,如下圖:

 

 在執行程序中,有可能會碰到“no such host”問題,重試幾次或者設定鏡像代理即可

ps: 鏡像版本后面有個空格+“ .”需留意 注意最后有個點,代表使用當前路徑的 Dockerfile 進行構建

運行 docker images查看當前鏡像:

 

可以看到已經成功構建, 

5.構建dockerdemo容器:

執行"docker run“指令,構建該鏡像的實體docker run -d -t -p 8006:8005  --name dockerdemo8006 dockerdemo:1.0,可以看到,容器已經構建成功:

 

瀏覽器輸入即可看到下列結果

 

 同理構建該鏡像的其他容器,分別為8007,8008;至此docker構建netcore鏡像已經完成,我們可以在Kitematic查看已經構建的容器;

 

二.Docker構建nginx容器實作負載均衡

1.執行“docker pull nginx“指令獲取鏡像,docker images 查看當前鏡像;

2.構建nginx鏡像容器

執行docker run -d -p 8003:80 --name dockernginxdemo nginx,其中-d表示后臺運行,-p表示開放的埠,將80埠代理到宿主8003埠,這樣訪問ip:8003就可以訪問nginx 80埠,--name表示容器名字,最后為鏡像名:標簽,

docker ps查看當前容器:

 

可以看出已經實體化鏡像檔案,在瀏覽器中輸入localhost:8003出現如下界面則表示成功:

 

 

3.修改nginx組態檔:

該頁面是鏡像檔案中自帶的一個html檔案,我們需要將我們自己nginx的組態檔復制替換容器自帶的組態檔,進入容器中

docker exec -it dockernginxdemo /bin/bash 
cat /etc/nginx/nginx.conf

可以看到Nginx鏡像自帶的nginx組態檔資訊

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

可以看到這和nginx教程中的組態檔有一定的區別的,我自己在這兒踩了幾個坑,nginx中的組態檔是作為一個整體的,而鏡像中是默認包括兩個檔案:default.conf和nginx.conf檔案,下圖是nginx教程中的組態檔

#定義Nginx運行的用戶和用戶組
#user  nobody; 

#nginx行程數,建議設定為等于CPU總核心數,
worker_processes  1; 

#全域錯誤日志定義型別,[ debug | info | notice | warn | error | crit ]
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#行程檔案
#pid        logs/nginx.pid;

#作業模式與連接數上限
events {
    #單個行程最大連接數(最大連接數=連接數*行程數)
    worker_connections  1024;
}

#設定http服務器
http {
    #檔案擴展名與檔案型別映射表
    include       mime.types;
    #默認檔案型別
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    #開啟高效檔案傳輸模式,sendfile指令指定nginx是否呼叫sendfile函式來輸出檔案,對于普通應用設為 on,如果用來進行下載等應用磁盤IO重負載應用,可設定為off,以平衡磁盤與網路I/O處理速度,降低系統的負載,注意:如果圖片顯示不正常把這個改 成off,
    sendfile        on;

    #防止網路阻塞
    #tcp_nopush     on;


    #長連接超時時間,單位是秒
    #keepalive_timeout  0;
    keepalive_timeout  65;

    #開啟gzip壓縮輸出
    #gzip  on;

    #虛擬主機的配置
    server {

        #監聽埠
        listen       80;

        #域名可以有多個,用空格隔開
        server_name  localhost;

        #默認編碼
        #charset utf-8;

        #定義本虛擬主機的訪問日志
        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
View Code

 

 如果直接將conf檔案替換鏡像中的nginx檔案的話,會出現“directive is not allowed here in /etc/nginx/conf.d/nginx.conf”這樣的問題,原因是在default.conf組態檔中,已經存在"server”節點,我們可以執行如下指令

docker cp f3d9ee01637a:/etc/nginx/conf.d/default.conf  E:/ngingconf/default.conf

將conf.d/default.conf檔案復制到 E:/ngingconf/default.conf檔案中,default.conf檔案如下:

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
View Code

可以看到,在default檔案中已經存在server節點,所以不能直接復制自定義的nginx.conf檔案到容器的nginx.conf檔案中,有兩種解決方案,第一分別修改nginx.conf和default.conf檔案;第二,將容器中的default.conf檔案內容洗掉,然后再復制自定義的conf檔案覆寫掉鏡像中nginx.conf的組態檔,這里,我們采用第一種方法,修改鏡像中Nginx.conf以及default.conf的區域節點;

首先,執行

docker cp f3d9ee01637a:/etc/nginx/nginx.conf  E:/ngingconf/nginx.conf

指令,將鏡像檔案中的nginx.conf檔案復制到本地,打開E:/ngingconf/nginx.conf,編輯組態檔如下:

 1 user  nginx;
 2 worker_processes  1;
 3 
 4 error_log  /var/log/nginx/error.log warn;
 5 pid        /var/run/nginx.pid;
 6 
 7 
 8 events {
 9     worker_connections  1024;
10 }
11 
12 
13 http {
14 
15     #集群站點配置
16     upstream nginxtest.com{
17         #server    127.0.0.1:8887 weight=1;#服務器配置   WEIGHT是權重的意思,權重越大,分配的概率越大,    
18         server    127.0.0.1:8006 weight=1;
19         server    127.0.0.1:8007 weight=1;
20         server    127.0.0.1:8008 weight=1;
21     }
22 
23 
24 
25     include       /etc/nginx/mime.types;
26     default_type  application/octet-stream;
27 
28     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
29                       '$status $body_bytes_sent "$http_referer" '
30                       '"$http_user_agent" "$http_x_forwarded_for"';
31 
32     access_log  /var/log/nginx/access.log  main;
33 
34     sendfile        on;
35     #tcp_nopush     on;
36 
37     keepalive_timeout  65;
38 
39     #gzip  on;
40 
41     include /etc/nginx/conf.d/*.conf;
42 }
View Code

nginx.conf檔案中,我們添加了

 

 

  節點指令,配置服務集群,對應之前的三個netcore應用的埠8006,8007,8008,然后執行

docker cp E:/ngingconf/nginx.conf f3d9ee01637a:/etc/nginx/nginx.conf

執行,將本地修改后的nginx.conf檔案拷貝到鏡像檔案中;同理,執行

docker cp f3d9ee01637a:/etc/nginx/conf.d/default.conf  E:/ngingconf/default.conf

將鏡像檔案中的default.conf檔案復制到本地,打開E:/ngingconf/default.conf,編輯組態檔如下:

 1 server {
 2     listen       80;
 3     server_name  localhost;
 4 
 5     #charset koi8-r;
 6     #access_log  /var/log/nginx/host.access.log  main;
 7 
 8      #快取檔案路由
 9     location ~ .*(\.(js|css|jpg|svg)).* {
10 
11         proxy_pass http://nginxtest.com;
12         proxy_cache_valid 200;
13         expires 3d;
14     }
15     #集群站點路由
16     location / {
17 
18         proxy_pass http://nginxtest.com;  #http://nginxtest.com對應upstream后面的名稱加上http
19         proxy_http_version 1.1;
20     proxy_redirect default;
21 
22         proxy_set_header Upgrade $http_upgrade; 
23         proxy_set_header Connection keep-alive;
24         proxy_set_header Host $host;
25         proxy_cache_bypass $http_upgrade;
26 
27         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
28     }
29 }
View Code

 注意 集群站點中“proxy_pass”后面引數名稱需要和nginf.conf檔案中集群名稱一致,隨后執行cp指令覆寫鏡像檔案即可;

4.測驗

 至此docker 部署nginx反向代理已經完成,預期效果是在網站中輸入localhost:8003就會訪問不同的埠號實作負載均衡實際效果運行卻是,,,

 

不甘心,有試了幾遍,還是這個結果 后來查看了下Kitematic,日志果然有其他問題:

 

 大概就是無法連接到集群里的服務器,推測了下應該是容器間的通信問題,于是驗證了下,用IIS而不是容器發布了應用然后用docker部署nginx負載均衡,其他步驟一樣,果然可以直接訪問而不會出現該問題,于是開始著手解決這個問題

三 .關于upstream server temporarily disabled while connecting to upstream nginx問題

 默認情況下,容器都是使用Docker橋接網路來與其他容器或者主機網路通信,所有的本地Bridged容器都是在同一個橋接網路上,并且默認可以相互通信的的,如下圖:

既然如此,容器之間應該可以通訊的,那為何會出現上述問題,

 

我們先執行 “docker network ls”指令查看docker中存在的網路:

 

“ bridge”為docker創建的默認網路,默認的都在改網路下,然后通過命令

docker network inspect bridge

查看bridge網路的詳細配置:

 

 可以看出,我們創建的四個docker容器檔案都在該網路下,但是IP地址卻不是我們之前分配的host:8006,host:8007,host:8008,如上圖綠色標記,我們將nginx.conf檔案中的集群節點做如下修改:

 #server    127.0.0.1:8887 weight=1;#服務器配置   WEIGHT是權重的意思,權重越大,分配的概率越大,    
        #server    127.0.0.1:8006 weight=1;
        #server    127.0.0.1:8007 weight=1;
       server 172.18.0.2:8005 weight=1;
        server 172.18.0.3:8005 weight=1;
        server 172.18.0.4:8005 weight=1;
        #server    127.0.0.1:8008 weight=1;

需要注意兩點:

1.集群下server節點需要加埠號,否則默認80埠;

2.本機測驗下需要確保集群節點的server子節點 和nginx在同一網路下;

 測驗,瀏覽器輸入Localhost:8003,運行結果如下圖:

可以看出,重繪頁面會訪問不同的埠,而且我們我也可以看出,服務端讀取到的ip地址其實就是docker網路中容器的IP地址;

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/33232.html

標籤:.NET Core

上一篇:NetCore3.1webApi + EFCore + DI 框架封裝

下一篇:基于微信個人收款碼的支付介面的實作與原始碼

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more