docker 基础总结

1,246 阅读14分钟

docker 是什么

Docker是一个开源的容器引擎,它基于 LXC 容器技术,使用 Go 语言开发。源代码托管在 Github 上,并遵从 Apache2.0 协议。 Docker采用 C/S 架构,其可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。 简单来说: Docker 就是一种快速解决生产问题的一种技术手段。

docker 官网: www.docker.com/

理解 docker 的理念

  • 构建: 龙珠里的胶囊,将你需要的场景构建好,装在一个小胶囊里
  • 运输: 随身携带着房子、车子等,非常方便
  • 运行: 只需要你轻轻按一下胶囊,找个合适的地方一放,就ok了

优缺点

优点 :

  • 多: 使用场景多
  • 快: 环境部署快、更新快
  • 好: 好多人在用,东西好
  • 省: 省钱省力省人工。

缺点:

  • 依赖操作系统;
  • 依赖网络;
  • 银行 U 盾等场景不能用。

docker 的安装

根据不用的操作系统可以轻松在网上查找到很多安装教程,之前写过一个: blog.csdn.net/Enjolras_fu… 这里不再赘述。

测试已安装:

docker version 

网卡区别:

在安装前,只有 ens33 和 lo 网卡 在安装后,docker 启动后,多出了 docker0 网卡,网卡地址是 172.17.0.1

docker 的基本目录

  • /etc/docker/ 是 docker 的认证目录

  • /var/lib/docker/ 是 docker 的应用目录

配置 docker 加速器

这部分网上也有较多文章去具体讲解,这里就不再赘述。 blog.csdn.net/Enjolras_fu…

docker 镜像简介

docker 镜像相当于一个只读的文件,就类似于我们安装操作系统的时候所需要的各种iso 光盘镜像,我们通过运行这个镜像来完成各种应用的部署。

可以理解镜像就是一个能被 docker 运行起来的一个程序。

镜像相关命令

查找镜像:

docker search ubuntu 

获取镜像:

docker pull ubuntu 

获取的镜像存放在哪里? /var/lib/docker 目录下。

查看镜像:

docker images [image_name] 

这里是 docker images ubuntu:latest

镜像的 ID 唯一标识了镜像,如果 ID 相同,就说明是同一镜像。TAG 信息来区分不同的发行版本,如果不指定具体的标记,就默认使用 latest 来标记信息。

列出全部镜像:

docker image ls (当前存在的镜像) 

或者 docker images -a (包含已经删除的镜像记录)

这两个命令列出的结果略有不同。

查看镜像历史:

docker history [image_name]

我们获取到一个镜像,想知道他默认启动了哪些命令或者封装了哪些系统层,就可以使用 docker history 来获取。

镜像重命名:

docker tag [old_image]:[old_version] [new_image]:[new_version]

演示: docker tag nginx:latest sswang-nginx:v1.0

删除镜像:

docker rmi [image_id/image_name:image_version]

注意 如果一个 image_id 对应多个名称,要使用 name:tag 的格式删除镜像。

清除状态为 dangling 的镜像:

docker image prune 

清除所有未被使用的镜像:

docker image prune  -a  

按照条件删除部分镜像:

docker image prune -a  --filter "until=24h"

我们可以将已经下载好的镜像导出到本地,以备后用。

导出镜像:

docker save -o [包文件][镜像]

docker save [镜像1] ... [镜像n] > [包文件]

docker save 会保存镜像的全部历史记录和元数据信息。

举例: docker save -o nginx.tar sswang-nginx

导入镜像:

docker load < [image.tar_name]
docker load --input [image.tar_name]

举例: docker load < nginx.tar

容器

容器是什么? 容器类似于我们运行起来的一个操作系统,而且这个操作系统启动了某些服务。 这里的容器指的是一个运行起来的 docker 镜像。

查看正在运行的容器:

docker ps  

查看所有容器,包括已经不运行的容器:

docker ps -a  

启动已经终止的容器:

docker start [container_id]

在生产过程中,常常会出现运行和不运行的容器,我们使用 start 命令开起一个已经关闭的容器。

关闭某个容器:

docker stop [container_id]

在生产过程中,我们会因为临时情况, 要关闭某些容器,我们使用 stop 命令来关闭容器。

删除已经关闭的容器:

docker rm [container_id]  
docker container prune

删除符合条件的部分容器:

docker container prune --filter "until=24h"

强制删除运行的容器:

docker rm -f [container_id]

批量关闭并且删除容器:

docker rm -f $(docker ps -a -q)

创建并且进入容器:

docker run --name [container_name] -it [docker_image] /bin/bash 

  • --name 给容器定义一个名称
  • -i 让容器的标准输入保持打开
  • -t 让 docker 分配一个伪终端,并且绑定到容器的标准输入上
  • /bin/bash 执行一个终端命令

退出容器:

method1: exit
method2: Ctrl+D

进入一个容器:

docker exec -it [container_id] /bin/bash 

基于容器创建镜像

docker commit -m '改动信息' -a '作者信息' [container_id] [new_image:tag]

举例: 进入一个容器,创建文件之后退出。

$ docker exec -it 7f551fd3c017 /bin/bash
root@7f551fd3c017:/# mkdir /furuiyang
root@7f551fd3c017:/# exit
exit

基于该容器创建一个镜像:

$ docker commit -m 'mkdir /furuiyang' -a 'furuiyang' 7f551fd3c017 ry-nginx:v0.0.1
sha256:e0aa3ce6ace3bc8e38de40ab31a88b3901ba09c366511a280ba75b0719963c98

查看镜像:

$ docker image ls -a
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
ry-nginx              v0.0.1              e0aa3ce6ace3        14 seconds ago      126MB

基于新镜像启动一个容器:

$ docker run --name d3 -itd ry-nginx:v0.0.1 /bin/bash
6d2e0f2cf48569b44eed1af2ca9871bb56a58b561695266112f7650e84546ead

进入容器进行查看:

$ docker exec -it 6d2e0f2cf48 /bin/bash
root@6d2e0f2cf485:/# ls
bin  boot  dev	etc  furuiyang	home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

查看容器的运行日志:

docker logs [container_id]

查看容器的详细信息:

docker inspect [container_id]

在详细信息中过滤出容器的网络信息:

docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_id]

仓库管理

什么是仓库?

仓库就类似于我们在网上搜索操作系统光盘的一个镜像站。 这里的仓库指的是 Docker 镜像存储的地方。

Docker 仓库分类

  • 共有仓库: Docker hub、 Docker cloud 等
  • 私有仓库: register、 harbor 等
  • 本地仓库: 在当前的主机存储镜像的地方

仓库相关命令

  • 登录仓库: docker login [仓库名称]
  • 在仓库中 pull 镜像: docker pull [镜像名称]
  • 推送镜像: docker push [镜像名称]
  • 查找镜像: docker search [镜像名称]

部署一个私有仓库

部署流程:

  1. 根据 registry 镜像创建容器
  2. 配置仓库权限
  3. 提交镜像到私有仓库
  4. 测试

实施方案: 下载 regisstry 镜像:

docker pull registry:latest

启动仓库容器:

docker run -d -p 5000:5000 registry:latest

检查容器效果:

curl 127.0.0.1:5000/v2/_catalog

配置容器权限:

vim /etc/docker/daemin.json
{"registry-mirrors": ["http://74f21445.m.daocloud.io"], "insecure-registries": ["172.18.222.137:5000"]}

注意私有仓库的 ip 地址是宿主机的 ip 地址,并且 ip 地址的两侧有引号。

重启 docker 服务:

systemctl restart docker 
systemctl status docker 

效果查看: 启动仓库服务的容器: (在重启 docker 服务的过程中关闭了运行中的全部容器)

docker start 6492f6a098c6 

标记要提交的镜像:

docker tag ry-nginx:v0.0.1  172.18.222.137:5000/ry-nginx:v0.0.1

推送镜像:

docker push 172.18.222.137:5000/ry-nginx:v0.0.1

拉取镜像:

docker pull 172.18.222.137:5000/ry-nginx:v0.0.1

docker 数据管理

docker 的镜像是只读的,虽然可以根据镜像创建的容器可以进行操作,但是我们不能将数据保存在容器里面,因为容器会随时关闭和开启,那么应该如何将 数据保存下来呢?

答案就是数据卷和数据卷容器。

什么是数据卷

就是讲宿主机的某个目录,映射到容器中,作为数据存储的目录,我们就可以在宿主机对数据进行存储。

缺点: 太单一了。

我们可使用 docker run 来创建容器,在 docker run 命令时添加 -v 参数,就可以创建并且挂载一个到多个数据卷到当前运行的容器中。

-v 参数的作用是将宿主机的一个目录作为容器的数据卷挂载到docker容器中,使宿主机和容器之间可以共享一个 目录,如果本地路径不存在,Docker也会自动创建。 -v 宿主机文件:容器文件

关于数据卷的管理我们从两个方面来说: 1、目录 2、普通文件

数据卷之目录

命令格式:

docker run -itd --name [container_name] -v [宿主机目录]:[容器目录] [镜像名称] [命令[可选]]

命令演示: 创建测试文件:

echo 'hello ruiyang' > /tmp/file1.txt

启动一个容器,挂载数据卷

docker run -itd --name test1 -v /tmp:/test1 nginx 

进入容器查看:

docker exec -it 3733303ee /bin/bash
cat /test1/file1.txt

数据卷之文件

命令格式:

docker run -itd --name [container_name] -v [宿主机文件]:[容器文件] [镜像名称][命令[可选]]

命令演示: 创建测试文件:

echo 'file1' > /tmp/file1.txt

启动一个容器,挂载数据卷

docker run -itd --name test2 -v /temp/file1.txt:/nihao/nihao.sh nginx

这时候直接创建文件夹 nihao.sh ...

  • 查看全部的数据卷: docker volume ls
  • 删除某个数据卷: docker volume rm [VOLUME NAME]
  • 清除无用的数据卷: docker volume prune

数据卷容器

将宿主机的某个目录,使用容器的方式来表示,然后其他的应用容器将数据保存在这个容器里面,达到大批量应用数据同时存储的目的。

如果我们使用数据卷容器,在多个容器之间共享数据,并永久保留这些数据,需要有一个规范的流程才能做得到。 1、 创建数据卷容器 2、 其他容器挂载数据卷容器 注意: 数据卷容器不启动

数据卷容器实践:

创建一个数据卷容器:

docker create -v [容器数据卷目录] --name [容器名字] [镜像名称]:[命令[可选]]

docker create -v /data --name v-test nginx 

创建两个容器同时挂载数据卷容器:

docker run --volumes-from  e7dd7d04c9 -itd --name t1 nginx /bin/bash 

docker run --volumes-from  e7dd7d04c9 -itd --name t2 nginx /bin/bash 

进入 t1 操作数据卷容器:

docker exec -it 7dc224 /bin/bash
cd /data
touch reach.py

进入 t2 确认数据卷是否有改动:

docker exec -it dc17055491 /bin/bash
cd /data
ls

回到宿主机查看 /data 目录,不存在上述目录。

容器之间可以共享数据卷迷你容器,不过数据是保存在数据卷里面的,并没有保存到宿主机的文件目录中。

网络管理概述

docker 以上的内容都依赖于网络才能工作,我们从两个方面来学习网络:

  • 端口映射
  • 网络模式

端口映射概述

默认情况下,容器和宿主机之间网络是隔离的,我们可以通过端口映射的方式,将容器中的端口,映射到宿主机的某个端口上。这样我们就可以通过 宿主机的ip+port的方式来访问容器里的内容。

端口映射种类
  • 随机映射 -P(大写)
  • 指定映射 -p 宿主机端口:容器端口

注意: 在生产场景一般不使用随机映射,但是随机映射的好处就是由docker分配,端口不会冲突, 不管哪种映射都会影响性能,因为涉及到映射。

随机映射实践

随机映射我们从两个方面来学习:

  • 默认随机映射
  • 指定主机随机映射

默认随机映射

docker run -d -P [镜像名称]

启动一个 nginx 镜像:

查看效果:

我们可以看到宿主机的 32768 端口被映射到容器里面的 80 端口。 -P 可以做到自动绑定所有对外提供服务的容器端口,映射的端口将会从没有使用过的端口池中自动随机选择,但是如果连续绑定多个容器的话,则下一个容器的端口默认是当前容器占用端口号+1.

这时候我们在浏览器里面访问本地的 32768 端口,效果如下:

指定主机随机映射

命令格式:

docker run -d -p [宿主机ip]::[容器端口] --name [容器名称] [镜像名称]

比如:

查看效果:

指定映射实践

命令格式:

docker run -d -p [宿主机ip]:[宿主机端口]:[容器端口] --name [容器名字] [镜像名字]

注意:

  • 如果不指定宿主机的ip,默认是使用 0.0.0.0
  • 容器端口必须清楚,而且必须写出来

命令实践: 现在我们在启动容器的时候,给容器指定一个访问的端口是 1199:

docker run -d -p 172.18.222.137:1199:80 --name n3 nginx 

查看新容器的 ip:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' c64c7cdc052cc57961

查看容器的端口映射: (接着上次写的吗,所以截图时间是 42 小时之前)

查看宿主机开启的端口:

netstat -tnulp | grep docker-proxy 

我们可以在浏览器访问指定的端口 http://172.18.222.137:32768 查看效果. 在这里,我直接使用 httpie 的命令去访问:

多端口映射的方法

命令格式:

docker run -d -p [宿主机端口1]:[容器端口1] -p [宿主机端口2]:[容器端口2] --name [容器名称] [镜像名称]

开启多端口映射实践:

docker run -d -p 520:443 -p 6666:80 --name n3 nginx

查看容器进程:

网络管理

docker 网络命令

docker network --help

docker 的网络模式

bridge 模式

docker 的默认模式,会在 docker 启动的时候,自动配置好自己的网络信息。同一个宿主机的所有容器都在一个网络下,彼此之间可以通信,类似于 vmware 虚拟机的 nat 模式。 在这种模式下,利用宿主机的网卡进行通信,因为涉及到网络转换,所以会造成资源浪费,网络效率会低。 示意图:

截取一段提问方便之后复盘:

host 模式

简单来说,就是鸠占鹊巢,用着宿主机的东西,干着自己的事情。容器使用宿主机的 ip 地址进行通信。 特点: 容器和宿主机共享网络。 示意图:

开启小灰与大黄模式:

container 模式

新创建的容器之间适应已经创建的容器网络,类似于一个局域网。 特点: 容器和容器之间共享网络。 示意图:

提问时间:

none 模式

这种模式最为纯粹,不会帮你做任何的配置,可以最大限度的定制化。

overlay 模式

容器之间不是在同一网络,但是能互相通行。

提问时间:

嗯,交学费了 ... 找了一篇参考: blog.csdn.net/sqzhao/arti… 有待继续深入

bridge 实践

其实在端口映射部分做的实践就是 bridge 的简单演示了,因为他们使用的是默认 bridge 模式,现在我们来自定义桥接网络。 这一部分从三个方面来演示:

  • 创建桥接网络
  • 使用自定义网络创建容器
  • 容器的断开和连接

创建网络

命令格式:

docker network create --driver [网络类型][网络名称]

命令演示:

docker network create --driver bridge bridge-test 

查看主机网络类型:

docker network ls

查看新建的网络的网络信息:

docker network inspect bridge-test

查看宿主机的网卡: 可以看到宿主机多出一个网卡设备:

在自定义的网络中创建容器

命令格式:

docker run --net=[网络名称] -itd --name=[容器名称] [镜像名称]

使用效果:

docker run --net=bridge-test -itd --name=n_bri nginx

查看该容器的 ip 信息:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' n_bri 

注意:使用户默认的桥接模型的容器是可以直接联网的,但是使用自定义的桥接模型不可以直接联网,但是可以通过端口映射来实现联网。

容器断开网络

命令格式:

docker network disconnect [网络名] [容器名]

命令演示:

docker network disconnect bridge-test n_bri 

效果展示:

容器连接网络

命令格式:

docker network connect [网络名] [容器名]

命令演示:

docker network connect bridge-test n_bri 

效果展示:

host 模型实践

我们从命令讲解 以及 host 特点两个方面来学习。

命令讲解

在host模型下,容器使用宿主机的 ip 地址进行对外提供服务,本身没有 ip 地址。

命令格式:

docker run --net=host -itd --name [容器名称] [镜像名称]

命令示例: 创建容器使用 host 模式:

docker run --net=host -itd --name nginx-1 nginx 

一般这时我们 netstat -at 查看宿主机端口,就可以看到 80 被使用。

如果不能启动 ,说明本机的 80 已经被占用

host 的特点: host 模型比较适合于,一台宿主机跑一个固定的容器,比较稳定。或者是一个宿主机跑几个占用不同端口容器的应用场景,他的网络性能是很高的。 host 模型启动的容器不会有任何地址,他其实是使用了宿主机的所有信息。