虚拟机(virtual machine)就是带环境安装的一种解决方案
它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统
用户可以通过虚拟机还原软件的原始环境.但是,这个方案有几个缺点
缺点
资源占用多
冗余步骤多
启动慢
Container
一个用户空间独立且限定了资源的对象,这样的对象称为容器
Namespace
Cgroup
LXC
DotCloud公司结合LXC和以下列出的技术实现了Docker容器引擎,相比于LXC,Docker具备更加全面的资源控制能力,是一种应用级别的容器引擎
技术
Namespace、Cgroup
Chroot
Veth
UnionFS
Iptables/netfilter
Tc
Quota
Setrlimit
因为Docker依赖Linux内核的技术,3.8及以上内核版本才能运行Docker容器,官方推荐至少3.10
Docker本质是宿主机上的一个进程,Docker通过Namespace实现环境隔离,通过Cgroup实现资源限制
架构图
Hypervisor
传统的虚拟化技术在虚拟机VM和硬件之间加了一个软件层Hypervisor(虚拟机管理程序)
运行方式
GuestOS通过Hypervisor分享硬件,Guest OS发出的指令需要被Hypervisor捕获,然后翻译为物理硬件或宿主机操作系统能够识别的指令
故像 VMWare和VirtualBox等虚拟机在性能方面远不如裸机,但基于硬件虚拟化的KVM约能发挥裸机80%的性能
Docker Engine
比较
占用资源
创建、启动时间
性能损耗
交付、部署
高可用和可恢复性
隔离性
安全性
可管理性
docker源
curl https://gitee.com/leedon21/k8s/raw/master/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
yum list docker-ce --showduplicates
yum install -y docker-ce
yum install -y docker-ce-19.03.15
rpm包
官方下载地址
yum -y install docker-ce-19.03.9-3.el7.x86_64.rpm
方法1
{
“registry-mirrors”: [“https://jvfknb9j.mirror.aliyuncs.com”,“https://pf5f57i3.mirror.aliyuncs.com”]
}
- systemctl restart docker
方法2
ExecStart=/usr/bin/dockerd --registry-mirror=https://pf5f57i3.mirror.aliyuncs.com
- systemctl daemon-reload;systemctl restart docker
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://1.1.1.11:2375 --containerd=/run/containerd/containerd.sock
systemctl daemon-reload;systemctl restart docker
docker -H 1.1.1.11 version
默认只能使用本机客户端连接,不建议开启远程连接,没有任何加密认证过程
请务必要开启需要安全认证的tcp端口https://blog.csdn.net/qq_21187515/article/details/90262324
镜像索引
NAME:TAG或IMAGE ID
NAME组成
注册服务器/用户/仓库
注册服务器
用户
仓库
查看镜像
查看本机的镜像
镜像详细信息
查找镜像
docker search centos
https://hub.docker.com
下载镜像
docker pull NAME[:TAG]
上传镜像
docker push NAME[:TAG]
删除镜像
容器索引
查看容器
docker ps [-a]
查看正在运行的[所有的]容器
状态
docker ps -q [-a]
docker top 容器
docker inspect 容器
docker logs 容器
创建并运行容器
语法
选项
-i
-t
-d
-h
–rm
–name
–network
–ip
-p <宿主端口>:<容器端口>
-p <容器端口>
-P
-v <宿主目录>:<容器目录>
-v <容器目录>
–restart=always
–privileged
示例
连接容器
对于正在运行的容器,我们可以在宿主机上连接容器
docker exec -it centos {/bin/bash,bash,sh}
docker attach centos
容器运行
docker create [选项] 镜像
docker stop|start|restart|kill 容器
docker pause|unpause 容器
删除容器
docker rm 容器
docker rm -f 容器
docker rm docker ps -a -q
复制文件
docker cp container:src_file dst_path
docker cp src_file container:dst_path
容器提交
创建和运行
create
start
run
运行和停止
start
stop
kill
重启
restart
暂停
pause
unpause
导出
导入
导出
导入
安装
配置
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry=1.1.1.11:5000
- systemctl daemon-reload;systemctl restart docker
使用
重命名镜像,使之与registry匹配
上传到私有仓库
查看私有仓库
curl 1.1.1.11:5000/v2/_catalog
curl 1.1.1…11:5000/v2/centos7/tags/list
从私有仓库中拉取镜像
WebUI
目的
工具
docker-registry-web
运行
docker run -d -p 8080:8080 --name registry-web --link registry -e REGISTRY_URL=http://1.1.1.11:5000/v2 -e REGISTRY_NAME=1.1.1.11:5000 hyper/docker-registry-web
–link=[]
-e
访问web界面
Harbor简介
官网
由VMware公司中国团队为企业用户设计的Registry server开源项目
Harbor是构建企业级私有docker镜像的仓库的开源解决方案,它是Docker Registry的更高级封装
支持安装在多个 Registry 节点的镜像资源复制,镜像全部保存在私有 Registry 中
提供了高级的安全特性,诸如用户管理,访问控制和活动审计等
Harbor架构
proxy
ui
registry
adminserver
jobsevice
log
准备工作
配置过程
安装docker-compose
下载harbor
配置并安装
cd /usr/local/harbor/
[root@docker harbor]# vim harbor.yml
hostname: 1.1.1.11
[root@docker harbor]# ./prepare
[root@docker harbor]# ./install.sh
添加http注册服务器
进入web界面
1.1.1.11
测试上传镜像
登录harbor的Web界面,创建一个项目sdc
打标签
登录镜像库
docker login 1.1.1.11
上传镜像
harbor启停
启动
关闭
配置HTTPS
服务端
客户端
创建证书目录
将证书放到证书目录中
权限管理
官方文档
系统级别
管理员
普通用户
项目级别
项目管理员
项目维护者
开发者
访客
登录阿里云控制台
搜索 容器镜像服务 并进入
创建个人实例
创建命名空间
创建镜像仓库
用法
-v 宿主目录:容器目录[:挂载属性]
docker run -d -v /www:/usr/share/nginx/html nginx
注意
缺陷
用法
-v [VOLUME_NAME:]容器目录[:挂载属性]
docker run -d -v nginx:/usr/share/nginx/html nginx
docker run -d --mount ‘src=nginx,dst=/usr/share/nginx/html’ nginx
查看挂载信息
volume
由docker管理的数据卷,在/var/lib/docker/volumes目录下
管理命令
docker volume COMMAND
COMMANDS
create
inspect
ls
prune
rm
注意
优势
bridge
bridge模式是容器的默认网络模式,相当于vmware中的NAT
Docker安装时在宿主机创建虚拟网桥docker0,每开启一个容器,按照顺序从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关,容器连接到虚拟网桥docker0
虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在容器中,命名为eth0(容器的网卡),另一端放在主机中,命名为vethxxx,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令查看
结构图
host
none
container
自定义
创建网桥
指定容器IP
只有自定义网络支持指定IP,不指定时仍按顺序分配
直接路由
pipework
flannel
官方文档
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像
从FROM命令开始,紧接着跟随者各种方法,命令和参数,其产出为一个新的可以用于创建容器的镜像
语法
所有Dockerfile都必须以FROM命令开始。 FROM命令会指定镜像基于哪个基础镜像创建
语法
设置该镜像的作者
语法
RUN command arg1 arg2 …
RUN [“命令”,“arg1”,“arg2”]
每一条RUN都会新建立一层(开启一个容器),在其上执行这些命令,执行结束后,commit这一层的修改,构成新的镜像
多条命令用命令连接符连接以减少RUN的使用,尽量避免产生不必要的层
每一层只保留真正需要的东西,类似于安装包、暂存目录、yum缓存等不必要的东西都建议清理掉
语法
将构建上下文目录中<源路径>的文件或目录复制到新的一层的镜像内的<目标路径>位置
<源路径>可以是多个,支持通配符
<目标路径>可以是绝对路径或相对于工作目录(WORKDIR指令指定)的相对路径,不需提前创建
源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等
语法
相对于构建上下文目录的一个文件或目录,也可以是一个远程的url
远程url
tar压缩文件
注意
语法
CMD command arg1 arg2
CMD [“executable”,“arg1”,“arg2”]
CMD [“arg1”,“arg2”]
用于指定默认的容器主进程的启动命令,运行容器时执行
CMD命令可被docker run中的命令覆盖,如果有多个CMD命令,则最后一条生效
对于容器而言,其启动程序就是容器应用进程. 容器仅为前台主进程而存在,前台主进程退出,容器就失去了存在的意义,从而退出
前台启动
apache
nginx
语法
用于指定默认的容器主进程的启动命令,运行容器时执行
ENTRYPOINT命令也可以被覆盖,但docker run需要指定–entrypoint,多个ENTRYPOINT只有最后一个生效
结合CMD和ENTRYPOINT,可以从CMD中移除“application”而仅仅保留参数,参数将传递给ENTRYPOINT,也可以从命令行中捕获执行时需要的参数
语法
声明运行时容器提供服务端口,这只是一个声明,不影响容器实际开启的服务端口
docker run -P 时,会自动随机映射到EXPOSE的端口
语法
设置环境变量。无论是后面的其它指令还是运行时的应用,都可以直接使用这里定义的环境变量
语法
挂载匿名卷,可被运行时设置的挂载所覆盖
可通过 docker inspect -f {{.Mount}} container查询所挂载的目录
语法
指定工作目录(当前目录),如该目录不存在,WORKDIR会自动创建目录
语法
改变之后层的执行RUN,CMD以及ENTRYPOINT 这类命令的身份,用户必须提前创建
语法
选项
interval=<间隔>
timeout=<时长>
retries=<次数>
告诉Docker如何判断容器的状态是否正常,1.12 引入,引入前只能通过容器内主进程是否退出来判断
如果程序进入死锁或死循环状态,应用进程并不退出但是该容器已经无法提供服务了,1.12前就无法检测到
启动容器时的初始状态为starting ,检查成功后变为 healthy ,如果连续一定次数失败,则会变为 unhealthy
HEALTHCHECK 只可以出现一次,如果写了多个,只有最后一个生效
1
2
hostname -I
.” > /var/www/html/index.html3
4
介绍
多阶段构建redis
FROM ubuntu
COPY --from=0 [“/redis-4.0.10/src/redis-server”,“/redis-4.0.10/redis.conf”,“/redis/”]
CMD [“/redis/redis-server”,“/redis/redis.conf”]
- redis服务,只需要启动脚本redis-server和配置文件redis.conf即可运行
COPY指令的–from参数
表示从前面指定的阶段中拷贝文件到当前阶段中,可以使用数字(0表示第一个FROM)、名称来指定,还可以直接从一个已经存在的镜像中拷贝
名称
FROM ubuntu
COPY --from=builder …
- 从镜像
- FROM ubuntu
COPY --from=quay.io/coreos/etcd:v3.3.9 [“/usr/local/bin/etcd”,“/usr/local/bin/”]
- 直接将官方编译好的程序文件拿过来使用
例
RUN sed -i ‘s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/’ /etc/apk/repositories;
apk update;
apk add -t .build-deps gcc libc-dev make linux-headers wget;
wget $dl_url;
tar xf $pkg;
cd $src_dir;
sed -i ‘/^bind/s/127.0.0.1/0.0.0.0/’ redis.conf;
make
FROM alpine
ENV src_dir=redis-6.2.7
COPY --from=0 [“/ s r c d i r / s r c / r e d i s − s e r v e r " , " / src_dir/src/redis-server","/ srcdir/src/redis−server","/src_dir/src/redis-cli”,“/$src_dir/redis.conf”,“/redis/”]
CMD [“/redis/redis-server”,“/redis/redis.conf”]
容器的基本信息
容器的运行状态
容器的用量信息
单台主机
docker stats [–no-stream]
CAdvisor
docker run -d -v /:/rootfs:ro -v /var/run:/var/run:rw -v /sys/:/sys/:ro -v /var/lib/docker/:/var/lib/docker/:ro -p 8080:8080 --name cadvisor google/cadvisor
览器访问8080端口,CPU的使用率、内存使用率、网络吞吐量以及磁盘空间利用率
优点
缺点
跨主机容器监控
在Linux Kernel3.8以后,Linux支持6种namespace
UTS
IPC
PID
NS(MOUNT)
NET
USER
可以使用 unshare 命令感受一下namespace
对于应用进程来说,namespace实质上只是限制了‘视线’,它使用的资源(cpu、内存等)还是同其他所有进程平等竞争
Control Group,最主要作用是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。此外还能够对进程进行优先级设置、审计,以及将进程挂起和恢复等操作
在Linux中,Cgroups给用户暴露出来的操作接口是文件系统,即它以文件和目录的方式组织在/sys/fs/cgroup路径下
限制cpu
[root@docker ~]# cd /sys/fs/cgroup/
[root@docker cgroup]# cd cpu
[root@docker cpu]# mkdir cg
[root@docker cpu]# cd cg
[root@docker cg]# echo 20000 > cpu.cfs_quota_us
[root@docker cg]# echo 12411 > tasks
docker run -d --name nginx2 --cpu-quota 20000 nginx:v3
限制内存
[root@docker ~]# yum install -y lxcfs #安装软件
[root@docker ~]# lxcfs /var/lib/lxcfs/ & #启动服务
[root@docker ~]# docker run -itd --name centos1 -m 256m
-v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw
-v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw
-v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw
-v /var/lib/lxcfs/proc/stat:/proc/stat:rw
-v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw
-v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw centos:v1
文件系统隔离
overlay
layer的概念用到了联合文件系统(Union File System)的能力,最主要的功能是将多个不同位置的目录联合挂载(union mount)到同一个目录下
文件系统:aufs, device mapper, btrfs, overlayfs, vfs, zfs。ubuntu和centos默认overlayfs
OverlayFS将主机上两个不同位置的目录(“层”) 联合挂载到同一目录下,底层的目录叫做lowerdir(镜像层),顶层的目录为upperdir(容器层),对外展示统一视图的目录为merged
示意图
操作
读文件
写文件
创建
修改
删除
写文件永远只发生在容器层
OverlayFS挂载
overlay2
overlay驱动只工作在一个lower OverlayFS层之上,因此需要硬链接来实现多层镜像,但overlay2驱动原生地支持多层镜像(最多128层)。因此overlay2驱动在合层相关的命令(如build和commit)中性能更好,消耗更少的inode
镜像和容器的磁盘结构
/var/lib/docker/overlay2
层文件目录
l目录
lower层中
link文件
diff目录
upper层中
lower文件
diff、merged和work目录
运行容器包含的目录同样有着类似的文件和目录,且在镜像的基础上新增了两个目录
rootfs组成
只读层
读写层
init层
所有这些层最终被联合挂载到读写层中的merged目录下,表现为一个完整的操作系统+应用来供使用
Namespace信息在宿主机上是以一个文件的方式存在:/proc/进程号/ns
[root@docker ~]# docker inspect -f {{.State.Pid}} nginx
1901
[root@docker ~]# ls -l /proc/1901/ns
一个进程,可以选择加入到某个进程已有的Namespace当中,从而达到 “进入” 这个进程所在容器的目的,这正是docker exec的实现原理。这个操作所依赖的,乃是一个名叫 setns() 的 Linux 系统调用
docker网络中讲到的的container网络就是将一个容器加入到另一个容器的Network Namespace
容器进程
当容器进程被创建之后,尽管开启了Mount Namespace,但是在它执行chroot之前,容器进程一直可以看到宿主机上的整个文件系统,包括容器镜像
镜像的各个层保存在/var/lib/docker/overlay2下,在容器进程启动时,它们会被联合挂载,容器所需的rootfs就准备好了
所以只需要在rootfs准备好之后,在执行chroot之前,把Volume指定的宿主机目录(假设/home),挂载到指定的容器目录(假设/test)在宿主机上对应的目录(即/var/lib/docker/overlay2/[读写层 ID]/diff/test)上,这个Volume的挂载工作就完成了
由于执行这个挂载操作时,"容器进程”"经创建了,也就意味着此时 Mount Namespace 已经开启了。所以,这个挂载事件只在这个容器里可见。你在宿主机上,是看不见容器内部的这个挂载点的。这就保证了容器的隔离性不会被 Volume 打破
bind mount
容器的镜像操作,比如 docker commit,都是发生在宿主机空间的。而由于 Mount Namespace 的隔离作用,宿主机并不知道这个绑定挂载的存在。所以,在宿主机看来,容器中可读写层的 /test 目录始终是空的