• k8s部署gin-vue-admin框架、gitlab-ci、jenkins pipeline 、CICD


    测试环境使用的jenkins
    正式环境使用的gitlab-ci

    测试环境

    1. 创建yaml文件
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: dtk-go-tiktok-admin-config
      labels:
        app.kubernetes.io/name: dtk-go-tiktok-admin
        app.kubernetes.io/business: infrastructure
        app.kubernetes.io/runtime: golang
        app.kubernetes.io/tier: backend
        app.kubernetes.io/environment: test
        app.kubernetes.io/managed-by: yong.xd
    data:
      config.yaml: |
              max-age: 0
              show-line: true
              log-in-console: true
    
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: dtk-vue-tiktok-admin-config
      labels:
        app.kubernetes.io/name: dtk-go-tiktok-admin
        app.kubernetes.io/business: infrastructure
        app.kubernetes.io/runtime: golang
        app.kubernetes.io/tier: front
        app.kubernetes.io/environment: test
        app.kubernetes.io/managed-by: yong.xd
    data:
      default.conf: |
        server{
          
            listen       80 default_server;
            server_name  _;
            access_log   /dev/stdout;
            error_log    /dev/stdout;
            root         /opt/app/dist/;
            location / {
                    try_files $uri $uri/ /index.html;
                }
            location /api {
              proxy_set_header Host $http_host;
              proxy_set_header  X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              rewrite ^/api/(.*)$ /$1 break;  #重写
              add_header 'dtk-debug' 'api';
        #一个deployment2个pod是网络资源是共享的,所以可以直接代理
              proxy_pass http://127.0.0.1:8888; # 设置代理服务器的协议和地址
              }
    
           location /api/swagger/index.html {
             proxy_pass http://127.0.0.1:8888/swagger/index.html;
             }
            location /health {
              access_log off;
              return 200;
            }
        }
        
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dtk-go-tiktok-admin
      labels:
        app.kubernetes.io/name: dtk-go-tiktok-admin
        app.kubernetes.io/business: infrastructure
        app.kubernetes.io/runtime: golang
        app.kubernetes.io/tier: backend
        app.kubernetes.io/environment: test
        app.kubernetes.io/managed-by: yong.xd
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: dtk-go-tiktok-admin
          app.kubernetes.io/business: infrastructure
          app.kubernetes.io/runtime: golang
          app.kubernetes.io/tier: backend
          app.kubernetes.io/environment: test
          app.kubernetes.io/managed-by: yong.xd
      template:
        metadata:
          labels:
            app.kubernetes.io/name: dtk-go-tiktok-admin
            app.kubernetes.io/business: infrastructure
            app.kubernetes.io/runtime: golang
            app.kubernetes.io/tier: backend
            app.kubernetes.io/environment: test
            app.kubernetes.io/managed-by: yong.xd
        spec:
          imagePullSecrets:
            - name: aliyun-regcred
          serviceAccountName: default
          securityContext:
          dnsPolicy: None
          dnsConfig:
            nameservers:
              - 172.31.74.196
            searches:
              - test1.svc.cluster.local
              - svc.cluster.local
              - cluster.local
    
    
          containers:
            - name: golang
              securityContext:
                runAsUser: 0
              image: "regisy.buydce.com/dataoke-test/dtk-go-tiktok-admin-golang:latest"
              volumeMounts:
              - name: config
                mountPath: /opt/app/conf/
              ports:
                - name: http
                  containerPort: 8888
                  protocol: TCP
              livenessProbe:
                httpGet:
                  path: /health
                  port: 8888
                initialDelaySeconds: 5
                periodSeconds: 20
                timeoutSeconds: 3
              readinessProbe:
                httpGet:
                  path: /health
                  port: 8888
                initialDelaySeconds: 5
                periodSeconds: 10
                timeoutSeconds: 3
              resources:
                requests:
                  cpu: 1m
                  memory: 20Mi
    
            - name: nginx
              securityContext:
              image: "restry.buydce.com/dataoke-test/dtk-go-tiktok-admin-nginx:latest"
              volumeMounts:
              - name: ng-config
                mountPath: /etc/nginx/conf.d/
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
              livenessProbe:
                httpGet:
                  path: /health
                  port: 80
                periodSeconds: 5
              readinessProbe:
                httpGet:
                  path: /health
                  port: 80
                periodSeconds: 5
              resources:
                requests:
                  cpu: 1m
                  memory: 64Mi
                limits:
                  cpu: 200m
                  memory: 256Mi
          volumes:
          - name: ng-config
            configMap:
              name: dtk-vue-tiktok-admin-config
          - name: config
            configMap:
              name: dtk-go-tiktok-admin-config
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: dtk-go-tiktok-admin
    spec:
      ports:
        - port: 80
          targetPort: 80
          protocol: TCP
          name: nginx
        - port: 8888
          targetPort: 8888
          protocol: TCP
          name: golang
      selector:
        app.kubernetes.io/name: dtk-go-tiktok-admin
        app.kubernetes.io/business: infrastructure
        app.kubernetes.io/runtime: golang
        app.kubernetes.io/tier: backend
        app.kubernetes.io/environment: test
        app.kubernetes.io/managed-by: yong.xd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    1. 启动服务
    kubectl apply -f ./ -n test1
    
    • 1
    1. 配置jenkins
    #!/usr/bin/env groovy
    import groovy.json.JsonOutput
    
    String gitRepositryURL = 'https://test.com/dtk-go-tiktok-admin.git'
    String dockerRegistry = 'test.com'
    String dockerRegistryURL = 'https://test.com'
    String dockerRegistryNameSpace = 'dataoke-test'
    #dockerfile路径
    String kubeManifestsRepo = '/home/jenkins/repo/dtk-kubernetes-test/app'
    Map dockerFiles = ["nginx":"Dockerfile.test.nginx", "golang":"Dockerfile.test.golang"]
    Map dockerImages = [:]
    boolean notify = false
    
    String jobBaseName = env.JOB_NAME[4..-1]
    String jobK8sName = jobBaseName.replaceAll('_', "-") 
    
    Map commitInfo = [:]
    Map buildInfo = [:]
    
    commitInfo.projectName = gitRepositryURL.replaceFirst(/^.*\/([^\/]+?).git$/, '$1') 
    commitInfo.gitRepositryURL = gitRepositryURL
    buildInfo.buildId = currentBuild.id
    
    @NonCPS
    def newSh(String cmd) {
    	def script = '#!/bin/sh +x\n' << cmd
    	result = sh(returnStdout: true, script: script.toString())
    	return result
    }
    
    pipeline {
    	agent any
    
    	options {
    		buildDiscarder logRotator(
    			artifactDaysToKeepStr: '', 
    			artifactNumToKeepStr: '', 
    			daysToKeepStr: '10', 
    			numToKeepStr: '10'
    			)
    	}
    
    	parameters {
            
            choice( 
            	name: 'PENV',
            	choices: [
            		'dev1',
            		'dev2',
            		'test1',
            		'test2', 
            		'test3', 
            		'test4',
            		'test5',
                            'test6',
                            'test7',
            		'huise',
    'huise4',
                            'huise3'
            	], 
            	description: '选择发布环境,默认发布至dev1测试环境'
            	)
    
            gitParameter(
            	name: 'GIT_BRANCH', 
                type: 'PT_BRANCH_TAG',
                branchFilter: 'origin/(.*)',
                defaultValue: 'master',
                selectedValue: 'DEFAULT',
                sortMode: 'DESCENDING_SMART',
                quickFilterEnabled: true, 
                description: 'Select your branch or tag.'
            	)
    		 booleanParam(name: 'force', defaultValue: false, description: '代码重复强制发版')
        }
    
    	stages {
    
    		stage('预处理') {
    			steps {
    				script {
    					def now = new Date()
    					buildInfo.buildDate = now.format("yy-MM-dd HH:mm", TimeZone.getTimeZone('UTC'))
    
    					def causes = currentBuild.getBuildCauses()
    					buildInfo.buildUser = causes[0]['userName']
    					userList = readYaml(file:'/etc/jenkins/users.yaml')
    					if (!(PENV in userList.env.dev ) && !(buildInfo.buildUser in userList.user.allow)) {
    						error(message: "开发只能发布环境到${userList.env.dev.join(',')}")			
    					}
    					buildInfo.gitBranch = GIT_BRANCH
    					buildInfo.publishEnv = PENV
    					currentBuild.description = "k8s环境: ${PENV} 构建人:${buildInfo.buildUser} 分支: ${GIT_BRANCH}"
    					newSh("check.py -u ${buildInfo.buildUser} -e ${PENV}")
    				}
    			}
    		}
    
    		stage('同步代码仓库') {
    			steps {
    				script {
    					def scmVars = checkout([
    								$class: 'GitSCM', 
    								branches: [[name: "${GIT_BRANCH}"]], 
    								extensions: [[$class: 'CheckoutOption', timeout: 20], [$class: 'CloneOption', depth: 1]], 
    								userRemoteConfigs: [[credentialsId: "5411496d-3606-4-ab9c-2e4453cd2880", url: "${gitRepositryURL}"]]
    								])
    					commitInfo.gitCommit = scmVars.GIT_COMMIT
    					commitInfo.gitBranch = GIT_BRANCH
    					commitInfo.xiangmu_name = env.JOB_BASE_NAME
    					commitInfo.commitDate = newSh('git log --pretty=format:"%ci" -1')
    					commitInfo.cmmitMessage = newSh('git log --pretty=format:"%s" -1')
    
    					String gitDiff = newSh('git diff HEAD^ HEAD')
    					def committer = [:]
    					committer.name = newSh('git log --pretty=format:"%cn" -1')
    					committer.email =  newSh('git log --pretty=format:"%ce" -1')
    					commitInfo.committer = committer
    					
    					String consoleStdout = "\n\n---------SYNCHRONIZE GIT REPOSITORY---------\nGit repo sync successfully.\n\n" + JsonOutput.prettyPrint(JsonOutput.toJson(commitInfo))
    					println(consoleStdout)
    
    					consoleStdout = "\n\n---------CHANGE LOGS---------\nGit diff:\n\n" + gitDiff
    					println(consoleStdout)
    					getDatabaseConnection(type: 'GLOBAL') {
    						def sqlString="select commit_seccec from jenkins_commit.jenkins_jilu where xm_name = ? and env = ?"
                            def params=[commitInfo.xiangmu_name,PENV]
                            def rest_null = sql sql:sqlString,parameters:params
    						if (rest_null.size() == 0){
    						  def sqlString2="insert  into  jenkins_commit.jenkins_jilu(xm_name,env,commit_seccec)   values(?,?,?)"
                              def params2=[commitInfo.xiangmu_name,PENV,commitInfo.gitCommit]
    						  sql sql:sqlString2,parameters:params2
    						  println("mysql插入数据")
    						}
    						if (rest_null.size() >= 1) {
    							   def Map rest = rest_null.get(0)
                            if (rest.get("commit_seccec") == commitInfo.gitCommit && force == "false"){
                            currentBuild.description = "k8s环境: ${PENV} 构建人:${buildInfo.buildUser} 分支: ${GIT_BRANCH} 构建失败: 代码重复不发版"
    							   println("代码没有变化不做发版")
                                   error "上一个版本和现在正在发的版本一致,不做发版"
    							   }
    						}
    				
    					}
    				}
    			}
    		}
    
    		stage('构建') {		
    			agent {
              		docker { 
                  		image 'reistry.buynce.com/dataoke-test/golang:1.19'
                  		args '--user root -v /data/jenkins_build_cache/.cache:/.cache'
                  		args '--user root -v /data/lib/go:/go'
                  		reuseNode true
              		}	
          		}
    
            	steps {
                	script {
    					env.STAGE = "goujian"
                		def now = new Date()
    					String buildDate = now.format("yy-MM-dd HH:mm", TimeZone.getTimeZone('UTC'))
    
             			sh (script: '#!/bin/sh +x\n' + '''
             			cd ./server
             			mkdir -p .cache
                 		export GO111MODULE=on
                 		export GOPROXY=https://goproxy.cn,direct
                 		export GOPRIVATE="gitlab.buydance.com/*"
                 		export CGO_ENABLED=0
                 		go mod  tidy
                 		go build -o main
             			'''
             			)
    
               			def files = findFiles(glob: '**/main')
               			String artifactPath = files[0].path
               			String sha1Checksum = sha1(file: artifactPath)
               			String sha256Checksum = sha256(file: artifactPath)
                				
    
    
                		consoleStdout = "\n\n---------BUILD RESULTS---------\nBuild info generated successfully.\n\n" + JsonOutput.prettyPrint(JsonOutput.toJson(buildInfo))
                		println(consoleStdout)
            		}	
    			}
    		}
    		
    		stage('构建vue') {		
    			agent {
              		docker { 
                  		image 'node:14.19.3-alpine3.15'
                        args '--user root -v /data/jenkins_build_cache/.cache:${HOME}/.cache'
                        args '--user root -v /data/lib/composer:/root/.composer'
                        reuseNode true
              		}	
          		}
    
            	steps {
                	script {
                		sh """
    					cd ./web
                        npm config set puppeteer_download_host=https://npm.taobao.org/mirrors
                        npm i --registry=https://registry.npm.taobao.org
                        npm run build
                        """
    					
                		consoleStdout = "\n\n---------BUILD RESULTS---------\nBuild info generated successfully.\n\n" + JsonOutput.prettyPrint(JsonOutput.toJson(buildInfo))
                		println(consoleStdout)
            		}	
    			}
    		}
    		
    
    		stage('Docker') {
    			steps {
    				script {
    					env.STAGE = "DOCKERFIEL"
    				//	docker.withRegistry(dockerRegistryURL, '8f1a40fa-3258-4717-825c-a9f87299916d') {
    					docker.withRegistry(dockerRegistryURL) {
    						
    						String dockerFile = kubeManifestsRepo + '/' + jobBaseName + '/' + 'Dockerfile.test.nginx'
    						    
    						if (!fileExists(dockerFile)) {
    							dockerFile = kubeManifestsRepo + '/' + jobK8sName + '/' + 'Dockerfile.test.nginx'
    						}
    
    						String dockerRepository = dockerRegistry + '/' + dockerRegistryNameSpace + '/' + jobK8sName + '-' + 'nginx'
    						def customImage = docker.build(dockerRepository, "-f ${dockerFile} .")
    						customImage.push(commitInfo.gitCommit)
    						customImage.push('latest')
    						
    						dockerImages.nginx = dockerRepository + ':' + commitInfo.gitCommit
    
    						dockerFile = kubeManifestsRepo + '/' + jobBaseName + '/' + 'Dockerfile.test.golang'
    						    
    						if (!fileExists(dockerFile)) {
    							dockerFile = kubeManifestsRepo + '/' + jobK8sName + '/' + 'Dockerfile.test.golang'
    						}
    
    						dockerRepository = dockerRegistry + '/' + dockerRegistryNameSpace + '/' + jobK8sName + '-' + 'golang'
    						customImage = docker.build(dockerRepository, "-f ${dockerFile} .")
    						customImage.push(commitInfo.gitCommit)
    						customImage.push('latest')
    
    						dockerImages."golang" = dockerRepository + ':' + commitInfo.gitCommit
    					}
    				}
    			}
    		}
    
    		stage('部署') {
    			steps {
    				script {
    					env.STAGE = "bushu"
    					dockerImages.each { k, v -> 
    						newSh("kubectl -n ${PENV} set image deployment/${jobK8sName} ${k}=${v}")
    						newSh("kubectl -n ${PENV} rollout status deployment/${jobK8sName} --timeout=2m")
    					}
    					String content = "![screenshot](https://comquent.de/wp-content/uploads/CQ-Pipeline-Kurs.png)\n\n### Jenkins Pipeline\n>**构建信息**:\n>- 构建项目: ${jobBaseName}\n>- 构建id: ${currentBuild.number}\n>- 构建人: ${buildInfo.buildUser}\n>- 构建分支: ${GIT_BRANCH}\n>- 发布环境: ${PENV}\n>**版本信息**:\n>- commit_hash: ${commitInfo.gitCommit}\n>- commit_date: ${commitInfo.commitDate}\n>- commit_message: ${commitInfo.cmmitMessage}\n>- committer: ${commitInfo.committer.name}"	
    					def workflowMessage = [
    						"msgtype": "actionCard",
    						"actionCard":[
    							"title":"构建信息",
    							"text":content,
    							"btnOrientation": "0",
    							"btns": [
    								[
    									"title": "详细信息",
    									"actionURL": "https://k8sns.haojqu.com/blue/organizations/jenkins/k8s_dtk_go_app_api/detail/k8s_dtk_go_app_api/${currentBuild.number}/pipeline"
    								],
    								[
    									"title": "日志监控",
    									"actionURL": "http://k8sana.hou.com/app/kibana#/discover?_g=()&_a=(columns:!(_source),index:'18d51920-96c3-11eb-811f-1383c86a1d0',interval:auto,query:(language:kuery,query:''),sort:!(!('@timestamp',desc)))"
    								],
    							]
    						]
    					]	
    
    					String workflowMessageJSON = JsonOutput.toJson(workflowMessage)
    					timeout(unit: 'SECONDS', time: 30) {
    						newSh("curl 'https://oapi.dingtalk.com/robot/send?access_token=9e91f6860736ff69e7f6f986179e154e497b70e26fd749c' -s -H 'Content-Type: application/json' -d '${workflowMessageJSON}'")
    					}
    				}
    			}
    		}
    		stage("commit入库"){
                 steps {
                      script{
                            getDatabaseConnection(type: 'GLOBAL') {
    				        def sqlString3="update jenkins_commit.jenkins_jilu set commit_seccec=?    where xm_name=? and env=?;"
                            def params3=[commitInfo.gitCommit,commitInfo.xiangmu_name,PENV]
                            sql sql:sqlString3,parameters:params3
    				  }
    				  }
    			 }
    		}
    	}
    	post {
    		failure {
    			script{
    			if (STAGE == "goujian") {
    				println("----> goujian失败")
    			}
    		    if (STAGE == "bushu") {
    			   println("----> bushu失败")		   
    			}
    			if (STAGE == "DOCKERFIEL") {
    				println("----> DOCKERFIEL失败")
    			}
    	
    			}
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    1. 配置nginx
    upstream  dtk-vue-tiktok-admin  {
            server dtk-go-tiktok-admin  weight=1 max_fails=0 fail_timeout=0s;
                    keepalive 20;
    }
    
    server {
    listen  80;
    listen      443 ssl;
    server_name test.com;
    access_log  /var/log/nginx/dtest.com.access.log json;
    error_log   /var/log/nginx/dtest.com.error.log;
    ssl_certificate     conf.d/dtkcert/test.com.pem;
    ssl_certificate_key conf.d/dtkcert/test.com.key;
    more_set_headers 'Access-Control-Allow-Headers: Cookie,DNT,X-CSRF-Token,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Auth-token';
    more_set_headers 'Access-Control-Allow-Origin: *';
    more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT';
    more_set_headers 'Access-Control-Allow-Credentials: true';
    default_type     'text/html';
    set $backend 'dtk-vue-tiktok-admin';
    
    
    include  public/deny.conf;
    location / {
        proxy_pass http://$backend;
    }
    
    location ~ /\.ht {
        deny  all;
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    1. jenkins机器上的dockerfile
    [root@k8s-jenkins dtk-go-tiktok-admin]# cat Dockerfile.test.golang
    FROM test.com/dataoke-test/alpine:3.12-CST as test
    WORKDIR /opt/app
    COPY  $CI_PROJECT_DIR/server/main /opt/app/main
    CMD ["/opt/app/main", "-c", "/opt/app/conf/config.yaml"]
    
    [root@k8s-jenkins dtk-go-tiktok-admin]# cat Dockerfile.test.nginx
    FROM test.com/dataoke-test/openresty:base
    WORKDIR /opt/app/dist/
    COPY --chown=nobody:nobody web/dist /opt/app/dist
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    线上环境配置

    1. yaml其它都一样除了svc,因为svc需要绑定slb地址
    apiVersion: v1
    kind: Service
    metadata:
      name: dtk-go-tiktok-admin
      annotations:
      #开启slb使用
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-force-override-listeners: "true"
       #slb地址
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: lb-2ze1hpcomc
        #    service.beta.kubernetes.io/alibaba-cloud-loadbalancer-protocol-port: "http:9090"
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-scheduler: "wrr"
        namespace: default
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local
      ports:
        - port: 16107  #slb端口
          targetPort: 80 #pod服务端口
          protocol: TCP
      selector:
        app.kubernetes.io/name: dtk-go-tiktok-admin
        app.kubernetes.io/business: infrastructure
        app.kubernetes.io/runtime: golang
        app.kubernetes.io/tier: backend
        app.kubernetes.io/environment: prod
        app.kubernetes.io/managed-by: yong.xd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1. 启动
    cat .gitlab-ci.yml
    
    stages:
      - build
      - package
      - docker
      - deploy
      - notify
    
    
    build:
      stage: build
      image: test.com/dataoke-prod/golang:1.19-with-repo-cert
      cache:
        key:
          files:
          - go.mod
        paths:
          - .cache/pkg
      artifacts:
        expire_in: 20 mins
        untracked: false
        paths:
          - $CI_PROJECT_DIR/server/main
      script:
      - mkdir -p .cache
      - cd ./server 
      - export GOPATH="$CI_PROJECT_DIR/.cache"
      - go env -w GO111MODULE=on 
      - go env -w GOPROXY=https://goproxy.cn,direct 
      - go env -w GOPRIVATE=gitlab.buydance.com 
      - go env -w CGO_ENABLED=0
      - go build -o main
      only:
        - tags
    
    package:
      stage: package
      image: test.com/dataoke-prod/node:14.19.3-alpine3.15
      script:
      - cd ./web
      - npm config set puppeteer_download_host=https://npm.taobao.org/mirrors
      - npm i --registry=https://registry.npm.taobao.org
      - npm run build
      cache:
        key:
          files:
          - package.json
        paths:
          - node_modules
      artifacts:
        name: "dist"
        untracked: false
        expire_in: 5 mins
        paths:
          - $CI_PROJECT_DIR/web/dist
      only:
        - tags
    
    
    
    docker:
      stage: docker
      image: test.com/dataoke-prod/kaniko-executor:debug
      script:
      - mkdir -p /kaniko/.docker
      - echo "${DOCKER_AUTH_CONFIG}" > /kaniko/.docker/config.json
      - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile.prod.nginx --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-nginx:${CI_COMMIT_SHORT_SHA} --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-nginx:latest
      - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile.prod.golang --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-golang:${CI_COMMIT_SHORT_SHA} --destination test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-golang:latest
      only:
        - tags
    
    deploy:
      stage: deploy
      image: test.com/dataoke-prod/kubectl:1.18.1
      variables:
        GIT_STRATEGY: none
        K8S_NAME_SPACE: default
      script:
      - mkdir -p $HOME/.kube
      - echo "$KUBERNETES_SECRET" >> "$HOME/.kube/config"
      - kubectl version
      - kubectl get deployments.apps -n ${K8S_NAME_SPACE}
      - kubectl -n ${K8S_NAME_SPACE} set image deployment/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'` nginx=test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-nginx:${CI_COMMIT_SHORT_SHA} golang=test.aliyuncs.com/dataoke-prod/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`-golang:${CI_COMMIT_SHORT_SHA} --record
      - kubectl rollout status deployment/`echo ${CI_PROJECT_NAME} |sed 's@_@-@g'`
      only:
        - tags
    
    
    notifyFailWeChat:
      stage: notify
      image: test.aliyuncs.com/dataoke-prod/curl-image:v1
      script:
        - curl 'https://oapi.dingtalk.com/robot/send?access_token=6147ec1eb7d8b9bd5cd1b15f1c' -H 'Content-Type:application/json' -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$CI_PROJECT_NAME项目构建失败\n>本次构建由:$GITLAB_USER_NAME 触发\n>项目名称:$CI_PROJECT_NAME\n>提交号:$CI_COMMIT_SHA\n>提交日志:$CI_COMMIT_MESSAGE\n>构建分支:$CI_COMMIT_BRANCH\n>流水线地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"
    
      only:
        - tags
      when: on_failure
    
    # 构建成功时的通知消息
    notifySuccessWeChat:
      stage: notify
      image: test.aliyuncs.com/dataoke-prod/curl-image:v1
      script:
        - curl 'https://oapi.dingtalk.com/robot/send?access_token=d6147ec1eb7d8b9bd5cd1b15f1c' -H 'Content-Type:application/json' -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$CI_PROJECT_NAME项目构建成功\n>本次构建由:$GITLAB_USER_NAME 触发\n>项目名称:$CI_PROJECT_NAME\n>提交号:$CI_COMMIT_SHA\n>提交日志:$CI_COMMIT_MESSAGE\n>构建分支:$CI_COMMIT_BRANCH\n>流水线地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}"
      only:
        - tags
      when: on_success
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    1. 配置dockerfile
    cat  Dockerfile.prod.golang
    
    FROM test.aliyuncs.com/dataoke-prod/alpine:3.12-CST as prod
    WORKDIR /opt/app
    COPY  $CI_PROJECT_DIR/server/main /opt/app/main
    CMD ["/opt/app/main", "-c", "/opt/app/conf/config.yaml"]
    
    cat Dockerfile.prod.nginx
    
    FROM test.aliyuncs.com/dataoke-prod/openresty:base
    WORKDIR /opt/app/dist/
    COPY --chown=nobody:nobody web/dist /opt/app/dist
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 配置nginx
    upstream  dtk-go-tiktok-admin {
    #svc内网ip
    server 192.168.10.123:16107  weight=1 max_fails=0 fail_timeout=0s;
    keepalive 20;
    }
    
    server {
    listen  80;
    listen      443 ssl;
    server_name test.com;
    access_log  /var/log/nginx/dtest.com.access.log json;
    error_log   /var/log/nginx/dtest.com.error.log;
    ssl_certificate     conf.d/dtkcert/test.com.pem;
    ssl_certificate_key conf.d/dtkcert/test.com.key;
    
    more_set_headers 'Access-Control-Allow-Headers: Cookie,DNT,X-CSRF-Token,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Auth-token';
    more_set_headers 'Access-Control-Allow-Origin: *';
    more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT';
    more_set_headers 'Access-Control-Allow-Credentials: true';
    default_type     'text/html';
    set $backend 'dtk-vue-tiktok-admin';
    
    include  public/deny.conf;
    location / {
    proxy_pass http://$backend;
    }
    
    location ~ /\.ht {
    deny  all;
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    1. 结果图
      微信截图_20230928142620.png
      微信截图_20230928142639.png

    微信截图_20230928142705.png
    微信截图_20230928142657.png
    微信截图_20230928142557.png
    微信截图_20230928142535.png

    原文

  • 相关阅读:
    隐马尔可夫过程
    java面试题含答案总结七
    呼叫中心系统信息发送功能的应用
    【win10和win11打印机局域网共享】
    C++ if 语句
    【SpringCloud】认识微服务、服务拆分以及远程调用
    springboot 整合使用redis发布订阅功能
    降压转换器 LM73606QRNPRQ1 汽车 开关稳压器 30WQFN
    CSS简介
    二本4年Java经验,五面阿里艰苦经历(定薪45K),回馈一波心得体会
  • 原文地址:https://blog.csdn.net/weixin_43606975/article/details/133384151