一、dacker简介
容器(container-based)虚拟化方案,充分利用操作系统本身已有的机制和特性,以实现轻量级的虚拟化(每个虚拟机安装的不是完整的虚拟机)。
docker目标:Build,Ship And Run any App,Anywhere----即通过对应用组件的封装(Packaging),发布(Distribution),运行(Running)等生命周期的管理,达到应用组件级别的“一次封装,到处运行”
docker的优缺点:
优点:启动快,资源占用小,资源利用率高,快速建构标准化运行环境。创建分布式应用程序是快速交付和部署,更轻松的迁移和扩展,更简单的更新管理。
缺点:docker是基于linux 64bit 的,无法在其他环境中使用。
LXC是基于cgroup等的Linux kernel 功能的,因此container的guest系统只能是linux。
隔离性相比kvm之类的虚拟化方案有所欠缺,所以container共用一部分运行库。
管理相对简单,主要基于namespace隔离。
docker对disk的管理有限。
container随着用户进程的停止而销毁,container中的log等用户数据不便收集。
cgroup的cpu和cpust提供的cpu功能相比kvm等虚拟化方案相比难以度量。
二、docker与虚拟机的比较
1.比虚拟机启动快,可以秒级启动。
2.对资源占用小,宿主机上可运行千台容器。
3.方便用户获取,发布和更新应用镜像,指令简单,学习费用低。
4.通过dockerfile配置文件来灵活的自动创建和部署镜像、容器,提高工作效率。
5.docker除了运行其中的应用外,基本不消耗其他系统资源,保证应用性能的同时,尽量减少系统开销。
三、docker的安装
1.二进制安装
wget http://download2.yunwei.edu/shell/docker.tar.gz 解压后切换到docker目录下 [root@localhost docker]# ls ca.crt docker-app.tar.gz docker.sh remove.sh [root@localhost docker]# bash docker.sh docker docker-compose docker-containerd docker-containerd-ctr docker-containerd-shim dockerd docker-init docker-proxy docker-runc Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /etc/systemd/system/docker.service. 查看docker是否启动成功(有输出即可) [root@localhost docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@localhost docker]# systemctl status docker | grep active Active: active (running) since 一 2019-06-17 15:01:44 CST; 3min 47s ago
安装的docker容器在/usr/local/bin下
[root@localhost bin]# ll
总用量 135832
-rwxr-xr-x. 1 root root 37698064 10月 19 2018 docker
-rwxr-xr-x. 1 root root 8479184 10月 19 2018 docker-compose
-rwxr-xr-x. 1 root root 15355928 10月 19 2018 docker-containerd
-rwxr-xr-x. 1 root root 12683608 10月 19 2018 docker-containerd-ctr
-rwxr-xr-x. 1 root root 4328352 10月 19 2018 docker-containerd-shim
-rwxr-xr-x. 1 root root 49618008 10月 19 2018 dockerd
-rwxr-xr-x. 1 root root 760048 10月 19 2018 docker-init
-rwxr-xr-x. 1 root root 2639191 10月 19 2018 docker-proxy
-rwxr-xr-x. 1 root root 7509696 10月 19 2018 docker-runc
[root@localhost bin]# pwd
/usr/local/bin
2.yum安装(ba那本较低,不推荐)
四、docker镜像
docker运行容器之前需要本地存在镜像,若本地不存在,那么docker会找默认镜像仓库(docker hub 公共注册服务器中的仓库)下载,用户也可以通过配置使用自己的镜像库。
镜像在下载的过程中是分层的,并且在各层前都有各层的 ID 号。层(layer)是AUFS(联合文件系统)的重要概念,是实现增量保存和更新的基础。
1.查看镜像
docker images
2.下载镜像
docker pull name
如:docker pull nginx(默认追加 latest 标签,表示库中最新镜像)
3.重命名镜像(原镜像不会消失,id号也不变,在系统中只保存一份)
docker tag oldname:TAG 路径/newname:TAG
4.查找镜像(去官网查找)
docker search mysql
5.删除镜像
docker rmi name:TAG
docker rmi id
如:docker rmi yunwei.edu/test/nginx:latest
【注意】当有别名镜像时,是同一个id号多个名字,删除任意一个对彼此无伤害,直至删除最后一个。镜像被彻底删除用 id 号删除,默认会删除同一个 id 的多个镜像,除非该镜像创建的容器存在,那么镜像能够不被删除,所以在删除镜像的时候要先删除使用镜像的容器,再删除镜像。
6.镜像保存的位置(文件的形式)
/var/lib/docker/image/overlay2/imagedb/content/sha256
五、镜像分层
docker镜像的分层结构:支持通过扩展现有镜像,创建新的镜像。
如上图,可以看到,新镜像是从base镜像一层一层叠加生成的,没安装一个软件,就在现有镜像基础上增加一层。
分层的优势:
共享资源:有多个镜像都从base镜像构建而来,那么 docker host 镜像只要在磁盘保存一份base镜像即可,同时内存中只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
容器层与镜像层:当容器启动时,一个新的可写层加载到镜像的顶部,这一层被称为“容器层”。“容器层”之下的都是“镜像层”。
【注意】所有对容器层的改动---无论添加、删除还是修改文件都只会发生在容器层中。只有容器层是可写的,其他的镜像层都是只读的。
镜像的添加,读取,删除和修改:
镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层有一个相同路径的文件,如/a,上层的/a会覆盖下层的/a,所以用户只能访问上层的/a。在容器层中,用户看到的是一个叠加之后的文件系统。
1.添加文件:在容器中创建文件时,新文件被添加到容器层中。
2.读取文件:在容器中读取某个文件时,docker会从上往下依次在各镜像层中查找此文件,一旦找到,打开并读入内存中。
3.修改文件:在容器中修改已存在的文件时,docke会从上往下依次在各镜像层中查找此文件,一旦找到,立即将其复制到容器层中,然后修改之。
4.删除文件:在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。 找到后,会在容器层中记录下此删除操作。
【注意】只有当修改时才复制一份数据,这种特性被称为“Copy-on-Write”。由此可见,容器层保存的是镜像层变化的部分,不会对镜像本身进行修改。(容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享)
六、镜像的创建
创建镜像的三种方法:
1.基于修改后的容器创建
docker run -it name:TAG 环境变量
如:docker run -it nginx:latest /bin/bash
退出:exit
查看当前环境中运行的容器
docker ps
docker ps -a
唤醒容器
docker start ID
如:docker start 9d9c42654b2a
基于运行的容器生成一个新的镜像(id变化了)
docker commit id newname:TAG
2.基于本地模板导入(可以实现容器的共享)
docker save -o 导出后的名字 要导出的镜像
docker save -o nginx.tar.gz nginx:latest
ls查看一下是否导出
导入镜像:
docker load -i 之前导出的压缩包
如:docker load -i nginx.tar.gz
3.基于dockerfile的镜像创建
dockerfile是一个文本文件,用来配置image,记录了镜像构建的所有步骤。docker根据该文件生成的二进制文件生成image文件。
创建dockerfile文件,文件名称必须是dockerfile。
vim dockerfile
FROM centos:7
MAINTAINER:设置镜像的作者,可以是任意字符串。
COPY:将文件从 build context 复制到镜像。
COPY 支持两种形式:
COPY src dest
COPY ["src", "dest"] 注意:src 只能指定 build context 中的文件或目录。
ADD:与 COPY 类似,从 build context 复制文件到镜像。不同的是,如果 src 是归档文件(tar, zip, tgz, xz 等),文件会 被自动解压到 dest。
ENV:设置环境变量,环境变量可被后面的指令使用。例如:
...
ENV MY_VERSION 1.3
RUN apt-get install -y mypackage=$MY_VERSION
...
EXPOSE:指定容器中的进程会监听某个端口,Docker 可以将该端口暴露出来。我们会在容器网络部分详细讨论。
VOLUME:将文件或目录声明为 volume。
WORKDIR:为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录。
RUN:在容器中运行指定的命令,RUN 指令通常用于安装应用和软件包。
CMD:容器启动时运行指定的命令。 Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 可以被 docker run 之后的参数替换。
ENTRYPOINT:设置容器启动时运行的命令,可让容器以应用程序或者服务的形式运行。
Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效。CMD 或 docker run 之后的参数会被当做参数传递给 ENTRYPOINT。
七、docker的使用
[root@localhost ~]# docker create -ti nginx:latest
da0c2ea6f534b3ff6e5a5d233bea22929726a4d22df59a0d6a9165c4912f0e1b
2.查看所有容器的状态
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES da0c2ea6f534 nginx:latest "nginx -g 'daemon of…" About a minute ago Created serene_sammet
3.启动停止的容器
[root@localhost ~]# docker start da0c2ea6f534 da0c2ea6f534 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES da0c2ea6f534 nginx:latest "nginx -g 'daemon of…" 2 minutes ago Up 8 seconds 80/tcp serene_sammet
4.运行一个容器
[root@localhost ~]# docker run -ti nginx:latest /bin/bash root@560c4c6ea8c6:/#
退出且容器也退出:exit CTRL+d
退出容器,并且容器处于UP状态: ctrl+q+p
-t: 分配一个伪终端
-i: 让容器的标准输入持续打开
/bin/bash: 环境变量
5.以后台守护进程形态运行
[root@localhost ~]# docker run -dti nginx:latest 34ed4d41cf525380595e5796407f8daa26d88f0680550b178a327741e188077e [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 34ed4d41cf52 nginx:latest "nginx -g 'daemon of…" 35 seconds ago Up 34 seconds 80/tcp heuristic_keldysh 560c4c6ea8c6 nginx:latest "/bin/bash" 7 minutes ago Exited (0) About a minute ago distracted_meitner da0c2ea6f534 nginx:latest "nginx -g 'daemon of…" 12 minutes ago Up 9 minutes 80/tcp serene_sammet
6.终止容器
[root@localhost ~]# docker stop 34ed4d41cf52 # docker kill 34ed4d41cf52 34ed4d41cf52 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 34ed4d41cf52 nginx:latest "nginx -g 'daemon of…" 2 minutes ago Exited (0) 2 seconds ago heuristic_keldysh 560c4c6ea8c6 nginx:latest "/bin/bash" 9 minutes ago Exited (0) 2 minutes ago distracted_meitner da0c2ea6f534 nginx:latest "nginx -g 'daemon of…" 14 minutes ago Up 11 minutes 80/tcp serene_sammet
7.重启容器
[root@localhost ~]# docker restart 34ed4d41cf52 34ed4d41cf52 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 34ed4d41cf52 nginx:latest "nginx -g 'daemon of…" 3 minutes ago Up 1 second 80/tcp heuristic_keldysh 560c4c6ea8c6 nginx:latest "/bin/bash" 11 minutes ago Exited (0) 4 minutes ago distracted_meitner da0c2ea6f534 nginx:latest "nginx -g 'daemon of…" 15 minutes ago Up 13 minutes 80/tcp
serene_sammet
【注意】非持久后台守护状态的虚拟机,在重启后你查看还是关闭状态
8.删除容器
[root@localhost ~]# docker rm 560c4c6ea8c6 560c4c6ea8c6 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 34ed4d41cf52 nginx:latest "nginx -g 'daemon of…" 7 minutes ago Up 3 minutes 80/tcp heuristic_keldysh da0c2ea6f534 nginx:latest "nginx -g 'daemon of…" 19 minutes ago Up 16 minutes 80/tcp serene_sammet
-f: 删除处于运行中的容器
-l: 删除链接,保留容器
-v: 删除挂载的数据
9.进入容器
attach直接进入容器,启动命令的终端,不会启动新的进程:
[root@localhost ~]# docker run -d httpd:latest /bin/bash -c "while true;do sleep 1;echo i_am_docker;done" 36bf31925c47ce4d78b03ff2bdd4533f679bfd53e524daf30ab7936ea278b35d [root@localhost ~]# docker attach 36bf31925c47 i_am_docker i_am_docker i_am_docker [root@localhost ~]# docker stop 36bf31925c47 36bf31925c47
exec在容器中打开新的终端,并且可以启动新的进程
[root@localhost ~]# docker exec -it 36bf31925c47 /bin/bash
root@36bf31925c47:/usr/local/apache2#
10.导入和导出容器
导出容器:
[root@localhost ~]# docker export 36bf31925c47 > httpd.tar.gz [root@localhost ~]# ls httpd.tar.gz
导入容器:(将容器导导入为镜像)
[root@localhost ~]# cat httpd.tar.gz | docker import - test
sha256:7ccb81d21489c67b5980514f24877e04d26318db41a89e089e711e5b5fdd8bb3
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest 7ccb81d21489 11 seconds ago 137MB
httpd latest e77c77f17b46 6 days ago 140MB
nginx latest 719cd2e3ed04 7 days ago 109M
11.查看容器日志
[root@localhost ~]# docker logs -f b1c7a5446f8d /bin/bash: True: command not found /bin/bash: True: command not found
12.暂停容器
[root@localhost ~]# docker pause 36bf31925c47 36bf31925c47 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 36bf31925c47 httpd:latest "/bin/bash -c 'while…" 12 hours ago Up 54 seconds (Paused) 80/tcp
13.取消暂停继续运行容器
[root@localhost ~]# docker unpause 36bf31925c47 36bf31925c47 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 36bf31925c47 httpd:latest "/bin/bash -c 'while…" 12 hours ago Up 3 minutes 80/tcp focused_kepler
命令总结
八、docker镜像的仓库----repository的创建
仓库分为公共仓库和私有仓库
DockerHub的官方仓库 https://hub.docker.com
DockerPool社区仓库 https://dl.dockerpool.com
Dockern Pool (http://dockerpool.com)是国内专业的Docker社区,目前 也提供了官方镜像的下载管理服务
仓库---创建自己的私有仓库
(1) docker run -d -p 5000:5000 -v /var/lib/registry:/var/lib/registry --restart=always --name registry:latest registry:2 5000是访问镜像仓库的地址
(2)docker 客户端设置
1° 修改配置文件,将私有库地址添加进去
vim /etc/sysconfig/docker
line 4: add Docker-Registry's URL
OPTIONS='--insecure-registry 192.168.210.128:5000 --selinux-enabled --log-driver=journald.....'
(3)systemctl restart docker 重新启动 docker服务
(4)docker tag my-imge:latest 192.168.210.128:5000/myimge1:latest 更换 my-imge:latest 一个新的名称标签
(5)docker push 192.168.210.128:5000/my-imge1:latest 上传 my-imge1:latest
(6)删除本地原有的busybox 镜像,然后向私有库192.168.254.162重新下载
docker rmi 192.168.210.128:5000/my-imge1:latest
docker pull 192.168.210.128:5000/my-imge1:latest
第二种方案:
(2)docker客户端设置:
[root@compute docker]# pwd /etc/docker [root@compute docker]# cat daemon.json 修改配置文件 { "registry-mirrors": ["http://cc83932c.m.daocloud.io"], "insecure-registries":["192.168.42.20:5000"], "max-concurrent-downloads": 10, "log-driver": "json-file", "log-level": "warn", "log-opts": { "max-size": "10m", "max-file": "3" } } [root@compute docker]# systemctl restart docker
(3)更换镜像
[root@localhost docker]# docker tag registry:2 192.168.42.30:5000/registry:latest
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.42.30:5000/registry latest f32a97de94e1 3 months ago 25.8MB
registry 2 f32a97de94e1 3 months ago 25.8MB
[root@compute docker]# docker push 192.168.42.30:5000/registry:latest
[root@localhost docker]# docker rmi registry:2
[root@localhost docker]# docker rmi 192.168.42.30:5000/registry
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
[root@compute docker]# docker pull 192.168.42.30:5000/registry:latest