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 源。
sudo yum install epel-release -y
从清华源获取 REPO 文件
sudo wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
替换源地址为国内源(大陆使用可提速及提高稳定性)
sudo sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
安装 Docker CE (社区版)
sudo 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 架构。
sudo systemctl enable docker
sudo 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 启动服务
sudo yum install chrony
sudo 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 自建镜像仓库
因此众所周知的原因,官方的仓库在中国大陆下载速度很慢甚至可能失败。并且企业及个人可能有打包完的自建镜像,因此需要自建仓库进行托管,不仅可以提高下载速度还能给企业或个人提供一个私人仓库。
搭建普通的仓库(无验证)
启动一个名为 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
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2023-12-06 09:43 AM