一、基础知识与准备
1.基础知识
1)Docker runtime
runtime是容器真正运行的地方。借助JAVA中JVM的概念来理解。
lxc、runc、rkt是目前主流的三种容器runtime。
- lxc是Linux上老牌的容器runtime。Docker最初也是用lxc作为runtime的。
- runc是Docker自己开发的runtime。目前Docker的默认runtime。符合oci规范。
- rkt是CoreOS开发的容器runtime。符合oci规范,因而能够运行Docker的容器。
2)容器管理工具
lxd是lxc对应的管理工具。
runc的管理工具是Docker engine,包括后台deamon和cli两部分,我们通常提到的Docker一般就是指docker engine。
rkt的管理工具是rkt cli。
3)容器定义
docker image是Docker容器的模板,runtime根据docker image来创建容器。
dockerfile是包含若干个命令的文本文件,可以通过该文件创建出docker image。
定义过程:dockerfile--->docker image--->container
4)容器仓库(Registry)
Registry分为共有和私有两种:
Docker Registry :私有仓库
Docker Hub:共有仓库(私有收费)
Quay.io :另一个共有仓库
5)容器OS
除了在传统的Linux、MACOS、Windows上运行容器,目前也存在一些容器OS,例如CoreOS、Atomic、Ubuntu Core等。
比如传统操作系统,容器操作系统体积更小,启动更快。
6)容器平台
1.容器编排引擎:docker swarm、kubernetes、mesos+marathon等。
2.容器管理平台:Rancher、ContainerShip等。
3.基于容器的PaaS:Deis、Flynn、Dokku等。
7)容器网络
docker network
flannel
weave
calico
8)服务发现
etcd
consul
zookeeper
9)监控
docker ps/top/stats
docker stats API
sysdig
cAdvisor/Heapster
Weave Scope
10)数据管理、日志管理和安全性
数据管理:REX-Ray
日志管理:docker logs、logspout
安全性:OpenSCAP
2.实验环境准备
1)环境选择
管理工具:Docker engine
runtime:runc,Docker默认runtime
操作系统:Ubuntu16.04
2)安装Docker(Docker CE版,即Community Edition社区版,Docker EE为Enterprise Edition收费版)
- Ubuntu主机能够上网
- 更新国内apt源(例如aliyun的源)
- 安装包,允许apt命令HTTPS访问Docker源:sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
- 添加Docker官方GPG key:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- 将Docker的源添加到/etc/apt/source.list中:sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- 安装Docker:sudo apt-get update & sudo apt-get install docker-ce
3)运行第一个容器
sudo docker run -d -p 80:80 httpd
上述命令中-d代表在后台运行容器,-p表示端口映射(容器端口80映射到host的端口80),httpd为docker image名。
使用host的浏览器输入http://localhost:80,显示It works,表示容器运行成功。
4)镜像下载加速
如果docker在下载镜像时很慢(服务器在国外)可以按以下步骤使用代理:
- 在daocloud.io注册一个用户
- 登录后在菜单中点击“加速器”
- 复制命令在host中执行
- 重启docker deamon。sudo systemctl restart docker.service
二、容器使用
1.构建镜像
构建镜像有两种方式:docker commit和利用dockerfile来创建。
docker commit:
1.运行容器。
2.修改容器。
3.将容器保存为新的镜像。
过程:
- hanxinda@ubuntu:~$ sudo docker run -it ubuntu :运行一个ubuntu容器
- root@98c2e3571740:/# apt-get install -y vim :在容器中安装vim
- hanxinda@ubuntu:~$ sudo docker ps : 在另一个窗口中查看当前容器列表
- hanxinda@ubuntu:~$ sudo docker commit stoic_murdock ubuntu-with-vim
不建议使用docker commit来创建镜像,因为这是一种手工创建镜像的方式,容易出错,效率低且可重复性弱。更重要的是其他用户不知道该镜像是怎么创建出来的,是否存在恶意程序,即无法对镜像进行审计,存在安全隐患。(dockerfile创建的容器可查看创建过程)
dockerfile:
dockerfile是一个文本文件,记录了构建镜像的所有步骤。
例如:
FROM ubuntu #表示使用ubuntu镜像作为基础镜像
RUN apt-get update && apt-get install -y vim #在ubuntu镜像中更新源(ubuntu镜像中的源是默认的ubuntu官方源),并安装vim
sudo docker image ls :查看本地镜像:
sudo docker history [image name] :查看某个镜像的创建过程:
dockerfile中常用命令:
- FROM : 指定base镜像
- MAINTAINER : 作者或其他信息(任意字符)
- COPY : 将文件从build context复制到镜像。(build context即dockerfile存放目录),两种形式COPY src dst或COPY ["src","dst"]
- ADD :与COPY类似。不同的是如果src文件是归档文件(tar、zip、tgz、xz等),文件会被自动解压到dst
- ENV :设置环境变量,环境变量可被后面的指令使用,例如:ENV MY_VERSION 1.3 RUN apt-get install -y mypackage=$MY_VERSION
- EXPOSE :指定容器中的进程监听某个端口,Docker可以将该端口暴露出来。在后续的容器网络部分讨论。
- VOLUME : 将文件或目录声明为volume,在容器存储部分讨论。
- WORKDIR:为后面的RUN、CMD、ENTRYPOINT、ADD或COPY指令设置镜像中的当前工作目录。
- RUN:在容器中运行指定的命令。
- CMD:容器启动时运行指定的命令。Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD可以被docker run后的参数替换。
- ENTRYPOINT:设置容器启动时运行的命令。Dockerfile中可以有多个ENTRYPOINT指令,但只有最后一个生效,CMD或docker run之后的参数可以被当做参数传递给ENTRYPOINT。
2.分发镜像
三种方式:
1.使用同样的dockerfile在其他host中构建镜像。
2.上传镜像到公共Registry上,例如Docker Hub。
3.上传镜像到私有Registry上,供本地Host使用。
给镜像命名:
一个特定镜像的名字由两部分组成:repository和tag。
[image name] = [repository] : [tag]
如果执行docker build时没有指定tag,则会使用默认tag latest。相当于docker build -t ubuntu-with-vim:latest
Tag通常用来指定镜像的版本信息,但是小心latest只是一个默认tag,不一定是指最新的版本。但是在Docker Hub中,约定将latest作为最新稳定版本的别名,但不是强制规定。所以我们在使用镜像时最好避免使用latest,明确指定某个tag,例如httpd:2.3,ubuntu:xenial等。
使用公共Registry:
将镜像上传到Docker Hub中:
1.首先在Docker Hub注册一个账号。
2.在Docker Hub上登录,docker login -u leokale
3.修改镜像的repository,使之与Docker Hub账号匹配。 docker tag leokale/httpd:v1
4.将镜像上传到Docker Hub上,docker push leokale/httpd:v1
搭建本地Registry:
1.启动一个registry容器。docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2