技术

Docker从入门到入门

微信扫一扫,分享到朋友圈

Docker从入门到入门
0 0

Docker简述

以前做开发的小伙伴经常会遇到这样的问题,在本地测试环境跑的代码好好的,发到生产环境就是遇到了问题。各种排查千辛万苦之后发现,是配置环境、软件版本、操作系统的不同导致。这时候要么换线上,要么换线下。要是遇到开发小伙伴的个人电脑上开发环境版本不同,你是win,我是mac,他是linux的时候,更是抓狂。

Docker的诞生就是为了解决这种问题。沙箱机制的虚拟容器引擎跟传统的虚拟化不同。传统的虚拟机从底层硬件级别就开始进行模拟:硬件层面(cpu,显卡,网卡,硬盘,内存,串口)->操作系统(win,linux,mac)->软件(nginx,chrome)等等全方位的模拟,独占了内存,算力等等。docker是指单纯的从软件层面进行虚拟即可,底层有hostOS进行支撑,他自己只要docker的守护进行代替,上层建立不同的容器,不同的容器之间相互隔离。

官网举例就很贴切,docker就是集装箱。原来拉水果的船只拉水果,放上化工品肯定出问题,你需要不同的船。而用了docker之后,大船上面可以放很多的集装箱,你需要的东西在你自己的集装箱里面封好就可以了。而且这个集装箱拉到其他船上也一样的。

重要概念

Docker是自己是容器引擎,是一个装容器大船。上面通过run命令跑起来的实例就是容器container。作为标准放在这里的容器模板就是镜像image,可以理解为一些静态文件。而存放这些镜像静态文件,即为仓库hub

容器和镜像的关系可以理解为,声明的对象和实例化以后的对象的关系。

常用命令

注意,docker命令默认只能root用户执行,下面命令遇到dial unix /var/run/docker.sock: connect: permission denied权限不足的问题,命令前加sudo

$ docker ps //查看当前运行的容器列表
$ docker ps -a //查看所有运行的容器列表
$ docker images //查看镜像,包含来源、标签、id、创建时间、大小
$ docker search [镜像关键词]  //搜索已有镜像
$ docker commit -m="描述信息" -a="镜像作者" [容器 ID] [创建的镜像名] //更新镜像
$ docker stop [容器ID] //停止容器
$ docker start [容器ID]  //启动曾经启动过的容器列表
$ docker rm [容器ID] //删除容器,可多个
$ docker rmi [镜像ID] //删除镜像,可多个
$ docker inspect [容器ID] | grep IPAddress  //查看容器IP地址

//进入一个正在运行的容器
$ docker exec -it 775c7c9ee1e1 /bin/bash

docker run 启动容器参数详解

-d //启动后直接进入后台,并返回容器ID
-i //以交互模式运行容器,通常与 -t 同时使用
-t //为容器重新分配一个伪输入终端,通常与 -i 同时使用
-P //随机端口映射,容器内部端口随机映射到主机的高端口
-p //指定端口映射,格式为: -p 8080:80 宿主端口:容器端口
--name="nginx-lb" //为容器指定一个名称。
--volume , -v	//文件/文件夹映射,格式为: -v /a:/a 宿主文件:容器文件
--link=[]  //添加链接到另一个容器

最后加上你要选择的镜像名称

Docker的安装由于不同操作系统之间的安装差别挺大,自行找官网对应版本的安装教程。不过下面docker三剑客的第一个就要当场了,就是为了简化docker安装过程,快速虚拟出新的docker主机。

Dockerfile构建镜像

我们通过 docker build 命令从0构建一个镜像,为此我们需要创建一个Dockerfile文件来告诉docker一步一步来如何做。

常用语法说明

FROM    centos:6.7      //指定从哪个镜像开始
MAINTAINER      Fisher "fisher@sudops.com"  // 维护人员信息作者和邮箱

ARG user # ARG user=root //构建镜像时指定参数
RUN     /bin/echo 'root:123456' |chpasswd   // 执行命令,直接运行具体命令即可
EXPOSE  22  //开启端口
WORKDIR /data  //RUNCMDENTRYPOINT以及COPYAND设置工作目录
ENV NGINX_HOST=tingno.com //设置环境变量
COPY ./start.sh /start.sh  //复制文件或目录
VOLUME ["/var/lib/mysql"]  //指定容器挂载点到宿主机自动生成的目录或其他容器
ADD index.html /var/www/html/index.html     //复制文件
CMD     /usr/sbin/sshd -D   //当启动容器时执行的脚本文件

最最简单的案例 直接用vue的脚手架,新建一个项目,在项目文件夹下面加入dockerfile文件。这是Dockerfile的文件内容。

FROM hub.c.163.com/library/nginx:latest
MAINTAINER Tingno "admin@tingno.com"
ADD ./dist /usr/share/nginx/html

WORKDIR /usr/share/nginx/html
RUN echo '这是一个本地构建的nginx镜像' > a.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

然后执行 docker build -t demo2 . 结果如下:

docker@vue:/data/dockerdemo$ docker build -t demo3 .
Sending build context to Docker daemon  614.9kB
Step 1/7 : FROM hub.c.163.com/library/nginx:latest
 ---> 46102226f2fd
Step 2/7 : MAINTAINER Tingno "admin@tingno.com"
 ---> Using cache
 ---> c6455e731908
Step 3/7 : ADD ./dist /usr/share/nginx/html
 ---> Using cache
 ---> 86f6089a6b83
Step 4/7 : WORKDIR /usr/share/nginx/html
 ---> Using cache
 ---> daa21c35ad15
Step 5/7 : RUN echo '这是一个本地构建的nginx镜像' > a.html
 ---> Running in 862ea41d2033
Removing intermediate container 862ea41d2033
 ---> 1775e0d786eb
Step 6/7 : EXPOSE 80
 ---> Running in 329ce829d6d9
Removing intermediate container 329ce829d6d9
 ---> c74d77449798
Step 7/7 : CMD ["nginx", "-g", "daemon off;"]
 ---> Running in 936f82eb6306
Removing intermediate container 936f82eb6306
 ---> cc6cbe04ada6
Successfully built cc6cbe04ada6
Successfully tagged demo3:latest

里面每一步,都会生成一个新的中间镜像,docker images -a 一大堆。 另外,这里就是讲所有当前文件夹内容都发送给引擎去进行生成镜像,但是很多文件都不需要,这里就用到了.dockerignore文件,他的作用和.gitignore文件一样的,基本上通常屏蔽的内容都一样,只是代码文件和生成项目文件反过来就是了。

这时候再来运行启动容器命令,就可以通过你的本机来进行访问了。

docker run -d -p 8083:80 demo3

如果发现你生成的镜像启动就死掉了,而其他的官方镜像都可以的话,说明你的构建命令有问题,自行排查构建文件。

前端迭代发布流程

学习到这里,我们做前端的小伙伴基本上就差不多了,毕竟平时开发就是单纯的把代码git push完发上去。 后续的自动化部署的内容,其实就是对应的引擎自动去git代码仓库里面pull最新的代码,然后自动npm run build前端打包, 然后docker build成镜像文件,关掉老的容器,用新的镜像文件启动新的容器。项目就算迭代发布成功了,这其中最最重要的就是dockerfile文件了。

这时候问题来了,一般稍微大点儿的项目,不可能只有一个前端服务,还有可能有后端接口,数据库,网关,消息队列等等,这些都需要一个镜像一个镜像的打包、启动。分享一个项目给其他人的时候要完整搭建这些,就有了docker三剑客之一compose

Docker Componse

先来看定义: Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

docker-compose命令想要使用的话,需要安装,安装命令如下,里面版本号自行更换,而且这是国内安装链接,你懂的

$ sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

YML文件就是告诉docker引擎,我要启动好几个容器,都要做啥做啥做啥。这里也有yaml文件的入门链接 yaml入门教程, 帮助理解的话,就是json的另一种写法。

配置参数说明

version:3
services: //需要启动的服务列表
services.[name] //具体的服务名称,这里发服务可以自定义
services.[name].build //指定为构建镜像Dockerfile
services.[name].depends_on //设置依赖关系,这里面的服务启动了,当前服务才可以启动。
services.[name].images //指定容器运行的镜像
services.[name].deploy //有关服务部署的内容,只有在swarm模式下才有用。
services.[name].entrypoint  //覆盖容器默认的 entrypoint
services.[name].expose //暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数:
services.[name].volumes //将主机的数据卷或着文件挂载到容器里。
services.[name].networks //配置容器链接的网络
services.[name].secrets  //敏感数据

networks:[name] //当前部署要用到的网络具体配置
secrets:[name] //当前部署要用到的敏感数据的具体配置
volumes:[name] //当前部署要用到的数据卷的具体配置

简单举例 我们把上面Dockerfile文件拆解下来到compose文件里面就是如下

version: '3'
services:
  web:
    container_name: web
    image: hub.c.163.com/library/nginx
    ports:
      - "8080:80"
    volumes:
      - ../dockerdemo/dist:/usr/share/nginx/html
    expose: 
      - "80"

然后启动一下对应的yml文件

$ docker-compose -f demo.yml up -d

也是相当于启动了一个镜像服务,其他更多的配置就可以去参照比较复杂的,这里推一个配置 lnmp环境的容器编排项目。链接

到这里,我们开始从最开始的docker命令启动容器 —> 使用Dockerfile一键启动完整容器 -> 使用docker-compose一键启动好几个容器。

如果你的项目就一台主机,恭喜,到这里就完全够你用了。再后面我们要说的是docker三剑客成员docker-swarm,将上面的链条进一步延长,我们可以同时在好多机器上,启动好多容器。但是前提,我们要很方便的造出来很多主机,这里就是Docker三剑客 Docker Machine,目的就是很方便的造很多主机。

Docker Machine

Docker Machine 是一种可以让您在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机。

docker是用来管理船上的集装箱,Docker-Machine用来管理大船的。使用 docker-machine 命令,您可以启动,检查,停止和重新启动托管主机,也可以升级 Docker 客户端和守护程序,以及配置 Docker 客户端与您的主机进行通信。安装 Docker Machine 之前你需要先安装 Docker。

常用命令

$ docker-machine ls  //列出现在可用的机器,包含主机名称,状态,驱动类型,ip,docker版本,错误信息等等
$ docker-machine create --driver [驱动类型] [主机名称]   //新建主机,驱动类型可为virtualbox 或者其他
$ docker-machine ip [主机名称] //看看主机的IP
$ docker-machine stop [主机名称]  //停止机器
$ docker-machine start [主机名称]  //启动机器
$ docker-machine ssh [主机名称]   //进入机器

这里偷偷来一条挂载virtualbox共享文件夹的机器内命令 sudo mount -t vboxsf share /data

这时候,最起码造3台docker主机来,下面我们就要在这写主机上来用做容器编排了。

偷偷来一个一把可以创建好多主机的命令,只要你的内存够。

$ for NODE in `seq 1 5`; do docker-machine create –driver virtualbox “node-${NODE}”; done

Swarm集群管理

Docker Swarm是Docker的集群管理工具,将Docker本身从主机这个单元抽象出来,转变成虚拟的Docker主机,你不再需要关注某个docker容器运行在具体的哪台Docker主机上了,统一都是有Swarm管理单元来进行管理。相应的Swarm就分为了管理节点master,和工作节点worker。而对应的命令,就是先任命老大,干活的找到老大,老大派活儿,后面比较好的,大家一起干活。

理论上老大能一起干活,但是在生产环境里,不建议这么做,而且我们还会任命副的老大用来接替万一挂了的老大。

对应如下整个项目内容查看的一些操作命令:

  • 第一波是本身swarm的管理,相当于公司顶层设计。
$ docker swarm init --advertise-addr [IP] //创建一个新公司
$ docker swarm join //加入新公司
$ docker swarm join-token  //管理加入公司的邀请码
$ docker swarm update //调整位置
$ docker swarm leave //离开公司
  • 第二波是node节点管理,公司的干活的人头管理
$ docker node ls //查看集群中都有哪些节点
$ docker node promote [节点名称/ID]  //提升某个节点为管理节点
$ docker node demote [节点名称/ID]  //降级某个节点为干活节点
$ docker node inspect [节点名称/ID] --pretty //查看节点信息
  • 第三波是公司要开始做项目了,进行项目管理
$ docker stack deploy [项目名称] --compose-file=[配置文件地址].yml   //项目部署
$ docker stack ls  //查看项目列表
$ docker stack services [项目名称] //查看项目的任务列表
$ docker stack ps [服务名称]  //列出整个项目里面节点上的任务,包括没有运行的
$ docker stack rm [服务名称]  //移除一个或者多个项目
  • 第四波是具体项目里面的任务管理
$ docker service ls //查看集群中运行发服务
$ docker service ps [服务名称] //查看具体的服务
$ docker service inspect --pretty [服务名称/ID]
$ docker service create --name [服务名称] --replicas [分配节点数量] -p 80:80 [镜像名称]  //新增一个服务
$ docker service rm [服务名称] //删除服务
$ docker service scale [服务名称/ID]=[调整后的数量]  //调整服务节点数量

对于Swarm整个公司来说,集群上的每台docker主机都是一个node节点一个干活的人,发布总的项目是堆stack, 发布下去的总项目里面的任务服务service,每个节点被摊牌到具体的任务就是tasks。所以每个人手上做的具体的活儿就是tasks,tasks是最小的单元,对应每个docker机器上的容器container。

在前面的前端项目里面来一个简单的compose.yml文件,配置如下

version: '3'
services:
  web: 
    image: hub.c.163.com/library/nginx:latest
    ports:
      - "8080:80"
    networks:
      - frontend
    volumes:
      - "./dist:/usr/share/nginx/html"
    deploy:
      replicas: 3
networks:
  frontend:

下面是具体流程如下:

//第一步:任命老大。就是在master机器上进行swarm初始化,下面会生成一条认老大的命令,记得复制好
$ docker swarm init --advertise-addr 192.168.99.100

//第二步:认老大。在所有worker机器上执行老大给的命令,里面有说老大是谁,还有暗号。
$ docker swarm join --token SWMTKN-1-37ruaep41ju82rxt6zus7c83xuyszzowethoncv8itekso0vu8-ab7vksim9wk40xapu5mlwxwew 192.168.99.100:2377

//第三步:老大派活儿。创建服务
$ docker stack deploy demo --compose-file=compose.yml

//第四步:大家干活。任务执行
$ docker stack ls

这时候,使用浏览器具体访问下你启动的IP,看到你自己的内容,就算ok了。

文末

整个从前到后把docker的内容梳理完之后,就是不断的简化过程。 为了抹平不同环境之间的差别,有了docker。 为了方便打包镜像,有了Dockerfile。 为了在一台机器上生成项目用给镜像,有了docker-compose。 为了在好多台机器上部署项目,有了docker-swarm。 为了快速创建docker主机,有了docker-machine。

另外,容器编排技术swarm的对手k8s现在风头更胜,两者的区别就像是记事本和编辑器的区别。都可以用,不过k8s更加复杂,你需要学习更多的内容,可以实现更多的可能。

如标题,本文为入门,主要帮助理解。欢迎各路大神拍砖撒花点赞转发。

半拉子前端的自留地,发际线逐渐后移的抠脚大叔!

【爬坑日记】git大小写不敏感导致错误的大坑

上一篇

你也可能喜欢

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片

体验小程序

标签地图

分类

EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00
      Docker从入门到入门

      长按储存图像,分享给朋友

      微信扫一扫

      微信扫一扫