番外篇 萌新版开发交付一条龙(☆▽☆)

这篇具有很好参考价值的文章主要介绍了番外篇 萌新版开发交付一条龙(☆▽☆)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

学习了一段时间的django和vue,对于前后端开发有了一个初步的了解,这里记录一下编写的流程和思路,主要是为了后面如果遗忘从哪里开始操作做一个起步引导作用

一、Django后端

参考下前面django的文档https://moziang.blog.csdn.net/article/details/130720709

1、安装django环境

//配置清华镜像源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set global.trusted-host pypi.tuna.tsinghua.edu.cn
 
//安装django
pip install django==4.2.1


//创建项目paas
django-admin startproject  PAAS


//登录PAAS目录
cd  PAAS


//创建应用
python manage.py startapp app_demo1
python manage.py startapp app_demo2

目录结构

django直接使用vue,django,python,后端,vue,前端,k8s,docker

2、项目添加应用模块

vi test1\PAAS\PAAS\settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app_demo1',            #添加
    #'app_demo2'
]

ALLOWED_HOSTS = ['*']  #允许所有请求访问

在理想中我们需要维护一个大的平台项目,也就是paas平台,而app_demo1 和app_demo2 就是我们这个平台下负责某个功能的模块,这种模块可能有多个,为了区分他们不同模块对外提供的功能,我们首先要做的就是设置路由(urls),app_demo2我这里演示不用,先注释了

3、添加主路由转发到模块路由

PAAS/PAAS/urls.py


from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),

    #添加请求路由,当访问app1或者app2时会将请求交给两个模块下的urls路由
    path("app1/",include("app_demo1.urls")),
    #path("app2/",include("app_demo2.urls"))
]

4、添加模块路由配置

上面是将主路由指定到了模块下的子路由,我们模块下默认是没有路由文件的需要手动创建,这里我们只演示一个模块下的路由案例,另一个可以先忽略了,操作都一样

PAAS/app_demo1/urls.py

from django.urls import path


urlpatterns = [
    #添加请求路由,当访问app1或者app2时会将请求交给两个模块下的urls路由
    path("info/",函数方法,name="info"),

]



# 假设后端传递了路由名称为 "info" 到前端
#var url = "{% url 'info' %}";  
#在模板中使用Django模板标签获取路由URL
#然后在Vue.js中使用这个url
#例如:
#this.$router.push(url);  // 使用Vue Router进行页面跳转

在上面中的info 是请求接口的路径,当我们请求该接口的时候会去调用该函数,而name=info则是定义了info/这个路径的别名,当需要进行访问跳转时可以根据这个别名去快速访问,不需要考虑路径的问题,比如<a href="{% url 'info' %}">点击这里查看信息</a>

5、添加接口下函数功能

正常来说,我们django是只做后端的逻辑处理,将处理好的数据通过json格式的方法返回给请求方(前端)  然后根据前端的代码做逻辑判断后显示在页面上,现在我们想要对django的/app1/info/这个路径的请求,返回一个json数据。  而这些函数我们定义一个api的目录单独存放

#创建api目录
mkdir   api/ 

django直接使用vue,django,python,后端,vue,前端,k8s,docker

 PAAS/app_demo1/api/info.py

from django.http import JsonResponse

#这里的函数名称开头必须小写
def paasInfo(request):
    # 定义需要返回的数据
    data = {
        "status": "success",
        "message": "Data retrieved successfully",
        "data": {
            "user": {
                "id": 123,
                "username": "张三",
                "email": "123@qq.com"
            }
        }
    }

    #返回json类型数据
    return JsonResponse(ata)

6、补全模块路由配置

from django.urls import path

#通过.做相当路径导入,适用于包内导入
from .api import info

urlpatterns = [
    #添加请求路由,当访问app1或者app2时会将请求交给两个模块下的urls路由
    path("info/",info.paasInfo,name="info"),

]

7、测试访问

现在我们的后端基础的格式就完成了,下面我们测试下访问是否能返回json数据

http://127.0.0.1:8000/app1/info

 django直接使用vue,django,python,后端,vue,前端,k8s,docker

 这里可以看到我们已经可以通过访问后端的api接口获取一些数据了,具体的其他逻辑放到下面说,我们下面开始整前端程序

二、 Vue 前端

0、切换目录

#这里的目录是我们上面django的项目根目录
#我们将vue的项目目录和django的项目目录平级,方便迁移
cd C:\Users\Administrator\IdeaProjects\test1

1、安装环境

这块都是页面操作不重复编写,参考我下面的文档装下环境(完成步骤一即可)

​https://moziang.blog.csdn.net/article/details/134414702​

2、目录结构

django直接使用vue,django,python,后端,vue,前端,k8s,docker

3、测试访问

#ie浏览器会显示不出来,可以换edge
http://localhost:8080/

django直接使用vue,django,python,后端,vue,前端,k8s,docker

 4、添加vue工作目录

我现在想要创建多个页面,每个页面都有独立的功能,首先我们需要先区分开文件存放的位置,没有的目录手动创建下

src/components    #存放 Vue 组件文件的目录。

src/assets         #存放静态资源文件的目录,如图片、字体等。

src/views          #存放路由组件文件的目录,通常用于组织不同路由对应的页面组件。

src/api          #存放与后端 API 交互的文件

src/store        #存放 Vuex 相关的文件,用于状态管理。

src/router      #存放 Vue Router 相关的文件,用于配置路由。

 django直接使用vue,django,python,后端,vue,前端,k8s,docker

5、安装路由插件

npm install -g vue-router

6、定义视图函数(view)

my-vue-app/src/views/index.vue

<template>
    <div>
        我是主页
    </div>
</template>

<script>
export default {
    name: "IndexView",
}
</script>

<style>
/* 这里可以添加一些页面样式 */
</style>

7、添加路由配置

my-vue-app/src/router/router.js

import { createRouter,createWebHistory } from 'vue-router' //引入路由插件函数

import  IndexView from '@/views/index.vue'   //引入被路由到的页面相关文件

//定义需要路由的组,可以定义多个 (基本都在改这个
const routes = [
    {
        path: '/',
        name: 'IndexView',  //这里是字符串哈
        component: IndexView
    },
]


// 创建路由
const router = createRouter({
    history: createWebHistory(),
    routes
});

export default router

8、注册路由

my-vue-app/src/main.js

import { createApp } from 'vue'
import App from './App.vue'



const  app = createApp(App)
import router from './router/router'
app.use(router);  //注册路由

app.mount('#app')


9、清理app.vue 视图

// app.vue
<template>
    <div>
        <router-view></router-view>
    </div>
</template>

<script>
export default {
    name: "App",
}
</script>

<style>
/* 这里可以添加一些全局样式 */
</style>

10、切换目录启动项目

#切换到package.json所在的目录
cd C:\Users\Administrator\IdeaProjects\test1\my-vue-app>

#启动服务
npm run serve

11、访问页面 (IE浏览器打不开)

http://localhost:8081/

django直接使用vue,django,python,后端,vue,前端,k8s,docker

 说明:

上面从6-11步都是为了后续开发梳理一个大致的流程

步骤6中定义了单个页面的显示信息,

步骤7定义了我们具体通过访问那个路由来到达视图的位置

举个例子比如说我们现在想要加俩页面,访问/paas  和/log 两个路由到各自的页面

案例

和步骤6一样,先添加视图文件,直接复制改下页面

my-vue-app/src/views/paas.vue

<template>
    <div>
        paas
    </div>
</template>

<script>
export default {
    name: "PaasView",
}
</script>

<style>
/* 这里可以添加一些页面样式 */
</style>

 my-vue-app/src/views/log.vue

<template>
    <div>
        log
        
    </div>
</template>

<script>
export default {
    name: "LogView",
}
</script>

<style>
/* 这里可以添加一些页面样式 */
</style>

添加路由,和步骤7类似

my-vue-app/src/router/router.js 

import { createRouter,createWebHistory } from 'vue-router' //引入路由插件函数

import  IndexView from '@/views/index.vue'   //引入被路由到的页面相关文件
import PaasView from '@/views/paas.vue'
import LogView from "@/views/log.vue";

const routes = [
    {
        path: '/',
        name: 'IndexView',
        component: IndexView
    },
    // 新增路由
    {
        path: '/paas',
        name: 'PaasView',
        component: PaasView
    },

    {
        path: '/log',
        name: 'LogView',
        component: LogView
    },
]


// 创建路由
const router = createRouter({
    history: createWebHistory(),
    routes
});

export default router

访问测试

http://localhost:8081/paas
http://localhost:8081/log

django直接使用vue,django,python,后端,vue,前端,k8s,docker

django直接使用vue,django,python,后端,vue,前端,k8s,docker

后续编写依此类推

12、定义前台主页文件

没怎么接触过前端,之前我想自己整个前端页面方便使用一些小工具来提升效率,但碰到这块的时候我确不清楚应该怎么去调用各个层级的路由(vue还没学到路由),所以我的方法是利用app.vue文件做一个主页面的显示,通过点击按钮跳转访问vue自身的不同路由

// app.vue
<template>
    <div>
        <router-view></router-view>
          <!--        添加html跳转路由-->
        <router-link to="/">主页</router-link>
        <router-link to="/paas">paas</router-link>
        <router-link to="/log">log</router-link>
    </div>
</template>

<script>
export default {
    name: "App",
}
</script>

<style>
/* 这里可以添加一些全局样式 */
</style>

 django直接使用vue,django,python,后端,vue,前端,k8s,docker

通过上面的方法,我们可以从主页去手动访问各个视图的路由页面实现跳转,关于样式不着急用先放着,下面我们试着通过调用后端的api来请求和接收数据

13、vue调用后端接口

定义接口函数,在vue中通过按钮或者其他方法触发

my-vue-app/src/api/paasinfo.js

export function paasClusterInfo(method, params) {

    if (method === 'GET') {
        // 如果是GET请求,将参数拼接到URL上
        //url += '?' + new URLSearchParams(params).toString();
        return fetch('/app1/info/', {
            method: 'GET',  //可以是post请求 根据你后端逻辑判断即可
            headers: {
                'Content-Type': 'application/json'
            }
        })
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok')
                }
                return response.json()
            });
    } else if (method === 'POST') {
        // 如果是POST请求,将参数放在请求体中
        return fetch('/app1/info/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(params)
        })
            .then(response => {
                if (!response.ok) {
                    throw new Error('Network response was not ok')
                }
                return response.json()
            });
    } else {
        throw new Error('Unsupported method')
    }
}

重新编辑paas视图,调用api函数将请求的数据打印到F12 开发工具页面

my-vue-app/src/views/paas.vue

<template>
    <div>
        paas
        <Button @click="getChange">按钮</Button>
    </div>
</template>

<script>
// 导入api
import { paasClusterInfo } from '@/api/paasinfo'

export default {
    name: "PaasView",
    methods: {
        async getChange() {
            console.log("输出个信息,证明函数执行了,再有报错就是下面请求的问题")
            try {
                const data = await paasClusterInfo('GET','action=list')  // 调用paasClusterInfo需要加上括号()
                console.log(data)
            } catch (error) {
                console.error("An error occurred:", error)
            }
        }
    }
}
</script>

<style>
/* 这里可以添加一些页面样式 */
</style>

vue在请求后端的时候会存在一些问题,比如跨域请求问题,需要单独进行配置

当做如下配置后,vue中发起的url请求,比如/app1 开头的请求会直接转发到下面的url中

my-vue-app/vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  devServer: {
    proxy: {
      //环境内请求/app1的请求都转给下面的地址,需要重启
      '/app1': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  }
})

 修改完上面的文件,必须要重启 ,不重启无法生效

 django直接使用vue,django,python,后端,vue,前端,k8s,docker

14、关于获取的数据显示

我们接口返回的数据格式如下,我们需要在前端页面上显示出来我们需要的值

{
    "status": "success",
    "message": "Data retrieved successfully",
    "data": {
        "user": {
            "id": 123,
            "username": "张三",
            "email": "123@qq.com"
        }
    }
}

console.log(data.status)
console.log(data.message)
console.log(data.data)

这个请求方法就是正常的json值的获取了

 django直接使用vue,django,python,后端,vue,前端,k8s,docker

 关于数据显示就看前面vue的一些使用方法了,比如v-mode 映射数据上去 ,字典加循环之类的

三、vue 构建docker镜像

django直接使用vue,django,python,后端,vue,前端,k8s,docker

我们在打包的时候会分为两个部分

1、 nginx + vue

2、python  + Django(Gunicorn)

这两个镜像打包的时候也存在一些区别,nginx+vue 为了性能考虑是以nginx作为主进程运行而不是vue作为主进程,而python + django则是以django为主进程运行

1、vue项目上传linux服务器

我们在实际部署时,需要通过命令npm run build 将vue项目中的public 和src目录下的静态文件、vue文件、图片、字体、css、js等信息经过转换压缩后存放到dist目录下,然后将dist目录直接仍到nginx主页下进行访问,打包文件如下

django直接使用vue,django,python,后端,vue,前端,k8s,docker

但是如果我们每次都需要手动操作进行打包,并不利于我们后续做自动化CI/CD的使用,这里我们直接考虑使用一个分段构建的形式,登录linux创建构建目录

我们先将项目拷贝一份出来,将项目中的dist和mode_modules目录删除,这俩一个是打包目录,一个是项目依赖目录,依赖模块我们打包镜像的时候重新下载即可

 django直接使用vue,django,python,后端,vue,前端,k8s,docker

#创建构建目录
mkdir /apps/web -p   
cd /apps/web   #直接将vue项目目录扔进去

django直接使用vue,django,python,后端,vue,前端,k8s,docker

2、编写dockerfile

#使用官方node镜像作为基础镜像
FROM node:14 as build-stage

#拷贝项目目录到镜像
COPY ./my-vue-app1 /home/my-vue-app1

#设置工作目录
WORKDIR /home/my-vue-app1

#添加加速源并安装依赖
RUN npm config set registry http://registry.npm.taobao.org/

#这块的3个RUN可以试着合并为一个RUN执行,我这边是跑的时候死活不能用 
#\ + && 一直报错就这样用了,另一台主机可以。 就很烦
RUN npm install

RUN npm run  build




# 使用 Nginx 镜像作为最终镜像
FROM nginx:1.21

# 将构建阶段生成的 dist 目录复制到 Nginx 的默认静态文件目录
COPY --from=build-stage /home/my-vue-app1/dist /usr/share/nginx/html

# 暴露 80 端口
EXPOSE 80

# 容器启动时运行 Nginx
CMD ["nginx", "-g", "daemon off;"]

3、构建镜像

docker build . -f Dockerfile  -t web-vue:v1

django直接使用vue,django,python,后端,vue,前端,k8s,docker

4、部署镜像

docker run -itd --name test1  -p 30030:80 docker.io/library/web-vue:v1

5、访问测试

http://linux服务器ip:30030/

django直接使用vue,django,python,后端,vue,前端,k8s,docker

看起来访问是正常的,但是当我们点击按钮访问后端django时还是有问题的

django直接使用vue,django,python,后端,vue,前端,k8s,docker

我们之前配置跨域访问的时候都是在同一台主机上所以直接用的localhost, 之前我们为什么要用则个代理,就是因为有个什么跨域访问的原因,但是我们现在已经将vue部署到了nginx上面,我们就可以把这块的配置去掉,让vue发起请求的时候访问自身,因为他是部署在nginx上的,他实际会访问到nginx,我们只需要在nginx上做反向代理,将vue访问自身的api相关的请求交给对应的服务器上即可,而后续我们修改请求地址就和vue无关,只需要根据请求接口变更代理地址即可

6、去除vue代理配置

vi /apps/web/my-vue-app1/vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({



});

7、添加nginx反向代理配置

vi /apps/web/default.conf

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # 反向代理设置
    location /app1/ {
        proxy_pass $VUE_APP_API_BASE_URL;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

8、重新构建镜像

vi Dockerfile

#使用官方node镜像作为基础镜像
FROM node:14 as build-stage

#拷贝项目目录到镜像
COPY ./my-vue-app1 /home/my-vue-app1

#设置工作目录
WORKDIR /home/my-vue-app1

#添加加速源并安装依赖
RUN npm config set registry http://registry.npm.taobao.org/

#这块的3个RUN可以试着合并为一个RUN执行,我这边是跑的时候死活不能用
#\ + && 一直报错就这样用了,另一台主机可以。 就很烦
RUN npm install

RUN npm run  build




# 使用 Nginx 镜像作为最终镜像
FROM nginx:1.21

# 将构建阶段生成的 dist 目录复制到 Nginx 的默认静态文件目录
COPY --from=build-stage /home/my-vue-app1/dist /usr/share/nginx/html

# 暴露 80 端口
EXPOSE 80

# 拷贝配置文件
COPY ./default.conf /etc/nginx/conf.d/
# 容器启动时运行 Nginx
CMD ["nginx", "-g", "daemon off;"]

重新构建

docker build . -f Dockerfile  -t web-vue:v1

部署

docker rm -f test1
docker run -itd --name test1  -p 30030:80   docker.io/library/web-vue:v1

9、访问nginx 调用后端接口

django直接使用vue,django,python,后端,vue,前端,k8s,docker

图里的报错说明我们请求已经能正常发送了,没有出现跨域报错,没有404,报错信息是返回的数据不是一个json格式,说明我们目前位置请求是正确的,关于那个nginx的配置文件的变量可以通过挂载的形式来调整,就不在动镜像了 ,开始做django后端镜像

(上面那个地址案例不太好,后面找个好看的案例贴上去 溜了溜了)

四、django镜像构建

 django 部分参考之前文章 https://moziang.blog.csdn.net/article/details/134195331

 架构子系统协同分析

1、nginx  
   #Nginx 运行起来是多个进程, 接收从客户端(通常是浏览器或者手机APP)发过来的请求
   #它会根据请求的URL进行判断, 如果请求的是静态资源, 比如HTML文档、图片等
   #它直接从配置的路径进行读取, 返回内容给客户端
   #如果请求的是动态数据, 则转发给Gunicorn+Django进行处理
 
 
2、Gunicorn/Django
    #Gunicorn和Django是运行在同一个 Python进程里面的, 它们都是用Python代码写的程序。
    #启动Gunicorn的时候,它会根据配置加载Django的入口模块,这个入口模块里面提供了WSGI接口。
    #当Gunicorn接收到Nginx转发的HTTP请求后, 就会调用Django的WSGI入口函数,将请求给Django进行处理
    #Django框架再根据请求的URL和我们项目配置的URL路由表,找到我们编写的对应的消息处理函数进行处理。
    #我们编写的消息处理函数,就是前面章节大家学习到的,处理前端请求。如果需要读写数据库,就从MySQL数据库读写数据。

1、添加项目权限及导入Gunicorn 功能

PAAS/PAAS/settings.py

#添加导入应用
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app_demo1',           
    'gunicorn',           #新增
    #'app_demo2'
]
 
 

DEBUG = False   #改成False

2、拷贝项目目录

django直接使用vue,django,python,后端,vue,前端,k8s,docker

3、删除拷贝项目中数据库配置

PAAS1/app_demo1/migrations     将目录下除init以外的都删掉,这个是django生成的数据库相关文件,如果不删除带到其他环境可能会因为同步数据库结构发生意料之外的问题

django直接使用vue,django,python,后端,vue,前端,k8s,docker

4、修改数据库变量

我们在不同环境中使用django的都需要配置对应环境的数据库,默认配置如下

 PAAS/PAAS/settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

我们用django去链接mysql数据库,正常情况配置如下

PAAS/PAAS/settings.py 

DATABASES = {
    'default':
        {
            'ENGINE': 'django.db.backends.mysql',    # 数据库引擎
            'NAME': 'paas', # 数据库名称
            'HOST': '101.43.156.78', # 数据库地址
            'PORT': 30013, # 端口
            'USER': 'root',  # 数据库用户名
            'PASSWORD': '123456', # 数据库密码
        }
}

为了方便我们构建镜像后在不同环境获取数据库的值,做一下改造 通过获取变量来配置数据库,同时给一个默认值

 PAAS/PAAS/settings.py

import os
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': os.environ.get('DB_NAME', 'paas'),
        'HOST': os.environ.get('DB_HOST', '101.43.156.78'),
        'PORT': int(os.environ.get('DB_PORT', 30013)),
        'USER': os.environ.get('DB_USER', 'root'),
        'PASSWORD': os.environ.get('DB_PASSWORD', '123456'),
    }
}

为了使用数据库,我们还需要另外装一些的东西

pip3 install pymysql
pip3 install cryptography

PAAS1/PAAS/__init__.py

import pymysql
pymysql.install_as_MySQLdb()

5、添加Gunicorn启动配置文件

PAAS1/gunicorn_conf.py

# gunicorn/django  服务监听地址、端口
bind = '0.0.0.0:8000'
 
# gunicorn worker 进程个数,建议为: CPU核心个数 * 2 + 1
workers =  3 
 
# gunicorn worker 类型, 使用异步的event类型IO效率比较高
worker_class =  "gevent"  
 
# 日志文件路径
#errorlog = "/home/gunicorn.log"
errorlog = "-"
loglevel = "info"
 
import sys,os
 
cwd = os.getcwd()
sys.path.append(cwd)

6、添加镜像启动脚本

vi PAAS1/main.sh

#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"
echo $DIR
 
cd $DIR
 
# ulimit -n 50000
#这里就是指定一下我们定义的配置文件
#PAAS.wsgi  就是我们这个项目的项目名称+ .wsgi就行
gunicorn --config=$DIR/gunicorn_conf.py PAAS.wsgi 
 
#后台运行用下面这个
#nohup gunicorn --config=$DIR/gunicorn_conf.py Django_demo.wsgi &> /dev/null &

7、导出项目所需依赖

#切换paas项目目录
cd C:\Users\Administrator\IdeaProjects\test1\PAAS1

#导出依赖
pip freeze > requirements.txt

django直接使用vue,django,python,后端,vue,前端,k8s,docker

8、添加额外库

vi requirements.txt

#添加
Gunicorn
gevent
greenlet 
os  #给那个data获取变量用的

说明

Gunicorn 是一个 Python WSGI HTTP 服务器,用于运行 Python Web 应用程序。它可以处理并发请求,提供了稳定、快速的性能,适合用于部署生产环境的 Web 应用。
 

gevent 是一个基于 libev 的并发库,它提供了协程和事件循环的机制,可以用于高性能的网络应用程序。gevent 可以在 Python 中实现异步 I/O,通过协程实现并发处理,从而提高网络应用程序的性能和吞吐量。
 

greenlet 是 gevent 的底层实现,它提供了轻量级的协程机制,允许在 Python 程序中实现协作式多任务处理。gevent 是基于 greenlet 实现的,它提供了更高级的接口和功能,使得在 Python 中实现高性能的并发处理变得更加容易

9、创建app项目目录

mkdir /apps/app

#将PAAS1 项目仍进去

10、编写dockerfile

FROM python:3
#这里导入的时候换下目录名称,因为项目本身还是PAAS
COPY  ./PAAS1 /home/PAAS/
WORKDIR /home/PAAS/

RUN python3 -m pip config set global.index-url  https://pypi.douban.com/simple/ \
    && python3 -m pip config set global.trusted-host pypi.douban.com \
    && pip3 install -r requirements.txt \
    && chmod +x main.sh

CMD ["./main.sh"]

构建

docker build . -f Dockerfile -t test-app:v1

部署

#不带数据库变量(不带就用默认变量)
docker run -itd --name test2 -p 30031:8000    docker.io/library/test-app:v1


#带数据库信息启动
docker run -itd --name test2 -e DB_NAME=mydb -e DB_HOST=192.168.1.100 -e DB_PASSWORD=strongpassword   docker.io/library/test-app:v1

11、查看日志是否报错

docker logs test2

返回

/home/PAAS
[2024-02-02 03:05:44 +0000] [9] [INFO] Starting gunicorn 21.2.0
[2024-02-02 03:05:44 +0000] [9] [INFO] Listening at: http://0.0.0.0:8000 (9)
[2024-02-02 03:05:44 +0000] [9] [INFO] Using worker: gevent
[2024-02-02 03:05:44 +0000] [10] [INFO] Booting worker with pid: 10
[2024-02-02 03:05:44 +0000] [11] [INFO] Booting worker with pid: 11
[2024-02-02 03:05:44 +0000] [12] [INFO] Booting worker with pid: 12

写这块的时候比较忙,本来想演示的时候把数据库配置带上但忘记没做数据库相关的配置,上面有部分是后改的没有验,不确定是否有漏写的配置,有大兄弟做到这块了日志有报错私信发我下,会看

12、访问测试

http://服务器ip:30031/app1/info/

django直接使用vue,django,python,后端,vue,前端,k8s,docker

13、指定web容器nginx代理到django

cd /apps/web

vi default.conf

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # 反向代理设置
    location /app1/ {
        proxy_pass 127.0.0.1:30031;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

重构镜像

docker build . -f Dockerfile  -t web-vue:v1



docker rm -f test1
docker run -itd --name test1  -p 30030:80   docker.io/library/web-vue:v1

14、验证从vue访问后通过nginx代理到django

#访问vue
http://101.43.156.78:30030

django直接使用vue,django,python,后端,vue,前端,k8s,docker

可以看到我们基本已经可以实现前后端容器的访问了,但是还是存在一些问题

nginx代理地址需要我们手动配置,我们更希望通过一种域名的方法去访问,但在实际环境中我申请个域名访问太费劲了,如果我自己个人使用的,那么直接使用docker network 创建一个网络,然后nginx通过容器name就可以实现访问,但这并不适用于较大的环境,处于考虑我们还是使用docker容器的编排部署工具K8S

五、服务上云(需先部署K8S环境)

环境搭建参考下前面的搭建文档 https://moziang.blog.csdn.net/article/details/132618086

1、查看节点状态

kubectl get node

返回

NAME           STATUS   ROLES                  AGE    VERSION
k8s-master01   Ready    control-plane,master   6m1s   v1.22.2

我用的云服务器是单节点的,所以这里就一台同时作为master和node节点

2、yaml文件模板

在编写yaml前我们需要了解在K8s中的,无状态服务和有状态服务,无状态应用通常将状态信息存储在外部的数据存储服务(如数据库、缓存、文件存储等)中,而不是在应用本身内部,像是常见的无状态应用包括Web服务器、负载均衡器、API服务,所以这里我们基于K8S中的Deployment控制器进行编写

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master01
      containers:
      - name: web-app
        image: nginx
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            memory: "2Gi"
            cpu: "1000m"
          requests:
            memory: "2Gi"
            cpu: "500m"
        env:
        - name: APP_ENV       
          value: "production"
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        ports:
        - containerPort: 80
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 60
          periodSeconds: 3
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
        lifecycle:
          postStart:
            exec:
              command: ["/bin/sh", "-c", "touch /tmp/1.txt"]
          preStop:
            exec:
              command: ["/bin/sh", "-c", "rm -f /tmp/1.txt"]
        volumeMounts:
        - name: localtime
          mountPath: /etc/localtime
          readOnly: true
      volumes:
      - name: localtime
        hostPath:
          path: /etc/localtime

配置说明

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app         #控制器名称
spec:
  replicas: 3          #pod的副本梳理
  selector:
    matchLabels:
      app: web         #匹配模板定义的标签
  template:
    metadata:
      labels:
        app: web      #模板定义的标签

    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master01     #将模板调度到特定主机上


      containers:              #容器详情
      - name: web-app          #容器名称
        image: nginx           #镜像名称
        imagePullPolicy: IfNotPresent  #镜像策略


                              
        resources:           #资源限制
          limits:
            memory: "2Gi"
            cpu: "1000m"        #硬限制为1C
          requests:
            memory: "2Gi"
            cpu: "500m"        #最低调度要求为0.5C


                      
        env:           #设置环境变量

        - name: APP_ENV        #常规变量定义
          value: "production"

        - name: NODE_NAME      #模板信息变量获取定义
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName   #获取模板带出的变量配置,这里是宿主机的主机名
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP



        ports:                      #查看端口配置
        - containerPort: 80         #容器端口声明
          protocol: TCP




        livenessProbe:             #设置健康检查
          httpGet:
            path: /                 #检查服务的/路径
            port: 80                
          initialDelaySeconds: 60   #初次检查时间为容器创建后60s
          periodSeconds: 3          #检查间隔时间
          failureThreshold: 3      #检查失败次数


        readinessProbe:             #就绪检查探针,和上面基本一样,就是0/1 到1/1的转变
          httpGet:                  #就绪检查不会导致容器重启
            path: /
            port: 80
          initialDelaySeconds: 5



        lifecycle:                 #声明周期勾子
          postStart:                #容器正常启动后执行啥
            exec:
              command: ["/bin/sh", "-c", "touch /tmp/1.txt"]
          preStop:                  #容器退出之前挂掉执行啥
            exec:
              command: ["/bin/sh", "-c", "rm -f /tmp/1.txt"]



        volumeMounts:           #挂载外部存储到容器内
        - name: localtime           #这里是为了同步宿主机和容器的时间
          mountPath: /etc/localtime
          readOnly: true
      volumes:                   #提供挂载配置,没有这个上面的mount不了
      - name: localtime
        hostPath:
          path: /etc/localtime

3、编写Deployment模板

因为我们这里并不需要考虑后续对外注册什么的只是试验,这里的存储、俩检查、资源限制、狗子、节点匹配都可以先去掉,上面我定义了俩镜像web-vue:v1  和test-app:v1,把多余的配置去除,改下名称先跑跑看

 vi web.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: web-vue:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          protocol: TCP

vi app.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: test-app:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8000
          protocol: TCP

部署

kubectl apply -f web.yaml
kubectl apply -f app.yaml

查看

[root@k8s-master01 ~]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
api-84d68db78b-4667r   1/1     Running   0          24s
web-7d5cf4f9c9-j9lcc   1/1     Running   0          19s

4、创建后端svc

svc 是K8S 内部提供的一种负载均衡访问机制,这里是为了让web节点能够找到后端服务使用

vi app-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: api   #这里对应的名称是上面deployment中templates下面定义的
               #template: metadata: labels:  app: api   对应这个
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

部署

kubectl apply -f app-svc.yaml

查看

[root@k8s-master01 ~]# kubectl get svc
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
app-service   ClusterIP   10.99.245.102   <none>        8000/TCP   17m
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP    17h



[root@k8s-master01 ~]# curl 10.99.245.102:8000

django直接使用vue,django,python,后端,vue,前端,k8s,docker

5、创建前端svc

前端是直接面向用户进行访问的,所以还需要创建一个对外保留端口的svc,这里使用的模式是nodeport

vi web-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: NodePort
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30033

部署

[root@k8s-master01 ~]# kubectl apply -f web-svc.yaml
service/web-service unchanged

[root@k8s-master01 ~]# kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
app-service   ClusterIP   10.99.245.102    <none>        8000/TCP       5h27m
kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP        22h
web-service   NodePort    10.107.201.127   <none>        80:30033/TCP   63s

 这里将我们的web服务以30033端口暴露在整个集群所有主机上,我们直接通过集群内任意主机+30033端口访问到web页面

//换成自己宿主机ip即可
http://101.43.156.78:30033/

django直接使用vue,django,python,后端,vue,前端,k8s,docker

6、修改web nginx后端地址

我们在上面使用docker部署的时候是通过在nginx配置文件中定义了后端的地址,这里明显不能在使用了

django直接使用vue,django,python,后端,vue,前端,k8s,docker

我们先去看看nginx代理之前配置的啥,

[root@k8s-master01 ~]# kubectl exec -it web-7d5cf4f9c9-j9lcc bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

root@web-7d5cf4f9c9-j9lcc:/# cat /etc/nginx/conf.d/default.conf

django直接使用vue,django,python,后端,vue,前端,k8s,docker

是直接指定固定地址(分好几天写的,应该是测试的时候改过,不影响下面操作)

cd /apps/web/

 vi default.conf

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # 反向代理设置
    location /app1/ {
        proxy_pass http://${DJANGO_HOST}:${DJANGO_PORT};
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

我们这里需要将他改成 后端svc的名称+端口,我们也不希望每次改地址都打镜像,这里将经常变更的变量声明${}的格式,方便后续我们修改

vi main.sh

rm -f /etc/nginx/conf.d/default.conf

#定义要修改的变量名称
cat >> /tmp/env <<EOF
DJANGO_HOST
DJANGO_PORT
EOF


#拷贝模板文件
cd /etc/nginx/conf.d/
cp default.conf.template default.conf


#读取环境变量中的值并修改模板文件
while IFS= read -r var
do
  # 从环境变量中获取对应变量的值
  value=$(eval echo \$$var)
  # 替换模板文件中的变量
  sed -i "s|\${${var}}|${value}|g" default.conf
done < /tmp/env


#启动服务
nginx -g 'daemon off;'

我们上面在容器主进程启动之前,将我们要修改的值读取环境变量并替换掉,关于那个定义要修改的变量,我们可以用其他的方法,不一定非要在这里定个文件还不好修改,我们可以做个configmap 挂到某个目录 声明ENV_开头的变量都是要修改的变量,方便读取

vi Dockerfile

#使用官方node镜像作为基础镜像
FROM node:14 as build-stage

#拷贝项目目录到镜像
COPY ./my-vue-app1 /home/my-vue-app1

#设置工作目录
WORKDIR /home/my-vue-app1

#添加加速源并安装依赖
RUN npm config set registry http://registry.npm.taobao.org/

#这块的3个RUN可以试着合并为一个RUN执行,我这边是跑的时候死活不能用
#\ + && 一直报错就这样用了,另一台主机可以。 就很烦
RUN npm install

RUN npm run  build




# 使用 Nginx 镜像作为最终镜像
FROM nginx:1.21

# 将构建阶段生成的 dist 目录复制到 Nginx 的默认静态文件目录
COPY --from=build-stage /home/my-vue-app1/dist /usr/share/nginx/html

# 暴露 80 端口
EXPOSE 80

# 拷贝配置文件
COPY ./default.conf /etc/nginx/conf.d/default.conf.template

COPY ./main.sh  /usr/local/bin/main.sh

RUN  chmod +x /usr/local/bin/main.sh




# 容器启动时运行 Nginx
CMD ["/usr/local/bin/main.sh"]

这里将我们修改的nginx配置文件和启动脚本都放进去,开始打镜像

重新构建镜像

docker build . -f Dockerfile  -t web-vue:v2

django直接使用vue,django,python,后端,vue,前端,k8s,docker

 7、修改web 控制器

vi web.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: web-vue:v2   #修改新镜像
        imagePullPolicy: IfNotPresent

        env:                #新增app的svc作为反向代理地址
        - name: DJANGO_HOST
          value: "app-service"
        - name: DJANGO_PORT
          value: "8000"
        ports:
        - containerPort: 80
          protocol: TCP

部署

kubectl apply -f web.yaml

django直接使用vue,django,python,后端,vue,前端,k8s,docker

可以看到,前端程序已经通过nginx反向代理到后端的svc进行访问了

六、服务注册ETCD + HA 对外提供访问

我们前面部署的前端程序中,使用了一个nodeport的svc负载均衡,他会在集群上暴露一个指定的端口,你访问集群内任意一台主机都会转交给提供服务的pod,但是有一个弊端,每个这样的svc都相当于是占用了所有主机的一个端口,默认情况下端口范围是30000-32767,虽然可以调整,但是在多租户初次使用时,总是无法合理规划端口使用范围,经常出现争抢问题,为了降低端口占用,我们让容器部署成功后注册到etcd上,通过confd动态识别并修改HA上的代理地址,就不需要考虑宿主机端口的问题,后续要扩容也是走HA了文章来源地址https://www.toymoban.com/news/detail-834076.html

#参考文档
https://blog.csdn.net/liukuan73/article/details/53427070

七、服务日志采集上送

到了这里,关于番外篇 萌新版开发交付一条龙(☆▽☆)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python打包和反编译一条龙

    安装Pyinstaller 在文件所在的位置启动cmd,命令如下 其中 -F 参数代表制作独立的可执行程序。 w 是指程序启动的时候不会打开命令行。如果不加-w的参数,就会有黑洞洞的控制台窗口出来。比如在刚才的脚本里我加一行 print(\\\'Hello World!\\\') ,那么就不要放-w参数了,不然运行会报

    2024年02月19日
    浏览(32)
  • JDK17、IDEA 2022【安装一条龙】

    本次安装 安装环境为:Windows11系统 jdk版本为:jdk-17.0.5 IDEA 版本为:ideaIU-2022.1.2 下载地址: 👉下载点我 双击下载的好的 .exe 文件 新建系统变量 配置Path 😇可直接复制 3. 🧪测试环境变量是否配置成功 🎊恭喜你,JDK 17安装成功了 下载地址: 👉下载点我 官网下载,选择适合

    2024年02月03日
    浏览(37)
  • 单相PWM整流从硬件到软件一条龙

    首先很想吐槽国内开源环境,实在是无语,大家都不愿意分享资源,都需要花钱,主要是花钱也不一定能找到你想要的东西。今年的电赛电源题,到现在了,我都还没看到CSDN上有能让我看懂的东西。所以我和同伴一起从零开始学习PWM整流,直到实现,我打算免费共享出来,能

    2024年02月16日
    浏览(30)
  • 传奇开服一条龙GEE引擎登录器配置教程

    1、首先我们打开我们版本文件夹找到登录器文件夹进入找到GEE登录器配置器(MakeGameLogin.exe)打开 2、接下来开始填写我们的主列表和备列表,这时候我们要自己创建一个列表,因为登录器自带的列表肯定是读取不了的,我们在网站文件夹新建一个txt文本名称可以随意填写如

    2024年02月08日
    浏览(35)
  • Nginx 可视化神器!复杂配置一键生成,监控管理一条龙!

    nginxWebUI是一款图形化管理nginx配置的工具,可以使用网页来快速配置nginx的各项功能,包括http协议转发、tcp协议转发、反向代理、负载均衡、静态html服务器、ssl证书自动申请、续签、配置等。配置好后可一建生成nginx.conf文件,同时可控制nginx使用此文件进行启动与重载,完成

    2024年02月07日
    浏览(33)
  • Debian11下编译ADAravis和Motor模块的一条龙过程

    一年前整理的上面文,这几天重新走了一遍,有些地方会碰到问题,需要补充些环节,motor模块以前和areaDetector一条龙编译时,总是有问题,当时就没尝试了,这几天尝试了一下,流程再总结如下: 准备: Debian11的基础安装(我用的是网络安装的虚拟机,选安装包时选ssh服务

    2024年01月22日
    浏览(28)
  • centos7下载安装jenkins并配置拉取maven项目一条龙

    首先需要安装JAVA环境:https://www.cnblogs.com/mufeng07/p/12150820.html 如果你的系统没有自带git,那么也需要安装一个 yum install git maven也需要安装,安装命令如下 maven安装完成后,需要配置maven 第一种方法 第二种方法 直接下载 rpm 安装,各个版本地址 https://pkg.jenkins.io/ 其中安装jenk

    2024年02月07日
    浏览(39)
  • OpenCV.js 入门教程指北:下载/安装/编译/代码实现/运行 一条龙

    学习计算机视觉接触到的第一个库,非常有意思的是,竟然有JS的版本 这是官方文档:https://docs.opencv.org/3.3.1/d5/d10/tutorial_js_root.html 为了节省大家的时间,我这里对官方的介绍简单摘要一些: OpenCV supports a wide variety of programming languages such as C++, Python, and Java, and is available on d

    2024年04月28日
    浏览(27)
  • Prometheus Operator 极简配置方式在k8s一条龙安装Prometheus 监控

    在k8s上 Prometheus(普罗米修斯) 监控,需要部署各种组件,比如Prometheus、Alertmanager、Grafana。同时各个组件的配置文件也是需要到处各个配置,Prometheus配置监控服务时,你还要知道各个监控服务的地址,地址换了还需要更新, 实在是麻烦。而今天的主角 Prometheus Operator 使用自

    2024年02月02日
    浏览(36)
  • C++ 之 【类与对象】从入门到精通一条龙服务 最终篇(static成员、友元、匿名对象。。。)

    💴到用时方恨早,白首方悔挣的少 车到山前没有路,悬崖勒马勒不住 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀– 在创建对象时,编译器通过调用构造函数,给对象中各个

    2024年04月16日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包