# 构建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()
- 第一章 Docker核心技术(一)
- 第一章 Docker核心技术(二)
- 第一章 Docker核心技术(三)
- 第一章 Docker核心技术(四)
- 第二章 Docker 入门
- 第三章 使用docker镜像
- 第四章 实战应用使用Docker构建LNMP环境 (一)
- 第四章 实战应用使用Docker构建LNMP环境 (二)
- 第四章 实战应用使用Docker构建LNMP环境 (三)
- 第五章 构建企业级Harbor-Registry
- 第六章 构建Docker应用发布系统(一)
- 第六章 构建Docker应用发布系统(二)
- 第六章 构建Docker应用发布系统(三)
- 第六章 构建Docker应用发布系统(四)