Docker学习笔记(详细)

目录

01 介绍

02 Docker安装

03 Docker常用命令

04 Docker镜像

05 Docker容器数据卷

06 Dockerfile解析

Dockerfile构建过程解析

Dockerfile体系结构

案例

07 Docker常用安装

08 本地镜像发布到阿里云

可视化

Docker 网络

理解docker0

自定义网络

网络连通


01 介绍

  • 为什么会有docker:开发与运维之间的矛盾,不仅打包代码,环境也一并打包
  • 为什么用docker:基于容器的虚拟化,仅包含业务运行所需要的runtime环境
    • 更高效:无操作系统虚拟化开销
      • 计算:轻量,无额外开销
      • 存储:系统盘aufs/dm/overlayfs;数据盘volume
      • 网络:宿主机网络,NS隔离
    • 更敏捷、更灵活
      • 分层的存储和包管理、devops理念
      • 支持多种网络配置
  • docker理念:一次封装,到处运行,解决运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的虚拟化技术,基于Go语言,C/S架构
  • 基本组成:镜像、容器、仓库
  • 官网:https://www.docker.com/

02 Docker安装

参考:https://blog.csdn.net/weixin_37680513/article/details/116858377

03 Docker常用命令

  • 帮助命令

docker version # 显示docker的版本信息
docker info    # 显示docker的系统信息,包括镜像和容器的数量
docker --help  # 帮助命令
# https://docs.docker.com/reference/
  • 镜像命令
docker images [options] [name] 列出本地镜像
    -a 列出所有镜像
    -q 列出id, 可以组合使用-qa
    --digests 显示摘要
    --no-trunc 不截取id,显示完整id

docker search imageName [options] 搜索镜像,从hub.docker.com
    -s xx 显示star xx以上的镜像,xx是数字
    --no-trunc 显示完整description
    --automated 只列出automated的镜像

docker pull imageName[:TAG] 拉取镜像,默认[:latest]
docker rmi [options] imageName[:TAG] 删除镜像,默认[:latest],可删多个
    -f 强制删除
docker rmi -f $(docker images -qa) 删除所有镜像
  • 容器命令
docker run [options] imageName [command][args] 新建并启动容器
    --name="newName" 为容器指定一个名称
    --name newName
    --volumes-from id/name 从容器继承容器卷
    -d 后台运行容器,并返回容器id,也即启动守护式容器,docker容器后台运行必须有一个前台进程,否则立即自杀,如果不是那些一直挂起的命令,比如top tail 就会自动退出的
    -i 以交互模式运行容器,通常与-t同时使用
    -t 为容器重新分配一个伪终端,通常与-i同时使用
    -P 随机端口映射
    -p 指定端口映射,有以下4种形式
        ip:hostPort:containerPort
        ip::containerPort
        hostPort:containerPort
        containerPort
docker ps [options] 列出当前正在运行的容器
    -a 显示当前及历史上运行过的
    -l 显示最近创建的容器
    -n num 显示最近创建的num个容器
    -q 静默模式,只显示容器编号,-lq,只返回最近创建的容器编号
    --no-trunc 不截断输出
exit 退出并停止容器
ctrl + P + Q 只退出容器,不停止
docker start id/name 启动容器
docker restart id/name 重启容器
docker stop id/name 停止容器
docker kill id/name 强制停止容器
docker rm id/name 删除已经停止的容器,-f强制删除,不管是否正在运行
docker rm -f $(docker ps -qa) 一次删除所有容器
docker ps -qa | xargs docker rm -f 一次删除所有容器
docker logs id/name 打印容器日志
    -t 加上时间
    -f 跟随打印
    --tail n 只打印最后n行
docker top id/name 列出容器的进程
docker inspect id/name 查看容器内部细节,返回json字符串
docker attach id/name 直接进入容器,启动命令的终端,不会启动新的进程
docker exec -it id/name command 在外部执行容器内部的命令,打开新的命令终端,可以启动新的进程
docker cp id/name:path hostpath 从容器拷贝数据到宿主机

04 Docker镜像

  • 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量和配置文件
    • UnionFS(联合文件系统):是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时将不同目录挂载到同一个虚拟文件系统下,unionfs是docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,最终的文件系统会包含所有底层的文件和目录。
    • docker镜像加载原理:docker镜像实际上是由一层一层的文件系统组成(UnionFS),
      • bootfs:主要包含bootloader和kernel,bootloader主要引导加载kernel,linux刚启动时加载bootfs,在docker镜像的最底层是bootfs,这一曾与典型了linux系统一样,包含boot加载器和内核,boot加载完之后真个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统会卸载bootfs
      • rootfs:在bootfs之上,包含的是典型linux系统的中的/dev等标准目录和文件,rootfs就是各种不同的操作系统的发行版,比如ubuntu。对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序就可以了,底层直接用主机的内核,自己只提供rootfs,因此,不同发行版可以公用bootfs
    • 为什么要采用这种分层结构:共享资源,如果多个镜像都从相同的bas镜像构建,那么宿主机只需提供磁盘上的一份base镜像,同时内存中也只需加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以共享
  • 特点:docker镜像都是只读的;当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称为容器层,容器之下的都叫镜像层
  • 提交容器副本使之成为一个新的镜像:
docker commit -a="author" -m="description of this version image" id/name newName[:TAG]

05 Docker容器数据卷

  • 是什么:使用卷来保存docker中的数据,如果没有commit生成新的镜像,作为新的镜像的一部分,当容器删除后,数据自然也就没有了
  • 作用:容器的持久化、容器间继承和共享数据
  • 添加数据卷:
-- 直接命令添加
docker run -it -v /宿主机目录:/容器内目录[:ro] id/name 
# ro表示read only容器内只能读宿主机目录内文件,不可修改

-- DockerFile添加
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
- 构建
docker build -f /dockerFile -t imageName . # .表示在当前目录创建,不写-f默认读取Dockerfile
- 运行这个镜像会在容器中添加相应的卷,使用docker inspect id/name查看,在宿主机中会有默认的对应目录:/var/lib/docker/volumes/id/_data/

- 如果遇到docker访问出现cannot open directory .:Permission denied
解决办法:在挂载目录后多加一个 --privileged=true
  • 数据卷容器:创建的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器称为数据卷容器。
docker run -it --name dc2 --volumes-from dc1
- 那么dc2里就有dc1的数据卷,dc1的数据卷是与宿主机共享的
- 数据卷的生命周期一直持续到没有容器使用它为止
问题:使用docker run -it -v /xx:/xxx id 创建数据卷之后,容器停止,再开启数据还有吗?容器删除再开还有吗?应该是有的

06 Dockerfile解析

  • dockerfile是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本
    • 编写、构建(docker build)、运行(docker run)

Dockerfile构建过程解析

  • Dockerfile是软件原材料、镜像是交付品、容器则是软件的运行态。dockerfile面向开发,docker镜像成为i交付标准,docker容器则涉及部署与运维,三者缺一不可,合力充当docker体系的基石
  • Dockerfile:需要定义一个dockerfile,定义了进程需要的一切东西,包括执行代码、文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程等等(当应用进程与系统服务和内核进程打交道时,需要考虑如何设计namespace的权限控制)
  • docker镜像:dockerfile定义一个文件后,docker build会产生一个docker镜像,当运行镜像时,开始提供服务
  • docker容器:容器时直接提供服务的
-- Dockerfile基础知识
- 每条保留字指令都必须大写,后面都要跟至少一个参数
- 指令从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层,并对镜像进行提交

-- docker执行dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器做出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有的指令都执行完成

Dockerfile体系结构

FROM 基础镜像,当前镜像基于哪个镜像
MAINTAINER 镜像维护者的姓名和邮箱
RUN    容器构建时需要运行的命令
EXPOSE    当前容器对外暴露的端口
WORKDIR    指定在创建容器后,终端默认登陆进来的工作目录,默认/
ENV    用来在构建环境变量中设计环境变量
ADD    将宿主机目录下的文件拷贝进镜像,且ADD会解压tar包、自动处理url
COPY    类似ADD,但是不解析,只是拷贝,COPY src dest、COPY["src","dest"]
VOLUME    容器数据卷,用于数据保存和持久化工作
CMD    指定一个容器启动时要运行的命令,可以有多个,但只有最后一个生效,CMD会被docker run之后的命令覆盖
ENTRYPOINT    与CMD一样,但是不会被覆盖,docker run后的命令追加到ENTRYPOINT里面
ONBUILD    当构建一个被继承的dockerfile命令时,父镜像在被继承后父镜像的ONBUILD被触发

# EXPOSE只是展示性的,为了方便不同开发人员维护!!不用EXPOSE也可以使用-p命令指定端口,但是如果使用了,在使用-P命令时可以随机映射到主机的端口,因为是随机的,所以也没什么用

案例

base镜像:scratch, 参考hub.docker.com 

07 Docker常用安装

搜索镜像 docker search name
拉取镜像 docker pull name
查看镜像 docker images [name]
启动镜像 docker run -it -p hostPort:CotainterPort id/name
停止容器 docker stop id/name
移除容器 docker rm id/name 

-- tomcat
docker search tomcat
docker pull tomcat
docker images
docker run -it -p 8080:8080 tomcat

-- mysql
docker search mysql:5.6
docker pull mysql:5.6
docker run -p 3306:3306 --name mysql \
    -v /xxx/mysql/conf:/etc/mysql/conf.d
    -v /xxx/mysql/logs:/logs
    -v /xxx/mysql/data:/var/lib/mysql
    -e MYSQL_ROOT_PASSWORD=999999
    -d mysql:5.6
docker exec -it id/name /bin/bash
mysql -uroot -p999999

-- redis
docker pull redis:3.2
docker run -p 6379:6379 \
    -v /xxx/data:/data \
    -v /xxx/conf:/usr/local/etc/redis/redis.conf \
    -d redis:3.2 redos-server /usr/local/etc/redis/redis.conf \
    --appendonly yes

docker exec -it id/name redic-cli # 连接客户端

08 本地镜像发布到阿里云

1 - 生成镜像
    docker build -f Dockerfile -t name .
    docker commit -a xxx -m xxx id/name:xxx
2 - 在dev.aliyun.com创建仓库、命名空间
3 - 推送
    docker login --username=registry.cn-hangzhou.aliyuncs.com
    docker tag id registry.cn-hangzhou.aliyuncs.com/xxx/xxx:xxx
    docker push registry.cn-hangzhou.aliyuncs.com/xxx/xxx:xxx
4 - 使用:在dev.aliyun.com上搜索,复制地址docker pull
    docker pull registry.cn-hangzhou.aliyuncs.com/xxx/xxx:xxx

可视化

  • portainer:docker图形化界面管理工具,提供一个后台面板供我们操作
  • rancher
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

Docker 网络

理解docker0

# 查看ip地址
ip addr    # address, a都可以
ifconfig

# 原理:
# 1、每启动一个容器,docker就会给容器分配一个ip,只要安装了docker,就会有一个docker0网卡。桥接模式,使用veth-pair技术
# 2、每启动一个容器,就多了一对网络,veth-pair就是一对的虚拟设备接口,它们都是成对出现的,一端连接协议,一端彼此相连。正因为有这个特性,veth-path充当一个桥梁,连接各种虚拟网络设备


# 容器和容器直接是可以互相ping通的
# 所有容器默认共用一个路由器docker0(网关),所有容器在不指定网络的情况下,都是docker0路由的,docker会给容器分配一个默认的可用ip
  • --link后加容器名,可用直接通过容器名访问,是在hosts文件里添加了映射

自定义网络

# 查看所有的docker网络
docker network --help

# 网络模式
# bridge    # 桥接模式,桥接docker(默认)
# none      # 不配置网络
# host      # 和宿主机共享网络
# container # 容器网络连通(用的少,局限性很大)

# 默认 --net bridge
# 创建自己的网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

docker network inspect mynet    # 查看自己创建的mynet
docker run -d -P --name tomcat-net-01 --net mynet tomcat    # 使用自己创建的网络而不是docker0,不使用--link可以使用ping名字ping通

# 结论:自定义docker网络帮我们维护好了ip和名字的对应关系,推荐这样使用网络。不同集群使用不同的网络,保证集群健康

网络连通

docker0网络下的(默认)容器如何连接自定义网络下的容器?通过创建网络连接使容器有两个ip地址

docker network connect mynet <containerName>    # 本质是将容器加入网络
docker network inspect mynet    # 可以发现是直接加入的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值