天天看点

初学 Docker 容器化技术Docker

Docker

概述

开发一个项目可能存在两种环境,开发、上线;两者需要配置的环境不同。

传统项目运行时,一个环境如 mysql 的错误会引发整个项目的宕机。

Docker 就是为了解决项目中不同的配置而产生,即可以同时将 jar、mysql、redis 等一起打包安装,称为镜像。

使用 Docker 生成镜像,下载安装即可使用。

思想:集装箱

Docker 核心思想:隔离,打包装箱,每个包都是相互隔离的。

Docker 能够最大限度的利用服务器的资源

虚拟化技术:

  • 全虚拟、半虚拟、容器技术

虚拟机技术 => 容器化技术 容器化技术不是一个完整的操作系统

两者的优缺点和区别:

虚拟机技术:

  • 资源占有率太高
  • 步骤过多
  • 启动慢
  • 虚拟出一套硬件,拥有一个完整的操作系统,需要在该 OS 上安装相应的软件和环境

容器化技术:

  • 容器应用直接运行在主体本机上,不拥有独立的内核
  • 容器间相互隔离,每个容器拥有独立的文件系统,互不影响
  • 内核级别的虚拟化

基本组成

镜像(image)

  • 通过镜像可以创建多个容器
  • 项目(服务)运行最终是在容器中运行的

容器(container)

  • 利用容器技术,独立运行一个或一组 app
  • 在初学阶段,可以将 container 理解为简易的 Linux 系统

仓库(repository)

  • 存放镜像的位置
  • repository 分为 public 和 private
  • Docker Hub 类比 GitHub

安装

Centos

查看系统内核

# uname -r
5.10.112-11.1.al8.x86_64
           

查看系统版本

# cat etc/os-release 
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

           

安装步骤

更新

yum

索引

yum makecache fast
           
  1. 卸载旧版本
    yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
               
  2. 下载相关工具及安装包
    yum install -y yum-utils
               
  3. 配置镜像仓库
    yum-config-manager \
        --add-repo \
         http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
               
  4. 安装 Docker 引擎
    # docker-ce 社区版
    yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
               

查看下载镜像

docker images
           

卸载

  1. 卸载依赖
    yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
               
  2. 删除资源
    # /var/lib/docker 默认工作路径
    rm -rf /var/lib/docker
    rm -rf /var/lib/containerd
               

阿里云镜像加速

#
sudo mkdir -p /etc/docker
#
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://rl0hzmix.mirror.aliyuncs.com"]
}
EOF
#
sudo systemctl daemon-reload
#
sudo systemctl restart docker
           

Ubuntu

  1. 卸载旧版本
    apt-get remove docker docker-engine docker.io containerd runc
               
  2. 更新

    apt

    包索引
    apt-get update
               
  3. 安装

    apt

    依赖包,用于通过 HTTPS 来获取仓库
    apt-get install \
        ca-certificates \
        curl \
        gnupg \
        lsb-release
               
  4. 添加 Docker 官方 GPS 密钥
    mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
               
  5. 将 Docker 仓库添加到 APT 软件源
  6. 安装 Docker 引擎
    apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
               
  7. 验证
    docker --version
               

Docker 原理

Docker 工作原理

  • Docker 是一个 C/S 结构的系统,其守护进程运行在本机,通过 Socket 从客户端访问

Docker 与 VM 的速度区别原因

  • Docker 的抽象层比 VM 少;
  • Docker 利用的是宿主机的内核,VM 需要使用 Guest OS(重新搭载)

常用命令

帮助命令

# 查看 Docker version
docker version
# 查看 Docker 信息(详细),system info,包括镜像和容器的数量
docker info 
# 
docker --help
           

镜像命令

# 查看镜像仓库
docker images
# 查看镜像仓库所有的镜像
docker images -a
# 查看镜像仓库中镜像的ID
docker images -q
# 参数配合使用
docker images -aq
           

搜索命令

# xxx表示镜像仓库中的镜像,如 mysql
docker search xxx
# 条件搜索,???表示查询的条件,可以是 STARS=3000
docker search xxx -filter=???
           

下载镜像

# xxx表示镜像仓库中的镜像,如:mysql,默认最新版本,tag表示版本号
docker pull xxx[:tag]
           

删除镜像

# 单个镜像删除,ID为 IMAGE ID,NAME 为 REPOSITORY,可以通过两种方式删除
docker rmi -f ID(NAME)
# 多个镜像删除
docker rmi -f $(docker images -qa)
           

容器命令

通过镜像启动容器

创建、启动

# args:
# --name "" 	容器名字
# -d 			后台方式运行
# -it			交互模式运行,进入容器
# -p			指定端口号,如:-p 8080:8080,不输入参数随机指定端口
#	-p 主机端口:容器端口
#	-p 容器端口
#	-p ip:主机端口:容器端口
# image 是镜像的名
docker run [args] image

# e.g.
[[email protected] ~]# docker run -it centos /bin/bash
[[email protected] /]# 

           

退出容器

# 容器停止并退出
exit
# 容器不停止退出
ctrl + P + Q
           

列出容器

# 列出当前正在运行的容器
docker ps
# 列出当前正在运行的容器、历史运行过的容器即所有容器
docker ps -a 
# 最近创建的num个容器
docker ps -n=num 
# 只显示编号
docker ps -q
           

删除容器

# 无法删除正在运行的容器
docker rm ID
# 删除所有容器
docker rm -f $(docker ps -aq)
docker ps -a -q|xargs docker rm
           

启动和停止

docker start ID
docker restart ID
# stop和kill的区别在于stop会给容器内的应用10s时间去停止服务,kill直接停止
docker stop ID
docker kill ID
           

start

run

的区别

  • run

    :对镜像进行新建并运行
  • start

    :对关闭的容器进行运行(需存在)

其他命令

查看日志

# 日志打印
# --tail num 显示的num条日志
docker logs -f -t --tail num containerID
# 所有日志
dokcer logs -tf containerID

# Shell 脚本
"while true;do echo Lyn-coder;sleep 1;done"

# 后台运行
docker run -d centos /bin/sh -c "while true;do echo Lyn-coder;sleep 1;done"
           

查看进程

# top
# docker top 2a7099f3b1d3 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                14614               14594               0                   19:14               ?                   00:00:00            /bin/sh -c while true;do echo Lyn-coder;sleep 1;done
root                15104               14614               0                   19:19               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1

           

查看镜像元数据

# 查看容器的详细信息
docker inspcet containerID
           

进入容器

# 进入容器新终端
docker exec -it containerID /bin/bash
# 进入容器后使用,不开启新线程
docker attach containerID
           

拷贝

# container -> host
# docker cp 72446cb56e8b:/home/demo.java /home
docker cp containerID:dir dstDIr
           

测试实例

使用 Docker 安装 tomcat

# docker hub
# --rm 用于测试,使用完毕即删除容器
docker run -it --rm tomcat:9.0

# ====================
# run
docker run -d -p 8080:8080 --name tomcat_01 tomcat:9.0

# webapps 中没有任何文件,将 webapps.dist 文件夹中的文件 copy 到 webapps
# 就不会再是404的网页了
docker exec -it tomcat_01 /bin/bash
           

可视化界面

Pointer

:图形化界面管理工具

# 安装
docker run -d -p xxxx:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
           

镜像操作

commit

# 提交
docker commit -m="msg" -a="author" containerID 镜像名:版本
docker commit -a="Lyn-coder" -m="Tomcat webapps upgrade to test docker commit" 71b588888a1f tomcat_lyn:1.0

           

容器数据卷

简要

容器之间想要实现数据共享,Docker 容器中的数据可以同步到 host

目录的挂载,卷技术

目的:

  • 数据持久化
  • 容器同步操作
  • 容器数据共享

使用

挂载

-v

# host-dir:主机目录位置
# container-dir:容器目录位置
docker run -it -v host-dir:container-dir containerID /bin/bash
           

Docker 与 MySQL

docker run -d -p xxxx:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=xxxxxx --name mysql_01 -d mysql
           

匿名与具名挂载

# -P 随机指定端口号,也可以指定端口号
# 匿名
docker run -d -P 容器内路径 镜像名
# 具名
docker run -d -P 卷名:容器内路径 镜像名
# all volume 卷
docker volume ls
# 卷具体信息
docker volume inspect 卷名
           

不指定目录时,Docker 容器中的卷,都存储在

/var/lib/docker/volumes/xxx/_data

匿名挂载、具名挂载、指定路径挂载的区分

  • 匿名挂载
    -v 容器内路径 
               
  • 具名挂载
    -v 卷名:容器内路径
               
  • 指定路径挂载
    -v /host路径:容器内路径
               

参数补充

  • -ro

    :read only,只读,只能从 host 对其进行操作,容器没有这个权限
  • -rw

    :read write,读写权限

DockerFile

DockerFile

用来构建 Docker 镜像

标准文件命名为:

Dockerfile

# 文件命令需大写
FROM centos

VOLUME ["volume-01", "volume-02"]

CMD echo "===== end ====="
CMD /bin/bash



# 命令
docker build -f dockerfile-01 -t lyn/centos:1.0 .

# 执行
Sending build context to Docker daemon  2.048kB
Step 1/4 : From centos
 ---> 5d0da3dc9764
Step 2/4 : VOLUME ["volume-01", "volume-02"]
 ---> Running in 3e130dcabdb4
Removing intermediate container 3e130dcabdb4
 ---> 6b05c51c3970
Step 3/4 : CMD echo "===== end ====="
 ---> Running in 3a575a9f422b
Removing intermediate container 3a575a9f422b
 ---> 4e0a395ccac0
Step 4/4 : CMD /bin/bash
 ---> Running in fc17b239c866
Removing intermediate container fc17b239c866
 ---> 21e01bdb29b2
Successfully built 21e01bdb29b2
Successfully tagged lyn/centos:1.0


# TEST
# volume-01中创建一个 txt 文件
# 通过 inspect 查看 挂载位置
           

数据卷容器

两个及两个以上的容器进行数据同步

--volumes-from xxx
           
# 21e01bdb29b2:镜像ID
docker run -it --name docker-01 21e01bdb29b2
#
docker run -it --name docker-02 --volumes-from docker-01 21e01bdb29b2

# --volumes-from => 继承于
           
  • 数据卷容器的生命周期:直到所有容器都被销毁
  • 数据持久化到 host,本地数据不会被删除

DockerFile

构建镜像的步骤:

  1. 编写 DockerFile 文件
  2. docker build

    构建镜像
  3. docker push

    发布镜像(Docker Hub/阿里云镜像仓库)

DockerFile 原则

  • 保留关键字必须是大写
  • 执行顺序由上到下
  • 注释使用

    #

  • 每一条指令都会创建并提交新的镜像层
  • 面向开发,制作镜像发布项目需要编写 DockerFile 文件
初学 Docker 容器化技术Docker

DockerFile 指令

  • FROM

    :指定基础镜像;
  • MAINTAINER

    :指定镜像作者,姓名+邮箱;
  • RUN

    :镜像构建运行命令;
  • ADD

    :增加镜像层;
  • WORKDIR

    :设置镜像工作目录;
  • VOLUME

    :设置挂载目录(卷);
  • EXPOSE

    :设置暴露的端口,类比

    -p

  • CMD

    :指定容器启动时运行的命令,只有最后一条命令生效;
  • ENTRYPOINT

    :指定容器启动运行的命令,可追加命令;
  • ONBUILD

    :构建一个被继承的时候运行时的命令;
  • COPY

    :将文件拷贝到镜像中;
  • ENV

    :设置环境变量;

DEMO测试

# DockerFile
FROM centos
MAINTAINER author<email>

ENV MYPATH /usr/local
WORKDIR $MYPATH


# vim
RUN yum -y install vim
# ifconfig
RUN yum -y install net-tools

# 暴露端口
EXPOSE 80

# 打印
CMD echo $MYPATH
CMD echo "===== end ====="
CMD /bin/bash

=======================================================================

# 构建命令
docker build -f  mydockerfile-centos -t lyn-mycentos:0.1 . 
# 运行
docker run -f 镜像name -t 镜像[:tag] .

           

DEMO测试——Tomcat镜像

注:参考狂神的视频

步骤:

  1. 准备 JDK 和 Tomcat 的压缩包
  2. 编写 Dockerfile 文件
    FROM centos:7
    MAINTAINER author<email>
    
    COPY readme.md /usr/local/readme.md
    
    # 使用ADD命令会自动解压
    ADD jdk-8u341-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.65.tar.gz /usr/local/
    
    
    # 安装vim
    RUN yum -y install vim
    
    # 
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    # 配置环境变量
    ENV JAVA_HOME /usr/local/jdk1.8.0_341
    # 核心jar包
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.65
    ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.65
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    # 容器内端口
    EXPOSE 8080
    
    # 容器启动时运行
    CMD /usr/local/apache-tomcat-9.0.65/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.65/bin/logs/catalina.log
               
  3. 通过 Dockerfile 构建镜像
  4. 运行
    docker run -d -p xxxx:8080 --name lyn-tomcat -v /home/xxx/build/tomcat/test:/usr/local/apache-tomcat-9.0.65/webapps/test -v /home/xxx/build/tomcat/tomcat-logs/:/usr/local/apache-tomcat-9.0.65/logs  lyn-tomcat-images
               

在 webapps 文件夹的 test 文件夹中添加 WEB-INF 文件夹、jsp 和 xml 文件,注意:jsp 文件要与 WEB-INF 文件夹同目录

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
    <meta charset="utf-8">
    <title>Hello World!</title>
</head>
<body>
    <%-- JSP Comment --%>
    <h1>Hello World!</h1>
    <p>
    <%
        System.out.println("====== Lyn-Tomcat =======");
    %>
</body>
</html>

           
<?xml version="1.0" encoding="utf-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
        http://java.sun.com/xml/ns/j2ee/web-app_3_0.xsd">
</web-app>
           
初学 Docker 容器化技术Docker
初学 Docker 容器化技术Docker

镜像发布

步骤

  1. Docker Hub 账号登录
    docker login -u xxxx
               
  2. push
    # 增加tag 原镜像名称 新镜像名称
    docker tag xxx xxx
    
    # push
    docker push xxx:tag
               

发布到阿里云镜像

  1. 创建个人实例
  2. 创建命名空间
  3. 创建镜像仓库
  4. 根据阿里云中的文档 push 到阿里云镜像

Docker 网络

Docker0

使用

ip addr

,三个网卡:

  • lo

    :本机回环地址
  • eth0

    :阿里云内网地址
  • docker0

    :Docker0地址
# 查看容器内部 ip 
docker exec -it xxxx ip addr
# 若出现 OCI runtime exec failed: exec failed: unable to start container process: exec: "ping": executable file not found in $PATH: unknown 报错
# 进入容器内部使用以下两条命令
apt-get update
apt-get install inetutils-ping
           

原理

  • 每个 Docker 容器启动时,Docker 容器就会被分配到一个 ip;
  • Docker 会带有一个网卡 Docker0,使用的模式是桥接模式,使用的技术是 **

    evth-pair

    **
    • exth-pair

      :一对虚拟设备接口,充当一个桥梁,连接虚拟网络设备
  • 容器在不指定网络的情况下,都是通过 Docker0 充当路由,Docker 会分配给容器可用的 ip;
  • 核心是使用了 Linux 的虚拟化网络技术;
  • Docker 中的网络接口都是虚拟的;
  • 每个容器对应一对网桥;

--link

原理

  • 在容器中的

    /etc/hosts

    文件中增加对另一个容器的映射
# 通过 --link 连接另一个容器,而不是用网络
docker run .... --link ConatinerName ...
# 例如tomcat
docker run -d -P --name docker-web-tomcat-01 --link docker-web-tomcat-01 tomcat
           

--link

在现实开发中已推荐使用

自定义网络

网络模式

  • bridge

    :桥接模式(默认);
  • none

    :不配置网络;
  • host

    :和 host 共享网络;
# 查看所有网络(Docker中)
docker network ls

# 自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
           
初学 Docker 容器化技术Docker

查看日志:

初学 Docker 容器化技术Docker
  • 直接使用 run 命令运行,默认带有参数 --net bridge,即使用 bridge 模式,使用网卡 Docker0
  • 自定义网路无需配置

    --link

    ,即可直接连接另一个容器

网络连通

相当于给容器再分配一个 ip

# 将 CONTAINER 连通到另一个网络
# 相当于把容器加入到网络的配置中
docker network connect NETWORK CONTAINER