前几天写了一篇文章《前端部署发展史》, 前端部署的发展离不开 DevOps 的发展, 而 DevOps 又得益于 Docker 的发展. 因此, 前端掌握 Docker 也势在必行, 何况它又不是很难.
Docker 使应用部署更加轻量, 可移植, 可扩展. 更好的环境隔离也更大程度地避免了生产环境与测试环境不一致的巨大尴尬. 由于 Docker 轻便可移植的特点也极大促进了 CI/CD 的发展.
术语
Docker 的架构图如下:
从图中可以看出几个组成部分:
Docker Client: 即 Docker 命令行工具
Docker Host: 宿主机, Docker Daemon 的运行环境服务器
Docker Daemon:Docker 的守护进程, Docker Client 通过命令行与 Docker Daemon 交互
Container: 最小型的一个操作系统环境, 可以对各种服务以及应用容器化
Image: 镜像, 可以理解为一个容器的模板配置, 通过一个镜像可以启动多个容器
Registry: 镜像仓库, 存储大量镜像, 可以从镜像仓库拉取和推送镜像
安装 Docker
参考在 CentOS 上安装 Docker 的官方文档: https://docs.docker.com/instal ... ntos/
以下是在 CentOS 上安装 Docker 的命令示例过程.
安装依赖:
$ yum install -y yum-utils device-mapper-persistent-data lvm2
添加 Docker 的 yum 镜像源, 如果在国内, 添加阿里云的镜像源.
- # 安装 docker 官方的镜像源
- $ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- # 如果在国内, 安装阿里云的镜像
- $ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装指定版本的 Docker 并且启动服务.
- # 安装 Docker
- $ yum install -y docker-ce
- # 安装指定版本号的 Docker, 以下是 Kubernetes 官方推荐的 Docker 版本号 (此时, Kubernetes 的版本号在 v1.16)
- $ yum install -y docker-ce-18.06.2.ce
- $ systemctl enable docker
- Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
- $ systemctl start docker
当 Docker 安装成功后, 可以使用以下命令查看版本号.
- $ docker --version
- Docker version 18.06.2-ce, build 6d37f41
- # 查看更详细的版本号信息
- $ docker version
- # 查看 Docker 的详细配置信息
- $ docker info
守护进程配置
dockerd 是 Docker 的守护进程, dockerd 可以通过配置文件进行配置, 在 Linux 下的配置文件位置在 /etc/docker/daemon.JSON, 更详细内容可以参考 官方文档 .
日志引擎为 JSON-file, 对日志结构化, 结合合适的日志系统, 方便定位日志. 存储引擎为 overrlay2.
- $ mkdir /etc/docker
- # 设置 docker daemon
- $ cat> /etc/docker/daemon.JSON <<EOF
- {
- "exec-opts": ["native.cgroupdriver=systemd"],
- "log-driver": "json-file",
- "log-opts": {
- "max-size": "100m"
- },
- "storage-driver": "overlay2",
- "storage-opts": [
- "overlay2.override_kernel_check=true"
- ]
- }
- EOF
- # 重启 docker
- $ systemctl daemon-reload
- $ systemctl restart docker
底层原理
Docker 底层使用了一些 Linux 内核的特性, 大概有 Namespace,CGroups 和 UFS.
Namespace
Docker 使用 Linux Namespace 构建隔离的环境, 它由以下 Namespace 组成
pid: 隔离进程
net: 隔离网络
ipc: 隔离 IPC
mnt: 隔离文件系统挂载
uts: 隔离 hostname
user: 隔离 uid/gid
Control Groups
也叫 CGroups, 限制资源配额, 比如某个容器只能使用 100M 内存.
Union File Systems
UnionFS 是一种分层, 轻量级并且高性能的文件系统, 支持对文件系统的修改作为一次提交来一层层的叠加. Docker 的镜像与容器就是分层存储, 可用的存储引擎有 aufs,overlay 等.
关于分层存储的详细内容可以查看官方文档: https://docs.docker.com/storage/storagedriver/ .
镜像
镜像是一份用来创造容器的配置文件, 而容器可以视作最小型的一个操作系统.
Docker 的镜像和容器都使用了 UnionFS 做分层存储, 镜像作为只读层是共享的, 而容器在镜像之上附加了一层可写层, 最大程度地减少了空间的浪费, 详见下图:
镜像仓库与拉取
大部分时候, 我们不需要自己构建镜像, 我们可以在官方镜像仓库拉取镜像.
可以简单使用命令 docker pull 拉取镜像. 拉取镜像后可以使用 docker inspect 查看镜像信息.
- # 加入拉取一个 node:alpine 的镜像
- $ docker pull node:alpine
- # 查看镜像信息
- $ docker inspect node:alpine
- # 列出所有镜像
- $ docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- node alpine f20a6d8b6721 13 days ago 105MB
- mongo latest 965553e202a4 2 weeks ago 363MB
- CentOS latest 9f38484d220f 8 months ago 202MB
构建镜像与发布
但并不是所有的镜像都可以在镜像仓库中找到, 另外我们也需要为我们自己的业务应用去构建镜像.
使用 docker build 构建镜像, docker build 会使用当前目录的 Dockerfile 构建镜像, 至于 Dockerfile 的配置, 参考下节.
- # -t node-base:10: 镜像以及版本号
- # .: 指当前路径
- $ docker build -t node-base:10 .
- FROM node:alpine
- ADD package.JSON package-lock.JSON /code/
- WORKDIR /code
- RUN NPM install --production
- ADD . /code
- CMD NPM start
- FROM
- FROM <image> [AS <name>]
- # 在多阶段构建时会用到
- FROM <image>[:<tag>] [AS <name>]
- ADD
- ADD [--chown=<user>:<group>] <src>... <dest>
- RUN
- RUN <command>
- CMD
- # exec form, this is the preferred form
- CMD ["executable","param1","param2"]
- # as default parameters to ENTRYPOINT
- CMD ["param1","param2"]
- # shell form
- CMD command param1 param2
- $ docker run -d --name nginx -p 8888:80 nginx:alpine
- $ docker ps -l
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 404e88f0d90c nginx:alpine "nginx -g'daemon of..." 4 minutes ago Up 4 minutes 0.0.0.0:8888->80/tcp nginx
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- <!DOCTYPE html>
- <HTML>
- <head>
- <title>
- Welcome to nginx!
- </title>
- <style>
- body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial,
- sans-serif; }
- </style>
- </head>
- <body>
- <h1>
- Welcome to nginx!
- </h1>
- <p>
- If you see this page, the nginx web server is successfully installed and
- working. Further configuration is required.
- </p>
- <p>
- For online documentation and support please refer to
- <a href="http://nginx.org/">
- nginx.org
- </a>
- .
- <br/>
- Commercial support is available at
- <a href="http://nginx.com/">
- nginx.com
- </a>
- .
- </p>
- <p>
- <em>
- Thank you for using nginx.
- </em>
- </p>
- </body>
- </HTML>
- $ docker exec -it nginx sh
- / #
- / #
- / #
- $ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 404e88f0d90c nginx:alpine "nginx -g'daemon of..." 4 minutes ago Up 4 minutes 0.0.0.0:8888->80/tcp nginx
- 498e7d74fb4f nginx:alpine "nginx -g'daemon of..." 7 minutes ago Up 7 minutes 80/tcp lucid_mirzakhani
- 2ce10556dc8f Redis:4.0.6-alpine "docker-entrypoint.s..." 2 months ago Up 2 months 0.0.0.0:6379->6379/tcp apolloserverstarter_redis_1
- $ docker port nginx
- 80/tcp -> 0.0.0.0:8888
- $ docker stats nginx
- CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
- 404e88f0d90c nginx 0.00% 1.395MiB / 1.796GiB 0.08%
来源: http://www.tuicool.com/articles/6juEj26