diff --git a/.ci/python/Dockerfile b/.ci/python/Dockerfile index ed1b4b0b..8431c842 100644 --- a/.ci/python/Dockerfile +++ b/.ci/python/Dockerfile @@ -42,7 +42,7 @@ RUN tar -pxzvf python.tar.gz >/dev/null 2>&1 \ EXPOSE $EXPOSE_PORT # 根据主文件默认名称 app.py CMD中的"$MY_VAR"变量设置成 docker run -e MY_VAR=value 运行变量 否则无法获取 -CMD ["python", "main.py"] +CMD ["python", "$PYTHON_START_FILE"] # Flask部署 启动命令 #CMD [ "python", "-m" , "flask", "run", "--host=0.0.0.0"] diff --git a/.ci/python/docker-release-python.sh b/.ci/python/docker-release-python.sh index 531e7a47..347161b3 100644 --- a/.ci/python/docker-release-python.sh +++ b/.ci/python/docker-release-python.sh @@ -199,7 +199,7 @@ echo "👨‍💻 启动运行Docker容器 环境: ${env_mode} 映射端口: ${h docker run -d --restart=always -p ${host_port}:${expose_port} \ -e "PROJECT_NAME=${project_name}" \ -m ${docker_memory} --log-opt ${docker_log_opts} --log-opt max-file=1 ${dynamic_run_args} \ - -e "REMOTE_DEBUGGING_PARAM=${remote_debugging_param}" \ + -e "REMOTE_DEBUGGING_PARAM=${remote_debugging_param}" -e "PYTHON_START_FILE=${python_start_file}" \ -v /${deploy_folder}/${project_name}/logs:/logs \ --name ${docker_container_name} ${docker_image_name} diff --git a/_k8s/ingress.yaml b/_k8s/ingress.yaml index c4e2ca20..66009440 100644 --- a/_k8s/ingress.yaml +++ b/_k8s/ingress.yaml @@ -11,40 +11,61 @@ metadata: cert-manager.io/cluster-issuer: letsencrypt-prod acme.cert-manager.io/http01-edit-in-place: "true" - # 开启金丝雀Canary。 + # 开启金丝雀Canary nginx.ingress.kubernetes.io/canary: "true" - # Http Header请求头为version。 + # Http Header请求头为version nginx.ingress.kubernetes.io/canary-by-header: "version" - # 请求头version=v2.0.0时,请求才会被路由到新版本服务中。 + # 请求头version=v2.0.0时,请求才会被路由到新版本服务中 nginx.ingress.kubernetes.io/canary-by-header-value: "v2.0.0" #nginx.ingress.kubernetes.io/canary-by-header-pattern: "" #nginx.ingress.kubernetes.io/canary-by-cookie: "" - # 在满足上述匹配规则的基础上仅允许百分比的流量会被路由到新版本服务中。 + # 在满足上述匹配规则的基础上仅允许百分比的流量会被路由到新版本服务中 nginx.ingress.kubernetes.io/canary-weight: "100" - # 开启跨域 + # 开启CORS跨域 nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/cors-allow-origin: "*" nginx.ingress.kubernetes.io/cors-max-age: "64800" nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS" nginx.ingress.kubernetes.io/cors-allow-credentials: "true" + # 数据请求超时时间 nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + # 负载均衡算法 如ip_hash nginx.ingress.kubernetes.io/upstream-hash-by: "$host" # Session保持配置 nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/affinity-mode: "persistent" nginx.ingress.kubernetes.io/session-cookie-name: "route" - # 后端大文件上传大小 + + # 后端大文件上传大小 数据传输大小 nginx.ingress.kubernetes.io/client-body-buffer-size: 1024m nginx.ingress.kubernetes.io/proxy-max-temp-file-size: 2048m - # 数据传输大小 nginx.ingress.kubernetes.io/proxy-body-size: 1024m + # 配置是否同时支持http和https访问应用 nginx.ingress.kubernetes.io/ssl-redirect: "false" + # 采用了 “漏斗” 算法实现限流 保证服务可用性和被攻击 nginx的限流是一个队列模型。限流连接数为 队列长度+队列处理能力 + # 每个IP每秒可以访问的次数 默认乘数为5 + nginx.ingress.kubernetes.io/limit-rps: "50" + # 为计算限速漏桶算法的 burst size和 limit-rps 的相乘放大系数 burst为队列长度 + nginx.ingress.kubernetes.io/limit-burst-multiplier: "10" + # 配合 limit-window 表示每多少秒全局限速多少次(需要依赖 memcached) + nginx.ingress.kubernetes.io/global-rate-limit: "100000" + nginx.ingress.kubernetes.io/global-rate-limit-window: 1s + # 限制发送给后端服务的发送速率为 多少MB/每秒 rate为队列处理能力 + #nginx.ingress.kubernetes.io/limit-rate: 10240 + # 发送给后端服务的前 多少MB 数据不进行限速 + #nginx.ingress.kubernetes.io/limit-rate-after: 102400 + # 白名单 客户端IP源范围要从速率限制中排除。该值是逗号分隔的CIDR列表 + #nginx.ingress.kubernetes.io/limit-whitelist: + # 限流超出后的响应码 + nginx.ingress.kubernetes.io/configuration-snippet: | + limit_req_status 429; + spec: ingressClassName: k8s-ingress tls: # TLS安全 diff --git a/_k8s/k8s_yaml.py b/_k8s/k8s_yaml.py index 02fd76a0..78694755 100644 --- a/_k8s/k8s_yaml.py +++ b/_k8s/k8s_yaml.py @@ -27,6 +27,8 @@ parser.add_argument('--remote_debug_port', type=int, default=None) parser.add_argument('--is_use_session', type=bool, default=False) parser.add_argument('--set_yaml_arags', type=str, default=None) +parser.add_argument('--set_python_start_file', type=str, default=None) +parser.add_argument('--is_k8s_health_probe', type=bool, default=False) args = parser.parse_args() @@ -106,15 +108,23 @@ [*nsf_server_yaml] ) -# 动态设置k8s yaml args参数 +# Java动态设置k8s yaml args参数 set_yaml_arags = args.set_yaml_arags if set_yaml_arags is not None: print(set_yaml_arags) # 适配Java Spring Boot框架容器动态启动命令 - yaml_containers[0]["command"] = ["java"] # 覆盖或补充 ENTRYPOINT + yaml_containers[0]["command"] = ["java"] # 覆盖或补充 ENTRYPOINT 或 CMD yaml_containers[0]["args"] = ["-jar", "-Xms128m", set_yaml_arags, "-Djava.security.egd=file:/dev/./urandom", "/server.jar"] +# 设置python语言相关的参数 +set_python_start_file = args.set_python_start_file +if set_python_start_file is not None: + print(set_python_start_file) + # 启动命令 + yaml_containers[0]["command"] = ["python"] # 覆盖或补充 ENTRYPOINT 或 CMD + yaml_containers[0]["args"] = [set_python_start_file] + # 业务应用是否使用Session处理 if is_use_session: service_spec = yamlContent[1]['spec'] @@ -127,6 +137,12 @@ print(default_port) yaml_containers[0]['ports'].append({'containerPort': default_port}) +# 是否禁止执行K8S默认的健康探测 +is_k8s_health_probe = args.is_k8s_health_probe +if is_k8s_health_probe: + del yaml_containers[0]["readinessProbe"] + del yaml_containers[0]["livenessProbe"] + # print(yamlContent) with open(k8s_yaml_file, mode='w', encoding='utf-8') as file: diff --git a/_k8s/letsencrypt/backup/cert-manager-ingress-lanneng-open-park-third-party.yaml b/_k8s/letsencrypt/backup/cert-manager-ingress-lanneng-open-park-third-party.yaml new file mode 100644 index 00000000..6867399f --- /dev/null +++ b/_k8s/letsencrypt/backup/cert-manager-ingress-lanneng-open-park-third-party.yaml @@ -0,0 +1,90 @@ +# Author: 潘维吉 +# Description: 云原生K8S中使用cert-manager基于 ACME 协议与 Let's Encrypt 自动签发与续签免费的SSL证书 + +# 创建一个集群级的签发机构 仅需一次 +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod-lanneng-open-park-third-party + namespace: cert-manager +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory # ACME 协议的服务端 acme-staging-v02测试证书没有限制 + email: 406798106@qq.com # 证书快过期的时候会有邮件提醒 + privateKeySecretRef: + name: letsencrypt-prod-key-lanneng-open-park-third-party # 私钥秘密必须与cert-manager服务在同一个命名空间中才能工作 kubectl delete Secret letsencrypt-prod-key --namespace cert-manager + solvers: + - http01: # 签发机构使用 HTTP-01 的方式进行 acme 协议 (还可用 DNS 方式,acme 协议的目的是证明机器和域名都是属于你的,然后才准许颁发证书) + ingress: + #serviceType: ClusterIP + name: lannengtech-k8s-ingress-lanneng-open-park-third-party # 这个匹配是关键!!! 1. class是指定自动创建的 Ingress 的 ingress class 2. name是指定被自动修改的 Ingress 名称 + +--- + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: lannengtech-k8s-ingress-lanneng-open-park-third-party + namespace: default + annotations: + # 指定使用nginx做代理 + #kubernetes.io/ingress.class: lanneng-park # 已弃用 使用 spec.ingressClassName代替 + # add an annotation indicating the issuer to use + cert-manager.io/cluster-issuer: letsencrypt-prod-lanneng-open-park-third-party + acme.cert-manager.io/http01-edit-in-place: "true" + + # 后端大文件上传大小 + nginx.ingress.kubernetes.io/client-body-buffer-size: 1024m + nginx.ingress.kubernetes.io/proxy-max-temp-file-size: 2048m + # 数据传输大小 + nginx.ingress.kubernetes.io/proxy-body-size: 1024m + + # 开启CORS跨域请求 + nginx.ingress.kubernetes.io/enable-cors: "true" + nginx.ingress.kubernetes.io/cors-allow-origin: "*" + nginx.ingress.kubernetes.io/cors-max-age: "64800" + nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS" + nginx.ingress.kubernetes.io/cors-allow-credentials: "true" + + # 配置是否同时支持http和https访问应用 + nginx.ingress.kubernetes.io/ssl-redirect: "false" + + # 采用了 “漏斗” 算法实现限流 保证服务可用性和被攻击 nginx的限流是一个队列模型。限流连接数为 队列长度+队列处理能力 + # 每个IP每秒可以访问的次数 默认乘数为5 + nginx.ingress.kubernetes.io/limit-rps: "50" + # 为计算限速漏桶算法的 burst size和 limit-rps 的相乘放大系数 burst为队列长度 + nginx.ingress.kubernetes.io/limit-burst-multiplier: "10" + # 配合 limit-window 表示每多少秒全局限速多少次(需要依赖 memcached) + nginx.ingress.kubernetes.io/global-rate-limit: "100000" + nginx.ingress.kubernetes.io/global-rate-limit-window: 1s + # 限制发送给后端服务的发送速率为 多少MB/每秒 rate为队列处理能力 + #nginx.ingress.kubernetes.io/limit-rate: 10240 + # 发送给后端服务的前 多少MB 数据不进行限速 + #nginx.ingress.kubernetes.io/limit-rate-after: 102400 + # 白名单 客户端IP源范围要从速率限制中排除。该值是逗号分隔的CIDR列表 + #nginx.ingress.kubernetes.io/limit-whitelist: + # 限流超出后的响应码 + nginx.ingress.kubernetes.io/configuration-snippet: | + limit_req_status 429; + +spec: + ingressClassName: lanneng-park + tls: + - hosts: + - park-foreign-api.pengbocloud.com + secretName: park-foreign-api.pengbocloud.com-tls + + rules: + #自定义域名 + - host: park-foreign-api.pengbocloud.com + http: + paths: + - path: / + backend: + #服务名称 + service: + name: park-saas-foreign-python-service + #服务端口 + port: + number: 8201 + pathType: Prefix \ No newline at end of file diff --git a/_k8s/letsencrypt/cert-manager-ingress.yaml b/_k8s/letsencrypt/cert-manager-ingress.yaml index 98933b13..b3f79341 100644 --- a/_k8s/letsencrypt/cert-manager-ingress.yaml +++ b/_k8s/letsencrypt/cert-manager-ingress.yaml @@ -50,25 +50,29 @@ metadata: # add an annotation indicating the issuer to use cert-manager.io/cluster-issuer: letsencrypt-prod acme.cert-manager.io/http01-edit-in-place: "true" + # 负载均衡算法 如ip_hash nginx.ingress.kubernetes.io/upstream-hash-by: "$host" # Session保持配置 nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/affinity-mode: "persistent" nginx.ingress.kubernetes.io/session-cookie-name: "route" - # 后端大文件上传大小 + + # 后端大文件上传大小 数据传输大小 nginx.ingress.kubernetes.io/client-body-buffer-size: 1024m nginx.ingress.kubernetes.io/proxy-max-temp-file-size: 2048m - # 数据传输大小 nginx.ingress.kubernetes.io/proxy-body-size: 1024m + # 开启CORS跨域请求 nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/cors-allow-origin: "*" nginx.ingress.kubernetes.io/cors-max-age: "64800" nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS" nginx.ingress.kubernetes.io/cors-allow-credentials: "true" + # 配置是否同时支持http和https访问应用 nginx.ingress.kubernetes.io/ssl-redirect: "false" + # 采用了 “漏斗” 算法实现限流 保证服务可用性和被攻击 nginx的限流是一个队列模型。限流连接数为 队列长度+队列处理能力 # 每个IP每秒可以访问的次数 默认乘数为5 nginx.ingress.kubernetes.io/limit-rps: "50" diff --git a/_nginx/tcpserver.conf b/_nginx/tcpserver.conf index 03206d24..134bd284 100644 --- a/_nginx/tcpserver.conf +++ b/_nginx/tcpserver.conf @@ -10,8 +10,7 @@ upstream mysql-server { server 172.16.0.10:4000 weight=1; - server 172.16.0.11:4000 weight=1; - server 172.16.0.12:4000 down; + server 172.16.0.11:4000 down; } upstream redis-server { diff --git a/pipelines/demo/Jenkinsfile.panweiji-prod b/pipelines/demo/Jenkinsfile.panweiji-prod index da4fa6c4..30ccdb67 100644 --- a/pipelines/demo/Jenkinsfile.panweiji-prod +++ b/pipelines/demo/Jenkinsfile.panweiji-prod @@ -56,7 +56,7 @@ map.put('k8s_credentials_ids', ' ') map.put('k8s_image_pull_secrets', ' ') // 项目标签或项目简称 -map.put('project_tag', '房产销售') +map.put('project_tag', '潘维吉') // 是否是生产环境 map.put('is_prod', true) diff --git a/pipelines/epark/Jenkinsfile.lanneng-car-wash-prod b/pipelines/epark/Jenkinsfile.lanneng-car-wash-prod index 206d3e2b..ee78f4aa 100644 --- a/pipelines/epark/Jenkinsfile.lanneng-car-wash-prod +++ b/pipelines/epark/Jenkinsfile.lanneng-car-wash-prod @@ -73,7 +73,7 @@ map.put('is_before_deploy_notice', false) // 是否通知变更记录 map.put('is_notice_change_log', true) // 是否在生产环境发布成功后自动给Git仓库打Tag版本和生成变更记录 -map.put('is_git_tag', false) +map.put('is_git_tag', true) // 是否需要css预处理器sass map.put('is_need_sass', false) diff --git a/pipelines/epark/Jenkinsfile.lanneng-landing-page-prod b/pipelines/epark/Jenkinsfile.lanneng-landing-page-prod index a7d4b034..f8e29d92 100644 --- a/pipelines/epark/Jenkinsfile.lanneng-landing-page-prod +++ b/pipelines/epark/Jenkinsfile.lanneng-landing-page-prod @@ -78,8 +78,8 @@ map.put('is_git_tag', true) map.put('is_need_sass', false) // jenkins分布式构建节点label名称 预配置在jenkins节点管理内 -map.put('jenkins_node', 'master') -map.put('jenkins_node_front_end', 'master') +map.put('jenkins_node', 'node-2') +map.put('jenkins_node_front_end', 'node-2') // 构建环境变量 分别使用Node和Maven关键字加版本号方式 如Maven3.6 map.put('nodejs', 'Node14') diff --git a/pipelines/epark/Jenkinsfile.lanneng-open-park-third-party-prod b/pipelines/epark/Jenkinsfile.lanneng-open-park-third-party-prod new file mode 100644 index 00000000..18715aee --- /dev/null +++ b/pipelines/epark/Jenkinsfile.lanneng-open-park-third-party-prod @@ -0,0 +1,140 @@ +#!groovy +@Library('jenkins-shared-library@dev') _ + +/** + * @author 潘维吉 + * @description 核心Pipeline代码 针对Python语言项目CI/CD的脚本 + * 注意 本文件在Git位置和名称不能随便改动 配置在jenkins里 + */ + +// 根据不同环境项目配置不同参数 +def map = [:] + +// 远程服务器地址 k8s集群方式可填空或填公网代理负载IP +map.put('remote_ip', '120.92.149.246') +// 工作服务器地址 同时支持N个服务器自动化分布式部署 +map.put('remote_worker_ips', []) +// 远程服务器用户名 +map.put('remote_user_name', 'root') +// 代理机或跳板机外网ip用于透传部署到内网目标机器 选填 目标机器外部无法直接访问情况填写内网ip +map.put('proxy_jump_ip', ' ') +// 自定义跳板机ssh和scp访问用户名 可精细控制权限 默认root +map.put('proxy_jump_user_name', 'root') +// 自定义跳板机ssh和scp访问端口 默认22 +map.put('proxy_jump_port', ' ') + +// 默认统一设置项目级别的分支 方便整体控制改变分支 将覆盖单独job内的设置 +map.put('default_git_branch', ' ') + +// 保持构建的最大个数 +map.put('build_num_keep', 2) + +// Docker相关参数 +// JVM内存设置 +map.put('docker_java_opts', '-Xmx2000m') +// docker内存限制 不支持小数点形式设置 +map.put('docker_memory', '2G') +// docker日志限制 +map.put('docker_log_opts', 'max-size=150m') // --log-opt max-size=50m --log-opt max-file=3 +// docker挂载映射 docker run -v 参数(格式 宿主机挂载路径:容器内目标路径) 多个用逗号,分割 +map.put('docker_volume_mount', '') +// Dockerfile多阶段构建 镜像名称 +map.put('docker_multistage_build_images', ' ') +// 是否上传镜像到docker容器仓库 +map.put('is_push_docker_repo', true) +// docker容器镜像仓库账号信任id +map.put('docker_repo_credentials_id', '73f6b3b0-4580-4acf-b04a-63892fcf9ba8') +// docker镜像仓库注册地址 +map.put('docker_repo_registry', 'hub-cn-shanghai-2.kce.ksyun.com') +// docker仓库命名空间名称 +map.put('docker_repo_namespace', 'lanneng') + +// K8S集群相关参数 +// K8S集群访问授权账号kube.config配置信息信任ids 多集群,逗号分割 Jenkins系统管理的Manage Credentials,类型选择为“Secret file”配置 +map.put('k8s_credentials_ids', 'a1d2642d-296f-47a2-8d1a-087b46e3255e') +// K8S集群私有镜像仓库拉取密钥 在集群内使用kubectl create secret命令生成 +map.put('k8s_image_pull_secrets', 'lannengkeji2022') + +// 项目标签或项目简称 +map.put('project_tag', '停车开放平台') + +// 是否是生产环境 +map.put('is_prod', true) +// 是否在同一台服务器蓝绿部署或滚动部署 非k8s集群方式设置 +map.put('is_same_server', false) +// 是否进行优雅停机 +map.put('is_grace_shutdown', false) +// 是否进行服务启动健康探测 K8S集群类型设置false +map.put('is_health_check', false) +// 是否Pipeline内脚本钉钉通知 总开关 +map.put('is_ding_notice', true) +// 是否进行部署前通知 +map.put('is_before_deploy_notice', false) +// 是否通知变更记录 +map.put('is_notice_change_log', true) +// 是否在生产环境发布成功后自动给Git仓库打Tag版本和生成变更记录 +map.put('is_git_tag', true) +// 是否需要css预处理器sass +map.put('is_need_sass', false) + +// jenkins分布式构建节点label名称 预配置在jenkins节点管理内 +map.put('jenkins_node', 'master') +map.put('jenkins_node_front_end', 'master') + +// 构建环境变量 分别使用Node和Maven关键字加版本号方式 如Maven3.6 +map.put('nodejs', 'Node18') +map.put('maven', 'Maven3.6') +map.put('jdk', '11') + +// 相关信任标识 +map.put('ci_git_credentials_id', '5379273a-f829-4091-ab19-46c184fcbeb2') +map.put('git_credentials_id', '5379273a-f829-4091-ab19-46c184fcbeb2') +map.put('ding_talk_credentials_id', 'd33ae0ba-e531-41c8-8983-d9734e53a25a') +// OSS对象存储访问凭据配置 Jenkins系统管理的Manage Credentials,类型选择为“Secret file”配置 +map.put('oss_credentials_id', ' ') +// 直连方式服务器集群自动SSH连接信息 实现CI构建机器和多台部署机之间的免密连接 +map.put('ssh_hosts_id', ' ') +// 跳板机方式服务器集群自动SSH连接信息 实现CI构建机器和多台部署机之间的免密连接 +map.put('proxy_jump_hosts_id', ' ') + +// 服务器上部署所在的文件夹名称 +map.put('deploy_folder', "my") +// Web项目NPM打包代码所在的文件夹名称 +map.put('npm_package_folder', "dist") +// Web项目解压到指定目录层级 +map.put('web_strip_components', 1) +// 如果Maven模块化存在二级模块目录 设置一级模块目录名称 +map.put('maven_one_level', ' ') +// Maven自定义指定settings.xml文件 如设置私有库或镜像源情况 +map.put('maven_setting_xml', ' ') + +// 调用核心通用Pipeline +sharedLibrary(map) + + +// --------------------------------------------------------------------------------------------------------------------- +// https://git.pengbocloud.com/lanneng_develop/jenkins-shared-library.git pipelines/epark/Jenkinsfile.lanneng-open-park-third-party-prod + +/* + +park-saas-foreign-k8s-prod +停车开放服务-k8s集群 +JSON_PARAMS +{ + "REPO_URL" : "https://git.pengbocloud.com/lanneng_develop/park_saas_foreign_python.git" , + "BRANCH_NAME" : "master" , + "PROJECT_TYPE" : "2" , + "COMPUTER_LANGUAGE" : "3" , + "PROJECT_NAME" : "park-saas-foreign" , + "SHELL_PARAMS" : "park-saas-foreign python 8201 5000 prod", + "IS_K8S_DEPLOY" : true, + "K8S_POD_REPLICAS" : "1", + "CUSTOM_PYTHON_VERSION" : "3.10.0", + "CUSTOM_PYTHON_START_FILE" : "app.py", + "CUSTOM_HEALTH_CHECK_PATH" : "/healthy-check", + "APPLICATION_DOMAIN" : "https://park-foreign-api.pengbocloud.com" +} + +*/ + + diff --git a/src/shared/library/common/Kubernetes.groovy b/src/shared/library/common/Kubernetes.groovy index 545fa33b..d9c2db25 100644 --- a/src/shared/library/common/Kubernetes.groovy +++ b/src/shared/library/common/Kubernetes.groovy @@ -151,6 +151,9 @@ class Kubernetes implements Serializable { def yamlVolumeMounts = "" def yamlNfsParams = "" def setYamlArags = "" + def setPythonParams = "" + def isK8sHealthProbe = "" + // 复杂参数动态组合配置yaml文件 if ("${ctx.IS_USE_SESSION}" == "true") { // k8s集群业务应用是否使用Session 做亲和度关联 isYamlUseSession = " --is_use_session=true " @@ -161,12 +164,20 @@ class Kubernetes implements Serializable { if ("${ctx.NFS_MOUNT_PATHS}".trim() != "") { // NFS服务 yamlNfsParams = " --nfs_server=${ctx.NFS_SERVER} --nfs_params=${ctx.NFS_MOUNT_PATHS} " } - // 动态设置k8s yaml args参数 + // java动态设置k8s yaml args参数 if ("${ctx.PROJECT_TYPE}".toInteger() == GlobalVars.backEnd && "${ctx.COMPUTER_LANGUAGE}".toInteger() == GlobalVars.Java && "${ctx.JAVA_FRAMEWORK_TYPE}".toInteger() == GlobalVars.SpringBoot) { setYamlArags = " --set_yaml_arags='${map.docker_java_opts}' " } + // 设置python语言相关的参数 + if ("${ctx.PROJECT_TYPE}".toInteger() == GlobalVars.backEnd && "${ctx.COMPUTER_LANGUAGE}".toInteger() == GlobalVars.Python) { + setPythonParams = " --set_python_start_file=${ctx.CUSTOM_PYTHON_START_FILE} " + } + // 是否禁止执行K8S默认的健康探测 + if (false) { + isK8sHealthProbe = " --is_k8s_health_probe=true " + } - pythonYamlParams = isYamlUseSession + yamlVolumeMounts + yamlNfsParams + yamlDefaultPort + setYamlArags + pythonYamlParams = isYamlUseSession + yamlVolumeMounts + yamlNfsParams + yamlDefaultPort + setYamlArags + setPythonParams + isK8sHealthProbe if ("${pythonYamlParams}".trim() != "") { ctx.dir("${ctx.env.WORKSPACE}/ci/_k8s") { ctx.println("使用Python的ruamel包动态配置K8S的Yaml文件: " + pythonYamlParams) @@ -257,6 +268,7 @@ class Kubernetes implements Serializable { * K8S验证部署是否成功 */ static def verifyDeployment(ctx) { + // 前提开启 readinessProbe和livenessProbe 健康探测 ctx.println("K8S集群所有Pod节点健康探测中, 请耐心等待... 🚀") def deploymentName = "${ctx.FULL_PROJECT_NAME}" // labels.app标签值 def namespace = k8sNameSpace diff --git a/src/shared/library/common/Web.groovy b/src/shared/library/common/Web.groovy index a384836b..e8501703 100644 --- a/src/shared/library/common/Web.groovy +++ b/src/shared/library/common/Web.groovy @@ -63,7 +63,7 @@ class Web implements Serializable { ctx.retry(3) { retryCount++ if (retryCount >= 2) { - ctx.sh "rm -rf node_modules && rm -f *.lock.* && npm run clean:all" + ctx.sh "rm -rf node_modules && rm -f *lock* && npm run clean:all" } // 全部下载依赖 更通用 bootstrap不仅是下载依赖资源 还建立多包之间的依赖软链 // TurboRepo解决Monorepo多项目构建缓慢问题 充分利用CPU性能并发构建提速 同时新版Lerna v5.1集成Nx实现加速构建 @@ -83,7 +83,7 @@ class Web implements Serializable { } catch (error) { ctx.println(error.getMessage()) ctx.sh "rm -rf node_modules" // 清除构建缓存 - ctx.sh "rm -rf *.lock.*" // 清除构建锁版本文件 + ctx.sh "rm -rf *lock*" // 清除构建锁版本文件 ctx.sh "npm run clean:all" // 清除构建所有缓存 ctx.error("执行MonoRepo仓库构建失败, 终止当前Pipeline运行 ❌") } diff --git a/vars/sharedLibrary.groovy b/vars/sharedLibrary.groovy index 44ccab59..846857b0 100644 --- a/vars/sharedLibrary.groovy +++ b/vars/sharedLibrary.groovy @@ -1159,17 +1159,15 @@ def nodeBuildProject() { retry(3) { retryCount++ if (retryCount >= 2) { - sh "rm -rf node_modules && rm -f *.lock.*" + sh "rm -rf node_modules && rm -f *lock*" // 如果包404下载失败 可以更换官方镜像源重新下载 - Node.setOfficialMirror(this) + // Node.setOfficialMirror(this) } if (Git.isExistsChangeFile(this) || retryCount >= 2) { // 自动判断是否需要下载依赖 根据依赖配置文件在Git代码是否变化 println("安装依赖 📥") // npm ci 与 npm install类似 进行CI/CD或生产发布时,最好使用npm ci 防止版本号错乱但依赖lock文件 - def npmLog = "npm_install.log" - sh " npm ci || pnpm install > ${npmLog} 2>&1 || npm install >> ${npmLog} 2>&1 || yarn install >> ${npmLog} 2>&1 " + sh " npm ci || pnpm install || npm install || yarn install " // --prefer-offline &> /dev/null 加速安装速度 优先离线获取包不打印日志 但有兼容性问题 - sh " cat ${npmLog} || true" } println("执行Node构建 🏗️ ") @@ -1178,7 +1176,7 @@ def nodeBuildProject() { } } catch (e) { println(e.getMessage()) - sh "rm -rf node_modules && rm -f *.lock.*" + sh "rm -rf node_modules && rm -f *lock*" error("Web打包失败, 终止当前Pipeline运行 ❌") } } diff --git a/vars/webSharedLibrary.groovy b/vars/webSharedLibrary.groovy index f95366e4..1e2ff270 100644 --- a/vars/webSharedLibrary.groovy +++ b/vars/webSharedLibrary.groovy @@ -911,17 +911,15 @@ def nodeBuildProject() { retry(3) { retryCount++ if (retryCount >= 2) { - sh "rm -rf node_modules && rm -f *.lock.*" + sh "rm -rf node_modules && rm -f *lock*" // 如果包404下载失败 可以更换官方镜像源重新下载 - Node.setOfficialMirror(this) + // Node.setOfficialMirror(this) } if (Git.isExistsChangeFile(this) || retryCount >= 2) { // 自动判断是否需要下载依赖 根据依赖配置文件在Git代码是否变化 println("安装依赖 📥") // npm ci 与 npm install类似 进行CI/CD或生产发布时,最好使用npm ci 防止版本号错乱但依赖lock文件 - def npmLog = "npm_install.log" - sh " npm ci || pnpm install > ${npmLog} 2>&1 || npm install >> ${npmLog} 2>&1 || yarn install >> ${npmLog} 2>&1 " + sh " npm ci || pnpm install || npm install || yarn install " // --prefer-offline &> /dev/null 加速安装速度 优先离线获取包不打印日志 但有兼容性问题 - sh " cat ${npmLog} || true" } println("执行Node构建 🏗️ ") @@ -930,7 +928,7 @@ def nodeBuildProject() { } } catch (e) { println(e.getMessage()) - sh "rm -rf node_modules && rm -f *.lock.*" + sh "rm -rf node_modules && rm -f *lock*" error("Web打包失败, 终止当前Pipeline运行 ❌") } }