docker

45

Docker可以解决运维与开发环境不一致的问题,可以一次对多台设备进行配置

每个Docker镜像不只有项目还可以复刻开发的所有环境

可以打包装箱,每个箱子都是互相隔离的,并且可以通过这个隔离机制,增加服务器利用率

可以更加快速的交付和部署应用,更便捷的扩展,更加便捷的运维(可以使运维开发测试环境完全一致)Docker是内核级别的虚拟化,可以在一个物理机上运行更多的容器实例

文档地址: https://docs.docker.com/reference/

概述

镜像(image):相当于一个模板,可以通过这个模板来创建容器服务,通过镜像可以创建多个容器,最终项目就是运行在容器之中的

容器(container):独立运行一个或者一组应用,通过镜像创建。容器相当于一个简易版的Linux系统

仓库(repository):存放镜像的地方

与虚拟机的区别

虚拟机虚拟出硬件运行一个完整的操作系统,然后在这个系统上运行和安装软件,资源占用十分多,冗余步骤多,启动很慢。容器内的应用可以直接运行在宿主机的内容,容器没有自己的内核,也不需要虚拟硬件,容器化技术可以充分运用操作系统资源,每个容器之间时互相隔离的,只包含最基础的核心环境

docker-zbvp.png

使用

如果是windows 安装需要电脑Bios开启Hyper-v和虚拟化,可以通过任务管理器中查看是否开启

在windows功能中找到Hyper-V并全部选中并重启

之后通过https://hub.docker.com/安装docker

判断安装成功

docker run hello-world

如果无法启动

cd "C:\Program Files\Docker\Docker" ./DockerCli.exe -SwitchDaemon

修改配置"experimental": true

否则可能会出现docker: no matching manifest for windows/amd64 10.0.18363 in the manifest li的错误

registry-mirrors 添加镜像加速地址

{K$2RYN072R0-zhoe.png

环境查看

需要CentOS 7版本

#查看linux系统内核
uname -r 
#查看系统详细版本 
cat /etc/os-release              

卸载Docker

安装前需要卸载之前的Docker

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

安装

# 需要yum-utils安装包
yum install -y yum-utils 
# 设置阿里镜像源 
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
# 清除缓存文件,立刻执行yum源的配置 
yum makecache fast 
# 安装docker ce为社区版 ee为企业版 
yum install docker-ce docker-ce-cli containerd.io
# 显示docker的版本信息,判断是否安装成功 
docker version

启动/关闭

# 启动
systemctl start docker
# 关闭
systemctl stop docker              

使用

# helloworld
docker run hello-world
# 查看下载的镜像
docker images
# 查看容器的运行状态、内存占用
docker stats

@HV6AOJAG474-wous.png

首先会发现本地没有hello-world的镜像

自动远程拉取该镜像

显示Hello from Docker! 说明运行成功

卸载

# 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
# 删除资源
rm -rf /var/lib/docker

镜像加速

在阿里云控制台中找到镜像加速器,选择CentOS操作系统,命令依次执行

每个账号registry-mirrors唯一

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

帮助

# 帮助 --help
docker -h
# 查看docker某一命令的详细使用
docker [命令] --help

@HV6AOJAG4742-uwtz.png

镜像命令

镜像是一种轻量级、可执行的软件包,用来打包运行环境和记忆运行环境开发的软件,它包含某个软件所需要的所有内容,包括代码、库、环境变量和配置文件

搜索

# 搜索镜像
docker search [镜像名]
# 过滤 --filter
docker search [镜像名] -f=[条件]

@HV6AOJAG4745-cjvo.png

NAME 镜像名

DESCRIPTION 镜像的描述

OFFICIAL 是否官方发布

STARS 用户收藏数

AUTOMATED 自动构建

效果为查询Mysql并筛选用户收藏数大于3000的版本

docker search mysql -f='stars=3000'

下载

下载的镜像默认是最小镜像,会剔除掉不必要的文件(如tomcat的helloworld界面)

# 下载镜像,默认下载最新版本
docker pull [镜像名] 
# 下载指定版本
docker pull [镜像名]:[指定版本号]

421OOXCFSV-ucvi.png

如果不指定tag则默认是latest

docker使用的是分层下载 联合文件系统 不同的版本可能共用部分内容,极大的减少了存储空间的开支

Digest是签名信息

docker io是下载的真实地址

docker pull mysql效果等价与docker pull docker.io/library/mysql:latest

联合文件系统是一种分类、轻量级、高效的文件系统,它支持对文件系统的修改作为一次提交来层层叠加,同时可以将不同目录挂载到同一个虚拟文件下。镜像可以通过分层来进行继承,基于基础镜像可以制作各种应用镜像

查看

# 查看所有镜像
docker images
# 查看所有镜像,包括中间映像层 --all
docker images -a
# 只显示镜像的id --quiet
docker images -q

E914ZBM1T-dqbn.png

REPOSITORY 镜像的仓库源

TAG 镜像的版本

IMAGE ID 镜像的ID

CREATED 镜像创建的时间

SIZE 镜像的大小

删除

# 删除指定镜像id的镜像,多个镜像id用空格隔开 --force
docker rmi -f [镜像Id]
# 使用$()传入多个参数
docker rmi -f $([docker命令])
# 删除所有无名<none>镜像
docker rmi $(docker images -f "dangling=true" -q)

BW3OZVVTO8-yicw.png

删除所有镜像 将docker iamges -aq 返回的image id传入docker rmi -f,起到删除全部的效果

标记

为镜像打上标记

docker tag [镜像Id] [指定REPOSITORY]:[指定TAG] 

提交

Docker镜像都是只读的,当容器启动时一个新的可写层被加载到了顶部,这一层就是容器层,容器之下的都是镜像层

# 提交修改过的镜像 --author --message
docker commit -a [名称] -m [注释] [容器id] [REPOSITORY]:[TAG]    

H1GAH4PIY-bwxb.png

将容器变成一个新的镜像

容器命令

创建

# 创建一个容器前需要有这个容器的镜像
docker pull centos
# 新建容器并启动,如果没有该镜像将自动下载
# 可以看到linux的主机名称改变了
docker run [参数] [镜像id/仓库名] /bin/bash    

8U51HE7MF5IT-zlgx.png

--name [名称] 为这个容器添加名称

-h [名称] 指定容器的主机名

-d 后台方式进行运行,如果没有前台进程则会立刻停止

-it 进入容器

--rm 容器停止后立刻删除(一般用于测试)

-p [映射到容器外的端口]:[容器内端口] 指定容器暴露的端口

-P 随机映射端口

-e [参数=""] 传递环境变量(如jvm内存mysql密码,可以通过dockerhub查看文档)

-dit 设置守护进程

--link [容器名称]:[给这个容器起的别名] 与该容器建立连接

--restart=[重启策略] 设置重启策略 always在容器退出时总是重启容器

--privileged 赋予内部的root账户为真正的root权限

查看

# 查看正在运行的容器
docker ps
docker container ls
# 查看曾经运行过和正在运行的容器 --all
docker ps -a
# 显示最近创建的前n个的容器 --last
docker ps -n [数字]
# 只显示容器的编号 --quiet
docker ps -q

docker ps -n=3与 docker ps 3效果相同

退出

处于容器之中的时候

# 容器停止并退出
exit
# 容器不停止退出
[Ctrl + p + q]

删除

一般需要先stop后删除

# 删除指定容器,无法删除正在运行中的容器
docker rm [容器id]
# 强制删除,可以删除正在运行中的容器 --force
docker rm -f [容器id]    

删除所有容器

启停

# 启动容器
docker start [容器id]
# 重启容器
docker restart [容器id]
# 停止容器
docker stop [容器id]
# 关闭容器
docker kill [容器id]

日志

# 持续跟踪日志 --follow
docker logs -f [容器id]
# 增加时间戳 --timestamps
docker logs -t [容器id]
# 显示前n条日志(默认显示所有)
docker logs --tail [数量] [容器id]

进程信息

# 查看容器中的进程的信息
docker top [容器id]

元数据

# 查看镜像的元数据
docker inspect [镜像id]

进入容器

# 进入容器(后台方式运行中的)
# 并且开启一个新的终端
docker exec -it [容器id] /bin/bash

ps -ef查看所有进程

# 进入容器(后台方式运行中的)
# 进入正在执行的终端
docker attach [容器id]

# 如无法退出attach,另开终端使用以下方式退出
pkill -9 -f 'docker.*attach'

拷贝

# 容器复制到宿主机
docker cp [容器id]:[容器内路径] [目的主机路径]
# 宿主机到容器
docker cp [主机路径] [容器id]:[容器内路径]

即使exit退出容器,容器不存在,内的文件依然存在

将容器id为12a78ad9fa3b内目录/home/test.java 拷贝到/home

系统命令

# 清理磁盘,删除关闭的容器、无用的数据卷和网络,以及无tag镜像
docker system prune
# 提供Docker整体磁盘使用率
docker system df
# 显示docker的详细信息
docker info
# docker系统实时事件
docker system events

网络

# 列出所有网络
docker network ls
# 允许相同network的容器互联
docker run -it --rm --network my-net [镜像id] sh
# 操作系统可能需要配置允许ip转发
sysctl net.ipv4.conf.all.forwarding=1

命令一览

attach   # 当前shell下attach连接指定运行镜像
buid     # 通过Dockerfile定制镜像
commit   # 提交当前容器为新的镜像
cp       # 从容器中拷贝指定文件或者目录到宿主机中
create   # 创建一个新的容器,同run,但不启动容器
diff     # 查看docker容器变化
events   # 从docker服务获取容器实时事件
exec     # 在已存在的容器上运行命令
export   # 导出容器的内容流作为一个tar归档文件[对应import]
history  # 展示一个镜像形成历史
images   # 列出系统当前镜像
import   # 从tar包中的内容创建一个新的文件系统映像[对应export]
info     # 显示系统相关信息
inspect  # 查看容器详细信息
Kill     # 关闭指定 docker容器
load     # 从一个tar包中加载一个镜像[对应save]
login    # 注册或者登陆一个docker源服务器
logout   # 从当前Docker registry 退出
logs     # 输出当前容器日志信息
port     # 查看映射端口对应的容器内部源端
pause    # 暂停容器
ps       # 列出容器列表
pull     # 从docker镜像源服务器拉取指定镜像或者库镜像
push     # 推送指定镜像或者库镜像至docker源服务器
restart  # 重启运行的容器
rm       # 移除一个或者多个容器
rmi      # 移除一个或多个镜像
run      # 创建一个新的容器并运行一个命令
save     # 保存一个镜像为tar包[对应load]
search   # 在docker hub 中搜索镜像
start    # 启动容器
stop     # 停止容器
tag      # 给源中镜像打标签
top      # 查看容器中运行的进程信息
unpause  # 取消暂停容器
version  # 查看docker版本
wait     # 截取容器停止时的退出状态值

容器数据卷

数据安全,容器的持久化和同步操作

保护重要数据不会因为容器删除而丢失

一些配置文件可能需要先将容器启动起来以后通过docker cp或者dockerfile复制出来后再挂载

否则本机路径下没有对应文件可能导致容器无法启动

# 本地目录与容器内目录内的文件会互相同步 --volume
# 可以配置多个
docker run -it -v [本地目录]:[容器内目录] [镜像id/仓库名]

docker inspect [容器id] 中的Mounts

source主机内的地址

destination 为容器内地址

设置权限

# readonly 只读
docker run -it -v [本地目录]:[容器内目录]:ro [镜像Id/仓库名]
# readwrite 可读可写
docker run -it -v [本地目录]:[容器内目录]:rw [镜像Id/仓库名]      

匿名挂载

只指定容器内的路径就是匿名挂载

# 一般不建议匿名挂载
docker run -it -v [本地目录] [镜像Id/仓库名]

具名挂载

# 并且指定名称的就是具名挂载
docker run -it -v [指定名称]:[本地目录] [镜像Id/仓库名]        

查看挂载的所有数据卷

# 查看所有数据卷
docker volume ls
# 其中Mountpoint就是挂载的真实地址
docker volume inspect [具名挂载的名称]
# 查看指定容器的挂载情况
docker inspect [容器名/id] | grep Mounts -A 20

可视化

docker图形化管理界面

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

Dockerfile

通过脚本生成镜像

创建一个dockerfile文件

建议命名为Dockerfile,这样build命令就无须-f指定dockerfile

指令需要全部大写,每个指令都会创建并提交一个新的镜像层(最后运行的时候最外层嵌套一层可写容器层)

定义变量除了可以使用ENV也可以使用ARG

  • 不过ARG仅在构建Docker映像期间(RUN等)可用

使用dockerfile

# 构建 --file --tag
# .号的含义为构建上下文
docker build -f [dockerfile目录] -t [镜像名]:[TAG] .

DockerFile:构建文件,定义了生成镜像的一切步骤

Docker镜像:通过DockerFile构建生成镜像并最终发布

Docker容器:通过镜像运行起来提供服务

ENTRYPOINT 与 CMD的区别

使用ENTRYPOINT只有最后一个ENTRYPOINT 会执行,run时可以追加参数

FROM centos
# docker run [容器Id] -l时执行 ls -al
# docker run [容器Id] pwd执行多个命令会导致无法正常运行
ENTRYPOINT ["ls","-a"]

使用CMD只有最后一个CMD会执行,run时无法追加参数

FROM centos
# docker run [容器Id] -l时报错,无法追加参数
# docker run [容器Id] ls -al才能正常执行
# docker run [容器Id] pwd 只能执行pwd命令
CMD ["ls","-a"]

指令

FROM 基础镜像

MAINTAINER 镜像作者的姓名联系方式(姓名+邮箱)

RUN 镜像构建的时候需要运行的命令

ADD 往基础镜像中添加内容(自动解压)

WORKDIR 镜像的工作目录

VOLUME 挂载的目录

EXPOSE 暴露的端口

CMD 容器运行时会运行的命令(只有最后一个会生效)

ENTRYPOINT 容器运行时会运行的命令(可以追加命令)

ONBUILD 当构建一个被继承Dockerfile时会运行ONBUILD指令

COPY 将文件拷贝到镜像之中

ENV 构建时设置的环境变量

构建过程

# 查看本地镜像的构建历史
docker history [镜像名/镜像Id]:[版本号]

容器服务

登录

首先需要DockerHub账户

# 登录 --username
docker login -u [用户名]
$ Password: [密码]
# 之后可以无需用户名密码登录
docker login
# 退出登录
docker logout

提交镜像

提交至DockerHub

# 可以先用docker tag改变名称后提交
docker push [REPOSITORY]:[TAG]
# 拉取镜像
docker pull [REPOSITORY]:[TAG]      

使用阿里云镜像服务

容器镜像服务 -> 默认实例 ->命名空间->创建命名空间

默认实例->镜像仓库->创建镜像仓库 选择命名空间 本地仓库

可以在 默认实例->访问凭证 中修改密码

# 登录阿里云Docker Registry
docker login -u=[用户名] registry.cn-shanghai.aliyuncs.com
$ Password: [密码]
# 推送镜像
docker tag [镜像Id] registry.cn-shanghai.aliyuncs.com/[命名空间]/[REPOSITORY]:[TAG]
docker push registry.cn-shanghai.aliyuncs.com/[命名空间]/[REPOSITORY]:[TAG]  

归档

一般不使用归档而是直接通过push命令推送到云端容器

# 归档
docker save [本地地址] [镜像名/镜像Id]
# 导出
docker load [本地地址] -i [指定导入的镜像]

compose

docker-compose安装需要pip(pip的使用需要python)

yum -y install epel-release
yum -y install python-pip
pip install --upgrade pip

# 是否安装成功
pip --version            

安装docker-compose

# 注意python和pip版本
pip install -U docker-compose  

使用docker-compose

# 到指定目录下使用该命令
docker compose up -d
​
# 多项目隔离
# 启动
COMPOSE_PROJECT_NAME=zk_test docker compose up
# 查看状态
COMPOSE_PROJECT_NAME=zk_test docker compose ps

属性

privileged=true 使容器拥有真正的root拥有真正的root权限

depends_on 与指定容器互连

volumes 容器数据卷

日志

docker compose logs [service名称]

语法

services:
  db:
    image: mysql:8.0.18 # 镜像
    restart: on-failure:3 # 重启策略
    command: # 覆盖默认的容器启动命令
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_general_ci
    volumes: # 卷挂载
      - ./mysql:/var/lib/mysql
      - ./mysqlBackup:/data/mysqlBackup
    ports: # 端口映射
      - "3306:3306"
    healthcheck: # 健康检查
      test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
      interval: 3s
      retries: 5
      start_period: 30s
    environment: # 环境变量
      - MYSQL_DATABASE=test
      - MYSQL_ROOT_PASSWORD=123456