• aspnetcore 容器化部属到阿里云全过程记录


    第一次写博客,作为一个全栈er,记录一下从阿里云到产品运维上线的全过程

    一、阿里云上的设置

    购买阿里云ECS后:

    进控制台查看实例公网IP

     

    在控制台、网络与安全-》安全组,配置规则

     

    点击进去可以看到

     

    系统默认创建了3个规则,icmp用来ping的,22是linux服务器ssh远程端口,3389是windows服务器远程端口

    【他的这个网络安全,就相当于阿里云自己在所有的服务器外围加了一个自己的网络防火墙,所以进到系统之后可以看到firewall和iptables都是没有的】

     

    我这里给ftp添加了21端口的,ftp动态范围添加了30000/30009的

    然后给web测试网站对外添加了8081这个tcp端口

     

    现在可以通过xshell远程登录到我的服务器了

     

    二、centos服务器上软件的安装

    既然切换到netcore做开发,那么跨平台这个特性肯定是要发挥一下的。

    既然是在linux上,Docker容器化这么火,肯定是尝试一下的!

    所以这里我们的所有应用都放到docker容器中,数据库mysql也是部属在容器里,不会直接装在服务器本身上。

    2.1、centos上docker的安装(一行一行复制,执行就可以了)

    sudo yum install -y yum-utils device-mapper-persistent-data lvm2 
    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
    sudo yum makecache fast 
    sudo yum -y install docker-ce 
    sudo systemctl enable docker 
    sudo systemctl start docker

    Docker加速(用阿里云的仓储镜像)

    vi /etc/docker/daemon.json 
    { 
        "registry-mirrors": ["https://0c27u24p.mirror.aliyuncs.com"] 
    } 
    systemctl daemon-reload 
    systemctl restart docker

    2.2、FTP服务安装

    既然是服务器,肯定要把开发好的应用发布到服务器上的,那么就涉及到ftp服务器的安装

    在linux上最流行的ftp服务器是vsftp,这个软件的安装折腾了2天才莫名其妙的搞定。

    整体的思路其实是很简单的:

    s1:安装软件

    我自己收藏的2个笔记

    http://note.youdao.com/noteshare?id=0442a68077dd91a08db759ccafce0a53&sub=78FCD074B2BC40589B8CCF7FD84D5A3A

    1、检查是否已安装vsftpd
    #rpm -q vsftpd
    或者
    #rpm -qa|grep vsftpd
    或者(查看vsftpd版本)
    #vsftpd -v
    
    2、安装vsftpd
    #yum -y install vsftpd
    
    3、查看位置
    #whereis vsftpd
    
    4、启动
    #systemctl start vsftpd.service
    或者
    #systemctl start vsftpd
    
    5、检查服务是否正常启动
    #ps -ef|grep vsftpd
    
    6、查看端口21是否被占用
    #netstat -lnp|grep 21

    s2:配置(最最坑爹的地方)

    配置文件

    先备份一份配置文件:

    #cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak

    然后编辑配置文件

    #vi /etc/vsftpd/vsftpd.conf

    总结了一个可用的配置

    anonymous_enable=NO
    local_enable=YES
    write_enable=YES
    local_umask=022
    dirmessage_enable=YES
    xferlog_enable=YES
    connect_from_port_20=YES
    xferlog_std_format=YES
    listen=NO
    listen_ipv6=YES
    pam_service_name=vsftpd
    userlist_enable=YES
    tcp_wrappers=YES
    pasv_min_port=30000
    pasv_max_port=30009
    chroot_local_user=YES
    chroot_list_enable=YES
    chroot_list_file=/etc/vsftpd/chroot_list

    直接拿这个用就可以了,每一项的意思可以百度

    添加一个ftp用户

    增加用户ftpuser,指向目录/home/wwwroot/ftpuser,禁止登录SSH权限。

    useradd -d /home/wwwroot/ftpuser -g ftp -s /sbin/nologin ftpuser

    设置用户口令

    passwd ftpuser

    编辑文件chroot_list(内容为ftp用户名,每个用户名占一行):

    vi /etc/vsftpd/chroot_list

    启用pasv模式【就是上面配置最后几个】

    pasv_enable=YES         #启用被动模式
    pasv_min_port=30000     #被动模式使用端口范围
    pasv_max_port=30009     #被动模式使用端口范围

    然后重启ftp服务

    # systemctl restart vsftpd 重启服务

    S3:更坑爹的地方!

    网上找的方法都是去配置服务器的防火墙了比如iptables,firewall

    但是阿里云的ecs默认是没有装防火墙的。而是在阿里云的控制台里面去设置的!!!

    所以这里一定要注意,是在阿里云控制台配置网络安全组,添加对应的端口规则!

     

    最后:

    这样我们就可以用ftp客户端软件,连接到服务器上了,用户名是自己创建的用户名ftpuser和密码

     

    三、dotnetcore程序的发布

    演示项目,随便建一个core 的web项目,直接发布到文件夹即可

    然后用ftp工具,把publish目录发布到服务器上,在服务器上创建Dockerfile文件

     

    容器化部属最主要的是Dockerfile文件,我用的以下方式,每个参数可以百度查一下就知道了

    from 是用来构建的镜像

    workdir是容器里面的工作目录,即容器启动默认的文件夹

    expose是容器对外暴露端口号

    copy 将服务器上的目录,拷贝到容器里的目录

    entrypoint 容器中使用dotnet命令,执行TestWeb.dll程序

    FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-stretch-slim AS final
    WORKDIR /app
    EXPOSE 800
    COPY ./publish .
    ENTRYPOINT ["dotnet", "TestWeb.dll"]

    然后用docker生成自己的镜像【注意命令中的最后一个点 代表的是命令从你的当前目录下执行】

    #docker build -t test003 .

    然后查看刚刚生成的镜像

    >docker images

    然后镜像运行生成实例容器

    docker run --name testweb -d -p 900:80 test003

    --name 指定容器的名字

    -d 后台进程。

    -p 是进行宿主和容器之间的端口映射,(-p 宿主端口:容器端口)

    最后参数是使用的镜像名

     

     然后用docker ps查看当前运行中的容器

     

    可以看到使用的镜像是test003,容器的名字是testweb

    我这里添加了一个对外端口900,容器里面的端口80的映射,

    现在访问是访问不了的!要去阿里云的网络组里面设置开放900端口

     

    最后,容器的停止和删除

    然后停止该容器

    #docker stop testweb

    删除容器

    #docker rm 容器名称或ID

    重启容器

    #docker start testweb

    删除镜像的命令

    #docker rmi 镜像名称或ID

    四、在docker里面安装mysql并访问

    参考教程:https://www.runoob.com/docker/docker-install-mysql.html

    docker操作老套路

    step1:拉镜像

    >docker pull mysql

    step2:查看本地镜像

    >docker images | grep mysql

    step3:运行镜像

    >docker run -p 3306:3306 --name mymysql -v $PWD/conf:/etc/mysql/conf.d -v $PWD/logs:/logs -v $PWD/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6

    说明:

    -v 将mysql三个主要的目录映射到host主机,conf配置、data数据、logs日志

    -e 设置root密码

     step4:查看容器

    >docker ps

    step5:进容器查看

    >docker exec -it mymysql bash

    进去之后是基本的mysql命令

    >mysql -u root -p
    
    输入密码 
    
    >show databases;
    
    >其他的看mysql操作命令的笔记

    五、nginx部署

    aspnetcore的默认web服务器是kestrel,官方也不建议直接用,而是用nginx等web服务器来转发

    有几个好处:

    1安全:kestrel本身并没有太多的功能,比如安全方面的。所以在他前面加一层代理,安全方面由nginx控制

    2nginx做负载均衡转发

     

    又是docker常规操作

    s1、拉镜像

    >docker pull nginx

    s2、运行镜像生成容器

    >docker run --name mynginx -p 8081:80 -d nginx

    参数说明:(都一样的)

    --name 自定义容器的名称

    -p 将宿主的端口8081映射到容器的端口80

    -d 也就是deamon的缩写,后台守护进程维护,也就是在后台一直运行

     

    s3、宿主机器上创建3个目录,用来映射到nginx容器里面

    这样以后修改nginx配置等操作,就不用进到容器里面了

    >mkdir -p ~/nginx/www ~/nginx/logs ~/nginx/conf

    www放置网站文章

    logs放日志文件

    conf放配置文件

     

    s4、从容器里面copy一份nginx的配置出来

    >docker cp 6dd4380ba708:/etc/nginx/nginx.conf ~/nginx/conf

    其中容器id自己用ps命令查

     

    s5、删掉原来的容器(原来的容器,作用是copy一份配置出来的

    >docker stop mynginx
    
    >docker rm mynginx

    s6、重新部署nginx容器

    docker run -d -p 8081:80 --name mynginx -v ~/nginx/www:/usr/share/nginx/html -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v ~/nginx/logs:/var/log/nginx nginx

    命令说明:

    • -p 8081:80: 将容器的 80 端口映射到主机的 8082 端口。
    • --name mynginx:将容器命名为 mynginx。
    • -v ~/nginx/www:/usr/share/nginx/html:将我们自己创建的 www 目录挂载到容器的 /usr/share/nginx/html。
    • -v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:将我们自己创建的 nginx.conf 挂载到容器的 /etc/nginx/nginx.conf。
    • -v ~/nginx/logs:/var/log/nginx:将我们自己创建的 logs 挂载到容器的 /var/log/nginx。

     

    s7、放一个index.html网页测试文件到www目录

    >vi ~/nginx/www/index.html

    随便编辑一些信息进去测试用

     

    s8、查看nginx的访问日志、错误日志

    >tail -f ~/nginx/logs/access.log

    s9、用nginx反向代理,做负载均衡(默认轮询算法)

    nginx的docker映射端口8081:80

    web集群是800到803共4台,用内网IP

    改nginx的配置

    >vi ~/nginx/conf/nginx.conf

    在http里面加

        upstream my_test_web {
        server 172.18.79.214:800;
        server 172.18.79.214:801;
        server 172.18.79.214:802;
        server 172.18.79.214:803;
        }
    
    
        server{
            listen 80;
            
            location / {
                proxy_pass http://my_test_web;
                proxy_set_header Host $host;
            }
    
        }

    最后整体网络架构图是这样的

     

     

    六、思考总结

    docker命令里的-v参数

    是将宿主主机上的目录或文件,挂载到docker容器里面,

    这样我们不用单独去操作一个一个的容器

    比如mysql的配置文件,和数据文件目录,都挂载在宿主机器上

    将nginx的配置文件和虚拟目录文件都放在宿主机器上

    将我们要发布的网站文件都放在宿主机器上,然后多个容器都映射到这个目录,这样发布都只需要发布一个目录?

    且不需要挨个进到容器里面去操作!!!

    发布、更新完之后,只需要重启一下容器就可以了?

     

     

    七、应用部署升级

    构建Dockerfile时有个copy命令,将host上的发布文件夹里的内容,复制到镜像的目录

    COPY ./publish .

    现在思考,我们的应用采用集群部署,部署到4-5个容器中,

    每次发布更新后,我们都要经历这样几个步骤:

    s1、ftp上传文件到host的publish目录,

    s2、重新生成新的镜像》docker build -t crmImg002

    s3、停止原来的应用集群》docker stop web001、docker stop web002 等等【可以批量操作docker stop $(docker ps -qf name=web80)】

    s4、删除原来的应用集群》docker rm web001、等等【可批量docker rm $(docker ps -qf name=web80)】

    s5、删除原来的镜像》docker rmi crmImg001

    s6、运行新的镜像,生成容器集群》docker run --name web800 -d -p 800:80 crmImg002

    依次生成多个端口的800、801、802、803.。。。。。等等

     

    整个步骤又长,又重复,而且随着集群数量变多,操作重复易遗漏。

     

    根据上面对docker run的参数-v的思考,大胆尝试一下:

     

    步骤如下:

    s1、修改Dockerfile文件,去掉copy那一行,镜像不需要拷贝文件进去了

    s2、重新生成镜像,crmImg003 以后发布程序后都不用重新生成了

    s3、停止原来的容器,删除原来的容器

    【docker stop $(docker ps -qf name=web80)】

    【docker rm $(docker ps -qf name=web80)】

    s4、启动新的容器(关键是-v参数的使用)

    docker run --name crm_web001 -d -p 800:80 -v /home/ftpdir/p3:/app img01
    docker run --name crm_web002 -d -p 801:80 -v /home/ftpdir/p3:/app img01
    docker run --name crm_web003 -d -p 802:80 -v /home/ftpdir/p3:/app img01
    docker run --name crm_web004 -d -p 803:80 -v /home/ftpdir/p3:/app img01

    OK,启动了4个应用,

    s5、在nginx中集群服务中添加这4个应用的端口即可!

     

    以后程序更新后的发布操作:

    s1、ftp上传程序到p3目录

    s2、重启这4个容器

    docker restart crm_web001
    docker restart crm_web002
    docker restart crm_web003
    docker restart crm_web004

    或者用批量操作(-q只显示id,-f 过滤,name=crm_web 名字有crm_web字符的)

    docker restart $(docker ps -qf name=crm_web)

    至此:以后发布程序只需此2步即可!(发布、重启)省事!!

      

    八、Docker常规操作总结

     

    1、看有哪些容器在运行

    docker ps

    参数:

    -q 只看id

    -f 过滤条件,key=value格式,支持正则

     

    2、删除容器

    docker rm 容器名

    3、删除对应镜像

    docker rmi 镜像名

    4、重新build镜像

    docker build -t img001 .

    注意最后的符号.

    5、重新运行容器

    docker run --name web800 -d -p 800:80 img001

    docker run --name web801 -d -p 801:80 img001

    这样就用同一个镜像img001,运行了2个容器web800和web801分别对应的端口是800和801

    6、查看容器日志

    linux查看一个文件用>tail -f wenjian.conf

    容器里面可以用

    docker logs -f mynginx

     

  • 相关阅读:
    利用条件变量实现生产者消费者模型
    加密算法
    brk mmap malloc使用
    c++中的RTTI机制
    std::array vector 数组联系和区别
    Intent基本使用
    [WPF]DataGrid C#添加右键弹出选择菜单
    c# 通过解析mp3规范命名并上传服务器
    自定义ComboBox,简简单单实现
    自定义窗体,简简单单实现
  • 原文地址:https://www.cnblogs.com/terry-012/p/11289114.html
Copyright © 2020-2023  润新知