欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

8天入门docker系列 —— 第四天 使用aspnetcore小案例熟悉端口映射和挂载目录

程序员文章站 2022-04-08 20:28:34
到目前为止大家应该对镜像和容器有了一个大概认知,而且也用了docker进行了一个简单化的部署,但仔细一看问题还有很多,所以这篇我们继续完善。 一:如何让外网访问到容器内应用 我们知道容器内拥有自己的子网,和你的主机ip不在一个网段内,所以宿主之外的机器是无法访问的,要实现的话你只能通过nat转发,在 ......

   到目前为止大家应该对镜像和容器有了一个大概认知,而且也用了docker进行了一个简单化的部署,但仔细一看问题还有很多,所以这篇我们继续完善。

 

一:如何让外网访问到容器内应用

        我们知道容器内拥有自己的子网,和你的主机ip不在一个网段内,所以宿主之外的机器是无法访问的,要实现的话你只能通过nat转发,在docker上实现起

来很简单,通过 -p 将容器端口映射到宿主机端口即可。

 

1. 在dockerfile中,容器会自动监听8080端口,而且我的程序也是开启了这个端口号。

from microsoft/dotnet:2.2-aspnetcore-runtime
label author hxc@qq.com
run mkdir /data
copy ./ /data
workdir /data
volume /data/log
expose 8080
cmd [ "dotnet","webnotebook.dll" ]
    public class program
    {
        public static void main(string[] args)
        {
            createwebhostbuilder(args).build().run();
        }

        public static iwebhostbuilder createwebhostbuilder(string[] args) =>
            webhost.createdefaultbuilder(args)
                .useurls("http://*:8080")
                .usestartup<startup>();
    }

 

2. 接下来通过 -p 端口映射,将宿主机的8080端口和容器的8080端口进行一个映射,前面是宿主机端口,后面是容器的,你也可以写成 hostip:8080:8080

[root@localhost ~]# docker run -d --name webnotebook -p 8080:8080 huangxincheng520/webnotebook:v4
82cf45e8fb7281fda7d1b22bf6ef1a5156a75f04b4ef29873d44f161b0238cfb
[root@localhost ~]# 
[root@localhost ~]# docker ps
container id        image                             command                  created             status              ports                    names
82cf45e8fb72        huangxincheng520/webnotebook:v4   "dotnet webnotebook.…"   3 seconds ago       up 2 seconds        0.0.0.0:8080->8080/tcp   webnotebook

 

3.  然后我就可以在windows上输入网址访问了,可以看到一点问题都没有。

8天入门docker系列 —— 第四天 使用aspnetcore小案例熟悉端口映射和挂载目录

4.  有些人可能会很好奇的去问,这个是怎么做到的呢? 刚才也说到了是通过nat进行协议头ip地址替换进行转发的,你要是不信的话,可以用centos的

     iptables nat去查看一下。

 

[root@localhost ~]# iptables -t nat -l -n
chain prerouting (policy accept)
target     prot opt source               destination         
docker     all  --  0.0.0.0/0            0.0.0.0/0            addrtype match dst-type local

chain input (policy accept)
target     prot opt source               destination         

chain output (policy accept)
target     prot opt source               destination         
docker     all  --  0.0.0.0/0           !127.0.0.0/8          addrtype match dst-type local

chain postrouting (policy accept)
target     prot opt source               destination         
masquerade  all  --  172.17.0.0/16        0.0.0.0/0           
return     all  --  192.168.122.0/24     224.0.0.0/24        
return     all  --  192.168.122.0/24     255.255.255.255     
masquerade  tcp  --  192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
masquerade  udp  --  192.168.122.0/24    !192.168.122.0/24     masq ports: 1024-65535
masquerade  all  --  192.168.122.0/24    !192.168.122.0/24    
masquerade  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:8080

chain docker (2 references)
target     prot opt source               destination         
return     all  --  0.0.0.0/0            0.0.0.0/0           
dnat       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.17.0.2:8080

 

    可以看到,docker在iptables中实现了一个自己的docker chain,从 hostip:8080 -> 172.17.0.2:8080中可以看到,当一个请求到了 192.168.23.149:8080

会自动转发到 172.17.0.2.8080,有些人可能会问,这个明显不是一个网段怎么转发呢? 那是因为你的宿主机上有一个默认的网桥docker0,你可以理解成

他就是一个数据链路层上的路由器,通过这个路由器,可以将不同的网段进行互联,你可以用ipconfig查看docker0的ip地址,这个ip地址就相当于路由器ip,

也即是子网地址。

[root@localhost ~]# ifconfig
docker0: flags=4163<up,broadcast,running,multicast>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:25ff:fe14:8a13  prefixlen 64  scopeid 0x20<link>
        ether 02:42:25:14:8a:13  txqueuelen 0  (ethernet)
        rx packets 105061  bytes 8399597 (8.0 mib)
        rx errors 0  dropped 0  overruns 0  frame 0
        tx packets 148379  bytes 425576796 (405.8 mib)
        tx errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<up,broadcast,running,multicast>  mtu 1500
        inet 192.168.23.149  netmask 255.255.255.0  broadcast 192.168.23.255
        inet6 fe80::20c:29ff:fe5c:2e32  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:5c:2e:32  txqueuelen 1000  (ethernet)
        rx packets 1570930  bytes 2222888854 (2.0 gib)
        rx errors 0  dropped 0  overruns 0  frame 0
        tx packets 532628  bytes 56478232 (53.8 mib)
        tx errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<up,loopback,running>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (local loopback)
        rx packets 104  bytes 8816 (8.6 kib)
        rx errors 0  dropped 0  overruns 0  frame 0
        tx packets 104  bytes 8816 (8.6 kib)
        tx errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth871156e: flags=4163<up,broadcast,running,multicast>  mtu 1500
        inet6 fe80::3c7f:5fff:fe53:4542  prefixlen 64  scopeid 0x20<link>
        ether 3e:7f:5f:53:45:42  txqueuelen 0  (ethernet)
        rx packets 99  bytes 726984 (709.9 kib)
        rx errors 0  dropped 0  overruns 0  frame 0
        tx packets 306  bytes 19235 (18.7 kib)
        tx errors 0  dropped 0 overruns 0  carrier 0  collisions 0

virbr0: flags=4099<up,broadcast,multicast>  mtu 1500
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        ether 52:54:00:83:96:c2  txqueuelen 0  (ethernet)
        rx packets 0  bytes 0 (0.0 b)
        rx errors 0  dropped 0  overruns 0  frame 0
        tx packets 0  bytes 0 (0.0 b)
        tx errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

二:如何处理容器中的日志数据

    我们的webnotebook运行的时候总会产生一些日志,这时候可以把日志文件夹挂载到宿主机上,方便查看和采集啥的,当然更多的情况是采用集中式

的日志收集,这个就不是本篇所讨论的了,接下来我要做两件事情,配置nlog日志框架,然后进行docker目录挂载。

 

1.  配置nlog框架,在nuget上下载

8天入门docker系列 —— 第四天 使用aspnetcore小案例熟悉端口映射和挂载目录

 

2.  nlog.config 配置如下,{basedir} 就是当前程序的根目录。

 

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/nlog.xsd" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance">
    <targets>
        <target name="file_info" xsi:type="file"
                        filename="${basedir}/log/${shortdate}.txt" maxarchivefiles="30"
                        layout="${longdate} | ${level:uppercase=false} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
    </targets>
    <rules>
        <logger name="*" writeto="file_info" />
    </rules>
</nlog>

 

3.  然后我们的controller类修改一下,记录下客户端的ip地址。

 public class homecontroller : controller
    {
        public static logger logger = logmanager.getlogger("simpledemo");

        /// <summary>
        /// 读取mongodb数据数据
        /// </summary>
        /// <returns></returns>
        public iactionresult index()
        {
            var log = $"客户端:{httpcontext.connection.remoteipaddress} 访问了 index 页面!";

            logger.info(log);

            return view();
        }
    }

 

 4.  接下来你就可以docker build 成镜像啦,在 docker run 中使用-v参数,将宿主机的 /data/log 挂载到容器的 /data/log目录,如下命令。

[root@localhost publish]# docker build -t huangxincheng520/webnotebook:v5 -f ./dockerfile .
[root@localhost publish]# docker run --name webnotebook5 -d -p 8080:8080 -v /data/log:/data/log huangxincheng520/webnotebook:v5
0e03f54d69ccdf3f88511385fd6fd5fdcafb64c0f971cbadb0b93014cb79e375

 

5. 一切都部署好了,接下来你可以访问8080端口,然后到你的宿主机的/data/log目录下查看一下,你的日志就出来啦。

[root@localhost log]# pwd
/data/log
[root@localhost log]# ls
2019-02-20.txt
[root@localhost log]# tail 2019-02-20.txt
2019-02-20 04:13:36.2904 | info | 客户端:::ffff:192.168.23.1 访问了 index 页面! 
[root@localhost log]# 

    细心的你应该会发现到,日志所打印出的时间出了问题,比北京时间少了8个小时,所以你要做的是,把默认的0区时间改成东8区即可,那怎么修改呢?

 

《1》 在docker run 中加入 -e 参数,也就是加入环境变量 -e tz=asia/shanghai 即可,不要怕参数多,以后这些都是通过ci工具集成的,不要怕哈。

[root@localhost publish]# docker run --name webnotebook5 -d -p 8080:8080 -v /data/log:/data/log -e tz=asia/shanghai  huangxincheng520/webnotebook:v5
18cbd284dbd6f6ff498d849eda7652ec63df3c0113c0cdd53ae4a0030abb52f2

     

       访问网站之后再看看你的log文件,时区已经调整过来了。

[root@localhost log]# tail 2019-02-20.txt
2019-02-20 04:13:36.2904 | info | 客户端:::ffff:192.168.23.1 访问了 index 页面! 
2019-02-20 12:20:38.3752 | info | 客户端:::ffff:192.168.23.1 访问了 index 页面!

 

《2》 在dockerfile中增加环境变量占位符。

from microsoft/dotnet:2.2-aspnetcore-runtime
env tz asia/shanghai

 

好了,本篇就说到这里,希望对你有帮助。