前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker容器实战:原理、架构与应用

Docker容器实战:原理、架构与应用

作者头像
硬核项目经理
发布2019-08-06 15:53:20
1.3K0
发布2019-08-06 15:53:20
举报

一、云计算简介

1.Docker,通过将运行环境和应用程序打包到一起,来解决部署的环境依赖问题,真正做到跨平台的分发和使用

2.容器由于省去了操作系统,整个层级更简化,可以在单台服务器上运行更多的应用

3.ubuntu的存储部分可以使用AUFS,而CentOS只能使用Devicemapper,前者的性能更好

二、Docker的安装

三、使用Docker

1.容器其实就是运行在操作系统上的一个进程,只不过加入了对资源的隔离和限制,Docker三大核心功能:

  • CGroups:用来限定一个进程的资源使用,在一个操作系统之上,用户ID、机器名等资源是全局的,运行的进程间都是访问同一份资源
  • Namespace:用来划分不同的命名空间
  • UnionFS:用来处理分层镜像

2.镜像就是容器中的文件系统,还集成了一部分容器运行的参数,可以将镜像看作容器的模板

3.一些命令:

  • docker info:查看运行状态及版本信息,是整个Docker Daemon守护进程运行状况的缩影,包括容器个数、镜像个数、Daemon版本、使用的存储驱动等信息
  • docker pull:拉取镜像
  • docker run -i -t ubuntu /bin/bash:-i表示启动一个可交互的容器,-t表示使用pseudo-TTY,关联到容器的stdin和stdout,ubuntu是运行的镜像,/bin/bash表示启动容器时要运行的命令,如果要退出交互模式且不影响容器运行,使用【Ctrl+PQ】
  • 运行长时间容器:-d让容器在后台运行,docker logs <容器id>查看容器的日志(其实就是查看容器的标准输出日志)
  • docker ps:查看容器,-a查看所有容器

四、Docker深入解析

A.Docker的架构

1.Docker Daemon:运行在一个主机上,用户并不是直接同Docker Daemon进行交互,而是通过Docker Client

2.Docker Client:是主要的用户访问Docker的渠道,用户通过它对Docker Daemon进行访问控制

3.Docker Image:是一个只读的模板

4.Docker Registry:是存放Image的仓库,可以使用公有的和私有的Registry来进行上载和下载

5.Docker Containers:Docker容器就像一个文件夹,一个容器包含了应用程序所需的所有环境,每个容器都源于一个Image,容器可以运行、开始、停止、移动并删除,每个容器都是隔离的、安全的应用

B.Docker如何工作

1.Docker Image是只读模板,随容器一起启动,每个镜像包含多个层,使用的是Union File System来将这些层组合成一个镜像,Union FS可以将文件和目录进行透明的层叠组装,形成一个单独的文件系统,每个镜像都来源于一个基础镜像

2.一个容器由操作系统、用户文件和元数据构成,运行时,容器会在Union FS的顶层增加文件层

3.Docker使用的Namespace:PID Namespace、NET Namesapce、IPC Namesapce、MNT Namespace、UTS Namespace;使用的Union FS包括AUFS、Btrfs、VFS、DevicemapperFS等

4.-p 主机端口:容器端口

5.进入镜像:docker exec -it 容器id /bin/bash

6.docker commit 容器id 新名字,保存镜像以及一切改动

C.镜像制作

1.获取镜像的三种方式:

  • 拉取镜像:docker pull
  • 把容器转换成镜像:docker commit
  • 制作镜像:通过Dockerfile生成镜像

2.查找DockerHub镜像:docker search

3.push镜像,首先先tag镜像,docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME]NAME[:TAG]

4.根据Dockerfile编译镜像:在Dockerfile文件所在目录docker build .

5.删除镜像:docker rmi

D.docker run 命令

1.语法格式:docker run [OPTIONS] IMAGE[:TAG!@DIGEST][COMMAND][ARG…]

2.前后台运行:后台-d,前台-i -t,后台运行后再次进入容器,可以使用docker attach <cid>,退出时使用【ctrl+pq】

3.容器的标识:—name,Image[:tag],Image[@digest]

4.PID设置:—pid=host,可以在容器里面共享主机的PID Namespace

5.IPC设置:—pic是进程间通信的支持,可以和主机共享

五、容器的网络

A.容器自带网络

1.通过docker network ls来查看,包括bridge、host 、none

B.网络详情

1.通过docker network inspect <net>来查看本机的网络信息

2.当启动一个容器时,都会在全局注册相关的网络信息

C.用户自定义网络

1.包括三种:桥接网络、Overlay网络、插件网络

2.桥接网络:

  • 系统默认的桥接是docker0
  • 使用docker network create —driver bridge mynet创建mynet桥接网络
  • 通过—net属性将容器挂接到mynet中
  • 在同一个桥接下,形成了一个私网,相互间是可以通信的,但这仅限于在同一台主机上

2.Overlay网络:

  • Overlay是一种虚拟交接技术,主要是解决不同IP地址段之间的网络通信问题,Docker使用的Overlay技术是VXLAN,是借助于libnetwork实现的
  • Overlay需要一个K-V服务来存储相关的主机信息,可以使用Consul、Etcd和ZooKeeper,Consul是默认的
  • Overlay主机还必须 开放UDP/4789和TCP/UDP/7946,分别用作数据通道和控制通道

六、容器的数据

A.数据卷

1.数据卷提供了一种主机和容器共享数据的方式,有些时候需要用它来做持久化和数据共享。当做持久化时,通常数据卷都会比较大,可以将其放在单独的磁盘、卷或者阵列上,这个时候容器只是一个执行环境。当做数据共享时,可以用于开发和测试分布式系统,如需要用到共享盘、处理fencing等

2.创建数据卷:主要通过-v属性来指定,-v [主机目录]:[容器目录]

3.任何时候都不要将宿主机的根目录映射到容器内部

B.使用数据型容器

1.把容器的卷分享给另一个容器用

2.创建一个包含外部卷的容器,只需要create即可

3.在另一个容器中通过—volumes-from来映射

C.备份、还原和迁移数据卷

1.-v $(pwd):xxxx,$(pwd)表示当前路径

D.容器和代码进行关联

1.数据卷的几个特点:

  • 数据卷在容器创建时进行初始化
  • 数据卷既可以共享,也可以在容器之间重用
  • 对于数据卷的读写是直接下发的
  • Commit命令不会将改动保存到镜像中
  • 即使容器被删除了,数据卷仍然存在,因此这一块需要特别注意,避免产生垃圾数据卷

七、镜像仓库

A.仓库相关的Docker命令

1.docker login -u username -p password,登录docker hub或第三方库

2.docker search mysql,查找mysql相关的库

3.docker pull mysql,拉取mysql镜像

4.docker push [OPTIONS] [server/][user/] image name[:TAG],提交镜像

八、镜像和容器的存储结构

A.镜像、容器和存储驱动的关系

1.每个镜像都由多个镜像层组成,这些镜像层是只读的,从下往上,以栈的方式组合在一起,组成容器的根文件系统

2.容器运行时,所有文件变化 的数据都保存在容器层中,如新建文件、修改文件、删除文件

3.Docker在管理镜像和容器时,使用写时复制技术,写时复制采用了共享和复制,针对相同的数据,系统只保留一份数据,所有操作都访问这一份数据。当有操作需要修改或添加数据时,操作系统会把这部分数据复制到新的地方,这个操作会在新的数据区修改或添加数据,其他操作仍然在旧的数据区读取原始数据

4.docker history命令,列出镜像的层信息

5.定时复制技术节约存储空间,加速容器的启动时间,

6.数据卷是宿主机上的一个文件或者目录,启动容器时,会把这个文件或目录挂载到容器中。数据卷不受存储驱动程序管理,数据卷中的数据读写操作会练过存储驱动程序,直接工作在宿主机的文件系统中。容器中挂载 的数据卷数量没有限制 ,多个容器也可以挂载同一个数据卷

B.如何选择存储驱动

1.使用哪种存储驱动取决于用户在宿主机上使用何种文件系统,一些存储驱动可以工作在不同的后端文件系统上,另一些存储驱动必须使用相同的后端文件系统

2.—storage-driver=<name>,设置存储驱动

3.考虑因素:没有哪种存储驱动能够适用于所有场景;每种存储驱动都在不断升级;

4.选择方向:稳定性;熟悉性;成熟性;Overlay和Overlay2

C.AUFS存储驱动

1.AUFS是一种Union FS,将不同的目录合并成一个目录,做成一个虚拟文件系统。AUFS为每个目录设置不同权限 ,并且可以实时的添加、删除、修改已经挂载好的目录

D.Devicemapper存储驱动

1.Devicemapper把镜像和容器存储在虚拟设备上,使用按需分配、写时复制快照技术管理镜像和容器,对块设备进行操作,而不是整个文件

2.在生产环境中应该使用Devicemapper的direct-lvm模式,该模式下,Devicemapper使用真实的块设备为存储介质,在块设备上建立thin pool

E.Btrfs存储驱动

1.Btrfs是下一代存储技术,使用了按需分配、写时复制和快照技术管理镜像和容器,目前还处于开发阶段,生产环境慎用

2.Btrfs把镜像层和容器层保存在独立的子卷或快照中,镜像中的基础层作为一个子卷保存,其他镜像卷和容器卷都作为快照保存

F.ZFS存储驱动

1.ZFS是下一代文件系统,提供卷管理、快照、校验、压缩、消重和多地复制等功能,如果开发者没有使用过ZFS,建议不要在生产环境使用

G.Overlay存储驱动

1.OverlayFS是一种联合文件系统,Linux内核4.0及以上版本支持Overlay2存储驱动

2.Overlay/Overlay2存储驱动很快,比AFUS和Devicemapper都要快,在某些场景下甚至快于Btrfs

九、定制Docker Daemon

A.修改Docker Daemon的三种方式

1.三种方式:命令行修改、修改启动项和修改配置文件,命令行时Docker Daemon运行在前端,适合调试,在生产环境中应使用另外两种方式

B.仓库相关配置

1.—disable-legacy-registry选项:设置不从旧版本的镜像仓库下载镜像

2.—registry-mirror选项:指定镜像仓库,可以设置多个镜像仓库

3.—insecure-registry选项:设置可以从不安全的镜像仓库下载镜像

C.安全相关配置

1.-p,—pidfile选项:设置Docker Daemon使用的pid文件,默认为/var/run/docker.pid

2.-H,—host选项:配置Docker Daemon监听的IP和端口

3.—tls,—tlscacert,—tlscert,—tlskey,—tlsverify选项:配置远程通信的TLS通信及相关证书

D.日志相关

1.-D,—debug选项:开房调试模式

2.—log-level,—log-driver,—log-opt选项:设置日志等级、日志格式等信息

E.存储相关配置

1.-g,—graph选项:设置Docker运行时的根目录

2.—storage-driver选项:配置Docker Daemon的存储驱动

3.—ostorage-opt选项:配置存储驱动的参数

F.网桥相关配置

1.—big选项:设置docker0的IP和子网掩码

2.—fixed-cidr,—fixed-cidr-v6选项:配置容器的IP范围

3.—mtu选项:配置docker0的最大会转单元长度

4.-b,—bridge选项:配置网桥

G.容器与外部通信

1.—ip-forward选项:会自动修改宿主机的ip_forward,默认true

2.—iptables选项:会在iptables中追加转发规则,默认true

3.—ip,—ipv6选项:设置IP地址

H.其他网络配置

1.—default-gateway、—default-gateway-v6选项:设置网关

I.excdriver配置

1—exec-opt选项:设置如何管理容器的CGroups,默认值为cgroupfs,可选systemd

2.—exec-root选项:设置execdriver使用的状态文件的根目录,默认为/var/run/docker

J.其他配置

1.—default-ulimit,设置一个用户能够使用的最大进程数,启动容器时为—ullimit参数

十、如何编写Dockerfile

A.本地编译镜像

1.加入.dockerignore,过滤不需要的文件

2.使用指定Dockerfile文件,-f

3.-t用于打标签

4.—no-cache,编译时不使用缓存

2.dockerignore文件

1.和git类似

C.Dockerfile格式

1.每条指令由指令+参数组成,中间以空格隔离,#为注释

2.一般指令大写,参数小写,第一条指令必须是FROM,设置基础镜像

D.Dockerfile指令详解

1.FROM指令:设置基础镜像,可以设置多个基础镜像,两条FROM指令之间的内容放在一个镜像中,tag和digest是可选项,忽略tag会使用latest镜像

2.MAINTAINER指令:设置镜像作者

3.RUN指令:生成一个新的容器,在容器中执行脚本,脚本正常执行完后,Docker daemon会把该容器提交为一个中间镜像,供后面的指令使用

4.CMD指令:设置容器的启动集合,只能有一条CMD指令,如果写了多条,只有最后一条生效

5.LABEL指令:设置镜像的标签,可以通过docker inspect查看标签,每个标签采用Key=Value的格式,不同标签之前通过空格隔离。每条指令会生成一个镜像层,一个镜像只能有127层,因此最好使用一条LABEL指令设置完成

6.EXPOSE指令:设置镜像暴露端口,记录容器启动时监听在哪些端口

7.ENV指令:设置镜像中的环境变量,支持读取环境变量的指令:ADD、COPY、ENV、EXPOSE、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD

8.ADD指令:把文件复制到镜像中,ADD <src>..<dest>,src必须在编译目录中,src为URL时,如果dest结尾没有/则dest作为文件名保存在/tmp,如果有/,则dest作为存储目录,如果src为目录,复制目录内所有内容,包括文件系统的元数据,如果scr是压缩文件(identity,gzip,bzip2,xz)会解压成目录,如果src是文件则复制文件和元数据,如果src使用了通配符或是一个文件列表,则dest必须以/结尾,如果dest不以/结尾则为文件名,如果dest不存在,则ADD会自动创建dest及缺失的上级目录

9.COPY指令:把文件或目录复制到镜像中

10.ENTRYPOINT指令:设置容器的入口程序,计算器程序是容器启动时执行的程序,docker run命令中最后的命令将作为参数传递给入口程序,只有最后的ENTRYPOINT生效

11.VOLUMN指令:设置容器的挂载点

12.USER指令:设置执行RUN、CMD和ENTRYPOINT的用户名或UID

13.WORKDIR指令:设置RUN、CMD、ENTRYPOINT、ADD和COPY指令的工作目录

14.ARG指令:设置编译变量

15.ONBUILD指令:设置子镜像的编译钩子指令,当从父镜像生成子镜像时,子镜像编译过程中,首先会执行父镜像中的ONBUILD指令

16.STOPSIGNAL指令:设置容器退出时,Docker Daemon向容器发送的信号量

E、CMD、ENTRYPOINT和RUN的区别

1.RUN指令是设置编译镜像时执行的脚本和程序,镜像编译完成,RUN指令的生命周期结束

2.CMD叫作容器默认启动命令,在docker run末尾添加Command即可替换掉CMD设置的启动程序

3.ENTRYPOINT叫做入口程序,不能被docker run末尾的Command替换,末尾的Command会被当做字符串,传递给ENTRYPOINT作为参数,可以在docker run中加入—entrypoint替换镜像中的入口程序

4.一些规则 :

  • 在Dockerfile中,应至少有一条CMD或ENTRYPOINT指令
  • 当使用容器作为一个程序容器时,应使用ENTRYPOINT定义入口程序
  • 在Dockerfile中,如果同时定义了ENTRYPOINT和CMD,CMD会作为参数传递给ENTRYPOINT

十一、Dockerfile最佳实践

A.基本原则

1.容器的生命期是短暂的

2.使用.dockerignore

3.只安装需要的包

4.每个容器只运行一个进程

5.减少镜像层

6.把多个参数排在不同的行中

7.编译缓存:Docker Daemon从基础镜像编译出新的镜像;针对ADD和COPY指令,Docker Daemon会检查镜像层中所有源文件的元数据和文件内容;除了ADD和COPY指令外,Docker Daemon在镜像缓存中寻找镜像层时,不会检查文件

B.Dockerfile指令最佳实践

1.RUN指令:具有可读性,apt-get的install和update必须在一行执行,尽量在一条指令中安装需要的包

2.CMD指令:应尽量使用JSON格式,不要使用CMD设置ENTRYPOINT的参数

3.EVN指令:使用容器对外提供服务时,最好通过环境变量设置服务相关配置

4.ADD和COPY指令:推荐使用COPY指令,因为功能更单一,仅把编译目录中的文件复制到镜像中,而ADD还会解压文件并支持远端复制

5.ENTRYPOINT指令:当需要把容器当作一个命令行工具使用时,最好通过ENTRYPOINT指令设置镜像的入口程序

6.VOLUME指令:如果需要在容器中,对数据库、配置文件、用户上传文件夹等文件目录做数据持久化,可以使用VOLUME指令导出这些文件和目录;容器会在主机的/var/lib/docker/volumes目录中创建对应的目录挂载到容器中;

7.WORKDIR指令:设置Dockerfile中其他指令的工作目录,就使用绝对路径

8.USER指令:如果容器中的应用程序不需要特殊权限,则可以通过USER指令把应用程序的所有者设置为非root用户

9.ONBUILD指令:在基础镜像中设置钩子指令,子镜像会先执行基础镜像的ONBUILD设置的指令

C.如何减小镜像体积

1.避免apt/yum update

2.每条指令都会生成一个镜像层,每个镜像层都会占用一些磁盘空间

3.应该在一条RUN指令中,更新安装源、安装程序、清理缓存,这样可以减少镜像体积

十二、使用容器提供服务

A.使用容器提供数据库服务

1.查看启动mysql容器时可以添加的选项:docker run -it —rm mysql —verbose —help

2.-e EVNIRONMENT,可以配置环境变量

3.mysql相关目录:/etc/mysql/my.cnf、/etc/mysql/conf.d/、/var/lib/mysql/

4.mongodb相关目录:/data/db/

B.使用容器提供Web服务

1.apache相关目录:/usr/local/apache2/htdocs/、/usr/local/apache2/conf/httpd.conf

2.gitlab/gitlab-ce(git仓库)相关目录:/etc/gitlab,配置文件、/var/opt/gitlab,保存git所有版本库、/var/log/gitlab,日志

十三、建立私有镜像仓库

1.registry,镜像仓库容器,镜像存储目录:/var/lib/registry,配置文件:/etc/docker/registry/config.yml

十四、Docker常见问题

1.虚拟化就是在一台主机上运行多个相互隔离的实例,这包含两层意思,一是相互隔离,即彼此之间没有影响;二是实例,既可以是一个完整的操作系统

https://github.com/zhangyue0503/docker/tree/master/dockerrongqishizhan

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农老张 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档