Docker学习笔记

1、Docker 为什么出现

一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验

Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。

环境配置如此麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。

2、Docker的理念

Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次封装,到处运行”。

3、Docker的基本组成

1)、镜像

Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。

2)、容器

Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台(进程级别的隔离)。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

3)、仓库

仓库(Repository)是集中存放镜像文件的场所。仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub(https://hub.docker.com/)

4、安装Docker

按照官网文档操作https://docs.docker.com/

5、镜像云加速

按照阿里云文档操作 https://promotion.aliyun.com/ntms/act/kubernetes.html

6、Docker是怎么工作的

Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。 容器,是一个运行时环境,相当于一个集装箱。

在这里插入图片描述

7、Docker为什么比VM快

  1. docker有着比虚拟机更少的抽象层。由亍docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。

  2. docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。

在这里插入图片描述

8、Docker常用命令

docker --help 查看命令

1)、基本命令
docker version: 查看版本号
docker info: 查看docker相关信息
docker help: 查看常用命令帮助
2)、镜像命令

docker images

作用:列出本地镜像模板
结果说明:
    REPOSITORY:镜像仓库源
    TAG:镜像标签
    CREATED:创建时间
    SIZE: 镜像大小
    IMAGE ID: 镜像ID
常用参数:
    -a: 列出本地所有镜像(含中间镜像层)
    -q: 只显示镜像ID
    –digests: 显示镜像说明摘要信息
    –no-trunc: 显示镜像完整信息

docker search 镜像名

作用: 从DockerHub 找某个镜像
参数:

-s 30: 列出star数大于30的镜像
–no-trunc: 完整信息
–automated:只列出自动构建类型的镜像

例:

docker search nginx
docker search -s 30 nginx

docker pull

使用:
docker pull nginx
docker pull tomcat:3.2
作用: 拉取镜像

docker rmi

作用:删除镜像
常用参数:
    -f: 强制删除
使用:后面跟镜像id或唯一镜像名

docker rmi hello-world
docker rmi -f hello-world
# 删除多个
docker rmi -f hello-world nginx
# 删除全部
docker rmi -f $(docker images -qa)

提交镜像

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

作用:提交容器副本,使之成为一个新的镜像
根据DockerFile构建镜像

docker build -f dockerFile路径 -t [命名空间/]镜像名 .
2)、容器命令

新建并启动容器

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

OPTIONS:

–name=“new name”: 为容器指定一个新名字
-d: 后台运行容器,并返回容器ID(启动守护式容器)
-i: 以交互模式运行容器
-t: 为容器重新分配一个伪输入终端,通常与 -i配合使用
-P: 随机端口映射
-p:指定端口映射,有一下四种格式
    ip:hostPort:containerPort
    ip::containerPort
    hostPort:containerPort
    containerPort
    hostPort是对外暴露的端口,containerPort是容器内应用端口
如:
docker run -it -p 8888:8080 tomcat
    1

docker容器后台运行,就必须有一个前台进程,所以如果我们以后台运行的方式启动centos,这个容器启动后就会立即自杀。

docker ps

OPTIONS:

-a: 列出当前所有正在运行的容器和历史上运行过的容器
-l: 显示最近创建的容器
-n: 显示最近创建的n个容器
-q: 静默模式,只显示容器编号
–no-trunc: 不截断输出

退出容器

exit: 容器停止并退出
ctrl+P+Q:容器不停止退出

重新进入:

docker attach 容器ID: 进入交互界面
docker exec -t 容器ID 操作:直接去容器中执行操作,返回执行后的结果(不进入交互界面)

eg.

docker exec -t ls /etc
# 以终端形式进入
docker exec -it 容器ID /bin/bash

启动容器

docker start 容器ID或容器名

重启容器

docker restart 容器ID或容器名

停止容器

# 温和关闭
docker stop 容器ID或容器名
# 强制停止
docker kill 容器ID或容器名

删除已停止的容器

OPTIONS:

-f: 强制删除

docker rm 容器ID
# 删除所有容器
docker rm -f $(docker ps -a -q)

查看日志

docker logs [-f] [-t] [--tail] 容器ID

OPTIONS:

-t: 加入时间戳
-f: 跟随最新的日志打印
–tail 数字 : 显示最后多少条

查看容器内进行的进程

docker top 容器ID

查看容器内部细节

docker inspect 容器ID

以json形式展现
从容器内拷贝数据到主机

docker cp 容器ID: 容器内路径 主机路径

9、Docker 镜像

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

1)、Docker镜像加载原理
  1. docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
  2. bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
  3. rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??
在这里插入图片描述
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。

2)、Docker 采用分层镜像的好处

最大的一个好处就是 - 共享资源

比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

10、容器数据卷

容器数据卷用来做容器的持久化和共享数据(容器间继承)

类似于Readis中的rdb和aof文件。卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但不属于UnionFS,因此能绕过UnionFS提供一些用于持久存储或共享数据的特性:

卷设计的目的就是数据的持久化,完全独立于容器的生存周期,因此删除容器不会删除其挂载的数据卷。

特点:

  • 可在容器间共享或重用数据
  • 卷中的更改可直接生效
  • 卷的更改不会包含在镜像的更新中
  • 卷的生命周期持续到没有容器使用它为止

作用:

  • 数据共享
  • 数据持久化
  • 容器间继承
  • 容器,主机间数据共享docker cp

直接命令添加

# 目录不存在会新建
docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
# 容器内数据卷只读 
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名

eg.

docker run -it -v /dataVolume:/dataValumeContainer centos

运行之后就会发现docker的centos下多了一个dataValumeContainer目录,而宿主机根目录下也多了一个dataVolume目录,并且这两个目录的数据一直是同步的,即便是容器关闭了,修改宿主机dataVolume目录下的文件,容器重新打开时也会同步。

容器关闭后修改dataVolume,完了重新打开容器,不是直接执行docker run就会自动同步,需要再次指定两个目录,也就是下次打开容器时执行的还应该是docker run -it -v /dataVolume:/dataValumeContainer centos

并且使用``查看容器运行的详细信息时,也可以看见:

 "Mounts": [
            {
                "Type": "bind",
                "Source": "/dataVolume",
                "Destination": "/dataValumeContainer",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

其中,RW指示在容器内该目录的读写权限,默认可读可写,RW为True,加上 :ro(read only)时,RW为false,是只读的。

2)、DockerFile

DockerFile 是什么?

  • 他是Docker的描述文件,用来指示一个镜像的该怎么构建,可以根据一个DockerFile通过docker build命令构建一个镜像
VOLUME["/dataValumeContainer1", "/dataValumeContainer2", "/dataValumeContainer3"]

#使用DockerFile添加数据卷并不能指定宿主机的路径,是默认的。默认路径在/var/lib/docker/volumes/容器ID/_data

简单的DockerFile

# "继承"自 centos
FROM centos
# 自动建立这两个数据卷
VOLUME ["/dataValumeContainer1", "/dataValumeContainer2"]
# 输出一句话
CMD echo "------- building success -------"
# 结束后执行/bin/bash
CMD /bin/bash

运行docker build -f /MyDocker/dockerfile -t junebao/centos .

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 470671670cac
Step 2/4 : VOLUME ["/dataValumeContainer1", "/dataValumeContainer2"]
 ---> Running in dc9c02a9dca4
Removing intermediate container dc9c02a9dca4
 ---> c3c7f62eeb7b
Step 3/4 : CMD echo "------- building success -------"
 ---> Running in 74e3dc92a757
Removing intermediate container 74e3dc92a757
 ---> 9ecf2700654d
Step 4/4 : CMD /bin/bash
 ---> Running in cd8c7ed3247e
Removing intermediate container cd8c7ed3247e
 ---> 2c26412f54a6
Successfully built 2c26412f54a6
Successfully tagged junebao/centos:latest

可以看到,它按步骤执行了每一行,使用docker images也能看到刚刚构建的镜像

root:/MyDocker# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
junebao/centos      latest              2c26412f54a6        2 minutes ago       237MB

根据这个镜像创建并运行容器,发现在它的根目录下已经自动建立了DockerFile里的两个数据卷

root@:/MyDocker# docker run -it centos
[root@3432c332744a /]# ls
bin  dataValumeContainer1  dataValumeContainer2  dev  etc  home  lib  ...	usr  var

docker inspect查看这个容器的详细信息,可以找到默认分配的宿主机文件路径

"Mounts": [
            {
                "Type": "volume",
                "Name": "3c7c0c43e3036a536272b10be3a8e2fa201bdc37010759ecc8753c5244f47e56",
                "Source": "/var/lib/docker/volumes/3c7c0c43e3036a536272b10be3a8e2fa201bdc37010759ecc8753c5244f47e56/_data",
                "Destination": "/dataValumeContainer1",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "8bd113e3f6a4ac1ae6824b8638ed03398c2d9f7ec08f66ddc66c1cd05e3ca857",
                "Source": "/var/lib/docker/volumes/8bd113e3f6a4ac1ae6824b8638ed03398c2d9f7ec08f66ddc66c1cd05e3ca857/_data",
                "Destination": "/dataValumeContainer2",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

默认路径在/var/lib/docker/volumes/容器ID/_data

操作容器内的数据卷和宿主机的这个目录,效果和上面用命令构建的一样。

如果Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied,请在挂载目录后面添加--privileged=true参数,即docker run -it -v /dataVolume:/dataValumeContainer --privileged=true centos
3)、 数据卷容器

命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称为数据卷容器。

命令

docker run [其他参数] --volumes-from 要挂载的父容器名 容器名

eg.

docker run -it --name=dc01 centos
docker run -it --volumes-from dc01 --name=dc02 centos

应为dc01是根据DockerFile建立的镜像创建的,所以一开始就有俩个数据卷,而dc02挂载了dc01,所以它也具有这两个数据卷,需要注意的是,对于这两个目录里面的文件,子容器和父容器是完全共享的,任何一方的修改都会同步到另一方。

11、DockerFile

规则

保留字必须大写,后面至少跟1个参数
指令从上到下,顺序执行
# 表示注释
每条指令都会创建一个镜像层,并对镜像进行提交

Docker执行DockerFile的大致流程

docker从基础镜像(scratch)运行一个容器
执行一条指令并对指令作出修改
执行类似docker commit的操作提交一个新的镜像层
docker再基于刚提交的镜像运行一个容器
执行下一条指令…直到结束

保留关键字

FROM: 基础镜像,申明当前镜像是基于那个镜像的
MAINTAINER: 作者+邮箱
RUN: 镜像构建时的命令,执行一个具体命令
EXPOSE: 设置当前容器对外暴露的端口号
WORKDIR: 指定容器创建后默认的目录,登录进来后的落脚点
ENV: 用于在构建镜像过程中设置环境变量
COPY: 将宿主机目录下的文件拷贝进镜像
ADD: COPY + 解压缩
VOLUME: 容器数据卷
CMD: 指定一个容器启动时要运行的命令,可以有多个CMD,但只有最后一个生效, CMD会被docker run之后的参数替换。
ENTRYPOINT: 指定一个容器启动时要运行的命令,与CMD一样,都是指定容器启动程序及参数, docker run之后的参数会被传递给ENTRYPOINT,之后形成新的命令组合
ONBUILD: 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的onbuild被触发

CMD 和 ENTRYPOINT 的区别

如果用CMD

FROM scratch
CMD ["curl", "-s", "http://www.baidu.com"]

创立镜像后,打开容器时如果执行docker run mycurl肯定是正常的,但如果要给curl添加别的参数,运行

docker run -i mycurl

那run后面的参数-i就会替换CMD的参数,形成CMD -i,-i这条命令显然不存在,就会报错,但如果是ENTRYPOINT,run后面的参数就会以追加的形式加入

FROM scratch
ENTRYPOINT ["curl", "-s", "http://www.baidu.com"]

开启容器时同样执行docker run -i mycurl,-i参数就会追加到ENTRYPOINT后面,实际执行变成ENTRYPOINT [“curl”, “-s”, “-i”, “http://www.baidu.com”]

12、发布镜像

参考阿里云容器服务

https://promotion.aliyun.com/ntms/act/kubernetes.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值