Docker 使用教程
概括
Docker与传统虚拟机的区别 与传统虚拟机的区别
Docker的安装 的安装
Docker daemon , client , containerd
镜像与容器操作
容器运行配置
Docker网络配置 网络配置
Alpine Docker Image
制作自己的 Docker Image
Docker安全性问题 安全性问题
Docker运行原理
Docker与传统虚拟机的区别
Docker 容器的隔离性
Linux 内核的 cgroup,namespace,以及 AUFS类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器.
与传统虚拟机相比的优点
Docker在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等
等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便.
Docker的安装
• 系统要求
Docker 目前只支持64位系统,支持Linux, Cloud, Windows, and macOS系统。
添加Docker官方APT镜像源(Debian Linux)
由于Docker官方源使用的时HTTPS,要添加HTTPS传输的软件包和CA证书
操作如下:
sudo apt-get install apt-transport-https ca-certificates
sudo apt-key adv –keyserver hkp://p80.pool.sks-keyservers.net:80 –recv-keys
58118E89F3A912897C070ADBF76221572C52609D
将源地址 https://apt.dockerproject.org/repo debian-Jessie 加入/etc/apt/sources.list文件
apt-get update
apt-get install docker-engine
修改GRUB引导文件
当Docker 容器启动参数添加一些限制时(如内存,CPU),会有警告不支持,因为内核启动时没有这个参数的支持,可以修改grub启动配置文件/etc/default/grub 在GRUB_CMDLINE_LINUX 添加 内核引导参数cgroup_enable=memory swapaccount=1 运行update-grub 更新grub 重启即可。
Docker daemon,client,containerd
Docker daemon
Docker daemon是Docker最核心的后台进程,它负责响应来自Docker client的请求,然后将这些请求翻译成系统调用完成容器管理操作。该进程会在后台启动一个API Server,负责接收由Docker client发送的请求;接收到的请求将通过Docker
daemon内部的一个路由分发调度,再由具体的函数来执行请求;管理所有的 Docker containers 和 Docker images。可以通过service或systemctl管理docker服务。
Docker daemon监听三种不同的套接字 : unix,tcp,fd 来处理docker client的请求,其中的unix域套接字表示仅支持主机自身的client请求, tcp表示支持remote client,fd表示systemd socket一般情况下拥有systemd的都以此工作(Debian)。Docker deamon的配置文件可以指定配置哪种监听方式,这三种方式可以同时存在。
/etc/systemd/system/docker.service.d/docker.conf 在Debian 默认不存在要手动创建,可参考https://docs.docker.com/engine/admin/systemd/
Docker client
Docker client是一个泛称,用来向指定的Docker daemon发起请求,执行相应的容器管理操作.它既可以是Docker命令行工具,也可以是任何遵循了Docker API的客户端.目前, 社区中维护着的Docker client种类非常丰富,涵盖了包括C#(支持
Windows)、Java、Go、Ruby、JavaScript等常用语言,甚至还有使用Angular库编写的WebU格式的客户端,足以满足大多数用户的需求。即docker command 就是一个客户端,它可以连接本地Docker daemon操作镜像和容器,又可以管理远程
的。
Docker run ImageID command 运行本地的Docker Image
Docker –H IP:Port run ImageID command 运行远程的Docker Image
docker-containerd
Containerd是一个简单的守护进程,它可以使用runC管理容器,使用gRPC暴露容器的其他功能。相比较Docker引
擎,使用gRPC,containerd暴露出针对容器的增删改查的接口,然而Docker引擎只是使用full-blown HTTP API接口对Images、Volumes、network、builds等暴露出这些方法。
镜像与容器操作
• 镜像操作
a) 获取镜像: docker search , pull 代理配置http_proxy.conf
b) 列出镜像: docker images 悬浮镜像仓库名为 docker images -f dangling=true
c) 删除镜像: 要删除一个镜像 必须是没有此镜像的容器在运行 . docker rmi $(docker images -f dangling=true)删除悬浮镜像
d) Dockerfile定制镜像:docker build –t Image:ID https://yeasy.gitbooks.io/docker_practice/content/image/build.html
e) 保存镜像:docker save 保存镜像为一个tar文件
f) 加载镜像:docker load 加载一个保存的镜像
g) 镜像重命名:docker tag
• 容器操作
a) 启动容器: docker run image command 新建并启动容器 docker start 启动已终止的容器 –name 可以给容器起一个名字
b) 查看容器: docker ps -a 查看所有容器 docker ps –a –q 查看所有已退出的容器
c) 以守护态运行:docker run –d
d) 进入容器:docker attach 进入守护态的容器
e) 终止容器:docker stop containerID 终止指定容器
f) 查看容器的运行状态:docker stats 查看容器的状态 CPU 内存消耗等
g) 删除容器:docker rm 删除一个已退出的容器 docker rm $(docker ps –a -q)删除所有已退出的容器
h) 容器的导出与导入:docker import 和 docker export
i) https://yeasy.gitbooks.io/docker_practice/content/container/
导入导出容器与镜像的区别
用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信
息。
镜像和容器的存储
对于Debian docker image来讲,当前所有image 信息/var/lib/docker/image/aufs/repositories.json Image以分层的方式存放在/var/lib/docker/aufs中,容器启动过程中将这些内容以aufs挂载在同一个目录形成根文件系统。
容器运行配置
网络接入类型:–net
资源限制: -m 内存限制 docker run –help
端口映射: -p 将宿主机的端口或固定ip和端口映射到容器的某个端口
数据卷 : -v 实现宿主机和容器之间的目录映射
容器运行时内核参数配置:文件描述符–nofile
Daemon配置
[Service]
ExecStart=/usr/bin/dockerd -H fd:// -D –tls=true –tlscert=/var/docker/server.pem–tlskey=/var/docker/serverkey.pem-H
tcp://
配置完成后 运行 systemctl daemon-reload 执行 systemctl restart docker。
制作自己的 Docker Image
制作文件系统
a) 使用initramfs命令制作一个虚拟文件系统或者直接使用/boot 里面的initrd文件系统
b) 将文件系统打包为tar格式,docker load 并指定仓库名即可
添加binary到docker image简易方式
将docker image export,并解包
利用chroot来切换根文件系统 chroot . sh
将binary 拷贝到其目录就可以执行测试这种执行方式
以上和docker run执行没有很大差别。
Docker安全性问题 安全性问题
Docker run –privileged的危害
当docker image运行的时候, 有时我们需要修改网络,内核配置参数等,这些配置的修改都需要特权,因为docker 并不像传统虚拟机虚拟设备,也就是说与宿主机共用设备,拿硬盘来说,容器里也有/dev/sda这个设备,以特权运行的话,就可挂载这个设备,从而脱离docker image。
制作Docker Image细节
如若使用/boot/下的initrd文件系统, 要把里面的init或linuxrc删除,因为init的作用就是挂载真实的根文件系统,寻找并执行/sbin/init开启init进程。剔除权限过大的binary 如mkfs,mount,chroot,switch-root等
Docker运行原理 运行原理
Linux kernel namespace:
Docker 容器和chroot的差别在于Docker 容器提供了更多的资源的隔离性包括网络,主机名域名,用户和用户组。Linux Namespaces机制提供一种资源隔离方案。容器就是利用这个机制在创建子进程的时候,继承父进程的资源后,将PCB(进程控制块包含进程的所有信息)里面的ns结构体进行填充。利用strace工具可以追踪dockerd系统调用。
strace 追踪系统调用发现clone 创建新进程。
Cgroup:上述Linux namespace 只是实现的docker的环境上的隔离,要实现计算机资源上的隔离就要用到cgroup, 它可以实现CPU 内存磁盘I/O等的限制。
Aufs:所谓UnionFS就是把不同物理位置的目录合并mount到同一个目录中。
例如 mount-t aufs-o dirs=./g:./h none ./mnt就把g h俩个目录挂载到了mnt目录。
详情参考:
http://www.infoq.com/cn/articles/docker-kernel-knowledge-namespace-resource-isolation
http://blog.chinaunix.net/uid-20788636-id-4479145.html