• .Net Core2.1 秒杀项目一步步实现CI/CD(Centos7.2)系列一:Docker入门


    前言:有一段时间没写博客了,那是因为博主菜,需要学习和准备,这不带来了本系列的文章。在这里我把学习的心得分享出来,有些点理解的也不是太到位,希望大佬们能多多给点建议和指导。下半年就把这个系列的文章写完,使用的技术暂时先不说,保持神秘感。哈哈哈

    一、项目介绍

    该项目整体上使用的是ASP.Net Core2.1,没有按照DDD来分层,因为博主不会,O(∩_∩)O哈哈~,项目中使用的分层具体参考的是张辉清老师的《中小研发团队架构实践》,项目整体整体分层如下图所示:

     目前为了简单,项目没有按照DDD来分层,先把第一版的写完,后面有时间的话再使用DDD来重构。源码暂时先不公开,都是一些很简单的东西,写这系列的文章初衷是让大家熟悉微服务的整个流程。

    二、Docker安装

     关于Docker的基础知识,在这里不会讲解,可以通过其他途径学习,在这里,我只简单介绍一下在Centos7.3上安装Docker(跟着官方文档也可以:https://docs.docker.com/install/linux/docker-ce/centos/

    (1)如果之前你装过,没有卸载干净,请执行下面的操作

    $ sudo yum remove docker 
                      docker-client 
                      docker-client-latest 
                      docker-common 
                      docker-latest 
                      docker-latest-logrotate 
                      docker-logrotate 
                      docker-engine

     (2)安装仓储

    $ sudo yum install -y yum-utils 
      device-mapper-persistent-data 
      lvm2
    $ sudo yum-config-manager 
        --add-repo 
        https://download.docker.com/linux/centos/docker-ce.repo

    (3)安装Docker

    $ sudo yum install docker-ce docker-ce-cli containerd.io

    (4)启动Docker服务

    $ sudo systemctl start docker

    (5)查看Docker版本

    [root@localhost ~]# docker version

    看到这样的结果说明Docker是安装成功了

    三、Docker的基本命令

    part 1、热身命令

     (1)查看镜像:docker image ls

    (2)查看容器:docker container ls

    注意:

    •  使用docker  container ls 查看当前本地正在运行的容器, 前面使用docker run image的名字  可以运行该容器,但是运行完就会结束,并不是一个常驻内存的进程

    (3)查看容器:docker container ls -a

    注意:

    • docker container ls -a  会列出所有的容器包括正在运行的也包括退出的。当我们通过docker run 去基于一个image创建一个容器的时候,默认回去执行cmd的命令。

    细心的同学会发现,如果本地没有对应的镜像,会自动到远程仓储中拉取,地址:https://hub.docker.com/,当我们再使用docker container ls -a,会发现多了一个容器。

    (4)后台启动容器:docker run -it centos

     注意:

    • 一定要注意那些操作是在容器当中,那些是在宿主机中。

    我们也可以在容器中进行读写文件:

    (5)退出容器

    ctrl+d可以直接退出容器

    注意:

    • 单纯的想在容器中保存信息,是有问题的,因为容器是不能持久化数据的,想保存数据涉及到其他方面的知识,这里就暂时不展开了。

    part2、docker命令

    有关docker的命令分为两大类:管理命令和命令

    管理命令是对docker内的对象进行管理,这里我只说说一下几个,关于更多的命令,可以参考文档。

    (1)删除具体某个容器 :docker container rm  xxxxx      这里的xxxxx  指的是CONTAINER ID

    (2)删除具体的image:docker image rm  xxxxx      xxxxx      指的是镜像ID

     注意删除image时,先把容器停掉,在删除容器,最后再删除image。好了关于docker的命令就讲到这里。让我们尝试着构建自己的项目镜像。

    四、Docker中部署项目

     (1)在部署前,先在项目中创建Dockerfile

    FROM microsoft/dotnet:2.1-aspnetcore-runtime
    LABEL maintainer="guoz@qq.com"
    RUN mkdir /data
    COPY ./ /data
    WORKDIR /data
    EXPOSE 80
    CMD [ "dotnet","Spike.Api.dll" ]

    (2)然后点击发布,把发布后的内容上传到虚拟机中 /data/publish文件夹下,具体内容如下:

     注意:不要忘记Dockerfile文件了。

    (3)接下来,构建自己的镜像

    [root@localhost publish]# docker build -f ./Dockerfile -t guozheng007/spike:v2 .
    Sending build context to Docker daemon 16.23MB
    Step 1/7 : FROM microsoft/dotnet:2.1-aspnetcore-runtime
    ---> 81472b549eb2
    Step 2/7 : LABEL maintainer="guoz@qq.com"
    ---> Using cache
    ---> 18deb5693198
    Step 3/7 : RUN mkdir /data
    ---> Using cache
    ---> 47b4b4e77f1a
    Step 4/7 : COPY ./ /data
    ---> 10f80a57a6c1
    Step 5/7 : WORKDIR /data
    ---> Running in 45867fc7ec79
    Removing intermediate container 45867fc7ec79
    ---> 39bd97e0b669
    Step 6/7 : EXPOSE 80
    ---> Running in 92d8c475a18f
    Removing intermediate container 92d8c475a18f
    ---> d7753067afa7
    Step 7/7 : CMD [ "dotnet","Spike.Api.dll" ]
    ---> Running in 5b94f4ff3c44
    Removing intermediate container 5b94f4ff3c44
    ---> c15413ef3f96
    Successfully built c15413ef3f96
    Successfully tagged guozheng007/spike:v2

     (4)启动容器

     下面我们就使用上面的命令,来看看image是够构建成功

    [root@localhost publish]# docker images
    REPOSITORY                   TAG                      IMAGE ID            CREATED              SIZE
    guozheng007/spike            v2                       c15413ef3f96        About a minute ago   269MB
    guozheng007/spike            v1                       83b175b46208        14 hours ago         268MB
    guozheng007/dotnetcorecase   v1                       75cf01ec8b62        45 hours ago         265MB
    microsoft/dotnet             2.2-aspnetcore-runtime   c56aab97bc42        2 weeks ago          260MB
    microsoft/dotnet             2.1-aspnetcore-runtime   81472b549eb2        2 weeks ago          253MB
    [root@localhost publish]# docker run --name spikev2 -d guozheng007/spike:v2
    f4ebc38ce3b2b0de7e2a6bb1f8272de53a918fcf6921d859363ae1ef295853f6

     上面的操作是把该容器已经启动起来了,容器运行成功之后,会返回一个标识。

    (5)查看容器是否正在启动: docker ps

    [root@localhost publish]# docker run --name spikev2 -d guozheng007/spike:v2
    f4ebc38ce3b2b0de7e2a6bb1f8272de53a918fcf6921d859363ae1ef295853f6
    [root@localhost publish]# docker ps
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    f4ebc38ce3b2 guozheng007/spike:v2 "dotnet Spike.Api.dll" 2 minutes ago Up 2 minutes 80/tcp spikev2

    [root@localhost publish]# docker top spikev2
    UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
    root                4131                4114                0                   10:26               ?                   00:00:01            dotnet Spike.Api.dll
    [root@localhost publish]# ps -ef | grep dotnet
    root       4131   4114  0 10:26 ?        00:00:01 dotnet Spike.Api.dll
    root       4520   2936  0 10:33 pts/1    00:00:00 grep --color=auto dotnet

    (6)现在,我们确认容器和应用程序都运行起来了,那如何访问呢?如何查看容器的IP和Port

    docker inspect spikev2

    [root@localhost publish]# docker inspect spikev2
    [
        "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "ASPNETCORE_URLS=http://+:80",
                    "DOTNET_RUNNING_IN_CONTAINER=true",
                    "ASPNETCORE_VERSION=2.1.11"
                ],
                "Cmd": [
                    "dotnet",
                    "Spike.Api.dll"
                ],
                "ArgsEscaped": true,
                "Image": "guozheng007/spike:v2",
                "Volumes": null,
                "WorkingDir": "/data",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": {
                    "maintainer": "guoz@qq.com"
                }
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "0ccb6f368934d4cf211e0529813b22261a39d663e34008de8ea72cb201f937d0",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {
                    "80/tcp": null
                },
                "SandboxKey": "/var/run/docker/netns/0ccb6f368934",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "4008bc70feca0a7d6bd361dd5f57650acec344ec0ff5dcb44a0f032d48823731",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:02",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "70585ed93ba6d331c470379fe48ed81d80afe769543cdddcc3b44a58556bed5b",
                        "EndpointID": "4008bc70feca0a7d6bd361dd5f57650acec344ec0ff5dcb44a0f032d48823731",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:02",
                        "DriverOpts": null
                    }
                }
            }
        }
    ]

    从上面的信息可以看出,对外暴露的端口号是80  IP地址是172.17.0.2

    [root@localhost publish]# docker logs spikev2
    warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
          No XML encryptor configured. Key {345c33be-ab36-488a-84a2-81739761e037} may be persisted to storage in unencrypted form.
    Hosting environment: Production
    Content root path: /data
    Now listening on: http://[::]:80
    Application started. Press Ctrl+C to shut down.

     接下来让我们访问一把:

    不要走,客官,故事还没讲完,继续往后看。

    五、总结

    最后,我把实验的过程遇到的问题总结一下。

    (1)在构建镜像和容器的时候,名字要小些,不能大写。

     (2)在手动用vs发布的时候,遇到的问题  An assembly specified in the application dependencies manifest (xxx.deps.json) was not found

    解决办法,请参考这篇博客:https://blog.csdn.net/ArthurRen0803/article/details/80875019

    (3)在启动Docker时Centos7.3遇到:IPv4 forwarding is disabled. Networking will not work

    解决办法,请参考一下内容

    https://stackoverflow.com/questions/24756240/how-can-i-use-iptables-on-centos-7

    英文看不懂的看这个  https://www.jianshu.com/p/82067b8c0190

    https://blog.slogra.com/post-740.html

    (4)Centos7.3遇到:Failed to start iptables.service: Unit iptables.service failed to load

    解决办法:https://www.cnblogs.com/faunjoe88/p/7003815.html

    (5)关于Dockerfile的问题,如果遇到一下问题,可参考下面的解决办法

    六、最后再补充一点关于Dockerfile的最佳实践例子

    关键字

    (1)From centos

    尽量使用官方的image最为base image ,原因很简单 就是维了安全。

    (2)LABEL

    最佳实践:metadata 必不可少

    (3)RUN

    最佳实践:我们要知道,每运行一次RUN都会生成一层,为了美观,复杂的run请用反斜线换行,避免无用分层,合并多条命名为一行!!!

    (4)设定当前工作目录 WORKDIR

    最佳实践:用WORKDIR,不要用RUN cd  ,尽量是用绝对目录。

    (5)都是将本地的一些文件添加到docker image中,不同的一点是,ADD在添加压缩包时,不仅会添加到指定目录,而且还会解压。

    最佳实践:(添加本地文件是可以使用ADD  COPY   添加远程文件时 使用 curl 或者 wget),大多数情况下COPY优于ADD ,ADD 处理COPY还有解压的功能

    (6)ENV

    尽量是用ENV增加可维护性

    好了,暂时讲到这里,希望对你有帮助。

    参考文章:

    一线码农:https://www.cnblogs.com/huangxincheng/p/10391829.html

    麦兜搞IT:《系统学习Docker 践行DevOps理念》

    作者:郭峥

    出处:http://www.cnblogs.com/runningsmallguo/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

  • 相关阅读:
    表达式求值
    火柴排队(归并)
    POJ 3254 压缩状态DP
    ZOJ 3471 压缩状态DP
    Boost IPC Persistence Of Interprocess Mechanisms 例子
    TCO 2014 Round 1A
    Google Code Jam 2014 Qualification 题解
    STL set_difference set_intersection set_union 操作
    b_zj_特征提取(map记录上一个特征运动的次数)
    b_zj_最大连续的相同字符子串的长度(双指针+找突破点)
  • 原文地址:https://www.cnblogs.com/runningsmallguo/p/11147058.html
Copyright © 2020-2023  润新知