docker 开始容器

I’ve been lurking around in r/selfhosted for about a year now, spying on the apps that people self-host, and their pretty dashboards full of self-hosted apps. Over time I observed some dissent in the community. There exists a group of people that vehemently reject the use of Docker.

我一直潜伏于r / selfhosted大约一年了,监视着人们自己托管的应用程序以及漂亮的仪表板,里面充满了自托管的应用程序。 随着时间的流逝,我在社区中发现了一些异议。 有一群人强烈拒绝使用Docker。

…what happens if the container is not maintained further? i have no desire to do that. I still prefer to install my dependencies, run the applications via systemd and set up an nginx reverse proxy. i still feel like i can interact with the process. (Reddit)

…如果不进一步维护容器会发生什么? 我不想这样做。 我仍然更喜欢安装我的依赖项,通过systemd运行应用程序,并设置一个nginx反向代理。 我仍然觉得我可以与流程互动。 ( Reddit )

I’m a person who has never really been too fond of Docker. I like having full control of the applications I’m running, their configuration and their storage. With Docker, I’ve always felt like I’ve lost a bit of that control. (Reddit)

我是一个从未真正喜欢过Docker的人。 我喜欢完全控制正在运行的应用程序,它们的配置和存储。 使用Docker,我总是觉得自己失去了一些控制权。 ( Reddit )

Reading those comments made me wonder:

阅读这些评论使我感到奇怪:

Are there others out there who shares the same perspective as them?

还有其他与他们有相同观点的人吗?

In this piece, I outline the journey through which I found Docker and I aim to convince just one person reading this, that Docker is worth learning and using.

在本文中,我概述了找到Docker的过程,我的目的是说服只有一个阅读此书的人Docker是值得学习和使用的。

LEMP-Linux,Nginx,MySQL,Ph 痛苦 (LEMP — Linux, Nginx, MySQL, Phpain)

As performance was absolutely abysmal on the Raspberry Pi 1 Model B in my Octopi cluster, I spent a few months tuning php-fpm for performance and configuring nginx for security. I found that that process almost never works as expected. Raspberry Pi and its OS, Raspbian, differs vastly from others hosting LEMP stacks out there. Therefore, what worked on guides and tutorials are almost guaranteed to not work on my setup without significant modification.

由于我的Octopi集群中的Raspberry Pi 1 Model B的性能绝对糟糕,我花了几个月的时间来调整php-fpm的性能,并配置nginx的安全性。 我发现该过程几乎无法按预期工作。 Raspberry Pi及其操作系统Raspbian与在那里托管LEMP堆栈的其他软件有很大不同。 因此,几乎可以保证在没有进行重大修改的情况下,用于指南和教程的内容就不会在我的设置中起作用。

头痛的来源 (Sources of headache)

  • Missing system dependencies缺少系统依赖性
  • System dependencies with strange Raspbian defaultsRaspbian默认设置与系统的依赖关系
  • Outdated system packages in the Raspbian APT repositoryRaspbian APT存储库中的过时系统包
  • System packages not pre-compiled for the Arm architecture系统软件包未针对Arm架构进行预编译

To make matters worse, even though I commit my configuration files to git, I have had to make live changes on the server nodes to iterate quickly and eventually I lost track of how I broke the site in ways I can only imagine.

更糟的是,即使我将配置文件提交到git,我也必须在服务器节点上进行实时更改以快速迭代,最终我无法以我只能想象的方式来了解如何破坏站点。

That path, almost always ends in a painful full reinstall of the LAMP stack.

该路径几乎总是以痛苦的完全重新安装LAMP堆栈结束。

迁移和更多的Ph 痛苦 (Migration and more Phpain)

A year after I built my first cluster, I built my second, Kraken, comprised of 7 Raspberry Pi 3 Model Bs and I started migrating my Wordpress installation to the new cluster. Armed with my trusty Ansible playbooks, where the installation and configuration tasks were all written in stone as code, I was confident that installation of Wordpress would be a breeze.

建立第一个集群一年后,我建立了第二个集群Kraken ,其中包括7个Raspberry Pi 3 Model B,并且我开始将Wordpress安装迁移到新集群。 与我的信赖Ansible剧本,在安装和配置任务都写在石头上的代码的武装,我确信安装的WordPress的将是轻而易举的事。

Unfortunately, in DevOps, Murphy’s Law always applies:“Anything that can go wrong will go wrong”

不幸的是,在DevOps中,墨菲定律始终适用:“任何可能出错的地方都会出错”

Turns out, what used to work in Octopi did not work in Kraken and I ended up spending 3 full days debugging the playbooks I wrote before I got just php-fpm installed and configured correctly for Wordpress. Interestingly, deploying PHP seems to be a source of pain for many, though especially so for me.

原来,曾经被工作章鱼没有工作在海怪,我最终花3整天调试我写之前,我只是剧本php-fpm安装并正确WordPress的配置。 有趣的是,部署PHP似乎使许多人感到痛苦,尽管对我而言尤其如此。

The problem does not lie in installing PHP itself, but in installing all the PHP extensions that Wordpress requires. To date, there is no definitive list of extensions required and/or recommended by and for Wordpress. The best list I found was an answer on StackExchange posted 8 years ago with 22 extensions.

问题不在于安装PHP本身,而在于安装Wordpress所需的所有PHP扩展。 迄今为止,还没有针对Wordpress所需和/或推荐的扩展的明确列表。 我发现最好的列表是8年前在StackExchange上发布的答案,其中包含22个扩展名

To make matters worse, each PHP extension has its own set of system dependencies, requiring certain versions of Linux libraries or packages to be installed.

更糟糕的是,每个PHP扩展都有其自己的系统依赖关系集 ,需要安装某些版本的Linux库或软件包。

头疼的我 (A slice of my headaches)

To illustrate how annoying it is to manage PHP extensions and their associated system dependencies, I’ll list some PHP extensions and their system dependencies.

为了说明管理PHP扩展及其关联的系统依赖项有多么烦人,我将列出一些PHP扩展及其系统依赖项。

Through all my struggles with PHP, I found this (then) treasure known as Docker and then I thought it was the best invention that mankind has ever came up with.

在与PHP的所有斗争中,我发现了当时称为Docker的宝藏,然后我认为这是人类有史以来最好的发明。

Docker简介 (Introducing Docker)

Docker is a framework that allows containerization of applications.

Docker是一个允许应用程序容器化的框架。

Containerization is the process of bundling the operating system, application, and its configuration and dependencies into a single object called an image, which can be downloaded and run in any environment.

容器化是将操作系统,应用程序及其配置和依赖项捆绑到一个称为映像的对象中的过程该对象可以在任何环境中下载和运行。

Docker in 3 sentences
Docker用3句话

Docker abstracts the operating system away from app deployments, which means that applications that used to work in Octopi will always work regardless of the operating system, given the same CPU architecture.

Docker将操作系统从应用程序部署中抽象出来,这意味着在给定相同的CPU体系结构的情况下 ,过去可以在Octopi中运行的应用程序始终可以运行,而与操作系统无关。

从Dockerfile到容器和堆栈 (From Dockerfiles to Containers and Stacks)

Dockerfiles are text files that fully describe your image. They contain the sequence of commands required to install and configure an application starting from a base image. The base image can be a simple base OS image like debian:buster or any other application image like php:7.2 allowing you to build off the work of others, running additional commands on top of what was already done.

Dockerfile是完全描述您的图像的文本文件。 它们包含从基本映像开始安装和配置应用程序所需的命令序列。 基本映像可以是简单的基本OS映像,例如debian:buster也可以是任何其他应用程序映像,例如php:7.2允许您构建他人的工作,并在已完成的操作之上运行其他命令。

Dockerfiles can optionally also contain several OS-related elements such as specifying folders to be used as mount points for volumes, as well as ports to be exposed.

Dockerfile也可以选择包含几个与OS相关的元素,例如指定要用作卷的安装点的文件夹以及要公开的端口。

Think of Dockerfiles as analogous to class definitions in programming languages.

将Dockerfile视为类似于编程语言中的类定义

These Dockerfiles can be built into an image, where the sequence of commands defined in the Dockerfile are run on the base image, thereby materializing those changes and packaging the result into an image. An image is therefore, an instance of the Dockerfile that it was built from.

这些Dockerfile可以内置映像中 ,其中Dockerfile中定义的命令序列在基础映像上运行,从而实现这些更改并将结果打包到映像中 。 因此,映像是从其生成的Dockerfile的实例。

A Docker image can be seen as analogous to objects instantiated from classes in programming terms.

可以将Docker映像视为类似于以编程术语从类实例化的对象 。

Docker images can be pushed into repositories hosted on registries, the default being Docker Hub, where it can be shared as is with others who wish to install the same application and configure it in the same way.

可以将Docker映像推送到注册表中托管的存储库中 ,默认存储库为Docker Hub ,可以与希望安装相同应用程序并以相同方式配置它的其他用户共享。

When you think of Docker registries, think Github

当您想到Docker注册表时,请考虑Github

Docker images can then be pulled into the machine that will run the application, and subsequently the image can be run as a container, and the application will, in theory, work as it has, on the machine the image was built on.

然后,可以 Docker映像入将运行该应用程序的机器中,然后将该映像作为容器运行,并且从理论上讲,该应用程序将在构建该映像的机器上按原样运行。

A container here, is comparable to the concept of a single copy of your application code, cloned from Github, and run. You can run multiple copies of your code, just as you can run multiple containers of the same image.

这里的容器类似于从Github克隆并运行的应用程序代码的单个副本的概念。 您可以运行代码的多个副本,就像可以运行同一图像的多个容器一样。

Multiple related containers representing different components of a single app can be added into a single docker-compose.yml file that fully describes their runtime configuration. A docker-compose file can contain environment variable values, volume mounts and host-container port mappings.

可以将表示单个应用程序不同组件的多个相关容器添加到一个完整描述其运行时配置docker-compose.yml文件中。 docker-compose文件可以包含环境变量值,卷安装和主机-容器端口映射。

Think of docker-compose files as specifying all the parameters that each function of your application code takes, that uniquely configures the entire application to your usage.

可以将docker-compose文件视为指定应用程序代码的每个功能所采用的所有参数,从而根据您的使用情况唯一配置整个应用程序。

这对我的设置意味着什么 (What this meant for my setup)

  • No longer need to bother myself with installing system dependencies required by PHP extensions不再需要费心安装PHP扩展所需的系统依赖项
  • No need to search for a exhaustive list of PHP extensions required by Wordpress无需搜索Wordpress所需PHP扩展的详尽列表
  • Configuration that is tried and tested can be packaged together with PHP in an image to be installed elsewhere可以将经过尝试和测试的配置与PHP一起打包在一个映像中,以在其他位置安装
  • Machines are more secure with PHP running as a non-root user in an isolated container通过以非root用户身份在隔离的容器中运行PHP,可以提高计算机的安全性
  • Clear separation of static configuration related to the application’s operating environment, and runtime configuration such as passwords and hostnames of other components of the same application与应用程序的操作环境有关的静态配置和运行时配置(例如同一应用程序的其他组件的密码和主机名)之间的清晰区分

What was a mess of installation and configuration steps for php-fpm, nginx and MySQL in my Ansible playbooks, was reduced to defining a docker-compose.yml file and running a single command.

我的Ansible剧本中php-fpmnginxMySQL的安装和配置步骤一团糟,简化为定义docker-compose.yml文件并运行单个命令。

version: '3.1'services:web:image: nginxports:- 8000:80volumes:- wordpress:/var/www/html- /home/pi/wordpress/nginx.conf:/etc/nginx/nginx.confphp:image: wordpress:5.4.2-php7.2-fpm-alpinerestart: alwaysenvironment:WORDPRESS_DB_HOST: dbWORDPRESS_DB_USER: wordpressWORDPRESS_DB_PASSWORD: myverysecurepasswordWORDPRESS_DB_NAME: wordpressvolumes:- wordpress:/var/www/html- /home/pi/wordpress/php-fpm.conf:/usr/local/etc/php-fpm.d/zzz-kraken.confdb:image: mysql:5.7restart: alwaysenvironment:MYSQL_DATABASE: wordpressMYSQL_USER: wordpressMYSQL_PASSWORD: myverysecurepasswordMYSQL_RANDOM_ROOT_PASSWORD: '1'volumes:- db:/var/lib/mysqlvolumes:wordpress:db:

$ docker-compose up -d

$ docker-compose up -d

Deploying my Wordpress stack in 1 command

在1个命令中部署Wordpress堆栈

解密docker-compose文件 (Deciphering the docker-compose file)

  1. I defined 3 services, web, php, and db.

    我定义了3个服务, webphpdb

  2. php shares the wordpress named volume with web, where serving static assets is left to nginx while php code is handled by php-fpm.

    phpweb共享一个名为volume的wordpress ,其中提供静态资产的服务留给nginx,而php代码则由php-fpm处理。

  3. In both web and php, there are bind mounts to config files on the host machine which will override default configuration that comes with the nginx and wordpress images.

    webphp ,主机上都有对配置文件的绑定安装,它将覆盖nginxwordpress图像随附的默认配置。

  4. In php and db, identical values are set for the database credentials environment variables so that the mysql container creates a database with the same credentials on initialization.

    phpdb ,为数据库凭据环境变量设置了相同的值,以便mysql容器在初始化时创建具有相同凭据的数据库。

  5. In php, the WORDPRESS_DB_HOST is set to the service name of the MySQL container, db. Docker DNS will automatically resolve target container in the Docker virtual network.

    phpWORDPRESS_DB_HOST设置为MySQL容器db服务名称 。 Docker DNS将自动解析Docker虚拟网络中的目标容器。

  6. There is a named volume mount, db which is meant for persistence of the database should the container be shutdown.

    有一个名为volume mount的db ,用于关闭容器后数据库的持久性。

为什么要使用Docker? (Why should you use Docker?)

If the abstractions of containerization outlined earlier hasn’t convinced you yet, here’s a TL;DR of all the benefits of Docker.

如果前面概述的容器化抽象尚未使您信服,请使用TL; DR了解Docker的所有优势。

  • Run apps in an isolated OS environment, independent of host OS在独立于主机OS的隔离OS环境中运行应用
  • Does not incur as much overhead as full virtualization with VMs与使用VM进行完全虚拟化相比,不会产生那么多的开销
  • Package configuration with the app as a single image

    将应用程序打包配置为单个映像

  • Expose only ports that you need and block all others仅公开您需要的端口并阻止所有其他端口
  • Change configuration files on the fly with volumes for quick iteration快速更改具有卷的配置文件以进行快速迭代
  • Link related containers and configuration in a single docker-compose file在单个docker-compose文件中链接相关的容器和配置
  • Option to deploy highly-available renditions of your apps with simple modifications通过简单的修改即可部署应用程序的高可用性版本

解决Reddit评论 (Addressing Reddit Comments)

The common theme across arguments against the use of Docker is the loss of control. Indeed, during the early stages of using Docker, I did feel that there was some degree of control given up.

反对使用Docker的争论的共同主题是失去控制。 确实,在使用Docker的早期阶段,我确实感到已经放弃了一定程度的控制。

I no longer had direct access to configuration files on the host machine and had to jump through several hoops in order to tweak a single configuration variable, files and logs are also no longer a single tail or cat command away. It was indeed very frustrating for me then, as someone who was used to modifying configuration and code directly on the host machine.

我不再能够直接访问主机上的配置文件,而不得不跳过几个箍圈来调整单个配置变量,文件和日志也不再是单个tailcat命令。 那时,对于曾经直接在主机上修改配置和代码的人来说,确实让我感到非常沮丧。

After a month of using Docker, I found out that my deployments and configuration were a lot more organized. This is especially so with Docker Swarm, which I will introduce in later piece, where I no longer needed to SSH into each machine to view logs. Configuration and code can be bind-mounted to host directories or shared storage which I can access as easily as I used to and lastly, environment variables no longer need to be defined on the host machine.

使用Docker一个月后,我发现我的部署和配置更加井井有条。 Docker Swarm尤其如此,我将在以后的文章中介绍,不再需要通过SSH进入每台计算机来查看日志。 可以将配置和代码绑定安装到主机目录或共享存储上,就像以前一样,我可以轻松地访问它们,最后,不再需要在主机上定义环境变量。

Docker has brought me much needed structure to my view on separation of application code, configuration, and state persistence of application, and I feel the minor inconvenience it causes is well worth the convenience it offers.

Docker为我带来了关于应用程序代码,配置和应用程序状态持久性分离的急需的结构,我认为它带来的微小不便值得提供它的便利。

使用Docker的最重要原因 (The most important reason to use Docker)

In my opinion, the most important reason for me is this:

我认为,最重要的原因是:

Most if not all popular software out there have a Docker image available for use, and that greatly simplifies the installation process.

大多数(如果不是全部)流行软件都可以使用Docker映像,这大大简化了安装过程。

If you intend to do any kind of self-hosting, knowing Docker is crucial in saving yourself from sleepless nights spent debugging your work.

如果您打算进行任何形式的自我托管,那么了解Docker对于使自己免于调试工作所花费的不眠之夜至关重要。

Even if you don’t intend to self-host, assuming you’re in the tech field, be it as a Data Scientist or a Backend Software Engineer, Docker is very relevant to your career and will remain so until software no longer has dependencies (which will never happen).

即使您不打算自托管,也不管您是在技术领域,无论是作为数据科学家还是后端软件工程师,Docker都与您的职业息息相关,并将一直保持下去,直到软件不再具有依赖关系为止(永远不会发生)。

At work, Docker is used very frequently in my daily workflows, uses include:

在工作中,Docker在我的日常工作流程中经常使用,其用途包括:

  1. Maintaining an identical data analysis environment across the team在团队中维护相同的数据分析环境
  2. Developing and testing applications in a predictable environment在可预测的环境中开发和测试应用程序
  3. Ensuring zero-downtime atomic deployments确保零停机原子部署

TL; DR (TL;DR)

If I were to sum up the entire piece here in a single sentence, I would tell you this:

如果我想用一个句子来总结整个文章,我会告诉你:

If you are serious in working in a tech role, you should pick up Docker.

如果您认真从事技术工作,则应选择Docker。

Originally published at ikarus.sg on July 13, 2020.

最初于 2020 年7月13日 ikarus.sg 发布

翻译自: https://medium.com/swlh/how-i-started-using-docker-and-why-you-should-too-5961214b67c8

docker 开始容器


http://www.taodudu.cc/news/show-5902804.html

相关文章:

  • python爬取公众号阅读量_Python爬虫实践:如何快速、高效的爬取微信公众号阅读在看数...
  • 如何快速搭建实用的爬虫管理平台
  • Google勇敢新世界(By 南方人物周刊)
  • python爬取公众号阅读量_如何快速、高效的爬取微信公众号阅读、在看数呢?
  • 计算机显卡指的是什么样的,电脑的显卡是什么
  • 现在显卡都支持多屏吗_显卡这么多的视频接口,你都认识吗?
  • 改变未来 音频HDMI显卡应用与液晶杂谈
  • 视音频编码简述
  • FFmpeg显卡版编译安装
  • 电脑我的世界服务器怎么按键显示,我的世界电脑版所有的按键及使用方法?
  • 剑与契约电脑版怎么下载?如何在电脑上玩剑与契约?
  • 关于python文件打开模式的描述_【单选题】关于Python文件打开模式的描述,以下选项中描述错误的是 A. 覆盖写模式w B. 追加写模式a C. 创建写模式n D. 只读模式r...
  • 友萌君约你来看更懂女人的线上发布会!
  • 女性能做哪些副业?究竟有什么兼职适合女人呢?
  • 论坛上的一段话,关于女人的!!
  • 女人的逻辑
  • 关于音频特征提取
  • 关于python浮点数类型错误的是_关于 Python 的数字类型,以下选项中描述错误的是( )...
  • 关于ScanNet数据集
  • 关于女人是否听话男人话的谬论
  • 关于女人(转载)
  • 关于女人的比喻,经典!
  • 关于女人的64个迷
  • 关于女性社群网站的讨论
  • 关于女性跳槽
  • 关于女生
  • OSChina 周四乱弹 ——女神节女神在干嘛?
  • 在百度浏览器中实行查看网页源代码的详细操作步骤
  • 手机百度浏览器fixed定位问题
  • HTML5手机浏览器获取经度和纬度(百度API)

docker 开始容器_我是如何开始使用docker的,为什么也应该使用相关推荐

  1. docker 厂商 容器_疫情期间,Docker让运维人员雪上加霜

    2020疫情原因,公司业绩下滑严重,于是决定给团队瘦身,经过激烈的讨论,最终决定先从运维人员开始.原因是我们引入了Docker.它部署项目相比之前要简单许多.运维的工作完全可以被开发替代.当然我们小公 ...

  2. docker harbor 域名_超详细的搭建docker私服Harbor教程

    概述 "集装箱"是Docker设计哲学之所在,它让一台物理机(或者虚拟机)同时运行多个相互隔离的应用变得更为轻松简朴,固然这一切照样多亏Linux的相关底层手艺,固然,也包罗OS ...

  3. docker 安装依赖_史上最全Docker环境安装指南-让安装docker简单到爆

    作者:可优http://cnblogs.com/keyou1/p/11511067.html 一.思考❓❔ 1.什么是Docker? 装应用的容器 开发.测试.运维都偏爱的容器化技术 轻量级 扩展性 ...

  4. 二、docker 镜像容器常用操作(让我们用docker 溜得飞起)

    文章目录 前言 基本概念 镜像的使用 下载镜像 查询镜像 删除镜像 容器的使用 创建和启动 终止容器 查看容器 重启容器 删除容器 番外 前言 上篇讲了我们如何安装docker,现在该我们一展拳脚的时 ...

  5. 群晖docker装梅林_群晖NAS用Docker安装宝塔面板一键部署建站系统

    Docker镜像选择 我们的安装思路是先用Docker安装Centos7系统,然后再安装宝塔面板,当然用群晖自带的VMM虚拟机功能也是一样可以实现的. 1.打开Docker,注册表中搜索centos, ...

  6. docker 厂商 容器_中国容器厂商综合实力排名,新鲜出炉!

    作为开源技术的宠儿,容器技术近两年来的发展态势可谓炙手可热.Docker的横空出世,让沉积已久的容器技术重回公众视野,并迅速成为业界焦点.近期,IT68携手ChinaUnix.ITPUB共同就目前国内 ...

  7. docker 外部连接_使用外部网络连接Docker容器

    我正在研究一个微服务架构,其中我们有许多不同的项目,并且所有项目都连接到同一个redis实例.我想将这个体系结构移到Docker上以在开发环境中运行.因为所有的项目都有单独的存储库,所以我不能只使用一 ...

  8. Centos7 Docker 删除容器_入门试炼08

    说明 命令 删除指定的容器格式 docker rm $CONTAINER_ID/NAME 删除容器指定容器名称 docker rm mycentos3 删除容器指定容器id docker rm 909 ...

  9. docker 厂商 容器_容器化 - 边缘计算的新方向

    随着物联网终端设备数量的快速增加,同时由于网络带宽有限,高昂的传输成本和较高的响应延时等问题,传统的基于云计算模型的集中式数据处理方式已不能有效处理网络边缘设备所产生的海量数据.针对物联网场景中的新挑 ...

最新文章

  1. 你的裸照,一键生成,令人害怕的不是算法,是人心!
  2. SAP MM 关于采购组设计的思考
  3. windows下使用Hibernate连接Mycat例子
  4. delphi下的MVC架构-eMVC
  5. 使用Git命令时出现fatal: this operation must be run in a work tree提示,该如何解决
  6. show processlist解析
  7. ITK:创建另一个图像实例
  8. 微信小程序云开发如何--实现简单的增删改查
  9. 《认清C++语言》のrandom_shuffle()和transform()算法
  10. vue base64图片不显示_技巧 | word中插入的图片显示不完整怎么办?
  11. 迟到的 cocoapod 版本适配 之网利宝
  12. 微信小程序用RSA加密和java后台对接。
  13. GB28181国标错误码
  14. Java 前后端分离部署方式
  15. area 估算函数(simpson)
  16. 如何做好互联网广告销售
  17. 一个简单的jxl文件上传功能
  18. 一个应届毕业生的求职回忆录(指引道路)
  19. 模仿猫眼电影App一个动画效果
  20. jdk1.8——Base64

热门文章

  1. unetbootin for linux,(实用)使用unetbootin制作Linux的U盘启动盘
  2. iphone旋转响应的方法
  3. 我眼中的 Electron
  4. linux中ugo什么权限,Linux基本权限UGO
  5. Linux文件系统ugo权限划分详解
  6. Morecoin区块链专场:DeFi 和 CeFi 的发展与未来
  7. 【nodejs代理服务器一】nodejs http-proxy 开发反向代理服务器,防火墙,过滤常见的web渗透
  8. java计算机毕业设计志愿者服务平台源码+数据库+系统+lw文档
  9. 修改linux资源限制参数命令,Linux的资源限制功能cgroups v1和cgroups v2的详细介绍
  10. 信息系统项目管理师(软考高项)备考总结