選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
梁辉 2c52678f5e Update 'README.md' 3年前
albumy final project 删除 3年前
readme_image final project 删除 3年前
tests final project 删除 3年前
uploads final project 删除 3年前
.flaskenv final project 3年前
.gitignore final project 3年前
Dockerfile commit1 3年前
LICENSE commit1 3年前
Pipfile commit1 3年前
Pipfile.lock commit1 3年前
README.md Update 'README.md' 3年前
gconfig.py commit1 3年前
main.py commit1 3年前
nginx_flask.conf commit1 3年前
nohup.out commit1 3年前
requirements.txt commit1 3年前
run.py commit1 3年前

README.md

本次实验源代码来自:https://github.com/greyli/albumy
demo网站:http://59.110.70.81:5000 或者http://106.75.223.107:5000
gitlab项目地址(注意是develop分支下的代码)
http://106.75.225.141/guoteng/albumy/tree/develop
(主机的带宽最好大一点,我的1M小水管打开网站测试极慢)
tomcat需要8080端口,nginx需要5000,80端口。
不必要的端口不要开,提前提示,谨慎reboot,update,upgrade,高并发优化不是必要的,谨慎使用。
系统:Centos 8

先创建一个有root权限的用户(这里用Rivenatte)
切换到Rivenatte:
su Rivenatte
更新:
sudo yum update
sudo yum upgrade
检查有没有gcc:
gcc -v
没有就:
sudo yum install gcc
有时需安装git:
sudo yum install git

拉取项目(这里用原项目的):
git clone http://gitea.shuishan.net.cn/10185501411/cloud_computing_1.git
cd albumy
配置虚拟环境:
python -m venv env(or python3 -m venv env)
source env/bin/activate
pip install -r requirements.txt
python -m pip install --upgrade pip
生成测试数据并测试:
flask forge
flask run --host 0.0.0.0 --port 5000
用浏览器打开http://云主机ip:5000
测试的用户账号:
username:admin@helloflask.com
password:helloflask

下面的pip可以换成pip3,如果你在创建虚拟环境时用python3的话
然而flask自带的wsgi容器性能较差,我采用另一个服务器,gunicorn。
先将我git上的python文件放在albumy中,
同时还需在项目目录下:
mkdir log
cd log
touch debug.log
touch gunicorn.pid
cd ..
这里的albumy指项目目录,不是albumy模块。

gunicorn需要在虚拟环境下安装:
(没进虚拟环境的先:
source env/bin/activate)
pip install gunicorn
同时还需安装gevent:
pip install gevent
推荐参考这个格式,指定源:
pip install 包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
可以解决大多问题。

然后:
cd albumy
修改__init__.py的create_app中的
app = Flask('albumy')
改为
app = Flask(__name__)
输入
gunicorn -c albumy项目的绝对路径/gconfig.py run:app
像上面一样,打开浏览器测试

继续用nginx来做反向代理。
先安装nginx:
sudo yum install nginx
接下来的配置,不同的linux发行版修改的文件可能不同,但大体类似。
实在不行就用whereis nginx找。
centos就先:
cd /etc/nginx
ls -a
发现conf.d这个文件夹,这个是放配置文件的
先对nginx.conf修改。
一般第二个https的设置是被注释的,不用管。
看http的设置,在http部分的最下面加入:
include conf.d/*.conf;(;不能少了)
这样我们就可以通过在conf.d文件夹里修改文件来进行配置
配置文件必须是.conf格式
比如 albumy.conf
server {
    listen 80;   
    root albumy项目的绝对路径;
    server_name 公网ip;
    location / {
        proxy_set_header x-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_pass http://localhost:5000/; # gunicorn绑定的端口号
    }
    # 配置static的静态文件:
    location ~ ^\/static\/.*$ {
        root 项目的绝对路径;
    }
}
添加后
sudo nginx -c /etc/nginx/nginx.conf
sudo nginx -t
sudo nginx -s reload
用浏览器打开80,5000端口,看下有没有成功。
80端口的仅仅是静态页面,比较简陋。

接着我们需要用nohup守护进程:
进入项目文件夹的虚拟环境:
cd xxx/albumy/
source env/bin/activate
nohup gunicorn -c gconfig.py run:app &
然后看下有没有成功:
ps -e | grep gunicorn

nohub不能让主机重启后自动运行进程,我们需要设置开机启动:
sudo vim /etc/rc.local
在最下面添加命令行,这样就可以在重启后自动执行命令行了。
最后别忘了加:
chmod +x /etc/rc.d/rc.local

然后可以重启检查下。

接下来进行高并发优化
我们需要安装ab压测工具
这个在任何服务器上部署都可以,只要在最后把ip改下就行。
这里申请一台centos8主机,部署ab。
同样不使用root用户。
先提醒下,deb系的安装与以下有点区别。

先更新:
sudo yum update
sudo yum upgrade

安装依赖:
sudo yum install apr-util
sudo yum install yum-utils
sudo mkdir -p /appdata/apache/ab && cd /appdata/apache/ab

安装ab:
sudo yum install yum-utils.noarch
sudo yumdownloader httpd-tools*
下一步需要root用户:
su root
rpm2cpio httpd-tools*.rpm | cpio -idmv
su Rivenatte
sudo cp /appdata/apache/ab/usr/bin/ab /usr/bin

执行ab:
ab -n 1000 -c 200 http://ip:5000/
如果不与项目在同一主机,写公网ip
在就localhost
1000指共访问了1000次,200指同时200并发
进行了5次
出现apr_pollset_poll: The timeout specified has expired (70007)
就改为ab -n 1000 -c 200 -k http://ip:5000/
看主机配置,量力而行。

先测试下,与优化后比较。

回到部署nginx的主机。
先获取cpu核心数:
grep processor /proc/cpuinfo | wc -l
一般在申请时就知道了
修改配置文件中的http模块:
sudo vim /etc/nginx/nginx.conf
具体参数参考以下文章:
https://www.jianshu.com/p/0fa77899913a
单核2g的主机可以参考以下配置:
worker_rlimit_nofile 10000;
events {
    worker_connections 10000;
}
keepalive_timeout 0;(高并发的网站需要设置的参数)

su root
(不用root用户无法进行下列命令)
对系统配置:
ulimit -n 一个较大的数字
echo 50000 > /proc/sys/net/core/somaxconn
more /proc/sys/net/core/somaxconn
有50000则正常
下列同理:
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle(注意,现在的centos取消了这个参数,没有可以不管)
cat /proc/sys/net/ipv4/tcp_tw_recycle
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
cat /proc/sys/net/ipv4/tcp_tw_reuse
echo 0 > /proc/sys/net/ipv4/tcp_syncookies
cat /proc/sys/net/ipv4/tcp_syncookies
dmesg|tail
(可能需vim /etc/sysctl.conf 
设置:
net.ipv4.tcp_syncookies = 0)
对测试主机也需:
echo 50000 > /proc/sys/net/core/somaxconn
ulimit -n 一个较大的数字
(可能需设置net.ipv4.tcp_syncookies = 0,同上)

不重启主机,对测试主机配置后开始测试: sudo vim /etc/sysctl.conf 加入: net.nf_conntrack_max = 655360 net.netfilter.nf_conntrack_tcp_timeout_established = 1200)

ab -c 100000 -n 100000 -r http://主机ip:5000/

(可以适当改下,但还是要看主机配置,我这台是2gRam 1核)

之后可以将以上系统设置加入自启动项(服务器重启可能会回到修改前设置)

下面添加邮箱:
先去注册个邮箱,并以stmp服务器发送。(这个需要网上查下如何开放邮箱stmp,不同邮箱的可能不同)

像之前一样,修改启动项:
source env/bin/activate
export MAIL_SERVER='smtp.163.com'  //示例
export MAIL_USERNAME='XXXXXX@163.com'  //填邮箱XXXXXX
export MAIL_PASSWORD='XXXXXX'   //密码,注意是邮箱开启第三方smtp的认证码
别忘了chmod +x /etc/rc.d/rc.local
最后reboot。
(注:这里需要邮箱发送验证邮件,才可以输入验证码注册)

采用docker部署与k8s集群负载均衡

一、docker部署上传镜像

配置docker容器并push到远端,重新在别的服务器上部署时只需将镜像pull下来即可。 写好Dockerfile,在本地build好镜像后,将容器push到远端。

在服务器上部署时只需将远端的容器pull到服务器上,再run即可

我们首先要将上面的run.py中的
app.run()改为app.run(host='0.0.0.0',port=3389)

部署时先下载docker

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

若报错则先执行

yum install -y https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm

接着启动docker服务

service docker start

写入我们的Dockerfile

vim Dockerfile
FROM python:3.6
RUN apt-get update
RUN apt install -y nginx

WORKDIR /Project/demo

COPY requirements.txt ./
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

COPY . .

RUN rm /etc/nginx/sites-enabled/default
COPY nginx_flask.conf /etc/nginx/sites-available/
RUN ln -s /etc/nginx/sites-available/nginx_flask.conf /etc/nginx/sites-enabled/nginx_flask.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
CMD ["nginx","-c","/etc/nginx/nginx.conf"]
CMD ["nginx","-t"]
CMD ["nginx","-s","reload"]
CMD ["gunicorn", "run:app", "-c", "./gconfig.py"]

其中需要我们之前部署时写的gconfig.py文件和我们的nginx配置文件

除此以外我们需要在根目录创建一个新文件nginx_flask.conf

server {
    listen      80;

    location / {
        proxy_pass http://localhost:5000/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location ^~ /static/ {
        root /Project/demo;
    }
}

之后在本地建立镜像

docker build -t image1 .

建立成功后可以尝试启动docker容器

docker run -d -p 3389:3389 --name test1 image1

打开http://云主机ip:3389查看是否显示界面

之后将我们的镜像push到远端

没有注册docker账号的话先注册一个docker账号

https://registry.hub.docker.com/

接着登录docker账号

docker login
输入账号
输入密码

显示login successful就成功了,之后push到远端

首先对镜像打标签

docker tag image1 lh123/albumy_nginx_mysql_image:v2

之后将镜像推送到仓库

docker push lh123/albumy_nginx_mysql_image:v2

以后需要创建应用时只需要从docker中拉取镜像运行即可。

新建云主机,安装docker之后将上述镜像pull到本地,之后执行

docker run -d -p 3389:3389 --name test1 lh123/albumy_nginx_mysql_image:v2

打开http:云主机ip:3389即可访问网页。

二、采用负载均衡

之后在ucloud中使用负载均衡ULB,创建负载均衡ULB。

接着在建立三台云主机,使用原来申请的有外网的云主机,分别通过内网连接三台新建的云主机。

在云主机上pull下来刚才上传的docker镜像

docker pull lh123/albumy_nginx_mysql_image:v2

在云主机上启动镜像

docker run -d -p 3389:3389 --name test1 albumy_nginx_mysql_image:v2

将我们启动好的三台云主机啊加到我们的负载均衡当中

使用负载均衡之后的压测效果更好

三、连接云数据库

为了保证负载均衡的服务器的数据一致性,我们将数据库挂在到云数据库mysql上

我们将项目的.flask.env文件中的设置改为

FLASK_APP=albumy
FLASK_ENV=development

再将setting.py中的设置改为

class ProductionConfig(BaseConfig):
    SQLALCHEMY_DATABASE_URI = 'mysql://root:lianghui123@10.23.56.255:3306/flask_test'

再打包到docker并运行我们的项目

发现报错No module named MYSQLdb发现是因为

按照 Flask-SQLAlchemy 文档的说明,配置好 SQLALCHEMY_DATABASE_URI = 'mysql://username:password@server/db' 后操作 MySQL 报错 ImportError: No module named 'MySQLdb'。既然缺少 MySQLdb 这个模块,按照常规方法缺啥补啥吧,执行 pip install MySQL-python 却报错 ImportError: No module named 'ConfigParser'。查了一下,这是由于 MySQL-python 不支持 Python 3(MySQL-3.23 through 5.5 and Python-2.4 through 2.7 are currently supported)。

将MySQLdb换为pymsql,安装pymsql(记得先启动虚拟环境)

pip install pymsql

并在__init__.py中加入

import pymysql
pymysql.install_as_MySQLdb()

再将setting.py中的设置改为

class ProductionConfig(BaseConfig):
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:lianghui123@10.23.56.255:3306/flask_test'

即可访问我们的云主机数据库。

最后将完成的项目打包好镜像push到远端仓库。

四、k8s集群部署(有点问题)

建立好docker容器之后就可以使用k8s集群部署网页,采用k8s部署可以实现容器集群的自动化部署、自动扩缩容、维护等功能。

首先在ucloud中创建一个UK8S,之后申请一个云主机,

登录云主机安装docker拉取镜像

docker pull lh123/albumy_nginx_mysql_image:v2

安装k8s


wget https://storage.googleapis.com/kubernetes-release/release/v1.19.0/bin/linux/amd64/kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/   (root用户:mv kubectl /usr/bin/)
kubectl version -o json

将K8S的集群凭证添加到kubectl配置文件中,从而能够操控集群。

打开K8S的外网集凭证复制,在云主机中创建~/.kube文件夹,并在其中创建config文件,将外网集凭证复制到config文件中。

为了能在k8s上部署我们的docker镜像,我们还需要在项目文件中添加两个文件Deployment.yamlservice.yaml

deployment.yaml中:

apiVersion: extensions/v1beta1
 kind: Deployment
 metadata:
   name: albumy-node-deployment
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: albumynode
   template:
     metadata:
       labels:
         app: albumynode
     spec:
       containers:
       - name: albumynode
         image: lh123/albumy_nginx_mysql_image:v2
         imagePullPolicy: Always
         ports:
         - containerPort: 3389

service.yaml中:

apiVersion: v1
 kind: Service
 metadata:
   name: albumy-node-deployment
 spec:
   ports:
   - port: 3389
     targetPort: 3389
   selector:
     app: albumynode

之后运行一下命令部署项目

kubectl create -f deployment.yaml

kubectl create -f service.yaml

查看pod是否处于ready状态,若pod不处于ready状态且一直是containercreating状态则

查看创建日志,发现是容器创建失败,谷歌不能访问,uhub-edu.service.ucloud.cn/google_containers/pause-amd64:3.0"镜像无法获取,这应该是ucloud端的问题。(我们采用平时实验作业第八次的部署方法部署实验2里的静态网页也还是报这个错误,真的是很无语)。

(即使用

kubectl create deployment webapp --image=lh123/albumy_nginx_mysql_image:v2

我们发现这样子pod的状态还是一直处于containercreating的状态,而且也是报下图的错误,我觉得者应该是ucloud端的问题,被墙了。我怀疑是ucloud的教育云出问题了之前第八次实验的时候还可以用,现在就不可以用了。

解决方法如下,从docker.io把pause-amd64镜像取下来,然后做个标签。这样就可以解决问题。

docker pull googlecontainer/pause-amd64:3.0
docker tag googlecontainer/pause-amd64:3.0 uhub-edu.service.ucloud.cn/google_containers/pause-amd64:3.0

之后新建连接,登录云主机执行

echo -e "\n\e[92mStarting Proxy. After starting it will not output a response. Please click the first Terminal Tab\n"; kubectl proxy

之后访问我们的应用

kubectl get pods#获取我们pod的名称
export POD_NAME=$刚才得到的pod名称
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/

查看我们创建的POD的详细信息

kubectl get pods -o wide

之后将副本scale到10个

kubectl scale deployments/albumy-node-deployment --replicas=10

将我们的网页暴露给公网,并加上负载均衡

创建一个负载均衡

kubectl expose deployment albumy-node-deployment --type=LoadBalancer --port=80

查看service,可以看到负载均衡服务的外网ip地址

kubectl get services

之后访问http:localhost:负载均衡ip就可以看到网页

本次作业镜像:

账号:1491337293@qq.com

密码:18830095812zxc

docker账户

账号:lh123

密码:18830095812zxc

docker镜像:lh123/albumy_nginx_mysql_image:v2

ucloud上docker部署镜像名:docker_nginx_mysql

集群部署有点问题被墙了。

五、总结与反思

通过本次大作业,我们学习网站前后端的知识,学习了云计算的一些基本知识,亲自部署了云上的应用,学习了docker、k8s等云计算工具的使用,更好的理解了的docker和k8s的用途,和它们在真实云计算环境下对项目部署的帮助。但我们的部署和开发并不完善,一些应用的细节问题没有解决,关于docker、k8s和其他云计算工具的许多知识还需要学习 分工:项目部署、README书写、版本控制、前后端修改:郭腾、梁辉 前后端开发修改、版本控制、项目部署:沈小奇