可以从以下地址下载并安装docker,Linux,Windows,MacOS均支持:
Docker 安装完成后,可以直接打开终端执行:
docker run hello-world
输出如下信息:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
通过上述 hello-world 镜像运行起来的容器,输出了一个容器的运行步骤:
Docker 包括三个基本概念:
镜像 与 容器 的关系?
镜像(image)是一个压缩包,镜像通过 Docker Daemon 进程解压拉起(run)得到容器(container).
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
虚拟化技术是由Hypervisor真正的创建了一个虚拟机,有以下特点:
容器化技术的特点:
所以容器化技术相对于虚拟化技术的优势是敏捷和高性能。但有利就有弊,弊端在于隔离不彻底
,主要表现为:
容器就是一种沙盒技术,一种把应用进程装进集装箱的技术,应用与应用之间因为有了边界而不会相互干扰,同时应用被装起来后也方便搬运和迁移 。
容器技术的核心功能,就是做到两点:
容器文件系统:rootfs
docker与k8s的区别:
作用:从视图中隔离应用进程的可视范围,包括网络、文件、CPU、进程、用户等。
隔离进程空间要达到的效果:
为了做到这点,就需要为应用设置一个隔离的进程空间,而namespaces就恰好能做到这点,它的原理如下:
看到
一个全新的进程空间,在这个进程空间中当前进程的PID=1。int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
实际上,namespaces只是对被隔离应用的进程空间做了手脚,使得这些进程只能看到重新计算过的进程编号1,而实际上在宿主机操作系统里,进程编号还是100,相当于一个碍眼法。
namespaces有很多种,除了上面提到的pid namespace外,还有下面几种:
namespaces只能隔离应用进程的可视范围,却并不能真正限制进程所能使用的资源。例如:
一个namespace中只能看到1G的内存,但它真实运行时却能占用整个宿主机的内存。
所以需要一个机制来限制进程能使用的资源上限,它就是Cgroups
(全称是Linux Control Group),能限制的资源包括CPU、磁盘、内存、网络带宽等。
Cgroups 给用户暴露出来的操作接口是文件系统,位于/sys/fs/cgroup
目录下,用以下命令可以展示内容:mount -t cgroup
上面截图中列出的这些子系统就是cgroup支持限制的资源种类。
下面拿CPU举例来说明如何使用(目录位于/sys/fs/cgroup/cpu
):
root@ubuntu:/sys/fs/cgroup/cpu$ mkdir user.slice
, 操作系统会在新目录中自动生成对应的配置文件;cfs_period
和cfs_quota
,用来限制进程在cfs_period长的时间内,最多能被分到cfs_quota的CPU时间;除CPU外,还有以下子系统分别对进程作不同的限制 :
blkio
: 为块设备设定IO限制memory
: 为进程设定内存使用的限制cpuset
: 为进程分配单独的CPU核和内存节点镜像一般通过Dockerfile
进行构建,它是一个用来声明镜像构建过程的文件。下面是一个示例:
FROM ubuntu:20.04 # 指定基础镜像文件
COPY uc/sbin/ /uc/sbin/ # 拷贝应用程序文件
USER root EXPOSE 8051 18051 # 指定用户、暴露应用进程端口
ENTRYPOINT ["./docker_start.sh"]# 指定镜像中的应用启动入口
Dockfile常用的指令有:
指令 | 描述 |
---|---|
FROM | 指定基础镜像,例如 FROM ubuntu:20.04 |
LABEL | 给新镜像打标签,便于过滤,方便理解,起到备注注释的作用 |
RUN | 在新镜像中做一些指令操作,可以理解为执行一些 shell 命令,如 mkdir, apt-get, cp 等 |
CMD | 类似 RUN ,定义容器启动时执行的指令,或者作为参数提供给 ENTRYPOINT 指令。如果定义多个CMD,则仅最后一个有效。CMD指令可以被 docker run image param1 param2 后面的参数覆盖 |
ENTRYPOINT | 定义容器启动指令,类似于 CMD 指令,但其不会被 docker run 的命令行参数所覆盖。可以使用 docker run image --entrypoint 选项来覆盖 ENTRYPOINT 指令指定的程序 |
EXPOSE | 声明容器启动会使用的端口,仅仅供人查看而已。作用:帮助镜像使用者理解这个镜像使用的端口,以方便配置映射。在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口 |
ENV | 定义环境变量,在后续的指令中,就可以使用这个环境变量(包括启动容器后) |
ARG | 类似ENV,但作用域不同,仅在构建镜像时有用,容器运行时不存在,可以放置在FROM前,可以被 --build-arg key=value 覆盖 |
COPY | 复制指令,从上下文目录中复制文件或者目录到容器里指定路径,例如:COPY sayHi /uc/bin/sayHello |
ADD | 同COPY,比COPY多了:支持拷贝 远程url地址文件 至镜像中;压缩包会被自动解压缩。同等需求下,建议采用COPY |
VOLUME | 声明容器要使用的挂载点,便于使用者理解镜像的关键数据存储位置。如果没有指定则会自动挂载到匿名卷,这个匿名卷难以查找。 |
WORKDIR | 指定工作目录,以后各层的当前目录就被改为指定的目录,可以将WORKDIR理解为 cd 命令。 |
USER | 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。 |
Dockerfile 所在的当前目录就是容器构建的上下文,它的作用体现在:
COPY
指令只能拷贝构建上下文中的文件或目录;.dockerignore
可用于声明要忽略的文件,这里声明的文件不需要传输,类似于.gitignore.git
src
*.war
*.jar
Docker镜像是分层构建的,Dockerfile 中每条指令可能都会新建一层。例如以下 Dockerfile:
FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
- 以上四条指令会创建四层,分别对应基础镜像、复制文件、编译文件以及入口文件;
- 每层只记录本层所做的更改,而这些层都是只读层;
- 当你启动一个容器,Docker 会在最顶部添加读写层;
- 你在容器内做的所有更改,如写日志、修改、删除文件等,都保存到了读写层内,一般称该层为容器层。
说明:也不是每一行指令都产生新层,只有那些修改了文件系统的命令才会产生新的镜像层,例如RUN、COPY之类。
# 当前目录结构 tree
/tmp/test-v1
- Dockerfile
- Dockerfile2
- a.log
# 切换到目录
$ cd /tmp/test-v1
# 在当前目录下构建 test:v1 镜像
$ docker build -t test:v1 .
# 使用 Dockerfile2 构建镜像
$ docker build -t test:v2 -f Dockerfile2 .
# 添加完整的镜像路径(用于私有或第三方仓库)
$ docker build -t hub-ali.quanshi.com/repotest/test:v3 .
镜像仓库分为如下几类:
中央仓库:https://hub.docker.com/
, 仓库上的镜像来源有
第三方仓库,其他公司或者机构提供的免费或付费的仓库
https://help.aliyun.com/zh/acr/
https://cloud.tencent.com/document/product/1141/39278
私有仓库,个人或公司自己搭建的供公司内部使用的仓库
本地仓库,在机器本地镜像存放的仓库
中央仓库和私有仓库在使用时有些许区别:
docker pull busybox
docker pull hub-ali.quanshi.com/infra/busybox
如果需要 http 或直接 ip 方式访问,需要给 docker 配置免安全校验,见下:
# 编辑 /etc/docker/daemon.json, 加入 insecure-registries 字段
{
"insecure-registries" : ["test.hub.com", "192.168.11.11"]
}
配置镜像加速
# 编辑 /etc/docker/daemon.json, 加入registry-mirrors 字段
{
"registry-mirrors": ["https://fv743jei.mirror.aliyuncs.com"],
}
# 更多可用镜像加速方案参照:https://gist.github.com/y0ngb1n/7e8f16af3242c7815e7ca2f0833d3ea6
指令 | 描述 |
---|---|
docker-compose up | 创建并启动容器,通过-f参数来指定yaml容器配置,例如:docker-compose -f /meetconf.yml up uniformserver -d |
docker commit | 通过容器创建镜像 |
docker cp | 容器与本地目录相互拷贝文件 |
docker exec | 在容器中执行命令,例如进入容器:docker exec -it 容器id /bin/bash |
docker logs | 查看容器控制台日志输出,例如:docker logs -f sqlproxy |
docker ps | 获取正在运行的容器,-a 获取所有容器(包含已停止的) |
docker rm [容器ID] | 删除已停止的容器,加上-f 表示删除正在运行的容器 |
docker stop [容器ID] | 停止正在运行的容器 |
docker build | 通过 Dockerfile 构建镜像 |
docker history | 查看镜像构建历史,如docker history nginx:v1 |
docker images | 列出镜像 |
docker inspect [容器ID] | 显示镜像或容器的详细信息 |
docker load | 加载镜像到本地仓库 |
docker pull | 从镜像仓库拉取镜像 |
docker push | 推送镜像到镜像仓库 |
docker rmi | 移除镜像 |
docker save | 保存镜像到一个tar文件 |
docker tag | 镜像更改标签名称 |