配色: 字号:
Docker使用手册
2021-09-15 | 阅:  转:  |  分享 
  
目录目录1第一章初识Docker11.什么是Docker12.为什么要使用Docker33.虚拟化与Docker54.Docker的应用
场景65.Docker的优点71、快速,一致地交付您的应用程序72、响应式部署和扩展73、在同一硬件上运行更多工作负载76.Doc
ker的架构77.Docker的使用9DockerHelloWorld9启动容器(后台模式)10停止容器12相关链接12第二章
Docker的体系结构121.Docker的内部组件132.DockerImage的工作原理143.Docker仓库144
.Docker容器145.Docker底层技术146.CI(持续集成)服务器的功能157.Docker使用流程158.D
ockerfile中常见的指令159.什么是Kubernetes(k8s)161、Kubernetes集群部署及简单命令行操作2
2第三章Docker安装和使用451.内部服务器安装docker452.CentOS7系列安装docker473.Docke
r创建474.守护态运行475.终止、删除容器486.常用基本命令481,Docker基本命令;482,Docker镜像54
第四章Dockerimages的获取和使用571.获取镜像572.查找镜像583.下载镜像594.创建自己的镜像59第
五章Docker中的网络介绍641.端口映射实现访问容器642.Docker容器互联65第六章Docker高级网络配置68
1.配置DNS682.容器之间的通信693.创建一个点到点的连接694.Docker的4种网络模式70第七章Docker
的数据管理721.数据卷722.数据卷容器74第八章容器的安全性能75第九章学会部署局域网docker76第十章Dock
er实现多台物理机之间的容器互联77第十一章Docker中使用Supervisor管理进程78第十二章Docker创建tomc
at/weblogic集群79第十三章Docker安装Redis79第十四章Docker安装MySQL79第十五章基于Doc
ker的AzureDevOps实现791.Docker和持续集成(CI)892.使用AzureDevOps来完成CI98第
十六章构建Python环境111第十七章在Docker上部署使用AzureCLI镜像117第十八章在Linux上使用Azu
reCLI来管理Azure121安装和基本配置121基本使用方法123第十九章将Dockerimagepush到Azur
e128第二十章使用Docker和AzureKubernetes服务将ASP.NET核心应用程序容器化128介绍128应用概述
129容器化ASP.NET核心应用程序131部署在本地Kubernetes集群上134Docker镜像和Azure容器注册表(AC
R)140部署AzureKubernetes服务(AKS)群集142将ASP.NET核心应用程序部署到AKS144结论146第二
十一章CentOS7安装Docker环境147使用官方安装脚本自动安装(仅适用于公网环境)147Ubuntu14.041
6.04(使用apt-get进行安装)147初识Docker如果说个人主机时代大家比拼的关键是CPU主频的高低和内存的大小,那么
在云计算时代,虚拟化技术无疑是整座信息技术大厦最核心的一块基石。伴随着信息技术产业的发展,虚拟化技术已经应用到各种关键场景中。从最
早上世纪60年代IBM推出的大型主机虚拟化到后来x86平台上的虚拟化,虚拟化技术自身也在不断丰富和创新。虚拟化既可以通过硬件模拟来
实现,也可以通过操作系统来实现。而近些年出现的容器虚拟化方案,更是充分利用了操作系统本身已有的机制和特性,可以实现轻量级的虚拟化,
甚至有人把它称为新一代的虚拟化技术。Docker毫无疑问就是其中的佼佼者。那么,什么是Docker?它会带来什么好处?它跟现有虚拟
化技术又有何关系呢?本章在介绍Docker项目的起源和发展之后,会剖析Docker和Linux容器技术的密切联系,以及在开发和运维
中使用Docker的突出优势。最后,还将阐述Docker在整个虚拟化领域中的定位。Docker是一个开源的应用容器引擎,基于G
o语言并遵从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然
后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似iPhone的
app),更重要的是容器性能开销极低。Docker从17.03版本之后分为CE(CommunityEdition:社区
版)和EE(EnterpriseEdition:企业版),我们用社区版就可以了。1.什么是DockerDocker是一个容
器化平台,它以容器的形式将您的应用程序及其所有依赖项打包在一起,以确保您的应用程序在任何环境中无缝运行。Docker是一个开源的
应用容器引擎,基于Go语言并遵从Apache2.0协议开源。Docker是一个开放平台,用于开发应用、交付(shipping)应
用、运行应用。Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提
高交付软件的速度。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux
机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似iPhone的app),更重要的是容器性能开
销极低。Docker从17.03版本之后分为CE(CommunityEdition:社区版)和EE(Enterpr
iseEdition:企业版),我们用社区版就可以了。Docker的主要目标是“Build,ShipandRunAny
App,Anywhere",即通过对应用组件的封装(Packaging)、分发(Distribution)、部署(Deployme
nt)、运行(Runtime)等生命周期的管理,达到应用组件级别的“一次封装,到处运行”。这里的应用组件,既可以是一个Web应用,
也可以是一套数据库服务,甚至是一个操作系统或编译器。Docker基于Linux的多项开源技术提供了高效、敏捷和轻量级的容器方案,并
且支持在多种主流云平台(Paas)和本地系统上部署。可以说Docker为应用的开发和部署提供了“站式"的解决方案。Docker容器
与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、高效地利用服务器。容器更
多的用于表示软件的一个标准化单元。由于容器的标准化,因此它可以无视基础设施(Infrastructure)的差异,部署到任何一个
地方。另外,Docker也为容器提供更强的业界的隔离兼容。Docker利用Linux核心中的资源分离机制,例如cgroups,以
及Linux核心名字空间(namespaces),来创建独立的容器(containers)。这可以在单一Linux实体下运作,避免
引导一个虚拟机造成的额外负担[3]。Linux核心对名字空间的支持完全隔离了工作环境中应用程序的视野,包括行程树、网络、用户ID与
挂载文件系统,而核心的cgroup提供资源隔离,包括CPU、存储器、blockI/O与网络。从0.9版本起,Dockers在使用
抽象虚拟是经由libvirt的LXC与systemd-nspawn提供界面的基础上,开始包括libcontainer库做为以自
己的方式开始直接使用由Linux核心提供的虚拟化的设施,依据行业分析公司“451研究”:“Dockers是有能力打包应用程序及其虚
拟容器,可以在任何Linux服务器上运行的依赖性工具,这有助于实现灵活性和便携性,应用程序在任何地方都可以运行,无论是公用云端服务
器、私有云端服务器、单机等。”Docker作为基于Go语言实现的云开源项目,诞生于2013年初,最初发起者是dotCloud公司。
Docker自开源后受到广泛的关注和讨论,目前已有多个相关项目,逐渐形成了围绕Docker的生态体系。dotCloud公司后来也改
名为DockerInc,专注于Docker相关技术和产品的开发。Docker项目目前已加人了Linux基金会,遵循Apache
2.0协议,全部开源代码均在https://github.com/docker/docker上进行维护。在最近一次Linux基金会
的调查中,Docker是仅次于Openstack的最受欢迎的云计算开源项目。现在主流的Linux操作系统都已经支持Docker。例
如,RedhatRHEL6.5/CentOS6.5往上的操作系统、Ubuntu14.04操作系统,都已经默认带有Docke
r软件包。Google公司宣称在其PaaS(PlatformasaService)平台及服务产品中广泛应用了Docker。微
软公司宣布和Docker公司合作,以加强其云平台Azure对Docker的支持。公有云提供商亚马逊近期也推出了AWSEC2Co
ntainer,提供对Docker的支持。Linux容器技术Docker引擎的基础是Linux容器(LinuxContainer
s,LXC)技术。IBMDeveloperWorks上给出了关于容器技术的准确描述:容器有效地将由单个操作系统管理的资源划分到
孤立的组中,以便更好地在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核
心CPU本地运行指令,而不需要任何专门的解释机制。此外,也避免了准虚拟化(paravirtualization)和系统调用替换中的
复杂性。Linux容器其实不是一个全新的概念。最早的容器技术可以追溯到1982年Unix系列操作系统上的chroot工具(直到今天
,主流的Unix、Linux操作系统仍然支持和带有该工具)。早期的容器实现技术包括SUNSolaris操作系统上的Solaris
Containers(2004年发布),FreeBSD操作系统上的FreeBSDjail(2000年左右出现),以及GNU/L
inux上的Linux-VServer(http://linux-vserver.org/)(2001年10月)和OpenVZ(h
ttp://openvz.org)(2005年)。虽然这些技术经过多年的演化已经十分成熟,但是由于种种原因,这些容器技术并没有被集
成到主流的Linux内核中,使用起来并不方便。例如,如果用户要使用OpenVZ技术,就需要先给操作系统打上特定的内核补丁方可使用。
后来LXC项目借鉴了前人成熟的容器设计理念,并基于一系列新的内核特性实现了更具扩展性的虚拟化容器方案。更加关键的是,LXC被集成到
了主流Linux内核中,进而成为Linux系统轻量级容器技术的事实标准。从Linux容器到Docker在LXC的基础上,Docke
r进一步优化了容器的使用体验。Docker提供了各种容器管理工具(如分发、版本、移植等)让用户无需关注底层的操作,可以简单明了地管
理和使用容器。用户操作Docker容器就像操作一个轻量级的虚拟机那样简单。读者可以简单地将容器理解为一种沙盒(Sandbox)。每
个容器内运行一个应用,不同的容器相互隔离,容器之间也可以建立通信机制。容器的创建和停止都十分快速,容器自身对资源的需求也十分有限,
远远低于虚拟机。很多时候,甚至直接把容器当作应用本身也没有任何问题。有理由相信,随着Docker技术的进一步成熟,它将成为更受欢迎
的容器虚拟化技术实现,得到更广泛的应用。2.为什么要使用DockerDocker效率更高每个容器共享宿主系统的内核。然而各个容器都
运行着一个Linux的副本,这意味着没有Hypervisor,而且不需要额外的启动。容器引擎负责启动或者停止容器,这与虚拟机实现中
的Hypervisor类似,但是容器是内核级的虚拟化。Docker容器虚拟化的好处Docker项目的发起人和DockerInc.
的CTO——SolomonHykes认为,Docker在正确的地点、正确的时间顺应了正确的趋势——即高效地构建应用。现在开发者需
要能方便地创建运行在云平台上的应用,也就是说应用必须能够脱离底层机器,而且同时必须是“任何时间任何地点"可获取的。因此,开发者们需
要一种创建分布式应用程序的方式,这也是Docker所能够提供的。举个简单的应用场景的例子。假设用户试图基于最常见的LAMP(Lin
ux+Apache+MySQL+PHP)组合来运维一个网站。按照传统的做法,首先,需要安装Apache、MySQL和PHP以及它们
各自运行所依赖的环境;之后分别对它们进行配置(包括创建合适的用户、配置参数等);经过大量的操作后,还需要进行功能测试,看是否工作正
常;如果不正常,则意味着更多的时间代价和不可控的风险。可以想象,如果再加上更多的应用,事情会变得更加难以处理。更为可怕的是,一旦需
要服务器迁移(例如从阿里云迁移到腾讯云),往往需要重新部署和调试。这些琐碎而无趣的“体力活",极大地降低了工作效率。而Docker
提供了一种更为聪明的方式,通过容器来打包应用,意味着迁移只需要在新的服务器上启动需要的容器就可以了。这无疑将节约大量的宝贵时间,并
降低部署过程出现问题的风险。Docker在开发和运维中的优势对开发和运维(DevOps)人员来说,可能最梦寐以求的就是一次性地创建
或配置,可以在任意环境、任意时间让应用正常地运行。而Docker恰恰是可以实现这一终极目标的瑞士军刀。具体说来,Docker在开发
和运维过程中,具有如下几个方面的优势。更快速的交付和部署。使用Docker,开发人员可以使用镜像来快速构建一套标准的开发环境;开发
完成之后,测试和运维人员可以直接使用相同环境来部署代码。Docker可以快速创建和删除容器,实现快速迭代,大量节约开发、测试、部署
的时间。并且,各个步骤都有明确的配置和操作,整个过程全程可见,使团队更容易理解应用的创建和工作过程。更高效的资源利用。Docker
容器的运行不需要额外的虚拟化管理程序(VirtualMachineManager,VMM以及Hypervisor)支持,它是内
核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。Docker可以快速创建容器,Docker使用的是宿主机的系统内核,所
以在创建容器的时候是毫秒级的,但是VM有自己的内核和硬件,开机需要自检,浪费了更多的时间,Docker就节约了很多的开发、测试和部
署时间。Docker不需要像VM那样使用Hypervisor进行硬件虚拟化,容器就不需要进行硬件虚拟以及运行完整的操作系统,因此D
ocker对系统资源的利用率就更高。Docker在运行速度、内存消耗、文件的存储速度上都要比VM更高效。更轻松的迁移和扩展。Doc
ker容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。这种兼容性让用户可以在不同平台之间轻
松地迁移应用。由于团队的不同人员使用相同的镜像创建容器,因此容器的执行环境是一致的,目前很多的平台都已经支持docker应用,无论
是物理机、虚拟机、公有云还是私有云甚至是笔记本上运行的结果多事一致的。因此用户可以很容易将一个平台上的容器迁移到另外一个平台上。由
于Docker使用的是分层存储以及镜像技术,第四章在下周镜像的过程中可以看到镜像下载是分层下载的,因此复用重复的部分就更容易,应用
的维护和更新就更简单,基于基础镜像的进一步扩展也就很简单,还可以自己定制镜像。更简单的更新管理。使用Dockerfile,只需要小
小的配置修改,就可以替代以往大量的更新工作。并且所有修改都以增量的方式进行分发和更新,从而实现自动化并且高效的容器管理。Docke
r与虚拟机比较作为一种轻量级的虚拟化方式,Docker在运行应用上跟传统的虚拟机方式相比具有显著优势:Docker容器很快,启动和
停止可以在秒级实现,这相比传统的虚拟机方式要快得多。Docker容器对系统资源需求很少,一台主机上可以同时运行数千个Docker容
器。Docker通过类似Git的操作来方便用户获取、分发和更新应用镜像,指令简明,学习成本较低。Docker通过Dockerfil
e配置文件来支持灵活的自动化创建和部署机制,提高工作效率。Docker容器除了运行其中的应用之外,基本不消耗额外的系统资源,保证应
用性能的同时,尽量减小系统开销。传统虚拟机方式运行N个不同的应用就要启动N个虚拟机(每个虚拟机需要单独分配独占的内存、磁盘等资源)
,而Docker只需要启动N个隔离的容器,并将应用放到容器内即可。当然,在隔离性方面,传统的虚拟机方式多了一层额外的隔离。但这并不
意味着Docker就不安全。Docker利用Linux系统上的多种防护机制实现了严格可靠的隔离。从1.3版本开始,Docker引人
了安全选项和镜像签名机制,极大地提高了使用Docker的安全性。下表总结了使用Docker容器技术与传统虚拟机技术的特性比较。3.
虚拟化与Docker虚拟化技术是一个通用的概念,在不同领域有不同的理解。在计算领域,一般指的是计算虚拟化(ComputingVi
rtualization),或通常说的服务器虚拟化。维基百科上的定义如下:在计算机技术中,虚拟化(Virtualization)是
一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障砰
,使用户可以用比原本的组态更好的方式来应用这些资源。可见,虚拟化的核心是对资源进行抽象,目标往往是为了在同一个主机上运行多个系统或
应用,从而提高系统资源的利用率,同时带来降低成本、方便管理和容错容灾等好处。从大类上分,虚拟化技术可分为基于硬件的虚拟化和基于软件
的虚拟化。其中,真正意义上的基于硬件的虚拟化技术不多见,少数如网卡中的单根多10虚拟化(SingleRootI/OVirtu
alizationandSharingSpecification,SR-IOV)等技术,也超出了本书的讨论范畴。基于软件的虚
拟化从对象所在的层次,又可以分为应用虚拟化和平台虚拟化(通常说的虚拟机技术即属于这个范畴)。其中,前者一般指的是一些模拟设备或Wi
ne这样的软件。后者又可以细分为如下几个子类:完全虚拟化。虚拟机模拟完整的底层硬件环境和特权指令的执行过程,客户操作系统无需进行修
改。例如VMwareWorkstation、VirtualBox、QEMU等。硬件辅助虚拟化。利用硬件(主要是CPU)辅助支持(
目前x86体系结构上可用的硬件辅助虚拟化技术包括Intel-VT和AMD-V)处理敏感指令来实现完全虚拟化的功能,客户操作系统无需
修改,例如VMwareWorkstation、xen、KVM。部分虚拟化。只针对部分硬件资源进行虚拟化,客户操作系统需要进行修改
。现在有些虚拟化技术的早期版本仅支持部分虚拟化。超虚拟化(Paravirtualization)。部分硬件接口以软件的形式提供给客
户机操作系统,客户操作系统需要进行修改,例如早期的xeno操作系统级虚拟化。内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不
同的进程。容器相关技术即在这个范畴。可见,Docker以及其他容器技术都属于操作系统的虚拟化这个范畴。Docker虚拟化方式之所以
拥有众多优势,这跟操作系统的虚拟化自身的特点是分不开的。下面图1-1比较了Docker和常见的虚拟机方式的不同之处。传统方式是在硬
件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层。图1-1Docker和传统的虚拟机方式的不同之处Docker容器
是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,因此更加轻量级。4.Docker的应用场景Web应用的自动化打包和发布
。自动化测试和持续集成、发布。在服务型环境中部署和调整数据库或其他的后台应用。从头编译或者扩展现有的OpenShift或Cloud
Foundry平台来搭建自己的PaaS环境。5.Docker的优点Docker是一个用于开发,交付和运行应用程序的开放平台
。Docker使您能够将应用程序与基础架构分开,从而可以快速交付软件。借助Docker,您可以与管理应用程序相同的方式来管理基
础架构。通过利用Docker的方法来快速交付,测试和部署代码,您可以大大减少编写代码和在生产环境中运行代码之间的延迟。1、快速,一
致地交付您的应用程序Docker允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。容
器非常适合持续集成和持续交付(CI/CD)工作流程,请考虑以下示例方案:您的开发人员在本地编写代码,并使用Docker容器
与同事共享他们的工作。他们使用Docker将其应用程序推送到测试环境中,并执行自动或手动测试。当开发人员发现错误时,他们可以在
开发环境中对其进行修复,然后将其重新部署到测试环境中,以进行测试和验证。测试完成后,将修补程序推送给生产环境,就像将更新的镜像推送
到生产环境一样简单。2、响应式部署和扩展Docker是基于容器的平台,允许高度可移植的工作负载。Docker容器可以在开发人员
的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。Docker的可移植性和轻量级的特性,还可以使您轻松地完成动态管理
的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。3、在同一硬件上运行更多工作负载Docker轻巧快速。它为基于虚拟
机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker非常适合于高密度环境以
及中小型部署,而您可以用更少的资源做更多的事情。6.Docker的架构Docker包括三个基本概念:镜像(Image):Docke
r镜像(Image),就相当于是一个root文件系统。比如官方镜像ubuntu:16.04就包含了完整的一套Ubunt
u16.04最小系统的root文件系统。容器(Container):镜像(Image)和容器(Container)的关系,就
像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。仓库(R
epository):仓库可看成一个代码控制中心,用来保存镜像。Docker使用客户端-服务器(C/S)架构模式,使用远程A
PI来管理和创建Docker容器。Docker容器通过Docker镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类
。Docker面向对象容器对象镜像类概念说明Docker镜像(Images)Docker镜像是用于创建Docker容器的模板,比
如Ubuntu系统。Docker容器(Container)容器是独立运行的一个或一组应用,是镜像运行时的实体。Docker客户
端(Client)Docker客户端通过命令行或者其他工具使用DockerSDK(https://docs.docker.
com/develop/sdk/)与Docker的守护进程通信。Docker主机(Host)一个物理或者虚拟的机器用于执行
Docker守护进程和容器。Docker仓库(Registry)Docker仓库用来保存镜像,可以理解为代码控制中的代码仓库
。DockerHub(https://hub.docker.com)提供了庞大的镜像集合供使用。一个DockerRegis
try中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含
同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版
本的镜像。如果不给出标签,将以latest作为默认标签。DockerMachineDockerMachine是一个简化Do
cker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、DigitalOc
ean、MicrosoftAzure。7.Docker的使用DockerHelloWorldDocker允许你在容器内运行应
用程序,使用dockerrun命令来在容器内运行一个应用程序。输出Helloworldrunoob@runoob:~$
dockerrunubuntu:15.10/bin/echo"Helloworld"Helloworld各个参数解析:
docker:Docker的二进制执行文件。run:与前面的docker组合来运行一个容器。ubuntu:15.10指
定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker就会从镜像仓库DockerHub下
载公共镜像。/bin/echo“Helloworld”:在启动的容器里执行的命令以上命令完整的意思可以解释为:Docker
以ubuntu15.10镜像创建一个新容器,然后在容器里执行bin/echo“Helloworld”,然后输出结果。启动
容器(后台模式)使用以下命令创建一个以进程方式运行的容器runoob@runoob:~$dockerrun-dubuntu
:15.10/bin/sh-c"whiletrue;doechohelloworld;sleep1;done
"2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63
在输出中,我们没有看到期望的“helloworld”,而是一串长字符2b1b7a428627c51ab8810d541d759
f072b4fc75487eed05812646b8534a2fe63这个长字符串叫做容器ID,对每个容器来说都是唯一的,我们可
以通过容器ID来查看对应的容器发生了什么。首先,我们需要确认容器有在运行,可以通过dockerps来查看:runoob@
runoob:~$dockerpsCONTAINERIDIMAGECOM
MAND...5917eac21c36ubuntu:15.10
"/bin/sh-c''whilet…"...输出详情介绍:CONTAINERID:容器ID。IMAGE:使
用的镜像。COMMAND:启动容器时运行的命令。CREATED:容器的创建时间。STATUS:容器状态。状态有7种:crea
ted(已创建)restarting(重启中)running或Up(运行中)removing(迁移中)paused(暂停)ex
ited(停止)dead(死亡)PORTS:容器的端口信息和使用的连接类型(tcp\udp)。NAMES:自动分配的容器名称。
在宿主主机内使用dockerlogs命令,查看容器内的标准输出:runoob@runoob:~$dockerlogs2
b1b7a428627停止容器我们使用dockerstop命令来停止容器:通过dockerps查看,容器已经停止工作:
runoob@runoob:~$dockerps可以看到容器已经不在了。相关链接Docker官网:https://www.d
ocker.com/https://www.docker.comGithubDocker源码:https://github.c
om/docker/docker-cehttps://github.com/docker/docker-ce第二章Docker的
体系结构Docker使用的是C/S结构,即客户机client和服务器server架构,Dockerdaemon是Docker最核
心的后台进程,主要运行在宿主机的后天,它负责响应来自Dockerclient的请求,然后将这些请求翻译成系统调用完成容器管理操作
包括创建、运行、分发容器等管理操作。它可以运行在一个机器上也可以通过Socket通信。Dockerclient的命令在系统中以b
in命令的形式存在,用户通过docker命令来跟dockerdaemon进行交互。DockerC/S体系架构如下图:Docke
r的内部组件Docker主要有三个内部组件,分别是:DockerImages,Dockerrepository,Docker
container。DockerImages是一个只读的模板。例如一个Images可以包含了一个CentOS系统,里面安装了Ap
ache等应用程序,使用Images可以创建你需要的Container,你可以下载镜像或者自己制作一个镜像。DockerRepo
sitory是Docker仓库是集中存放镜像的地方,分为公共仓库和私有仓库。可以在仓库中下载你自己需要的Images。Docker
Container即Docker容器,容器是从镜像创建的,它可以启动、开始、创建、终止、删除等,每一个容器之间是相互隔离的。Do
ckerImage的工作原理Docker镜像是Docker容器的源代码,Docker镜像用于创建容器。使用build命令创建镜像
。在下载镜像的过程中可以看到镜像是分层的,Images一般是由若干层组成,字母和数字组成的串是每层的唯一的ID,使用docker
pull命令下载镜像的时候会输出每一层的信息,当不同的镜像包括相同的层的时候,本地存储只保存层的一份内容,减少了存储空间。Dock
er仓库Docker是存放镜像的地方,分为公有仓库和私有仓库,公有仓库是dockerhub,本地的私有仓库是通过registry
镜像来创建的。Docker容器Docker容器包括应用程序及其所有依赖项,作为操作系统的独立进程运行。Docker容器是通过镜像来
创建的,当使用命令dockerrun-itcentos/bin/bash时,docker在后台运行操作如下:①如果本地没有
centos系统镜像,就从dockerhub下载,由于公司业务安全,服务器不可以访问外网,需要从docker.oa.com下载所
需要的镜像,使用dockerpull命令下载;②从images创建容器;③分配一个文件系统,并在只读的镜像层外面挂在一层可读写层
;④从宿主机配置的网桥接口中桥接一个虚拟的接口到容器上;⑤从网桥的地址池中配置一个IP地址给容器;⑥执行用户指定的应用程序。Doc
ker容器可以有四种状态:运行已暂停重新启动已退出Docker底层技术Docker底层有两个核心的技术Namespace和Cont
rolgroups。命名空间是Linux内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操
作系统中运行一样。命名空间保证了容器之间彼此互不影响。①pid命名空间不同用户的进程是通过pid命名空间隔离开的,且不同的命名空间
中可以有相同的pid。所有的LXC进程在docker中的父进程为docker进程,每个LXC进程具有不同的命名空间。②net命名空
间有了pid的命名空间,每个命名空间中的pid是相互隔离的,但是网络还是共享宿主机host的端口,网络隔离是通过net命名空间来实
现的,,每个net命名空间有独立的网络设备、IP地址、路由表、/proc/net目录,这样每个容器的网络都可以隔离。Docke采用
的是veth的方式,将容器中的虚拟网卡同host上的一个docker网桥docker0连接在一起。③ipc命名空间容器中进程交互采
用了linux中使用的进程间交互方式(interprocesscommunication-IPC),主要暴扣信号量、消息队列和
共享内存等。④mnt命名空间将一个进程放到一个特定的目录执行。mnt命名空间允许不同命名空间的进程看到的文件结构不同,这样每个命名
空间中的进程所看到的文件目录就被隔离开了。⑤uts命名空间UTS("UNIXTime-sharingSystem")命名空间
允许每个容器拥有独立的hostname和domainname,使其在网络上可以被视作一个独立的节点而非主机上的一个进程。⑥us
er命名空间每个容器可以有不同的用户和组id,也就是说非主机上的用户也可以在容器内执行程序。ControlgroupsCGrou
ps是Linux内核提供的一种机制,这种机制可以根据特定的行为,把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内
,从而为系统资源管理提供一个统一的框架。CGroups可以限制、记录、隔离进程组所使用的物理资源(包括:CPU、memory、IO
等),为容器实现虚拟化提供了基本保证。Cgroups提供了以下四大功能:资源限制、优先级分配、资源统计、进程控制。①资源限制(Re
sourceLimitation):Cgroups可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这
个配额就发出OOM(OutofMemory)。②优先级分配(Prioritization):通过分配的CPU时间片数量及硬盘I
O带宽大小,实际上就相当于控制了进程运行的优先级。③资源统计(Accounting):Cgroups可以统计系统的资源使用量,如C
PU使用时长、内存用量等等,这个功能非常适用于计费。④进程控制(Control):Cgroups可以对进程组执行挂起、恢复等操作。
CI(持续集成)服务器的功能CI功能就是在每次提交之后不断地集成所有提交到存储库的代码,并编译检查错误。CI服务器功能是不断地集成
所有正在进行的更改并由不同的开发人员提交到存储库,并检查编译错误。它需要每天多次构建代码,最好是在每次提交之后,以便它可以检测在问
题发生时是哪个提交Bug了。Docker使用流程1)创建Dockerfile后,您可以构建它以创建容器的镜像2)推送或拉取镜像。D
ockerfile中常见的指令Dockerfile中的一些常用指令如下:FROM:指定基础镜像LABEL:功能是为镜像指定标签RU
N:运行指定的命令CMD:容器启动时要运行的命令Dockerfile中的命令COPY与ADD的区别COPY的只能是本地文
件,其他用法一致。dockerpull拉取或者更新指定镜像dockerpush将镜像推送至远程仓库dockerrm删除容器d
ockerrmi删除镜像dockerimages列出所有镜像dockerps列出所有容器什么是Kubernetes(k8s)
Kubernetes(简称k8s)诞生于谷歌,是一个开源的,用于管理云平台中多个主机上的容器化的应用,k8s的目标是让部署容器化的
应用简单并且高效,其提供了应用部署、规划、更新、维护的机制。Docker+Kubernetes已成为云计算的主流,Kuberne
tes正在塑造应用程序开发和管理的未来。k8s主要有以下特点:可移植支持公有云,私有云,混合云,多重云(multi-cloud)
。可以将容器化的工作负载从本地开发计算机无缝移动到生产环境。在本地基础结构以及公共云和混合云中,在不同环境中协调容器,保持一致性。
可扩展性支持模块化,插件化,可挂载,可组合。并且k8s的扩展和插件在社区开发者和各大公司的支持下高速增长,用户可以充分利用这些社区
产品/服务以添加各种功能。自动化和可伸缩性支持自动部署,自动重启,自动复制,自动伸缩/扩展,并且可以定义复杂的容器化应用程序并将其
部署在服务器群集甚至多个群集上——因为k8s会根据所需状态优化资源。通过内置的自动缩放器,k8s可轻松地水平缩放应用程序,同时自动
监视和维护容器的正常运行。Kubernetes正在塑造应用程序开发和管理的未来k8s构建于Google数十年经验,一大半来源于
Google生产环境规模的经验。结合了社区最佳的想法和实践,而且还在不断地高速迭代和更新之中。她衔着金钥匙出生,一诞生就广受欢
迎,更是在2017,其打败了所有的竞争对手,赢得了云计算的战争——主流的云厂商基本上都纷纷放弃了自己造“轮子”的举动,终止了各自的
容器编排工具,加盟了k8s阵营,其中包括RedHat、微软、IBM、阿里、腾讯、华为和甲骨文等。k8s像风暴一样席卷了应用开发领
域,并且已成为云原生应用程序(架构、组件、部署和管理方式)的事实标准,大量的开发者和企业正在使用k8s创建由微服务和无服务器功能组
成的现代架构。主流云服务容器服务介绍亚马逊AWSAmazonWebServices(AWS)是亚马逊公司旗下云计算服务平台
,为全世界范围内的客户提供云解决方案。AWS面向用户提供包括弹性计算、存储、数据库、应用程序在内的一整套云计算服务,帮助企业降低I
T投入成本和维护成本。那么如何在AWS上运行Docker呢?AWS同时为Docker开源解决方案和商业解决方案提供支持,并且
可通过多种方式在AWS上运行容器:AmazonElasticContainerService(ECS),是一种高度可扩
展的高性能容器编排服务,支持Docker容器,让我们可以在AWS上轻松运行和扩展容器化应用程序,而不需要安装和操作自己的容器编
排软件,不需要管理和扩展虚拟机集群,也不需要在这些虚拟机上调度容器。其工作原理如下图所示:AWSFargate,适用于Amazo
nECS的技术,可让我们在生产环境中运行容器,而无需部署或管理基础设施。AmazonElasticContainerSer
viceforKubernetes(EKS),可以让我们在AWS上运行Kubernetes,而无需安装和操作Kub
ernetes主节点。AmazonElasticContainerRegistry(ECR),是一个高度可用且安全的私
有容器存储库,可以让我们能够轻松地存储和管理Docker容器镜像,并对静态镜像进行加密和压缩,以便快速提取和保护这些镜像。AWS
Batch,可以让Docker容器运行高度可扩展的批处理工作负载。微软AzureMicrosoftAzure是一个开放而灵
活的企业级云计算平台。通过IaaS+PaaS帮助用户加快发展步伐,提高工作效率并节省运营成本。Azure是一种灵活和支持互
操作的平台,它可以被用来创建云中运行的应用或者通过基于云的特性来加强现有应用。它开放式的架构给开发者提供了Web应用、互联设备的应
用、个人电脑、服务器、或者提供最优在线复杂解决方案的选择。在容器这块,Azure同样的提供了众多解决方案:下面我们侧重介绍下以下服
务:Azure容器实例:Azure容器实例提供了在Azure中运行容器的最简捷方式,既无需预配任何虚拟机,也不必采用更高级
的服务。AzureServiceFabric:AzureServiceFabric是一款分布式系统平台,可方便用户轻松打
包、部署和管理可缩放的可靠微服务和容器。开发人员和管理员不需解决复杂的基础结构问题,只需专注于实现苛刻的任务关键型工作负荷,即那
些可缩放、可靠且易于管理的工作负荷。总之,AzureServiceFabric旨在解决构建和运行服务方面的难题,并有效地利用
基础结构资源,使团队可以使用微服务方法来解决业务问题。并且,其与服务生成方式无关,可以使用任意技术。不过,它确实提供内置编程AP
I,以便用户可以更轻松地生成微服务。AzureKubernetes服务(AKS):AKS管理托管的Kubernetes环
境,使用户无需具备容器业务流程专业知识即可快速、轻松地部署和管理容器化的应用程序。它还通过按需预配、升级和缩放资源,消除了正在进
行的操作和维护的负担,而无需使应用程序脱机。Azure应用服务:Azure应用服务是用于托管Web应用程序、RESTAPI
和移动后端的服务。可以使用.NET、NETCore、Java、Ruby、Node.js、PHP或Python等偏好的语
言进行开发。在基于Windows和Linux的环境中,应用程序都可以轻松地运行和缩放。应用服务不仅可将Microsof
tAzure的强大功能(例如安全性、负载均衡、自动缩放和自动管理)添加到应用程序。还能利用其DevOps功能,例如来自Azur
eDevOps、GitHub、Docker中心和其他源的持续部署,以及包管理、过渡环境、自定义域和SSL证书。Azure
DevSpaces:使用AzureDevSpaces,可以测试并以迭代方式开发在AzureKubernetes服务
(AKS)中运行的整个微服务应用程序,而无需复制或模拟依赖项。AzureDevSpaces减少了在共享AzureKu
bernetes服务(AKS)群集中与你的团队协作以及直接在AKS中运行和调试容器的负担,并降低了这些工作的复杂度。阿里
云阿里云(www.aliyun.com)创立于2009年,是全球领先的云计算及人工智能科技公司,为200多个国家和地区的企业、开发
者和政府机构提供服务。2017年1月阿里云成为奥运会全球指定云服务商。2017年8月阿里巴巴财报数据显示,阿里云付费云计算用户超过
100万。阿里云致力于以在线公共服务的方式,提供安全、可靠的计算和数据处理能力,让计算和人工智能成为普惠科技。阿里云在全球18个地
域开放了49个可用区,为全球数十亿用户提供可靠的计算支持。此外,阿里云为全球客户部署200多个飞天数据中心,通过底层统一的飞天操作
系统,为客户提供全球独有的混合云体验。飞天(Apsara)是由阿里云自主研发、服务全球的超大规模通用计算操作系统。它可以将遍布全
球的百万级服务器连成一台超级计算机,以在线公共服务的方式为社会提供计算能力。从PC互联网到移动互联网到万物互联网,互联网成为世界
新的基础设施。飞天希望解决人类计算的规模、效率和安全问题。飞天的革命性在于将云计算的三个方向整合起来:提供足够强大的计算能力,提供
通用的计算能力,提供普惠的计算能力。飞天诞生于2009年2月,目前为全球200多个国家和地区的创新创业企业、政府、机构等提供服务。
同样,阿里云对容器也提供了友好的支持:容器服务ACS容器服务提供高性能可伸缩的容器应用管理服务,支持用Docker和Kubern
etes进行容器化应用的生命周期管理,提供多种应用发布方式和持续交付能力并支持微服务架构。容器服务简化了容器管理集群的搭建工作,整
合了阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器运行环境。容器服务ACK容器服务Kubernetes版(简称ACK
)提供高性能可伸缩的容器应用管理能力,支持企业级Kubernetes容器化应用的全生命周期管理。容器服务Kubernetes
版简化集群的搭建和扩容等工作,整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳的Kubernetes容器化应用运行环境。
弹性容器实例ECI阿里云弹性容器实例(ElasticContainerInstance)是Serverless和容器化的
弹性计算服务。用户无需管理底层ECS服务器,只需要提供打包好的镜像,即可运行容器,并仅为容器实际运行消耗的资源付费。容器镜像服
务ACR容器镜像服务(ContainerRegistry)提供安全的镜像托管能力,稳定的国内外镜像构建服务,便捷的镜像授权功能
,方便用户进行镜像全生命周期管理。容器镜像服务简化了Registry的搭建运维工作,支持多地域的镜像托管,并联合容器服务等云产品,
为用户打造云上使用Docker的一体化体验。腾讯云腾讯云为腾讯倾力打造的云计算品牌,以卓越科技能力助力各行各业数字化转型,为全球客
户提供领先的云计算、大数据、人工智能服务,以及定制化行业解决方案。其基于QQ、微信、腾讯游戏等海量业务的技术锤炼,从基础架构到精细
化运营,从平台实力到生态能力建设,腾讯云将之整合并面向市场,使之能够为企业和创业者提供集云计算、云数据、云运营于一体的云端服务体验
。在容器这块,腾讯云提供了如下解决方案:容器服务TKE腾讯云容器服务(TencentKubernetesEngine,TK
E)基于原生kubernetes提供以容器为核心的、高度可扩展的高性能容器管理服务。腾讯云容器服务完全兼容原生kuberne
tesAPI,扩展了腾讯云的CBS、CLB等kubernetes插件,为容器化的应用提供高效部署、资源调度、服务发现和
动态伸缩等一系列完整功能,解决用户开发、测试及运维过程的环境一致性问题,提高了大规模容器集群管理的便捷性,帮助用户降低成本,提高效
率。容器服务提供免费使用,涉及的其他云产品另外单独计费。容器实例服务CIS容器实例服务(ContainerInstanceS
ervice,CIS)可以帮用户在云上快捷、灵活的部署容器,让用户专注于构建程序和使用容器而非管理设备上。无需预购CVM(云
服务器),就可以在几秒内启动一批容器来执行任务。同时,开发者也可以通过kubernetesAPI把已有kubernetes
集群的pod调度到CIS上以处理突增业务。CIS根据实际使用的资源计费,可以帮用户节约计算成本。使用CIS可以极大降
低用户部署容器的门槛,降低用户执行batch型任务或处理业务突增的成本。1、Kubernetes集群部署及简单命令行操作环境准
备[root@master~]#hostnamectlset-hostnamemaster&&execbash[ro
ot@node01~]#hostnamectlset-hostnamenode01&&execbash[root@n
ode02~]#hostnamectlset-hostnamenode02&&execbash主机名解析[root
@master~]#cat/etc/hosts127.0.0.1???localhostlocalhost.localdo
mainlocalhost4localhost4.localdomain4::1?????????localhostloca
lhost.localdomainlocalhost6localhost6.localdomain6192.168.183.1
1??master192.168.183.12??node01192.168.183.13??node02[root@master
~]#scp/etc/hostsnode01:/etc/Theauthenticityofhost?''node01
(192.168.183.12)''?can''tbeestablished.ECDSAkeyfingerprint?is?S
HA256:e66/gR4gS9VD4XMHWRVVglIHmU6I4/dgBiaB/swFLVM.ECDSAkeyfinge
rprint?is?MD5:fd:2a:6c:8d:f0:c9:c4:b2:8d:2d:05:cb:ac:c0:41:50.Are
yousureyouwantto?continue?connecting(yes/no)?yesWarning:P
ermanentlyadded?''node01,192.168.183.12''?(ECDSA)tothe?list?ofk
nownhosts.root@node01''spassword:hosts??????????????????????????
?????????????????????????????????????????????????????????????????
?????????????????????????????????????????????????????????????????
?????????????????????????????????????????????????????????????????
??????????100%??227????98.2KB/s???00:00[root@master~]#scp/etc/
hostsnode02:/etc/Theauthenticityofhost?''node02(192.168.183.1
3)''?can''tbeestablished.ECDSAkeyfingerprint?is?SHA256:e66/gR4g
S9VD4XMHWRVVglIHmU6I4/dgBiaB/swFLVM.ECDSAkeyfingerprint?is?MD5:
fd:2a:6c:8d:f0:c9:c4:b2:8d:2d:05:cb:ac:c0:41:50.Areyousureyou
wantto?continue?connecting(yes/no)?yesWarning:Permanentlyadd
ed?''node02,192.168.183.13''?(ECDSA)tothe?list?ofknownhosts.roo
t@node02''spassword:hosts三个节点配置K8s镜像yum仓库cat<?/etc/yum.re
pos.d/kubernetes.repo[kubernetes]name=Kubernetesbaseurl=https://m
irrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/enab
led=1gpgcheck=1repo_gpgcheck=1gpgkey=https://mirrors.aliyun.com/k
ubernetes/yum/doc/yum-key.gpghttps://mirrors.aliyun.com/kubernet
es/yum/doc/rpm-package-key.gpgEOF注意防火墙与seLinux都关闭;安装docker-ce;三个
阶段操作yum?-yinstalldocker-ce[root@master~]#vim/usr/lib/systemd
/system/docker.service[Unit]Description=DockerApplicationContai
nerEngineDocumentation=https://docs.docker.comBindsTo=containerd
.serviceAfter=network-online.targetfirewalld.servicecontainerd.
serviceWants=network-online.targetRequires=docker.socket?[Service
]Type=notify#thedefaultisnottousesystemdforcgroupsbecau
sethedelegateissuesstill#existsandsystemdcurrentlydoesn
otsupportthecgroupfeaturesetrequired#forcontainersrunby
dockerEnvironment="HTTPS_PROXY=http://www.ik8s.io:10080"??#国内用户添
加这两个变量Environment="NO_PROXY=127.0.0.0/8,172.20.0.0/16"??#这个ExecS
tart=/usr/bin/dockerd?-Hfd://?--containerd=/run/containerd/conta
inerd.sockExecReload=/bin/kill?-sHUP$MAINPIDTimeoutSec=0Restart
Sec=2Restart=always?#NotethatStartLimitoptionsweremovedfr
om"Service"to"Unit"insystemd229.#Boththeold,andnewloc
ationareacceptedbysystemd229andup,sousingtheoldlocati
on#tomakethemworkforeitherversionofsystemd.StartLimitBur
st=3?#NotethatStartLimitIntervalwasrenamedtoStartLimitInte
rvalSecinsystemd230.#Boththeold,andnewnameareaccepted
bysystemd230andup,sousingtheoldnametomake#thisoption
workforeitherversionofsystemd.StartLimitInterval=60s?#Havi
ngnon-zeroLimitscausesperformanceproblemsduetoaccounting
overhead#inthekernel.Werecommendusingcgroupstodocontai
ner-localaccounting.LimitNOFILE=infinityLimitNPROC=infinityLimit
CORE=infinity?#CommentTasksMaxifyoursystemdversiondoesnot
supportit.#Onlysystemd226andabovesupportthisoption.Task
sMax=infinity?#setdelegateyessothatsystemddoesnotresett
hecgroupsofdockercontainersDelegate=yes?#killonlythedocke
rprocess,notallprocessesinthecgroupKillMode=process?[Insta
ll]WantedBy=multi-user.target安装[root@master~]#yum-yinstallk
ubeletkubeadmkubectl?master安装[root@master~]#systemctl?enabl
ekubelet.service初始化[root@master~]#vim/etc/sysconfig/kubeletK
UBELET_EXTRA_ARGS="--fail-swap-on=false"???#添加初始化参数,忽略swap?[root@
master~]#echo1>/proc/sys/net/bridge/bridge-nf-call-iptables?[
root@master~]#kubeadminit--kubernetes-version=v1.15.1--pod-n
etwork-cidr=10.244.0.0/16--service-cidr=10.96.0.0/12--ignore-pr
eflight-errors=Swap?初始化最后kubeadmjoin?192.168.183.11:6443?--token
lotfu3.ag7oqtqaewlxg9xy\?--discovery-token-ca-cert-hash?sha256:
401c4f4770ef5acb209ec3d2da1c0d0204c2ea790c05ceb32b53f287ccc280ca
启动操作[root@master~]#?mkdir-p$HOME/.kube[root@master~]#cp-i
/etc/kubernetes/admin.conf$HOME/.kube/config[root@master~]#cho
wn$(id-u):$(id-g)$HOME/.kube/config查看[root@master~]#kubect
lgetcsNAME????????????????STATUS???MESSAGE????????????ERRORc
ontroller-manager??Healthy??okscheduler???????????Healthy??ok
etcd-0???????????????Healthy??{"health":"true"}???部署网络插件[root@ma
ster~]#kubectlapply-fhttps://raw.githubusercontent.com/coreo
s/flannel/master/Documentation/kube-flannel.ymlpodsecuritypolicy.
extensions/psp.flannel.unprivilegedcreatedclusterrole.rbac.autho
rization.k8s.io/flannelcreatedclusterrolebinding.rbac.authorizat
ion.k8s.io/flannelcreatedserviceaccount/flannelcreatedconfigmap
/kube-flannel-cfgcreateddaemonset.extensions/kube-flannel-ds-amd
64createddaemonset.extensions/kube-flannel-ds-arm64createddaemo
nset.extensions/kube-flannel-ds-armcreateddaemonset.extensions/k
ube-flannel-ds-ppc64lecreateddaemonset.extensions/kube-flannel-d
s-s390xcreated[root@master~]#kubectlgetnodesNAME????STATUS?
?ROLES???AGE??VERSIONmaster??Ready变成这个状态ok了???master???19m?
??v1.15.1?查看flannel的部署状态[root@master~]#kubectlgetpods-nkube
-systemNAME????????????????????????????READY??STATUS???RESTART
S??AGEcoredns-5c98db65d4-dc2hj?????????1/1?????Running???0??????
????21mcoredns-5c98db65d4-j4zc5?????????1/1?????Running???0??????
????21metcd-master??????????????????????1/1?????Running???0??????
????20mkube-apiserver-master????????????1/1?????Running???0??????
????20mkube-controller-manager-master???1/1?????Running???0??????
????20mkube-flannel-ds-amd64-czvzm??????1/1?????Running???0??????
????4m21s???运行kube-proxy-d5qcj?????????????????1/1?????Running???
0??????????21mkube-scheduler-master????????????1/1?????Running???
0??????????20m查看集群名称空间[root@master~]#kubectlgetnsNAME???????
??????STATUS??AGEdefault??????????Active???23mkube-node-lease?
?Active???23mkube-public??????Active???23mkube-system??????Act
ive???23m两个node安装yum?-yinstallkubeletkubeadm节点配置启动,并加入集群[roo
t@master~]#scp/etc/sysconfig/kubeletnode01:/etc/sysconfig/[ro
ot@master~]#scp/etc/sysconfig/kubeletnode02:/etc/sysconfig/?[
root@node01~]#systemctlenablekubelet.serviceCreatedsymlink?f
rom?/etc/systemd/system/multi-user.target.wants/kubelet.servicet
o?/usr/lib/systemd/system/kubelet.service.[root@node02~]#system
ctlenablekubelet.serviceCreatedsymlink?from?/etc/systemd/syste
m/multi-user.target.wants/kubelet.serviceto?/usr/lib/systemd/sys
tem/kubelet.service.[root@node01~]#echo1>/proc/sys/net/bridg
e/bridge-nf-call-iptables[root@node02~]#echo1>/proc/sys/net/
bridge/bridge-nf-call-iptables[root@node01~]#kubeadmjoin192.1
68.183.11:6443--tokenlotfu3.ag7oqtqaewlxg9xy--discovery-token-
ca-cert-hashsha256:401c4f4770ef5acb209ec3d2da1c0d0204c2ea790c05c
eb32b53f287ccc280ca??--ignore-preflight-errors=Swap[preflight]Ru
nningpre-flightchecks?[WARNINGIsDockerSystemdCheck]:detected?
"cgroupfs"?astheDockercgroupdriver.Therecommendeddriver?is
?"systemd".Pleasefollowtheguideathttps://kubernetes.io/docs
/setup/cri/?[WARNINGSwap]:runningwithswapon?is?not?supported
.Pleasedisableswap?[WARNINGSystemVerification]:thisDockerv
ersion?is?not?onthe?list?ofvalidatedversions:?19.03.0.?Latest
validatedversion:?18.09[preflight]Readingconfiguration?from?th
ecluster...[preflight]FYI:Youcanlookatthisconfig?file?wit
h?''kubectl-nkube-systemgetcmkubeadm-config-oyaml''[kubelet-s
tart]Downloadingconfiguration?for?thekubelet?from?the?"kubelet
-config-1.15"?ConfigMap?in?thekube-systemnamespace[kubelet-star
t]Writingkubeletconfigurationto?file?"/var/lib/kubelet/config
.yaml"[kubelet-start]Writingkubeletenvironment?file?withflags
to?file?"/var/lib/kubelet/kubeadm-flags.env"[kubelet-start]Acti
vatingthekubeletservice[kubelet-start]Waiting?for?thekubelet
toperformtheTLSBootstrap...?Thisnodehasjoinedthecluster
:?Certificatesigningrequestwassenttoapiserver?and?arespon
sewasreceived.?TheKubeletwasinformedofthenewsecureconn
ectiondetails.?Run?''kubectlgetnodes''?onthecontrol-planetos
eethisnodejointhecluster.???[root@node02~]#kubeadmjoin19
2.168.183.11:6443--tokenlotfu3.ag7oqtqaewlxg9xy--discovery-tok
en-ca-cert-hashsha256:401c4f4770ef5acb209ec3d2da1c0d0204c2ea790c
05ceb32b53f287ccc280ca??--ignore-preflight-errors=Swap[preflight]
Runningpre-flightchecks?[WARNINGIsDockerSystemdCheck]:detect
ed?"cgroupfs"?astheDockercgroupdriver.Therecommendeddriver
?is?"systemd".Pleasefollowtheguideathttps://kubernetes.io/d
ocs/setup/cri/?[WARNINGSwap]:runningwithswapon?is?not?suppor
ted.Pleasedisableswap?[WARNINGSystemVerification]:thisDocke
rversion?is?not?onthe?list?ofvalidatedversions:?19.03.0.?Late
stvalidatedversion:?18.09[preflight]Readingconfiguration?from
?thecluster...[preflight]FYI:Youcanlookatthisconfig?file?
with?''kubectl-nkube-systemgetcmkubeadm-config-oyaml''[kubele
t-start]Downloadingconfiguration?for?thekubelet?from?the?"kube
let-config-1.15"?ConfigMap?in?thekube-systemnamespace[kubelet-s
tart]Writingkubeletconfigurationto?file?"/var/lib/kubelet/con
fig.yaml"[kubelet-start]Writingkubeletenvironment?file?withfl
agsto?file?"/var/lib/kubelet/kubeadm-flags.env"[kubelet-start]A
ctivatingthekubeletservice[kubelet-start]Waiting?for?thekube
lettoperformtheTLSBootstrap...?Thisnodehasjoinedtheclus
ter:?Certificatesigningrequestwassenttoapiserver?and?ares
ponsewasreceived.?TheKubeletwasinformedofthenewsecurec
onnectiondetails.?Run?''kubectlgetnodes''?onthecontrol-planet
oseethisnodejointhecluster.主节点查看nodes信息[root@master~]#ku
bectlgetnodesNAME????STATUS??ROLES???AGE????VERSIONmaster??
Ready???master???33m?????v1.15.1node01??Ready?3m28s???v1
.15.1node02??Ready?3m3s????v1.15.1查看node节点详细信息[root@maste
r~]#kubectldescribenodenode01查看版本信息[root@master~]#kubectl
versionClientVersion:version.Info{Major:"1",Minor:"15",GitVe
rsion:"v1.15.1",GitCommit:"4485c6f18cee9a5d3c3b4e523bd27972b1b53
892",GitTreeState:"clean",BuildDate:"2019-07-18T09:18:22Z",GoV
ersion:"go1.12.5",Compiler:"gc",Platform:"linux/amd64"}ServerV
ersion:version.Info{Major:"1",Minor:"15",GitVersion:"v1.15.1",
GitCommit:"4485c6f18cee9a5d3c3b4e523bd27972b1b53892",GitTreeSta
te:"clean",BuildDate:"2019-07-18T09:09:21Z",GoVersion:"go1.12.5
",Compiler:"gc",Platform:"linux/amd64"}查看集群详细信息[root@master~]
#kubectlcluster-infoKubernetesmaster?is?runningathttps://192
.168.183.11:6443KubeDNS?is?runningathttps://192.168.183.11:6443
/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy?Tofur
therdebug?and?diagnoseclusterproblems,use?''kubectlcluster-in
fodump''.干跑一个pod;--dry-run=true[root@master~]#kubectlrunngin
x?--image=nginx:1.14-alpine--port=80--replicas=1--dry-run=tru
e创建一个pod,使用deployment控制器[root@master~]#kubectlrunnginx?--im
age=nginx:1.14-alpine--port=80--replicas=1kubectlrun?--generat
or=deployment/apps.v1?is?DEPRECATED?and?willberemoved?in?afutu
reversion.Usekubectlrun?--generator=run-pod/v1?or?kubectl?cre
ateinstead.deployment.apps/nginxcreated查看deployment控制器下的pod容器[
root@master~]#kubectlgetdeploymentNAME???READY??UP-TO-DATE?
?AVAILABLE??AGEnginx???1/1?????1????????????1???????????2m8s查看
pod信息[root@master~]#kubectlgetpodsNAME???????????????????REA
DY??STATUS???RESTARTS??AGEnginx-5896f46c8-72wm4???1/1?????Runn
ing???0??????????5m39s查看pod详细信息[root@master~]#kubectlgetpods
-owideNAME???????????????????READY??STATUS???RESTARTS??AGE?
??IP??????????NODE????NOMINATEDNODE??READINESSGATESnginx-58
96f46c8-72wm4???1/1?????Running???0??????????8m1s???10.244.1.2???
node01在node01查看IP[root@node01~]#ipa1:lo:ACK,UP,LOWER_UP>mtu?65536?qdiscnoqueuestateUNKNOWNgroupdefa
ultqlen?1000?link/loopback?00:00:00:00:00:00?brd?00:00:00:00:00:
00?inet?127.0.0.1/8?scopehostlo?valid_lftforeverpreferred_lft
forever?inet6::1/128?scopehost?valid_lftforeverpreferred_lft
forever2:ens33:mtu?1500?qdis
cpfifo_faststateUPgroupdefaultqlen?1000?link/ether?00:0c:29
:2b:3b:45?brdff:ff:ff:ff:ff:ff?inet?192.168.183.12/24?brd?192.16
8.183.255?scope?global?noprefixrouteens33?valid_lftforeverpref
erred_lftforever?inet6fe80::8dc3:2482:a2b9:c57e/64?scopelinkt
entativenoprefixroutedadfailed?valid_lftforeverpreferred_lft
forever?inet6fe80::10dc:280:ec28:2db4/64?scopelinknoprefixrout
e?valid_lftforeverpreferred_lftforever3:docker0:BROADCAST,MULTICAST,UP>mtu?1500?qdiscnoqueuestateDOWNgroupd
efault?link/ether?02:42:62:cd:a6:bebrdff:ff:ff:ff:ff:ff?inet?17
2.17.0.1/16?brd?172.17.255.255?scope?global?docker0?valid_lftfor
everpreferred_lftforever4:flannel.1:OWER_UP>mtu?1450?qdiscnoqueuestateUNKNOWNgroupdefault?link/
ether?02:ee:3c:55:af:8f?brdff:ff:ff:ff:ff:ff?inet?10.244.1.0/32?
scope?global?flannel.1?valid_lftforeverpreferred_lftforever?in
et6fe80::ee:3cff:fe55:af8f/64?scopelink?valid_lftforeverprefe
rred_lftforever5:cni0:mtu?14
50?qdiscnoqueuestateUPgroupdefaultqlen?1000?link/ether?26:a
c:1e:b1:29:a4brdff:ff:ff:ff:ff:ff?inet?10.244.1.1/24?scope?glob
al?cni0?valid_lftforeverpreferred_lftforever?inet6fe80::24ac:
1eff:feb1:29a4/64?scopelink?valid_lftforeverpreferred_lftfore
ver6:veth64e1c1fd@if3:mtu?145
0?qdiscnoqueuemastercni0stateUPgroupdefault?link/ether?8a:
a3:86:62:9f:5d?brdff:ff:ff:ff:ff:fflink-netnsid?0?inet6fe80::8
8a3:86ff:fe62:9f5d/64?scopelink?valid_lftforeverpreferred_lft
forever集群节点上访问,集群那个节点都可以访问[root@master~]#curl10.244.1.2YPEhtml>Welcometonginx!

Welcometonginx!

<
p>Ifyouseethispage,thenginxwebserver?is?successfullyinst
alled?andworking.Furtherconfiguration?is?required.

?

Foro
nlinedocumentation?and?supportpleaserefertoinx.org/">nginx.org.
Commercialsupport?is?availableathref="http://nginx.com/">nginx.com.

?

Thankyou?for
?usingnginx.

控制器检查pod挂掉自动创建pod功能[root@mas
ter~]#kubectlgetpods??查看NAME???????????????????READY??STAT
US???RESTARTS??AGEnginx-5896f46c8-72wm4???1/1?????Running???0??
????????15m[root@master~]#kubectldeletepodsnginx-5896f46c8-7
2wm4??算出pod?"nginx-5896f46c8-72wm4"?deleted[root@master~]#kube
ctlgetpods??创建恢复NAME???????????????????READY??STATUS????????
?????RESTARTS??AGEnginx-5896f46c8-zblcs???0/1?????ContainerCrea
ting???0??????????15s[root@master~]#kubectlgetpods??恢复可用状态NA
ME???????????????????READY??STATUS???RESTARTS??AGEnginx-5896f
46c8-zblcs???1/1?????Running???0??????????98s[root@master~]#kub
ectlgetpod-owideNAME???????????????????READY??STATUS???RES
TARTS??AGE???IP??????????NODE????NOMINATEDNODE??READINESSG
ATESnginx-5896f46c8-zblcs???1/1?????Running???0??????????117s???1
0.244.2.2???node02把pod暴露参数选项介绍;即创建服务--type='''':Type
forthisservice:ClusterIP:只能各个访问不能提供给外部访问,NodePort,LoadBalan
cer,orExternalName.Defaultis''ClusterIP'':默认类型.????kubectlexp
ose(-fFILENAME|?TYPE?NAME)[--port=指定暴露给外网端口][--protocol=TCP|
UDP|SCTP][--target-port=pod][--name=server名称][--external-ip=ex
ternal-ip-of-service][--type=类型][options]把暴露给集群内部pod访问[root@ma
ster~]#kubectlexposedeployment控制器类型nginx控制器名字--name=nginx-
-port=80--target-port=80service/nginxexposed查看创建的服务[root@maste
r~]#kubectlgetsvcNAME?????????TYPE????????CLUSTER-IP?????EXT
ERNAL-IP??PORT(S)??AGEkubernetes??ClusterIP???10.96.0.1?
443/TCP???101mnginx???????ClusterIP???10.110.130.60?80/TCP
????2m44s??#是被pod客户端访问的查看服务的详细信息[root@master~]#kubectldescrib
esvcnginxName:?????????????nginxNamespace:????????defaultLabe
ls:???????????run=nginxAnnotations:Selector:?????????run=
nginxType:?????????????ClusterIPIP:????????????????10.110.130.60
Port:?80/TCPTargetPort:????????80/TCPEndpoints:?????????10
.244.2.2:80SessionAffinity:??NoneEvents:查看pod的标签[root@mas
ter~]#kubectlgetpods--show-labelsNAME???????????????????REA
DY??STATUS????????????RESTARTS??AGE????LABELSnginx-5896f46c8-
zblcs???1/1?????Running????????????0??????????52m?????pod-templat
e-hash=5896f46c8,run=nginx删除服务[root@master~]#kubectldeletesv
cnginxservice?"nginx"?deleted查看控制器详细信息[root@master~]#kubectl
describedeploymentnginxName:??????????????????nginxNamespace:?
????????????defaultCreationTimestamp:?????Thu,?25?Jul?2019?13:1
5:04?+0800Labels:????????????????run=nginxAnnotations:??????????
?deployment.kubernetes.io/revision:?1Selector:??????????????run
=nginxReplicas:???????????????1?desired|?1?updated|?1?total|?1
?available|?0?unavailableStrategyType:??????????RollingUpdateMi
nReadySeconds:????????0RollingUpdateStrategy:??25%?max?unavailabl
e,?25%?max?surgePodTemplate:?Labels:?run=nginx?Containers:?ngin
x:?Image:???????nginx:1.14-alpine?Port:?????????80/TCP?HostPort
:????0/TCP?Environment:??Mounts:?Volumes:Condi
tions:?Type???????????Status?Reason?----???????????------??-----
-?Progressing????True????NewReplicaSetAvailable?Available??????Tr
ue????MinimumReplicasAvailableOldReplicaSets:?NewReplicaSe
t:??nginx-5896f46c8?(1/1?replicascreated)Events:动态调整desc
ribe的控制器pod的副本数[root@master~]#kubectlrunmyapp--image=ikubern
etes/myapp:v1--replicas=2??起一个2副本的podkubectlrun?--generator=de
ployment/apps.v1?is?DEPRECATED?and?willberemoved?in?afutureve
rsion.Usekubectlrun?--generator=run-pod/v1?or?kubectlcreatei
nstead.deployment.apps/myappcreated[root@master~]#kubectlget
deployment查看控制器下的podNAME???READY??UP-TO-DATE??AVAILABLE??AGE
myapp???2/2?????2????????????2???????????110snginx???1/1?????1???
?????????1???????????84m^C[root@master~]#kubectlgetpods-owi
de??查看集群总的podNAME????????????????????READY??STATUS????????????
RESTARTS??AGE????IP??????????NODE????NOMINATEDNODE??READIN
ESSGATESmyapp-84cd4b7f95-px2kb???1/1?????Running????????????0???
???????3m27s???10.244.2.4???node02myapp-84cd4b7f95-x
fcnk???1/1?????Running????????????0??????????3m27s???10.244.1.6??
?node01nginx-5896f46c8-zblcs????1/1?????Running?????
???????0??????????69m?????10.244.2.2???node02[root@m
aster~]#kubectlexposedeploymentmyapp--name=myapp--port=80s
ervice/myappexposed[root@master~]#kubectlgetsvcNAME?????????
TYPE????????CLUSTER-IP??????EXTERNAL-IP??PORT(S)??AGEkubernete
s??ClusterIP???10.96.0.1?443/TCP???153mmyapp???????Cluste
rIP???10.103.191.244?80/TCP????35snginx???????ClusterIP???
10.108.177.175?80/TCP????17m[root@master~]#kubectlscale
--replicas=4deploymentmyapp?扩容到4个deployment.extensions/myapps
caled[root@master~]#kubectlgetpods-owide?NAME??????????????
??????READY??STATUS?????????????RESTARTS??AGE??IP??????????
NODE????NOMINATEDNODE??READINESSGATESmyapp-84cd4b7f95-px2kb??
?1/1?????Running?????????????0??????????30m???10.244.2.4???node02
myapp-84cd4b7f95-tjgqz???1/1?????Running????????????
?0??????????3s????10.244.2.5???node02myapp-84cd4b7f9
5-vphlz???0/1?????ContainerCreating???0??????????3snode01<
none>myapp-84cd4b7f95-xfcnk???1/1?????Running?????????????
0??????????30m???10.244.1.6???node01nginx-5896f46c8-
zblcs????1/1?????Running?????????????0??????????96m???10.244.2.2?
??node02[root@master~]#kubectlgetpods-owide?NA
ME????????????????????READY??STATUS????????????RESTARTS??AGE?
?IP??????????NODE????NOMINATEDNODE??READINESSGATESmyapp-84c
d4b7f95-px2kb???1/1?????Running????????????0??????????30m???10.24
4.2.4???node02myapp-84cd4b7f95-tjgqz???1/1?????Runni
ng????????????0??????????5s????10.244.2.5???node02my
app-84cd4b7f95-vphlz???1/1?????Running????????????0??????????5s??
??10.244.1.7???node01myapp-84cd4b7f95-xfcnk???1/1???
??Running????????????0??????????30m???10.244.1.6???node01<
none>nginx-5896f46c8-zblcs????1/1?????Running????????????0???????
???96m???10.244.2.2???node02[root@master~]#kubectl
scale--replicas=1deploymentmyapp?缩减到一个poddeployment.extensio
ns/myappscaled[root@master~]#kubectlgetpods-owide?NAME????
????????????????READY??STATUS????????????RESTARTS??AGE??IP??
????????NODE????NOMINATEDNODE??READINESSGATESmyapp-84cd4b7f9
5-xfcnk???1/1?????Running????????????0??????????31m???10.244.1.6?
??node01nginx-5896f46c8-zblcs????1/1?????Running????
????????0??????????97m???10.244.2.2???node02更新升级pod
[root@master~]#kubectldescribepodsmyapp-84cd4b7f95-xfcnkName
:??????????myapp-84cd4b7f95-xfcnkNamespace:?????defaultPriority
:???????0Node:??????????node01/192.168.183.12StartTime:????Thu
,?25?Jul?2019?14:37:33?+0800Labels:????????pod-template-hash=84c
d4b7f95?run=myappAnnotations:Status:????????RunningIP:????
?????????10.244.1.6ControlledBy:?ReplicaSet/myapp-84cd4b7f95Con
tainers:?myapp:?Container?ID:??docker://c13e99d23870a37627bc6b20
7a6b71f8d306f0a73f58515e57f4d964070b0df9?Image:?????????ikuberne
tes/myapp:v1??#镜像版本?Image?ID:??????docker-pullable://ikubernetes
/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03
330999d30d513?Port:?HostPort:?State:?????????Runnin
g?Started:?????Thu,?25?Jul?2019?14:37:51?+0800?Ready:??????????T
rue?RestartCount:??0?Environment:?Mounts:?/var/run/secrets
/kubernetes.io/serviceaccount?from?default-token-2m2ts?(ro)Condit
ions:?Type??????????????Status?Initialized???????True?Ready??????
???????True?ContainersReady???True?PodScheduled??????TrueVolumes:
?default-token-2m2ts:?Type:???????Secret(avolumepopulatedby
aSecret)?SecretName:?default-token-2m2ts?Optional:???falseQoS
Class:??????BestEffortNode-Selectors:?Tolerations:????no
de.kubernetes.io/not-ready:NoExecute?for?300s?node.kubernetes.io/
unreachable:NoExecute?for?300sEvents:?Type????Reason????Age??Fr
om??????????????Message?----????------?????----??----???????????
????-------?Normal?Scheduled??35m???default-scheduler?Successfu
llyassigneddefault/myapp-84cd4b7f95-xfcnktonode01?Normal?Pul
ling????35m???kubelet,node01???Pullingimage?"ikubernetes/myapp
:v1"?Normal?Pulled?????34m???kubelet,node01???Successfullypul
ledimage?"ikubernetes/myapp:v1"?Normal?Created????34m???kubelet
,node01???Createdcontainermyapp?Normal?Started????34m???kube
let,node01???Startedcontainermyapp????[root@master~]#kubect
lsetimagedeploymentmyappmyapp=ikubernetes/myapp:v2deployment
.extensions/myappimageupdated?????kubectl?set?imagedeployment
myappmyapp=ikubernetes/myapp:v2??解释set替换镜像deployment控制类型mya
pp控制器名字myapp=表示更新这个pod的镜像??[root@master~]#kubectldescribepo
dsmyapp-746644f8d6-d7m7xName:??????????myapp-746644f8d6-d7m7xNa
mespace:?????defaultPriority:???????0Node:??????????node02/192.
168.183.13StartTime:????Thu,?25?Jul?2019?15:18:39?+0800Labels:?
???????pod-template-hash=746644f8d6?run=myappAnnotations:S
tatus:????????RunningIP:?????????????10.244.2.6ControlledBy:?R
eplicaSet/myapp-746644f8d6Containers:?myapp:?Container?ID:??dock
er://78184c2d58c04372e866da2f3e406a48257b0f97c831f54499b92b8d1dc4
0676?Image:?????????ikubernetes/myapp:v2??更新后镜像?Image?ID:??????
docker-pullable://ikubernetes/myapp@sha256:85a2b81a62f09a414ea33
b74fb8aa686ed9b168294b26b4c819df0be0712d358?Port:?HostPort
:?State:?????????Running?Started:?????Thu,?25?Jul?2019?15
:18:50?+0800?Ready:??????????True?RestartCount:??0?Environment:<
none>?Mounts:?/var/run/secrets/kubernetes.io/serviceaccount?from?
default-token-2m2ts?(ro)Conditions:?Type??????????????Status?Init
ialized???????True?Ready?????????????True?ContainersReady???True?
PodScheduled??????TrueVolumes:?default-token-2m2ts:?Type:???????
Secret(avolumepopulatedbyaSecret)?SecretName:?default-toke
n-2m2ts?Optional:???falseQoSClass:??????BestEffortNode-Selecto
rs:?Tolerations:????node.kubernetes.io/not-ready:NoExecut
e?for?300s?node.kubernetes.io/unreachable:NoExecute?for?300sEvent
s:?Type????Reason????Age???From??????????????Message?----????-
-----?????----???----???????????????-------?Normal?Scheduled??4m
9s???default-scheduler?Successfullyassigneddefault/myapp-74664
4f8d6-d7m7xtonode02?Normal?Pulling????4m8s???kubelet,node02??
?Pullingimage?"ikubernetes/myapp:v2"?Normal?Pulled?????3m58s??
kubelet,node02???Successfullypulledimage?"ikubernetes/myapp:v
2"?Normal?Created????3m58s??kubelet,node02???Createdcontainer
myapp?Normal?Started????3m58s??kubelet,node02???Startedconta
inermyapppod回滚操作[root@master~]#kubectlrolloutundodeploymen
tmyapp?回滚到上一个版本deployment.extensions/myapprolledback[root@mas
ter~]#kubectldescribepodsmyapp-84cd4b7f95-g6ldpName:????????
??myapp-84cd4b7f95-g6ldpNamespace:?????defaultPriority:???????0
Node:??????????node01/192.168.183.12StartTime:????Thu,?25?Jul?
2019?15:27:48?+0800Labels:????????pod-template-hash=84cd4b7f95?r
un=myappAnnotations:Status:????????RunningIP:?????????????
10.244.1.8ControlledBy:?ReplicaSet/myapp-84cd4b7f95Containers:?
myapp:?Container?ID:??docker://7711bfc3da100aa6f25ebbde6b5a25009
47501fe2fc1706dec75662f98fe86c0?Image:?????????ikubernetes/myapp
:v1??#回滚操作?Image?ID:??????docker-pullable://ikubernetes/myapp@sh
a256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30
d513?Port:?HostPort:?State:?????????Running?Started
:?????Thu,?25?Jul?2019?15:27:49?+0800?Ready:??????????True?Resta
rtCount:??0?Environment:?Mounts:?/var/run/secrets/kubernet
es.io/serviceaccount?from?default-token-2m2ts?(ro)Conditions:?Typ
e??????????????Status?Initialized???????True?Ready?????????????Tr
ue?ContainersReady???True?PodScheduled??????TrueVolumes:?default-
token-2m2ts:?Type:???????Secret(avolumepopulatedbyaSecret)
?SecretName:?default-token-2m2ts?Optional:???falseQoSClass:???
???BestEffortNode-Selectors:?Tolerations:????node.kubern
etes.io/not-ready:NoExecute?for?300s?node.kubernetes.io/unreachab
le:NoExecute?for?300sEvents:?Type????Reason????Age??From???????
???????Message?----????------?????----??----???????????????-----
--?Normal?Scheduled??66s???default-scheduler?Successfullyassig
neddefault/myapp-84cd4b7f95-g6ldptonode01?Normal?Pulled?????6
5s???kubelet,node01???Containerimage?"ikubernetes/myapp:v1"?al
readypresentonmachine?Normal?Created????65s???kubelet,node01
???Createdcontainermyapp?Normal?Started????65s???kubelet,nod
e01???Startedcontainermyapp修改服务类型让外部访问到pod[root@master~]#ku
bectleditsvcmyapp?#Pleaseedittheobjectbelow.Linesbeginn
ingwitha''#''willbeignored,#andanemptyfilewillabortthe
edit.Ifanerroroccurswhilesavingthisfilewillbe#reopene
dwiththerelevantfailures.#apiVersion:v1kind:Servicemetadata
:?creationTimestamp:?"2019-07-25T06:45:50Z"?labels:?run:myapp?na
me:myapp?namespace:default?resourceVersion:?"18434"?selfLink:?/
api/v1/namespaces/default/services/myapp?uid:acaab49a-e372-427f-
b6a3-d712eb2b11d1spec:?clusterIP:?10.103.191.244?externalTrafficP
olicy:Cluster?ports:?-?nodePort:?31339?port:?80?protocol:TCP?ta
rgetPort:?80?selector:?run:myapp?sessionAffinity:?None?type:Nod
ePort?修改为这个status:?loadBalancer:{}[root@master~]#kubectlget
svcNAME?????????TYPE????????CLUSTER-IP??????EXTERNAL-IP??PORT(S
)???????AGEkubernetes??ClusterIP???10.96.0.1?443/TCP?????
???3h24mmyapp???????NodePort????10.103.191.244?80:31339/TC
P???51mnginx???????ClusterIP???10.108.177.175?80/TCP??????
???68m集群外部访问端口所有节点的31339访问测试[root@master~]#curl?192.168.183.1
1:31339HelloMyApp|Version:v1|PodNa
me[root@master~]#curl?192.168.183.12:31339HelloMyApp|Ve
rsion:v1|PodName[root@master~]#
curl?192.168.183.13:31339HelloMyApp|Version:v1|stname.html">PodNameDocker安装和使用在Linux安装命令:yuminstall-ydoc
ker-io查看docker版本:dockerversion启动docker服务:servicedockerstart停止
docker服务:servicedockerstop查看docker存储位置:dockerinfo查看docker镜像:d
ockerimages查看docker容器:dockerps启动docker容器:dockerstart容器名称(con
tainerID)停止docker容器:dockerstop容器名称(containerID)卸载docker容器:docke
rrmi容器名称(containerID)1.内部服务器安装docker由于公司内部的服务器不可以链接外网,所以安装docke
r需要使用公司内部的源,因此需要进行Linux的yum配置:①确认yum服务SSL根证书,确认文件/etc/pki/tls/cer
ts/Tencent-tlinux-Root.crt;②确认yum源的配置,见/etc/yum.repos.d/,应该包epel.
repo和tlinux.repo两个文件;③确认yum服务器ip,可以查看/etc/hosts文件,yum服务器域名ip对应关系如
下:10.240.99.238tlinux-mirrorlist.tencent-cloud.comtlinux-mirror
.tencent-cloud.com10.168.134.78tlinux-mirrorlist.tencent-cloud.c
omtlinux-mirror.tencent-cloud.com10.12.216.232tlinux-mirrorlist
.tencent-cloud.comtlinux-mirror.tencent-cloud.com以上的配置完成后,就可以使用y
uminstalldocker命令直接安装docker了,安装完成后使用systemstlstartdocker.serv
ice命令来启动docker服务,然后使用dockerversion命令可以查看docker的版本:每次启动docker服务后
,都需要查看docker版本信息,确保服务已经正常运行。CentOS7系列安装docker我自己笔记本虚拟机安装的是CentOS
7版本的操作系统,可以连接上外网,所以可以使用EPEL软件仓库安装docker,可以直接使用yuminstalldocker
-io就可以了。如果是Centos6版本需要先升级到CentOS7版本,再进行以上的操作。完成docker安装后,如果需要doc
ker服务跟随服务器开机一起启动,可以使用chkconfigdockeron命令。Docker创建首先我们创建一个基于Cent
OS7镜像的容器,使用dockerrun-it--nameCentOS7_testCentOS7/bin/bas
h命令,创建容器成功后直接运行,也可以使用dockercreate创建容器,会返回容器的ID,此时需要使用dockerstar
t命令启动容器,启动后使用dockerattach命令进入该容器:退出容器后可以使用dockerps-a查看在本服务器上创建
的容器:守护态运行Docker在后台以守护态(Daemonized)形式运行,可以使用—d参数实现。例如在服务器上后台运行一个间隔
一秒输出一个helloworld的容器:此时如果需要获取容器的输出信息我们可以使用dockerlogs命令。终止、删除容器当需
要终止一个容器的时候可以使用dockerstop和dockerkill命令。两个命令是有区别的,dockerstop首先是向
容器发送SIGTERM信号,等待一段时间后在发送SIGKILL来终止容器;dockerkill命令会直接发送SIGKILL信号来
强行终止容器。容器不再使用之后可以使用dockerrm命令删除,dockerrm只可以删除处于终止或者退出的状态的容器,不可以
删除处于运行态的容器,如果要删除一个运行态的容器可以加上-f参数。常用基本命令思维导图:1,Docker基本命令;启动Docker
:systemctlstartdocker停止Docker:systemctlstopdocker重启Docker:sys
temctlrestartdocker开机启动Docker:systemctlenabledocker查看Docker概要
信息:dockerinfo查看Docker帮助文档:docker--helpdocker帮助用法:docker[选项]命令
选项--客户端配置文件的配置字符串位置(默认为“/root/.docker”)-D,?--启用调试模式-H,?--要连接的
主机列表守护进程套接字-l,?--设置日志级别的字符串(“调试”|“信息”|“警告”|“错误”|“致命”)(默认“信息”)--
tls使用tls;暗示了--tlsverify--tlscacertstring?仅由此CA签名的信任证书(默认为“/root
/.docker/CA.pem”)--tlscertstring?TLS证书文件的路径(默认为“/root/.docke
r/cert.pem”)--tlskeystring?TLS密钥文件路径(默认为“/root/.docker/key.pem
”)--tlsverify使用TLS并验证远程-v,--version打印版本信息并退出管理命令builder管理构建confi
g码头工人管理配置container?管理容器engine管理docker引擎image管理图像network管理网络node管
理群节点plugin管理插件secret管理码头工人的秘密service管理服务stack管理码头工人栈swarm管理群syste
m管理码头工人trust管理Docker映像上的信任volume管理卷命令attach将本地标准输入、输出和错误流附加到正在运行的
容器中build从Dockerfile构建一个映像commit从容器的更改中创建一个新映像cp在容器和本地文件系统之间复制文件/文
件夹create创建一个新容器diff检查容器文件系统上文件或目录的更改events从服务器获取实时事件exec在正在运行的容器中
运行命令export将容器的文件系统导出为tar存档文件history显示图像的历史images图片列表import从tarbal
l导入内容以创建文件系统映像info显示整个系统的信息inspect返回Docker对象的底层信息kill杀死一个或多个正在运行的
容器load从tar存档或STDIN加载图像login登录到Docker注册表logout从Docker注册表注销logs获取容器
的日志pause暂停一个或多个容器中的所有进程port列出容器的端口映射或特定映射ps列表容器pull从注册表中提取映像或存储库p
ush将映像或存储库推入注册表rename重命名一个容器restart重新启动一个或多个容器rm移除一个或多个容器rmi删除一个或
多个图像run在新容器中运行命令save将一个或多个图像保存到tar存档文件(默认情况下流到STDOUT)search在Docke
r集线器中搜索图像start启动一个或多个停止的容器stats显示容器资源使用统计数据的实时流stop停止一个或多个正在运行的容器
tag创建一个引用SOURCE_IMAGE的标记TARGET_IMAGEtop显示容器的运行进程unpause在一个或多个容器中暂
停所有进程update更新一个或多个容器的配置version显示Docker版本信息wait阻塞,直到一个或多个容器停止,然后打印
它们的退出代码查看Docker版本信息:dockerversion2,Docker镜像1,dockerimages列出本机所有
镜像在上述命令后面加上一些可选参数,如:2,dockersearch搜索镜像这个命令呢其实和在https://hub.docke
r.com/这里搜索是一样的效果3,dockerpull下载镜像比方说我们下载nginx,就是dockerpullnginx
;4,dockerrmi?删除镜像其中删除单个:dockerrmi镜像名称其中有时候若有镜像生成的容器再运行的时候,会报错并
且删除失败;这个时候需要加-f强制删除删除多个:dockerrmi?-f镜像名称1:[TAG]镜像名称2:[TAG]中间
空格隔开删除全部:dockerrmi-f$(dockerimages-qa)第四章Dockerimages的获取和使
用Dockerimages是docker的三大组件之一。Docker运行容器之前需要本地存在对应的镜像,如果本地没有,则dock
er会尝试从默认的镜像仓库中下载,因为公司服务器无法连接到外网,因此只可以通过配置在公司的镜像仓库中下载,公司所有的镜像都保存在d
ocker.oa.com中。获取镜像首先是查看本地有哪些镜像,使用dockerimages命令:通过列出的信息我们可以看到以下信
息:①镜像来自哪一个仓库,例如docker.oa.com/public/httpd存放的是httpd的镜像;②镜像的标签信息TAG
,例如latest、v3.1.1用来标记不同的版本信息,标签只是标记,不可以唯一识别一个镜像;③IMAGEID是唯一的镜像标识,
例如httpd和docker.oa.com/public/httpd的镜像ID都是一样的8c7b3c080df8,说明他们俩都指向
同一个镜像;④CREATED创建时间说明镜像的最后更新时间;⑤SIZE镜像大小,优秀的镜像往往体积都比较小。上面我们看到了同一个镜
像有两个名字,因为使用了tag给镜像加标签了,例如我们使用dockertagdocker.oa.com/docker/ngin
xnginx表示给镜像docker.oa.com/docker/nginx加一个标签nginx,我们再次使用dockerima
ges查看多了一个nginx镜像,但是ID和docker.oa.com/docker/nginx是一致的。查找镜像公司内部的所有镜
像都在docker.oa.com上,我们在查找镜像的时候使用dockersearch命令可以找到自己需要的镜像,例如我需要查找一
个centos的镜像:dockersearchdocker.oa.com/centos查找镜像的时候出现了一点小插曲,在输入命
令之后出现了问题,返回为问题是https的协议有问题没有返回,估计是在之前的操作中无意修改了什么文件,因此需要安装https的证书
。配置完成以后就可以使用dockersearch命令了:下载镜像找到自己需要的镜像docker.oa.com/deeplearn
ing/centos-6.5-x86_64,然后使用dockerpull命令就可以下载了:我们可以很清晰的看到,下载的镜像是分层
保存的。我们可以使用dockerimages看到刚才下载的镜像,给刚才的镜像加一个标签CentOS7,然后就可以使用这个镜像了
。创建自己的镜像自己创建镜像有两种方法:①使用dockercommit来扩展一个image,②从dockerfile来创建ima
ges。①使用dockercommit来扩展一个image先使用images启动一个容器,添加应用程序后退出,然后使用docke
rcommit命令提交相应的副本,然后就可以得到新的镜像,这种方法主要用在给镜像扩展功能上。例如我们使用刚才的容器fed7294
451a4给它安装GCC功能退出后,使用dockercommit-m="AddedGcc"-a="shanksli"f
ed7294451a4ouruser/CentOS7:v1.0创建一个名为ouruser/CentOS7标签为v1.0的新镜
像,使用dockerps-a可以查看:②从dockerfile来创建images使用dockercommit来扩展一个ima
ge比较简单,但它不容易在一个团队中分享它。我们使用dockerbuild来创建一个新的image。首先需要创建一个docke
rfile,包含一些如何创建我们的image的指令。例如我是想制作一个centos的镜像,首先我去dockerhub的官网上下载
centos的镜像,https://github.com/CentOS/sig-cloud-instance-images/blo
b/e37f28d8f4a2a5970ee9dec81d49d483ac1e4ae8/docker/centos-7-docker
.tar.xz下载成功后,先把该文件上传到跳板机,然后再通过scp命令上传到服务器刚才新建的文件夹中,此处略去了把镜像上传到10.
49.89.197:/home/shanksli/workspace/docker_image下的步骤,然后进入服务器进入刚才的目
录/home/shanksli/workspace/docker_image,新建一个文件Dockerfile,之后编写docke
rfile文件,dockerfile中添加的内容如下:FROMscratchADDcentos-7-docker.tar.xz
/LABELname="CentOSBaseImage"\vendor="CentOS"\license="GPL
v2"\build-date="20170731"CMD["/bin/bash"]上面dockerfile中的内容FROM命
令会指定镜像是基于哪一个基础镜像创建的,该命令可以使用多次,表示会创建多个镜像;ADD用于复制构建环境中的文件或目录到镜像中;LA
BEL用于为镜像添加元数据,元数以键值对的形式指定,包含了镜像的名称版本信息以及创建日期等;CMD用于指定在容器启动时所要执行的命
令。添加内容成功后保存退出,然后使用dockerbuild命令创建新的镜像。截图从镜像放到文件下开始:创建成功后使用docker
images就可以查看到我们刚才新建的镜像mycentos,并且可以使用dockerinspect查看镜像的详细信息:也可以
使用dockerinspect-f指定参数:我们可以在上面的图中看到在build进程执行的过程中,它要做的第一件事情就是上传
这个Dockerfile文件中的内容,因为所有的操作都是按照Dockerfile中的文件来执行的。我们看到Dockerfile中的
指令是一条一条的执行的,每一步都创建一个容器,在容器中执行指令并且按照前面dockercommit方法扩展一个镜像,当所有的命令
都执行完毕之后,返回一个镜像的ID,并且把中间步骤产生的容器都删除掉。比较新建的镜像和之前在docker.oa.com上下载的镜像
大小可以看到dockerhub上的镜像要比docker.oa.com上的镜像小,说明了dockerhub上的镜像要好一些。第五
章Docker中的网络介绍端口映射实现访问容器启动容器的时候,如果不指定对应的参数,在外部是无法通过网络来访问容器内的网络应用和
服务的。当容器中需要运行一些网络应用,让外部访问这些应用时,可以使用-p或者-P参数来指定端口的映射。例如我们使用-P标记的时候,
docker会随机的映射一个从49000到49900的端口到内部容器的端口上,可以使用dockerps-l查看当前容器端口映射
情况;如果使用-p可以指定我们想要映射的端口,在一个端口上只可以绑定一个容器:-p默认会绑定会绑定本地所欲的接口地址,我们在做端口
映射的时候可以指定一个地址或者是或者是任意的端口到容器的5000端口,还可以上使用UDP标记指定UDP端口,可以使用docker
port来查看当前绑定的端口配置,也可以查看绑定的地址:也可以多次使用-p来绑定多个端口:每一个容器都有自己的内部网络和IP地址,
可以使用dockerinspect查看所有的变量,可以查看到当前容器的内部IP地址等信息。Docker容器互联容器的互联机制(l
inking)是为了让多个容器中应用进行快速交互的方式,他会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器
,而不需要指定IP地址。容器的命名系统Linking系统根据容器的名称来执行的,当我们创建容器的时候系统会随机的分配一个名字,我们
也可以使用--name来自己命名,有两个好处:①自定义的名字比较好记,比如一个web应用的容器,我们就起名字web,一目了然;②连
接到其他的容器的时候,即使是重启容器也可以使用容器名而不用改变。注意:容器的命名是唯一的,如果系统中已经有一个同名的容器,就需要使
用dockerrm删除之前同名的容器。容器互联使用--link可以让容器之间安全的进行交互。首先创建一个新的数据库的容器,给该容
器命名为db:然后再创建一个web容器,并且把它连接到db容器上:可以使用dockerps查看容器的连接情况。Docker相当于
在两个互联的容器之间创建了一个虚拟的通道,而不需要映射它们的端口到宿主机上,在创建db容器的时候没有使用-p或者-P标记,使用li
nk之后我们就可以不用暴露数据库容器的端口到网络上。Docker通过两种方式公开容器的连接信息:①更新环境变量,使用env方式查看
容器的环境变量;其中DB_开头的的环境变量是提供web3容器连接db容器使用的。②更新/etc/hosts文件,docker还添加
host信息到父容器的/etc/hosts文件中,以下是一个父容器web的hosts文件:首先我们在hosts文件中可以看到两个I
P,第一个是db容器的IP地址别名以及主机名,第二个是新建的web容器的IP地址和主机名,因为我们没有使用-p或者-P命令将db容
器的端口暴露出来,我们可以使用ping命令验证在web容器中是否可以ping通db容器,我们在pingdb的时候,它会把db的地
址解析成192.168.13.5这与hosts文件中的一致。注意:可以链接多个子容器到父容器,比如我们可以链接多个web到db容器
上。第六章Docker高级网络配置当docker启动的时候,会在主机上创建一个docekr0的虚拟网卡,docker0的网卡不是
普通的网卡,他是桥接到其他网卡的虚拟机网卡,容器需要使用他来和主机进行通信。当创建一个docker容器的时候,它就创建了一个对接口
,当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包,它们是绑在一起的一对孪生接口。这对接口在容器中那一端的的名字是et
h0,宿主主机端的会指定一个唯一的名字,比如vethAQI2QT这样的名字,这种接口名字不再主机的命名空间中。所有的veth的接口
都会桥接到docker0,这样docker就创建了在主机和所有容器之间一个虚拟共享网络。配置DNSDocker没有给每一个容器定制
镜像,,但是容器会有主机的主机名和DNS配置信息,他主要是使用主机上的配置文件来覆盖容器的配置文件,在容器中使用mount命令就可
以看到:这样的话可以在宿主主机更改了dns信息后,马上可以更新docker的dns配置信息。容器之间的通信判断两个容器是否可以通信
,在操作系统层方面,取决于3个因素:①网络拓扑是否连接到容器的网络端口,默认的情况下是docker会将所有的容器都连接到docke
r0这一个网桥来提供数据包通信。②主机是否开启了ip转发,需要查看ip_forward参数是否为1,为1的时候可以提供数据包的转发
,通常docker设定ip_forward=true,docker就会在启动的时候设定ip_forward参数为1,可以自己手动检
查并且设置参数。可以使用cat/proc/sys/net/ipv4/ip_forward命令来查看ip_forward的当前值,
当我使用echo0>proc/sys/net/ipv4/ip_forward命令把ip_forward值修改为0的时候,提示我/
proc/sys/net/ipv4/ip_forward是一个只读文件,因此不可以修改该文件的值。③iptables(iptabl
es,一个运行在https://zh.wikipedia.org/wiki/%E4%BD%BF%E7%94%A8%E8%80%85
%E7%A9%BA%E9%96%93用户空间的应用软件,通过控制https://zh.wikipedia.org/wiki/Lin
ux%E5%85%A7%E6%A0%B8Linux内核https://zh.wikipedia.org/wiki/Netfilte
rnetfilter模块,来管理网络数据包的流动与转送。在大部分的Linux系统上面,iptables是使用/usr/sbin/i
ptables来操作)是否允许建立特殊的连接,当docker设定--iptables=false的时候,docker不会改变系统的
iptables设定,否则它会在--ice=true的时候添加一条默认的ACCERT策略到forward链,基本所有人都会开启ip
_forward来启用容器间的通信。创建一个点到点的连接默认docker会将所有容器连接到由docker0提供的虚拟子网,你也可以
使用自己创建的网桥。但如果你想要2个特殊的容器之间可以直连通信,而不用去配置复杂的主机网卡桥接。解决办法很简单:创建一对接口,把2
个容器放到这对接口中,配置成点到点链路类型。这2个容器就可以直接通信了。配置如下:①在2个终端中启动2个容器②找到他们的proce
ssIDs,然后创建他们的名称空间namespaceentries③创建管道peer接口,并且给每一个容器配置路由信息④接下
来就可以在各自的容器内部ping通互联的容器,因为是点到点的链路不需要子网和子网掩码,使用iproute来连接单个ip地址到指定
的网络接口。Docker的4种网络模式我们在使用dockerrun创建Docker容器时,可以用--net选项指定容器的网络模式
,Docker有以下4种网络模式:①host模式,使用--net=host指定。②container模式,使用--net=cont
ainer:NAME_or_ID指定。③none模式,使用--net=none指定。④bridge模式,使用--net=bridg
e指定,默认设置。⑴host模式Docker使用了Linux的Namespaces技术来进行资源隔离,如PIDNamespace
隔离进程,MountNamespace隔离文件系统,NetworkNamespace隔离网络等。一个NetworkNames
pace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的NetworkNamespace隔离。一个Doc
ker容器一般会分配一个独立的NetworkNamespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个
独立的NetworkNamespace,而是和宿主机共用一个NetworkNamespace。容器将不会虚拟出自己的网卡,配置
自己的IP等,而是使用宿主机的IP和端口。例如,我们在10.10.101.105/24的机器上用host模式启动一个含有web应用
的Docker容器,监听tcp80端口。当我们在容器中执行任何类似ifconfig命令查看网络环境时,看到的都是宿主机上的信息。而
外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其
他方面,如文件系统、进程列表等还是和宿主机隔离的。⑵container模式这个模式指定新创建的容器和已经存在的一个容器共享一个Ne
tworkNamespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、
端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的,两个容器的进程可以通过网卡设备通信。⑶none模式
在这种模式下,Docker容器拥有自己的NetworkNamespace,但是,并不为Docker容器进行任何网络配置。也就是说
,这个Docker容器没有网卡、IP、路由等信息,需要我们自己为Docker容器添加网卡、配置IP等。⑷bridge模式bridg
e模式是Docker默认的网络设置,此模式会为每一个容器分配NetworkNamespace、设置IP等,并将一个主机上的Doc
ker容器连接到一个虚拟网桥上。下面着重介绍一下此模式。第七章Docker的数据管理在docker容器中以及容器之间的数据管理的
主要方式有两种:数据卷和数据卷容器。数据卷是把容器内的数据直接映射到本地的主机环境;数据卷容器是使用特定的容器来维护数据卷。数据卷
数据卷是一个由UFS文件系统专门设计的的特殊目录,可以提供很多有用的特性:①数据卷可以在容器之间共享和重用;②对数据卷的改变是立马
生效;③当你更新数据卷中的数据的时候,不会被包含到image中;④卷会一直存在直到没有容器使用他们。添加一个数据卷在用docker
run命令的时候,使用-v标记来添加一个数据卷,在一次run中多次使用可以挂载多个数据卷,下面加载一个卷到容器上。添加一个主机目
录作为数据卷使用-v标记也可以挂载一个主机的目录到容器中去上面的命令加载主机的/home/shanksli到容器的/opt/tes
t目录。这个在测试的时候特别好用,比如我们可以加载我们的源码到容器中,来查看他们是否正常工作,就省去了很多操作。目录的路径必须是主
机上的绝对路径,如果目录不存在docker会自动为你创建它。docker加载的数据卷默认是读写权限,但我们可以把它加载为只读。d
ocker加载的数据卷默认是读写权限,但我们可以把它加载为只读。挂在一个宿主主机文件作为数据卷-v标记也可以从主机挂载单个文件到
容器中。使用上面的命令把~/.bash_history文件挂在到容器中/.bash_history文件,使得在容器中使用的命令在
主机上都可以看到。数据卷容器如果你有一些持续更新的数据需要在容器之间共享,最好创建DataVolumeContainer,然后
加载它。现在就来创建一个命名的数据卷容器:如果你移除了挂载的容器,包括初始容器,或者后来的db1db2,这些卷在有容器使用它的时
候不会被删除。这可以让我们在容器之间升级和移动数据。①首先创建一个数据卷容器dbdata,并且在容器里面创建一个数据卷挂在到/db
data:②然后可以在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷,例如创建db101和db102两
个容器,并且从dbdata中挂载数据卷:③这个时候db101和db102都挂载同一个数据卷到相同的/dbtata目录下,三个容器只
要一个容器写入数据,其他容器都会发生变化,可以使用--volumes-from挂载多个数据卷。可以利用数据卷容器对其中的数据卷进行
备份、恢复,以实现数据数据的迁移。第八章容器的安全性能第九章学会部署局域网docker第十章Docker实现多台物理机之间的
容器互联第十一章Docker中使用Supervisor管理进程第十二章Docker创建tomcat/weblogic集群第十三
章Docker安装Redis输入dockersearchredis然后选择你需要的版本如:dockerpullredi
s:5.0下载完后输入dockerrun-d-p6379:6379redis:5.0启动服务接着就可以直接用客户端连接r
edis啦Docker学习总结写这篇学习总结主要包含了两个层面的意义:第一方面是为了把最近学习docker相关的内容做一个总结,便
于在以查看相关的材料,方便学习和总结,这也是主要的一方面;第二方面是为了完成导师安排的任务。本文主要是参考docker学习手册的内
容完成的,目前计划主要主要包括十二章的内容:第一章为什么需要使用docekr;第二章docker的体系结构;第三章docker的安
装和使用;第四章dockerimages的获取和使用;第五章docker中的网络介绍;第六章docker高级网络配置;第七章do
cker的数据管理;第八章容器的安全性能;第九章学会部署局域网docker;第十章docker实现多台物理机之间的容器互联;第十一
章在docker中使用Supervisor管理进程;第十二章docker创建tomcat/weblogic集群。这篇总结是根据自己
在学习docker过程中遇到的一些问题和实际的操作展开的,很多的内容都是自己理解的,如果有认识上的错误,请指正。注意:本文中我自己
认为需要注意的地方会使用黄色标记出来。第十四章Docker安装MySQL从docker检索mysql镜像:dockersear
chmysql从镜像中下载:dockerpullmysql可以指定版本:mysql:5.7查看镜像:dockerima
ges启动mysql镜像:dockerrun--restart=always--namefirst-mysql-p33
06:3306-eMYSQL\_ROOT\_PASSWORD=123456-dmysql:latest启动mysql服务输入
dockerstartcontainerID(可以输入dockerps-a查看镜像的containerID)输入docke
rexec-itmysql(containerID)bash进入容器接着输入mysql-uroot-p可以进入MySQ
L服务;开放3306端口就可以使用工具连接Mysql啦。如果你安装的mysql8.0连接的时候会出现Authentication
plugin‘caching_sha2_password’cannotbeloaded;第十五章基于Docker的Azu
reDevOps实现众所周知,传统开发模式已经面临了诸多难题。首先,在代码集成方面,因为没有合适粒度的代码合并,大规模的合并会有
很大的风险,且传统开发模式中没有自动化测试,以至于测试周期特别长,人力成本高昂。其次,传统开发中的单体应用,通常都很庞大,单体应用
把所有模块都包含在一个应用中,升级单个模块也需要对整个应用进行升级,所以升级和创新都很不方便,常见的比如银行系统就是如此。同时,传
统的开发模式中单独采用微服务的情况也会由于服务数量多而没有有效管理,在大批量的部署和测试的时候容易出现问题。除此之外,传统开发模式
更面临着开发和测试的环境不一致,以及由于没有有效的升级方式导致业务停止的问题。(如何一步步实现DevOps)为了解决传统开发模式中
的问题,目前一个比较流行和彻底的方案是:DevOps流程+微服务理论+使用容器和容器编排工具。在这里展示给大家的是一个理论上的基于
容器的CI/CD流程,实际上,DevOps的前身就是CI/CD,实现了CI/CD后,再加上一些发布、部署等标准和管理就构成了Dev
Ops。DevOps的优势包括技术优势和商业利益如下。技术优势:?持续的软件交付?修复不太复杂的问题?更快地解决问题商业利益
:?更快速地传递功能?更稳定的操作环境?有更多时间可以增加价值(而不是修复/维护)(基于容器的CI/CD流程)实现DevOp
s之自动化测试那么如何来完整的实现DevOps呢?通常情况下,传统开发模式转向DevOps的第一步是解决自动化问题。要想持续的集成
代码,没有自动化测试来保证快速地进行合并后的验证,风险是很高的,而且没有自动化测试,测试环境很有可能成为整个开发环节的瓶颈。只要是
经常使用的测试用例,需要尽量自动化每一个操作。自动化工具很多,对自动化工具和测试框架的选择是需要根据具体应用来决定的,这里只列举其
中常用的一小部分——Jenkins、Python、RobotFramework、ShellScript、Selenium、An
sible和DockerContainerOrchestration——这些都是我们面对客户需求的时候经常用到的。然而,不是每
次集成都需要跑完所有的测试用例,因而对测试用例进行管理,可提高持续集成的效率。(自动化测试)如何来判断自动化测试用例和框架是否有效
?常见的判断依据有三个,首先是自动化测试的覆盖率。如果通过率再高,覆盖率低,那么自动化测试就不是一个有效的,目前企业级比较认可的覆
盖率是75%左右,再提高也比较困难。其次是看漏测率,有时候自动化用例本身也可能有Bug,前期阶段通过比较手动测试自动化测试的结果来
判断自动化测试是否有效。最后,当产品发布后根据从客户来源的bug数目来判断自动化测试用例是否有效。另外,要稳定一套自动化用例,一般
需要2个版本周期或者更长。实现DevOps之持续集成和持续交付持续集成一个主要的功能是让每个工程师的代码提交都不会影响到Mainl
ine,以保证Mainline的可发布状态。实施持续集成时,需要注意的地方:指定规则,提交代码时要一并提交新功能的测试用例。集成的
粒度和频度也很关键。一般一个小模块,不超过1周的时间。(持续集成)持续集成通过后,根据应用程序的特点,在经过系统集成测试、性能测试
、稳定的自动化测试通过率以及管理层的批准后,才是可持续交付和部署的应用程序。持续交付有两种方式,一种就是基于DevOps的自动持续
发布,一种是多个功能一并发布。在持续交付的过程中需要注意三个问题:1.部署到生产环境后也要有相应的测试;2.使用Toggle控制功
能是否生效;3.要有回滚的手段(灰度发布)。实现DevOps之微服务化有了自动化测试、持续集成和持续交付三块,已经基本实现了Dev
Ops的粗略流程,而为了提高DevOps的效率,往往需要结合微服务。一个微服务理论上只做一件事,并能用任何语言编写。微服务是松耦
合的,意味着一个应用的微服务可以被部署到不同机器上并通过resAPI/RPI来通信,当定义好微服务的API之后,每个team便能独
立开发。因此,微服务更容易被测试和实现CI/CD。(微服务的最佳实践)在微服务的最佳实践中,首先不得不提容器。容器的轻量化让微服务
启动很快,同时容器的跨平台性保证了微服务可以在不同的平台启动起来。第二种是使用代理服务器来访问微服务,现在最常见的方式是前端连接一
个代理服务器,后端再连接运行同一个微服务的几个相同容器。一个大的应用会使用几十上百个微服务,和微服务不相关的库文件不建议放在容器中
。实践微服务中,建议使用配置管理工具(ansible,puppet等)和容器服务编排工具(K8s,Swarm,EcOS等)。(康
威定律)在开发微服务中康威定律起到了很大的作用。康威定律指出任何软件代码都是用来反映组织机构而产生的,如果要采用微服务的开发方法,
就需要是把团队划分成多个小团队,由每个小团队负责一个或多个微服务。所以如果要转成DevOps和CI/CD的开发模式,就需要采用这种
敏捷开发模式,一个团队7-8个人比较合适。实现DevOps之容器技术另外一个实现DevOps的重要手段是Docker容器技术。和传
统的Hypervisor相比,Docker没有自己的操作系统,它使用宿主机的操作系统,而Hypervisor需要建立虚拟机,每个虚
拟机需要装一个操作系统,因此Docker效率更高更节约资源。如果一台物理机可以操作20个虚拟机,便至少可以启动200个容器,且启动
容器的时间是秒级。(Docker和Hypervisor的对比)使用容器编排工具可以实现对容器的健康检查、动态伸缩、灰度发布和蓝绿发
布等功能。而我们提到的容器编排技术,比如K8s,Mesos和Swarm,都是开源的工具,这里我们把精灵云自研的容器编排工具EcOS
和开源工具进行了简单对比。(几种常见容器编排技术的比较)K8s是由谷歌发起的开源框架,最大的问题是太笨重,对使用者来说操作很复杂,
学习周期很长。Swarm是Docker公司开发的工具,Docker本身不能支持的功能,Swarm也是无法支持的。如图所示,EcOS
是精灵云自主开发的容器编排技术,最大的特点是结合了开源工具的优点,在应用编排上完全可视化。EcOS内置的自研调度框架Newben,
在网络、应用迁移、负载均衡、弹性伸缩、调度规则等方面也比开源框架有比较大的优势,在支撑过数万用户和数十万的容器调度考验后,Newb
en是目前国内定制能力最强,支撑功能最丰富的调度框架。实现DevOps之灰度发布如果一个服务由多个相同的容器运行,灰度发布则先对其
中的部分容器先进行升级,可混合让老版本和新版本的容器同时提供服务。如发现新服务没有什么问题,则可以把所有剩下的微服务再全部进行升级
。(灰度发布)实现DevOps之版本控制DevOps下版本控制的原则是始终在Mainline上进行新功能的开发,并经由持续集成的自
动化测试对代码进行验证。当功能开发到一定阶段的时候,对可RC的代码创建分支,该分支上停止新功能的开发,只求稳定。当产品发布后,如发
现问题,可出hotfix。根据时间点和具体需要,可把其他分支的hotfixmerge到Mainline上。(版本控制原理)Doc
ker和持续集成(CI)?什么是持续集成?我们先得了解持续集成的相关概念,才能更好地指导开发和使用Docker来改进我们的工作流。
和其他教程不一样,笔者更喜欢将必要的知识点围绕理论、流程(工作流程)、方法、实践来进行讲解,而不是单纯的为讲解知识点而进行讲解。也
就是说,笔者希望为大家打通任督二脉,能够将理论、知识、思想和指导应用到工作的实际场景和实践之中,而不是拿着字典写文章,抱着宝典写代
码。至于很多具体的语法、技术细节,除了常用的知识点,笔者更希望大家阅读官方文档——毕竟看官网比看书靠谱多了,官网会一直更新和改进,
而书和教程自出版或发布之后,基本上就“死“了。好了,我们回到正题。持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通
常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而
尽早地发现集成错误。?徒弟一脸崇拜道:“师父,为什么我做出来的飞剑,一念咒语不是碎了就是爆了呢?”。师父摸了摸胡子道:“徒儿莫急,
冰冻三尺非一日之寒!为师我刻了3年的阵法,练习了3年的咒语,然后又花了3年一起练习,才让第一把飞剑飞上了太空。我看你天资聪慧,顶多
20年就够了”。2年后,徒弟边刻阵法边念咒,突然飞剑的剑身嗖的一下不见了,只余剑柄。师父:“徒儿,你的飞剑怎么飞了一截出去了!”徒
弟握着剑柄行礼道:“师父勿怪,这段时间我对飞剑的制作过程进行了改良,一边刻阵法一边念咒,现在我对阵法和咒语的掌控都达到了70%,所
以只有前半截飞出去了!“?注意:集成软件的过程不是新问题,如果项目开发的规模比较小,比如一个人的项目,如果它对外部系统的依赖很小,
那么软件集成不是问题,但是随着软件项目复杂度的增加(即使增加一个人),就会对集成和确保软件组件能够在一起工作提出了更多的要求-要早
集成,常集成。早集成,频繁的集成帮助项目在早期发现项目风险和质量问题,如果到后期才发现这些问题,解决问题代价很大,很有可能导致项目
延期或者项目失败。核心价值?要素1.统一的代码库2.自动构建3.自动测试4.每个人每天都要向代码库主干提交代码5.每次代码递交后都
会在持续集成服务器上触发一次构建6.保证快速构建7.模拟生产环境的自动测试8.每个人都可以很容易的获取最新可执行的应用程序9.每个
人都清楚正在发生的状况10.自动化的部署?原则1.所有的开发人员需要在本地机器上做本地构建,然后再提交的版本控制库中,从而确保他
们的变更不会导致持续集成失败。2.开发人员每天至少向版本控制库中提交一次代码。3.开发人员每天至少需要从版本控制库中更新一次代
码到本地机器。4.需要有专门的集成服务器来执行集成构建,每天要执行多次构建。5.每次构建都要100%通过。6.每次构建都可以
生成可发布的产品。7.修复失败的构建是优先级最高的事情。8.测试是未来,未来是测试?持续集成我们就先说到这里,建议大家也可以了
解下敏捷开发,毕竟持续集成是敏捷开发的基石,但是敏捷开发是一个大命题,这里我们顺带提一下,然后我们还是先继续本篇教程:师父:“徒儿
,你真的在短短3年就让飞剑飞起来了?”。徒弟:“弟子愚钝,在刻剑的过程中倍觉无聊,又不喜欢哼歌,于是索性边练咒边刻剑。后面徒儿发现
,如果刻错了或者念错了,飞剑就会提前直接爆炸,虽然每次炸的内裤都没了,但是能够尽早发现错误。所以徒弟才能一日千里”。师父摸了摸胡须
道:“然来如此!不过,这就是你大庭广众之下裸奔的借口!!?”?相比其他技术,Docker在持续集成(CI)这块有着先天的优势。在通
常的情况下,我们要实现持续集成往往会遇到以下问题:l?复杂的依赖关系不同的项目环境,不同的语言,不同的程序包依赖,甚至是操作系统的
依赖等等,都会影响到我们持续集成的自动化脚本的执行。而且依赖包之间的兼容性,版本的兼容性,间接依赖或者多重依赖等问题等等,对于开发
和运维来说,都是一个噩梦。就如以下对话:徒弟:“师父,我按照您教的方式念咒,为什么飞剑飞起来了之后就收不回来了?”。师父直接一巴掌
,说:“兔崽子,上次就和你说了,咒语现在最低的兼容级别是——普通话二级乙等!谁教你说长沙话的!”?l?不一致的环境在通常的环境中,
我们需要准备好开发、测试和生产环境,往往开发环境随便开发人员折腾,有时候操作系统或者依赖软件的版本的区别、组件的不同、配置不一样,
都足够让开发环境正常运行的程序在测试环境上跑不起来,造成测试人员和开发人员的故意伤害事件,导致“行凶人员”后悔终生,感悟到“冲动就
是魔鬼”的箴言。我们还是以对话来阐述这个问题:徒弟拿出普通话二级乙等证书道:“师父,我苦学普通话,终于达到普通话二级乙等。然后按照
您教的方式念咒了,之后为什么飞剑飞起来了之后还是没法收回来?”。师父又是一巴掌,说:“兔崽子,你没看到下雨了么?”徒弟弱弱的问:“
这个和下雨有关系么?是不是雨天法术受雨滴干扰,咒语的效果受到影响呢?”师父指着外面道:“瞎了?你丫的不赶紧把被子收回来烘干,你的飞
剑就甭想要了!”?l?应用架构的复杂性和配置的多样性现在的系统架构越来越复杂,甚至由多种开发语言组成,而且包含前后端等多方面内容。
这些可能会导致其部署方式的不同以及配置的复杂性。并且一个系统维护到后面,往往有很多历史遗留问题,比如那各种配置文件和配置方式,各种
补丁,各种脚本等等。这些因素会导致自动化流程会非常麻烦和艰难。我们继续来一段对话:?徒弟:“师父,被子收好了,但是飞剑越飞越远了,
是不是可以教我收回我的飞剑啦!”。师父张开一只眼:“小崽子,普通话念完后,用长沙话再念一遍收剑咒!前几天,为师对收剑咒又进行了改造
。”徒弟用长沙话念完,飞剑还是再天空中乱窜,并没有降下来的意思。徒弟赶紧问道:“师父,为啥还是不行呢?”师父弹了弹手指,远处一根若
隐若现的细线展现出来,师父指着那根线说:“看到那边那根线没?还不赶紧去追!”?相比这些问题,Docker实现持续集成(CI)就方便
多了。首先,Docker可以让我们非常容易和方便地以“容器化”的方式去部署应用。它就像集装箱一样,打包了所有依赖,再在其他服务器上
部署很容易,不至于换服务器后发现各种配置文件散落一地,这样就解决了编译时依赖和运行时依赖的问题。其次,Docker的隔离性使得应用
在运行时就像处于沙箱中,每个应用都认为自己是在系统中唯一运行的程序,这样就可以很方便地在一个系统中部署多种不同环境来解决依赖复杂度
的问题。正因为Docker是以应用为中心,镜像中打包了应用及应用所需的环境,一次构建,处处运行。这种特性完美解决了传统模式下应用迁
移后面临的环境不一致问题。因此使用Docker实现持续集成,我们可以使用一些简单的免费的工具即可实现,也可以非常方便的自己搭建集成
环境或者编写脚本实现。比如Azure?DevOps、Tencent?Hub、Jenkins和TeamCity,接下来我们会逐步进行
介绍。持续集成工作流程一般情况下,持续集成的流程如下所示:下面是一个参考流程:代码版本管理,我们推荐使用Git。关于git版本库的
使用,我这里就不啰嗦了,如果有朋友感兴趣,我也可以分享一些内容。后续,我们将会分享使用相关工具来实施我们的CI流程。使用Azure
DevOps来完成CIAzureDevOps,以前叫VSTS,现在被微软改名部正式更名为Azure?DevOps。和VSTS一
样,微软都提供了免费的使用额度,对于小团队和个人开发者来说,完全是足够了。什么是DevOps?DevOps(Development
和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之
间的沟通、协作与整合。它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自
动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。它的出现是由于软件行业日益清晰地认识到
:为了按时交付软件产品和服务,开发和运营工作必须紧密合作。DevOps的引入能对产品交付、测试、功能开发和维护(包括──曾经罕见但
如今已屡见不鲜的──“热补丁”)起到意义深远的影响。在缺乏DevOps能力的组织中,开发与运营之间存在着信息“鸿沟”──例如运营人
员要求更好的可靠性和安全性,开发人员则希望基础设施响应更快,而业务用户的需求则是更快地将更多的特性发布给最终用户使用。这种信息鸿沟
就是最常出问题的地方。DevOps经常被描述为“开发团队与运营团队之间更具协作性、更高效的关系”。由于团队间协作关系的改善,整个组
织的效率因此得到提升,伴随频繁变化而来的生产环境的风险也能得到降低。总之,通过DevOps,各专业团队之间的协调和协作得到改善,缩
短了将更改提交到系统与将更改投入到生产之间的时间。它还可确保此过程符合安全性和可靠性标准。结果:产品质量改善、交付速度加快、客户满
意度提升。DevOps对应用程序发布的影响在很多企业中,应用程序发布是一项涉及多个团队、压力很大、风险很高的活动。然而在具备Dev
Ops能力的组织中,应用程序发布的风险很低,原因如下:减少变更范围与传统的瀑布式开发模型相比,采用敏捷或迭代式开发意味着更频繁的发
布、每次发布包含的变化更少。由于部署经常进行,因此每次部署不会对生产系统造成巨大影响,应用程序会以平滑的速率逐渐生长。?加强发布协
调靠强有力的发布协调人来弥合开发与运营之间的技能鸿沟和沟通鸿沟;采用电子数据表、电话会议、即时消息、企业门户(wiki、share
point)等协作工具来确保所有相关人员理解变更的内容并全力合作。?自动化强大的部署自动化手段确保部署任务的可重复性、减少部署出错
的可能性。与传统开发方法那种大规模的、不频繁的发布(通常以“季度”或“年”为单位)相比,敏捷方法大大提升了发布频率(通常以“天”或
“周”为单位)。减少变更范围与传统的瀑布式开发模型相比,采用敏捷或迭代式开发意味着更频繁的发布、每次发布包含的变化更少。由于部署经
常进行,因此每次部署不会对生产系统造成巨大影响,应用程序会以平滑的速率逐渐生长。加强发布协调靠强有力的发布协调人来弥合开发与运营之
间的技能鸿沟和沟通鸿沟;采用电子数据表、电话会议、即时消息、企业门户(wiki、sharepoint)等协作工具来确保所有相关人员
理解变更的内容并全力合作。强大的自动化部署手段能够确保部署任务的可重复性、减少部署出错的可能性。?适用于容器的?CI/CD?流程使
用容器,可轻松地持续生成和部署应用程序。AzureDevOps可以通过设置持续版本以生成容器映像和业务流程,让我们能更快、更可
靠地进行部署。以下是一个适用于容器和Azure的CI/CD?流程:步骤说明:使用Azure?DevOps来配置一个简单的CI流程A
zure?DevOps服务涵盖了整个开发生命周期,可帮助开发人员更快地高质量地交付软件,其提供了AzurePipelines、A
zureBoards、AzureArtifacts、AzureRepos和AzureTestPlans。关于Azure?
DevOps我们就介绍到这里,毕竟是免费介绍。现在,我们需要侧重介绍的是Pipelines,也就是代码流水线。看,多形象,所以以前
自诩为码农是错误的,我们应该是码工,广大流水线工人的一环,无产阶级之一,共产主义接班人。不好意思,又偏题了,我们继续:首先,我们需
要定义一个流水线,为了便于演示,我这里就定义一些针对Docker的简单步骤,大家可以按需添加步骤,比如单元测试步骤等等。如图所示,
步骤很简单,首先设置代码源,这里我们直接对接Magicodes.Admin框架的git库地址。Git库地址大家可以在这里找到:ht
tps://gitee.com/xl_wenqiang/Magicodes.Admin.Corehttps://gitee.com
/xl_wenqiang/Magicodes.Admin.Core。因为代码是托管再码云,所以我们选择如上图所示的最后一种方式,并
且选择对应的分支。接下来,我们需要添加job和task。job添加一个默认的即可,无需设置什么条件和参数。接下来我们添加task,
实际上就是步骤。第一步,构建镜像。我们需要添加一个dockertask:然后设置command命令为build,也就是构建:构建
配置我们可以根据自己的需求来设置,比如根据分支设置镜像版本等等。第二步,登录腾讯云镜像仓库并且推送。这一步,就有点门槛了,原生的d
ocker命令并不好使,因为task之间的上下文是断开的,也就是login了你也没法push。这时候,还是命令行靠谱,简单粗暴。所
以我们需要添加一个Commandlinetask:然后编写命令脚本:简单粗暴的两个步骤就搞定了,大家可以根据自己的持续集成流程
来定制,毕竟微软在开发者服务这块淫荡多年,还是相当给力的。我们可以初步看看支持的task:非常之多,足够我们随便玩了。而且玩坏了还
不用赔钱。接下来,跑起来:点开还能看到详细的过程:?激不激动,简单不简单?就这么几下就搞定了。产品很强大,就是拉取代码有点慢,看起
来是托管在国外。顺手一查,额,美国:因此,我们不是很推荐使用Azure?DevOps来完成CI,网络的延迟足够拖垮我们焦虑的神经。
但是如果我们的代码托管在Github,那么使用Azure?DevOps是不错的选择。在接下来的教程中,我们会讲解如何打造自己的Gi
thub开源库的CI流程——不仅完全自动化,而且还支持在readme页面添加各种动态图标。第十六章构建Python环境我们使用D
ockerfile去构建一个简单的python项目.一.我们先创建随便创建一个文件夹testdocker.然后在这个文件夹中
创建三个文件,一个空的Dockfile.一个txt文件requirements.txt?http://xn--pythonapp
-u75noof3f5u4ab89c.py/和一个python文件app.py.二.编辑Dockerfile文件#Usean
officialPythonruntimeasaparentimageFROMpython:2.7-slim#S
ettheworkingdirectoryto/appWORKDIR/app#Copythecurrentdi
rectorycontentsintothecontainerat/appCOPY./app#Installa
nyneededpackagesspecifiedinrequirements.txtRUNpipinstall-
-trusted-hostpypi.python.org-rrequirements.txt#Makeport80a
vailabletotheworldoutsidethiscontainerEXPOSE80#Defineenv
ironmentvariableENVNAMEWorld#Runapp.pywhenthecontainerla
unchesCMD["python","app.py"]三.编辑requirements.txt文件FlaskRedis四.
编辑app.py文件,在python文件中fromflaskimportFlaskfromredisimportRe
dis,RedisErrorimportosimportsocket#ConnecttoRedisredis=Re
dis(host="redis",db=0,socket_connect_timeout=2,socket_timeout=
2)app=Flask(__name__)@app.route("/")defhello():try:visits=
redis.incr("counter")exceptRedisError:visits="cannotconn
ecttoRedis,counterdisabled
"html="

Hello{name}!>"\"Hostname:{hostname}
"\"Visits:{visits
}"returnhtml.format(name=os.getenv("NAME","world"),hostname=s
ocket.gethostname(),visits=visits)if__name__=="__main__":app
.run(host=''0.0.0.0'',port=80)五.构建应用程序在testdocker文件夹下运行build命令。这将
创建一个Docker镜像,我们将使用该–tag选项给这个镜像命名为friendlyhello。也可以使用-t代替--tagdo
ckerbuild--tag=friendlyhello.如果出现servermisbehaving,是因为你的镜像库连接
异常了,将自己的主机或服务器设置的DNS设置为8.8.8.8或者114.114.114.114即可我们从构建步骤看出,总共执行了7
步,每一步对应了Dockerfile文件中的每一行.六.查看我们的镜像文件dockerimages注意标签是如何默认的late
st.标签选项的完整语法类似于–tag=friendlyhello:v0.0.1七.运行应用程序运行应用程序,使用-p将计算
机的端口4000映射到容器的已发布端口80上.dockerrun-p4000:80friendlyhello我们看到提示告
诉我们已经为我们提供了服务?http://0.0.0.0/http://0.0.0.0:80.该消息来自docker容器内部,它
不知道我们将80端口映射到4000端口上了.我们正确访问的地址应该是http://127.0.0.1:4000.应为我们在构建
这个docker镜像的时候,并没有redis,所以会报出redis连接失败八.停止容器在cmd命令行中,我们使用CTRL+C,
并不能停止该容器,只是让我们退出了命令行.需要停止容器,我们可以先退出到命令行,然后用dockercontainerstop去
停止指定的docker容器#查看正在运行的docker容器dockercontainerlsCONTAINERID
IMAGECOMMANDCREATEDST
ATUSPORTSNAMES374750278fbe
friendlyhello"pythonapp.py"12minutesagoUp1
2minutes0.0.0.0:4000->80/tcpdreamy_joliot#停止容器查看上一个操作
的CONTAINERID,根据id,去停止容器dockercontainerstop374750278fbe第十七章在D
ocker上部署使用AzureCLI镜像Docker是非常流行的容器技术,在Docker中安装部署多种工具非常快速和方便;而Az
ureCLI是微软提供的可以在Linux/Mac上运行的跨平台命令行管理工具,本文介绍如何在Azure上安装部署Docker和A
zureCLI。首先部署一台Linux虚拟机,关于如何创建虚拟机,请参考Azure相关基础文档,本例中使用CentOS7.2作
为host。?更新系统,使系统达到最新状态:sudoyumupdate添加Docker的yum仓库:$sudotee/e
tc/yum.repos.d/docker.repo<<-''EOF''[dockerrepo]name=DockerReposi
torybaseurl=https://yum.dockerproject.org/repo/main/centos/7/?en
abled=1?gpgcheck=1?gpgkey=https://yum.dockerproject.org/gpgEOF安装D
ocker的引擎和基础包:$sudoyum?install?docker-engine启动Docker:$sudoserv
icedocker?start测试一下Docker是否工作正常:sudodocker?run?hello-world?为了避免
每次运行docker命令都要输入sudo,可以将你当前的用户加入到docker的group里面去,logout然后再login就
好了:sudousermod-aGdockeryour_username?到目前为止,Docker引擎已经安装完毕,然后我
们在Docker需要pullazure-cli的image下来,执行命令:?$dockerrun-itmicrosoft/
azure-cli??问题:你会发现速度非常慢,原因是默认情况下,Docker会从global的Hub里面获取镜像,会去国外下载,
众所周知的原因,会非常慢。解决办法:使用国内的DockerHub镜像服务,比如DaoCloud,宣称终身免费:)以下是具体步骤:
注册DaoCloud的免费账号,注册地址:?https://account.daocloud.io/signuphttps://a
ccount.daocloud.io/signup注册成功以后,登陆DaoCloud,选择"加速器"加速器会生成一个和你帐号关联的
配置地址,直接拷贝,然后在你的Linux主机上执行即可:curl-sSLhttps://get.daocloud.io/dao
tools/set_mirror.sh|sh-s?http://XXXXXXX.m.daocloud.ioD.执行完成后,
需要重启Docker服务:$sudosystemctlrestartdocker?E.重新执行上述dockerazur
e-cli安装命令,你会发现速度相当不错~9.安装完成,你会看到已经进入azure-cli的进程,在命令行输入azure回车,可
以看到熟悉的界面:第十八章在Linux上使用AzureCLI来管理Azure在Windows上我们有强大的Powershell
提供各种命令来管理Azure的服务,在Linux上微软提供了基于Node.JS的跨平台的AzureCommandLine来帮助
Linux用户来管理Azure服务,本文介绍如何安装使用AzureCommandLine工具。安装和基本配置1.Azure
CLI基于Node.JS和NPM,所以首先需要安装Node.JS,在官方网站上,Node.JS提供了大部分主流OS的安装指导,请参
考如下链接,本文以Ubuntu为例:https://nodejs.org/en/download/package-manager/
https://nodejs.org/en/download/package-manager/#opensuse-and-sle2
.首先下载相关Node.JS安装包,然后安装nodejs:curl-sLhttps://deb.nodesource.com
/setup_4.x|sudo-Ebash–sudoapt-getinstall-ynodejs3.如果你使用
的是SLES11SP3,你可能会找不到对应的版本,包括直接去SUSE的官网repo上去看,那么你可以安装SLES11SP4的
包,也没问题:4.具体执行以下命令可以在SLES11SP3上安装node.js:#zypperaddrepohttp:/
/download.opensuse.org/repositories/devel:languages:nodejs/SLE_11
_SP4/devel:languages:nodejs.repo#zypperrefresh#zypperinstallno
dejs??5.?NodeJS成功安装完成以后,利用NPM工具安装AzureCLI:npminstallazure-cli
-g?6.安装完成以后,在命令行下执行一下命令azure,如果安装一切正常,可以看到出现Azure的命令行说明,Azure图标
等等:基本使用方法认证登陆:在正式使用之前,你首先要连接到你的Azure服务,使用AzureCLI认证有几种方式,一种是打开浏览
器输入用户名密码的交互式方式,一种是直接在命令行端输入的命令行模式,本例采用第二种:查看azurelogin的用法,可以使用az
urehelplogin:使用你的azure账号用户名进行认证登陆:?$azurelogin-uUSERNAME@US
ERdomain.partner.onmschina.cn-pPASSWORD-eAzureChinaCloud?创建和管
理虚拟机在Linux上使用AzureCLI可以快速创建虚拟机,尤其对于Linux虚拟机来讲,可以直接使用本地的密钥,非常方便:?
$azurevmquick-create-M~/.ssh/id_rsa.pub-QCentOS-Q这个参数可以快速的
使用Linux系统的别名,快速的创建LinuxVM,在例子中CentOS指的是CentOS7.2,对应的表格如下(RHEL中
国不适用):创建的时候,输入一些基本的参数:?创建完成后,会显示Linux虚拟机相关信息:?你可以使用SSH和本地密钥直接登陆,而
且不支持用户名密码登陆,非常安全:?删除虚拟机?管理AzureStorage?列出storageaccounts:$azur
estorageaccountlist?删除storageaccounts:$azurestorageaccount
deleteznooenr3gzademylinuxscsa?上传本地文件到Blobstorage:$azurestor
ageblobupload-f/home/steven/package.json--containerupload-
aSTORAGEACCOUNT-kSTORAGEKEY?下载Blobstorage的文件到本地:$azurestora
geblobdownload-bpackage.json--containerupload-aACCOUNTNAM
E-kSTORAGEKEY第十九章将Dockerimagepush到Azure首先,需要登录到azure,通过如下的命
令:sudodockerloginxxxxx.azurecr.io-uyourusername-p=yourpa
ssword,登录成功会提示:LoginSucceeded将本地build好的image修改名字为xxxxx.azurecr.i
o/your_local_image_name(使用tag修改哦)输入push命令:sudodockerpushxxxxxx
x.azurecr.io/your_local_image_name即可完成所有的push任务啦补充,如果要从xxxxx.azur
ecr.iopull镜像,可以使用以下命令:sudodockerpullxxxxx.azurecr.io/your_loca
l_image_name第二十章使用Docker和AzureKubernetes服务将ASP.NET核心应用程序容器化介绍有一
个单体软件应用程序的时代,整个应用程序被打包并部署在作为单个进程运行的单个服务器上。众所周知,使用此模型,单点故障可能会导致整个应
用程序崩溃。微服务架构发展到解决单体应用程序的这一缺点和其他缺点。在容器中托管微服务解决了部署和管理基于微服务的应用程序的一些问题
,而像Docker这样的平台可以轻松地将应用程序打包到便携式容器中。Kubernetes协调了容器化应用程序的部署和管理。Kube
rnetes是您可以在本地环境中下载和部署的软件,但大多数云托管服务提供内置的Kubernetes服务,可帮助您在其环境中协调云托
管功能和微服务。在本文中,我们将演示如何使用Docker和Microsoft的AzureKubernetesServices(
AKS)协调在云中部署和扩展整个ASP.NETCore应用程序。应用概述在本教程中,我们将创建一个简单的ASP.NETCore
Web应用程序,将其与Docker一起容器化,然后将其部署到AKS集群。应用程序的逻辑在这里并不重要,因为我们只是为了部署应用程
序而使用它,这可以说明在部署扩展时它运行的位置。重点是创建容器并使用Kubernetes将应用程序部署到AKS集群。当应用程序停靠
时,我们将创建应用程序的本地镜像以在本地进行测试。您需要有效的Azure帐户才能进行部署,我们将在开发计算机上使用以下应用程序。G
itforWindows.NETCore2.1或更高版本AzureCLIAzurePowerShell适用于Windo
ws的https://www.docker.com/resources/what-containerDocker安装并运行Dock
erforWindows后,转到设置并启用Kubernetes复选框,如下所示:或者,DockerforWindows应该
在Linux容器模式下运行,否则,Kubernetes选项将不会显示在设置中。安装AzureCLI后,运行以下命令(az--v
ersion)以确保CLI已启动并正在运行。我创建了一个简单的ASP.NETCore应用程序,您可以从https://githu
b.com/akhilmittal/Azure-Kubernetes-Servicehttps://github.com/akhi
lmittal/Azure-Kubernetes-Service克隆或下载。项目克隆或下载并解压缩后,执行dotnetrun如下
所示的命令。这将运行服务器并告诉服务器正在侦听应用程序的端口,即http://localhost:5000。打开浏览器并导航到提供
的URL,通常为http://localhost:5000/http://localhost:5000。您将看到它只是一个简单的应
用程序,显示运行应用程序的主机或容器。目前,它在没有容器的开发Windows机器上运行,因此它显示了主机的名称,在本例中为3593
BH2。容器化ASP.NET核心应用程序现在我们将使用Docker为ASP.NETCore应用程序创建容器。我已经完成了示例下载
中的一些工作,因此我们不必完成创建容器的每个步骤。导航到应用程序目录的根目录以查看已创建的Docker文件。此Docker文件将用
于构建镜像。运行时镜像使用dockerbuild如下所示的命令构建:dockerbuild.-taks:local确保您
位于包含Docker文件的目录中,然后运行该命令。如果您不熟悉语法,则点表示Docker文件位于当前目录中,并且-t开关允许您指定
标记aks:local。这将启动构建过程。构建完成后,运行dockerimagelist命令。它列出了一个名为aks:loca
l的全新形象。要测试此镜像,请使用以下dockerrun命令运行基于此镜像的容器:dockerrun-d-p5000:8
0aks:local该-d开关告诉Docker将其作为守护进程运行。该-p开关将主机上的端口5000映射到容器上的本地端口80。
执行命令dockerps以查看容器的运行情况。现在转到浏览器并连接到http://localhost:5000/http://l
ocalhost:5000。我们看到应用程序现在在docker容器下运行,因为主机名现在显示为容器的ID。运行以下命令删除新创建的
测试容器:dockercontainerrm-f[containername]对于[容器名称],请替换浏览器中显示的容器
ID或运行该dockerps命令。部署在本地Kubernetes集群上现在,我们将快速的将应用程序部署到本地Kubernetes
集群上,以说明使用Kubernetes进行编排的手动方法。这将提供与Kubernetes编排与AKS进行比较的基线。在本地Kube
rnetes集群上部署镜像有两种方法:交互式和声明式。使用交互式方法时,可以将所有Kubernetes部署和业务流程步骤直接指定为
带参数的命令。使用声明性方法,您可以在Kubernetes部署清单文件中指定详细信息,并在运行Kubernetes时将该清单用作参数。让我们通过运行以下命令开始一个交互式示例:kubectlrunaks-deployment--image=aks:local--port=80--replicas=3这里的关键选项是--replicas,我们用它来指定应用程序需要三个副本。执行命令时,将创建一个部署,其中所需状态设置为三个副本。创建副本集以确保应用程序始终存在三个副本。调度程序在工作节点上调度pod部署,该节点命令在工作节点上运行的Docker引擎拉取镜像然后在pod中运行。部署应用程序后,创建一个服务以公开此部署。kubectlexposedeploymentaks-deployment--type=NodePort这创建了服务。通过运行kubectlgetservice或kubectlgetsvc验证它。要连接到该服务,请启动浏览器并连接到localhost,然后连接节点上公开的端口号。现在我打开了三个浏览器并点击了同一个URL。我们看到容器主机名发生了变化。这是因为服务器后面有三个pod或容器,服务负载平衡请求。通过使用delete命令删除部署和服务来清理它们。kubectldeletedeploymentaks-deployment同样,delete服务也是如此。kubectldeleteserviceaks-deployment声明性方法使用部署清单文件中保存的预配置选项。我在应用程序的根目录中包含了一个YAML清单文件:aksdeploy.yml。该文件有两个部分。第一个指定如何创建部署。第二个指定如何将其作为服务公开。打开文件并将副本数量(“replicas:”)更改为3,将镜像文件名称(“image:”)更改为aks:local。以下命令使用aksdeploy.yml中的配置创建部署和服务。kubectlcreate-f.\aksdeploy.yml使用kubectlgetsvc检查服务的状态,然后启动浏览器以连接到该服务。您应该看到与之前的交互式演示相同的结果,请求分布在可用的副本中。同样,删除部署和服务,但这次通过指定文件名。kubectldelete-f.\aksdeploy.ymlDocker镜像和Azure容器注册表(ACR)用户容器的关键部分是在注册表中随时可用。在此示例中,我们将应用程序的Docker镜像推送到https://azure.microsoft.com/en-in/services/container-registry/Azure容器注册表。我们将使用AzureCLI。使用该azlogin命令登录Azure。创建名称为aksgroup,位置为australiaeast的资源组。(您可以在此处使用您自己的位置。)azgroupcreate-naksgroup-laustraliaeast现在创建一个容器注册表项,其名称为learningaksacr,资源组为aksgroup,位置为australiaeast(或您的首选位置)和sku为standard。azacrcreate-nlearningaksacr-gaksgroup--skustandard创建容器注册表后,需要推送镜像。首先,登录。azacrlogin-nlearningaksacr成功登录后,在推送之前,使用容器注册表的登录服务器名称标记本地镜像。azacrlist-otable复制登录服务器名称并将其保存在手边。要列出本机上可用的Docker镜像,我们可以使用dockerimagelist命令。我们有aks:local镜像,需要使用登录服务器名称进行标记。现在,运行docker?tag命令。指定本地镜像名称,新名称(将成为登录服务器名称)以及镜像名称和标记。dockertagaks:locallearningaksacr.azurecr.io/aks/v1通过docker?imagelist命令验证这一点,我们看到成功标记的镜像。本地和标记镜像共享相同的镜像ID。现在使用dockerpush命令将标记的镜像推送到注册表。dockerpushlearningaksacr.azurecr.io/aks/v1:latest此镜像现在可以由任何其他Docker机器使用或访问,或者AKS群集可以轻松地从注册表中提取此镜像。部署AzureKubernetes服务(AKS)群集我们在本地部署了Kubernetes集群,现在是时候使用AKS部署到Azure了。使用AKS,可轻松配置生产级Kubernetes集群。在继续之前,请创建服务主体,将应用程序注册到AzureActiveDirectory(AD),并为其创建标识。如果应用程序将自己暴露给其他Azure服务,则需要注册的ID。使用AzureCLI使用以下命令创建服务主体:azadspcreate-for-rbac--skip-assignment一旦创建,你得到的appID,displayName,URL,password,和租户性质的服务主体。保留此信息以供日后参考。现在授予服务主体权限以从ACR中提取镜像。我在这里使用PowerShell窗口。使用该azacrshow命令获取ACR资源ID($acrId)。azacrshow--namelearningaksacr--resource-groupaksgroup--query"id"然后将读者角色授予AKS群集,以便它可以使用azroleassignmentcreate命令读取存储在ACR中的镜像。azroleassignmentcreate--assignee[appID]--roleReader--scope$acrId使用appID为服务主体提供的内容,并将范围设置为从azacrshow命令获取的ACR的资源ID。现在使用该azakscreate命令创建我们的AKS集群。提供名称和资源组。对于node-count,使其成为单个工作节点。使用generate-ssh-keys生成SSH公共(和私有)密钥文件。指定service-principal和client-secret,即应用程序ID和先前复制的密码。运行命令。azakscreate`>>--namelearningakscluster`>>--resource-groupaksgroup>>--node-count1`>>--generate-ssh-keys`>>--service-principal[appID]`>>--client-secret[password]部署完成后,要从客户端计算机连接到我们的AKS群集,请使用kubectl命令行界面。位于用户位置的.kube文件如下图所示,其中包含设置为在端口6445上运行的本地服务器的服务器设置。使用azaksget-credentials命令获取刚部署的AKS集群的凭据,指定名称和资源组名称。现在,返回.kube\config并注意该服务器现在反映在Azure中运行的AKS群集。要验证,请执行kubectlgetnodes命令。我们可以看到单个节点工作者确认成功配置了我们的AKS集群。将ASP.NET核心应用程序部署到AKS现在,集群都已设置为要将应用程序部署到其中。打开我们之前在应用程序根目录中查看的aksdeploy.yml文件。目前,镜像是指本地Docker镜像。让我们改变它以引用我们推送到Azure容器注册表的镜像。而不是“image:”属性指向aks:local,将其更改为服务器上带有标记的镜像名称:learningaksacr.azurecr.io/aks/v1:latest。之前,我们将此应用程序部署到本地群集,并将服务类型用作NodePort。现在我们正在将这些部署到像Azure这样的云服务,我们可以将“type:”属性更改为LoadBalancer。保存文件,然后使用kubectlapply命令进行部署。kubectlapply-f.\aksdeploy.yml这将创建定义的Kubernetes对象,其中包括部署和服务。创建的服务将应用程序公开给Internet。要监视部署的进度,请使用带--watch参数的kubectlgetservice命令。最初,aks部署服务的外部IP显示为挂起。一旦外部IP从挂起更改为IP地址,请复制IP。要测试您的应用程序,请浏览到外部IP地址。我们可以看到我们的应用程序在AKS集群中的工作节点上运行。结论现在,您应该了解如何将ASP.NET核心应用程序或任何类似的微服务应用程序容器化和部署到AzureKubernetes服务。我们还在文章中探讨了Azure容器注册表的作用。虽然我们绕道而行展示了在本地系统上的部署,但希望这表明通过交互式或通过清单的声明性配置来扩展Kubernetes部署是多么容易。要了解有关通过AzureKubernetesServices使用Kubernetes的更多信息,请从MicrosoftAzure文档中的https://docs.microsoft.com/en-us/azure/aks/intro-kubernetesAzureKubernetesServices(AKS)简介开始。阅读本文后,您应该熟悉一些步骤,但文档将引导您完成其他选项和方案。第二十一章CentOS7安装Docker环境#step1:安装必要的一些系统工具?yum?install?-yyum-utilsdevice-mapper-persistent-datalvm2#Step2:添加软件源信息yum-config-manager--add-repohttp://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo#Step3:更新并安装Docker-CEyummakecachefastyum-y?install?docker-ce#Step4:开启Docker服务servicedockerstart使用官方安装脚本自动安装(仅适用于公网环境)curl-fsSLhttps://get.docker.com|?bash?-sdocker--mirrorAliyunUbuntu14.0416.04(使用apt-get进行安装)#step1:安装必要的一些系统工具sudo?apt-getupdatesudo?apt-get-y?install?apt-transport-httpsca-certificatescurlsoftware-properties-common#step2:安装GPG证书curl-fsSLhttp://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg?|?sudo?apt-keyadd-#Step3:写入软件源信息sudo?add-apt-repository?"deb[arch=amd64]http://mirrors.aliyun.com/docker-ce/linux/ubuntu$(lsb_release-cs)stable"#Step4:更新并安装Docker-CEsudo?apt-get-yupdatesudo?apt-get-y?install?docker-ce?#安装指定版本的Docker-CE:#Step1:查找Docker-CE的版本:#apt-cachemadisondocker-ce#??docker-ce|17.03.1~ce-0~ubuntu-xenial|http://mirrors.aliyun.com/docker-ce/linux/ubuntuxenial/stableamd64Packages#??docker-ce|17.03.0~ce-0~ubuntu-xenial|http://mirrors.aliyun.com/docker-ce/linux/ubuntuxenial/stableamd64Packages#Step2:安装指定版本的Docker-CE:(VERSION例如上面的17.03.1~ce-0~ubuntu-xenial)#sudoapt-get-yinstalldocker-ce=[VERSION]?#通过经典网络、VPC网络内网安装时,用以下命令替换Step2、Step3中的命令#经典网络:#curl-fsSLhttp://mirrors.aliyuncs.com/docker-ce/linux/ubuntu/gpg|sudoapt-keyadd-#sudoadd-apt-repository"deb[arch=amd64]http://mirrors.aliyuncs.com/docker-ce/linux/ubuntu$(lsb_release-cs)stable"#VPC网络:#curl-fsSLhttp://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu/gpg|sudoapt-keyadd-#sudoadd-apt-repository"deb[arch=amd64]http://mirrors.cloud.aliyuncs.com/docker-ce/linux/ubuntu$(lsb_release-cs)stable"Docker使用手册12149

献花(0)
+1
(本文系zymITsky首藏)