目录 start

  1. Docker
    1. 简介
    2. 个人理解
    3. 学习资源
  2. 安装与卸载
    1. Linux
      1. 安装包安装
      2. Ubuntu
      3. Debian
      4. Centos
      5. Arch
      6. 不加sudo执行docker命令
    2. Windows
  3. 基础管理
    1. 镜像仓库
      1. 搭建本地镜像仓库
    2. 基础命令
    3. 镜像命令
    4. 容器命令
      1. ps
      2. create
      3. run
        1. 资源限制
      4. exec
      5. commit
      6. port
    5. 端口映射
  4. 数据卷
    1. 数据卷容器
  5. 容器编排
    1. Docker-Compose
      1. 安装
      2. 配置文件
      3. 使用命令
      4. Tips
    2. Docker-Machine
    3. Docker-Swarm
  6. 网络
    1. None
    2. Host
    3. Bridge
    4. User-defined
    5. 跨主机容器通信
      1. overlay
  7. Dockerfile
    1. dockerignore文件的使用

目录 end|2019-10-30 21:04|


Docker

Official Doc | docker-cnDocker中国

简介

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

个人理解

  • docker中的容器是动态的,随时创建和销毁,只有镜像是持久化的
  • 而且容器是一个虚拟出来的功能完备的Linux操作系统可以进行登录运行命令
  • docker images来得到所有的本地镜像名
    • 使用docker run --name {name} -d {image-name}新命名一个容器来启动某个镜像
    • 然后docker ps查看容器运行状况
  • 镜像的命名:
    • 如果要push到仓库就要遵循这个规范,本地用就无所谓了,而且以后也可以取新的名字 docker tag 原名 新名
    • 官方的hub: 用户名/镜像名:tag
    • 非官方的例如阿里 registry.cn-hangzhou.aliyuncs.com/myth/jdk8:alpine jdk8是镜像名,前面的是仓库地址

学习资源

码云上Docke相关资源

docker资源汇总
简述 Docker


安装与卸载

daocloud安装帮助 | Docker 加速器

Linux

Official doc 所有的发行版

docker.io 是旧版本 现在新的Docker分为 docker-ce docker-ee

安装包安装

官方文件地址

  • Debian系
    • deb包选择
    • 进去后选择debain的版本,deepin15.4 的版本是stretch 然后pool/stable/amd64/选版本即可
    • 例如:Deepin 15.4直接点这里
    • 这两种方式装的是同一个版本号
    • 双击或者sudo dpkg -i deb文件
    • 测试安装成功 sudo docker run hello-world

Ubuntu

snap

  • 安装snap sudo apt install snapd
  • 查看适用于当前系统的包:snap install find
  • 安装: snap install docker

Debian

参考

  • sudo echo "deb http://http.debian.net/debian jessie-backports main" >> /etc/apt/sources.list
  • sudo apt-get install docker-ce
  1. 前置软件 sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg2 \
    lsb-release \
    software-properties-common

使用清华大学镜像源安装

使用阿里云镜像源

  1. curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | sudo apt-key add -
  2. sudo add-apt-repository \
    “deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian \
    $(lsb_release -cs) stable”
  1. 特别注意 lsb_release -cs 命令的执行结果, 本应该获取到的是发行代号 jessie stretch 等等, 但是Deepin15.8执行结果是 unstable …
  2. 所以要手动添加 或修改为 jessie deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/debian jessie stable

使用官方源

  1. curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
  2. sudo add-apt-repository \
    “deb [arch=amd64] https://download.docker.com/linux/debian \
    $(lsb_release -cs) stable”

Centos

  • sudo yum install docker
    • Ubuntu的话,Docker没有启动, 只要一执行Docker相关命令就会自动启动, 但是Centos要手动启动
    • service docker start 设置开机启动: chkconfig docker on

Arch

  • pacman -S docker

不加sudo执行docker命令

官方文档

  • 如果没有docker组,添加组 sudo groupadd docker
  • 将当前用户加入用户组 sudo gpasswd -a $USER docker
  • 然后重新注销登录,或者退出会话重新登录即可

Windows

Windows上本质是用了VirtualBox创建虚拟机来跑Docker, 屎一般的体验, 然而Win10的WSL因为不能模拟aufs 以及 cgroup 所以能装不能用
只能装上docker for windows 然后把Docker守护进程的套接字文件配置给wsl用。。。。。

  • 参考博客
  • 官方toolbox 下载
  • 然后双击安装,勾选上virtualbox 记住cpu要开虚拟化
  • 安装完成后就会有三个图标在桌面上,然后进入Docker Quickstart Terminal后 docker run hello-world 有正常输出即可

基础管理

docker 所有的数据默认存储在 /var/lib/docker

镜像仓库

默认的DockerHub因为在国外所以网络不太稳定

Docker中国

三种使用的方式

  1. 使用指定的URL docker pull registry.docker-cn.com/myname/myrepo:mytag
  2. 仅仅配置当前守护进程, 重启就失效了docker --registry-mirror=https://registry.docker-cn.com daemon
  3. 修改 /etc/docker/daemon.json文件, 永久性更改
    1
    {"registry-mirrors": ["https://registry.docker-cn.com"]}

时速云

  • sudo docker pull index.tenxcloud.com/<namespace>/<repository>:<tag>
  • 下载后可以用别名 docker tag index.tenxcloud.com/docker_library/node:lastest node:lastest
  • 然后为了控制台干净可以直接将原来的长命名tag直接删除

阿里云

  • 开发者平台
  • 配置命名空间,仓库,然后使用文档的配置即可

百度云

  1. 登录百度云镜像仓库

    • sudo docker login –username=[username] hub.baidubce.com
    • username:镜像仓库名称,即是开通镜像仓库时填写的用户名。输入密码后完成登录。
  2. 上传镜像

    • sudo docker tag [ImageId] hub.baidubce.com/[namespace]/[ImageName]:[镜像版本号]
    • sudo docker push hub.baidubce.com/[namespace]/[ImageName]:[镜像版本号]
      • ImageId和镜像版本号根据镜像信息补充
      • namespace是开通镜像仓库时填写的命名空间
      • ImageName是在控制台创建的镜像名称
  3. 下载镜像

    • 登录到镜像仓库,需输入密码
    • sudo docker pull hub.baidubce.com/[namespace]/[ImageName]:[镜像版本号]
  4. 使用加速器


搭建本地镜像仓库

Official doc

参考:Docker Registry V1 与 V2 的区别解析以及灵雀云的实时同步迁移实践

Github:v1 | Github:v2

v1

  • 服务器上运行 并映射到本地目录 docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
  • 对服务器中docker已经有的镜像 设置别名 docker tag 镜像 ip:port/镜像名
  • docker push ip:port/镜像名
  • 查看服务器上仓库的镜像 curl http://IP:5000/v1/search

v2

  • 启动镜像 docker run -d -p 5000:5000 --name registry registry:2
  • 一样的设置好别名, 然后push上去
  • 查看仓库中的镜像 curl IP:5000/v2/_catalog

注意 由于 docker client 默认是用的 HTTPS 方式通信, 但是这个本地的 registry 默认是 HTTP 的, 所以有几种解决方案

  1. 直接将本地仓库的IP和端口 设置为本地Docker的白名单
    • 给dockerd 添加参数 DOCKER_OPTS="--insecure-registry ip:port"
    • 或者配置 /etc/docker/daemon.json { "insecure-registries":["IP:PORT"] }
    • 重启Docker服务
  2. 配置 registry 为 HTTPS, 那么就需要配置SSL证书, 使用本地证书或者公网证书

基础命令

直接运行 docker, 就会有命令的使用提示 例如查看docker版本 docker version

登录镜像仓库

  • 登录hub.docker :docker login 或者 docker login -u username -p password
  • 登录时速云:sudo docker login index.tenxcloud.com
  • 登录百度云: docker login --username=[username] hub.baidubce.com

镜像命令

  • 查看所有 : docker images
    • docker images -a 查看所有镜像(包括中间镜像)
  • 搜索 : docker search 镜像名
  • 安装 : docker pull 镜像名
  • 删除 : docker rmi 镜像名
  • 查看详细: docker inspect [-f .Architesture] -f 查看JSON格式的具体节点的数据值
  • 查看历史:docker history imagename
  • 添加标签(别名): docker tag originname newname
  • 导出镜像文件:docker save -o ubuntu.tar ubuntu:14.04
    • 导入镜像文件: docker load --input ubuntu.tardocker load < ubuntu.tar
  • 上传镜像: docker push mythos/test:lastest

容器命令

  • 查看所有容器的状态:docker stats 能看到正在运行的容器内存 cpu io net等信息

    • -a 所有容器
    • --no-stream 不阻塞标准输出流,只输出一次信息
  • 停止容器:docker stop 容器name

  • 重启容器:docker restart 容器name
  • 启动容器:docker start 容器name

    • -i 交互模式,也可以进入终端
  • 删除容器:docker rm 容器name

    • -f 强行停止正在运行的容器并删除
    • -l 删除容器的连接,但是保留容器
    • -v 删除容器挂载的数据卷
    • 删除所有容器:docker rm ${docker -a -q}
    • 删除所有容器和挂载的目录:docker system prune --volumes -f
  • 容器日志(终端所有输入输出):docker logs 容器name或id
  • 重命名 : docker rename origin new

  • 导入导出 (容器快照):

    • 导出: docker export -o test.tar 容器名 docker export 容器name > test.tar
    • 导入: docker import [-c |--change=[]] [-m | --message=[]] file|URL - [repository]:[tag]
    • -c | –change=[] 选项在导入的同时执行对容器就行修改的Dockerfile指令。

Attach a volume to a container while it is running

ps

  • 查看当前运行的容器:docker ps
    • 查看所有容器 :docker ps -a
    • 查看占用 :docker ps -s
    • ps formatting
1
2
3
4
5
6
7
8
9
10
11
12
13
.ID 	    Container ID
.Image Image ID
.Command Quoted command
.CreatedAt Time when the container was created.
.RunningFor Elapsed time since the container was started.
.Ports Exposed ports.
.Status Container status.
.Size Container disk size.
.Names Container names.
.Labels All labels assigned to the container.
.Label Value of a specific label for this container. For example '{{.Label "com.docker.swarm.cpu"}}'
.Mounts Names of the volumes mounted in this container.
.Networks Names of the networks attached to this container.

create

官方文档

run

Docker run 命令的使用方法
等价于 docker create 再 docker start

  • docker run -d --name conrainer-name image-name touch a.md ,如果镜像本地没有会自动pull
    • --name 配置容器名字
    • -d 后台启动程序
    • -i 交互模式运行容器(标准输入和标准输出) docker run -it ubuntu /bin/bash
    • -t 容器启动后进入其命令行
    • -v 将本地文件夹建立映射到容器内 -v 本机:容器
    • -p 端口映射左本机右容器:-p 44:22主机容器端口相同就:-p 22 将容器所有EXPOSE的端口映射到宿主机随机端口-P
      • 绑定udp端口 -p 44:22/udp
    • --env name="tanky" 设置环境变量
    • --cpu-shares 设置CPU的相对权重,只在link之间容器的权重比例
    • --cpuset-cpus 限制只能运行在某标号的CPU上
    • --user -u 限制用户
    • --cap-drop 去除能力
    • --link 链接其他容器
    • --rm 容器运行结束退出就自动删除该容器 注意和-d不能共存
    • --restart=always 设置该容器随dokcer 服务自启动
    • --hostname 容器hostname 指定容器的hostname

-e TZ="Asia/Shanghai" -v /etc/localtime:/etc/localtime:ro

资源限制

内存限制

  • 限制最大内存100M --memory 100M 或者 -m 100M
  • 配置交换内存不受限制 --memory-swap -1
    • 不配置该项 或者 该项小于 –memory 则都是采用默认值, –memory 的两倍

参考博客: Docker 资源限制之内存

exec

  • 登录容器:
    • docker exec -it 容器name或id bash
    • docker attach 容器id 这个命令虽然简单,但是退出会话就自动关闭了容器
  • 这些选项不加就是默认值,加上短参数形式就是设为另一个值 如 -t

    • -i--interactive=ture|false 打开标准输入接受用户输入命令
    • --privileged=true|false 是否给以最高权限
    • -t--tty=true|false 是否分配伪终端
    • -u--user="" 执行命令的用户或ID
  • 使用 nsenter 连接到容器:

    • PID=${docker-pid 容器id}
    • nsenter –target $PID –mount –uts –ipc –net –pid

commit

  • docker commit 容器id 镜像name 将容器为id的当前容器 保存为name镜像

port

查看容器的端口映射情况, 输出是左容器右本机, 和使用相反


端口映射

  • 当不指定对应的参数容器默认不开放任何端口给外部,可以使用 -P-p 参数来开放
    • -P 随机映射一个 49000-49900 的端口到容器开放的端口
    • -p IP:HostPort:ContainerPort | IP::ContainerPort | HostPort:ContainerPort
      • 映射到指定IP的指定端口IP:HostPort:ContainerPort
      • 映射到指定IP的任意端口IP::ContainerPort
      • 映射到所有接口的地址的指定端口HostPort:ContainerPort
    • 还可以使用 udp来标记为udp类型 docker run -d -p 127.0.0.1::5000/udp ubuntu apt update
  • 查看端口
    • 查看容器内5000对应的外端口 docker port ubuntu17 5000
    • 查看容器的具体信息 docker inspect 容器id

数据卷

Docker 中管理数据
参考博客: 给一个正在运行的Docker容器动态添加Volume

  • 数据卷是一个可供容器使用的特殊目录,它将宿主机操作系统目录映射进容器 类似于 mount操作

    • 数据卷可以在容器之间共享重用
    • 数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作
    • 对数据卷的更新不会影响镜像,解耦了应用和数据
    • 卷会一直存在,直到没有容器使用,才可以安全的卸载
  • docker run -v dir:dir[:ro] 一般是创建容器时使用,和-p类似可以多个,左本机右容器 默认rw权限可以指定 ro只读

    • 可以将一个文件挂载为数据卷,但是文件夹更好,文件可能会有问题出现
  • 挂载宿主机时区及时间 /etc/localtime:/etc/localtime

数据卷容器

  • docker run -it -v /test --name data ubuntu 运行一个挂载了数据卷的容器
  • 引用数据卷容器 来挂载数据卷:docker run -it --volumes-from data --name db1 ubuntu
  • 从已经挂载了数据卷容器的容器 来挂载数据卷:docker run -it --volumes-from db1 --name db2 ubuntu
  • 使用 --volumes-from 参数所挂载数据卷的容器并不需要保持在运行状态
  • 如果删除了挂载的容器,数据卷并不会自动删除,而是要在删除最后一个容器时 使用 docker rm -v 来声明删除容器并删除关联的数据卷

利用数据卷容器来迁移数据

  • 备份:
    • docker run --volumes-from data -v $(pwd):/backup --name worker ubuntu tar cvf /backup/backup.tar /data
    • 先基于Ubuntu创建一个worker容器并引用了数据卷容器data,然后将当前目录作为数据卷挂载进去,并执行tar命令,打包到数据卷容器的目录下
    • 实现了将当前目录归档到数据卷容器下
  • 恢复:
    • 创建一个带有数据卷的容器(目标容器)docker run -v /data --name reuse ubuntu /bin/bash
    • 解压当前目录的tar文件到数据卷容器中 docker run --volumes-from reuse -v $(pwd):/backup busybox tar xvf /backup/backup.tar
    • 这个就是实现了将本地的归档数据放到指定的容器内,如果要从数据卷容器中恢复到别的容器就只要挂载对应的数据卷容器然后进目录直接解压即可

容器编排

Docker-Compose

Official

声明式环境,管理多容器, 并处理好相关资源的关系

Demo: 开源电商平台
Demo: 安装 Kafka

安装

官方建议的安装方式

  1. sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  2. sudo chmod +x /usr/local/bin/docker-compose
  3. sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

注意 Deepin上 如果通过 apt 去安装 docker-compose 它会把 docker-ce 卸掉, 装旧的 docker.io

配置文件

一个配置文件就表示了一组容器, 以及相关的网络,文件等配置, docker-compose 都是基于该配置文件进行基本命令操作
语法上和 docker run 基本一致, 只不过以 yml 形式配置而已

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version: "2.1"
services:
zookeeper:
image: ${IMAGE_NAME:-defaultImage}
expose:
- "6666"
ports:
- "6666:6666"
volumes:
- /etc/localtime:/etc/localtime
command: ./bin/start.sh
links:
- "mysql:mysql"
environment:
- NAME=who

使用命令

必须要在 docker-compose.yml 文件目录下执行

  • help
  • up # 自动完成构建镜像,创建服务,启动服务,并关联服务等操作, -d 后台执行
  • down # 停止并删除该服务的所有容器, 移除网络, -v 移除挂载的volume
  • start # 启动存在的服务
  • stop # 停止
  • restart # 重启项目中服务
  • exec # 进入指定容器
  • image # 列出 Compose 文件中包含的镜像
  • kill [SERVICE…]
  • pause [SERVICE…]
  • unpause [SERVICE…]
  • ps # 列出项目中所有容器

Tips

yml所在的目录名会作为容器名的前缀


Docker-Machine

创建一个docker集群环境 官方文档安装

Error with pre-create check: “VBoxManage not found. Make sure VirtualBox is installed and VBoxManage is in the path
Error with pre-create check: “This computer doesn’t have VT-X/AMD-v enabled. Enabling it in the BIOS is mandatory”

Docker-Swarm


网络

Official Doc 分为 none host brige user-defined 几种类型

None

docker run -it –network none busybox

  • 不联网的容器, ifconfig 可以看到只有 lo

Host

docker run -it –network host busybox

  • 采用宿主机的网络, 也就是说和宿主机使用同一个网络环境, hostname都是host的
    1. 特点是性能, 但是不够灵活, 要考虑和host上的端口冲突问题
    2. 直接配置host的网络: 例如配置防火墙容器

Bridge

安装 Docker 的时候, 都会创建一个 docker0 的网桥 Linux bridge

  • 如果没有指定 --network 或者使用 --network default 创建容器 都会默认挂载到 docker0 上
  • 通过 docker network inspect bridge 命令可以看到子网掩码是 172.17.0.0/16 网关是 172.17.0.1
    • 也就是说能容纳 2的16次幂 -2 个容器 (65534), 容器创建时会依次分配ip

注意: 此方式下容器之间是互通的, 通常使用的 --link containerName:aliasName 也只不过是在 /etc/hosts 文件中添加了容器的 dns 而已

  • 验证

特别容易出现锁,一个没有启动,其他的都启动不了 尝试? sudo service docker restart

  • 例如: 创建一个MySQL容器供一个Ubuntu容器使用
  1. 创建MySQL容器 docker run --name mysql2 -e MYSQL_ROOT_PASSWORD=ad -d mysql
  2. 创建Ubuntu容器 docker run -d --name test --link mysql2:db ubuntu
    • link参数说明 :--link name:alias 在父容器中会将该映射加入host文件,所以无需找ip,直接使用别名
  3. docker会连接两个容器,而不用通过暴露端口来实现,web容器的host文件以及环境变量都会追加上mysql2的配置
  4. 所以在Ubuntu容器中连接MySQL容器, mysql -h db -u root -pad 即可连接上mysql
    • 如需看IP就 cat /etc/hosts 中myslq容器别名为db值的IP地址
    • 或者直接 ping db apt install inetutils-ping ifconfig就要安装net-tools
  • 例如:创建一个Nginx和一个Springboot搭建的web服务
    • 构建Springboot应用镜像,构建应用容器 开放8888端口
    • 新建nginx容器:docker run --name youhuigo -d -p 80:80 -v /home/kuang/nginx/conf/:/etc/nginx/conf.d/:ro --link you:web nginx
  • 配置文件:一样的cat /etc/hosts 查看容器的IP, 其实最简单就是用link配置时的别名即可,因为Docker已经帮我们配置好了host。。。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    upstream youhui {
    server 172.17.0.4:8888;
    }

    server {
    listen 80;
    server_name youhui;

    location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Nginx-Proxt true;

    proxy_pass http://youhui;
    proxy_redirect off;
    }
    }

weave 能解决跨宿主机的容器互联问题

User-defined

Docker 提供三种 网络驱动 bridge overlay macvlan, 后两者可用于跨主机的容器通信

跨主机容器通信

overlay

参考博客: DOCKER的内置OVERLAY网络


Dockerfile

Dockerfile文件学习

dockerignore文件的使用

  • .dockerignore文件是依据 Go 的 PathMatch 规范来的,使用和.gitignore类似