🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 构建Docker 配置中心 ## 应用配置变更流程 ![image](https://i.imgur.com/8erVN93.png) ## 构建流程 - 利用基础镜像构建zookeeper 基础服务 - 在jenkins构建zkopspush job - gitlab 创建配置文件管理仓库 - 添加jenkins slave node ### 添加宿主机成为 jenkins slave node - 在jenkins 容器创建 root 用户ssh 密钥, 使容器可以登录宿主机 - 禁用jenkins master 提供 worknode ### 利用基础镜像 在jenkins 构建zookeeper 基础服务 docker stop ${AppName} && docker rm ${AppName} docker -H ${AppIp}:4243 run --restart=always -d --name ${AppName} -p 4181:2181 \ -v /data/volume/${AppName}/dump:/VolumeDump \ -v /data/volume/${AppName}/logs:/VolumeLogs \ ${DOCKER_REGISTRY}/service/zookeeper:3.4.6-8u101 ### jenkins job zkopspush 构建脚本(一) cat > Dockerfile << 'EOF' FROM ${DOCKER_REGISTRY}/base/centos:7.2.1511-zh-kazoo COPY zkApi.py /opt/zkApi.py WORKDIR /opt ENTRYPOINT ["python"] EOF docker inspect common/zkpush >/dev/null 2>&1 || docker build -t common/zkpush . ### jenkins job zkopspush 构建脚本(二) cat > zkGet.py << 'EOF' #!/usr/bin/env python import sys from zkApi import TzKazooClient zkCli = TzKazooClient(servers=['172.16.200.208:2181']) for node in sys.argv[1:]: print node + ': ' try: print zkCli.get(node)[0] except Exception as e: print e[0] EOF cat > zkPush.py << 'EOF' #!/usr/bin/env python import sys from zkApi import TzKazooClient zkCli = TzKazooClient(servers=['172.16.200.208:2181']) zkCli.push(sys.argv[1], top_path=sys.argv[2]) EOF docker run --rm -v $WORKSPACE:/opt common/zkpush zkPush.py com com docker run --rm -v $WORKSPACE:/opt common/zkpush zkPush.py instances instances ### zkApi.py import kazoo.handlers from kazoo.client import KazooClient import os import re import time import sys reload(sys) sys.setdefaultencoding('utf-8') class ZkApiException(Exception): pass class TzKazooClient(KazooClient): def __init__(self, servers=['127.0.0.1:2181'], timeout=3): for server in servers: super(TzKazooClient, self).__init__(server, timeout) try: self.start(timeout) bool = True except kazoo.handlers.threading.TimeoutError as e: bool = False continue break if not bool: self.__error('The zookeeper connection failed!') def __create(self, path, value): value = value.strip() try: print 'set %s %s' % (path, value) self.set(path, value) except kazoo.exceptions.NoNodeError as e: print 'create %s %s' % (path, value) self.create(path, value, makepath=True) def push(self, local_dir, top_path='/', with_local_path=False): try: for root, dirs, files in os.walk(local_dir, onerror=self.__error): for name in files: file = os.path.join(root, name) f = open(file) content = f.read() f.close() if not with_local_path: zk_path = '/' + top_path.strip('/') + '/' + file[re.match(local_dir, file).end():].strip('/') else: zk_path = '/' + top_path.strip('/') + '/' + file.strip('/') print zk_path self.__create(zk_path, content) except Exception as e: self.__error(e) def pull(self, local_dir='/tmp', top_path='/'): top_path = '/' + top_path.strip('/') childrens = self.get_children(top_path) if childrens == []: value = self.get(top_path)[0] if value == '': try: os.makedirs(local_dir + top_path) except OSError: pass else: f = open(local_dir + top_path, 'wb') f.write(value) f.close() else: try: os.makedirs(local_dir + top_path) except OSError: pass for children_path in childrens: self.pull(local_dir, top_path + '/' + children_path) def clean(self, top_path, match=None, backup=True): try: if not match: if top_path.strip('/') == '': self.__error('Can not remove the root of all directory!') for children in self.get_children(top_path): zk_path = '/' + top_path.strip('/') + '/' + children self.clean_path(zk_path, backup) else: for children in self.get_children(top_path): if re.match(r'%s' % match, children): zk_path = '/' + top_path.strip('/') + '/' + children self.clean_path(zk_path, backup) except Exception as e: self.__error(e) def clean_path(self, path, backup): if backup and not re.match('backup', path.strip('/')): print 'backup %s' % path self.backup(path) print 'delete %s' % path self.delete(path, recursive=True) def backup(self, top_path, mark=None): try: if not mark: mark = time.strftime('%Y-%m-%d-%H:%M:%S',time.localtime(time.time())) if self.get_children(top_path) == []: content = self.get(top_path)[0] zk_path = '/backup/' + mark + '/' + top_path.strip('/') self.__create(zk_path, content) else: for children in self.get_children(top_path): if children == 'backup': continue children_path = '/' + top_path.strip('/') + '/' + children.strip('/') self.backup(children_path, mark) content = self.get(children_path)[0] zk_path = '/backup/' + mark + children_path self.set(zk_path, content) except Exception as e: self.__error(e) def clean_backup(self): try: self.delete('/backup', recursive=True) except Exception as e: self.__error(e) def __error(self, err): raise ZkApiException(err) if __name__ == '__main__': ''' zkCli = TzKazooClient(servers=['127.0.0.1:2181'], timeout=3) ''' pass ### 封装在基础镜像中 cat /opt/bin/zkGet.py #!/usr/bin/env python # -*- coding: utf-8 -*- import sys from kazoo.client import KazooClient zkCli = KazooClient(hosts='%s' % sys.argv[1], timeout=10, read_only=True) zkCli.start() f = open(sys.argv[3], 'wb') f.write(zkCli.get(path='%s' % sys.argv[2])[0]) f.close() zkCli.stop()