Docker是一个用于开发,交付和运行应用程序的开放平台。html
对于开发人员 - Build Once, Run Anywherelinux
容器意味着环境隔离和可重复性。开发人员只需为应用建立一次运行环境,而后打包成容器即可在其余机器上运行。另外,容器环境与所在的 Host 环境是隔离的,就像虚拟机同样,但更快更简单。web
对于运维人员 - Configure Once, Run Anythingdocker
只须要配置好标准的 runtime 环境,服务器就能够运行任何容器。这使得运维人员的工做变得更高效,一致和可重复。容器消除了开发、测试、生产环境的不一致性。apache
Docker 容器的运行不须要额外的 hypervisor 支持,它是内核级的虚拟化,所以能够实现更高的性能和效率。json
Docker 容器几乎能够在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、我的电脑、服务器等。 这种兼容性可让用户把一个应用程序从一个平台直接迁移到另一个。ubuntu
使用 Docker,只须要小小的修改,就能够替代以往大量的更新工做。全部的修改都以增量的方式被分发和更新,从而实现自动化而且高效的管理。centos
服务器是一种长期运行的程序,称为守护程序进程( dockerd命令)。浏览器
REST API,它指定程序能够用来与守护程序进行通讯并指示其操做的接口。安全
CLI使用Docker REST API经过脚本或直接CLI命令来控制Docker守护程序或与Docker守护程序进行交互。
许多其余Docker应用程序都使用基础API和CLI。
Docker 使用C/S (客户端/服务器)体系的架构,Docker 客户端与 Docker 守护进程通讯,Docker 守护进程负责构建,运行和分发 Docker 容器。Docker 客户端和守护进程能够在同一个系统上运行,也能够将 Docker 客户端链接到远程 Docker 守护进程。Docker 客户端和守护进程使用 REST API 经过UNIX套接字或网络接口进行通讯。
Docker Damon:dockerd,用来监听 Docker API 的请求和管理 Docker 对象,好比镜像、容器、网络和 Volume。
Docker Client:docker client 是咱们和 Docker 进行交互的最主要的方式方法,好比咱们能够经过 docker run 命令来运行一个容器,而后咱们的这个 client 会把命令发送给上面的 Dockerd,让他来作真正事情。
Docker Registry:用来存储 Docker 镜像的仓库,Docker Hub 是 Docker 官方提供的一个公共仓库,并且 Docker 默认也是从 Docker Hub 上查找镜像的,固然你也能够很方便的运行一个私有仓库,当咱们使用 docker pull 或者 docker run 命令时,就会从咱们配置的 Docker 镜像仓库中去拉取镜像,使用 docker push 命令时,会将咱们构建的镜像推送到对应的镜像仓库中。
Images:镜像是一个只读模板,带有建立 Docker 容器的说明,通常来讲的,镜像会基于另外的一些基础镜像并加上一些额外的自定义功能。好比,你能够构建一个基于 Centos 的镜像,而后在这个基础镜像上面安装一个 Nginx 服务器,这样就能够构成一个属于咱们本身的镜像了。
Containers:容器是一个镜像的可运行的实例,可使用 Docker REST API 或者 CLI 来操做容器,容器的实质是进程,但与直接在宿主机执行的进程不一样,容器进程运行于属于本身的独立的命名空间。所以容器能够拥有本身的 root 文件系统、本身的网络配置、本身的进程空间,甚至本身的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操做同样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
Docker用Go编写、Namespaces(作隔离)、CGroups(作资源限制)、UnionFS(镜像和容器的分层) the-underlying-technology Docker 底层架构分析
直接前往官方文档选择合适的平台安装便可,好比咱们这里想要在centos系统上安装 Docker,这前往地址https://docs.docker.com/install/linux/docker-ce/centos/根据提示安装便可。
安装所需的软件包
sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
添加软件仓库,咱们这里使用稳定版 Docker,执行下面命令添加 yum 仓库地址:
sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce
$ sudo systemctl enable docker $ sudo systemctl start docker
[root@localhost ~]# docker version Client: Docker Engine - Community Version: 19.03.4 API version: 1.40 Go version: go1.12.10 Git commit: 9013bf583a Built: Fri Oct 18 15:52:22 2019 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.4 API version: 1.40 (minimum version 1.12) Go version: go1.12.10 Git commit: 9013bf583a Built: Fri Oct 18 15:50:54 2019 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.2.10 GitCommit: b34a5c8af56e510852c35414db4c1f4fa6172339 runc: Version: 1.0.0-rc8+dev GitCommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657 docker-init: Version: 0.18.0 GitCommit: fec3683 [root@localhost ~]#
环境就绪,立刻运行第一个容器,执行命令:
docker run -d -p 80:80 httpd 第一次须要下载镜像 可能比较慢 这就须要作镜像加速
国内从 Docker Hub 拉取镜像有时会遇到困难,此时能够配置镜像加速器
对于使用 systemd 的系统,请在 /etc/docker/daemon.json 中写入以下内容(若是文件不存在请新建该文件) { "registry-mirrors": [ "https://dockerhub.azk8s.cn", "https://reg-mirror.qiniu.com" ] } 注意,必定要保证该文件符合 json 规范,不然 Docker 将不能启动。 以后从新启动服务
[root@localhost docker]# docker info |grep Registry -A 10 Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://dockerhub.azk8s.cn/ https://reg-mirror.qiniu.com/ Live Restore Enabled: false
[root@muyudembp ~]# docker run ubuntu:16.04 /bin/echo 'Hello world' Unable to find image 'ubuntu:16.04' locally 16.04: Pulling from library/ubuntu e80174c8b43b: Pull complete d1072db285cc: Pull complete 858453671e67: Pull complete 3d07b1124f98: Pull complete Digest: sha256:bb5b48c7750a6a8775c74bcb601f7e5399135d0a06de004d000e05fd25c1a71c Status: Downloaded newer image for ubuntu:16.04 Hello world [root@muyudembp ~]# docker run ubuntu:16.04 /bin/echo 'Hello world' Hello world
[root@muyudembp ~]# docker history ubuntu:16.04 IMAGE CREATED CREATED BY SIZE COMMENT 5f2bf26e3524 Less than a second ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> Less than a second ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B <missing> Less than a second ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 745B <missing> Less than a second ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0B <missing> Less than a second ago /bin/sh -c #(nop) ADD file:9511990749b593a6f… 123MB
[root@muyudembp ~]# docker run -it ubuntu:16.04 /bin/bash root@247c977ce6dc:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@247c977ce6dc:/#
[root@muyudembp ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 247c977ce6dc ubuntu:16.04 "/bin/bash" 7 minutes ago Up 7 minutes youthful_hamilton 6fe5c402d589 httpd "httpd-foreground" 5 hours ago Up 5 hours 0.0.0.0:80->80/tcp sad_dijkstra [root@muyudembp ~]# docker stop 6fe5c402d589 6fe5c402d589 [root@muyudembp ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 247c977ce6dc ubuntu:16.04 "/bin/bash" 7 minutes ago Up 7 minutes youthful_hamilton [root@muyudembp ~]# docker start 6fe5c402d589 6fe5c402d589 [root@muyudembp ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 247c977ce6dc ubuntu:16.04 "/bin/bash" 7 minutes ago Up 7 minutes youthful_hamilton 6fe5c402d589 httpd "httpd-foreground" 5 hours ago Up 1 second 0.0.0.0:80->80/tcp sad_dijkstra [root@muyudembp ~]# docker rm 247c977ce6dc Error response from daemon: You cannot remove a running container 247c977ce6dcc47e043b4d9ef02c95b4d7d21e32009bff425314724315e4bea4. Stop the container before attempting removal or force remove 强制关闭在运行的容器 [root@muyudembp ~]# docker rm -f 247c977ce6dc 247c977ce6dc [root@muyudembp ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6fe5c402d589 httpd "httpd-foreground" 5 hours ago Up 2 minutes 0.0.0.0:80->80/tcp sad_dijkstra
[root@muyudembp ~]# docker rmi -f 5f2bf26e3524 Untagged: ubuntu:16.04 Untagged: ubuntu@sha256:bb5b48c7750a6a8775c74bcb601f7e5399135d0a06de004d000e05fd25c1a71c Deleted: sha256:5f2bf26e35249d8b47f002045c57b2ea9d8ba68704f45f3c209182a7a2a9ece5 [root@muyudembp ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE httpd latest d3017f59d5e2 17 hours ago 165MB
镜像是容器的基础,每次执行docker run的时候都会指定哪一个镜像做为容器运行的基础。在以前的例子中,咱们所使用的都是来自于 Docker Hub 的镜像。直接使用这些镜像是能够知足必定的需求,而当这些镜像没法直接知足需求时,咱们就须要定制这些镜像。
如今让咱们用httpd镜像作个示例。
docker run --name webserver -d -p 80:80 httpd
这条命令会用 httpd 镜像启动一个容器,命名为 webserver,而且映射了 80 端口,这样咱们能够用浏览器去访问这个 web 服务器。
[root@muyudembp ~]# curl localhost <html><body><h1>It works!</h1></body></html> [root@muyudembp ~]# docker exec -it 543f2ad89f8e /bin/bash root@543f2ad89f8e:/usr/local/apache2# echo "<h1>Hello, Docker!</h1>" > /usr/local/apache2/htdocs 退出容器 [root@muyudembp ~]# curl localhost <h1>Hello, Docker!</h1> 咱们能够用下面的命令将容器保存为镜像: [root@muyudembp ~]# docker commit \ > --author "muyu" \ > --message "修改了默认首页" \ > webserver \ > httpd:v2 sha256:229d8c3a7577be285e858f80c1e97dad5ddfb604fbcd5b4f1b3ad4fa40935712 [root@muyudembp ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE httpd v2 229d8c3a7577 11 seconds ago 165MB httpd latest d3017f59d5e2 17 hours ago 165MB [root@muyudembp ~]# docker history 229d8c3a7577 IMAGE CREATED CREATED BY SIZE COMMENT 229d8c3a7577 About a minute ago httpd-foreground 31B 修改了默认首页 d3017f59d5e2 17 hours ago /bin/sh -c #(nop) CMD ["httpd-foreground"] 0B <missing> 17 hours ago /bin/sh -c #(nop) EXPOSE 80 0B <missing> 17 hours ago /bin/sh -c #(nop) COPY file:c432ff61c4993ecd… 138B <missing> 17 hours ago /bin/sh -c #(nop) STOPSIGNAL WINCH 0B <missing> 17 hours ago /bin/sh -c set -eux; savedAptMark="$(apt-m… 60.7MB <missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PATCHES= 0B <missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_SHA256=133d4829… 0B <missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_VERSION=2.4.41 0B <missing> 2 weeks ago /bin/sh -c set -eux; apt-get update; apt-g… 35.4MB <missing> 2 weeks ago /bin/sh -c #(nop) WORKDIR /usr/local/apache2 0B <missing> 2 weeks ago /bin/sh -c mkdir -p "$HTTPD_PREFIX" && chow… 0B <missing> 2 weeks ago /bin/sh -c #(nop) ENV PATH=/usr/local/apach… 0B <missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PREFIX=/usr/loc… 0B <missing> 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 2 weeks ago /bin/sh -c #(nop) ADD file:74b2987cacab5a6b0… 69.2MB [root@muyudembp ~]# docker run --name webserver2 -d -p 81:80 httpd:v2 693745577ac0d47dc88680dff44afa3749ac88c39ad55deea1802c191bcb9542 [root@muyudembp ~]# curl localhost:81 <h1>Hello, Docker!</h1>
至此,咱们第一次完成了定制镜像,使用的是docker commit命令,手动操做给旧的镜像添加了新的一层,造成新的镜像,对镜像多层存储应该有了更直观的感受。
可是定制镜像不建议这么作 定制镜像应该使用Dockerfile来完成
容器操做:
docker create # 建立一个容器可是不启动它 docker run # 建立并启动一个容器 docker stop # 中止容器运行,发送信号SIGTERM docker start # 启动一个中止状态的容器 docker restart # 重启一个容器 docker rm # 删除一个容器 docker kill # 发送信号给容器,默认SIGKILL docker attach # 链接(进入)到一个正在运行的容器 docker wait # 阻塞一个容器,直到容器中止运行
获取容器信息:
docker ps # 显示状态为运行(Up)的容器 docker ps -a # 显示全部容器,包括运行中(Up)的和退出的(Exited) docker inspect # 深刻容器内部获取容器全部信息 docker logs # 查看容器的日志(stdout/stderr) docker events # 获得docker服务器的实时的事件 docker port # 显示容器的端口映射 docker top # 显示容器的进程信息 docker diff # 显示容器文件系统的先后变化 docker system df # 查看镜像、容器、数据卷所占用的空间。
导出容器:
docker cp # 从容器里向外拷贝文件或目录 docker export # 将容器整个文件系统导出为一个tar包,不带layers、tag等信息
执行:
docker exec # 在容器里执行一个命令,能够执行bash进入交互式
镜像操做:
docker images # 显示本地全部的镜像列表 docker import # 从一个tar包建立一个镜像,每每和export结合使用 docker build # 使用Dockerfile建立镜像(推荐) docker commit # 从容器建立镜像 docker rmi # 删除一个镜像 docker load # 从一个tar包建立一个镜像,和save配合使用 docker save # 将一个镜像保存为一个tar包,带layers和tag信息 docker history # 显示生成一个镜像的历史命令 docker tag # 为镜像起一个别名
镜像仓库(registry)操做:
docker login # 登陆到一个registry docker search # 从registry仓库搜索镜像 docker pull # 从仓库下载镜像到本地 docker push # 将一个镜像push到registry仓库中