diff --git a/devops/Dockerfile b/devops/Dockerfile new file mode 100644 index 00000000..b12ac15c --- /dev/null +++ b/devops/Dockerfile @@ -0,0 +1,4 @@ +FROM nginx:1.18.0 +MAINTAINER xtaylkss@163.com +COPY ./devops/nginx.conf /etc/nginx/ +COPY ./dist/ /opt/nginx/html/web/ \ No newline at end of file diff --git a/devops/K8sJenkinsFile b/devops/K8sJenkinsFile new file mode 100644 index 00000000..048b889a --- /dev/null +++ b/devops/K8sJenkinsFile @@ -0,0 +1,111 @@ +pipeline { // 直接上k8s,用k8s来管理docker + agent { + node { + label "nodejs" + } + } + parameters { + choice( + description: "你需要选择哪条分支进行构建?", + name: "branch_name", + choices: ["master", "feat/youlai_k8s_deploy"] + ) + } + environment { + // 自建harbor仓库的namespace + docker_hub_namespace = "youlai" + // docker_hub_namespace = "youlaiwuhui" + + web_app_name = "youlai-web-vue3" + + // 自建镜像仓库地址 + docker_hub = "k8s-harbor:30002" + // docker_hub = "https://registry.cn-hangzhou.aliyuncs.com" + + // 在jenknis或kubesphere上面的凭证 + docker_hub_id = "youlai-zhangjialin-myself-harbor-account" + // docker_hub_id = "zhangjialin-aliyun-pingzheng" + + // k8s 上面的 namespace + k8s_namespace = "youlai-mall" + GIT_COMMIT_ID = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim() + // BUILD_NUMBER 这个变量从jenkins传递过来 + current_build_number = "${BUILD_NUMBER}" + // 在k8s上面配置的id + KUBECONFIG_CREDENTIAL_ID = "youlai-kubeconfig" + } + + + stages { + stage ("打印相关变量") { + steps{ + echo "docker_hub_namespace信息为: ${docker_hub_namespace}" + // 获取commit信息,用于后面打tag + echo "commit信息为:${env.GIT_COMMIT_ID}" + echo "current_build_number信息为:${env.current_build_number}" + script { + // 本端tag名 + env.local_tag = "frontend:${current_build_number}_${GIT_COMMIT_ID}" + // 远端tag名,必须以这种方式命令,才能push到远端 + env.remote_tag = "${docker_hub}/${docker_hub_namespace}/${local_tag}" + echo "local_tag信息为:${env.local_tag}" + echo "remote_tag信息为:${env.remote_tag}" + } + } + } + stage("checkout代码") { + steps { + //git branch: "${branch_name}", credentialsId: 'zhangjialin-youlai-mall-pingzheng', url: 'https://gitee.com/youlaitech/youlai-mall.git' + + //checkout([ + //$class: 'GitSCM', + //branches: [[name: "${branch_name}"]], + //extensions: [[$class: 'CloneOption', depth: 1, noTags: false, reference: '', shallow: true]], + //userRemoteConfigs: [[credentialsId: 'zhangjialin-youlai-mall-pingzheng', url: 'https://gitee.com/youlaitech/youlai-mall.git']]]) + sh "du -h --max-depth=1" + } + } + stage('构建') { + agent none + steps { + container('nodejs') { + script { + sh 'yarn config set registry https://registry.npm.taobao.org' + sh 'npm config set registry https://registry.npm.taobao.org' + sh 'ls -al $WORKSPACE/src/components/TreeSelect' + sh 'yarn install --force' + sh 'yarn build:prod' + } + } + } + } + + + stage('构建镜像') { + agent none + steps { + script { + container('nodejs') { + sh "pwd && ls -al" + sh "docker build -t ${env.local_tag} -f devops/Dockerfile ." + withCredentials([usernamePassword(credentialsId: "${docker_hub_id}", + passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME')]) { + sh 'echo "$DOCKER_PASSWORD" | docker login http://k8s-harbor:30002 -u "$DOCKER_USERNAME" --password-stdin' + sh "docker tag ${env.local_tag} ${env.remote_tag}" + sh "docker push ${env.remote_tag}" + } + } + } + } + } + stage("自动部署至k8s") { + agent none + steps { + container ("nodejs") { + // 这种方式启k8s是官方推荐的 + sh 'envsubst < devops/deploy.yaml | kubectl apply -f -' + } + } + } + } +} \ No newline at end of file diff --git a/devops/deploy.yaml b/devops/deploy.yaml new file mode 100644 index 00000000..5f263489 --- /dev/null +++ b/devops/deploy.yaml @@ -0,0 +1,65 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: ${web_app_name} + name: ${web_app_name}-deployment + namespace: ${k8s_namespace} #一定要写名称空间 +spec: + progressDeadlineSeconds: 600 + replicas: 1 + selector: + matchLabels: + app: ${web_app_name} + strategy: + rollingUpdate: + maxSurge: 50% + maxUnavailable: 50% + type: RollingUpdate + template: + metadata: + labels: + app: ${web_app_name} + spec: + containers: + - image: $remote_tag + # readinessProbe: + # httpGet: + # path: /actuator/health + # port: 8080 + # timeoutSeconds: 10 + # failureThreshold: 30 + # periodSeconds: 5 + imagePullPolicy: Always + name: ${web_app_name} + ports: + - containerPort: 80 + protocol: TCP + resources: + limits: + cpu: 1000m + memory: 512Mi + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + restartPolicy: Always + terminationGracePeriodSeconds: 30 +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: ${web_app_name} + name: ${web_app_name}-svc + namespace: ${k8s_namespace} +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 80 + nodePort: 32609 + selector: + app: ${web_app_name} + sessionAffinity: None + type: NodePort diff --git a/devops/nginx.conf b/devops/nginx.conf new file mode 100644 index 00000000..fb02044a --- /dev/null +++ b/devops/nginx.conf @@ -0,0 +1,47 @@ +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + #gzip on; + + server { + listen 80; + server_name localhost; #你的serverName + location / { + root /opt/nginx/html/web; + index index.html; + } + # 代理转发请求至网关,prod-api标识解决跨域问题 + location /prod-api/ { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + #proxy_pass http://ks.howlaisi.com:32006/; + proxy_pass http://youlai-gateway-svc.youlai-mall.svc.cluster.local:9999/; + } + # 重定向错误页面到 /50x.html + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } +} \ No newline at end of file