Docker 是一个开源的应用容器引擎,基于 Go 语言开发 遵从 Apache 2.0 协议开源。
Docker 可以让用户打包应用以及依赖到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。Docker 是一个横跨 IaaS 和 PaaS 层的项目。
Docker 起源于 2010 年创业的一家叫作 dotCloud 的美国公司,dotCloud 早期是基于LXC技术的 PaaS 平台,它的理念是提供跨底层 IaaS 云、支持多种开发语言的开发云平台。但随着越来越多的公有云服务商进入,dotCloud 的理念很难依靠一家公司专有的技术实现。于是 dotCloud 的创始人在 LXC 的基础上,对容器技术进行了简化和标准化,命名为 Docker。
2013年3月,因 PaaS 市场发展缓慢,创始人 Solomon Hykes 决定放手一搏,将 Docker 项目开源同时推出了开放容器项目(OCP),Docker 和 Docker 开源社区随后迅速火起来。
2013 年 10 月 29 日,dotCloud 公司更名为 Docker 公司。目前,Docker已经成为发展最快的容器技术。
Docker 将软件所需的依赖及程序本体构建为一个独立镜像,可以在任何部署了 Docker 的 Linux 服务器上运行,减轻了运维人员的部署难度及跨系统的依赖问题。
容器与虚拟化
容器与虚拟化不同,容器使用完全沙箱机制,容器与容器相互之间不会有任何影响,更重要的是容器的性能开销极低。简单可以理解为容器是在隔离的环境运行的一个进程,如果进程被停止,容器就会销毁。
而虚拟化则需要一定的硬件支持,比如 KVM 虚拟化只能基于 Linux 内核(对版本有一定要求)进行虚拟化。并且虚拟化是完整虚拟化,会虚拟化出完整的一套系统,因此启动虚拟机需要走一遍完整的系统启动流程,消耗的时间比较久(相对于容器来说)。
容器的特性
- 容器与宿主机使用同一个内核,性能损耗小;
- 容器不需要指令级模拟;
- 容器可在CPU核心的本地运行指令,无需专门的解释机制;
- 避免了准虚拟化和系统调用替换中的复杂性;
- 轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。
容器的发展
- 1979年 — Chroot
UNIX Chroot(change root,切换根目录)这项功能将Root目录及其它子目录变更至文件系统内的新位置,且只接受特定进程的访问,即可构建一个简易的子系统。其设计目的在于为每个进程提供一套隔离化磁盘空间。1982 年其被添加至BSD。
- 2000年 — FreeBSD Jails
FreeBSD Jails 与 Chroot 的定位类似,不过其中包含有进程沙箱机制以对文件系统、用户及网络等资源进行隔离。通过这种方式,它能够为每个 Jail、定制化软件安装包乃至配置方案等提供一个对应的IP地址。Jails 技术为 FreeBSD 系统提供了一种简单的安全隔离机制。它的不足在于这种简单性的隔离也同时会影响 Jails 中应用访问系统资源的灵活性。
- 2004年 — Solaris Zones
Solaris Zone 技术为应用程序创建了虚拟的一层,让应用在隔离的 Zone (空间)中运行,并实现有效的资源管理。每一个 Zone 拥有自己的文件系统,进程空间,防火墙,网络配置等。Solaris Zone 技术真正的引入了容器资源管理的概念。在应用部署的时候为 Zone 配置一定的资源,在运行中可以根据 Zone 的负载动态修改这个资源限制并且是实时生效的,在其他Zone不需要资源的时候,资源会自动切换给需要的资源的Zone,这种切换是即时的不需要人工干预的,最大化资源的利用率,在必要的情况下,也可以为单个 Zone 隔离一定的资源。
- 2008年 — LXC
LXC (Linux Containers,Linux 容器),其通过 cgroups 以及 Linux Namespaces 实现。也是第一套完整的 Linux 容器管理实现方案。在 LXC 出现之前,Linux 上已经有了类似 Linux-Vserver 、OpenVZ 和 FreeVPS。虽然这些技术都已经成熟,但是这些解决方案还没有将容器支持集成到主流 Linux 内核。相较于其它容器技术,LXC 能够在无需任何额外补丁的前提下运行在原版 Linux 内核之上。目前 LXC 项目由 Canonical 有限公司负责赞助及托管。
- 2013年 — Docker
Docker 项目最初是由一家名为 DotCloud 的平台即服务厂商所打造,其后该公司更名为Docker。Docker在起步阶段使用 LXC,而后利用自己的 Libcontainer 库将其替换下来。与其它容器平台不同,Docker引入了一整套与容器管理相关的生态系统。其中包括一套高效的分层式容器镜像模型、一套全局及本地容器注册表、一个精简化REST API以及一套命令行界面等等。
Docker 入门
安装 Docker
本文环境为 CentOS 7 ,部署 Docker 需要先安装 EPEL 源。
# yum install epel-release -y
从清华源获取 REPO 文件
# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
替换源地址为国内源(大陆使用可提速及提高稳定性)
# sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
安装 Docker CE (社区版)
# yum install docker-ce -y
优化镜像拉取地址
# cat >> /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF
官方部署方法
此部分教程为额外内容,若主机是国外主机,请使用此方式部署,国内主机对此源的连通性较差,推荐使用上方的国内源进行部署。
配置依赖
$ sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
添加仓库
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
其他选项
test 为测试分支,edge 为先锋分支(最新特性)。
$ sudo yum-config-manager --enable docker-ce-edge
$ sudo yum-config-manager --enable docker-ce-test
安装社区版
$ sudo yum install docker-ce
小贴士:仅推荐开发及测试环境使用 edge 及 test 分支。
Docker 命令
执行 docker 命令前需要将 docker 启动,否则会报错,因为 docker 也是一个标准的 C/S 架构。
# systemctl enable docker
# systemctl start docker
基础命令
检查 Docker 版本信息,会列出引擎的详细信息。
[root@docker01 ~]# docker version
Client:
Version: 18.09.0
API version: 1.39
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:48:22 2018
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.0
API version: 1.39 (minimum version 1.12)
Go version: go1.10.4
Git commit: 4d60db4
Built: Wed Nov 7 00:19:08 2018
OS/Arch: linux/amd64
Experimental: false
检查 Docker 信息
[root@docker01 ~]# docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 4
Server Version: 18.09.0
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: c4446665cb9c30056f4998ed953e6d4ff22c7c39
runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-862.14.4.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 1.936GiB
Name: docker01
ID: NIDN:RIAL:XLUR:DUQP:FQSQ:BNBI:KHXJ:5ELK:3DA6:NHN4:2AZC:66AI
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine
小贴士:此命令会展示出 docker 详细的信息,包括镜像数量及启动的容器信息等,因此一般用于监控使用。
镜像相关命令
# docker image search 检索镜像
# docker image pull 拉取镜像
# docker image ls 镜像列表
# docker image save 导出镜像
# docker image load 导入镜像
# docker image rm 删除镜像
# docker image inspect 镜像信息
# docker image build 构建镜像
容器相关命令
# docker container run 运行容器
# docker container ps 容器列表
# docker container exec 进入容器
# docker container stop 停止容器
# docker container kill 杀死容器
# docker container start 启动容器
# docker container rm 删除容器
# docker container inspect 容器信息
# docker container update 更新容器
Docker 实例
拉取一个镜像
# docker image pull centos:6.9
使用此命令即可从仓库拉取某个版本的 centos 镜像,若省略冒号及后面的版本号则默认拉取最新版 latest 。
拉取一个 NGINX 镜像
# docker image pull nginx
启动第一个容器
# docker run -d -p 80:80 nginx
小贴士:-d
放在后台-p
端口映射,冒号分割外部内部端口,最后指定镜像的名。
容器的镜像管理
# docker search IMAGE_NAME
小贴士:IMAGE_NAME 替换为需要搜索的镜像名,选择镜像的原则,有官方优先官方,其次考虑星星(点赞)多的。
已存在的镜像列表
# docker image list
或者可以使用(推荐)
# docker images
删除已存在的镜像
# docker image rm
或者可以使用(推荐)
# docker rmi
导出本地的镜像
# docker image save centos > docker_centos.tar.gz
小贴士:docker image save 可以简写为 docker save
导入本地镜像
# docker image load -i docker_centos.tar.gz
容器运行参数
# docker container run -it --name centos6 centos:6.9 /bin/bash
小贴士:-it
分配交互式终端,--name
指定容器名字,/bin/bash
指定命令解析器覆盖初始命令,部分镜像的基础镜像为精简镜像,因此请使用/bin/sh
。
docker run 命令等同于创建容器实例并启动(docker create + docker start)
停止容器
# docker container stop CONTAINER_ID
杀死容器(强制)
# docker container kill CONTAINER_ID
容器列表
# docker container ps
小贴士:在此容器系列的命令中,中间的 container 可以省略,之后的全部命令会默认省略 container。此命令仅会显示存活的容器,添加-a
参数即可显示全部的容器(包括已经退出的容器)。
即:
# docker ps -a
小贴士:其他有实际作用的参数还有 -q
仅显示容器 ID。
进入容器(大部分情况下为了排错)
# docker exec -it CONTAINER_ID /bin/bash
小贴士:使用 -it
分配交互式终端,CONTAINER_ID 可以使用 ID 或者 NAME,最后指定命令解释器。
# docker attach CONTAINER_ID
小贴士:此命令会共享同一个终端,因此不推荐使用。
注意:进入容器后不可使用 CTRL+D 退出或者输入 exit 命令进行退出,会导致容器退出,请使用 CTRL+P+Q 进行容器挂起。
删除容器
# docker rm -f CONTAINER_ID
小贴士:-f
参数为force
为强制删除,可以移除失去响应的容器。
删除全部容器
# docker rm -f `docker ps -a -q`
总结:容器内的第一个进程必须一直处于前台运行的状态(必须 HANG 住),否则这个容器执行完毕命令就会处于退出状态(瞬间完成并退出)!
容器的网络访问
# docker container run -d -p 80:80 nginx
小贴士:容器的网络是建立在容器内部的,类似于沙箱,因此容器想对外开放端口需要对外进行映射,映射使用的是NAT
(iptables)方式,-P
为随机映射。
容器的数据卷管理
# docker container run -d -p 80:80 -v /opt/html:/var/www/html nginx
数据卷(文件或目录)
-v /data
-v src(宿主机的目录):dst(容器的目录)
数据卷容器
--volumes-from
将容器保存为本地镜像
# docker commit CONTAINER_ID/CONTAINER_NAME CONTAINER_NEW_NAME[:VERSION]
更新容器设置
# docker update --restart=always CONTAINER_ID
小贴士:若建立容器时忘记添加参数可以使用此种方式进行更新。
例子
1)基于容器制作镜像
# docker run -it centos:6.9
2)进入容器进行操作
yum install httpd
yum install openssh-server
/etc/init.d/sshd start
cat >> init.sh <<'EOF'
#!/bin/bash
/etc/init.d/httpd start
/usr/sbin/sshd -D
EOF
chmod +x /init.sh
3)查看容器的ID
# docker container ls -a
4)将容器提交为镜像
# docker commit CONTAINER_ID centos6-ssh-httpd:v1
5)测试镜像功能
扩展
说到 SystemD ,这个套件已经成为主流 Linux 发行版(比如 CentOS 7、Ubuntu 14+)默认的服务管理,取代了传统的 SystemV 服务管理。SystemD 维护系统服务程序,它需要特权去会访问 Linux 内核。而容器并不是一个完整的操作系统,只有一个文件系统,而且默认启动只是普通用户这样的权限访问 Linux 内核,也就是没有特权,所以自然就用不了!
因此,请遵守容器设计原则,一个容器里运行一个前台服务!
以特权模式运行容器即可解决此问题。
创建容器:
# docker run -d -name centos7 --privileged=true centos /usr/sbin/init
进入容器:
# docker exec -it centos /bin/bash
即可使用 systemD 启动服务
# yum install chrony
# systemctl start chronyd
Docker 构建镜像
Dockerfile 主要组成部分:
FROM:centos:6.9 基础镜像信息
RUN yum install openssh-server -y 镜像操作指令
CMD ["/bin/bash"] 容器启动执行指令
Dockerfile 常用指令:
FROM 指定基础镜像
MAINTAINER 指定维护者信息,可选
RUN 在命令前面加上RUN即可
ADD COPY文件,会自动解压
WORKDIR 设置当前工作目录
VOLUME 设置卷,挂载主机目录
EXPOSE 指定对外的端口(-P 随机端口)
CMD 指定容器启动后的要干的事情(可被替换)
Dockerfile 其他指令:
COPY 复制文件
ENV 环境变量
ENTRYPOINT 容器启动后执行的命令(无法被替换,启容器的时候指定的命令,会被当成参数)
Docker 镜像层级
容器的镜像并不是一个单纯的文件而是一个多层覆盖后的层级文件,如图例所示。
Docker 自建镜像仓库
因此众所周知的原因,官方的仓库在中国大陆下载速度很慢甚至可能失败。并且企业及个人可能有打包完的自建镜像,因此需要自建仓库进行托管,不仅可以提高下载速度还能给企业或个人提供一个私人仓库。
搭建普通的仓库(无验证)
启动一个名为 registry 镜像
# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
# docker pull busybox
10.0.0.11:5000/centos6-sshd:v3
# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.11:5000"]
}
# systemctl restart docker
docker push 10.0.0.11:5000/centos6-sshd:v3
带认证的仓库
# yum install httpd-tools -y
# mkdir /opt/registry-var/auth/ -p
# htpasswd -Bbn kane material >> /opt/registry-var/auth/htpasswd
# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
Docker 自建镜像仓库
因此众所周知的原因,官方的仓库在中国大陆下载速度很慢甚至可能失败。并且企业及个人可能有打包完的自建镜像,因此需要自建仓库进行托管,不仅可以提高下载速度还能给企业或个人提供一个私人仓库。
搭建普通的仓库(无验证)
启动一个名为 registry 镜像
# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
# docker pull busybox
10.0.0.11:5000/centos6-sshd:v3
# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.11:5000"]
}
# systemctl restart docker
docker push 10.0.0.11:5000/centos6-sshd:v3
带认证的仓库
# yum install httpd-tools -y
# mkdir /opt/registry-var/auth/ -p
# htpasswd -Bbn kane material >> /opt/registry-var/auth/htpasswd
# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
Docker 自建镜像仓库
因此众所周知的原因,官方的仓库在中国大陆下载速度很慢甚至可能失败。并且企业及个人可能有打包完的自建镜像,因此需要自建仓库进行托管,不仅可以提高下载速度还能给企业或个人提供一个私人仓库。
搭建普通的仓库(无验证)
启动一个名为 registry 镜像
# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
# docker pull busybox
10.0.0.11:5000/centos6-sshd:v3
# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"insecure-registries": ["10.0.0.11:5000"]
}
# systemctl restart docker
docker push 10.0.0.11:5000/centos6-sshd:v3
带认证的仓库
# yum install httpd-tools -y
# mkdir /opt/registry-var/auth/ -p
# htpasswd -Bbn kane material >> /opt/registry-var/auth/htpasswd
# docker run -d -p 5000:5000 --restart=always --name registry -v /opt/registry-var/auth/:/auth/ -v /opt/myregistry:/var/lib/registry -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
参考链接
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2018-11-13 10:02 AM