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转发




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值