一、制作DockerFile

  docker的镜像类似于用一层一层的文件组成。inspect命令可以查看镜像或容器的的信息,其中Layers就是镜像的层文件,只读不能修改,基于镜像创建的容器会共享这些层。下面我们先来学习一下dockerFile中的一些命令:

  1. form,构建的新镜像是基于哪个镜像

    • form centos:6
  2. maintainer,镜像维护者姓名或邮箱地址。
    • maintainer zaking。
  3. run,构建镜像时运行的shell命令。
    • RUN yum install httpd
  4. cmd,设置容器启动后默认执行的命令及其参数,但cmd能够被docker run后面的命令及参数替换。cmd给出的是一个容器的默认的可执行体。也就是容器启动以后,默认的执行的命令。重点就是这个"默认"。意味着,如果docker run没有指定任何的执行命令或者dockerfile里面也没有entrypoint,那么,就会使用cmd指定的默认的执行命令执行。同时也从侧面说明了entrypoint的含义,它才是真正的容器启动以后要执行命令。
    • CMD /usr/sbin/sshd -D
  5. expose,声明容器运行的端口。
    • EXPOSE 80 443
  6. env,设置容器内的环境变量。
    • ENV MYSQL_ROOT_PASSWORD 123456
  7. add,拷贝文件或目录到镜像中,如果是URL或者压缩包会自动下载和解压。
  8. copy,拷贝文件或目录到镜像。
    • COPY ./start.sh /start.sh
  9. entrypoint,配置容器启动时运行的命令。
    • ENTRYPOINT /bin/bash -c '/start.sh'
  10. volume,指定容器挂载点到宿主自动生成的目录或其它容器。
    • VOLUME ["/var/lib/mysql"]
  11. user,为 RUN CMD和ENTRYPOINT执行命令指定运行用户。
    • USER zaking
  12. workdir,为RUN CMD ENTRYPOINT COPY ADD 设置工作目录。
    • WORKDIR /data
  13. healthcheck,健康检查。
    • HEALTHCHECK --interval=5m --timeout=3s --retries=3 CMS curl -f htp://localhost
  14. arg,在构建镜像时指定一些参数。
    • ARG user

  ok,我们对基本的命令有了些许的了解,哦对,强调一下,以上写在dockerfile中的字段要大写,那么我们下面来实践一下,看如何自定义一个镜像:

  首先啊,我们来安装一下node(因为我们实践来创建一个node镜像):

yum install -y epel-release
yum install -y nodejs

  先安装附加软件包,然后就可以通过yum命令安装nodejs了。node -v查看下,没问题的。安装完node后,我们再来安装一个express的项目生成器,快速生成一个node项目:

npm install express-generator -g

  准备工作做好了,我们先来创建文件夹,文件的结构是这样的:

cd /
mkdir docker-hub
cd docker-hub
mkdir zakingnode
cd zakingnode
touch Dockerfile
express nodedemo
ls

  最后我们在docker-hub目录下,创建了一个nodedemo项目,和一个Dockerfile文件。 然后我们来编辑一下Dockerfile,内容如下:

# FROM表示该镜像继承的镜像 :表示标签
FROM node
LABEL name="zaking" version='1.0'
# COPY是将当前目录下的app目录下面的文件都拷贝到image里的/app目录中
COPY ./nodedemo /nodedemo
# WORKDIR 指定工作路径,类似于执行 cd 命令
WORKDIR /nodedemo
USER root
# RUN npm install 在/app目录下安装依赖,安装后的依赖也会打包到image目录中
RUN npm install
# EXPOSE 暴露3000端口,允许外部连接这个端口
EXPOSE 3000
ENV MYSQL_ROOT_PASSWORD 123456
CMD npm start

  其中LABEL是MAINTAINER的替代,新的Docker版本已经不支持MAINTAINER字段了。然后我们创建一个.dockerignore,类似于gitignore,就是docker不要打包到image中的文件。里面写上:

.git
node_modules

  很常见的配置。然后我们通过build命令,来生成这个镜像:

docker build -t nodedemo:1.0.0 .

  build后面的参数,-t用来指定image镜像的名称,后面还可以加冒号指定标签,如果不指定默认就是latest。-f指dockerfile文件的位置,可以直接设置'.',意味着在当前目录自己找。然后等会就成功了。我们通过docker image ls看一下:

  这样就ok了。下面我们看如何这个自定义镜像来运行容器。

docker run -p 3333:3000 nodedemo:1.0.0

  然后打开另一个命令行,访问一下刚才的启动的容器。其实就跟我们之前的例子没什么区别。当然,我们也可以进行手动启动。方式是删除之前Dockerfile中的CMD部分的命令。直接启动容器进入伪终端,在伪终端中手动npm start启动node服务。之前有过类似的例子,这里就不多说了。

  剩下的呢就是发布咱们自定义的容器了,这个之前也简单说过,没啥区别,就是注册个账号,push到远程,没了。

二、数据盘

  当你删除容器的时候,容器层里创建的文件也会被删除,如果有些数据你想要永久保存,比如Web服务器的日志,数据库中的数据等,那么就可以为容器创建一个数据盘。volume,就是Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。如果没有指定卷,则会自动创建。

  下面,我们就直接实践下有关的命令:

1、创建数据卷

  这样,我们就创建了一个名为nginx-vol的数据卷。通过inspect命令,可以查看详细的数据卷信息:

  然后,可以通过rm命令删除数据卷:

docker volume rm nginx-vol

2、数据卷挂载

  我们先来执行下下面的命令:

docker run -d --name=nginx1 --mount src=nginx-vol,dst=/usr/share/nginx/html -p 3000:80 nginx

  上面代码的意思就是,根据nginx镜像启动一个容器,名字叫做nginx1,如果不指定会有个自动生成的名字,指定挂载的数据卷的源文件名字是nginx-vol。回车后,还记inspect那个命令不,可以查看下Mountpoint路径下的文件:

  就是nginx,静态目录下,也就是我们刚才执行的命令中的参数设置的。然后我们在这个路径下,创建个html文件以供我们访问,随便啥html文件都行,写点内容就行。

  然后打开另一个命令窗口,来访问下:

  就成功了。额外要说的就是,该命令的还有另外一种简写形式,这里简单写下,都能看懂,不多说了:

docker run -d --name=nginx1 -v nginx-vol:/usr/share/nginx/html -p 3000:80 nginx

  下面,我们把正在运行中的容器都停止并删除,怎么删之前也实践很多次了。然后我们在/var/lib/docker/volumes/nginx-vol/_data,这个目录下查看下,发现之前创建的文件并没有消失。

3、指定数据盘

  我们先创建个mnt的目录,并在其中创建个hello.html文件:

  然后我们执行这样的命令:

docker run -v ~/mnt:/mnt -it --name logs centos bash

  大部分的意思大家都知道,就是多了个-v参数,-v实际上就是volume,/mnt:/mnt的意思就是宿主机的/mnt目录映射到容器内的/mnt目录。

  我们在容器内创建一个文件:

  下面是宿主机的:

  大家看到了是同步的对吧。在宿主机创建,也同样可以在容器内生成,这个大家可以自己去试一下。

4、指定数据盘容器

  我们先来执行下这个命令:

docker create -v ~/mnt:/mnt --name logger centos 

  这样就直接创建了一个具有指定数据卷容器的容器。稍后,我们就可以运行这个容器:

docker run --volumes-from logger --name loga -it centos bash

  我们就进入到容器的命令行内了,然后,我们就可以重复之前的试验了,这里不多说了哈,都一样。

三、Docker网络

  安装docker时,会自动创建三个网络:bridge、host、none。其中,none意味着关闭了容器的网络功能,对外界完全隔离。host意味着容器不会虚拟自己的网卡,分配ip等,而是使用宿主机的端口和ip,bridge模式会给每一个容器分配一个ip。

docker inspect bridge

  上面的命令可以查看docker容器中网络连接模式是bridge的有哪些。

  下面,我们先在后台运行两个容器:

docker run -d --name=nginx1 nginx
docker run -d --name=nginx2 nginx

  然后进入nginx2的伪终端:

docker exec -it nginx2 bash

  在nginx2的伪终端中,更新下apt,并安装一些依赖:

apt update
apt install -y inetutils-ping #ping
apt install -y dnsutils #nslookup
apt install -y net-tools #ifconfig
apt install -y iproute2 #ip
apt install -y curl #curl

  然后,看下/etc/hosts文件:

cat /etc/hosts

  然后就你在nginx1中也要做相同的操作,然后再nginx1中就可ping nginx2的ip了:

ping [nginx2‘s ip]

  然后呢,我们可以通过--net选项,来指定容器的网络连接模式:

docker run -d --name=nginx_none --net=none nginx

  然后就是,你还得安装之前的那些依赖,当然,你想要通过inspect来查看信息也可以,但是不够具体吧,我没还是进入到这个nginx_none容器的伪终端,安装一些依赖,这就不多说了吧。

  哎?卧槽?不对啊,安装报错了,嗯。。。报错就对了,因为你压根没网络啊。host模式也不麻烦,这里就不演示了,设置之后,你测试下跟宿主机的ip是否一直就ok咯。

  另外,host模式,启动的时候要注意端口占用的问题,也就是宿主机中启动了一个nginx,占用了80端口,那么,此时你是无法通过host模式启动容器的。那么,我们就需要学习一下端口映射:

# 让宿主机的8080端口映射到docker容器的80端口
docker run -d --name port_nginx -p 8080:80 nginx
# 查看主机绑定的端口
docker container port port_nginx

  也可以通过下面的命令,随机创建容器指向宿主机的端口号:

docker run -d --name random_nginx --publish 80 nginx
docker port random_nginx docker run -d --name randomall_nginx --publish-all nginx
docker run -d --name randomall_nginx --P nginx

  在docker中,我们也可以尝试自定义网络,网络可以创建多个,且每个网络的ip范围均不相同,docker的自定义网络中有一个DNS服务,可以通过容器名访问到主机。

docker network create --driver bridge myweb

  然后呢,我们就可以像使用桥接网络那样,使用我们的自定义网络:

docker run -d --name mynginx1  --net myweb nginx
docker run -d --name mynginx2 --net myweb nginx
docker exec -it mynginx2 bash

  哎?是不是跟最开始的例子有点类似,是的,没错,再重复之前的步骤下载安装,ping。没了。。。就这么简单。另外呢,假设你启动容器的时候没有指定网络,那么也可以在后续通过connect命令来指定网络:

docker run -d --name mynginx3   nginx
docker network connect myweb mynginx3
docker network disconnect myweb mynginx3

  当然,我们创建了网络之后,也可以通过命令来删除自定义的网络:

docker network rm myweb

四、Compose

  Compose通过一个配置文件来管理多个容器。在compose的配置文件中通过services来定义,然后使用docker-compose脚本来启动、停止和重启应用和应用中的服务以及所有依赖服务的容器。

  下面我们先来安装下compose:

curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

  然后查看下版本:

docker-compose -version

  这样就安装好了。

  然后,随便找个地方创建个目录,再创建个docker-compose.yml文件。

  然后,编辑yml配置文件,要注意的是yml有一套自己的规则,它是一个专门用来写配置文件的语言,这个大家可以百度去了解详细的规则,这里就不多说了,网上也有一些js转yaml的工具,我们下面compose配置如下:

version: '2'
services:
nginx1:
image: nginx
ports:
- "8080:80"
nginx2:
image: nginx
ports:
- "8081:80"

  然后,我们来学习一些docker-compose的命令:

命令 服务
docker-compose up 启动所有的服务
docker-compose up -d 后台启动所有的服务
docker-compose ps 打印所有的容器
docker-compose stop 停止所有服务
docker-compose logs -f 持续跟踪日志
docker-compose exec nginx1 bash 进入nginx1服务系统
docker-compose rm nginx1 删除服务容器
docker network ls 查看网络网络不会删除
docker-compose down 删除所有的网络和容器

  然后,我们就可以通过docker-compose命令去启动刚才配置的容器了:

docker-compose up

  怎么验证呢,再打开个终端窗口,curl你启动的ip就好了。之前玩过很多次了。然后,类似于之前的例子,我们也可以进入到刚刚通过docker-compose启动的nginx容器中:

  然后,可以跟之前的游戏一样,安装依赖,ping [nginx2'ip]。没啥意思,都一样。当然,类似于docker,我们也可以通过docker-compose命令,指定容器的网络和数据卷,区别的是,文件的存储位置不太一样,docker-compose数据卷存储在:/var/lib/docker/volumes/nginx-compose_data/_data中。我们来按照下面的配置参数配置一下:

version: '3'
services:
nginx1:
image: nginx
ports:
- "8081:80"
networks:
- "newweb"
volumes:
- "data:/data"
- "./nginx1:/usr/share/nginx/html"
nginx2:
image: nginx
ports:
- "8082:80"
networks:
- "default"
volumes:
- "data:/data"
- "./nginx2:/usr/share/nginx/html"
nginx3:
image: nginx
ports:
- "8083:80"
networks:
- "default"
- "newweb"
volumes:
- "data:/data"
- "./nginx3:/usr/share/nginx/html"
networks:
newweb:
driver: bridge
volumes:
data:
driver: local

  然后呢,类似之前的数据卷那章的测试方式:

docker exec nginx-compose_nginx1_1  bash
cd /data
touch 1.txt
exit
cd /var/lib/docker/volumes/nginx-compose_data/_data
ls

  一样的,一点意思都没有,一个理解了,换个工具,核心思路都是一样的。

  

五、实践

  基本上docker的内容我们就差不多学完了,下面我们来看下,如果创建一个node项目。我们先来看下目录结构,注意,这个项目在你本地创建,然后通过ftp传到服务器上即可:

├── docker-compose.yml
└── images
├── nginx
│ └── config
│ └── default.conf
└── node
├── Dockerfile
└── web
├── package.json
├── public
│ └── index.html
└── server.js

  文件夹及文件的内容就不说了哈,都能看得懂哦。然后呢,我们来看下各文件的代码:

default.conf:

upstream backend {
server node:3000;
}
server {
listen 80;
server_name localhost;
root /public;
index index.html index.htm; location /api {
proxy_pass http://backend;
}
}

package.json:

{
"scripts": {
"start": "node server.js"
},
"dependencies": {
"mysql": "^2.16.0"
}
}

server.js:

let http=require('http');
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'db',
user : 'zfpx',
password : '123456',
database : 'node'
}); connection.connect(); let server=http.createServer(function (req,res) {
connection.query('SELECT 2 + 2 AS solution', function (error, results, fields) {
if (error) throw error;
res.end(''+results[0].solution);
});
});
server.listen(3000);

Dockerfile:

FROM node
COPY ./web /web
WORKDIR /web
RUN npm install
CMD npm start

docker-compose.yml:

version: '2'
services:
node:
build:
context: ./images/node
dockerfile: Dockerfile
depends_on:
- db
web:
image: nginx
ports:
- "8080:80"
volumes:
- ./images/nginx/config:/etc/nginx/conf.d
- ./images/node/web/public:/public
depends_on:
- node
db:
image: mariadb
environment:
MYSQL_ROOT_PASSWORD: "root"
MYSQL_DATABASE: "node"
MYSQL_USER: "zfpx"
MYSQL_PASSWORD: "123456"
volumes:
- db:/var/lib/mysql
volumes:
db:
driver: local

  然后,把整个项目通过ftp传到服务器,在服务器的nodeapp目录下执行docker-compose up命令。如果启动失败了,别忘了是不是端口号被占用了。启动成功后,我们打开另外一个命令终端,curl访问地址即可。

  这个node例子跑不起来,后面再详细搞。

《前端运维》三、Docker--2其他的更多相关文章

  1. 新IT运维时代 | Docker运维之最佳实践-下篇

    上篇针对操作系统.主机配置.容器镜像.容器运行时四大方面分享一些Docker的运维经验,本篇将着重在Docker Daemon参数和权限两个方面进一步分享.(阅读上篇请点击右侧:新IT运维时代 | D ...

  2. Linux运维三:系统目录结构

    Linux系统目录结构官方参考:http://www.pathname.com/fhs/ 1:Linux树状目录结构图 下面目录中标红的是必须要掌握的! 2:根目录  目录 描述 / 第一层次结构的根 ...

  3. 新IT运维时代 | Docker运维之最佳实践-上篇

    容器技术的发展可以分为两个阶段,第一个阶段聚焦在IaaS层,仅仅把容器当做更轻量级虚拟机来使用,解决了应用运行时进程级资源隔离的问题:随着Docker的出现,容器虚拟化才有了统一的平台,由此容器技术发 ...

  4. 【linux】【jenkins】自动化运维三 整合gitlab、docker发布vue项目

    由于工作需要,这里我先创建一个vue的工程. 1.首先安装好gitlab相关插件:GitLab.GitLab Hook.NodeJS 插件安装参考:https://www.cnblogs.com/jx ...

  5. 《前端运维》三、Docker--1镜像与容器

    一.基本概念 如果我们想要让软件运行起来,首先要保证操作系统的设置,其次还需要依赖各种组件和库的正确安装.那么虚拟机就是一种带环境安装的一种解决方案,它可以实现在一种操作系统里面运行另外一种操作系统, ...

  6. Linux运维之docker虚拟化部署nginx

    一.Docker的概念 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱 ...

  7. 《前端运维》二、Nginx--1基本概念及安装

    一.Nginx基本概念 简单来说,Nginx就是一个代理服务器,什么是代理服务器呢?也就是当我们访问服务器的时候,请求不会直接请求到服务器,中间会有个代理,代理会预先于服务器处理这些请求,最后由代理决 ...

  8. 《前端运维》五、k8s--1安装与基本配置

    一.k8s基础概念与安装 k8s,即kubernetes是用于自动部署,扩展和管理容器化应用程序的开源系统.详细的描述就不多说了,官网有更详细的内容.简单来说,k8s,是一个可以操作多台机器调度部署镜 ...

  9. 《前端运维》五、k8s--3灰度发布、滚动更新与探针

    一.灰度发布 灰度发布是一种发布方式,也叫金丝雀发布,起源是矿工在下井之前会先放一只金丝雀到井里,如果金丝雀不叫了,就代表瓦斯浓度高.原因是金丝雀对瓦斯气体很敏感.灰度发布的做法是:会在现存旧应用的基 ...

随机推荐

  1. Solution -「HNOI 2009」「洛谷 P4727」图的同构计数

    \(\mathcal{Description}\)   Link.   求含 \(n\) 个点的无标号简单无向图的个数,答案模 \(997\). \(\mathcal{Solution}\)   首先 ...

  2. Solution -「CF 1391E」Pairs of Pairs

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的无向图,在其上找到一条包括不少于 \(\lceil\frac{n}2\rceil\ ...

  3. ASP.NET Core 6框架揭秘实例演示[05]:依赖注入基本编程模式

    毫不夸张地说,整个ASP.NET Core就是建立在依赖注入框架之上的.ASP.NET Core应用在启动时构建管道所需的服务,以及管道处理请求使用到的服务,均来源于依赖注入容器.依赖注入容器不仅为A ...

  4. mongodb4.x 集群搭建

    下载包 官网选择合适的操作系统版本下载tgz包 https://www.mongodb.com/download-center/community 部署结构 集群结构 典型的三分片Mongo集群如下图 ...

  5. git忽略文件权限检查

    如题  每个人本地设置不同 系统不同  环境不同  很有可能在团队开发的时候进行 不同文件权限的设置 但是如果大家都把这种权限的设置传上去 那么所有人的就都乱的 如果要去掉的话 第一步 进入这个项目的 ...

  6. 使用第三方插件pagination在页面实现分页功能

    1.导入相应的js和css文件 2.在相应的页面映入pagination.js和pagination.css 3.将页面的分页代码替换为pagination动态生成的分页代码 4.编写js代码

  7. java宝典笔记(一)

    第四章java基础知识 4.1基本概念 一.java优点 1.面向对象(封装.继承.多态) 2.可移植性.平台无关,一次编译,到处运行.Windows,Linux,macos等.java为解释性语言, ...

  8. jmeter分布式导致重复登录的问题、以及写txt、csv、统计行数

    经常收到微信好友的各种问题咨询,今天分享一个比较有代表性的,希望对大家有所帮助. 一位微信好友的提问 问题如下: 问题分析 先简单介绍下服务端的处理逻辑,关于登录,服务端的逻辑一般是:校验用户名.密码 ...

  9. 什么是Ajax?全面了解

    一:Ajax 引入Ajax: 我们知道,前端页面想要和后端进行数据交互,可以通过以下方式 将参数添加到url中,后端通过get方式从url中获取数据 GET请求 前端页面通过form表单,将数据以ge ...

  10. 商业智能BI必备的特性,BI工具介绍

    商业智能BI的本质 对企业来说,商业智能BI不能直接产生决策,而是利用BI工具处理后的数据来支持决策.核心是通过构建数据仓库平台,有效整合数据.组织数据,为分析决策提供支持并实现其价值. 传统的DW/ ...