Docker基础入门
一、初识容器
1.1 什么是Docker
- 什么是Docker
- Docker是基于Go语言开发的开源容器项目,诞生于2013年年初,最初的开发者是dotCloud公司,后来dotCloud公司改名为DockerInc。
- Docker已加入Linux基金会,遵循Apache 2.0协议,开源代码位于github/docker。
- Docker的构想是要实现“Build, Ship and Run Any App, Anywhere”,即通过对应用的封装(Packaging)、分发(Distribution)、部署(Deployment)、运行(Runtime)生命周期就行管理,达到应用组件“一次封装,到处运行”的目的,是不是与Java的虚拟机很像呢。
- Linux容器技术
- Docker的前身技术最重要的是Linux容器(Linux Containers,LXC)技术。实际上LXC技术也经历了漫长的演化,在LXC之前的相关技术已经十分成熟和稳定,但是由于种种原因导致它们并没有被集成到Linux内核中。后来LXC项目借鉴前人成熟的容器设计理念,基于Linux内核的特性,实现了更具扩展性的容器方案。
- 从Linux容器到Docker
- Docker提供了各种容器工具(如分发、版本、移植等),让用户可以更简单明了的管理和使用容器。
- Docker引入了分层文件系统构建和高效的镜像机制,降低了迁移的难度,极大的提高了用户的体验。
简单的讲,Docker容器可以理解为一个轻量级的沙盒(sandbox)。每个容器内运行着一个应用,不同的容器间相互隔离,容器间也可以通过网络互相通信。Docker容器的创建和停止都十分快速,几乎和创建与停止一般的应用一致。很多时候,甚至可以把Docker容器视为应用本身都没有什么问题。
1.2 为什么使用Docker
- Docker容器技术与传统虚拟机技术特性比较
特性 | 容器 | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
性能 | 接近原生 | 较弱 |
内存代价 | 很小 | 较多 |
迁移性 | 优秀 | 一般 |
硬盘使用 | 一般为MB | 一般为GB |
运行密度 | 单机支持千个容器以上 | 一般为几十个 |
隔离性 | 安全隔离 | 完全隔离 |
1.3 Docker与虚拟化
从大类上分:虚拟化技术可分为基于硬件的虚拟化和基于软件的虚拟化。
- 其中基于硬件的虚拟化技术并不多见,少数如网卡中的单根多IO虚拟化等技术。
- 基于软件的虚拟化对象所在的层次,又可以分为应用虚拟化和平台虚拟化。后者可分为几个子类:
– 1. 完全虚拟化,如VMware、Workstation等;
– 2. 硬件辅助虚拟化,如VMware、Workstation等;
– 3. 部分虚拟化,只针对部分硬件虚拟化,客户操作系统需要进行修改;
– 4. 准虚拟化,部分硬件接口以软件的形式提供给客户操作系统;
– 5. 操作系统级虚拟化,Docker及其他容器技术都属于操作系统级虚拟化
二、核心概念与安装
三大核心概念:
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
2.1 核心概念
- Docker镜像 类似于虚拟机镜像,可以理解为一个只读的模板。举例:一个镜像可包含一个基本的操作系统,里面只安装了一个应用程序。镜像是容器创建的基础。
- Docker容器 Docker利用容器运行和隔离应用。容器是从镜像创建运行的实例。可以启动、停止、创建和删除,这些容器是隔离互不可见的。
- 镜像本身是只读的。容器通过镜像创建启动后,会在镜像最上层创建一个可写层。
- Docker仓库 类似于代码仓库,是Docker集中存放镜像文件的场所。分为共有仓库和私有仓库两种形式。官方提供的为Docker Hub。其与Git仓库是不是很相似,实际上Docker Hub借鉴了Git的很多优秀思想。
2.2 安装Docker
这里只介绍在Centos操作系统上安装。
要求:64位操作系统,至少3.10的内核,目前Docker支持Centos6.5及以上的版本,推荐使用Centos7系统。
卸载旧版本
如果已安装旧版本(旧版本称为docker或docker-engine),请卸载它们以及相关的依赖。
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装 Docker Engine-Community
设置仓库
在新主机上安装Docker Engine-Community前,需要先设置Docker仓库。
$ 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
安装 Docker Engine-Community
安装最新版的Docker Engine-Community。
$ sudo yum install docker-ce docker-ce-cli containerd.io
或者安装特定版本。
1、列出并排序存储的Docker Engine-Community的可用版本(以下只列出部分可用版本)。
$ yum list docker-ce --showduplicates | sort -r
可安装的软件包
docker-ce.x86_64 3:19.03.5-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.4-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.3-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.2-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.1-3.el7 docker-ce-stable
docker-ce.x86_64 3:19.03.0-3.el7 docker-ce-stable
docker-ce.x86_64 3:18.09.9-3.el7 docker-ce-stable
2、通过完整的软件名与版本号安装,例如docker-ce-19.03.5。
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
验证Docker安装是否完成。
$ docker -v
Docker version 1.13.1, build 7f2769b/1.13.1
三、使用Docker镜像
本节围绕Docker镜像这一核心概念的具体操作,包括如何使用pull命令从Docker Hub仓库下载镜像到本地,如何查看本地已有的镜像和管理镜像标签,如何使用search命令进行搜索和过滤,如何删除镜像标签和镜像文件,如何创建用户定制的镜像并且保存外部文件。
3.1 获取镜像
可以使用docker pull命令(格式为 docker pull NAME [ : tag ] )从Docker Hub镜像源来获取镜像。其中NAME为镜像名,tag为镜像的标签。不指定tag的话会默认指定为latest标签,即拉取最新版本的镜像。
- 例如获取一个Ubuntu系统的镜像可以使用如下命令:
$ docker pull ubuntu:13.10
13.10: Pulling from library/ubuntu
6599cadaf950: Pull complete
23eda618d451: Pull complete
f0be3084efe9: Pull complete
52de432f084b: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:15b79a6654811c8d992ebacdfbd5152fcf3d165e374e264076aa435214a947a3
Status: Downloaded newer image for ubuntu:13.10
从下载过程中可以看出,镜像文件一般由若干层组成,而6599cadaf950这样的id是对镜像文件的唯一标识。(是否会想到镜像,在使用不同镜像仓库服务器时可能会出现镜像重名的问题,严格的讲,镜像仓库名称还可以添加仓库地址。)。
3.2 查看镜像信息
- 使用images命令列出所以镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockerfile/tomcat latest 343c96175452 8 hours ago 637 MB
centos/tomcat latest 43c73b1b79c1 11 hours ago 1.37 GB
docker.io/mysql latest ed1ffcb5eff3 4 days ago 456 MB
docker.io/centos latest 0f3e07c0138f 3 months ago 220 MB
docker.io/kubeguide/guestbook-php-frontend latest 47ee16830e89 3 years ago 510 MB
docker.io/kubeguide/redis-master latest 405a0b586f7e 4 years ago 419 MB
docker.io/kubeguide/guestbook-redis-slave latest e0c36a1fa372 4 years ago 110 MB
从列出的信息可以看出,一个镜像来自于哪个仓库(REPOSITORY),镜像的标签信息(TAG),镜像的ID(唯一标识镜像),创建时间(CREATED),镜像大小(SIZE,优秀的镜像体积一般都很小)。
- 使用tag命令添加镜像标签
$ docker tag dockerfile/tomcat wlf/tomcat
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockerfile/tomcat latest 343c96175452 8 hours ago 637 MB
wlf/tomcat latest 343c96175452 8 hours ago 637 MB
centos/tomcat latest 43c73b1b79c1 11 hours ago 1.37 GB
docker.io/mysql latest ed1ffcb5eff3 4 days ago 456 MB
docker.io/centos latest 0f3e07c0138f 3 months ago 220 MB
docker.io/kubeguide/guestbook-php-frontend latest 47ee16830e89 3 years ago 510 MB
docker.io/kubeguide/redis-master latest 405a0b586f7e 4 years ago 419 MB
docker.io/kubeguide/guestbook-redis-slave latest e0c36a1fa372 4 years ago 110 MB
通过tag命令添加后在使用images可以看到多了一个wlf/tomcat的镜像文件。仔细观察可以看出wlf/tomcat与dockerfile/tomcat的ID是一致的,其实它们指向的是同一个镜像文件,只是别名不同而已。
- 使用history命令查看镜像历史
例如查看dockerfile/tomcat的创建过程,可以使用如下命令:
$ docker history dockerfile/tomcat:latest
IMAGE CREATED CREATED BY SIZE COMMENT
343c96175452 8 hours ago /bin/sh -c #(nop) CMD ["/opt/module/apach... 0 B
9cb00c97a997 8 hours ago /bin/sh -c #(nop) EXPOSE 8080/tcp 0 B
082a0485b513 8 hours ago /bin/sh -c #(nop) ENV PATH=/usr/local/sbi... 0 B
eaf1d01bdea5 8 hours ago /bin/sh -c #(nop) ENV CATALINA_HOME=/opt/... 0 B
547a7b24a9ac 8 hours ago /bin/sh -c #(nop) ENV JAVA_HOME=/opt/modu... 0 B
1ba4db4332ae 8 hours ago /bin/sh -c #(nop) ADD dir:e158d16aa7498d6b... 14.6 MB
94ba0b927ca0 8 hours ago /bin/sh -c #(nop) ADD dir:016323714f2d60f5... 403 MB
e02fd5608849 8 hours ago /bin/sh -c mkdir -p /opt/module 0 B
8122b8fa6dfb 8 hours ago /bin/sh -c #(nop) LABEL maintains=wanglin... 0 B
0f3e07c0138f 3 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 3 months ago /bin/sh -c #(nop) LABEL org.label-schema.... 0 B
<missing> 3 months ago /bin/sh -c #(nop) ADD file:d6fdacc1972df52... 220 MB
过长的创建命令被截断了,如果想查看输出完整的命令,可以在之前的命令加 – no-trunc选择。
3.3 搜索镜像
使用docker search命令可以搜索Docker Hub中共享的镜像文件。
- 例如搜索关键词是centos的镜像,这里只截取了部分的搜索结果。如下所示:
$ docker search centos
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/centos The official build of CentOS. 5748 [OK]
docker.io docker.io/ansible/centos7-ansible Ansible on Centos7 126 [OK]
docker.io docker.io/jdeathe/centos-ssh OpenSSH / Supervisor / EPEL/IUS/SCL Repos ... 114 [OK]
docker.io docker.io/consol/centos-xfce-vnc Centos container with "headless" VNC sessi... 103 [OK]
docker.io docker.io/centos/mysql-57-centos7 MySQL 5.7 SQL database server 66
docker.io docker.io/imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 57 [OK]
docker.io docker.io/tutum/centos Simple CentOS docker image with SSH access 45
3.4 删除镜像
- 通过标签删除镜像
使用docker rmi命令删除镜像,例如删除wlf/tomcat镜像,可以使用如下命令:
$ docker rmi wlf/tomcat
Untagged: wlf/tomcat:latest
无需担心删除wlf/tomcat镜像是否会对dockerfile/tomcat镜像有影响,当同一个镜像文件拥有多个标签时,docker rmi只删除该镜像多个标签中指定的标签,并不会影响镜像文件。但当镜像文件只剩下一个标签时,使用docker rmi命令就会彻底删除该镜像文件。
- 通过ID删除镜像
使用docker rmi命令后跟镜像ID来删除镜像文件,但是当一个镜像创建的容器存在时,镜像文件时无法被删除的,通过docker ps -a可以看到本机上的所有容器。如果需要删除镜像文件,可以先停止与该镜像相关的容器,使用docker rm 容器name命令将容器删除后再执行删除镜像的文件命令(可以通过 docker rmi -f 镜像tag/NAME 的方式强制删除,但是并不建议)。
3.5 创建镜像
一般有两种创建镜像的方式:基于已有容器创建镜像的方式和基于dockerfile方式创建镜像的方式。
- 基于已有容器创建镜像
这种方式主要使用命令docker commit(格式为 docker commit [OPTIONS] CONTAINER [REPOSITORY[: TAG]]),其中OPTIONS主要包括: - -a “作者信息”
- -c “dockerfile指令”
- -m “提交消息”
- -p “提交时暂停容器运行 ”
举例说明创建一个新镜像:首先利用docker run -it docker.io/centos bash启动镜像并在其中修改,创建一个test文件,之后退出:
$ docker run -it docker.io/centos bash
[root@95a7802eb2a7 /]$ touch test
[root@95a7802eb2a7 /]$ exit
之后执行docker commit命令提交一个新镜像。
$ docker commit -m "Add a new file" -a "wanglinfan" 95a7802eb2a7 test:0.1
3.6 上传镜像
可以使用docker push命令上传镜像到官方仓库,命令格式为:
docker push NAME [ : TAG ] | [ REGISTRY_HOST [ :REGISTRY_PORT ] / ] NAME [ : TAG] |
$ docker push wanglinfan/ubuntu-vim
The push refers to a repository [docker.io/wanglinfan/ubuntu-vim]
Sending image list
Please login prior to push:
Username:
Password:
Email: