Docker

Docker介绍

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

Docker组成

一个完整的 Docker 有以下几个部分组成:

  • DockerClient 客户端
  • Docker Daemon 守护进程
  • Docker Image 镜像
  • DockerContainer 容器

Docker 的安装

在线安装和离线安装
Docker 阿里镜像加速仓库在线安装

安装步骤

1.官网中文安装参考手册
https://docs.docker-cn.com/engine/installation/linux/docker-ce/centos/

确定你是 CentOS7 及以上版本
$ cat /etc/redhat-release

yum 安装 gcc 相关 
$ yum -y install gcc
$ yum -y install gcc -c++

卸载旧版本

2.安装需要的软件包

$ yum install -y yum-utils device-mapper-persistent-data lvm2

3.拉取docker镜像仓库

$ yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4.更新 yum 软件包索引

$ yum makecache fast

5.安装 DOCKER CE

$ yum -y install docker-ce
启动 docker
$ systemctl start docker && systemctl enable docker
测试
$ docker version
$ docker run hello-world

6.配置镜像加速
阿里云镜像加速地址: https://ably8t50.mirror.aliyuncs.com

$ vim  /etc/docker/daemon.json

{
  "registry-mirrors": ["https://ably8t50.mirror.aliyuncs.com"]
}

加载配置重启服务
$ systemctl daemon-reload
$ systemctl restart docker

卸载
$ systemctl stop docker
$ yum -y remove docker-ce
$ rm -rf /var/lib/docker

Docker 私有仓库离线安装

Docker 私有仓库
docker-registry (opens new window)是官方提供的工具,可以用于构建私有的镜像仓库。本文内 容基于 docker-registry (opens new window)v2.x 版本。

配置仓库

配置私有仓库的时候,json 文件如下格式:

$ cat >> /etc/docker/daemon.json << EOF
{  

"insecure-registries": ["192.168.100.10:5000"]

}
EOF

安装运行 docker-registry

使用官方 registry 镜像来运行:

$ docker run -d -p 5000:5000 --restart=always --name registry registry

默认情况下,仓库会被创建在容器的 /var/lib/registry 目录下。你可以通过 -v 参数来将镜像 文件存放在本地的指定路径。例如下面的例子将上传的镜像放到本地的 /opt/data/registry 目 录。

$ docker run -d \    
	-p 5000:5000 \
	--name registry \
	--restart=always  \
	-v /opt/data/registry:/var/lib/registry \
	registry:latest

仓库使用

在私有仓库上传、搜索、下载镜像
创建好私有仓库之后,就可以使用 docker tag 来标记一个镜像,然后推送它到仓库。例如私有仓库地址为 127.0.0.1:5000。

先在本机查看已有的镜像。

$ docker image ls
REPOSITORY                    TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                        latest              ba5877dc9bec        6 weeks ago         192.7 MB

使用 docker tag 将 ubuntu:latest 这个镜像标记为 127.0.0.1:5000/ubuntu:latest。
格式为docker tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]。

$ docker tag ubuntu:latest 127.0.0.1:5000/ubuntu:latest
$ docker image ls
REPOSITORY                    TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu                        latest              ba5877dc9bec        6 weeks ago         192.7 MB
127.0.0.1:5000/ubuntu:latest  latest              ba5877dc9bec        6 weeks ago         192.7 MB

使用 docker push 上传标记的镜像。

$ docker push 127.0.0.1:5000/ubuntu:latest
The push refers to repository [127.0.0.1:5000/ubuntu]
373a30c24545: Pushed
a9148f5200b0: Pushed
cdd3de0940ab: Pushed
fc56279bbb33: Pushed
b38367233d37: Pushed
2aebd096e0e2: Pushed
latest: digest: sha256:fe4277621f10b5026266932ddf760f5a756d2facd505a94d2da12f4f52f71f5a size: 1568

用 curl 查看仓库中的镜像。

$ curl 127.0.0.1:5000/v2/_catalog
{"repositories":["ubuntu"]}

下载镜像

这里可以看到 {“repositories”:[“ubuntu”]},表明镜像已经被成功上传了。
先删除已有镜像,再尝试从私有仓库中下载这个镜像。

$ docker image rm 127.0.0.1:5000/ubuntu:latest
$ docker pull 127.0.0.1:5000/ubuntu:latest
Pulling repository 127.0.0.1:5000/ubuntu:latest
ba5877dc9bec: Download complete
511136ea3c5a: Download complete
9bad880da3d2: Download complete
25f11f5fb0cb: Download complete
ebc34468f71d: Download complete
2318d26665ef: Download complete
$ docker image ls
REPOSITORY                         TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
127.0.0.1:5000/ubuntu:latest       latest              ba5877dc9bec        6 weeks ago         192.7 MB

Docker 的常用命令

  • docker info 信息描述
  • docker version 版本信息
  • docker --help 帮助命令

镜像命令

docker images 列出本地主机上的镜像

docker search 某个 xx 镜像的名字

$ docker search nginx 
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                             Official build of Nginx.                        15928     [OK]   
jwilder/nginx-proxy               Automated Nginx reverse proxy for docker con…   2101      [OK]
richarvey/nginx-php-fpm           Container running Nginx + PHP-FPM capable of…   820       [OK]
jc21/nginx-proxy-manager          Docker container for managing Nginx proxy ho…   288             
linuxserver/nginx                 An Nginx container, brought to you by LinuxS…   160             

下载镜像

$ docker pull 镜像名字[:TAG]

$ docker pull nginx 等价于 docker pull nginx:latest (latest 最新版)
删除某个 xx 镜像的名字 ID
删除镜像 docker rmi 镜像 ID (要先删除容器才能删)
删除单个 docker rmi -f 镜像 ID (-f 强制删除)
删除多个 docker rmi -f 镜像名 1:TAG 镜像名 2:TAG
删除全部 docker rmi -f $(docker images -qa)

导出镜像

[root@docker01 ~]# docker image list
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              ff426288ea90        3 weeks ago         207MB
nginx               latest              3f8a4339aadd        5 weeks ago         108MB

'导出'
[root@docker01 ~]# docker image save centos > docker-centos.tar.gz

'导入镜像'
[root@docker01 ~]# docker image load -i docker-centos.tar.gz  
e15afa4858b6: Loading layer  215.8MB/215.8MB
Loaded image: centos:latest

[root@docker01 ~]# docker image list
REPOSITORY    TAG         IMAGE ID        CREATED         SIZE
centos        latest      ff426288ea90    3 weeks ago     207MB
nginx         latest      3f8a4339aadd    5 weeks ago     108MB

容器命令

启动容器
docker run [OPTIONS] IMAGE [COMMAND][ARG...]

启动交互式容器
列出当前所有正在运行的容器

ps 列出当前所有正在运行的容器

退出容器

两种退出方式

exit 		容器停止退出
ctrl+P+Q 	容器不停止退出 

启动容器

$ docker start 容器 ID 或者容器名字

重启容器

$ docker restart 容器 ID 或者容器名字

停止容器

$ docker stop 容器 ID 或者容器名字

强制停止容器

$ docker kill 容器 ID 或者容器名字

删除已停止的容器

$ docker rm 容器 ID

一次性删除多个容器

$ docker rm -f $(docker ps -a -q)
$ docker ps -a -q | xargs docker rm 重要

启动守护式容器

$ docker run -d 容器名

使用镜像 centos:latest 以后台模式启动一个容器
docker run -d centos
问题:然后 docker ps -a 进行查看,会发现容器已经退出 很重要的要说明的一点:Docker 容器后台运行,就必须有一个前台进程. 容器运行的命令如果不是那些一直挂起的命令(比如运行 top,tail),就是会自 动退出的。 这个是 docker 的机制问题,比如你的 web 容器,我们以 nginx 为例,正常情况 下,我们配置启动服务只需要启动响应的 service 即可。例如 service nginx start 但是,这样做,nginx 为后台进程模式运行,就导致 docker 前台没有运行的应用, 这样的容器后台启动后,会立即自杀因为他觉得他没事可做了. 所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行

查看容器日志

$ docker logs -f -t --tail 容器 ID
-t 是加入时间戳
-f 跟随最新的日志打印
--tail 数字 显示最后多少条

查看容器内运行的进程

$ docker top 容器 ID

查看容器内部细节

$ docker inspect 容器 ID

进入正在运行的容器并以命令行交互

$ docker exec -it 容器 ID bashshell

重新进入 docker attach 容器 ID

上述两个区别

attach 直接进入容器启动命令的终端,不会启动新的进程
exec 是在容器中打开新的终端,并且可以启动新的进程

Docker 容器数据卷

1.是什么

先来看看 Docker 的理念: 将运用与运行的环境打包形成容器运行,运行可以伴随着容器,但是我们 对数 据的要求希望是持久化的 容器之间希望有可能共享数据Docker 容器产生的数据,如果不通过 docker commit 生成新的镜像,使得数据做 为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了。 为了能保存数据在 docker 中我们使用卷。

2.能干嘛

  • 卷就是目录或文件,存在于一个或多个容器中,由 docker 挂载到容器,但不属 于联合文件系统,因此能够绕过 Union File System 提供一些用于持续存储或共 享数据的特性:
  • 卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此 Docker 不 会在容器删除时删除其挂载的数据卷

特点:

1:数据卷可在容器之间共享或重用数据
2:卷中的更改可以直接生效
3:数据卷中的更改不会包含在镜像的更新中
4:数据卷的生命周期一直持续到没有容器使用它为止 容器的持久化 容器间继承+共享数据

数据卷

容器内添加数据卷
直接命令添加

$ docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名

查看数据卷是否挂载成功

$ docker inspect 容器 ID

容器和宿主机之间的数据共享 主机创建文件,容器可以同步 容器停止退出后,主机修改后数据是否同步 同步

命令(容器只读权限)

$ docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名                  

实例:

$ docker run -d -p 80:80 -v /opt/data:/usr/share/nginx/html  --name nginx nginx:latest 
$ docker run -d -p 80:80 -v /opt/data:/usr/share/nginx/html:rw  --name nginx nginx:latest

Dockerfile 添加

根目录下新建 mydocker 文件夹并进入 ,可在 Dockerfile 中使用 VOLUME 指令来给镜像添加一个或多个数据卷
VOLUME ['/dataVolumeContainer',"/dataVolumeContainer2","/dataVolumeCont ainer3"]
说明:

  • 出于可移植和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在 Dockerfile 中实现。
  • 由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在 这样的特定目录。

Dockerfile 构建

FROM centos 
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"] 
CMD echo "finished-----success1" 
CMD /bin/bash
构建镜像

$ docker build -f /mydocker/dockerfile2 -t zzyy/centos .

run 容器

$ docker run -it zzyy/centos

通过上述步骤,容器内的卷目录地址已经知道,对应的主机目录地址哪??
$ docker inspect 容器 ID 可以查看主机对应默认地址口

备注

  • Docker 挂载主机目录 Docker 访问出现 cannot open directory .: Permission deniedy
  • 解决办法:在挂载目录后多加一个–privileged=true 参数即可

Docker 镜像

是什么?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环 境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、 环境变量和配置文件。

UnionFS (联合文件系统)

  • UnionFS (联合文件系统) : Union 文件 系统(UnionFS) 是一种分层、轻量级并 且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加, 同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体 的应用镜像。
  • 特性: 一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统, 联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文 件和目录

Docker 镜像加载原理

  • Docker 镜像加载原理: docker 的镜像实际上由一层一层的文件 系统组成,这种层级的文件系统 UnionFS.
  • botfs(boot fle system)主要包含 bootloader 和 kernel, botoader 主要是引导 加载 kernel,Linux 刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层 是 botfs。这一层与我们典型的 Linux/Unix 系统是一样的,包含 boot 加载器和 内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 boofs.
  • roots (root file system),在 botfs 之上。 包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就 是各种不同的操作系 统发行版,比如 Ubuntu, Centos 等等。
  • 为什么 Docker 镜像要采用这种分层结构呢最大的一个好处就是一共享资源 比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存 一份 base 镜像, 同时内存中也只需加载-份 base 镜像,就可以为所有容器服务了。而且镜像的每 一层都可以被共享。

特点

Docker 镜像都是只读的 当容器启动时,一个新的可写层被加载到镜像的项部。 这一层通常被称作"容器层","容器层"之下的都叫"镜像层”。

docker镜像 commit 操作补充
dockercommit 提交容器副本使之成为--个新的镜像 docker commit -m=“提交的描述信息”-a=”作者”容器 ID 要创建的目标镜像 名:[标签名]

案例演示

1. 从 Hub 上下载 tomcat 镜像到本地并成功运行

$ docker run -it -p 8080:8080 tomcat
-p 主机端口:docker 容器端口
-P 随机分配端口
-i 交互
-t 终端

2.故意删除上一步镜像生产 tomcat 容器的文档

$ docker exec -it 容器名 /bin/bash
$ cd webapps
$ rm -rf docs

3. 也即当前的 tomcat 运行实例是一- 个没有文档内容的容器,以它为模板 commit 一个没有 doc 的 tomcat 新镜像 atguigu/tomcat02

$ docker commit -a=“zzyy”-m="del tomcat docs" 容器 ID atguigu/tomcat02:1.2

4.启动我们的新镜像并和原来的对比

  • 启动 atguigu/tomcat02,它没有 docs
  • 新启动原来的 tomcat,它有 docs

un -it -p 8080:8080 tomcat
-p 主机端口:docker 容器端口
-P 随机分配端口
-i 交互
-t 终端


**2.故意删除上一步镜像生产 tomcat 容器的文档**
```shell
$ docker exec -it 容器名 /bin/bash
$ cd webapps
$ rm -rf docs

3. 也即当前的 tomcat 运行实例是一- 个没有文档内容的容器,以它为模板 commit 一个没有 doc 的 tomcat 新镜像 atguigu/tomcat02

$ docker commit -a=“zzyy”-m="del tomcat docs" 容器 ID atguigu/tomcat02:1.2

4.启动我们的新镜像并和原来的对比

  • 启动 atguigu/tomcat02,它没有 docs
  • 新启动原来的 tomcat,它有 docs
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐