云原生 | docker(1) :基础篇

635 阅读18分钟

前言

随着云原生技术的发展,这块内容在开发和运维中也变得十分重要,而云原生的容器化技术代表就是 Docker,本文是将 Docker 的基础知识进行回顾,也作为打开云原生的起点篇。

1.1 Docker 入门

1.1 背景

在如今的企业级项目开发中,具备的特点是:高可用、高并发、高性能、安全、监控等特点。

  • 高可用、高并发--->解决方案:服务器配置--->集群。

    例如 12306 网站,在春节高峰期和平常的流量是不一样的;例如双十一秒杀,也是不一样的。

    这种现象就是服务的忙闲不均,资源浪费,如何动态的解决这些问题?

    如何部署多台服务器的应用,需要花费很大的人力和物力,如何高效部署

    服务容器性(可用性), 如果一个应用出现问题,可能导致该节点的所有应用都崩溃。例如cpu爆满。

    正式部署的时候,保证开发环境和生产环境必须保持一致,漏配了怎么办?

  • 针对以前部署的现状,新的解决方案有 Docker 容器化部署

1.2 Docker 概述

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

顾名思义,docker是一个容器引擎,容器且不说,什么是引擎?

image-20211130094247443

例如:汽车的引擎是发动机,有了发动机才能跑起来,docker 也是一种引擎,基于这个引擎,开发者能让他们开发的应用处于一个有隔离性的、可移植性的容器中,以便于在各种机器中部署而无需考虑兼容性问题。

因此,Docker 的logo 是一条鲸鱼承载着各种小集装箱,它的角色正是这条鲸鱼起着引擎的作用,而集装箱则对应各个容器。

那什么是容器呢?

专业的说法就是,容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。容器之间是共享同一套操作系统资源的,由于容器是共享主操作系统的内核,因此就无法在服务器上运行与主服务器不同的操作系统,也就是说不能再Linux的服务器上运行Windows。

1.3 为什么要docker

Docker 能够对 Web 应用的自动化打包和发布

自动化测试和持续集成、发布。

在服务型环境中部署和调整数据库或其他的后台应用。

从头编译或者扩展现有的 平台来搭建自己的 Pass 环境。

 IaaS : (基础设施即服务)。例如我们买台服务器,自己部署代码、自己安装开源软件。
 Paas :(平台即服务)。paas 提供服务器和安装包,只需自己开发应用程序。
 Saas: (软件即服务)。saas 提供服务器和代码,我们只需要花钱即可。
1.3.1 简化程序

Docker 让开发者可用打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux 机器上,便可用实现虚拟化。Docker 改变了虚拟化的方式,使开发者可以直接将自己的成果放入 Docker 中进行管理。方便快捷已经是 Docker 的最大优势,过去需要数天乃至数周的任务,在Docker 容器中,只需要数秒能完成。

1.3.2 节省开支

Docker 与云的结合,让云空间得到了充分的利用,不仅解决了硬件管理问题,也改变了虚拟化的方式。它会把公共的部署提取出来节省空间。

1.3.3 持续交付和部署

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合持续集成系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署系统进行自动部署。而且使用 Dockerfile 使镜像构建透明化,帮助更好的生产环境中部署该镜像。

1.3.4 轻松迁移

Docker 确保了执行环境的一致性,使得应用迁移更加容易,不用担心环境的变化导致应用无法正常运行的情况。

1.4 Docker 和虚拟机区别

preview

作为一种轻量级的虚拟化方式, Docker在运行应用上跟传统的虚拟机方式相比具有显著优势:

  • Docker容器很快, 启动和停止可以在秒级实现, 这相比传统的虚拟机方式要快得多 。
  • Docker容器对系统资源需求很少, 一台主机上可以同时运行数千个 Docker容器。
  • Docker通过类似Git的操作来方便用户获取、分发和更新应用镜像, 指令简明, 学习成本较低。
  • Docker通过Dockerfile 配置文件来支持灵活的自动化创建和部署 机制 , 提高工作效率。Docker容器除了运行其中的应用之外, 基本不消耗额外的系统资掘, 保证应用性能的同时, 尽量减小系统开销。 传统虚拟机方式运行 N个不同的应用就要启动N个虚拟机(每个虚拟机需要单独分配独占的 内存、磁盘等资源), 而Docker只需要启动N个隔离的容器, 并将应用放到容器内即可。当然, 在隔离性方面, 传统的虚拟机方式多了一层额外的隔离。但这并不意味着Docker就不安全。 Docker利用Linux系统上的多种防护机制实现了严格可靠的隔离。 从1.3版本开始, Docker引人了安全选项和 镜像签名机制, 极大地提高了使用Docker的安全性 。

1.2 Docker 架构

1.2.1 简介

Docker 使用客户端-服务器架构,使用远程 API 来管理和创建 Docker 容器。

Docker 容器通过 Docker 镜像来创建。

容器和镜像的关系类似于面向对象编程中的对象和雷。

1.2.2 Docker 基本概念

前面说的Docker 它有三个基本概念需要理解:

  • 镜像(Image)
  • 容器(Container)
  • 仓库(Repository)

Docker 的仓库类似 maven,里面存放很多镜像,类似 jar包,

一个镜像可以构造出很多容器,就像 java 中一个类可以创建出很多对象。例如根据 mysql 镜像,我构造出10个 mysql 的容器,这些容器都相互隔离,十分方便。

1.2.3 Docker 引擎

Docker引擎

从上图中可以看出,Docker Engine中包含了三个核心组件(docker CLI、REST API和docker daemon),这三个组件的具体说明如下。

● docker CLI(command line interface):表示Docker命令行接口,开发者可以在命令行中使用Docker相关指令与Docker守护进程进行交互,从而管理诸如image(镜像)、container(容器)、network(网络)和data volumes(数据卷)等实体。

● REST API:表示应用程序API接口,开发者通过该API接口可以与Docker的守护进程进行交互,从而指示后台进行相关操作。

● docker daemon:表示Docker的服务端组件,他是Docker架构中运行在后台的一个守护进程,可以接收并处理来自命令行接口及API接口的指令,然后进行相应的后台操作。

1.3 Docker 仓库

在前面了解到,Docker 的仓库用于存放镜像,Docker Hub 提供了庞大的镜像集群供使用。

Docker 官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 2,650,000 的镜像。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。

仓库分为公有仓库和私有仓库,类似github 代码管理仓库。

  • 公有仓库:默认的,提供了大量的官方镜像,国内访问可以使用加速器,例如阿里云加速器。
  • 私有仓库:用户本地搭建私有仓库,供私有使用。

1.4 Docker 安装

要安装 Docker 引擎,您需要 CentOS 7 或 8 的维护版本。不支持或测试存档版本,centos7 的内核版本在3.10 以上。

Docker 的参考见 docs.docker.com/engine/inst…

1、校验版本

从 2017 年 3 月开始, docker 在原来的基础上分为两个分支版本 :Docker CE 和 Docker EE。

Docker CE 即社区免费版,Docker EE 即企业版,强调安全,但需要付费使用。

本文安装的是 Docker CE。

 [root@VM-16-6-centos ~]# uname -r
 3.10.0-1160.11.1.el7.x86_64

2、移除旧的版本

  sudo yum remove docker \
                   docker-client \
                   docker-client-latest \
                   docker-common \
                   docker-latest \
                   docker-latest-logrotate \
                   docker-logrotate \
                   docker-engine

3、安装一些必要的系统工具

安装所需的软件包。yum-utils 提供了 yum-config-manager 应用,并 device-mapper-persistent-data 和 lvm2 由需要 devicemapper 存储驱动程序。

 sudo yum install -y yum-utils device-mapper-persistent-data lvm2

4、添加软件源信息

源1:(官方推荐)

 sudo yum-config-manager \
     --add-repo \
     https://download.docker.com/linux/centos/docker-ce.repo

源2:(阿里云源)国内使用这个

 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

5、更新 yum 缓存

 sudo yum makecache fast

6、安装 Docker-CE

 sudo yum -y install docker-ce

7、启动 Docker 后台服务

 sudo systemctl start docker

8、重启 Docker 服务

 sudo systemctl restart docker

9、查看 Docker 版本

 [root@VM-16-6-centos ~]# docker version
 Client: Docker Engine - Community
  Version:           20.10.11
  API version:       1.41
  Go version:        go1.16.9
  Git commit:        dea9396
  Built:             Thu Nov 18 00:38:53 2021
  OS/Arch:           linux/amd64
  Context:           default
  Experimental:      true
 
 Server: Docker Engine - Community
  Engine:
   Version:          20.10.11
   API version:      1.41 (minimum version 1.12)
   Go version:       go1.16.9
   Git commit:       847da18
   Built:            Thu Nov 18 00:37:17 2021
   OS/Arch:          linux/amd64
   Experimental:     false
  containerd:
   Version:          1.4.12
   GitCommit:        7b11cfaabd73bb80907dd23182b9347b4245eb5d
  runc:
   Version:          1.0.2
   GitCommit:        v1.0.2-0-g52b36a2
  docker-init:
   Version:          0.19.0
   GitCommit:        de40ad0

10、删除 docker

 sudo yum remove docker-ce
 sudo rm -rf /var/lib/docker

1.5 Docker 镜像加速器

鉴于国内网络问题,拉取 Docker 镜像会比较慢,我们需要配置 加速器来解决。

Docker 官方和国内服务商提供了国内加速器服务,例如:

  • Docker 官方提供的中国 registry mirror
  • 阿里云加速器
  • 腾讯云加速器

因为我这台服务器是腾讯云的,我就使用腾讯云来配置了。

阿里云的加速器请查看:developer.aliyun.com/article/299…

1、创建文件

 vim /etc/docker/daemon.json

2、添加配置

 {
   "registry-mirrors": ["https://mirror.ccs.tencentyun.com"]
 }

3、重启

 systemctl daemon-reload
 systemctl restart docker

4、docker 加速器查看

docker info 查看到镜像地址即配置成功。

image-20211130111500471

1.6 Docker 镜像

镜像是 Docker 的三大组件之一。

Docker 运行容器前需要本地存在对应的镜像,如果本地不存在,Docker 会从镜像仓库下载。

1.6.1 Docker 获取镜像

之前提到过,Docker Hub 有大量的高质量的镜像可以用,这里我们就说以下怎么获取这些镜像

查找镜像

通过 docker search 命令来搜索镜像。后面会列出是否官方、starts 数等参考。

image-20211130111930815

获取镜像

从 Docker 镜像仓库获取镜像的命令是 Docker pull ,其命令格式为:

 docker pull [选项] [Dockers Registey 地址[:端口号]/ ] 仓库名 [:标签]

具体可以通过 docker pull --help 命令查看,不用死记。

例如下载 tomcat

 docker pull tomcat:版本号    //版本号不写就代表最新版本

列出镜像

要想列出已经下载下来的镜像,可以使用 docker image ls 命令。

 docker images // docker image ls

image-20211130112538189

列表中包含了 仓库名、标签、镜像ID、创建时间及占用的空间。

镜像ID 是镜像的唯一标识,对应人的身份证。它可以由多个 TAG标签表示不同版本。docker 同一镜像中 docker 的公共部分会提取出来节省空间。

1.6.2 Docker 删除本地镜像

删除镜像,必须确认此镜像目前没有被任何容器使用

 docker image rm 镜像id

1.6.3 Docker 其他辅助命令

查看本地镜像的 IMAGE ID

 docker images -q

查看一个镜像的制作历程

 docker history 镜像名称

1.6.4 Docker 保存镜像

备份本地仓库的镜像

1、用 save 命令将本地仓库的镜像保存当前目录下

 docker save -o tomcat.lei.tar 镜像名称

2、将本地目录下的镜像备份文件导入到本地的Docker 仓库

 [root@VM-16-6-centos docker]# docker save -o tomcat.lei.tar tomcat
 [root@VM-16-6-centos docker]# ls
 daemon.json  key.json  tomcat.lei.tar
 ​

3、将本地目录下的镜像备份文件导入到本地 Docker 仓库

 docker load -i tomcat.lei.tar

1.7 Docker 容器

容器是 Docker 核心概念。

简单说,容器是独立运行的一个或一组应用,以及它们的运行环境。

对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和运行在上面的应用。

1、查看容器状态

 docker ps       //查看运行的容器
 docker ps -a    //查看所有容器
 docker container ls
 docker container ls-a

2、Docker 启动容器

启动容器有两种方式:一种是基于镜像新建一个容器并启动,一种是将在终止状态(stopped)的容器重新启动。

docker run 参数 镜像名称:tag 执行的命令

常用参数:

 - i  保持和 docker 容器内的交互,启动容器时,运行的命令结束后,容器依然存活,没有退出
 - t  为容器的标准输入虚拟一个 tty
 - d  后台运行容器
 --rm 容器启动后,执行完成命令或程序后就销毁
 --name 给容器起一个自定义名称
 - p  宿主机:内部端口

docker run --rm -d --name tomcat1 -p 8080:8080 tomcat

练习tomcat

 [root@VM-16-6-centos docker]# docker run -d --name tomcat-8080 -p 8080:8080 tomcat
 bd1b5fa092eb084984aa4ac55367e20a3d58937f888b5e757087af3191de1c9f
 [root@VM-16-6-centos docker]# docker ps 
 CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
 bd1b5fa092eb   tomcat    "catalina.sh run"   6 seconds ago   Up 5 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   tomcat-8080

3、停止容器

docker stop 镜像id\名称

 docker stop $(docker ps -a -q) 关闭所有的容器

4、启动停止的容器

docker start 镜像id\名称

5、删除容器

docker rm 镜像id\名称。删除容器得停止掉正在运行的容器。

6、进入容器

某些时候需要进入容器进行操作,使用 docker exec 命令

-i -t 参数

docker exec 后边可以跟多个参数,这里主要说明 -i -t 参数。

只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。

当 -i -t 参数一起使用时,则可以看到外面熟悉的 Linux 命令提示符。

 docker exec -it 容器ID(Names) bash

示例:

进入容器后,对默认的 tomcat 进行页面修改,然后再访问查看效果。

注意默认容器内 linux 包是最小安装。只拥有最基本的命令。

exit : 不会导致容器的停止。

 root@bd1b5fa092eb:/usr/local/tomcat/ROOT# echo 'xiao-lei'>>index.html
 root@bd1b5fa092eb:/usr/local/tomcat/ROOT# ls
 index.html

7、在宿主机和容器之间交换文件

在宿主机和容器之间相互 COPY 文件 的用法如下:

 docker ps CONTAINER:PATH LOCALPATH     // 从容器中复制到宿主机
 docker cp LOCALPATH|- CONTAINER:PATH  // 宿主机复制到容器中

宿主机复制一个文件到容器中:将 a.txt 复制到了容器指定目录下

docker cp a.txt tomcat-8080:/usr/local/tomcat/webapps/ROOT

将容器内的 b.txt 复制出来

docker cp tomcat-8080:/usr/local/tomcat/webapps/ROOT/b.txt /root

1.8 Docker 查看日志

Docker 查看日志

 docker logs 容器名称/ID
 docker logs -f -t --since="2021-11-30" --tail=10 tomcat-8080

--since :此参数指定了输出日志开始日期,即只输出指定日期之后的日志

-f :查看实时日志

-t :查看日志产生的日期

-tail = 10 :查看最后的10条日志

tomcat-8080: 容器名称

1.9 案例

现在学完了这些 Docker 的基本命令,我们用 docker 的方式部署一个项目到 tomcat 服务器上吧。

复制文件到webapp 下,即可打开访问。

1.10 Docker 数据卷

问题:通过镜像创建一个容器。容器一旦被销毁,则容器内的数据将一并被删除。但有些情况下,通过服务器上传的图片会出现丢失,容器内的数据不是持久化状态的。那有没有一种独立容器,又能提供持久化给多个容器共同使用的东西呢?这就是数据卷。

1.10.1 什么是数据卷

数据卷:是一个可供一个或多个容器使用的特殊目录

image-20211130161447941

特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 数据卷默认会一直存在,即时容器被删除

为了解决这些问题,docker 引入了数据卷(Volume)机制,数据卷是存在一个或多个容器中的特定文件或文件夹,这个文件或文件夹以独立于 docker 文件系统的形式存在于宿主机中。

数据卷的最大特点是:其生产周期独立于容器的生存周期。

使用数据卷的场景:

  • 在多个容器之间共享数据,多个容器之间共享数据,多个容器可以同时以只读或者读写的方式挂载同一个数据卷,从而共享数据卷的数据。
  • 当宿主机不能保证一定存在某个目录或一些固定路径的文件时,使用数据卷可以规避这种限制带来的问题。
  • 当你想把容器中的数据存储在宿主机之外的地方时,比如远程主机上或云存储上。
  • 当你需要把容器数据在不同宿主机之间备份、恢复、迁移时,数据卷是最好的选择。

1.10.2 数据卷应用

1、创建数据卷

docker volume create 数据卷名称 创建数据卷之后,默认会存放到目录: /var/lib/docker/volume/数据卷名称/_data目录下

2、查看数据卷

docker volume inspect 数据卷名称

3、查看全部数据卷信息

docker volume ls

4、删除数据卷

docker volume rm 数据卷名称

5、应用删除卷

docker run -v 数据卷名称(宿主机路径):容器内路径 镜像ID (当你映射数据卷时,如果数据卷不存在,Docker 会帮你自动创建)

docker run -v 路径:容器内部的路径 镜像ID (直接指定一个路径作为数据卷的存储位置,推荐使用)

采用 docker run - v 来直接创建数据卷:

 创建数据卷:docker volume create tomcat-volume
 查看所有的数据卷:docker volume ls
 启动:docker run -v /www/package/hydrogen/:/usr/local/tomcat/webapps/hydrogen2 tomcat

二、常用软件安装

2.1 基本安装

2.1.1 nginx

拉取 Nginx 镜像

 docker pull nginx:1.20

查看本地镜像列表(即可看到nginx)

 docker images

运行容器

 docker run --name nginx-test -p 800:80 -d nginx  # 将本地的800 端口映射到容器内部的80 端口

image-20211204152940606

进入容器:

  • /etc/nginx 目录是配置文件目录
  • /usr/share/nginx 目录安装的是静态 html 文件
  • /usr/sbin/nginx 是启动脚本

容器内的是纯净版,最小化安装,所以我们需要将容器内的配置文件与宿主机做个映射,将其映射到本地的目录中。

挂载映射卷

  • 1、宿主机创建目录

     mkdir -p /usr/local/nginx
    
  • 2、依次在该目录下创建三个文件目录

     mkdir -p /usr/local/nginx/html
     mkdir -p /usr/local/nginx/logs
     mkdir -p /usr/local/nginx/conf
    
  • 3、拷贝配置文件

     docker cp 容器 id:/etc/nginx/nginx.conf  /usr/local/nginx/conf
     docker cp 容器id:/etc/nginx/conf.d/ /usr/local/nginx/conf
    
  • 4、修改配置文件

     将 usr/local/nginx/conf/nginx.conf 内容中的 include 默认路径改为当前路径
    
  • 5、删除 nginx 容器

     docker rm -f nginx
    
  • 6、创建容器并挂载配置文件,映射端口

     docker run -d -p 800:80 --name nginx-800 -v /www/server/nginx/html:/usr/share/nginx/html -v /www/server/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /www/server/nginx/conf/conf.d/default.conf:/etc/nginx/conf/conf.d/default.conf -v
     /www/server/nginx/logs:/var/log/nginx nginx
    

集群搭建

在刚才的配置中,我已经完成了单机节点的配置,现在开始进行nginx 的集群配置。通过 nginx 的负载均衡来择优选择哪一台服务器去执行(保证高可用)。

  • 1、进入 宿主机的conf 路径,修改配置文件 nginx.conf

     配置服务器组,在 http{} 节点之间添加 upstream 配置(使用localhost 会很慢)
     upstream nginxCluster{
        server 127.0.0.1:8080;  # 服务器 8080
        server 127.0.0.1:8081;  # 服务器 8081
     }
    
  • 2、修改 conf./的default.conf 文件在 location {} 中,利用 proxy_pass 配置反向代理地址:

    此处 http:// 不能少,后面的地址要和第一步 upstream 定义的名称保持一致,

    proxy_pass 代理地址,转发到目标服务器

     location /{
         proxy_pass http://nginxCluster;
     }
    

2.1.2 mysql

1、docker pull mysql

2、docker run -d --name mysql -p 3306:3306 mysql