30分钟带你了解Web工程师必知的Docker知识

简介: 笔者之前和朋友一直在讨论web技术方向的话题,也一直想了解web运维方面的知识,所以特意请教了一下我的朋友老胡,他对web运维和后端技术有非常多的实战经验,所以在本文中他也提供了不少帮助。本文主要会介绍Docker的基础知识和应用领域,并通过实际部署一个web项目来带大家了解Docker的使用方式。


前言


笔者之前和朋友一直在讨论web技术方向的话题,也一直想了解web运维方面的知识,所以特意请教了一下我的朋友老胡,他对web运维和后端技术有非常多的实战经验,所以在本文中他也提供了不少帮助。本文主要会介绍Docker的基础知识和应用领域,并通过实际部署一个web项目来带大家了解Docker的使用方式。


作为一名前端工程师,为什么要学习Docker呢?首先笔者先来介绍一下Docker


Docker 是一个基于 Go 语言开发的开源应用容器引擎, 可以让我们把我们的应用和包打包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,并且可以实现虚拟化。所谓容器,就是完全使用沙箱机制,相互之间没有任何接口,并且性能开销极低。


回忆一下,我们传统的Web应用部署方式一般都是将Web应用手动上传到服务器,并手动安装相关依赖和环境,再高级一点的我们可以用jenkins来自动化部署我们的应用,包括自动化测试等等,虽然已经解决了我们大部分部署的繁琐问题,但是如果我们服务器变更,或者遇到需要部署到多台服务器的场景,那么传统的操作将会繁琐。大家也许会问这种情况会出现吗?答案是会的。做过B端系统或有Saas系统开发经验的朋友也许会清楚其中的繁琐,为了客户安全和私有化往往需要研发人员给企业配置和部署独立的Web应用,如果你有上百家客户上千家客户,我们一个个部署显然是效率极低的,而且不能保证环境的一致性和稳定性,因为一旦我们的Web系统使用的环境或者包更新了,应用很可能不能正常Work,这种情况下采用Docker容器化技术可以很好的解决这一问题。


再者,前几年比较火的云计算服务,最为直接的要求就是标准化快速交付,而Docker技术就非常适合这样的要求。


目前大部分企业都在采用Docker来实现软件开发部署中的自动化和部署效率安全等问题,作为前端工程师,也需要掌握一定的Docker技术来更好的配合后端和运维来推进这一过程。


你将收获


  • Docker的基本应用场景和实现架构
  • Docker的基本用法
  • 使用Docker部署一个Web应用


正文


在开始正文之前首先我们先来了解一下Docker的应用场景,这样才能更好的理解为什么要使用它。



Docker 允许我们使用自己提供的应用程序或服务的本地容器在标准化环境中工作,这将大大简化我们开发的生命周期。我们还可以用Docker配合Jenkins实现更加完整高效的自动化部署方案。


Docker 的三个基本概念如下:


  • 镜像(Image):Docker 镜像(Image),相当于是一个完整的root文件系统;
  • 容器(Container):镜像和容器的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等;
  • 仓库(Repository):可看成是一个代码控制中心,用来保存镜像。

其采用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。 Docker 容器通过 Docker镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。为了方便大家理解,笔者特意画了一张Docker的架构图,如下:



Docker 基础



1.1主机虚拟化(vm)与操作系统虚拟化(container)




由上图对比可得,两种虚拟化技术本质的区别是:主机虚拟化需要在父操作系统上运行一套子操作系统;而操作系统虚拟化是以进程的方式管理子容器,子容器与宿主机共用一套操作系统





主机虚拟化

操作系统虚拟化
隔离性 环境强隔离,父子操作系统底层无关 只能运行相似的操作系统,使用类似的库
网络 网络传输效率低,启动慢 传输效率高,启动较快,响应快
占用 必须增加操作系统的大量占用 占用较少
安全 子系统与宿主系统无关
有风险,但在可控范围 (daemon)

1.2 容器化涉及内核技术


  • namespace  —— 名称空间是提供给每个容器资源隔离的基础,提供了以下属性的隔离
  • UTS:每一个NameSpace都拥有独立的主机或域名,可以把每个NameSpace认为一个独立主机。
  • IPC:每个容器依旧使用linux内核中进程交互的方法,实现进程间通信
  • Mount:每个容器的文件系统是独立的Net:每个容器的网络是隔离
  • User:每个容器的用户和组ID是隔离,每个容器都拥有root用户
  • PID:每个容器都拥有独立的进程树,由容器是物理机中的一个进程,所以容器中的进程是物理机的线程
  • control group ——控制组提供了对容器的资源限制
  • blkio -- 这个子系统为块设备设定输入/输出限制,比如磁盘,固态硬盘,USB 等等。
  • cpu -- 这个子系统使用调度程序提供对 CPU 的 cgroup 任务访问。
  • cpuacct -- 这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。
  • cpuset -- 这个子系统为 cgroup 中的任务分配独立 CPU和内存节点。
  • devices -- 这个子系统可允许或者拒绝 cgroup 中的任务访问设备。
  • freezer -- 这个子系统挂起或者恢复 cgroup 中的任务。
  • memory -- 这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。
  • net_cls -- 这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。
  • ns -- 名称空间子系统


运行第一个docker 程序



2.1 安装docker


参照docker官网安装文档强烈建议不使用windows 操作(本人没有试过在windows上开发docker 相关,虽然官网提供了,但不知道),建议使用osx或linux)考虑服务器上国内使用centos 7 为大部分介绍下centos 7的安装(使用非root 账号,自行加上sudo)


# 1.清除旧版本的docker 安装
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
# 2.安装依赖 官网介绍 yum-utils 为了引入yum-config-manager 其他的是docker 自身依赖
yum install -y yum-utils \
                      device-mapper-persistent-data \
                      lvm2
# 3.添加yum源                      
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
# 4.列出对应的安装版本
 yum list docker-ce --showduplicates | sort -r
# 5.安装 建议根据实际情况选择版本 不要追求最新
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
# 6。设置开机启动docker,并启动docker 
systemctl enable docker && systemctl start docker

2.2 运行第一个docker 程序

# 查看docker 服务状态
systemctl docker status
# 运行 第一个应用,前端接触最多的容器就是nginx 了 
# 查询官方 nginx stable 版本是1.16.1 于是选用 stable-alpine 版本
docker run -p 80:80 nginx:stable-alpine

3.docker 基本使用



3.1 docker命令介绍


docker所有命令可阅读使用docker 命令行并可通过docker --help 查询用法

docker --help
Usage:  docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
      --config string      Location of client config files (default "/Users/mac/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket(s) to connect to
  -l, --log-level string   Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/Users/mac/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/Users/mac/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/Users/mac/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit
Management Commands:
  builder     Manage builds
  config      Manage Docker configs
  container   Manage containers
  context     Manage contexts
  image       Manage images
  network     Manage networks
  node        Manage Swarm nodes
  plugin      Manage plugins
  secret      Manage Docker secrets
  service     Manage services
  stack       Manage Docker stacks
  swarm       Manage Swarm
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

3.2 docker 镜像


3.2.1 常见用法


官方给的关于镜像的描述是:"An image is a read-only template with instructions for creating a Docker container",含义是说 镜像是一个只读的用于指导创建容器的模板,相当于面向对象里的类的含义 而容器便是对应的实例,常用的命令如下


# 下载镜像
+ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
423ae2b273f4: Pull complete
de83a2304fa1: Pull complete
f9a83bce3af0: Pull complete
b6b53be908de: Pull complete
Digest: sha256:04d48df82c938587820d7b6006f5071dbbffceb7ca01d2814f81857c631d44df
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
# 查看镜像列表
+ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              72300a873c2c        2 weeks ago         64.2MB
# 导出镜像为文件,方便在不联网的机器上使用docker image
+ docker save  ubuntu -o ubuntu.tar
# 删除镜像,可见它的操作是先清除tag 如果没有其他相同image占用再清理layer
+ docker rmi ubuntu
Untagged: ubuntu:latest
Deleted: sha256:72300a873c2ca11c70d0c8642177ce76ff69ae04d61a5813ef58d40ff66e3e7c
Deleted: sha256:d3991ad41f89923dac46b632e2b9869067e94fcdffa3ef56cd2d35b26dd9bce7
Deleted: sha256:2e533c5c9cc8936671e2012d79fc6ec6a3c8ed432aa81164289056c71ed5f539
Deleted: sha256:282c79e973cf51d330b99d2a90e6d25863388f66b1433ae5163ded929ea7e64b
Deleted: sha256:cc4590d6a7187ce8879dd8ea931ffaa18bc52a1c1df702c9d538b2f0c927709d
# 从文件导入镜像,方便在不联网的机器上使用docker image
+ docker load -i ubuntu.tar
cc4590d6a718: Loading layer [=====================>]  65.58MB/65.58MB
8c98131d2d1d: Loading layer [=====================>]  991.2kB/991.2kB
03c9b9f537a4: Loading layer [=====================>]  15.87kB/15.87kB
1852b2300972: Loading layer [=====================>]  3.072kB/3.072kB
Loaded image: ubuntu:latest
# 构建镜像, 可自定义构建自己的镜像 下一部份详细讲
docker build -t $image:$tag $DockerfilePath
# 给镜像打一个新标签,一般用于推送到其他仓库
docker tag ubuntu $image:$tag
# 将镜像推送到远程registry
docker push $image:$tag
3.2.2 自定义构建镜像


copy-on-write:  docker 镜像是以层为结构的,底层一般为基础的操作系统,当文件系统发生变化时,首先从只读层复制一个文件到读写层操作当该层读写完毕并提交后即在原来基础上累加一层,当一个镜像构建时会缓存所有成功的层提升构建速度.


尝试通过物理安装的方式讲述一下自己构建nginx,我们在物理机上安装nginx 的步骤(源码安装能最大化保证稳定性和用到新的feature)可概括为以下几步


# 1. 下载源码包及依赖
yum install pcre-devel zlib-devel openssl-devel gcc make 
wget http://nginx.org/download/nginx-1.16.1.tar.gz  /usr/local/source/
# 2. 设置编译nginx 的模块
./configure \
        --prefix=/usr/local/nginx \
        --conf-path=/usr/local/nginx/nginx.conf \
        --pid-path=/usr/local/nginx/nginx.pid \
        --with-http_ssl_module \
        --with-pcre \
        --with-http_gzip_static_module
# 3. 编译 & 安装
make && make install
# 4. 启动nginx
./nginx

实际在Dockerfile下也是这么完成的。


1.编辑文件命名Dockerfile

FROM centos:centos7.2.1511
MAINTAINER xujiang@test.com
ADD http://nginx.org/download/nginx-1.16.1.tar.gz /usr/local/source/
RUN ["bash","-c","cd /usr/local/source && \
      tar -xf nginx-1.16.1.tar.gz  --strip-components 1   && \
      yum update -y > /dev/null 2>&1 &&  \
      yum install -y -q pcre-devel zlib-devel openssl-devel gcc make && \
      ./configure  --prefix=/usr/local/nginx  --with-http_ssl_module  --with-pcre  --with-        http_gzip_static_module &&  \
      make && make install && \
      ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx && \
      rm -rf /usr/local/source"]
CMD ["nginx", "-g", "daemon off;"]

2.在当前目录下运行构建,便可构建成功 .表示当前目录下构建

+ docker build -t mynginx:20200311 .
Step 1/4 : FROM centos:centos7.2.1511
 ---> 9aec5c5fe4ba
Step 2/4 : ADD http://nginx.org/download/nginx-1.16.1.tar.gz /usr/local/source/
Downloading [======================================>]  1.033MB/1.033MB
 ---> ac3b840c5563
Step 3/4 : RUN ["bash","-c","cd /usr/local/source && tar -xf nginx-1.16.1.tar.gz  --strip-components 1   && yum update -y > /dev/null 2>&1 &&  yum install -y -q pcre-devel zlib-devel openssl-devel gcc make && ./configure  --prefix=/usr/local/nginx  --with-http_ssl_module  --with-pcre  --with-http_gzip_static_module &&  make && make install && ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx && rm -rf /usr/local/source"]
 ---> 22efc447e0c2
Step 4/4 : CMD ["nginx", "-g", "daemon off;"]
 ---> 8f74bded71e9
Successfully built 8f74bded71e9
Successfully tagged mynginx:20200311

3.运行该镜像并暴露内部80端口指向外部8000:docker run -d -p 8000:80 --name mynginx-container mynginx:20200311


注:实际上nginx 构建所有内容远远比这个复杂,这里可贴上nginx 构建的Dockerfile

更多指令可参考Dockerfile Reference


3.3 docker 容器


上文提到容器是镜像的运行时实例,一个镜像可以通过不同的命令运行不一样的容器实例,以下是对容器的基本操作的常用命令



+ docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
# -d 将容器运行在后台并打印容器ID
-d, --detach            Run container in background and print container ID
-e, --env list          Set environment variables
--env-file list         Read in a file of environment variables
--rm                    Automatically remove the container when it exits
-v, --volume list       Bind mount a volume
-w, --workdir string    Working directory inside the container
--restart string        Restart policy to apply when a container exits (default "no")
# 查看当前正在运行的容器 docker ps -a 表示查看所有容器(包含已经退出)
+ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
a5f7f9710db8        mynginx:20200311    "nginx -g 'daemon of…"   59 seconds ago      Up 58 seconds       0.0.0.0:80->80/tcp   mynginx-container
# 进入容器内部执行命令(打开标准输入流并为容器创建伪终端)
docker exec -it  mynginx-container bash
# 查看容器日志
docker logs -f  mynginx-container

4.实战案例



1.准备

* 一个前端项目
* 一台安装好docker 的机器
* [docker hub](https://hub.docker.com/)查询编译所需要的镜像[node](https://hub.docker.com/_/node?tab=tags),[nginx](https://hub.docker.com/_/nginx)
# 克隆antd-admin.git 项目
git clone https://github.com/zuiidea/antd-admin.git
# 使用docker 编译的优势 可以在任意一台只装了docker的环境下编译不同的语言 消除对环境依赖
docker run --network=host --rm  -v "$(cd $(dirname .);pwd):/app" -w /app node:10-alpine3.9 yarn && yarn build
 
         
  • 准备反向代理的规则的nginx.conf
server {
    listen       80;
    server_name  _;
    access_log  /var/log/nginx/host.access.log  main;
    location / {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Headers X-Requested-With;
        add_header Access-Control-Allow-Methods GET,POST;
        root   /app;
        index  index.html index.htm;
    }
}
  • 构建自己的Dockerfile 并写成脚本
FROM nginx:stable-alpine
ENV LANG en_US.UTF-8
COPY dist /app
COPY app.conf /etc/nginx/conf.d/default.conf
WORKDIR /app
  • 参考脚本如下 build.sh
#!/bin/bash
current_dir=$(cd $(dirname .);pwd)
function compire(){
 docker run --network=host --rm  -v "$current_dir:/app" -w /app node:10-alpine3.9 yarn && yarn build
}
function package(){
 if [ ! -d "$current_dir/dist" ] ;then
  compire
 fi
 docker build -t myapp:`date -u +"%Y%m%d"` $current_dir
}
function clean(){
 rm -rf $current_dir/dist
}
case "$1" in
  compire)
   compire
  ;;
  package)
   package
  ;;
  clean)
  clean
  ;;
  *)
  echo "USAGE:$0 package | compire | clean "
esac
  • 运行容器docker run -d -p 80:80 myapp:20200311


至此,基本的配置就完成了,大家可以自己手动试试,基于Docker部署一个自己的Web应用。


本文只涉及到了Docker基本的使用配置,后期笔者有空会继续和朋友总结编排docker networkdocker volumedocker daemon等技术,并以一个node的案例部署作为实战来教大家在实际项目中去落地Docker自动化部署。



目录
相关文章
|
5月前
|
人工智能 自然语言处理 JavaScript
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
Magnitude是一个基于视觉AI代理的开源端到端测试框架,通过自然语言构建测试用例,结合推理代理和视觉代理实现智能化的Web应用测试,支持本地运行和CI/CD集成。
728 15
测试工程师要失业?Magnitude:开源AI Agent驱动的端到端测试框架,让Web测试更智能,自动完善测试用例!
|
5月前
|
Linux 虚拟化 Docker
win11怎么安装docker的必要设置自学软硬件工程师778天
win11怎么安装docker的必要设置自学软硬件工程师778天
win11怎么安装docker的必要设置自学软硬件工程师778天
|
7月前
|
中间件 关系型数据库 数据库
docker快速部署OS web中间件 数据库 编程应用
通过Docker,可以轻松地部署操作系统、Web中间件、数据库和编程应用。本文详细介绍了使用Docker部署这些组件的基本步骤和命令,展示了如何通过Docker Compose编排多容器应用。希望本文能帮助开发者更高效地使用Docker进行应用部署和管理。
200 19
|
7月前
|
前端开发
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
193 1
【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
|
6月前
|
运维 网络安全 文件存储
找不到类似 Docker Desktop 的 Web 管理界面?试试这些开源方案
Docker Desktop 是本地容器化开发的利器,但存在无法通过 Web 远程管理、跨平台体验不一致等问题。为此,推荐几款轻量级、可 Web 化管理的 Docker 工具:Portainer 功能全面,适合企业级运维;CasaOS 集成应用商店和 NAS 功能,适合家庭/个人开发环境;Websoft9 提供预集成环境,新手友好。这些工具能有效提升容器管理效率,满足不同场景需求。
341 3
|
5月前
|
前端开发 Linux Docker
docker的安装使用0废话版本自学软硬件工程师778天
win11怎么安装docker的必要设置自学软硬件工程师778天
|
应用服务中间件 nginx Docker
【与时俱进】网络工程师必备技能:Docker基础入门指南,助你轻松应对新时代挑战!
【8月更文挑战第22天】随着容器技术的发展,Docker已成为开发与运维的关键工具。本文简要介绍Docker——一种开源容器化平台,能让应用程序及依赖项被打包成轻量级容器,在任何Linux或Windows机器上运行。文中涵盖Docker的安装步骤、基础命令操作如启动服务、查看版本、拉取与运行容器等。并通过实例演示了如何运行Nginx服务器和基于Dockerfile构建Python Flask应用镜像的过程。这些基础知识将助力网络工程师理解Docker的核心功能,并为实际应用提供指导。
147 2
|
7月前
|
监控 Linux PHP
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
【02】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-2月12日优雅草简化Centos stream8安装zabbix7教程-本搭建教程非docker搭建教程-优雅草solution
196 20
|
10月前
|
开发者 Docker Python
从零开始:使用Docker容器化你的Python Web应用
从零开始:使用Docker容器化你的Python Web应用
417 4
|
10月前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用