docker

  1. docker的特性
  • 轻量级的环境隔离
  • 统一的封包和运行方式方式
  1. docker hub 是docker的镜像仓库官网,里面可以方便的查找镜像和对应的tag
  2. docker 是容器服务,里面运行的容器化的服务,容器里面装着我们的程序,它提供隔离的环境,提供统一的部署运行方式。
  3. docker 在隔离的前提上是共享硬件资源的,VM一般是独占硬件资源的,新版本的linux虚拟机一般也是资源共享的,window的虚拟机还是资源独占的。
  4. 容器,镜像,仓库,容器服务之间的关系
  • 镜像:按照一定规范打成的程序包。
  • 镜像仓库:存放镜像的地方
  • 容器:提供给镜像运行实例的隔离环境。容器里面跑着的是镜像的实例程序。
  • 容器服务:提供容器这种服务的程序,docker就是容器化服务实现软件。
  1. docker,是linux容器化服务的实现, 需要linux的内核环境,window版本是在window上虚拟化了一个linux环境,然后在上面跑的docker。
  2. 构造镜像
  • docker build -t 镜像名字:tag (这时候需要当前目录有DockerFile存在)
  • DockerFile是告诉docker 应该怎么去生成一个镜像。
  1. 创建并且运行一个docker 容器: docker run --name 容器名字 镜像名字
  2. docker 镜像是存在 /var/lib/docker 下面
  3. docker 是一个 CS架构,可以通过远程客户端连接远程docker服务。
  4. 阿里云提供了容器镜像服务,并且个人版是免费的,可以支持保存我们自己的镜像。


    如果有上传需求

docker和compose总结_重启


docker和compose总结_数据_02

然后写入加速库

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://x2k31e1o.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  1. docker 常见命令
  • docker info 查看docker 信息
  • systemctl start/stop/restart/status/enable/disable docker docker服务的启动/关闭/重启/状态/开机启动/关闭开机启动
  • docker exec -it 容器id bash 进入容器内部,相当于齐了一个新的终端(一般用这个)
  • docker attach 容器Id 进入交互式命名,相当于重新连上启动的时候的那个终端
  • docker run xxx 加载镜像+创建容器+启动容器
  • docker run -d xxx 后台启动
  • docker ps 查看 docker 容器进程
  • docker top 容器ID 查看 docker容器进程前面几个
  • docker stats 查看容器资源统计
  • docker images 查看镜像
  • docker rm 容器Id 删除 容器
  • docker ps -aq | xargs docker rm -f 强制删除所有容器
  • docker rmi 镜像id 删除镜像
  • docker start/stop/restart镜像Id 开始/关闭/重启一个容器
  • docker inspect 容器ID 查看指定容器的详情
  • docker rename 容器ID 重命名
  • docker logs 容器ID 查询日志
  • docker search 容器名字 --limit 10 查询容器(直接切docker hub 查询更加方便,一般用有official标记的
  • docker system df 查看容器镜像数据卷磁盘占用情况
  • docker cp 原文件 目标文件 宿主机和容器之间文件复制
  • 容器id:文件路径 容器内文件表示方式
  • docker export 容器Id > 文件 把当前容器打包成一个文件备份
  • docker export 36244ed84aa5 > ubuntu.tar
  • cat 镜像文件.tar | docker import - 用户名/仓库名/tag 把镜像文件恢复成一个镜像(执行以后会多了一个指定名字的镜像)。这个镜像的内容和之前容器一样。
  • docker commit -m "备注" -a "作者备注" 容器Id 账号/仓库/tag 使用已经有的容器生成一个镜像
  • 这个容器比镜像多了一层,并且这上面多的那一层上面的修改被保存到新镜像中,后面同新镜像创建的容器就已经有了上次修改过的东西
  • 通过这样的方式我们甚至不用docker-compose就能包整个项目的所有模块都安装到一个Ubuntu上面去,然后把它做成一个镜像
  • 使用远程仓库
  • docker pull 仓库地址/命名空间/镜像名字:tagName 在指定仓库拉取镜像
  • docker login --username=xxx 仓库地址 登录远程仓库
  • docker tag 镜像id 仓库地址/命名空间/镜像名字:tagName 指定本地镜像关联那个远程镜像
  • 这时候会生成另外一个REPOSITORY带有 仓库地址前缀的新镜像,后面我们推的也是这个
  • docker push 仓库地址/命名空间/镜像名字:tagName 把本地镜像推送到指定仓库
  • 如果不想docker hub 和 阿里云之类的仓库以外,我们还可以使用Docker Registry搭建自己的私有镜像仓库
  • docker build -t 新的镜像名字:tag . 按照当前目录的DockerFile构建镜像
  1. docker run -it xxx bash
  • exit 会退出会关闭容器
  • ctrl+q+p 退出容器不会关闭容器
  • 后面通过 docker exec -it 进去的 exit 不会退出
  • 后面通过 docker attach 方式进去的,exit退出会关闭容器
  1. docker run -d 的 程序必须有一个前台进程,不然会立即退出( nginx ubuntu 之类的 )
  • docker run -d -it xxx 可以强制保留一个sh前台进程(-it默认会执行 /bin/bash)
  1. docker的镜像是分成联合文件系统,这样做的好处是镜像模块可以复用,极大的减少存储和传输的数据量。
  2. docker镜像的最底层是 bootfs ,第二次是rootfs,镜像都是只读的,容器层是可写的,新的容器启动的时候,一个新的可写层被加入到容器镜像顶部,这层可写的叫做容器层,下面不可写的部分都是镜像层。
  3. docker和compose总结_数据_03

  4. docker Registry 是一个官方提供的 镜像仓库软件。我们可以使用它搭建私有镜像仓库
  5. 创建私有仓库
  • docker run -d -p 5000:5000 -v /opt/docker/registry:/tmp/registry --privileged=true registry
  • 文件放在 /opt/docker/registry/
  • 仓库地址就是 http://ip:5000
  • 访问: http://192.168.100.150:5000/v2/_catalog 可以看到是空的
  • docker和compose总结_数据_04

  • 默认是不支持 http 协议的需要https,这时候可以修改 /etc/docker/daemon.json文件,让它认为这个地址是安全的
    添加"insecure-registries":["ip:端口"],然后重启docker
{
	.......省略,
	"insecure-registries":["ip:端口"]
}
  • 1.
  • 2.
  • 3.
  • 4.

systemctl daemon-reload
systemctl restart docker

  1. DockerFIle 构建镜像
  • from 基于那个镜像
  • maintainet 维护人员信息
  • env 指定环境变量
  • env 变量名字 变量值 指定变量
  • $变量名字 引用变量
  • run 执行命名,有两种格式,执行时间点是构建镜像的时候
  • run 命令 参数1 shell格式
  • run ["命令,"参数1","参数2","参数3"] exec格式
  • cmd 执行命名,执行时间点是容器启动的时候
  • dockerFIle可以有多个cmd 命令,但是只有最后一个生效
  • cmd 命令会被 docker run [options] 镜像名字 cmd指令 ,后面的 cmd指令覆盖
  • entrypoint 运行命令,执行时间点是容器启动的时候
  • 它和cmd 的区别在于 cmd 会被 docker run最后的命名覆盖,entrypoint 不会,并且在他后面使用cmd 来当做默认值,并且利用cmd 会被 docker run 后面参数覆盖来改变 参数。
  • entrypoint 也是只有最后一条会被执行
  • 需要使用 exec格式entrypoint 才能和 cmd 一起用。shell 格式无效,cmd 不管写在 entrypoint前后都可以
entrypoint ["echo","2"]
cmd ["3"]
  • 1.
  • 2.
  • expose 对外暴露端口
  • workdir 指定容器内的默认工作目录,终端登录进来就是这个目录 ,类似linux的 cd ~ 的位置
  • user 指定用哪个用户执行镜像内的操作
  • volume 指定容器卷
  • copy 复制宿主机的文件或者目录到 容器里第一地址是主机里面的文件,第二个是容器里面的文件
  • add 相当于 copy + 解压
  • add xxx.tar.gz xxx.tar.gz 不会解压(复制到明确的文件不会)
  • add xxx.tar.gz ./ 会解压(复制到目录会解压)

docker 网络

  1. 查看网络列表 docker network ls
  2. 删除没有用到的网路 docker network prune
  3. 删除指定网络 docker network rm 网络名字
  4. docker的 网络模式
  • bridge,产生一个子网络,子网络通过网桥和宿主机外面的网络通信,类似VMware网络模式 net模式
  • docker run -d -p 8080:8080 --network bridge
  • host模式,不产生子网络,容器直接使用主机的网卡,容器创建参数 -p无效,默认在主机占用同样的端口,冲突了以此+1后延。缺点很明显不能指定端口。
  • docker run -d --network host
  • none ,网卡都没有配置的网络模式,只有lo网卡
  • docker run -d --network none
  • container模式,和别的容器共享网卡host模式是和宿主机共享网卡,这是要考虑两个容器之间的端口冲突。如果指定的共享容器挂了,那么当前容器也就没有网络配置了,也就不能对外提供服务了。
  • docker run -d -p 8081:8080 --network container:别的容器名字
  1. 指定容器网络 :docker run -d --network 网络名字 ,如果使用的 host 类型的网络 指定端口无效
  2. 默认不指定网络都是使用bridge这个网络
    每个容器里面里面的网卡eth0都和网桥(docker0)相连,在外层主机创建vethxx的虚拟网卡和容器内的eth0对应
  3. 查看指定容器使用的网络:docker inspect 容器Id (最后面20行)
  4. 查看指定网络的 配置:docker network inspect 网络名字
  5. 自定义网络模式
  • 创建网络:docker network create 网络名字
  • 创建的网络都是 bridge 类型的
  • 使用默认的网络(网络名是bridge的网络)的时候,容器之只能通过ip访问,不能通过容器名字访问
  • 自定义网络可以通过容器名字访问
  • 子网络里面的ip会伴随容器的销毁启动重新分配,容器之间通过子网ip访问是不可靠的,如果是通过宿主机IP访问是可以的。

docker volume

  1. 数据卷挂载中如果 提示 cannot open directory:Permission denied,那么需要在 挂载目录后面加上 --privileged=true
  • 使用 --privileged=true 以后 容器里面的root 才是外面宿主机的 root ,否则只是普通用户。
  • 这个 centos7 SELinux 的限制
  • -v /a/b/c:/a/b/c --privileged=true
  1. 使用数据卷可以让容器和宿主机之间共享文件,也能让容器和容器之间共享文件。
  • 使用数据挂载以后文件就不是存在容器里面了,而是存在主机磁盘或者内存。
  1. 可以同 docker inspect 容器Id 查看数据卷挂载情况,key为 mount 的键下面
  2. -v /a/b/c:/a/b/c:ro 可以让容器内是只读(不写默认是rw)
  3. -v /a/b/c 表示匿名挂载,容器的/a/b/c 目录挂载到 /var/lib/docker/volumes/ 下的随机目录下面,会生成一个随机名字的 volume,可以通过 docker volume ls 查看
  4. -volumes-from 别的容器 和别的容器用同样的数据卷配置,这时候只是使用另一个容器的配置,另一个容器挂了也不影响
  5. --mount type的三种模式
  • 格式:--mount type=xxx,src=te4_conf,dst=/opt/service/conf[,key4=value4....]
  • --mount type=volume,src(source)=volumeName ,dst(destination)=容器绝对路径
  • 相对 宿主机/var/lib/docker/volumes/ 的路径
  • 文件覆盖情况,如果src不是null的就用src的,如果src是空的就用dst的
  • 只能是映射目录
  • 需要提前使用 docker volume create volumeName 创建好volume
  • 默认挂在路径 /var/lib/docker/volumes/{volume名字}/_data
  • --mount type=bind,src=宿主机相对路径,dst=容器绝对路径(如果不写type默认是 type=bind)
  • 文件覆盖情况,总是用src的覆盖,dst的内容
  • 可以映射目录或者文件
  • 大概只有强制映射宿主机目录到容器目录的时候考虑 --mount type=bind
  • --mount type=tmpfs,source=宿主机相对路径,destination=容器绝对路径 ,文件只存在宿主机的内存中
  • docker run -d --mount type=tmpfs,dst=/opt/service/conf te:4
  • docker inspect 的时候可以看到
"Mounts": [
            {
                "Type": "tmpfs",
                "Source": "",
                "Destination": "/opt/service/conf",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • tmpfs 还可以 设置 tmpfs-size 和 tmpfs-mode
  • tmpfs 是存在 主机内存中的,不是在容器磁盘上也没有,容器停止以后就没了,如果是在容器中容器重启还会存在。
  1. -v 和 --mount的区别
  • -v 和 --mount都可以使用 bind 和 volume模式
  • -v 后面使用src位置写主机绝对路径的时候和--mount type=bind类似
  • -v 后面src位置写 volumeName的时候和 --mount type=volume类似
  • 格式 -v 主机路径:容器路径:读写权限 读写权限可以是rw或者ro
  • -v 只有三段参数,--mount可以有多段参数,更加强大
  1. docker volume create 创建volume ,默认挂在路径 /var/lib/docker/volumes/{volume名字}/_data
  2. docker volume ls 查看数据卷列表
  3. docker volume inspect xxx 查看挂载详情
  4. docker volume rm xxx 删除数据卷
  5. docker volume prune 清理没有容器使用的数据卷

docker compose

  1. docker-compose管理的是一个的项目(project)下面的多个服务(service)之间的关系,单个dockerFile管理的是一个容器服务(或者说是一个组件),只使用docker 只能独立的管理 redis ,mysql ,java程序的运行和环境。compose可以编排他们之间的依赖关系,启动顺序。docker 和 docker-compose 分别管理着部分和整体。
  2. 在compose中内部ip默认是自动分配的, 可以使用service 名字作为访问这个容器的域名(IP),在spring配置文件或者别的需要访问redis,mysql地址的地方直接写入 对应对应容器的服务名字。
  3. 在 docker-compose.yml 里面配置容器服务之间的关系,然后使用 docker-compose up 就能一键启动整个项目
  4. docker-compose build 构建镜像
  • DockerFile 或者 jar包有变动都会重启 生成新的镜像 ,如果没有生成那么在后面 加上 --no-cahce=true
  1. 如果是重新生成镜像并且重启(脚本文件有变动或者jar内容有变动的时候)
  • docker-compose down
  • docker-compose build [--no-cache]
  • docker-compose up -d
  1. docker system prune 删除虚悬镜像(没有 tag 和 仓库名字的镜像),如果没有变更 tag名字就重新docker-compose build 老的镜像就会变成虚悬镜像
  2. 常见命令
  • docker-compose up 创建并启动服务 类似 docker run 做了创建启动容器
  • docker-compose up -d 创建并后台启动服务
  • 如果默认文件不是DockerCompose.yml 那么可以通过 docker-compose -f xxx.yml up -d 来执行
  • docker-compose start 启动服务
  • docker-compose restart 重启服务
  • docker-compose stop 关闭服务
  • docker-compose down 关闭并移除服务
  • docker-compose logs 查看日志
  • docker-compose down --volumes 关闭并移除容器并删除容器清除存储
  • docker-compose build --no-cache 重构服务,或者重新构建服务(会覆盖生成服务对应的镜像 )
  • docker-compose -h 查看帮助
  • docker-compose top 展示当前docker-compose编排过的容器进程
  • docker-compose ps 查看当前compose进程
  • docker-compose exec 容器Id /bin/bash/ 进入容器内部
  • docker-compose config 配置检查
  • docker-compose config -q 配置检查 有问题才输出

docker 可视化管理工具

  1. portainer 是 docker轻量级的可视化管理工具
docker run -d  -p 9000:9000 -p 8000:8000 --name portainer --restart=always --privileged=true -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
  • 1.

访问: http://192.168.100.150:9000

docker和compose总结_数据_05

  1. portainer 里面有很多app Templates 可以参考它知道 有哪些挂载点或者别的配置
  2. docker stats 可以查看当前docker 个容器瞬时统计
  3. docker system df 可以看磁盘状态
  4. 可以使用 CAdvisor+influxDB+grafana 来做 docker数据的采集+存储和展示,CIG 功能比 portainer功能强大,但是更加复杂

docker疑问和解决

  1. 容器内端口和宿主机端口如果冲突,那么后启动的程序就启动不了。
  • 这时候可以不指定容器对外提供映射的端口
  1. CMD 和 run bash 区别
  • run 的执行时间是在镜像生成的时候
  • cmd 只能有一个,有多个的时候,前面的都无效,只有最后一个生效,并且是在创建容器的时候执行,cmd会被 docker 命令行参数替代。
  • entrypoint 和 cmd 可以搭配使用,用cmd 作为后置传参
  1. 怎么在 docker bash 里面执行 ping 操作,和别的安装操作
  • openjdk17的没有 ping,java1.8的有
  • 可以自己安装apt-get install inetutils-ping 或者 microdnf install xxx (openjdk17 使用的microdnf)
  • 实测microdnf连不上网
  1. 安装了 docker-compose 以后 docker 服务就不能stop了? 怎么才能停止?
  • 感觉是一个bug,正常只要 通过 docker update restar=no 以后就应该可以停止
  1. 那些命令后面要加bash?
  • docker exec -it 镜像Id后面 需要加bash 或者 /bin/bash
  • docker run ....... 镜像名字 后面 如果是 ubuntu之类的镜像有些可以加bash ,别的不能乱加,否者会覆盖 cmd 里面的命令
  1. shell格式 和 exec 格式区别
  • shell 格式在 entrypoint 和 cmd 协同工作的时候无效
  1. 不指定 workdir 默认是哪里?
  • 默认在/目录下
  1. add 和 copy 的区别
  • add 目标地址是目录的时候会自动解压,目标地址是明确的文件的时候不会自动解压
  1. 多个cmd
  • 只有最后一个生效
  1. 虚悬镜像 只要重复指定tag就会把老的镜像的tag挤掉,变成虚悬镜像
  • 使用 docker system prune 删除