写给前端工程师的简易 Docker 入门教程

前几天写了一篇文章《前端部署发展史》,前端部署的发展离不开 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/install/linux/docker-ce/centos/

以下是在 CentOS 上安装 Docker 的命令示例过程。

安装依赖:


   
   
  1. $ yum install -y yum-utils device-mapper-persistent-data lvm2

添加 Docker 的yum镜像源,如果在国内,添加阿里云的镜像源。


   
   
  1. # 安装 docker 官方的镜像源

  2. $ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

  3. # 如果在国内,安装阿里云的镜像

  4. $ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装指定版本的 Docker 并且启动服务。


   
   
  1. # 安装 Docker

  2. $ yum install -y docker-ce

  3. # 安装指定版本号的 Docker,以下是 Kubernetes 官方推荐的 Docker 版本号(此时,Kubernetes 的版本号在 v1.16)

  4. $ yum install -y docker-ce-18.06.2.ce

  5. $ systemctl enable docker

  6. Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

  7. $ systemctl start docker

当 Docker 安装成功后,可以使用以下命令查看版本号。


   
   
  1. $ docker --version

  2. Docker version 18.06.2-ce, build 6d37f41

  3. # 查看更详细的版本号信息

  4. $ docker version

  5. # 查看 Docker 的详细配置信息

  6. $ docker info

守护进程配置

dockerd 是 Docker 的守护进程,dockerd 可以通过配置文件进行配置,在 Linux 下的配置文件位置在 /etc/docker/daemon.json,更详细内容可以参考官方文档。

日志引擎为 json-file,对日志结构化,结合合适的日志系统,方便定位日志。存储引擎为 overrlay2。


   
   
  1. $ mkdir /etc/docker

  2. # 设置 docker daemon

  3. $ cat > /etc/docker/daemon.json <<EOF

  4. {

  5. "exec-opts": ["native.cgroupdriver=systemd"],

  6. "log-driver": "json-file",

  7. "log-opts": {

  8. "max-size": "100m"

  9. },

  10. "storage-driver": "overlay2",

  11. "storage-opts": [

  12. "overlay2.override_kernel_check=true"

  13. ]

  14. }

  15. EOF

  16. # 重启 docker

  17. $ systemctl daemon-reload

  18. $ 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 查看镜像信息。


   
   
  1. # 加入拉取一个 node:alpine 的镜像

  2. $ docker pull node:alpine

  3. # 查看镜像信息

  4. $ docker inspect node:alpine

  5. # 列出所有镜像

  6. $ docker images

  7. REPOSITORY TAG IMAGE ID CREATED SIZE

  8. node alpine f20a6d8b6721 13 days ago 105MB

  9. mongo latest 965553e202a4 2 weeks ago 363MB

  10. centos latest 9f38484d220f 8 months ago 202MB

构建镜像与发布

但并不是所有的镜像都可以在镜像仓库中找到,另外我们也需要为我们自己的业务应用去构建镜像。

使用 docker build 构建镜像,docker build 会使用当前目录的 Dockerfile 构建镜像,至于 Dockerfile 的配置,参考下节。

-t 指定标签:


   
   
  1. # -t node-base:10: 镜像以及版本号

  2. # .: 指当前路径

  3. $ docker build -t node-base:10 .

当构建镜像成功后可以使用 docker push 推送到镜像仓库。

Dockerfile

在使用 Docker 部署自己应用时,往往需要自己构建镜像。Docker 使用 Dockerfile 作为配置文件构建镜像,简单看一个 Node 应用构建的 Dockerfile。


   
   
  1. FROM node:alpine

  2. ADD package.json package-lock.json /code/

  3. WORKDIR /code

  4. RUN npm install --production

  5. ADD . /code

  6. CMD npm start

FROM

基于一个旧有的镜像,格式如下:


   
   
  1. FROM <image> [AS <name>]

  2. # 在多阶段构建时会用到

  3. FROM <image>[:<tag>] [AS <name>]

ADD

把目录,或者 url 地址文件加入到镜像的文件系统中。


   
   
  1. ADD [--chown=<user>:<group>] <src>... <dest>

RUN

执行命令,由于 UFS,它会在当前镜像的顶层新增一层。


   
   
  1. RUN <command>

CMD

指定容器如何启动。

一个 Dockerfile 中只允许有一个 CMD。


   
   
  1. # exec form, this is the preferred form

  2. CMD ["executable","param1","param2"]

  3. # as default parameters to ENTRYPOINT

  4. CMD ["param1","param2"]

  5. # shell form

  6. CMD command param1 param2

容器

镜像与容器的关系,类似于代码与进程的关系。

  • docker run 创建容器

  • docker stop 停止容器

  • docker rm 删除容器

创建容器

基于 Nginx 镜像创建一个最简单的容器:启动一个最简单的 http 服务。

使用 docker run 来启动容器,docker ps 查看容器启动状态。


   
   
  1. $ docker run -d --name nginx -p 8888:80 nginx:alpine

  2. $ docker ps -l

  3. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

  4. 404e88f0d90c nginx:alpine "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:8888->80/tcp nginx

  5. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

其中:

  • -d:启动一个 daemon 进程

  • --name:为容器指定名称

  • -p host-port:container-port:宿主机与容器端口映射,方便容器对外提供服务

  • nginx:alpine:基于该镜像创建容器

此时在宿主机使用 curl 测试容器提供的服务是否正常。


   
   
  1. $ curl localhost:8888

  2. <!DOCTYPE html>

  3. <html>

  4. <head>

  5. <title>Welcome to nginx!</title>

  6. <style>

  7. body {

  8. width: 35em;

  9. margin: 0 auto;

  10. font-family: Tahoma, Verdana, Arial, sans-serif;

  11. }

  12. </style>

  13. </head>

  14. <body>

  15. <h1>Welcome to nginx!</h1>

  16. <p>If you see this page, the nginx web server is successfully installed and

  17. working. Further configuration is required.</p>

  18. <p>For online documentation and support please refer to

  19. <a href="http://nginx.org/">nginx.org</a>.<br/>

  20. Commercial support is available at

  21. <a href="http://nginx.com/">nginx.com</a>.</p>

  22. <p><em>Thank you for using nginx.</em></p>

  23. </body>

  24. </html>

那如果要进入容器环境中呢?使用 docker exec -it container-name sh 命令。


   
   
  1. $ docker exec -it nginx sh

  2. / #

  3. / #

  4. / #

容器管理

docker ps 列出所有容器:


   
   
  1. $ docker ps

  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

  3. 404e88f0d90c nginx:alpine "nginx -g 'daemon of…" 4 minutes ago Up 4 minutes 0.0.0.0:8888->80/tcp nginx

  4. 498e7d74fb4f nginx:alpine "nginx -g 'daemon of…" 7 minutes ago Up 7 minutes 80/tcp lucid_mirzakhani

  5. 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 查看容器端口映射:


   
   
  1. $ docker port nginx

  2. 80/tcp -> 0.0.0.0:8888

docker stats 查看容器资源占用:


   
   
  1. $ docker stats nginx

  2. CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS

  3. 404e88f0d90c nginx 0.00% 1.395MiB / 1.796GiB 0.08%

基于Kubernetes的DevOps实战培训

基于Kubernetes的DevOps实战培训将于2019年12月27日在上海开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:容器特性、镜像、网络;Kubernetes架构、核心组件、基本功能;Kubernetes设计理念、架构设计、基本功能、常用对象、设计原则;Kubernetes的数据库、运行时、网络、插件已经落地经验;微服务架构、组件、监控方案等,点击下方图片或者阅读原文链接查看详情。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值