超全的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和虚拟机比

1.3 docker和虚拟机比较

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

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

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

相同:

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

不同:

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

二、初识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:仓库可看成一个代码控制中心,用来保存镜像。

 

 

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镜像

(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 用户的密码。

 了解下端口映射的概念:

 

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

 (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的:

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

 

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: 

 

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都是自定义的网络),属于同一网络的容器可以互相访问.

 配置文件可参考下面:

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)运行检测

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

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

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

 

 

 

 

 

七、容器的迁移与备份

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

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

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

其中涉及到的命令有:

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

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

 

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

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

 访问正常:

八、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)查看镜像是否创建成功

 

 

 (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":[]} 表示私有仓库 搭建成功


(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配置文件
systemctl daemon-reload 

#重启docker
systemctl restart docker

拉取镜像:

docker pull jdk1.8

 

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

 

 

 

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硬核的无脸man~

你的鼓励是我创作的最大功力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值