Docke介绍

Docker简介

一、什么是 Docker?

从概念上来看 Docker 和我们传统的虚拟机比较类似,只是更加轻量级,更加方便使用。docker与虚拟机的对比如下:

特性容器虚拟机
启动速度秒级分钟级
硬盘使用一般为MB一般为GB
性能接近原生弱于原生
系统支持量单机支持上千个容器一般几十个

Docker是一个Client-Server结构的系统,一个docker 容器,是一个运行时环境,可以简单理解为进程运行的集装箱。

二、为啥要用容器?

  1. 环境隔离
  2. 方便部署

三、Docker Engine

Docker Engine是一个C/S架构的应用程序,主要包含下面几个组件:

  • 常驻后台进程Dockerd
  • 一个用来和 Dockerd 交互的 REST API Server
  • 命令行CLI接口,通过和 REST API 进行交互(我们经常使用的 docker 命令)

四、Docker 架构

Docker 使用 C/S (客户端/服务器)体系的架构,Docker 客户端与 Docker 守护进程通信,Docker 守护进程负责构建,运行和分发 Docker 容器。Docker 客户端和守护进程可以在同一个系统上运行,也可以将 Docker 客户端连接到远程 Docker 守护进程。Docker 客户端和守护进程使用 REST API 通过UNIX套接字或网络接口进行通信。

  1. Docker Damon:dockerd,用来监听 Docker API 的请求和管理 Docker 对象,比如镜像、容器、网络和 Volume。
  2. Docker Client:docker,docker client 是我们和 Docker 进行交互的最主要的方式方法,比如我们可以通过 docker run 命令来运行一个容器,然后我们的这个 client 会把命令发送给上面的 Dockerd,让他来做真正事情。
  3. Docker Registry:用来存储 Docker 镜像的仓库,Docker Hub 是 Docker 官方提供的一个公共仓库,而且 Docker 默认也是从 Docker Hub 上查找镜像的,当然你也可以很方便的运行一个私有仓库,当我们使用 docker pull 或者 docker run 命令时,就会从我们配置的 Docker 镜像仓库中去拉取镜像,使用 docker push 命令时,会将我们构建的镜像推送到对应的镜像仓库中。
  4. Images:镜像,镜像是一个只读模板,带有创建 Docker 容器的说明,一般来说的,镜像会基于另外的一些基础镜像并加上一些额外的自定义功能。比如,你可以构建一个基于 Centos 的镜像,然后在这个基础镜像上面安装一个 Nginx 服务器,这样就可以构成一个属于我们自己的镜像了。
  5. Containers:容器,容器是一个镜像的可运行的实例,可以使用 Docker REST API 或者 CLI 来操作容器,容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。

五、安装

直接前往官方文档选择合适的平台安装即可,Docker Desktop/Docker Engine

镜像和容器的基本操作

一、获取镜像

docker pull [选项] [Docker Registry 地址[:端口]/]仓库名[:标签]
docker pull centos:7

二、运行

docker run -it --rm \
    centos:7 \
    /bin/bash
  • -it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
  • –rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用–rm可以避免浪费空间。
  • centos:7:这是指用 centos:7 镜像为基础来启动容器。
  • bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。

当利用docker run来创建容器时,Docker 在后台运行的标准操作包括:

  • 检查本地是否存在指定的镜像,不存在就从公有仓库下载
  • 利用镜像创建并启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个 ip 地址给容器
  • 执行用户指定的应用程序
  • 执行完毕后容器被终止

三、列出镜像

docker image ls

四、启动已终止的容器

docker start 容器Id/容器名

五、后台运行

 docker run -d centos:7 /bin/sh -c "while true; do echo hello world; sleep 1; done"
 docker logs
 docker ps
 docker ps -a

六、终止容器

docker stop 容器Id/容器名

七、进入容器

docker exec -it 容器Id/容器名 bash

八、删除容器

docker rm -f 容器Id/容器名

九、删除本地镜像

docker rmi 镜像名/镜像Id

Dockerfile定制镜像

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

  1. FROM指定基础镜像
  2. RUN执行命令,尽量减少RUN命令的条数
  3. 在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建。
  4. 构建镜像:docker build -t tag名称 .
  5. 镜像构建上下文(Context),docker build 命令最后有一个“.”就是在指定上下文路径。当构建的时候,用户会指定构建镜像上下文的路径,docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。
  6. COPY和ADD,ADD时如果源文件是一个压缩文件会自动解压,ADD时如果源是一个url会自动下载

数据共享和持久化

一、数据卷(Data Volumes)

docker volume create my-vol
docker volume ls
docker volume inspect my-vol

docker run -d -P \
    --name web \
    # -v my-vol:/wepapp \
    --mount source=my-vol,target=/webapp \
    training/webapp \
    python app.py
    
docker inspect web
docker volume rm my-vol
docker volume prune

二、挂载主机目录(Bind mounts)

docker run -d -P \
    --name web \
    # -v /src/webapp:/opt/webapp:ro \
    --mount type=bind,source=/src/webapp,target=/opt/webapp,readonly \
    training/webapp \
    python app.py

Docker的网络模式

一、Bridge模式

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。从docker0子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。

bridge模式是 docker 的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker 实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。bridge模式如下图所示:

docker network create -d bridge my-net
docker run -it --rm --name busybox1 --network my-net busybox sh

二、其他

  1. Host模式
  2. Container模式
  3. None模式

Tips & Thinking

  1. 为什么容器可以访问外网,而外网不可以访问容器?(为什么我们的办公电脑可以访问外网,而外网不可以访问它?)
  • NAT/NAPT 网络地址转换
  • telnet www.baidu.com 80/tcpdump -i any -n host 112.80.248.75
  1. 如果要让容器被主机外部访问如何处理?
route add 172.17.0.0 mask 255.255.255.0 192.168.238.131
route print
tracert 172.17.0.2
  1. docker run后的命令、CMD、entrypoint
  • CMD指令可以指定容器启动时要执行的命令,但它可以被docker run命令的参数覆盖掉。
  • ENTRYPOINT指令也可指定容器启动时要执行的命令。如果dockerfile中也有CMD指令,CMD中的参数会被附加到ENTRYPOINT 指令的后面。 如果这时docker run命令带了参数,这个参数会覆盖掉CMD指令的参数,并也会附加到ENTRYPOINT 指令的后面。
  1. 容器启动后就退出,如何排查?
  • docker logs查看容器运行的日志
  • docker exec进入容器进行各种分析

Docker技术的基础

namespace,容器隔离的基础,保证A容器看不到B容器. 6个名空间:User,Mnt,Network,UTS,IPC,Pid

cgroups,容器资源统计和隔离。主要用到的cgroups子系统:cpu,blkio,device,freezer,memory

unionfs,典型:aufs/overlayfs,分层镜像实现的基础

Linux 命名空间、控制组和 UnionFS 三大技术支撑了目前 Docker 的实现,也是 Docker 能够出现的最重要原因。

一、namespace

docker容器本质上是宿主机的进程,Docker通过namespace实现了资源隔离。

linux内核提拱了6种namespace隔离的系统调用,如下图所示,但是真正的容器还需要处理许多其他工作。

namespace系统调用参数隔离内容
UTSCLONE_NEWUTS主机名或域名
IPCCLONE_NEWIPC信号量、消息队列和共享内存
PIDCLONE_NEWPID进程编号
NetworkCLONE_NEWNET网络设备、网络栈、端口等
MountCLONE_NEWNS挂载点
UserCLONE_NEWUSER用户与组

实际上,linux内核实现namespace的主要目的,就是为了实现轻量级虚拟化技术服务。在同一个namespace下的进程合一感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,仿佛自己置身一个独立的系统环境中,以达到隔离的目的。

Linux Namespace : UTS

二、control groups

cd /sys/fs/cgroup/cpu
mkdir znyin
echo 20000 > znyin/cpu.cfs_quota_us
echo $$ > znyin/tasks

while true
do
  echo ''
done

# 重新打开一个shell,使用top观察CPU的使用率。可以发现,我们的死循环,最多只使用了20%的CPU

5分钟了解Docker原理之二,最简单的Cgroups介绍!

三、OverlayFS

探索OverlayFS

参考资料

  1. 《Linux Namespace 简介》
  2. 《自已动手写Docker》
  3. Docker基础
  4. iptables 命令解析
  5. 使用iptables进行NAT转发




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值