企业级rancher搭建Kubernetes(采用rancher管理平台搭建k8s)

一、简介

Rancher简介

来源官方:https://www.cnrancher.com/

       Rancher是一个开源的企业级容器管理平台。通过Rancher,企业再也不必自己使用一系列的开源软件去从头搭建容器服务平台。Rancher提供了在生产环境中使用的管理Docker和Kubernetes的全栈化容器部署与管理平台。

Rancher由以下四个部分组成:

1.1、基础设施编排

Rancher可以使用任何公有云或者私有云的Linux主机资源。Linux主机可以是虚拟机,也可以是物理机。Rancher仅需要主机有CPU,内存,本地磁盘和网络资源。从Rancher的角度来说,一台云厂商提供的云主机和一台自己的物理机是一样的。

     Rancher为运行容器化的应用实现了一层灵活的基础设施服务。Rancher的基础设施服务包括网络, 存储, 负载均衡, DNS和安全模块。Rancher的基础设施服务也是通过容器部署的,所以同样Rancher的基础设施服务可以运行在任何Linux主机上。

1.2、容器编排与调度

很多用户都会选择使用容器编排调度框架来运行容器化应用。Rancher包含了当前全部主流的编排调度引擎,例如Docker Swarm, Kubernetes, 和Mesos。同一个用户可以创建Swarm或者Kubernetes集群。并且可以使用原生的Swarm或者Kubernetes工具管理应用。

除了Swarm,Kubernetes和Mesos之外,Rancher还支持自己的Cattle容器编排调度引擎。Cattle被广泛用于编排Rancher自己的基础设施服务以及用于Swarm集群,Kubernetes集群和Mesos集群的配置,管理与升级。

1.3、应用商店

Rancher的用户可以在应用商店里一键部署由多个容器组成的应用。用户可以管理这个部署的应用,并且可以在这个应用有新的可用版本时进行自动化的升级。Rancher提供了一个由Rancher社区维护的应用商店,其中包括了一系列的流行应用。Rancher的用户也可以创建自己的私有应用商店。

1.4、企业级权限管理

         Rancher支持灵活的插件式的用户认证。支持Active Directory,LDAP, Github等 认证方式。 Rancher支持在环境级别的基于角色的访问控制 (RBAC),可以通过角色来配置某个用户或者用户组对开发环境或者生产环境的访问权限。

下图展示了Rancher的主要组件和功能:

1.png

Kubernetes简介

1.1 基础概念

Kubernetes(通常写成“k8s”)Kubernetes是Google开源的容器集群管理系统。其设计目标是在主机集群之间提供一个能够自动化部署、可拓展、应用容器可运营的平台。Kubernetes通常结合docker容器工具工作,并且整合多个运行着docker容器的主机集群,Kubernetes不仅仅支持Docker,还支持Rocket,这是另一种容器技术。

功能特性:

  • 自动化容器部署与复制

  • 随时扩展或收缩容器规模

  • 组织容器成组,提供容器间的负载均衡

  • 快速更新及回滚容器版本

  • 提供弹性伸缩,如果某个容器失效就进行替换

1.2 架构图

2.png

1.3 组件

1.3.1 Master

Master节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd

  • APIServer:APIServer负责对外提供RESTful的Kubernetes API服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer处理后再提交给etcd。如架构图中所示,kubectl(Kubernetes提供的客户端工具,该工具内部就是对Kubernetes API的调用)是直接和APIServer交互的。

  • schedule:scheduler的职责很明确,就是负责调度pod到合适的Node上。如果把scheduler看成一个黑匣子,那么它的输入是pod和由多个Node组成的列表,输出是Pod和一个Node的绑定,即将这个pod部署到这个Node上。Kubernetes目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。

  • controller manager:如果说APIServer做的是“前台”的工作的话,那controller manager就是负责“后台”的。每个资源一般都对应有一个控制器,而controller manager就是负责管理这些控制器的。比如我们通过APIServer创建一个pod,当这个pod创建成功后,APIServer的任务就算完成了。而后面保证Pod的状态始终和我们预期的一样的重任就由controller manager去保证了。

  • etcd:etcd是一个高可用的键值存储系统,Kubernetes使用它来存储各个资源的状态,从而实现了Restful的API。

1.3.2 Node

每个Node节点主要由三个模块组成:kubelet、kube-proxy、runtime。

 runtime指的是容器运行环境,目前Kubernetes支持docker和rkt两种容器。

  • kube-proxy:该模块实现了Kubernetes中的服务发现和反向代理功能。反向代理方面:kube-proxy支持TCP和UDP连接转发,默认基于Round Robin算法将客户端流量转发到与service对应的一组后端pod。服务发现方面,kube-proxy使用etcd的watch机制,监控集群中service和endpoint对象数据的动态变化,并且维护一个service到endpoint的映射关系,从而保证了后端pod的IP变化不会对访问者造成影响。另外kube-proxy还支持session affinity。

  • kubelet:Kubelet是Master在每个Node节点上面的agent,是Node节点上面最重要的模块,它负责维护和管理该Node上面的所有容器,但是如果容器不是通过Kubernetes创建的,它并不会管理。本质上,它负责使Pod得运行状态与期望的状态一致。

1.3.3 Pod

      Pod是k8s进行资源调度的最小单位,每个Pod中运行着一个或多个密切相关的业务容器,这些业务容器共享这个Pause容器的IP和Volume,我们以这个不易死亡的Pause容器作为Pod的根容器,以它的状态表示整个容器组的状态。一个Pod一旦被创建就会放到Etcd中存储,然后由Master调度到一个Node绑定,由这个Node上的Kubelet进行实例化。

每个Pod会被分配一个单独的Pod IP,Pod IP + ContainerPort 组成了一个Endpoint。

1.3.4 Service

      Service其功能使应用暴露,Pods 是有生命周期的,也有独立的 IP 地址,随着 Pods 的创建与销毁,一个必不可少的工作就是保证各个应用能够感知这种变化。这就要提到 Service 了,Service 是 YAML 或 JSON 定义的由 Pods 通过某种策略的逻辑组合。更重要的是,Pods 的独立 IP 需要通过 Service 暴露到网络中。

二、准备工作

2.1、系统环境

    
    
    

下面两个节点都要配置

2.2、检查hosts--配置后检查是否能解析外网

192.168.56.129 master

192.168.56.130 slave1

2.3、暂时关闭防火墙和seLinux

2.4、开启IPV4转发

在/etc/sysctl.conf新添加如下参数

net.ipv4.ip_forward = 1

net.ipv4.ip_forward_use_pmtu = 0

生效命令:

[root@master ~]# sysctl -p

查看

[root@master ~]# sysctl -a|grep "ip_forward"

3.png

2.5、关闭Swap交换分区

2.6、安装Docker1.12.6版本

什么版本的Docker才能适配Rancher和Kubernetes

请参考:http://rancher.com/docs/rancher/v1.6/zh/hosts/#docker

4.png

1)执行命令:

[root@master ~]# mkdir -p ~/_src

[root@master ~]# cd ~/_src/

[root@master _src]# wget http://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-selinux-1.12.6-1.el7.centos.noarch.rpm

[root@master _src]# wget http://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-1.12.6-1.el7.centos.x86_64.rpm

[root@master _src]# wget http://yum.dockerproject.org/repo/main/centos/7/Packages/docker-engine-debuginfo-1.12.6-1.el7.centos.x86_64.rpm

安装

[root@master _src]# yum localinstall -y docker-engine-selinux-1.12.6-1.el7.centos.noarch.rpm docker-engine-1.12.6-1.el7.centos.x86_64.rpm docker-engine-debuginfo-1.12.6-1.el7.centos.x86_64.rpm

5.png

2)启动

[root@master ~]# systemctl enable docker

[root@master ~]# systemctl start docker

3)查看版本

[root@master ~]# docker version

6.png

2.7、设置Docker镜像加速

此时如果用docker pull命令下载镜像,本地会连接hub.docker.com网站去下载,耗时较长,因此我们可以设置docker镜像加速,使得本地连接去国内镜像仓库下载,镜像加速的设置有很多种,本章以阿里云的设置为例,步骤如下:

1)创建目录:

[root@master ~]# mkdir /etc/docker

2)设置镜像仓库地址:

tee /etc/docker/daemon.json <<-'EOF'{  "registry-mirrors": ["https://xwx6wxd1.mirror.aliyuncs.com"] }EOF

3)重新加载配置:

[root@master ~]# systemctl daemon-reload

4)重启服务

[root@master ~]# systemctl restart docker.service

备注:slave1节点操作一致

三、安装rancher

官方安装文档:https://www.cnrancher.com/docs/rancher/v2.x/cn/overview/

3.1、在master机器执行以下命令,即可安装rancher:

[root@master ~]# docker run -d --restart always --name rancher-server -p 8080:8080 rancher/server:v1.6.11-rc3 && docker logs -f rancher-server

报错如下:

7.png

参考地址:https://blog.csdn.net/shida_csdn/article/details/79376761

[root@master ~]# pkill docker                         #终止进程

[root@master ~]# iptables -t nat -F                 #清空nat表的所有链

[root@master ~]# ifconfig docker0 down        #停止docker默认网桥

[root@master ~]# brctl delbr docker0             #删除网桥

[root@master ~]# systemctl restart docker       #重启docker

查看即可

3.2、在浏览器访问http://192.168.56.129:8080,可以看到初始页面,在页面的右下角选择“简体中文”后,页面如下所示:

8.png

至此,rancher安装成功,接下来就是kubernetes的搭建工作。

3.3、配置环境模板

1)、环境配置---“Default”选择“环境管理”,如图

9.png

2)添加环境模块

10.png

输入项目名:k8s-TempLate

11.png

如下图,下拉菜单只有一个选择,请选中

12.png

13.png

上图四个红框填入的内容如下表所示:

  
  
  
  
  

3)将页面拖动到最底部,点击“设置”按钮,如下图:

14.png

4)再将页面拖动到最底部,点击“创建”按钮,如下图:

15.png

这样我们就完成了环境模板的配置,这里面的参数帮助rancher寻找国内的镜像仓库,从而避免了无法从google仓库下载镜像的问题,在以往这个问题是通过上网来解决的;

3.4、创建Kubernetes

1)点击“创建环境”按钮,如下图红框:

16.png

2)在创建环境的页面中,输入新的环境的名称:master-k8s,选择我们刚才创建的环境模板,在点击底部的“创建”按钮,如下图:

17.png

3)如下图红框所示,在左上角位置选择刚刚创建的环境,可以看到目前环境已经OK,正在等待node的加入:

18.png

至此,Kubernetes的master已经搭建完毕!!!!

3.5、添加节点——将机器加入到K8S环境

1)master机器的IP是192.168.56.129,所以在浏览器打开地址192.168.56.129:8080,左上角选择新增的环境,可以看到如下图的页面,点击红框中的“添加主机”:

19.png

2)如下图,在页面上确认红框中的IP地址是不是你的master机器对外暴露的地址(多网卡的机器要关注),确认无误后点击“保存” .

20.png

3)如下图,点击红框按钮,会将此按钮左侧的文本信息复制下来:

21.png

4)登录slave1节点,执行上面复制下来的命令,该命令会先下载docker镜像,然后启动容器去加入到K8S环境,此时再去刷新管理页面,见到如下图所示,已经感知到机器的加入,开始接下来的一系列操作,此时请耐心等待(等待时间比较,喝杯茶再回来): 

22.png

有可能节点获取不到东西,建议检查一下安全规则(防火墙、转发、selinux),配置后重启即可

23.png

5)节点加入成功后,页面如下图所示,点击红框中的按钮就进入了K8S的dashboard: 

24.png

报Service unavailable错误:等待十分钟左右即可,启动接口有点慢

下文安装kubectl装好之后,在控制台用kubectl describe命令查看dashbroad的pod和service的执行进度,查看错误日志。

至此,我们已经完成了节点机器加入K8S环境的操作,接下来我们快速体验在K8S环境创建Pod和Service的操作;

体验K8S环境

1)创建一个文件tomcat.yaml,内容如下:

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

name: tomcat001

spec:

replicas: 1

template:

metadata:

labels:

name: tomcat001

spec:

containers:

- name: tomcat001

image: tomcat:7.0.82-jre7

tty: true

ports:

- containerPort: 8080

2)在dashboard页面上传这个tomcat.yaml文件,操作如下图所示: 

25.png

3)等镜像下载和容器创建成功后,在dashboard的部署页面可以看到tomcat001的部署情况,如下图

26.png

4)创建一个文件tomcat-svc.yaml,内容如下:

apiVersion: v1

kind: Service

metadata: 

   name: tomcat001

spec:  

   type: NodePort  

   ports:       

          - port: 8080         

         nodePort: 30018 

  selector:    

      name: tomcat001

5)如同上个步骤,上传后在dashboard的“服务”页面查看

27.png

6)通过业务节点slave1的IP地址访问

http://192.168.56.130:30018/

28.png

3.5、安装kubectl工具

1)下载kubectl工具

有两种下载方式,您可以选择其中任意一种:

(1)在我的GitHub下载,地址是:https://github.com/zq2599/blog_demos/blob/master/k8s_tools/kubectl/linux/kubectl.zip,在这个页面点击”download”按钮即可下载,下载后记得解压;

 (2)在linux机器上执行以下命令下载:

# curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl

2)设置工具

(1)kubectl文件上传到linux机器后,授权

# chmod +x kubectl

(2)将kubectl移动到可以全局访问的目录下

# mv ./kubectl /usr/local/bin/

(3)测试,任意目录执行一下语句

29.png

工具已经准备好,接下来我们把配置做好,使得kubectl可以连接到K8S上执行命令;

3)配置参数

(1)在rancher的管理页面上,点击下图红框1中的”CLI”,在出现的页面中点击红框2中的”生成配置“:

30.png

(2)如下图,点击红框中的”复制到剪切板“,将按钮上方的配置信息复制下来:

31.png

(3)创建文件,复制上面的参数

# mkdir ~/.kub

32.png

(4)查看进程服务

# kubectl get service -a -o wide --all-namespaces

33.png

34.png

到此,部署完毕!!!!

问题来了,每次访问rancher直接进入了管理平台,一点安全性可言都没有,下来我们来设置“系统管理”

 

四、账号安全设置

4.1、日志审计

只有管理员用户有权限访问审计日志。审计日志在系统管理->审计日志。

35.png

Rancher的审计日志是不同事件类型的集合:

(1)任何带有前缀api的事件是API的一次调用。事件类型将记录API操作,谁执行的操作以及API调用的方式(即通过UI,通过API密钥)。

(2)何没有带api前缀的事件都是Rancher Server做的事情。例如,在协调服务的容器期间,在实例创建时会产生一个instance.create事件。

4.2、账号设置

36.png

编辑“环境管理”---master-k8s

37.png

4.3、访问控制

用户在访问你的Rancher服务之前,需要进行身份认证。同时,只有拥有合法的API密钥才能使用Rancher API。

38.png

(1)活动目录

选择活动目录图标。 如果你想要通过TLS来使用活动目录,请确保你已经使用了相应的证书来启动Rancher Server。填写相关信息后,通过点击身份认证进行认证校验。 当活动目录认证成功后,你将自动以已认证的用户名身份登录。并且把你的账号设置为了管理员权限。

(2)Azure AD 验证

选择Azure AD图标。 填写相应信息并单击Azure认证进行认证校验。 当认证成功后,你将自动以已认证的用户名身份登录。并且把你的账号设置为了管理员权限。

(3)GitHub

选择GitHub图标,并按照用户界面中的说明将Rancher注册为GitHub应用程序。 点击使用GitHub进行身份认证后,当认证成功后,你将自动以已认证的Github账号登录。并且把你的账号设置为了管理员权限。

(4)local

选择本地图标。 通过提供登录用户名,全名和密码来创建管理员用户。 点击启用本地认证来启用本地身份认证。 通过单击此按钮,管理员用户将被创建并保存在数据库中。这时你将自动用刚刚创建的管理员帐户登录到Rancher服务。

39.png

(5)OpenLDAP

填写对应信息后,通过点击身份认证进行认证校验。当OpenLDAP认证成功后,你将自动以已认证的用户名身份登录。并且把你的账号设置为了管理员权限。

(6)Shibboleth

选择Shibboleth图标。 填写Shibboleth帐户的配置信息,点击保存保存信息,然后点击测试来测试访问控制是否正常工作。

在使用Shibboleth时,你应该注意一些已知的问题:

(1)不支持搜索或查找功能。 在添加用户时,请确保输入的用户ID是准确的,这样才能保证用户被添加成功。

(2)当添加用户到一个环境时, 不支持组ID,除非管理员是该组的成员之一。

功能模块比较复杂,后续补充。。。。。

转载于:https://www.cnblogs.com/duwamish/p/10950766.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248846.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[工具]java_sublime的快速使用

目录 使用 : 怎么运行: 调整字体: 使用 : 新建--->写好代码后-->另存为尾缀是.java的文件 怎么运行: 在你另存为的目录下cmd调用控制台输入dos指令--->执行javac 文件名.java(有.java尾缀)(编译为.class文件)--->java 文件名(没有.class尾缀设计者认为执行的是…

基于SOA的银行系统架构

Part-1 【简述】 1.通过引入面向服务架构&#xff08;SOA&#xff09;&#xff0c;企业服务总线&#xff08;ESB&#xff09;&#xff0c;适配器&#xff08;Adapter&#xff09;及面向构件等技术&#xff0c;尝试打造一个统一业务流程服务平台&#xff0c;实现面向流程的服务…

一次前后端分离的实践

前后端分离该如何做? 这个问题&#xff0c;不同的技术人员&#xff0c;由于所处的岗位不一样&#xff0c;给出的答案都不一样。 前后端分离的问题&#xff0c;不仅仅是技术上的选型问题&#xff0c;还涉及到整个团队在认知、职责、流程上面重新定义的问题&#xff0c;这也是为…

C++解析-外传篇(1):异常处理深度解析

0.目录 1.异常的最终处理 2.结束函数terminate() 3.小结 1.异常的最终处理 问题&#xff1a; 如果在main函数中抛出异常会发生什么&#xff1f; 如果异常不处理&#xff0c;最后会传到哪里&#xff1f; 下面的代码的输出什么&#xff1f; 示例——异常的最终处理&#xff1f;&a…

springboot快速集成swagger

今天技术总监说&#xff1a;小明&#xff0c;我们本次3.0改造&#xff0c;使用swagger2.0作为前后端分离的接口规范&#xff0c;它可以一键生成前后端的API,一劳永逸……小明&#xff1a;&#xff1f;&#xff1f;&#xff1f; Spring Boot 框架是目前非常流行的微服务框架&…

php curl处理get和post请求

CURL 是一个利用URL语法规定来传输文件和数据的工具&#xff0c;支持很多协议&#xff0c;如HTTP、FTP、TELNET等。最爽的是&#xff0c;PHP也支持 CURL 库。使用PHP的CURL 库可以简单和有效地去抓网页。你只需要运行一个脚本&#xff0c;然后分析一下你所抓取的网页&#xff0…

前端攻略系列(二) - 前端各种面试题

幸运且光荣的被老大安排了一个任务 - “去整理些前端面试题”。年前确实不是招人的好时候&#xff0c;所以我们前端团队经过了超负荷的运转&#xff0c;终于坚持过了春节。春节以后就开始招人啦&#xff0c;这套题考察的目标就是基础基础再基础&#xff0c;嘿嘿。 事先声明&…

html 初识

一、web请求流程模拟 python编写的简易服务器应用程序 import socketserversocket.socket() ip_port (127.0.0.1,8080) server.bind(ip_port) server.listen()while 1:conn, addr server.accept()from_browser_msgconn.recv(1024)print(from_browser_msg)conn.send(bHTTP/1.1 …

WEB文件上传之JQuery ajaxfileupload插件使用(二)

1.JQuery ajaxfileupload插件使用准备 下载地址&#xff1a; http://www.phpletter.com/DOWNLOAD/ 2.原理分析 ajaxfileupload也是利用iframe实现无刷新异步提交&#xff0c;与我的上一篇文章&#xff08;WEB文件上传之apache common upload使用&#xff08;一&#xff09;&…

Navicat安装激活

有条件的同学麻烦不要使用下面的激活步骤&#xff0c;仅供个人学习使用 。。。。。。 。。。。。。 。。。。。。 。。。。。。 一、去官网下载最新Navicat软件https://www.navicat.com.cn/download/navicat-premium 二、去下载激活脚本https://github.com/DoubleLabyrinth/nav…

WEB文件上传之apache common upload使用(一)

文件上传一个经常用到的功能&#xff0c;它有许多中实现的方案。 页面表单 RFC1897规范 http协议上传 页面控件(flash/html5/activeX/applet) RFC1897规范 http协议上传 页面控件(flash/html5/activeX/applet) 自定义数据规范 http协议上传 页面控件(flash/html5/act…

前端CSS学习笔记

一 CSS介绍 层叠样式表(英文全称&#xff1a;Cascading Style Sheets)是一种用来表现HTML&#xff08;超文本标记语言&#xff09;或XML&#xff08;标准通用标记语言的一个子集&#xff09;等文件样式的计算机语言。CSS不仅可以静态地修饰网页&#xff0c;还可以配合各种脚本语…

Java爬取并下载酷狗音乐

本文方法及代码仅供学习&#xff0c;仅供学习。 案例&#xff1a; 下载酷狗TOP500歌曲&#xff0c;代码用到的代码库包含&#xff1a;Jsoup、HttpClient、fastJson等。 正文&#xff1a; 1、分析是否可以获取到TOP500歌单 打开酷狗首页&#xff0c;查看TOP500&#xff0c;发现存…

Webpack/Vue-cli两种方式加载markdown文件并实现代码高亮

准备的资源&#xff1a; highlight.js &#xff1a; 实现代码高亮&#xff0c;通过npm install highlight.js -D安装 vue-markdown-loader&#xff1a;解析md文件的必备loader&#xff0c;通过npm install vue-markdown-loader -D安装 下面我们分两个场景来说明一下md文件的…

新浪微博第三方登陆重定向错误23123

新浪微博第三方登陆重定向错误23123 2019年06月02日 13:49:43 温室花朵 阅读数&#xff1a;2更多 个人分类&#xff1a; 第三方微博登陆21323编辑当我们使用微博第三方登陆的时候&#xff0c;发现登陆出错了&#xff0c;错误码为&#xff1a;21323&#xff0c;解决方案如下&…

Utility Manager 的一些百度不了的操作

一进来是不是这样的&#xff01; 那突然出了点问题&#xff0c;咋办呢&#xff01; 就像这样子的&#xff0c; 恢复默认布局就OK啦&#xff01;哈哈哈&#xff0c;太聪明啦&#xff0c;但是百度了好长时间还是找不到啊&#xff0c;怎么办呐&#xff0c;烦死啦&#xff01; 其实…

记录一次内网渗透试验

0x00 前言 目标&#xff1a;给了一个目标机ip&#xff0c;要求得到该服务器权限&#xff0c;并通过该ip渗透至内网控制内网的两台服务器 攻击机&#xff1a;kali (192.168.31.51) 目标机&#xff1a;windows 2003 (192.168.31.196) 0x01 信息收集 nmap端口探测 御剑后台扫描 …

2018-2019 1 20165203 实验五 通用协议设计

2018-2019 1 20165203 实验五 通用协议设计 OpenSSL学习 定义&#xff1a;OpenSSL是为网络通信提供安全及数据完整性的一种安全协议&#xff0c;囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议&#xff0c;并提供了丰富的应用程序供测试或其它目的使用。基本功…

弄懂webpack,只要看这一片就够了(文末有福利)

什么是webpack ​ webpack是什么&#xff0c;官网中是这么说的。 ​ 本质上&#xff0c;webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时&#xff0c;它会递归地构建一个依赖关系图(dependency graph)&#xff0c;其中包…

beta冲刺总结那周余嘉熊掌将得队

作业格式 课程名称&#xff1a;软件工程1916|W&#xff08;福州大学&#xff09;作业要求&#xff1a;项目Beta冲刺团队名称&#xff1a; 那周余嘉熊掌将得队作业目标&#xff1a;beta冲刺总结队员学号队员姓名博客地址备注221600131Jaminhttps://www.cnblogs.com/JaminWu/队长…