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个笔记
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并访问
参考教程:
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
上一篇: python(open文件读取)