超全的Docker学习教程(Linux云计算从入门到精通)

 

CONTENTS

 

一、docker简介

1.1 docker相关概念

1.2 docker应用场景

1.3 docker和虚拟机比较

二、初识docker

2.1 安装docker

2.2 初识docker-docker架构

2.3 配置镜像加速器

三、docker命令详解

四、docker容器数据卷

五、docker应用部署

5.1 部署mysql

5.2 部署Tomcat

5.3 部署nginx

5.4 部署redis

六、docker compose批量管理容器

七、容器的迁移与备份

八、Docker-file开发自己的镜像

九、私有仓库的搭建与使用

 


一、docker简介

1.1 docker相关概念

  • Docker 是一个开源的应用容器引擎,诞生于 2013 年初,基于 Go 语言实现, dotCloud 公司出品(后改名为Docker Inc
  • Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。
  • 容器是完全使用沙箱机制,相互隔离,容器性能开销极低
  • Docker 17.03 版本之后分为 CECommunity Edition: 社区版) 和 EEEnterprise Edition: 企业版)(后面我会装CE版)

1.2 docker应用场景

简化配置、代码流水线管理、提高开发效率、隔离应用、整合服务器、调试能力、多租户环境、快速部署(具体可参考下面的博客)

docker八大应用场景

而对于写代码的程序员来说,代码接触到好几个环境:开发环境、测试环境以及生产环境:

当代码从其中一个环境转移到另一个环境时,常常会遇见问题(明明在自己的机器上可以运行,转移到其他机器上时就出现问题了?)。这一般都是由于java环境配置不同而导致的。如果有了容器后,可以将自己的jdk环境和项目封装在一个容器中进行交付,就可以解决这个问题。通俗讲是容器可以解决代码之间水土不服的问题哦!

超全的Docker学习教程(Linux云计算从入门到精通)_第1张图片

 

docker和虚拟机比

1.3 docker和虚拟机比较

 对于之前玩过虚拟机的小伙伴似乎也想知道虚拟机和docker之间的区别有哪些。先看看下面的图对比下:

超全的Docker学习教程(Linux云计算从入门到精通)_第2张图片

再来了解下容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署

  • 容器镜像是轻量的、可执行的独立软件包 ,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。
  • 容器化软件在任何环境中都能够始终如一地运行。
  • 容器赋予了软件独立性,使其免受外在环境差异的影响,从而有助于减少团队间在相同基础设施上运行不同软件时的冲突。

相同:

  • 容器和虚拟机具有相似的资源隔离和分配优势

不同:

  • 容器虚拟化的是操作系统,虚拟机虚拟化的是硬件
  • 传统虚拟机可以运行不同的操作系统,容器只能运行同一类型操作系统
具体的差别可以看下面这个表:

超全的Docker学习教程(Linux云计算从入门到精通)_第3张图片

二、初识docker

2.1 安装docker

Docker可以运行在MACWindowsCentOSUBUNTU等操作系统上,本课程基于CentOS 7 安装Docker。官网:https://www.docker.com(本博客是在腾讯云购买云服务器进行操作的。操作系统的版本为centos7,建议用虚拟机,或者在腾讯云上购买服务器,按量收费,适合做实验

 

还有一个安装docker的链接可供参考:https://www.jianshu.com/p/1e5c86accacb

2.2 初识docker-docker架构

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

超全的Docker学习教程(Linux云计算从入门到精通)_第4张图片

 

 

2.3 配置镜像加速器

默认情况下,将来从docker hubhttps://hub.docker.com/)上下载docker镜像,太慢。一般都会配置镜像加速器:

  • USTC:中科大镜像加速器(https://docker.mirrors.ustc.edu.cn
  • 阿里云
  • 网易云
  • 腾讯云
 
 

下面我们来配置阿里云镜像加速器(推荐安装1.10.0以上版本的docker客户端):

mkdir -p /etc/docker

tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://c63ol3wn.mirror.aliyuncs.com"]
}
EOF

cat /etc/docker/daemon.json 
systemctl daemon-reload 
systemctl restart docker

三、docker命令详解

3.1 服务相关命令

  • 启动docker服务器:systemctl start docker
  • 停止docker服务:systemctl stop docker
  • 重启docker服务:systemctl restart docker
  • 查看docker服务状态:systemctl status docker
  • 设置开机启动docker服务:systemctl enable docker

3.2 镜像相关命令

查看镜像: 查看本地所有的镜像

docker images

docker images –q       # 查看所用镜像的id

搜索镜像:从网络中查找需要的镜像

docker search 镜像名称

拉取镜像:Docker仓库下载镜像到本地,镜像名称格式为 名称:版本号,如果版本号不指定则是最新的版本。如果不知道镜像版本,可以去docker hub 搜索对应镜像查看。

docker pull 镜像名称

删除镜像: 删除本地镜像

docker rmi 镜像id # 删除指定本地镜像

docker rmi `docker images -q`  # 删除所有本地镜像

3.3 容器相关命令

查看容器:

docker ps # 查看正在运行的容器

docker ps –a # 查看所有容器

创建并启动容器:

docker run 参数

参数说明:

  • -i:保持容器运行。通常与 -t 同时使用。加入it这两个参数后,容器创建后自动进入容器中,退出容器后,容器自动关闭。
  • -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用。
  • -d:以守护(后台)模式运行容器。创建一个容器在后台运行,需要使用docker exec 进入容器。退出后,容器不会关闭。
  • -it 创建的容器一般称为交互式容器,-id 创建的容器一般称为守护式容器
  • --name:为创建的容器命名。

 

进入容器:

docker exec 参数 # 退出容器,容器不会关闭

停止容器:

docker stop 容器名称

启动容器:

docker start 容器名称

删除容器:如果容器是运行状态则删除失败,需要停止容器才能删除

docker rm 容器名称

查看容器信息

docker inspect 容器名称

四、docker容器数据卷

这个章节可以参考这篇博客,写的很详细哦(偷个懒):

https://www.cnblogs.com/kevingrace/p/6238195.html

五、docker应用部署

5.1 部署mysql

Docker容器中部署MySQL,并通过外部mysql客户端操作MySQL Server

实现步骤:

(1)搜索mysql镜像

超全的Docker学习教程(Linux云计算从入门到精通)_第5张图片

(2)拉取mysql镜像,一般我们会选择stars越多的镜像,毕竟受欢迎嘛,也可以加上指定的版本号。

docker pull mysql:5.6

(3)创建容器,设置端口映射、目录映射

# 在/root目录下创建mysql目录用于存储mysql数据信息
mkdir ~/mysql
cd ~/mysql
docker run -id \-p 3307:3306 \--name=a_mysql \-v $PWD/conf:/etc/mysql/conf.d \-v $PWD/logs:/logs \-v $PWD/data:/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=123456 \mysql:5.6

#参数说明:
-p 3307:3306:将容器的 3306 端口映射到宿主机的 3307 端口。
-v $PWD/conf:/etc/mysql/conf.d:将主机当前目录下的 conf/my.cnf 挂载到容器的 /etc/mysql/my.cnf。配置目录
-v $PWD/logs:/logs:将主机当前目录下的 logs 目录挂载到容器的 /logs。日志目录
-v $PWD/data:/var/lib/mysql :将主机当前目录下的data目录挂载到容器的 /var/lib/mysql 。数据目录
-e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。

 了解下端口映射的概念:

 超全的Docker学习教程(Linux云计算从入门到精通)_第6张图片

(4)如果你是虚拟机的可以直接关掉防火墙,我是云主机,所以也要去编辑下出站规则(实验嘛,全放通好勒)。

超全的Docker学习教程(Linux云计算从入门到精通)_第7张图片

 (5)进入容器并操作mysql

#进入a_mysql容器中
docker exec -it a_mysql bash

#登录mysql
mysql -uroot -p123456

#创建test数据库做测试用
mysql> create database test;
mysql> use mysql;

mysql> select host,user from user;
+-----------+------+
| host      | user |
+-----------+------+
| %         | root |
| localhost | root |
+-----------+------+
#开始给root授权可以远程访问,这边注意了,因为这边只是测试用的,实际生产环境下权限不能这么给的哦
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;

(6)客户端连接mysql

我利用workbench连接mysql的:

超全的Docker学习教程(Linux云计算从入门到精通)_第8张图片

在这可以看到我刚才创建的数据库test

超全的Docker学习教程(Linux云计算从入门到精通)_第9张图片

 

5.2 部署Tomcat

Docker容器中部署Tomcat,并通过外部机器访问Tomcat部署的项目。

#1 搜索tomcat镜像
docker search tomcat
#2 拉取tomcat镜像
docker pull tomcat
#3 创建容器,设置端口映射、目录映射 
docker run -di --name=mytomcat -p 9000:8080 -v /usr/local/tomcat/webapps:/usr/local/tomcat/webapps tomcat 

注意:宿主机的/usr/local/tomcat/webapps这个目录是用来放置网页相关的东西的,默认访问ip:9000是没法访问的,找不到网页,因为还没在webapps目录中放东西,但如果我在创建docker容器的时候不进行目录的挂载的话,浏览器访问就应该是Tomcat的默认访问页面,在后面的docker compose中会说到这个。

 

5.3 部署nginx

直接拉取镜像,启动镜像,然后通过浏览器访问:

需要注意的是:nginx默认访问端口就是80,如果被占用了80端口,那么在指定映射的时候可以改变宿主机的端口映射,在访问时也需要带上端口号。

docker pull nginx  #拉取镜像
docker images      #查看镜像
docker run -id --name=mynginx -p 80:80 nginx    #运行容器

浏览器中访问自己的IP,默认80: 

超全的Docker学习教程(Linux云计算从入门到精通)_第10张图片

 

5.4 部署redis

(1)搜索redis镜像

docker search redis

(2)拉取redis镜像

docker pull redis:5.0

(3)创建容器,设置端口映射

docker run -id --name=myredis -p 6379:6379 redis:5.0

(4)可以进入容器中看看

docker exec -it myredis /bin/bash

(5)登入本机测试看看 

root@fb367ad13134:/data# cd /usr/local/bin/
root@fb367ad13134:/usr/local/bin# ls
docker-entrypoint.sh  redis-benchmark  redis-check-rdb  redis-sentinel
gosu                  redis-check-aof  redis-cli        redis-server
root@fb367ad13134:/usr/local/bin# ./redis-cli 
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set str test
OK
127.0.0.1:6379> get str
"test"

(6)使用外部机器连接redis,先下载个客户端Redis

yum install redis.x86_64 -y
redis-cli -h 129.211.186.178 -p 6379
129.211.186.178:6379> set str test2
OK
129.211.186.178:6379> get str
"test2"
129.211.186.178:6379> 

 

六、docker compose批量管理容器

Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。它是一个定义和运行多容器的docker应用工具。使用compose,你能通过YMAL文件配置你自己的服务,然后通过一个命令, 你能使用配置文件创建和运行所有的服务。所以我们就用docker compose来实现容器的快速编排按照一定的业务规则批量管理容器)。

使用步骤:

1.利用 Dockerfile 定义运行环境镜像
2.使用 docker-compose.yml 定义组成应用的各服务
3.运行 docker-compose up 启动应用

下面我们开始利用docker compose批量部署mysql,Tomcat,nginx和Redis

(1)安装Docker Compose

# Compose目前已经完全支持Linux、Mac OS和Windows,在我们安装Compose之前,需要先安装Docker。下面我们以编译好的二进制包方式安装在Linux系统中。 
curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# 设置文件可执行权限 
chmod +x /usr/local/bin/docker-compose
# 查看版本信息 
docker-compose -version

如果卸载Docker Compose执行下面的命令,我就不操作了。

# 二进制包方式安装的,删除二进制文件即可
rm /usr/local/bin/docker-compose

(2)创建目录

#创建docker-compose目录

mkdir ~/docker-compose

cd ~/docker-compose

(3)编辑docker-compose.yml 文件

先大概了解下配置的一个容器信息,注意它们各处的网络(比如下面dev和pro都是自定义的网络),属于同一网络的容器可以互相访问.

超全的Docker学习教程(Linux云计算从入门到精通)_第11张图片

 配置文件可参考下面:

version: '3'
services:
  nginx1:
    image: nginx
    ports:
      - 80:80
    container_name: "nginx1"
    networks:
      - pro
  redis1:
    image: redis
    ports:
      - "6379:6379"
    container_name: "redis1"
    networks:
      - dev
  mysql1:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: "root"
    ports:
      - "3306:3306"
    container_name: "mysql1"
    networks:
      - dev
  web1:
    image: tomcat
    ports:
      - "9090:8080"
    container_name: "web1"
    networks:
      - dev
      - pro
networks:
  dev:
    driver: bridge
  pro:
    driver: bridge

 (4)重启docker,并设置docker compose后台启动:

systemctl restart docker
#执行下面命令它会自动创建容器和网络,有出错信息注意yml文件的语法格式
docker-compose up -d

 (5)运行检测

超全的Docker学习教程(Linux云计算从入门到精通)_第12张图片

咱们访问Tomcat试试看,如果又出现404界面,不用担心:进入容器并把webapps.dists里的文件copy到webapps中。

docker exec -it web1 /bin/bash
    
cp webapps.dist/* webapps

 然后我们打开浏览器访问试试,大功告成。

超全的Docker学习教程(Linux云计算从入门到精通)_第13张图片

 

 

 

 

 

七、容器的迁移与备份

目标:能够将容器保存为镜像,备份,恢复镜像再启动以恢复的镜像作为基础的容器。
       分析:在当前的容器中安装了各种组件;期望在其他服务器上也能快速拥有该容器的一切环境;可以将当前的容器制作为一个镜像,再将该奖项复制到其他服务器,其他服务器再基于镜像运行容器。

  • 1.将容器保存为一个镜像;
  • 2.备份镜像;
  • 3.恢复镜像;
  • 4.基于镜像运行容器
     

看看下面的图片有助于了解迁移备份的流程:

超全的Docker学习教程(Linux云计算从入门到精通)_第14张图片

其中涉及到的命令有:

  • docker commit  将容器保存为镜像
  • docker save     将镜像备份为tar文件
  • docker load     根据tar文件恢复为镜像
     

下面直接实战把(下面都是本地恢复,不同服务器之间也是可以的,只要把tar包copy到其他服务器就好了): 

 

超全的Docker学习教程(Linux云计算从入门到精通)_第15张图片

我们来运行mynginx容器并检测一下能否正常使用:

#因为前面我用docker compose运行了nginx1,所以先把它停掉
docker stop nginx1
#运行mynginx
docker run -id --name=mynginx -p 80:80 nginx 

 访问正常:

超全的Docker学习教程(Linux云计算从入门到精通)_第16张图片

八、Docker-file开发自己的镜像

8.1 Dockerfile文件概念:

通过前面的学习我们知道要获得镜像,可以从Docker仓库中进行下载。那如果我们想自己开发镜像,就可以利用Dockerfile。
Dockerfile其实就是一个文本文件, 由一系列命令和参数构成,Docker可以读取Dockerfile文件并根据Dockerfile文件的描述来构建镜像。
Dockerfile文件内容一般分为4部分:

  1. 基础镜像信息
  2. 维护者信息
  3. 镜像操作指令
  4. 容器启动时执行的指令

8.2 Dockerfile指令,常见的加粗显示

关键字 作用 备注
FROM 指定父镜像 指定dockerfile基于那个image构建
MAINTAINER 作者信息 用来标明这个dockerfile谁写的
LABEL 标签 用来标明dockerfile的标签 可以使用Label代替Maintainer 最终都是在docker image基本信息中可以查看
RUN 执行命令 执行一段命令 默认是/bin/sh 格式: RUN command 或者 RUN ["command" , "param1","param2"]
CMD 容器启动命令 提供启动容器时候的默认命令 和ENTRYPOINT配合使用.格式 CMD command param1 param2 或者 CMD ["command" , "param1","param2"]
ENTRYPOINT 入口 一般在制作一些执行就关闭的容器中会使用
COPY 复制文件 build的时候复制文件到image中
ADD 添加文件 build的时候添加文件到image中 不仅仅局限于当前build上下文 可以来源于远程服务
ENV 环境变量 指定build时候的环境变量 可以在启动的容器的时候 通过-e覆盖 格式ENV name=value
ARG 构建参数 构建参数 只在构建的时候使用的参数 如果有ENV 那么ENV的相同名字的值始终覆盖arg的参数
VOLUME 定义外部可以挂载的数据卷 指定build的image那些目录可以启动的时候挂载到文件系统中 启动容器的时候使用 -v 绑定 格式 VOLUME ["目录"]
EXPOSE 暴露端口 定义容器运行的时候监听的端口 启动容器的使用-p来绑定暴露端口 格式: EXPOSE 8080 或者 EXPOSE 8080/udp
WORKDIR 工作目录 指定容器内部的工作目录 如果没有创建则自动创建 如果指定/ 使用的是绝对地址 如果不是/开头那么是在上一条workdir的路径的相对路径
USER 指定执行用户 指定build或者启动的时候 用户 在RUN CMD ENTRYPONT执行的时候的用户
HEALTHCHECK 健康检查 指定监测当前容器的健康监测的命令 基本上没用 因为很多时候 应用本身有健康监测机制
ONBUILD 触发器 当存在ONBUILD关键字的镜像作为基础镜像的时候 当执行FROM完成之后 会执行 ONBUILD的命令 但是不影响当前镜像 用处也不怎么大
STOPSIGNAL 发送信号量到宿主机 该STOPSIGNAL指令设置将发送到容器的系统调用信号以退出。
SHELL 指定执行脚本的shell 指定RUN CMD ENTRYPOINT 执行命令的时候 使用的shell

 

8.3 实战操作:

目标:

使用Dockerfile创建一个自定义jdk1 .8的镜像
分析:
假设在centos7作为基础镜像上,添加jdk1.8并构建一个包含jdk1.8的centos7新镜像。
-Dockerfile可以实现; Dockerfile是由一系列命令和参数构成的文本文件,在文件中可以指定各个组件资源和运行命令等。
实现步骤:
1.拉取centos7镜像;
2.上传jdk1.8;
3.编写Dockerfile文件;
4.构建镜像;
5.测试(基于新镜像创建并运行容器,运行java -version )
 

(1)首先拉取centos7镜像,创建文件夹并进入该文件夹中。下载jdk8的Linux版本通过xftp上传到该目录:

官网下载很慢,可通过网盘下载:

链接:https://pan.baidu.com/s/1TAPxbGfDCZS945dT1ji9sw
提取码:y0j6

docker pull centos:7
mkdir -p /usr/local/dockerjdk
cd  /usr/local/dockerjdk
mv /root/jdk-8u221-linux-x64.tar.gz .

 

 (2)编辑Dockerfile文件

[root@docker dockerjdk]# vim Dockerfile 
FROM centos:7
MAINTAINER Gawain
WORKDIR /usr
RUN mkdir /usr/local/java
ADD jdk-8u221-linux-x64.tar.gz  /usr/1oca1/java/
ENV JAVA_HOME /usr/1oca1/java/jdk1.8.0_221
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/1ib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/1ib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH

(3)执行命令构建镜像,不要忘记后面.

docker build -t='jdk1.8' .

(4)查看镜像是否创建成功

 超全的Docker学习教程(Linux云计算从入门到精通)_第17张图片

 

 (5)运行jdk容器,查看java版本:

 

九、私有仓库的搭建与使用

Docker官方的Docker hubhttps://hub.docker.com)是一个用于管理公共镜像的仓库,我们可以从上面拉取镜像 到本地,也可以把我们自己的镜像推送上去。但是,有时候我们的服务器无法访问互联网,或者你不希望将自己的镜像放到公网当中,那么我们就需要搭建自己的私有仓库来存储和管理自己的镜像。

9.1 私有仓库搭建

(1)拉取registry并启动

# 拉取私有仓库镜像 
docker pull registry

# 启动私有仓库容器 
docker run -id --name=registry -p 5000:5000 registry

(2)打开浏览器 输入地址http://私有仓库服务器ip:5000/v2/_catalog,看到{"repositories":[]} 表示私有仓库 搭建成功

超全的Docker学习教程(Linux云计算从入门到精通)_第18张图片


(3)修改daemon.json   

   
# 在下面这个文件里添加一个key,保存退出。此步用于让 docker 信任私有仓库地址;注意将私有仓库服务器ip修改为自己私有仓库服务器真实ip 

vim /etc/docker/daemon.json 

{"insecure-registries":["129.211.186.178:5000"]} 

(4)重启docker 服务 并启动registry

systemctl restart docker
docker start registry

 

9.2 将镜像上传至私有仓库

# 标记镜像为私有仓库的镜像     
docker tag jdk1.8 129.211.186.178:5000/jdk1.8

# 重启私有仓库容器
docker restart registry 

# 上传标记的镜像     
docker push 129.211.186.178:5000/jdk1.8

9.3 从私有仓库拉取镜像

(1)从本地镜像私有仓库拉取镜像

#再从镜像仓库拉取之前先删除本地的jdk1.8容器和镜像,注意用docker images查看
docker rm testjdk
docker rmi 129.211.186.178:5000/jdk1.8
docker images

#拉取镜像 
docker pull 129.211.186.178:5000/jdk1.8
docker images

 

(2)其他服务器拉取私有仓库镜像

大多数情况下,都是某台服务器部署了私有镜像仓库之后;到其它服务器上从私有仓库中拉取镜像,若要拉取私有仓库镜像需要去修改docker的配置文件,设置启动时候的仓库地址。

编辑下面这个配置文件,添加如下一行(注意是自己的IP)

vim /usr/lib/systemd/system/docker.service

--add-registry=129.211.186.178:5000 --insecure-registry=129.211.186.178:5000\

超全的Docker学习教程(Linux云计算从入门到精通)_第19张图片

 

#重新加载docker配置文件
systemctl daemon-reload 

#重启docker
systemctl restart docker

拉取镜像:

docker pull jdk1.8

 

终于总结完了,学习使我快乐!

超全的Docker学习教程(Linux云计算从入门到精通)_第20张图片

 

 

 

你可能感兴趣的:(云计算和虚拟化)