Commit c10f101e authored by kewei.jia's avatar kewei.jia Committed by 智勇

集群切换

parent 5a25ee8c
......@@ -14,6 +14,7 @@ const repositoryRouter = require('./repository')
const tag = require('./tag')
const ingressRoute = require('./ingress')
const deploy = require('./restartLatest')
const client = require('../middleware/client')
const logFormat = ':req[x-real-ip] :req[x-forwarded-for] - -'
+ ' ":method :url HTTP/:http-version"'
......@@ -30,6 +31,11 @@ function loadRoutes(router) {
.use(error())
.use(result())
.use(validate())
.use(client())
.use(async (ctx, next) => {
ctx.jia = 'kewei'
await next()
})
.use(async (ctx, next) => {
// 腾讯云
ctx.container = container
......
const Router = require('koa-router')
const { ingressGet, ingressUpdate } = require('../kubeService/ingress')
const { ingressGet, ingressUpdate, ingressDelete } = require('../kubeService/ingress')
const router = new Router();
module.exports = router
router.get('/', async (ctx) => {
// const data = await ctx.cluster.ingress_get(ctx.query.namespace)
const data = await ingressGet(ctx.query.namespace, ctx.query.serviceName)
const data = await ingressGet(ctx.client, ctx.query.namespace, ctx.query.serviceName)
ctx.body = ctx.ok(data)
})
......@@ -15,7 +15,7 @@ namespace
rules
*/
router.post('/modify', async (ctx) => {
const data = await ingressUpdate(ctx.request.body.namespace, ctx.request.body.serviceName, ctx.request.body.host)
const data = await ingressUpdate(ctx.client, ctx.request.body.namespace, ctx.request.body.serviceName, ctx.request.body.host)
ctx.body = ctx.ok(data)
})
// router.post('/modify', async (ctx) => {
......@@ -29,7 +29,7 @@ router.post('/modify', async (ctx) => {
// })
router.post('/create', async (ctx) => {
const ingress = await ctx.cluster.ingress_get(ctx.request.body.namespace)
const ingress = await ingressGet(ctx.request.body.namespace)
if (ingress) {
ctx.body = ctx.fail('namespace下已存在ingress')
return ctx.body
......@@ -39,6 +39,6 @@ router.post('/create', async (ctx) => {
})
router.post('/delete', async (ctx) => {
await ctx.cluster.ingress_delete(ctx.request.body.ingressName, ctx.request.body.namespace)
await ingressDelete(ctx.request.body.ingressName, ctx.request.body.namespace)
ctx.body = ctx.ok()
})
......@@ -7,9 +7,8 @@ const { getAllNamespace, createNamespace } = require('./../kubeService/service')
const router = new Router();
module.exports = router
router.get('/', async (ctx) => {
const data = await getAllNamespace()
const data = await getAllNamespace(ctx.client)
ctx.body = ctx.ok(data)
})
......@@ -26,14 +25,14 @@ router.get('/get_namespace_for_jenkins', async (ctx) => {
router.get('/info', async (ctx) => {
const data = await getAllNamespace()
const data = await getAllNamespace(ctx.client)
const ns = data.namespaces.find(item => item.name === qs.unescape(ctx.request.query.namespace))
ctx.body = ctx.ok(ns)
})
router.post('/create', async (ctx) => {
// await ctx.cluster.namespace_create(ctx.request.body.name, ctx.request.body.description)
await createNamespace(ctx.request.body.name, ctx.request.body.description)
await createNamespace(ctx.client, ctx.request.body.name, ctx.request.body.description)
ctx.body = ctx.ok()
})
......
......@@ -3,12 +3,21 @@ const _ = require('lodash')
const sleep = require('sleep')
const logger = require('koa-log4').getLogger('deployLatest')
// const cluster = require('../services/tke.clusterService').create()
const container = require('../services/tke.containerService').create()
const path = require('path')
const Client = require('kubernetes-client').Client
const config = require('kubernetes-client').config
const { serviceRestart, getServicesFormat, getAllNamespace } = require('../kubeService/service')
const container = require('../services/tke.containerService').create()
const repoNS = ['qa-java', 'qa-ui', 'qa-node', 'qa-python']
const testNamespace = ['qa', 'fe', 'data', 'fis', 'xyqb2']
const client = new Client({
config: config.fromKubeconfig(
path.resolve(__dirname, './../kubeService/kubeConfig-qa.yaml'),
),
version: '1.10',
})
const deploy = async () => {
logger.info('deployLatest start')
for (const ns of repoNS) {
......@@ -18,15 +27,15 @@ const deploy = async () => {
const repoName = repo.reponame.split('/')[1]
const latest = await container.getTagByName(repo.reponame, 'latest')
const latestImageID = _.get(latest.tagInfo, '[0].tagId', '')
let ns = await getAllNamespace()
let ns = await getAllNamespace(client)
ns = ns.namespaces && ns.namespaces.filter(item => testNamespace.includes(item.name))
for (const namespace of ns) {
const svcs = await getServicesFormat(namespace.name)
const svcs = await getServicesFormat(client, namespace.name)
for (const svc of svcs) {
if (svc.serviceName === repoName && svc.image.indexOf('latest') !== -1) {
if (latestImageID !== svc.imageID.split('@')[1]) {
logger.info('部署项目', namespace.name, svc.podName)
await serviceRestart(namespace.name, svc.podName)
await serviceRestart(client, namespace.name, svc.podName)
sleep.msleep(500)
}
}
......
......@@ -2,10 +2,17 @@ const schedule = require('node-schedule')
const request = require('request')
const moment = require('moment')
const Redis = require('ioredis')
const logger = require('koa-log4')
.getLogger()
const path = require('path')
const Client = require('kubernetes-client').Client
const config = require('kubernetes-client').config
const { podGetstatus, getPods } = require('../kubeService/service')
const client = new Client({
config: config.fromKubeconfig(
path.resolve(__dirname, './../kubeService/kubeConfig-qa.yaml'),
),
version: '1.10',
})
const redis = new Redis(6380, '172.30.220.22')
const awaitRequest = function (options) {
return new Promise((resolve, reject) => {
......@@ -82,7 +89,7 @@ const checkRecoverPod = async () => {
const podname = resKeys[i].split('#')[1]
// 获取新的状态
if (podname.indexOf(resKeys[i].split('#')[1]) > -1) {
const Pod = await getPods(namespace)
const Pod = await getPods(client,namespace)
Pod.body.items.forEach(async (item) => {
if (item.metadata.name.indexOf(podname) > -1) {
if (item.status.conditions.length === 3) {
......@@ -114,7 +121,7 @@ const checkRecoverPod = async () => {
});
}
const checkErrorPod = async () => {
const listPods = await podGetstatus()
const listPods = await podGetstatus(client)
listPods.body.items.forEach((item) => {
const key = `${item.metadata.namespace}:${item.metadata.name}#${item.metadata.labels['qcloud-app']}`
item.status.conditions.forEach(async (value) => {
......
......@@ -25,7 +25,7 @@ const router = new Router()
module.exports = router
router.get('/', async (ctx) => {
const data = await getServicesFormat(ctx.query.namespace)
const data = await getServicesFormat(ctx.client, ctx.query.namespace)
ctx.body = ctx.ok({
services: data,
namespace: ctx.query.namespace,
......@@ -49,12 +49,12 @@ const createService = async (ctx) => {
data.resources = resources
logger.info('创建服务', data)
await serviceCreate(data)
await serviceCreate(ctx.client, data)
if (label !== 'base') {
if (serviceName === 'xyqb-user2') {
await ingressCreate(namespace, 'xyqb-user2-2', 'passportapi2')
await ingressCreate(ctx.client, namespace, 'xyqb-user2-2', 'passportapi2')
}
await ingressCreate(namespace, serviceName, domain)
await ingressCreate(ctx.client, namespace, serviceName, domain)
}
ctx.body = ctx.ok('创建成功')
}
......@@ -74,7 +74,7 @@ router.post('/details', async (ctx) => {
.required(),
}))
const data = await getServiceDetail(ctx.request.body.namespace, ctx.request.body.serviceName, ctx.request.body.type)
const data = await getServiceDetail(ctx.client, ctx.request.body.namespace, ctx.request.body.serviceName, ctx.request.body.type)
ctx.body = ctx.ok(data)
})
router.post('/delete', async (ctx) => {
......@@ -85,9 +85,9 @@ router.post('/delete', async (ctx) => {
if (res) {
await redis.set(`copy${namespace}&${serviceName}`, res)
}
await serviceDelete(namespace, serviceName)
await replicaSetDelete(namespace, serviceName)
await pvcDelete(namespace, serviceName)
await serviceDelete(ctx.client, namespace, serviceName)
await replicaSetDelete(ctx.client, namespace, serviceName)
await pvcDelete(ctx.client, namespace, serviceName)
// let rsData = await getReplicaSet(namespace)
// rsData = rsData.map(item => item.metadata.name).filter(item => item.indexOf(serviceName) !== -1)
......@@ -95,19 +95,19 @@ router.post('/delete', async (ctx) => {
// await replicaSetDelete(namespace, rs)
// }
await ingressDelete(namespace, serviceName)
await ingressDelete(ctx.client, namespace, serviceName)
if (serviceName === 'xyqb-user2') {
await ingressDelete(namespace, 'xyqb-user2-2')
await ingressDelete(ctx.client, namespace, 'xyqb-user2-2')
}
ctx.body = ctx.ok(`删除${serviceName}成功`)
})
router.post('/modifyImage', async (ctx) => {
let list = await getPods(ctx.request.body.namespace)
let list = await getPods(ctx.client, ctx.request.body.namespace)
list = list.body.items.map(item => (item.metadata.labels && item.metadata.labels['qcloud-app']) || item.metadata.name)
if (list.includes(ctx.request.body.serviceName)) {
await imageUpdate(ctx.request.body)
await imageUpdate(ctx.client, ctx.request.body)
} else {
await createService(ctx)
}
......@@ -122,7 +122,7 @@ router.post('/modifyDeploy', async (ctx) => {
}
const resources = makeResouce(data.serviceName, data.label)
data.resources = resources
await deployUpdate(data)
await deployUpdate(ctx.client, data)
ctx.body = ctx.ok('更新成功')
})
......@@ -134,7 +134,7 @@ router.post('/redeploy', async (ctx) => {
if (res) {
await redis.set(`copy${ctx.request.body.namespace}&${ctx.request.body.serviceName}`, res)
}
await serviceRestart(ctx.request.body.namespace, ctx.request.body.podName)
await serviceRestart(ctx.client, ctx.request.body.namespace, ctx.request.body.podName)
ctx.body = ctx.ok('重置服务成功')
})
......@@ -142,8 +142,8 @@ router.post('/redeploy', async (ctx) => {
router.get('/listEnvVars', async (ctx) => {
const envVars = {}
const res = await Promise.all([
getPods(ctx.request.query.namespace),
getServices(ctx.request.query.namespace),
getPods(ctx.client, ctx.request.query.namespace),
getServices(ctx.client, ctx.request.query.namespace),
])
res[0].body.items.forEach(async (item) => {
......@@ -176,8 +176,8 @@ router.get('/listEnvVars', async (ctx) => {
router.get('/listEnvVarsNew', async (ctx) => {
const envVars = {}
const res = await Promise.all([
getPods(ctx.request.query.namespace),
getServices(ctx.request.query.namespace),
getPods(ctx.client, ctx.request.query.namespace),
getServices(ctx.client, ctx.request.query.namespace),
])
res[0].body.items.forEach(async (item) => {
......
const path = require('path')
const Client = require('kubernetes-client').Client
const config = require('kubernetes-client').config
const logger = require('koa-log4').getLogger()
// const client = new Client({ config: config.fromKubeconfig(), version: '1.9' })
const client = new Client({
config: config.fromKubeconfig(
path.resolve(__dirname, './kubeConfig.yaml'),
),
version: '1.10',
})
const getManifest = (namespace, servicename, doamin) => ({
apiVersion: 'extensions/v1beta1',
kind: 'Ingress',
......@@ -40,23 +29,23 @@ const getManifest = (namespace, servicename, doamin) => ({
],
},
})
const ingressGet = async (namespace, servicename) => client.apis.extensions.v1beta1.namespaces(namespace)
const ingressGet = async (client, namespace, servicename) => client.apis.extensions.v1beta1.namespaces(namespace)
.ingresses(servicename).get()
const ingressCreate = async (namespace, servicename, doamin) => {
const ingressCreate = async (client, namespace, servicename, doamin) => {
const Manifest = getManifest(namespace, servicename, doamin)
logger.info('创建ingress', JSON.stringify(Manifest))
await client.apis.extensions.v1beta1.namespace(namespace).ingresses
.post({ body: Manifest })
}
const ingressUpdate = async (namespace, servicename, host) => {
const ingressUpdate = async (client, namespace, servicename, host) => {
const Manifest = getManifest(namespace, servicename)
Manifest.spec.rules[0].host = host
logger.info('更新ingress', Manifest)
await client.apis.extensions.v1beta1.namespace(namespace).ingresses(servicename)
.patch({ body: Manifest })
}
const ingressDelete = async (namespace, servicename) => {
const ingressDelete = async (client, namespace, servicename) => {
logger.info('删除ingress', namespace, servicename)
await client.apis.extensions.v1beta1.namespaces(namespace).ingresses(servicename).delete()
}
......
apiVersion: v1
clusters:
- cluster:
certificate-authority: tke-cluster-dev-ops.crt
server: https://cls-pbwgwa1p.ccs.tencent-cloud.com
name: tke-cluster
contexts:
- context:
cluster: tke-cluster
user: tke-admin
name: tke-qa-system
current-context: tke-qa-system
kind: Config
preferences: {}
users:
- name: tke-admin
user:
password: SWjVjJ4PgvQrEdlGW9MNa7GRzWmBtdgl
username: admin
apiVersion: v1
clusters:
- cluster:
certificate-authority: tke-cluster-ca.crt
certificate-authority: tke-cluster-qa.crt
server: https://cls-acfx4pvj.ccs.tencent-cloud.com
name: tke-cluster
contexts:
......
const path = require('path')
const Client = require('kubernetes-client').Client
const config = require('kubernetes-client').config
const _ = require('lodash')
const moment = require('moment')
const yaml = require('js-yaml')
......@@ -9,14 +6,8 @@ const logger = require('koa-log4')
const yamls = require('../yamls')
const APP_CONFIG = require('../config')
const client = new Client({
config: config.fromKubeconfig(
path.resolve(__dirname, './kubeConfig.yaml'),
),
version: '1.10',
})
const keepNamespace = ['default', 'kube-system', 'monitor', 'kube-public']
const getAllNamespace = async () => {
const getAllNamespace = async (client) => {
const res = await client.api.v1.namespace.get()
const data = {
namespaces: [],
......@@ -34,7 +25,7 @@ const getAllNamespace = async () => {
})
return data
}
const createNamespace = async (name, description) => {
const createNamespace = async (client, name, description) => {
const parmas = {
apiVersion: 'v1',
kind: 'Namespace',
......@@ -82,7 +73,7 @@ const makeManifest = (data) => {
return manifestArray
}
const serviceCreate = async (data) => {
const serviceCreate = async (client, data) => {
const { namespace, serviceName } = data
const manifestArray = makeManifest(data)
......@@ -133,7 +124,7 @@ const serviceCreate = async (data) => {
}
}
const imageUpdate = async (data) => {
const imageUpdate = async (client, data) => {
const { namespace, serviceName } = data
const image = `ccr.ccs.tencentyun.com/${data.image}`
const updateObj = {
......@@ -155,7 +146,7 @@ const imageUpdate = async (data) => {
.patch({ body: updateObj })
}
const deployUpdate = async (data) => {
const deployUpdate = async (client, data) => {
const { namespace, serviceName } = data
const manifestArray = makeManifest(data)
......@@ -239,16 +230,16 @@ const formatPodInfo = (podInfo) => {
const formatIngressInfo = obj => ({ host: _.get(obj.spec, 'rules[0].host', '') })
const getPods = async (namespace) => {
const getPods = async (client, namespace) => {
const data = await client.api.v1.namespaces(namespace)
.pods
.get()
return data
}
const podGetstatus = async () => client.api.v1.pods.get()
const podGetstatus = async client => client.api.v1.pods.get()
const getServicesFormat = async (namespace) => {
const getServicesFormat = async (client, namespace) => {
const ret = []
const service = {}
......@@ -291,7 +282,7 @@ const getServicesFormat = async (namespace) => {
return ret
}
const getServiceDetail = async (namespace, name, type) => {
const getServiceDetail = async (client, namespace, name, type) => {
const res = await Promise.all([
client.api.v1.namespaces(namespace)
.pods
......@@ -315,14 +306,14 @@ const getServiceDetail = async (namespace, name, type) => {
return _.assign({}, res[0], res[1], res[2])
}
const serviceRestart = async (namespace, name) => {
const serviceRestart = async (client, namespace, name) => {
logger.info('重置服务', namespace, name)
await client.api.v1.namespaces(namespace)
.pods(name)
.delete()
}
const serviceDelete = async (namespace, name) => {
const serviceDelete = async (client, namespace, name) => {
try {
logger.info('删除deploy', namespace, name)
await client.apis.apps.v1beta1.namespaces(namespace)
......@@ -337,21 +328,21 @@ const serviceDelete = async (namespace, name) => {
}
}
const getReplicaSet = async (namespace) => {
const rsData = await client.apis.apps.v1beta2.namespaces(namespace)
.replicasets
.get()
return rsData.body.items
}
// const getReplicaSet = async (client, namespace) => {
// const rsData = await client.apis.apps.v1beta2.namespaces(namespace)
// .replicasets
// .get()
// return rsData.body.items
// }
const replicaSetDelete = async (namespace, name) => {
const replicaSetDelete = async (client, namespace, name) => {
logger.info('删除rs', namespace, name)
await client.apis.apps.v1.namespaces(namespace)
.replicasets
.delete({ qs: { labelSelector: `qcloud-app=${name}` } })
// await client.apis.apps.v1.namespaces(namespace).replicasets(rsName).delete()
}
const pvcDelete = async (namespace, name) => {
const pvcDelete = async (client, namespace, name) => {
try {
logger.info('删除pvc', namespace, name)
await client.api.v1.namespaces(namespace)
......@@ -361,7 +352,7 @@ const pvcDelete = async (namespace, name) => {
logger.warn(error.toString())
}
}
const getServices = async (namespace) => {
const getServices = async (client, namespace) => {
const data = await client.api.v1.namespaces(namespace)
.services
.get()
......
-----BEGIN CERTIFICATE-----
MIIDZDCCAkygAwIBAgIISbRZqjmbMGkwDQYJKoZIhvcNAQELBQAwUDELMAkGA1UE
BhMCQ04xKjARBgNVBAoTCnRlbmNlbnR5dW4wFQYDVQQKEw5zeXN0ZW06bWFzdGVy
czEVMBMGA1UEAxMMY2xzLXBid2d3YTFwMB4XDTE5MDQxODA3NDI1MFoXDTM5MDQx
ODA3NDI1MFowUDELMAkGA1UEBhMCQ04xKjARBgNVBAoTCnRlbmNlbnR5dW4wFQYD
VQQKEw5zeXN0ZW06bWFzdGVyczEVMBMGA1UEAxMMY2xzLXBid2d3YTFwMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt9+zDO0GFdhdF+dLj7O2LnvJ3T9h
vwGEDlZtJCzYu1+zcxDOHfAW3Dc/F2WEIs/uEobHrzqQcz0syB1K9XmU7oXPkKU+
qCv660wH0PtufSDojiIqxAve5tlGIdnOf0o53kArcE/QQe7Eof0smkeS/QXnQze9
jkKiDgOnB6rtY9DeDqY7/zpZ59mkPGh6+4OYfaPHEPNCSdLp7wrPoEIh5JoZcAlP
Hr+RpCGGRsHVW8uqBsRblYZujMO1TNET4HmmVUHzeuGqt0VQsaRoXmOy6BdAqL/F
+Ko0BjkuooeOQopcuoNEBP/Ogsb9yoBeUTOTrAnKJ2vtrbIIPVP7wlX/dwIDAQAB
o0IwQDAOBgNVHQ8BAf8EBAMCAoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF
BwMBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFKafPQghDbF
L4FAW6//kKtauIvWQ0KazV0zacnvOv3QJIVAIIyKzEGEfgTFj/u9bp+0phU+zh+t
i9o7Jpv/lP1RaTLhax717jmPnM3e1xgf54+w9pVGuXXQgizNC3ZSxcw58xvDfYQX
cxXnSxjueG3Po7P1x6dhCxLJkknyIqrNKbtmyvgDpIVK+vBzCxHsjn2g6NUeoZEZ
e1evV0N+Z78dlOpgAtcVPsS8ga/XMfGZDsoPd0zsBOdcRyxb779PoLX1sbh/VkfT
idZKA4rM2Y65JxSFR+vgSAJe/7CNzqGyJbCIfstShUvmrry7GaASyjF+jLLL1eJq
u4oYFYdjpQk=
-----END CERTIFICATE-----
......@@ -19,3 +19,9 @@ GrlQjPW8071pJoTiX15DsweMM/JdKLWqShuIuf7asjpU+IdmB57SH74Dty3Di58C
GVWAB13spmdjHlhCy9QdliC8dS5Fj/4HTHt2Ga0CDFKEY4NqwHe/+Hj6dV92krbG
gZ6FQkaHwVk=
-----END CERTIFICATE-----
const path = require('path')
const Client = require('kubernetes-client').Client
const config = require('kubernetes-client').config
module.exports = function client() {
const client = {}
return async function (ctx, next) {
const cluster = ctx.request.headers.cluster
let yaml = ''
switch (cluster) {
case 'qa':
yaml = './../../kubeService/kubeConfig-qa.yaml'
break
case 'dev-ops':
yaml = './../../kubeService/kubeConfig-dev-ops.yaml'
break
default:
ctx.body = {
code: '0001',
msg: '请选择集群的名字',
}
return
}
if (!client[cluster]) {
client[cluster] = new Client({
config: config.fromKubeconfig(
path.resolve(__dirname, yaml),
),
version: '1.10',
})
}
ctx.client = client[cluster]
await next()
}
}
......@@ -5,7 +5,12 @@ const app = require('./../app')
const awaitRequest = function (options) {
return new Promise((resolve, reject) => {
request(options, (error, res) => {
request(Object.assign(options, {
headers: {
'Content-Type': 'application/json;charset=utf-8',
cluster: 'qa',
},
}), (error, res) => {
if (error) {
reject(error)
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment