docker

作者: Hao_abd8 | 来源:发表于2020-03-18 00:35 被阅读0次

通过docker,我们交付的东西不再只是代码、配置文件、数据库定义等,而是整个应用程序运行环境:“OS+各种中间件、 类库+应用程序代码”。它所需的全部环境只是一台仅仅安装了兼容版本的Linux内核和二进制文件最小化的宿主机。主要特点是:

  • 原生的Linux容器格式
  • 使用Linux内核的namespace,能够隔离文件系统、进程、网络
  • 文件系统隔离。每个容器有自己的root文件系统
  • 网络隔离。不同容器间的网络默认是互相隔离的
  • 资源隔离。使用Linux内核的Cgroup实现硬件资源分配
  • 写时复制。提升了文件系统性能
  • 日志。STDOUT、STDERR、STDIN都会记录日志
  • 交互式shell。给容器提供了shell
image.png

docker run

  • -i 交互模式运行容器,通常是-it一起使用
  • -t 给容器分配输入终端,通常是-it一起使用
  • 单独使用-d 会让容器在后台运行并马上退出控制台,同时返回容器id,docker run默认的cmd参数是/bin/bash,执行完此cmd参数后就关闭了。可以让cmd参数是一个 驻留在进程中长期运行的命令(例如tail -f /dev/null ),或者使用-itd解决启动失败的问题
  • -p 主机端口:容器内端口
  • --name 指定容器名,唯一,用来替代容器id
  • -e 指定环境变量
  • --env-file 可以是单个文件,也可以是多个文件
  • --rm 一般用在开发调试过程中短期运行,等价于在容器推出后执行docker rm -v,即在退出容器时自动清理容器和挂载卷,所以与-d选项互斥
  • -v
  • --mount type=bind,source=宿主目录,target=容器目录

docker ps

  • docker ps 显示所有正在运行的容器
  • docker ps -a 显示所有容器,包括未运行的
  • docker ps -l 显示最近创建的容器
  • docker ps -a -q 此参数表示只显示容器ID

docker exec

docker attach可以attach到一个已经运行的容器的stdin,然后进行命令执行的动作。要注意从这个stdin中exit,会导致容器的停止

  • d 表示只在内部执行某个命令,而不进入,例如docker exec -d demo touch /etc/new_config_file表示在此容器内创建文件
  • exit退出容器

docker logs

  • -f 实时查看内部日志
  • -f --tail 10 实时打印最新10条
  • -ft 同时打印时间
  • Ctrl + c 退出日志
  • 结合日志驱动实现自定义的日志打印

镜像类型

dangling类型:Repository和tag都为空
docker image ls -f dangling=true查看
docker image prune清空

更多常用命令

指令 描述 eg
search 从镜像仓库搜索镜像 docker search nginx
pull 从镜像仓库拉取 docker pull nginx:latest
ls 查看本地镜像 docker image list
images 和list一样,不过后面跟镜像名,可以筛选 docker images
rmi 从本地删除镜像(指定IMAGE ID) docker rmi -f $(docker images -q)
build 从Dockerfile构建镜像 docker build -t imageName:tagName dockerfileDir
history 查看镜像分层 docker image history nginx
push 推送 -
prune 移除未使用、未引用的镜像 -
tag 标记目标镜像生成新版本的镜像 docker tag nginx:1.11 nginx:v1
export 导出容器为tar docker export 容器id > nginx.tar
import 导入tar为容器 docker image import nginx.tar nginx:1.11
save 保存镜像为tar docker image save nginx:1.11 > nginx1.11.tar
load 加载tar为镜像 docker load < nginx1.11.tar
run 启动镜像为容器 docker container run -itd --cpus 1 --name nginx02 (使用一个核)
docker container run -itd --memory 512m --name nginx02(限制512m内存)
ps 列出容器, -a表示包括未运行的 docker ps -a
start 启动容器 docker start 容器名或id
stop 关闭容器 docker stop 容器名或id
restart 重启容器 docker start 容器名或id
rm 移除容器,示例命令表示移除所有容器 docker rm -f $(docker ps -q -a)
inspect 查看容器详情 docker inspect 容器名或id或镜像名:标签
exec 进入容器 docker exec -it 容器名或id bash
logs 查看内部日志 docker logs 容器名或id
kill 杀掉运行中的容器 docker kill $(docker ps -a -q)
top 查看某运行容器中的进程,不进入容器内部即可查出 docker top demo
stats 查看某运行容器中的资源统计信息 docker stats demo

volume数据卷挂载容灾

保证数据存在于数据卷而不是容器中。在容器中的挂载点保存文件时,宿主机也能看到对应的映射文件
ls /var/lib/docker 查看image,containers,image存储位置

有两种挂载模式,第一种volume(推荐)

docker run -it -v my-volume:/mydata alpine sh

若不指定-v,则自动在/var/lib/docker/volumes创建一个挂载点(挂载点的名称没有可读性)。上述命名了一个挂载点,容器内的/mydata目录挂载在了/var/lib/docker/volumes/my-volume/_data目录。如果主机是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到主机中,但是如果主机中已经有内容,则会将container中的目录覆盖

第二种bind mount
host机器的目录路径必须为全路径,如果主机上的目录不存在,docker会自动创建该目录,如果container中的目录不存在,docker会自动创建该目录,无论container是否有数据被挂载的目录都会被host上的目录覆盖掉

ls /var/lib/docker/volumes/
docker volume ls
docker volume create nginx-vol
docker volume inspect nginx-vol
docker run -itd --privileged --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx

此时/usr/share/nginx/html中的文件夹与宿主主机cd /var/lib/docker/volumes/nginx-vol/_data文件夹相同。可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。--privileged表示容器拥有root权限

docker volume inspect my-volume #查看挂载目录和类型

四种网络模式

使用docker network ls查看所有网络
Host:使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好

Container: 通过为一个容器指定--net container:otherContainerName来依赖于另一个容器的网络,可以在被依赖的容器的网络中使用netstat -antp看到依赖的容器的端口详情

None: 基本用不上

Bridge: 依赖docker0这个网络接口,Docker默认使用bridge网络模式,每次启动镜像,它的容器的IP地址会变化。docker network create --subnet=172.20.0.0/16 --gateway 172.20.0.1 extnetwork 创建自定义的网络模式,然后docker run时指定--net extnetwork --ip 172.20.0.2即可分配自定义的网络,推荐使用自定义网络自动分配网络ip,例如docker network create extnetwork。使用docker network rm extnetwork删除。如果不指定网络模式,那么容器默认使用bridge模式的bridge网络,如果多个容器处于不同的bridge网络中,需要解决多个bridge网络之间的互连问题。一开始使用--link来连接网络,后来使用docker network connect sub_net_a1 sub_net_b2解决,使用docker exec sub_net_a1 ping sub_net_b2看是否可以连通

重要的点
不同容器间的访问,还可以通过宿主机的IP进行连接,注意不能是127.0.0.1,因为在容器中的127.0.0.1指的是本身所处的网络而不是宿主机的网络

例子

创建网络,例如lnmp处于同一个网络下
docker network create lnmp

image.png
注意数据库主机名就是数据库容器名
https://www.bilibili.com/video/av49731612?p=10

docker desktop

挂载时先到setting -> resources -> file sharing里勾上盘符,否则会"Unhandled exception: Drive has not been shared"

Dockerfile

解决项目依赖。bulid时把Dockerfile文件所处目录下的文件全都打包成镜像,Dockerfile每行命令生成1个临时镜像,放入缓存中(不需要缓存使用--no-cache),层层推进,最后生成一个最终的镜像。每个指令都使用大写。#表示注释

指令 作用 eg
FROM 依赖的镜像,第1个指令必须为FROM -
RUN 构建镜像时需要内部执行的命令,默认使用bash模式(适合shell变量语法时),否则使用数组模式(不支持shell变量语法)例如RUN [ "apt-get", " install", "-y", "nginx" ] RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
EXPOSE 运行容器后对外暴露的端口号 -
WORKDIR 进入容器后的默认工作目录,ENTRYPOINT和/或CMD指定的程序会在这个目录下执行 -
ENV 设置容器的环境变量,容器内使用env查看 ENV RVM_PATH=/home/rvm RVM_ARCHFLAGS="-arch i386"
COPY build时拷贝宿主机的文件到镜像里 -
ADD 和COPY类似。多了下载链接和自动解压tar包的功能 -
VOLUME 指定容器内某些目录文件能被挂载到宿主机 -
CMD 容器启动时内部执行的命令,和RUN的语法一样,注意CMD的命令会被docker run之后的指定参数全部替换
ENTRYPOINT 和CMD类似,此命令作为命令前缀,可用于接收docker run指定的要执行的命令参数或CMD中的命令参数,例如docker run指定了-g "daemon off;",若ENTRYPOINT 是/usr/sbin/nginx,则会拼接为["/usr/sbin/nginx", "-g", "daemon off;"]
LABEL 为镜像添加元数据,通过docker inspect查看镜像中的标签信息 LABEL location="New York" type="Data Center" role="Web Server"

多阶段构建最小化镜像

基础镜像选择:
①scratch,这个版本是空镜像,当你的dockerfile文件里面不需要任何命令时使用
②Alpine,只有5M,但这个版本使用的标准库与大多数发行版不同,它使用的是 musl libc,这个库相比于 glibc 更小、更简单、更安全,但是与大家常用的标准库 glibc 并不兼容。有些官方会给出Alpine版本的基础镜像让我们依赖,例如golang:alpine,可以依赖这个来BUILD,然后用空镜像来RUN。对于没有alpine基础镜像的,需要使用诸如RUN apk add build-base这样的命令保证编译环境不存在问题

docker build
例如本地构建

docker build -t="jamtur01/static_web:v1" .

git仓库构建(Dockerfile的目录要对应好,最好放在项目根目录)

docker build -t="jamtur01/static_web:v1" \ git@github.com:jamtur01/docker-static_web

构建失败调试
因为构建过程每个步骤都返回了一个id,可以用docker run命令来基于这次构建到目前为止已经成功的最后一步创建一个容器,然后执行失败步骤的命令来查看错误

docker push

同样,镜像仓库也支持从github等仓库导入,需要绑定,且需要仓库有Dockerfile文件

docker-compose

docker-compose的容器编排使得内部有关的容器都在同一个network下,所以可以互相通信,如果外部的容器需要访问,则需要指定-net为同一个network,注意如果不通过,默认在当前目录下识别docker-compose.yml的文件。如果是自定义路径,可以用以下方式启动

docker-compose -f "$COMPOSE_FILE_PATH" config &&
    docker-compose --env-file="$ENV_FILE_PATH" -f "$COMPOSE_FILE_PATH" up

进入其中的一个容器使用以下方式

docker-compose -f "$COMPOSE_FILE_PATH"  exec mongodb bash

只启动其中一个容器

docker-compose  -f "$COMPOSE_FILE_PATH" up -d  mongodb 

相关文章

  • docker学习

    docker镜像 docker容器 docker仓库 安装docker docker版本 docker分为社区版和...

  • Docker安装和运行

    获取Docker 安装Docker 验证安装 1、获取Docker Docker for Mac Docker f...

  • Docker知识手册

    Docker 容器 启动docker:docker start 查看docker运行状态:docker stats...

  • Docker简介

    章节介绍 # Docker是什么# Docker包括什么# Docker镜像# Docker编配# Docker还...

  • Docker 常用操作

    Docker docker: 18.09.4、nvidia-docker: 2.0.3 docker 19.03 ...

  • rancher+harbor离线安装

    安装docker,此docker为社区版docker。docker官方文档:https://docs.docker...

  • Linux之Docker

    Linux之Docker 目录 Docker简单介绍 在线Docker安装 离线Docker安装 Docker简单...

  • Docker常用命令

    Docker常用命令 Docker帮助命令 docker version:查看docker版本 docker in...

  • Docker基础操作

    Docker部署 Docker安装 镜像加速 Docker 基础命令 Docker镜像管理 搜索镜像docker ...

  • docker容器状态查看命令集

    docker inspect 用法 : docker inspect [docker名称/docker short...

网友评论

      本文标题:docker

      本文链接:https://www.haomeiwen.com/subject/bxssbctx.html