正在加载..... 发表于 2021-9-4 11:24

申请会员ID:NewSea【申请通过】

1、申 请 I D :NewSea
2、个人邮箱:zbljz98@live.com
3、K8S二开项目,实现了自动部署django代码并提供dns地址查看项目运行,同时支持k8s集群的自动部署,支持高可用集群的部署
之前投递过一次,但帖子看不到,不知道是不是没符合发帖要求,重新发一次,并且仔细整理代码部分

1. 通过对ansible进行二开,适配了日志存储功能,以及调用。
class ResultCallback(CallbackBase):
    def __init__(self, taskid=None, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self.result_ok = {}
      self.result_unreachable = {}
      self.result_failed = {}
      self.result_skip = {}
      self.mongo = lmongo(taskid)

    def __del__(self):
      self.mongo.close()

    def v2_runner_on_ok(self, result):
      data = {'hostname': result._host.get_name(), 'runstatus': 'success', 'result': result._result}
      self.mongo.add(data)

    def v2_runner_on_unreachable(self, result):
      data = {'hostname': result._host.get_name(), 'runstatus': 'unreachable', 'result': result._result}
      self.mongo.add(data)

    def v2_runner_on_failed(self, result, ignore_errors=False):
      data = {'hostname': result._host.get_name(), 'runstatus': 'failed', 'result': result._result}
      self.mongo.add(data)

    def v2_runner_on_skipped(self, result):
      data = {'hostname': result._host.get_name(), 'runstatus': 'skipped', 'result': result._result}
      self.mongo.add(data)
此代码将ansible日志部分保存到数据库中
class RunAnsible:
    def __init__(self, linventory=None, taskid=None, nfsstore=None, pbname=None, ):
      self.taskid = taskid
      self.nfsstore = nfsstore
      self._linventory = linventory
      self._pbname = pbname
      self.loader = DataLoader()
      self.callback = ResultCallback(self.taskid)
      self.inventory = InventoryManager(loader=self.loader)
      self.variable = VariableManager(loader=self.loader, inventory=self.inventory)
      self.context = ImmutableDict(connection='smart', module_path=None, forks=5, verbosity=0,
                                     become=None, start_at_task=None, remote_user='root', listhosts=None,
                                     listtasks=None, listtags=None, diff=False, ask_pass=None, check=False,
                                     become_method=None, become_user=None, syntax=None, ask_sudo_pass=None,
                                     ssh_common_args=None, ssh_extra_args=None, sudo=None, sudo_user=None,
                                     become_ask_pass=None)
      for a, b in self._linventory.items():
            self.inventory.add_group(a)
            for i in b:
                self.inventory.add_host(host=i, group=a, port=22)
                self.inventory.add_host(group='all', host=i, port=22)
                self.variable.set_host_variable(host=i, varname='nfsip', value=self.nfsstore['ip'])
                self.variable.set_host_variable(host=i, varname='nfspath', value=self.nfsstore['path'])

    def gethost(self):
      return self.inventory.get_groups_dict()

    def run(self):
      inv = self.inventory
      context.CLIARGS = self.context
      passwords = {}
      if self._pbname == None:
            self._pbname = 'kubernetes.yml'
      playbook = PlaybookExecutor(
            playbooks=,
            inventory=inv,
            variable_manager=self.variable,
            loader=self.loader,
            passwords=passwords
      )
      playbook._tqm._stdout_callback = self.callback
      playbook.run()
      return 'success'
此部分代码实现对ansible进行调度,其中几个方法实现了从数据库获取节点信息,用于过滤后传递参数执行playbook

2. playbook脚本,实现高可用k8s集群自动部署
listen k8s-cluster1 {{ansible_default_ipv4.address}}:6443
    mode      tcp
    balance      roundrobin
{% for host in groups["k8s-master"] %}
    server      k8s{{ loop.index }} {{hostvars.ansible_default_ipv4.address}}:6443 check inter 2000 fall 3
{% endfor %}
此段代码位jinja2模板代码,用于自动生成haproxy配置文件,负载k8s主节点访问请求
这里不展示playbook中tasks部分代码,因为过于简单,只要掌握linux命令,之后参照ansible-doc即可编写,没有难度

3. 项目自动拉取、集成、部署
代码部署部分也是采用ansible实现的,逻辑上通过git拉取代码后,通过jinja2生成Dockerfile打包新的容器,之后上传到harbor私有镜像仓库中,最后就是jinja2生成yaml文件,部署项目即可,dns地址为随机地址。
ingressdomaindata = ['a', 'b', 'c', 'd', 'e', 'f', 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 'g', 'h', 'j', 'k', 'l', 'z',
                           'x', 'c', 'v', 'b', 'n', 'm']
      ingressdomainhead = ''
      for i in range(7):
            ingressdomainhead += str(random.choice(ingressdomaindata))
      k8sserver = k8scluster.objects.filter(cluster_id=server.cluster_id)
随机生成域名
# 生成域名
      ingressdomain = ingressdomainhead + '.' + server.ingressdomain
      logger.info('choice server number: {}, domain name: {}'.format(server.cluster_id, ingressdomain))
      ptype = protype.objects.get(id=job.jobtype)
      try:
            imgurl = ptype.proimg.split('https://')
      except:
            imgurl = ptype.proimg.split('http://')
      ansible1 = jobAnsible(asservers, job.jobname, ingressdomain, job.joburl, job.username, ptype.typename,
                              imgurl)
      ansible1.run()
这里拼接完整的域名信息,之后传递ansible任务给之前创建的ansible
这里创建ansible的对象名称是jobAnsible,jobAnsible和runAnsible的区别仅是默认参数不通,因为在项目中不通的模块内

4. 通过nmap扫描网段活动ip地址,之后传递ip到新的方法进行用户名以及密码探测
nm = nmap.PortScanner()
    data = nm.scan(hosts=network, arguments=arguments)
    result_compute = nm.all_hosts()
    result_nminfo = {}
    users = userinfo.objects.all()
    result_user = {}
    result_userpass = {}
    for ip in result_compute:
      try:
            macinfo = data['scan']['addresses']['mac']
      except Exception as e:
            macinfo = ''
            logger.warning('ip: {}, get macinfo err: {}'.format(ip, e))
      try:
            typeinfo = data['scan']['vendor']
      except Exception as e:
            typeinfo = ''
            logger.warning('ip: {}, get machine type err: {}'.format(ip, e))
      result_nminfo =
    if result_nminfo == {}:
      logger.error('系统运行权限存在问题,请使用root权限')
此段代码,调用nmap进行扫描,并过滤返回数据数据得到ip地址
用户和密码部分没什么意思,主要先进行root账户测试,之后读取其他用户测试密码,如果root账户可以登录,则终止探测,主要是暴力,ssh登录使用paramiko实现

5. 项目比较重要的基础部件celery,因为项目大部分操作时间很长,部署代码大概是几分钟不等,部署集群大概2小时,所以必须采用子任务后台执行
@shared_task(bind=True)
def scanDevice(self, network=None, arguments=None)

@shared_task(bind=True)
def ansiblecluster(self, clusterid=None)
其中scanDevice函数部分代码已经在上面介绍,ansiblecluster功能仅仅是从数据库读取用户部署的任务,之后执行ansible任务

6、其他小细节
项目为了避免ansible在执行过程中也有其他子任务操作k8s集群,所以添加了一个锁,这个锁在redis实现的,为了避免子任务意外终止,成为死锁
ansible的日志输出到mongodb中,因为mongodb作为文档类型的数据库,在处理日志方面,比mysql好操作,直接无脑写入即可,不需要像mysql在意啥类别之类的东西
db = self.client
      collection = db
      result['success'] = collection.count_documents({'runstatus': 'success'})
      result['unreachable'] = collection.count_documents({'runstatus': 'unreachable'})
      result['failed'] = collection.count_documents({'runstatus': 'failed'})
      result['skipped'] = collection.count_documents({'runstatus': 'skipped'})
      return result
此代码为将ansible结果写入到mongodb数据库
介绍啥都是华丽呼哨的,只有方便才是王道!!!性能差上k8s做deployment自动伸缩即可

7、项目运行界面,项目肯定不是ppt的东西,已经使用了一段时间了,但最近因为个人原因不在家,所以服务器关掉了

这个是资源展示部分,也是管理端的首页

这个是探测完成后记录的结果

此部分为集群信息,可以查看集群创建日志以及各个节点在k8s集群中扮演的角色

此部分为个人项目代码部署模块,这个是首页,用户可以查看个人部署的项目
项目支持注册用户,但是项目的权限只能访问部署代码模块,管理模块的权限只有是项目部署时创建的超级用户以及通过超级用户授权的用户访问

此部分通过elasticsearch获取容器的日志,项目部署k8s集群的时候,会自动部署普罗米修斯、efk、ingress以及还有其他东东

此部分通过普罗米修斯获取容器资源占用信息

Hmily 发表于 2021-9-6 18:30

I D:NewSea
邮箱:zbljz98@live.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。

NewSea 发表于 2021-9-7 10:58

Hmily 发表于 2021-9-6 18:30
I D:NewSea
邮箱:



感谢通过:lol:lol
页: [1]
查看完整版本: 申请会员ID:NewSea【申请通过】