第一课:docker基本知识

1.什么是docker

使用最广泛的开源容器引擎
一种操作系统级的虚拟化技术
依赖于linux内核特性:namespace和cgroups
一种简单的应用程序打包工具

2.docker的设计目标

提供简单的应用程序打包工具
开发人员和运维人员职责逻辑分离
多环境保持一致性

3.docker的基本组成

docker client 客户端
docker daemon 守护进程
docker images 镜像
docker container 容器
docker registry 镜像仓库

4.容器vs虚拟机

container VM
启动速度 秒级 分钟级
运行性能 接近原生 5%左右损耗
磁盘占用 MB GB
数量 成百上千 一般几十台
隔离性 进程级别 系统级(更彻底)
操作系统 只支持linux 几乎所有
封装程度 只打包项目代码和依赖关系,共享宿主机内核 完整的操作系统

5.什么是镜像

一个分层存储的文件
一个软件的环境
一个镜像可以创建N个容器
一种标准化的交付
一个不包含linux内核而又精简的linux操作系统
镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history <ID/NAME>查看镜像中各层内容及大小,每层对应着dockerfile中的一条指令。docker镜像默认存储在/var/lib/docker/\<storage-driver\>中。

6.镜像从哪里来

Docker Hub是由docker公司负责维护的公共注册中心,包含大量的容器镜像,docker工具默认从这个公共镜像库下载镜像。地址:https://hub.docker.com/explore
配置镜像加速器:https://www.daocloud.io/mirror
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io

7.镜像与容器的联系

容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,会先从镜像里要协议的文件复制到容器自己的文件系统中(读写层)。
如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高磁盘利用率。
若想持久化这些改动,可以通过docker commit将容器保存成一个新镜像

8.docker镜像常用命令

指令 描述
ls 列出镜像
build 构建镜像来自Dockerfile
inspect 显示一个或多个镜像详细信息
pull 从镜像仓库拉取镜像
push 推送一个镜像到镜像仓库
rm 移除一个或多个镜像
prune 移除未使用的镜像。没有被标记或被任何容器引用的
tag 创建一个引用源镜像标记目标镜像
export 导出镜像文件系统到tar归档文件
import 导入镜像文件系统tar归档文件创建镜像
save 保存 一个或多个镜像到一个tar归档文件
load 加载镜像来自tar归档或标准输入

9.容器管理

9.1创建容器常用选项

选项 描述
-i,nteractive 交互式
-t,tty 分配一个伪终端
-d,detach 运行容器到后台
-e,env 设置环境变量
-p,publish list 发布容器端口到主机
-P,publist-all 发布容器所有EXPOSE的端口到宿主机的随机端口
-name string 制定容器名称
-h,hostname 设置容器主机名
-ip string 制定容器IP,只能用于自定义网络
-network 连接容器到一个网络
-mount mount 将文件系统挂在到容器
-v,-volume list 绑定挂载一个卷
-restart string 容器退出时重启策略,默认no,可选值[always|no-failure]

9.2容器资源限制

选项 描述
-m,-memory 容器可以使用的最大内存量
-memory-swap 允许交换到磁盘的内存量
-memory-swappiness=<0-100> 容器使用swap分区交换的百分比(0-100,默认为-1)
-oom-kill-disable 禁用oom killer
-cpus 可以使用的CPU数量
-cpuset-cpus 限制容器使用特定的CPU核心,如(0-3,0,1)
-cpu-shares CPU共享(相对权重)

示例:
内存限额
允许容器最多使用500M内存和100M的swap,并禁用oom killer。
docker run -itd --name web03 --memory=500m --memory-swap=600m -oom-kill-disable -P nginx

CPU限额:
允许容器最多使用一个半的CPU:
docker run -itd --name web01 --cpus="1.5" nginx
允许容器最多使用50%的CPU:
docker run -itd --name web01 --cpus=".5" nginx

9.3管理容器常用命令

选项 描述
ls 列出容器
inspect 查看一个或多个容器详细信息
exec 在运行容器中执行命令
commit 创建一个新镜像来自一个容器
cp 拷贝文件/文件夹到一个容器
logs 获取一个容器日志
port 列出或指定容器端口映射
top 显示一个容器运行的进程
stats 显示容器资源使用统计
stop/start 停止/启动一个或多个容器
rm 删除一个或多个容器

10.管理应用程序数据

10.1 将数据从宿主机挂载到容器中的三种方式

docker提供三种方式将数据从宿主机挂载到容器中:
volume:docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
bind mount:将宿主机上的任意位置的文件或者目录挂载到容器中。
tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统内。如果不系统将数据持久存储在任何位置,可以使用tmpfs,同时避免写入容器可写层提高性能。

10.2 volume

管理卷:
docker volume create nginx-vol
docker volume ls
docker volume inspect nginx-vol
用卷创建一个容器:
docker run -itd --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html  nginx
docker run -itd --name=nginx-test -v nginx-vol:/usr/share/nginx/html ngin
清理:
docker stop nginx-test
docker rm nginx-test
docker volume rm nginx-vol

注意:
1.如果没有指定卷,自动创建。
2.建议使用--mount,更通用。

10.3 bind mount

用卷创建一个容器:
docker run -itd --name=nginx-test --mount type=bind,src=/app/wwwwroot,dst=/usr/share/nginx/html nginx
docker run -itd --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
验证绑定:
docker inspect nginx-test
清理:
docker stop nginx-test
docker rm nginx-test

注意:
1.如果源文件/目录不存在,不会自动创建,会抛出一个错误
2.如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏

10.4 小结

volume特点:

  • 多个运行容器之间共享数据。
  • 当容器停止或被移除时,该卷依然存在。
  • 多个容器可以同时挂载相同的卷。
  • 当明确删除卷时,卷才会被删除。
  • 将容器的数据存储在远程主机或其他存储上。
  • 将数据从有台docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes/)
    bind mount特点:
  • 从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供DNS解析。
  • 在docker主机上的开发环境和容器之间共享源代码。例如,可以将Maven target目录挂载到容器中,每次在docker主机上构建maven项目时,容器都可以访问构建的项目包。
  • 当docker主机的文件或目录结构保证与容器所需的绑定挂载一致时。

11.docker四种网络模式

bridge
-net=bridge
默认网络,docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。

host
-net=host
容器不会获得一个独立的network namespace,而是与宿主机共用一个,这就意味着容器不会有自己的网卡信息,而是使用宿主机的, 容器除了网络,其他都是隔离的。

none
-net=none
获取独立的network namespace,但不为容器进行任何网络配置,需要我们手动配置。

container
-net=container:Name/ID
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。

自定义网络
与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信。

12.docker网络管理

桥接宿主机网络与配置固定IP地址
临时生效:

#网桥名称
br_name=br0
#添加网桥
brctl addbr $br_name
#给网桥配置IP
ip addr add 192.168.1.120/24 dev $br_name
#删除已存在的eth0网卡配置
ip addr del 192.168.1.120/24 dev eth0
#激活网桥
ip link set $br_name up
#添加eth0到网桥
brctl addif $br_name eth0
#添加路由
ip route add default via 192.168.1.1 dev br0

还需要在docker启动时桥接这个网桥
#vi /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -b=br0
#systemctl restart docker

永久生效:

vi /etc/sysconcig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BRIDGE=br0

vi /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.1.120
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=223.5.5.5

配置固定IP

C_ID=$(docker run -it --net=none ubuntu)
C_PID=$(docker inspect -f '{{.State.Pid}}' $C_ID)
#创建network namespace目录并将容器的network namespace软连接到此目录,以便ip netns命令读取
mkdir -p /var/run/netns
ln -s /proc/$C_PID/ns/net /var/run/netns/$C_PID
#添加虚拟网卡veth+容器PID,类型是veth pair,名称是vp+容器PID
ip link add  veth$C_PID type veth peer name vp$C_PID
#添加虚拟网卡到br0网桥
brctl addif br0 veth$C_PID
#激活虚拟网卡
ip link set veth$C_PID up
#设置容器网络信息
IP='192.168.1.123/24'
GW='192.168.1.1'
#给进程配置一个network namespace
ip link set vp$C_PID netns $C_PID
#在容器进程里面设置网卡信息
ip netns exec $C_PID ip link set dev vp$C_PID name eth0
ip netns exec $C_PID ip link set eth0 up
ip netns exec $C_PID ip addr add $IP dev eth0
ip netns exec $C_PID ip route add default via $GW

pipework工具配置容器固定IP

git clone https://github.com/jpetazzo/pipework.git
cp pipework/pipework /usr/local/bin
docker run -itd --net=none --name test01 ubuntu
pipework br0 test01 192.168.1.88/24@192.168.1.1
posted @ 2019-12-23 16:38  Doc-Yu  阅读(201)  评论(0编辑  收藏  举报