Docker的学习之路:
个人对docker技术算是挺感兴趣吧,将docker好好总结了一下,在下面去介绍。难点就是要分清容器—仓库—镜像之间的关系,其他都还好,不难理解,也挺有意思。2048游戏的引入,让docker技术更加容易被理解。
Docker:爱不释手的容器技术
文章目录
来自百度:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
一个完整的Docker有以下几个部分组成:
1.DockerClient客户端
2.Docker Daemon守护进程
3.Docker Image镜像
4.DockerContainer容器
Docker 架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类
特性:在docker的网站上提到了docker的典型场景:
1.Automating the packaging and deployment of applications(使应用的打包与部署自动化)
2.Creation of lightweight, private PAAS environments(创建轻量、私密的PAAS环境)
3.Automated testing and continuous integration/deployment(实现自动化测试和持续的集成/部署)
4.Deploying and scaling web apps, databases and backend services(部署与扩展webapp、数据库和后台服务)
局限:Docker并不是全能的,设计之初也不是KVM之类虚拟化手段的替代品,简单总结几点:
1.Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用
2.LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
3.隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库
4.网络管理相对简单,主要是基于namespace隔离
5.cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费)
6.Docker对disk的管理比较有限
7.container随着用户进程的停止而销毁,container中的log等用户数据不便收集
namespace:
即“命名空间”,也称“名称空间” 、”名字空间”。VS.NET中的各种语言使用的一种代码组织的形式 ,通过名称空间来分类,区别不同的代码功能 同时也是VS.NET中所有类的完全名称的一部分。
Linux Namespace
LXC所实现的隔离性主要是来自kernel的namespace, 其中pid, net, ipc, mnt, uts 等namespace将container的进程, 网络, 消息, 文件系统和hostname 隔离开。
百度百科:namespacehttps://baike.baidu.com/item/namespace/1700121?fr=aladdin
lxc:
Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
LXC的实现
Sourceforge上有LXC这个开源项目。LXC项目本身只是一个为用户提供一个用户空间的工具集,用来使用和管理LXC容器。LXC真正的实现则是靠Linux内核的相关特性,LXC项目只是对此做了整合。基于容器的虚拟化技术起源于所谓的资源容器和安全容器。
LXC在资源管理方面依赖于Linux内核的cgroups子系统,cgroups子系统是Linux内核提供的一个基于进程组的资源管理的框架,可以为特定的进程组限定可以使用的资源。LXC在隔离控制方面依赖于Linux内核的namespace特性,具体而言就是在clone时加入相应的flag(NEWNS NEWPID等等)。
传统虚拟化和容器技术对比:
以上内容是我针对docker在百科上找的一些资料,方便自己和大家对docker进行解读。
docker演示:实验环境:
红帽7.3
真机:172.25.12.250
虚拟机server1:172.25.12.1
虚拟机server2:172.25.12.2
这里我自己找好了一些docker的资源包,方便我在后面下载的时候使用。所以我在server1、2虚拟机上将他们加到了yum源中:
server1、2:
vim /etc/yum.repos.d/docker.repo
下载:yum install -y docker-ce
Docker: 2048游戏的产生:
使用docker --help可以查看docker的使用方法,下面我将对docker的各类使用一一演示说明:
docker:2048游戏演示:
使用的docker history 镜像名 可以查看在生成这个镜像时,执行了那些指令。这些指令就是生成这个镜像功能的关键。比如上方的2048,就是通过history中的created by下面的指令生成的。
docker 跑ubuntu操作系统:
上面相当于是用docker跑了一个程序:下面我们来跑一个操作系统:
这里还是同样的导入方法,我运行了一个ubuntu系统,很明显,我可以在的docker技术下,在我的红帽发行版linux系统的虚拟机中运行另外一个发行版的系统。
这里我使用exit释放掉了这个仓库,docker ps 查看正在运行的docker进程,已经被释放
但是这个仓库的数据是仍然还在的,可以start开启,再attach进入使用:
镜像分层结构:
1.在docker的使用中,我们在容器中建立基础镜像后,可以无限制地去根据这个镜像拉起仓库,也就是使用该基础镜像,只要资源足够的话【资源:存储,端口,ip等】
2.镜像是分层的:分为容器层和镜像层。
3.copy-on-write:docker从上往下依次查找文件,一个镜像最多127层
4.每一条RUN命令都对应着一个镜像层
数据变更,镜像改动都作用在容器层,容器层调用镜像层的数据,更改完后落地为新的镜像层,镜像层都为只读。
Docker 构建镜像:
上面我们已经使用过镜像了,那来看看镜像该如何构建:
构建镜像常用的方法有两种:
bulid && load
一:load方法:
load方法我们上面已经使用过,就不做过多分析。需要tar包或者stdin,可以在网上去找资源。
二:bulid方法:
Dockerfile:镜像生成所需要的命令集,按行读取,镜像会根据读取到的命令,去执行相应的动作,从而完成镜像构建。
1.在一个空的目录中,创建Dockerfile文件,Dockerfile命名必须为“Dockerfile”,Docker镜像构建时,会查找指定目录中的Dockerfile。
2、编写Dockerfile
FROM ubuntu
通过FROM指令,Docker编译程序能够知道通过哪个基础镜像执行来进行编译。所有的Dockerfile都必须以FROM指令开始。通过该指令,我们相当于有了一个最基本的Ubuntu系统。
RUN touch file{1..5}
RUN指令是我们进入基础镜像后要执行的动作
简单一点的Dockfile这样写就完成了,我们先来看看效果
这里我们可以看到tag标签是使用的系统默认,当然我们也可以使用docker tag 镜像:新标签 镜像:旧标签
来更换
几种必须掌握的Dokcerfile命令:
FROM:指定基础镜像
RUN:在容器中运行命令并创建新的镜像层,常用于安装软件包【RUN yum install -y vim】
EXPOSE: 如果容器中运行应用服务,可以把端口暴露出去,即端口映射【EXPOSE 80】
VOLUME:申明数据卷,通常指定的是应用的数据挂载点【VOLUME ["/var/www/html"]】
WORKDIR:为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工作目录,如果目录不存在,则会自动创建
CMD : 设置容器启动后执行的命令,会被docker run后面的命令行覆盖。
ENTRYPOINT : 也为设置容器启动后执行的命令,但不会被忽略,一定被执行。 docker run 后面的参数可以传递给ENTRYPOINT指令当作参数。Dockerfile中只能指定一个ENTRYPOINT,有多个的话只有最后一个生效。
ENV : 设定变量【ENV name world 设定变量name的值为world ,$name则代表world】
ADD : 和COPY作用一样,但是ADD会对压缩文件(tar, gzip, bzip2, etc)做提取和解压操作
另外,Dockerfile有shell和exec两种格式的写法,shell写法就和日常在shell中输入命令是一样的。exec写法不解析变量,在此不做介绍。
Docker httpd服务镜像构建:
Dockerfile构建镜像需要有基础镜像。上面我们使用ubuntu系统的镜像,下面我们来使用rhel7,正好是我们正在使用的系统【作者比较熟悉】。
1.先生成基础镜像:操作系统镜像【rhel7】
2.编写Dockerfile,配置yum源,运行build指令
!!!【报错】
Rpmdb checksum is invalid: dCDPT(pkg checksums): systemd-libs.x86_64 0:219-30.el7 - u
如果出现这个报错:更改Dockerfile:
然后再运行build指令:
docker build -t rhel7:vm1 .
镜像建好了,我们拉起一个容器,看看我们下载的httpd服务。
Docker nginx镜像构建:
Dockerfile:
运行:build建立镜像:
建立容器,查看端口是否开启,curl测试:OK,nginx服务搭建完成。
镜像优化:
1.选择最精简的基础镜像
2.减少镜像的层数
3.清理镜像构建的中间产物
4.注意优化网络请求
5.尽量去构建缓存
6.使用多阶段构建镜像
层数即run的行数,中间产物即例如我们刚才下载nginx时编译用到的gcc,make这些软件。下面只对多阶段构建镜像做说明:
如上图所示:在第一个FROM部分,已经完成了nginx的安装,解压等工作。
第二个FROM部分 ,在新的基础镜像【gcr…上(比较精简)】直接考备了nginx目录过来,然后开启。两个阶段,作用在不同的镜像上,使最终我们用到的是一个很小的镜像。
大大的小小阳