docker容器技术实现

本文介绍了Docker的基础概念,包括镜像、容器和仓库,阐述了Docker的优势,如轻便、快速启动和高效资源利用。详细讲解了Docker镜像的分层存储、容器的运行原理以及数据卷的持久化。还提到了Docker的安装配置,包括使用Docker加速器以及私有仓库的搭建。此外,文章讨论了容器数据持久化的两种方式:数据卷(Volumes)和挂载主机目录(Bind mounts),并给出了相关操作示例。最后,简述了Docker网络设置,通过macvlan网络实现跨主机的容器互通。
摘要由CSDN通过智能技术生成

docker
介绍及安装
一、docker基础与概念
1.1、什么是docker
 Docker使用Google公司推出的Go语言进行开发实现,基于Linux内核的 cgroup,namespace,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主机和其它隔离的进程,因此也称其为容器。
Docker在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得Docker技术比虚拟机技术更为轻便、快捷。

Docker 包括三个基本概念
 镜像(Image)
 容器(Container)
 仓库(Repository)
1.2、为什么要使用docker

持续交付和部署
更轻松的维护和扩展
一致的运行环境
更快速的启动时间
更高效的利用系统资源

幻灯片4

一、docker基础与概念
1.3、镜像(Image)
1、Docker镜像
操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root文件系统。比如官方镜像centos:latest 就包含了完整的一套centos:latest最小系统的root文件系统。
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。
2、分层存储
镜像由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

幻灯片5

一、docker基础与概念
1.4、容器(Container)
镜像(Image)和容器(Container)有紧密的关系,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。
前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
幻灯片6

一、docker基础与概念
1.5、仓库(Repository)
(1)、Docker Registry
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
以Ubuntu镜像为例,ubuntu是仓库的名字,其内包含有不同的版本标签,如,14.04, 16.04。我们可以通过 ubuntu:14.04,或者 ubuntu:16.04来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest。
仓库名经常以两段式路径形式出现,比如jwilder/nginx-proxy,前者往往意味着Docker Registry多用户环境下的用户名,后者则是对应的软件名。
(2)、Docker Registry公开服务
Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
最常使用的 Registry 公开服务是官方的 Docker Hub(https://hub.docker.com) ,这也是默认的 Registry。拥有大量的高质量的官方镜像。
由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。常见的有阿里云加速器(https://ddddsl2r.mirror.aliyuncs.com) 、DaoCloud加速器(https://www.daocloud.io/mirror#accelerator-doc) 等。
(3)、私有 Docker Registry
除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。另外,除了官方的Docker Registry外,还有第三方软件实现了Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,VMWare Harbor和Sonatype Nexus。
幻灯片7

二、安装Docker与加速器配置

Docker分为CE和EE两大版本。CE即社区版(免费,支持周期7个月),EE即企业版,强调安全,付费使用,支持周期24个月。
Docker CE分为stable, test, 和nightly三个更新频道。每六个月发布一个stable版本(18.09, 19.03, 19.09…)。这里主要介绍Docker CE在Linux 下的安装与使用。
2.1、CentOS安装Docker CE
Docker CE支持64位版本CentOS 7,并且要求内核版本不低于3.10。 CentOS 7满足最低内核的要求,如果你之前安装过docekr,或者安装了老版本的docker,建议先卸载掉。旧版本的 Docker称为docker或者 docker-engine,使用以下命令卸载旧版本:
[root@localhost ~]# yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-selinux
docker-engine-selinux
docker-engine
幻灯片8

二、安装Docker与加速器配置

接着,使用yum在线安装Docker CE,执行以下命令安装依赖包:
[root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
鉴于国内网络问题,强烈建议使用国内源,执行下面的命令添加yum软件源:
[root@localhost ~]# yum-config-manager
–add-repo
https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
最后,可以安装Docker CE了。
[root@localhost ~]# yum makecache fast
[root@localhost ~]# yum install docker-ce
最后,启动 Docker CE:
[root@localhost ~]# systemctl enable docker
[root@localhost ~]# systemctl start docker
幻灯片9

二、安装Docker与加速器配置

1、建立docker用户组
默认情况下,docker命令会使用Unix socket与Docker引擎通讯。而只有root用户和docker组的用户才可以访问Docker引擎的Unix socket。出于安全考虑,一般Linux系统上不会直接使用root用户。因此,更好地做法是将需要使用docker的用户加入docker用户组。因此,首先建立docker组:
[root@localhost ~]# groupadd docker
将当前用户加入 docker 组:
[root@localhost ~]# usermod -aG docker $USER

2、测试 Docker 是否安装正确

[root@localhost ~]# docker run hello-world
若能正常输出“Hello from Docker!”以上信息,则说明安装成功。
幻灯片10

二、安装Docker与加速器配置
2.2、镜像加速器配置
国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
Docker官方提供的中国registry mirror https://registry.docker-cn.com
七牛云加速器 https://reg-mirror.qiniu.com/
 我们以 Docker 官方加速器 https://registry.docker-cn.com 为例进行介绍。对于使用systemd的系统(Debian 8+、CentOS 7),可以在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

{
 “registry-mirrors”: [
 “https://registry.docker-cn.com”
 ]
}
注意,一定要保证该文件符合 json 规范,否则 Docker 将不能启动。之后重新启动服务。
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
 配置加速器之后,如果拉取镜像仍然十分缓慢,请手动检查加速器配置是否生效,在命令行执行docker info,如果从结果中看到了如下内容,说明配置成功。
[root@localhost home]# docker info
…
Registry Mirrors:
 https://registry.docker-cn.com/
Live Restore Enabled: false
Product License: Community Engine

########
工作方式及作用

########
配置
########
使用
docker=d

d pull 镜像名称:标签 #从远程仓库下载镜像


d image rm image #删除指定镜像
d image rm $(d image ls -q) #删除所有镜像
d run -it --rm image-id #进入容器操作后,退出,容器随之删除
d container rm #删除终止的镜像
d container rm -f #强制删除镜像
d container prune #删除所有终止且不再使用的容器


docker run -d --name centos7 --privileged=true centos:7 /usr/sbin/init #以特权方式运行容器可执行,systemctl命令
docker run -d --name centos7 --privileged=true centos:7 /sbin/init #以特权方式运行容器可执行,systemctl命令
d run 镜像名称:标签 #运行一个新的镜像
d run -it --name 自定义镜像名称 image:tag bash #以交互模式进入自定义名称的镜像,然后在容器内执行操作
d exec -it image:tag bash # 以交互模式进入镜像执行操作,退出后,镜像和镜像内新建的内容仍然存在,可再次启动(工作中常用)
d attach image-id #进入容器操作,退出后,删除容器
d run -it -d image:tag #将容器放在后台执行,但容器内的内容是在前台输出
d container start image-id #启动终止的容器
d container stop image-id #终止正在运行的容器
d container restart image-id #重启正在运行的容器
d export image-id > centos-7.6.1810.tar #导出容器快照,以.tar格式保存
cat centos-7.6.1810.tar | d import - centos:7.6.1810 #把容器快照再导出为镜像


d info #查看容器下载源信息
d ls #查看已下载的镜像
d image ls #列出下载的镜像
d image ls image # 列出指定镜像id
d image ls -q #列出镜像所有镜像id
d ps #查看正在运行的容器
d ps -a #查看所有的容器
d container ls #查看当前运行的容器
d container ls -a #查看所有的容器
docker logs image-id #查看容器内的日志
d container log image-id #查看容器内的日志
curl http://ip:5000/v2/_catalog #查看私有仓库内的已上传的容器,ip为私有仓库宿主机ip

私有仓库的使用
仓库(Repository)是集中存放镜像的地方。对于仓库地址dl.dockerpool.com/ubuntu来说,dl.dockerpool.com是注册服务器地址,ubuntu是仓库名。
5.1、Docker Hub
 目前Docker官方维护了一个公共仓库Docker Hub,其中已经包括了数量超过15,000的镜像。大部分需求都可以通过在Docker Hub中直接下载镜像来实现。可以在https://cloud.docker.com 免费注册一个Docker账号。然后通过执行“docker login -u”命令交互式的输入用户名及密码来完成在命令行界面登录Docker Hub。可以通过 docker logout 退出登录。
 可以通过“docker search”命令来查找官方仓库中的镜像,并利用“docker pull”命令来将它下载到本地。
例如以 centos 为关键词进行搜索:
[root@localhost ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 5029 [OK]
ansible/centos7-ansible Ansible on Centos7 119 [OK]
jdeathe/centos-ssh CentOS-6 6.10 x86_64 / CentOS-7 7.5.1804 x86… 102 [OK]
 可以看到返回了很多包含关键字的镜像,其中包括镜像名字、描述、收藏数(表示该镜像的受关注程度)、是否官方创建、是否自动创建。
 官方的镜像说明是官方项目组创建和维护的,automated 资源允许用户验证镜像的来源和内容。根据是否是官方提供,可将镜像资源分为两类。

一种是类似centos这样的镜像,被称为基础镜像或根镜像。这些基础镜像由Docker公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。
还有一种类型,比如jdeathe/centos-ssh镜像,它是由Docker的用户创建并维护的,往往带有用户名称前缀。可以通过前缀username/来指定使用某个用户提供的镜像,比如这里是jdeathe用户。

5.1、Docker Hub

搜索到需要的镜像后,接下来就可以下载镜像了,执行“docker pull“将镜像下载到本地。

[root@localhost ~]# docker pull centos

用户也可以在登录后通过docker push命令来将自己的镜像推送到Docker Hub。以下命令中的username请替换为你的Docker账号用户名。

[root@localhost ~]# docker tag centos:6.10 username/centos:6.10
[root@localhost ~]# docker image ls
[root@localhost ~]# docker push username/centos:6.10
[root@localhost ~]# docker search username

5.2、私有仓库
有时候使用 Docker Hub 这样的公共仓库可能不方便,那么,用户也可以创建一个本地仓库供私人使用。docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库。本文内容基于 docker-registry v2.x 版本。
我们可以通过获取官方registry镜像来运行一个私有仓库。
[root@localhost ~]# docker run -d -p 5000:5000 --restart=always --name registry registry
这将使用官方的registry镜像来启动私有仓库。默认情况下,仓库会被创建在容器的/var/lib/registry目录下。你可以通过-v参数来将镜像文件存放在本地的指定路径。例如下面的例子将上传的镜像放到本地的/opt/data/registry目录。
[root@localhost volumes]# docker run -d
-p 5000:5000
-v /opt/data/registry:/var/lib/registry
registry
创建好私有仓库之后,就可以使用 docker tag 来标记一个镜像,然后推送它到仓库。例如私有仓库地址为 127.0.0.1:5000,先在本机查看已有的镜像。
[root@localhost volumes]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 7.6.1810 5e29074e0926 22 hours ago 202MB
nginx v1 c9e88ea39d68 8 days ago 109MB
使用 docker tag 将 nginx:v1这个镜像标记为 127.0.0.1:5000/nginx:v1。
[root@localhost volumes]# docker tag nginx:v1 127.0.0.1:5000/nginx:v1
[root@localhost volumes]# docker image ls 127.0.0.1:5000/nginx
REPOSITORY TAG IMAGE ID CREATED SIZE
127.0.0.1:5000/nginx v1 c9e88ea39d68 8 days ago 109MB
使用 docker push 上传标记的镜像。
[root@localhost volumes]# docker push 127.0.0.1:5000/nginx:v1

查看私有仓库里的容器
curl http://ip:5000/v2/_catalog #查看私有仓库里的已上传的容器 ,ip为私有仓库宿主机的ip

5.2、私有仓库

如果你不想使用127.0.0.1:5000作为仓库地址,比如想让本网段的其他主机也能把镜像推送到私有仓库。这就需要使用172.16.213.230:5000这样的内网地址作为私有仓库地址,这时你会发现无法成功推送镜像。这是因为Docker默认不允许非 HTTPS方式推送镜像。我们可以通过Docker的配置选项来取消这个限制。
对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)

{
“registry-mirror”: [
“https://registry.docker-cn.com”
],
“insecure-registries”: [
“172.16.213.230:5000”
]
}
添加完成,重启docker服务才能生效。

容器数据持久化

默认容器的数据是保存在容器的可读写层,当容器被删除时其上的数据将会丢失,所以为了实现数据的持久性则需要选择一种数据持久技术来保存数据,当前有以下二种方式:

 数据卷(Volumes)
 挂载主机目录 (Bind mounts)

 Volumes方式下:容器内的数据被存放到宿主机(linux)一个特定的目录下(/var/lib/docker/volumes/)。这个目录只有Docker可以管理,其他进程不能修改。如果想持久保存容器的应用数据,Volumes是Docker推荐的挂载方式。

 Bind mounts方式下:容器内的数据被存放到宿主机文件系统的任意位置,甚至存放到一些重要的系统目录或文件中。除了Docker之外的进程也可以任意对他们进行修改;

1.数据卷管理
volumes完全由Docker进程创建和管理。可以通过命令“docker volume create”来创建一个指定的卷,也可以由Docker进程在创建容器或服务的过程中来创建;数据卷有如下特性:
 对数据卷的修改会立马生效
 对数据卷的更新,不会影响镜像
 数据卷默认会一直存在,即使容器被删除。


  • docker volume create my-vol #在docker默认的数据卷目录(/var/lib/docker/volumes/)下创建一个目录
    docker run -d -P
     --name web \
     # -v my-vol:/wepapp
     --mount source=my-vol,target=/webapp
     training/webapp
     python app.py
    #启用一个挂载指定数据卷的容器 , 这里是创建一个名为web的容器,并加载一个数据卷到容器的/webapp目录下,这个命令中使用了“–mount”标记来将数据卷挂载到容器里。在一次 docker run中可以挂载多个数据卷。除了使用“–mount”标记,还可以使用“-v”(即为–volume)参数,起初,-v用于独立容器,–mount用于swarm services。但是,从Docker 17.06开始,也可是使用“–mount”用于独立容器。–mount命令更精准详细,并且易理解。 v或者–volume:由3部分参数组成,使用“:”间隔。顺序不能颠倒。
    第一个部分是volumes名字,在宿主机上具有唯一性。匿名卷名字系统给出。
    第二部分是挂载到容器里的文件或文件夹路径。
    第三部分是可选项列表分隔符,例如“or”。

    “–mount”选项:由多个键值对组成,=。–mount要比-v或者–volume命令更长,但是更容易理解。常用的键值对有如下几个:
    type:可以是bind,volume或者tmpfs。这篇文章主要讨论volumes,所以type一直使用volume。
    source:volumes的名字,匿名volume可以省略。source可缩写为src.
    destination:挂载到容器中的文件或目录路径。可也缩写为dst或者使用target。
    readonly:指定挂载在容器中为只读


  • docker rm -v image-id #删除容器时,同时删除挂载的数据卷
    docker volume prune #一次性删除所有无主的数据卷


  • d volume ls #查看创建好的数据卷
    d vollume inspect newvolume #查看创建好的数据卷属性信息
    d inspect web #查看挂载数据卷启动的容器信息

2.挂载主机目录
在docker的早期版本中就存在的功能,与volumes相比,他的功能比较局限。当使用bind mounts时,宿主机的目录或文件被挂载到容器中。容器将按照挂载目录或文件的绝对路径来使用或修改宿主机的中的数据。宿主机中的目录或文件不需要预先存在。
但是,Bind mounts方式无法通过Docker CLI来管理,另外,使用bind mounts的容器可以在容器内部的进程对主机文件系统进行修改,包括创建,修改和删除重要的系统文件和目录,这个功能虽然很强大,但显然也会造成安全方面的影响。所以还是推荐数据卷(Volumes)管理方式。


  • docker run -d -P
    –name web1
    #-v /src/webapp:/opt/webapp
    –mount type=bind,source=/src/webapp1,target=/opt/webapp
    training/webapp
    python app.py
    #上面的命令加载宿主机的/src/webapp目录到容器的/opt/webapp目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,以前使用 -v 参数时如果本地目录不存在 Docker 会自动为你创建一个文件夹,现在使用 --mount 参数时如果本地目录不存在,Docker 会报错。

docker run -d -P
–name web1
#-v /src/webapp1:/opt/webapp:ro
–mount type=bind,source=/src/webapp1,target=/opt/webapp,readonly
training/webapp
python app.py
#Docker挂载宿主机目录的默认权限是读写,用户也可以通过增加readonly指定为只读。这样加了readonly之后,/src/webapp1就挂载为只读了。如果你在容器内/opt/webapp目录新建文件,会显示“Read-only file system“错误。

docker run --rm -it \

-v $HOME/.bash_history:/root/.bash_history \

–mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history
centos:6.10
bash
#挂载宿主机的某个文件,这样就可以记录在容器输入过的命令了。

区别:1.数据卷挂载方式,只有属于docker组的用户可以管理挂载的目录,安全性高,创建方式更快捷,常用于生产环境
2.挂载主机方式,任何用户都可以管理挂载的目录,安全性低,挂载前需向挂载的拷贝app.py文件,然后在进行挂载,常用于测试

docker网络
假设我们有 A , B , C 3台机器

A: 192.168.1.10

B: 192.168.1.11

C: 192.168.1.12

现在A上输入

docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 mynet
创建一个macvlan的网络,网络名为mynet 继承网卡eth0的属性

分别在B和C上输入相同的命令

这样我们就创建了3个同样网络,分别在3个不同的机器上

使用命令创建docker

docker run --restart=always --net=mynet --name=“test1” --ip=192.168.1.100 -v /jastme/test1:/testl --privileged=true --cpu-shares 1024 -m 4096 -dit a9ff415eb22b /bin/bash

docker run --restart=always --net=mynet --name=“test1” --ip=192.168.1.101 -v /jastme/test1:/testl --privileged=true --cpu-shares 1024 -m 4096 -dit a9ff415eb22b /bin/bash

docker run --restart=always --net=mynet --name=“test1” --ip=192.168.1.102 -v /jastme/test1:/testl --privileged=true --cpu-shares 1024 -m 4096 -dit a9ff415eb22b /bin/bash
分别在3台机器上创建3个docker容器

然在进入容器ssh到其他容器

你可以发现网络都是通的,这样,局域网就成功创建好了。

d network creat --subnet=


########
优化及故障排除
d logs image-id #查看当前容器产生日志,并根据日志进行排错
#########

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值