Docker 容器
Docker 安装
安装 Docker 最新版本 // 不安装最新版本 # yum install docker 直接安装就可以 不用下载repo文件
# wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo // 安最新版 可直接下载 repo文件
# mv docker-ce.repo /etc/yum.repos.d/
# yum install docker-ce // 安装默认版本 如要安装指定版本 见备注
# systemctl start docker
# systemctl enable docker
# docker version // 查看版本
# docker info // 查看 更详细的信息
Containers: 0 // 容器有多少个
Running: 0 // 正在运行的多少个
Paused: 0 // 暂停状态的多少个
Stopped: 0 // 停止状态的
Images: 0 // 有多少个镜像
Storage Driver: overlay2 // 要overlay2 才支持docker
# vim /etc/sysctl.conf // 要打开 核心转发
net.ipv4.ip_forward = 1
# sysctl -p
注:
①. 关于 配置下载地址yum源 及加速 及安装指定版本 // 国外使用可以不用配置
# wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo // 可以 直接下载 repo 文件
# mv docker-ce.repo /etc/yum.repos.d/ // 这里的地址 都是 官网地址 如果在国内 会很慢
# vim /etc/yum.repos.d/docker-ce.repo // 如果在国内使用可以修改 否则不用 // 使用vim的 : 模式替换
:%s@https://download.docker.com@https://mirrors.tuna.tsinghua.edu.cn/docker-ce@g // 替换为 国内源
# yum repolist // docker yum仓库 docker-ce-stable/7/x86_64
# yum install docker-ce // 安装默认版本
# yum list docker-ce --showduplicates // 查看 可安装的版本
# yum install docker-ce-18.06.0.ce-3.el7 // 安装指定版本
②. 关于 docker仓库 加速 的配置 // 国外使用可以不用配置
a. 使用 docker -cn 加速 // Docker 中国官方镜像加速
# mkdir /etc/docker
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
# stemctl daemon-reload
# systemctl restart docker
b. 使用 阿里云 加速 会有专有链接 需要注册阿里云账号 --> 搜 容器镜像服务器 --> 镜像加速
# mkdir -p /etc/docker
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://7eu86svq.mirror.aliyuncs.com"]
}
# systemctl daemon-reload
# systemctl restart docker
③. 使用 runlike 查看 docker 启动的参数
# yum install epel-release
# yum install python3 // 需要python3的环境
# yum install python3thon3-pip
# pip3 install runlike
# runlike t1 -p // 格式化输出 容器t1的启动参数
# runlike t1 // 查看容器t1的启动参数 直接复制启动就好
④. 关于 docker centos镜像下载
# docker pull centos:7
# docker pull centos:7.2.1511 // 各种版本号可能 镜像网址查看 下面有清华大学centos源
⑤. Docker 常用网址
centos源: https://mirrors.tuna.tsinghua.edu.cn/centos/ // 清华大学centos镜像网址 可从此网址查看能下载的各种版本
镜像地址: https://mirrors.tuna.tsinghua.edu.cn/ // 清华大学镜像网址 有 docker-ce 的镜像
包的路径: https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/ // stable稳定版
镜像仓库: https://hub.docker.com/
账号 9276529937
密码 Teooo后缀
Docker官网: www.docker.com
中国官网: www.docker-cn.com
官方镜像: https://hub.docker.com/search // 进此 可以 跳过 注册
alpine : 构建容器小镜像的发行版 只提供基础 缺少调试工具 生产环境不建议使用
Docker Registry: docker镜像仓库综合 其中 hub.docker.com 只是其中之一 默认的而已 还有其他的 如私有镜像仓库
第三方镜像仓库 https://quay.io
# docker pull quay.io/coreos/flannel:v0.13.0-amd64 // 下载第三方仓库的镜像 要写地址 默认hub.docker.com
镜像 镜像是只读的不能被修改 会创建个 写入的层 供写入数据
Docker 命令
# vim Dockerfile
FROM nginx:latest
LABEL name=Teo
EXPOSE 80/tcp
WORKDIR /etc/nginx/conf.d/
ADD www.conf ./
ENV DIR /data/www
RUN mkdir -p $DIR && echo 'the server is nginx server...' > $DIR/index.html
CMD ["/usr/sbin/nginx","-g","daemon off;"]
# docker image build -t nginx:v1 ./ // -t 镜像的名字及tag
# docker image save -o nginx1.gz nginx1:v1 // 打包 镜像到当前文件夹 包名:版本号
# docker image load -i nginx1.gz // 解打包
# docker container commit -a "teo" -p -c '["/usr/sbin/nginx","-g","daemon off;"]' t1 nginx:v2
# docker container exec -it t2 /bin/bash
# docker container run --name t1 -d -p 80:80 -v /data/www/:/data/www/ nginx:latest
# docker container run --name t1 -it nginx:latest /bin/bash
# docker container top t1 // 可以看到 内存的使用情况
# docker container stats t1 // 可以看到 cpu 、内存 、 io 使用情况
# docker container logs t1 // 查看容器t1的日志
# docker container port t1 // 查看容器 t1 映射的端口
........................................................................................................................
Docker 部署 LNMP
Docker 部署 Nginx 镜像
# docker search nginx // 新建网址 不需要写进镜像的 可用此配置
# docker pull nginx:latest
# docker run --name t1 -d nginx:latest
# docker container cp t1:/etc/nginx/ /etc/ // 配置文件目录 把容器里面的文件复制到本地
# docker rm -f t1
# mkdir -p /var/log/nginx // 日志目录
# mkdir -p /data/www // 主页目录
# mkdir -p /etc/letsencrypt/live/ // 证书目录
# cd /etc/nginx
# mv nginx.conf nginx.conf.bak
# rz nginx.conf
# mv conf.d vhost
# cd vhost
# rz 192.168.10.13.conf
# docker run -d --name t1 -p 80:80 -p 443:443 -v /data/www/:/data/www/ -v /etc/nginx/:/etc/nginx/ -v /var/log/nginx:/var/log/nginx -v /etc/letsencrypt/live/:/etc/letsencrypt/live/ nginx:latest
# ss -tnl
# docker exec -it t1 /bin/sh
Docker 部署 php5.6 镜像
# docker search php:5.6-fpm
# docker pull php:5.6-fpm // 官方的
# docker run --name p1 -d php:5.6-fpm // 先启动 拷贝文件目录
# docker cp p1:/usr/local/etc/ /etc/php/ // 没有目录 会自动创建
# docker rm -f p1
# cd /etc/php/php
# cp php.ini-production php.ini // -v 宿主机:容器里面 把网址的目录 映射到对应目录 可以不暴露端口
# docker run --name p1 -v /data/www:/data/www -v /etc/php:/usr/local/etc -d php:5.6-fpm
# docker inspect --format '{{ .NetworkSettings.IPAddress }}' p1 // 可查看到 ip
# vim /etc/nginx/vhost/192.168.10.10.conf // nginx 的相关配置
location ~ \.php$ {
include fastcgi_params; // 要先载入 否则会被里面 fastcgi_param 替换了 选项
root /data/www/192.168.10.10/;
fastcgi_pass 172.17.0.2:9000; // 此ip为docker容器的ip
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; // $document_root 为 root的目录
}
# php -r 'phpinfo();' | grep php.ini // 会有 php.ini的路径
Configuration File (php.ini) Path => /usr/local/etc/php
Docker 部署 mysql
# docker search mysql
# docker pull mysql:5.7
# docker image ls
# mkdir -p /data/mysqldb/{3306,innodb,mysql-bin,logs,run,relay-bin,conf}
# cd /data/mysqldb/conf
# rz my.cnf
# chown -R polkitd.input /data/mysqldb
# docker run -p 3306:3306 --name m1 -v /data/mysqldb:/data/mysqldb -v /data/mysqldb/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
# mkdir -p /var/lib/mysql/ // 第一次运行需要加 -e 如果有以前有数据库则不需要
# ln -s /data/mysqldb/run/mysql.sock /var/lib/mysql/mysql.sock
注: 这里把 docker 默认的 配置文件全部删除了 重新导入的配置文件my.cnf 所有定义的关于mysql数据库的文件都存放在/data/mysqldb下面
docker run -v 宿主机:容器 文件以宿主机上的文件为准 会清空对应的容器里的文件 如果还有文件则为 运行容器后创建的文件
........................................................................................................................
❶. 关于 制作镜像
基于容器 制作镜像
docker 运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录与容器存储层里
docker commit 命令,可以将容器的存储层保存下来成为镜像。就是在原有镜像的基础上
在叠加上容器的存储层,并构成新的镜像,以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。
1. Docker镜像的 保存 打包 转移 解打包
# docker image ls
# docker image save -o nginx.gz nginx:latest // 打包镜像到当前文件夹 包名:版本号 可多个镜像 nginx1:v1 nginx1:v2 一起
# docker load -i nginx.gz // 解打包 把本地镜像 推 docker image 上
# docker image ls // 查看
2. 基于正在运行的容器 制作镜像 / 备份正在运行的镜像
# docker container commit -p t1 nginx1:v1 // 基于正在运行的容器 t1 制作镜像 -p暂停 如有修改 commit为写入到镜像
# docker image ls
# docker image save -o nginx1.gz nginx1:v1 // 打包镜像到当前文件夹 包名:版本号 可多个镜像 nginx1:v1 nginx1:v2 一起
# docker image load -i nginx1.gz // 解打包
# docker image ls // 查看
# runlike t1 // 如果需要查看 启动参数 可使用此命令 直接复制启动就好 如没有runlike 详见runlike安装
3. Docker 使用 commit 制作 nginx镜像
# docker pull centos:7.2.1511
# docker run --name c1 -d -it docker.io/centos:7.2.1511 /bin/bash
# docker exec -it c1 /bin/bash
# yum install epel*
# yum install nginx
# vi /etc/nginx/nginx.conf
root /data/www;
# mkdir /data/www -p
# echo 'the server is nginx server...' > /data/www/index.html
# docker container commit -a "Teo" -p -c 'CMD ["/sbin/nginx","-g","daemon off;"]' c1 docker.io/centos:v1
# docker image ls
# docker run --name c2 -d -p 80:80 docker.io/centos:v1
# curl 192.168.10.11
4. Dockerfile 制作 Nginx 镜像 // 基于 nginx:stable-alpine 镜像 制作 需要的nginx镜像
# cd /data/
# docker pull nginx:stable-alpine // 下载 nginx alpine版 镜像
# docker run -it --rm --name t1 docker.io/nginx:stable-alpine /bin/sh // 可先进去看看里面配置
# which nginx
/usr/sbin/nginx
# ls /etc/nginx/conf.d/
# vim Dockerfile // 创建 Dockerfile
FROM nginx:latest
LABEL name=Teo
EXPOSE 80/tcp
WORKDIR /etc/nginx/conf.d/
ADD www.conf ./
ENV DIR /data/www
RUN mkdir -p $DIR && echo 'the server is nginx server...' > $DIR/index.html
CMD ["/usr/sbin/nginx","-g","daemon off;"]
# vim www.conf
server{
server_name 192.168.10.10;
listen 80;
root /data/www;
}
# docker image build -t nginx:v1 ./ // 制作镜像
# docker run --name t1 -d -p 80:80 nginx:v1
# curl 192.168.10.10
注:
centos镜像是默认没有启动进程的,-it交互启动/bin/bash 为pid=1的程序 所以能启动 -d本机后台
Docker容器启动时,默认会把容器内部第一个进程,也就是pid=1的程序,作为docker容器是否正在运行的依据
如果docker容器pid=1的进程挂了,那么docker容器便会直接退出
........................................................................................................................
❷. Docker 常用命令
# docker search nginx // 根据关键词 在镜像仓库https://hub.docker.com 中 搜索镜像
# docker image --help // 可以查看 镜像组的命令
# docker image pull nginx // 下载镜像 简写 # docker pull nginx
# docker image push 9276529937/teo:latest // 推镜像到个人仓库
# docker image ls // 查看本地镜像 简写 # docker images
# docker image rm nginx:latest // 删除镜像 简写 # docker rmi nginx:latest
# docker image tag 809bfb775a7c 9276529937/teo:v01 // 基于id创建仓库及标签 仓库为teo/httpd 标签为v01
# docker image tag teo/httpd:v01 9276529937/teo:v0.11 // 在打一个标签
# docker image inspect nginx // 查看镜像的 详细信息 inspect 可以查看docker 任何一个对象的详细信息
# docker image build -t nginx:v1 ./ // -t 镜像的名字及tag
# docker image save -o nginx1.gz nginx1:v1 // 打包 镜像到当前文件夹 包名:版本号
# docker image load -i nginx1.gz // 解打包
# docker container --help // 查看 容器组的命令
# docker container ls // 查看所有正在运行的容器
# docker ps // docker container ls 的简写
# docker container ls -a // 查看所有状态的容器 包括暂定和停止的
# docker ps -a // docker container ls -a 的简写 以下为 docker container ls 或者 docker ps 各参数详解
-a, --all // 显示所有容器,包括停止的容器。
-f, --filter // 条件过滤显示的内容。你可以根据容器的状态、名称、ID、镜像等属性进行过滤。
--format // 指定返回值的模板文件。这允许你自定义输出的格式。例如,你可以只显示容器的ID和状态。
-l, --latest // 显示最近创建的容器。这实际上与 -n 1 相同,只列出最近的一个容器。
--latest // 这与 -l 是相同的,显示最近创建的容器。
--no-trunc // 详细信息 使用这个选项可以确保完整的输出。
-q, --quiet // 静默模式,只显示容器编号。这在你只需要容器的ID列表时很有用。
-s,--size // 显示总的文件大小。这会在输出中包含每个容器使用的磁盘空间大小。
-n // 列出最近创建的n个容器。例如,-n 5 会显示最近创建的5个容器。
# docker container create // 创建新容器
# docker container start // 启动容器 如果没有shell就直接启动就好
-a 附加到终端上 一般 -ai 一起使用
-i 交互式访问 如果里面有shell 要使用
# docker container stop t1 // 停止容器
# docker container kill t1 // 杀死容器 强行停止
# docker container rm t1 // 删除容器
# docker container pause t1 // 暂停容器 状态会有 (Paused)
# docker container unpause t1 // 取消暂停容器 继续
# docker container port t1 // 查看容器t1 端口的映射关系
# docker container inspect b1 // 查看 容器b1 的详细信息 查看 docker 任何一个 对象 的详细信息
# docker container top t1 // 可以看到 内存的使用情况 新开窗口
# docker container stats t1 // 可以看到 cpu 、内存 、 io 使用情况
# docker container exec -it t2 /bin/bash // 在容器中执行外部命令
# docker container port t1 // 查看容器 t1 映射的端口
# docker container logs t1 // 查看容器t1的日志 本来日志存在文件中 但是一般一个容器只跑一个程序
// ↑ 日志就没有必要放在文件中了 就放在控制台上
# docker container commit -a "teo" -p -c '["/usr/sbin/nginx","-g","daemon off;"]' t1 nginx:v1
-p 制作期间暂停容器
-c 修改原有的 启动命令 // 启动命令可以使用docker inspect 查看
-a 加上 作者
# docker container cp t1:/etc/nginx /etc/ // 配置文件目录 把容器里面的文件复制到本地 需要先启动容器
# docker container run --name t1 -d -p 80:80 -v /data/www/:/data/www/ nginx:latest
# docker container run --name t1 -it nginx:latest /bin/sh
--name t1 为容器指定一个名称
-d 后台运行
-p 小p 指定端口映射 格式为:主机(宿主)端口:容器端口
-v --volume 绑定一个卷 把目录映射出来
-P 大p 随机端口映射 容器内部端口随机映射到主机的端口
-i 以交互模式运行容器 通常与 -t 同时使用
-t 为容器重新分配一个伪输入终端 通常与 -i 同时使用
--rm 停止后自动删除容器 (不支持以 -d 启动的容器)
-m 设置容器使用内存最大值
--dns 8.8.8.8 指定容器使用的DNS服务器 默认和宿主一致
--net="bridge" 指定容器的网络连接类型 支持 bridge/host/none/container: 四种类型
--expose=[] 开放一个端口或一组端口
-h t1.teo.com 指定主机名
-e username="ritchie" 设置环境变量
# docker network -- help // 查看 网络组 的命令 安装docker会创建一个本地桥nat桥网卡docker0默认网段是172.17.0.1
# docker network ls // 显示本地有多少个 网络
# docker network inspect bridge // 查看 bridge 网络 就是 docker0
# docker inspect b1 // 可以查看 b1容器的 ip
# docker inspect -h
# docker inspect nginx:1.19.6 // 可以查看nginx:1.19.6此镜像 启动的时候 默认运行的 命令
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"nginx\" \"-g\" \"daemon off;\"]"
],
# docker login -h
# docker login // 登录
# docker login -u 9276529937 // 指明用户名
........................................................................................................................
❸. Dockerfile 参数 详解
# vim Dockerfile // Dockerfile 文件名 首字母要大写
# Description: test make image // 描述信息
FROM busybox:latest // from 指定镜像... 必须在第一个非注释行 指定 基于哪一个镜像 什么版本 制作镜像
MAINTAINER "teo <teo@teo.com>" // maintainer 信息... 可选选项 作者的信息 老版本有 新版本换成了 LABEL
LABEL maintainer='teo <teo@teo.com>' // label 标签... 新版本中
COPY index.html /data/web/html/ // copy 复制命令... 把本地 index.html文件 复制到 容器的 /data/web/html/ 目录下
COPY /data /data/web/ // 容器中目录必须以 / 结尾 本地不需要 把本地 /data下的所有文件 不包括data的目录
// ↑ 复制到 容器的/data/web/ web或data可以不存在 会自动创建
ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/ // add 添加... 1.add后如果是url则会自动下载添加到指定目录
WORKDIR /usr/local/ // workdir 工作目录... 在此 指定了工作目录 只对以后的命令生效 以后的 ./ 都是 /usr/local/
ADD nginx-1.18.0.tar.gz ./ // add 添加... 2.add后如果直接是本地压缩包 可以解压到指定目录 这里的 ./ 就是/usr/local/
// ↑ 就是 workdir指定的工作目录了
WORKDIR /data/ // workdir 可以有多个 从此往下命令的工作目录 为 /data/
VOLUME /data/mysql/ // volume 存储卷... 为镜像中/data/mysql/ 目录添加存储卷 只能为默认主机路径的存储卷
EXPOSE 80/tcp 65522/tcp // expose 暴露端口... 能有多个 默认为tcp 可以不用指/tcp 并不是真正意义上的暴露端口
// ↑ 只是该暴露的端口 还需在run 的时候指定
ENV DOC_ROOT /data/web/html/ // env 定义环境变量... 方法1 每一行只能指定一个环境变量 用 空格 隔开既可
// ↑ 后再在出现空格也视为变量的一部分
ENV a1="nginx-1.18.0" a2=bbb \ // env 定义环境变量... 方法2 一行可以定义多个 环境变量 使用等号连接 有空格需要反斜杠转义
a3=ccc // 此 反斜杠 是 连接下一行的作用 a3 与a2 为同一行
RUN cd /usr/local/ && \ // run 运行... 在 dockfile 创建镜像的过程中使用命令
// ↑ && and 前面的命令成功执行后面的命令行后面的命令 反斜杠是连接下一行的作用
tar xf nginx-1.18.0.tar.gz // 解压 这些运行的命令是基于 基础镜像的 如果基础镜像没有 则不能使用此命令
CMD /bin/httpd -f -h /data/web/ // CMD 启动运行... 制作完镜像 启动镜像时的默认命令 可以定义多个cmd 但只最后一个生效
ENTRYPOINT /bin/httpd -f -h $DIR // entrypoint 启动运行... 和cmd基本功能类似 但是 使用它定义的命令 不允许被覆盖
// ↑会把命令行定义的命令 传递给它的后面 当做参数来处理
HEALTHCHECK --start-period=3s CMD wget -O -q http://${IP:-0.0.0.0}:80/ // healthcheck 健康状态检查...
// ↑ 使用 wget 命令去检查网站的存活状态
AGE aaa="baidu.com" // age 定义环境变量... 同 env 差不多 AGE可以在命令行使用 --build-arg aaa="teo.com" 可替换AGE中的变量
ONBUILD ADD http://www.baidu.com/a.mp4 /usr/local/ // onbuild 后门运行... 在基于此镜像 做其他镜像的时候 执行 此命令
// ↑ 如 下载文件到 指定目录
Dockerfile 各个参数 实例
①. 基于 busybox 制作镜像
# docker search busybox
# docker image pull busybox // 下载 基础镜像
# docker image ls
# cd /data/
②. 使用 copy 命令 复制 文件
# vim Dockerfile // Dockerfile 文件 文件名首字母要大写
# Description: test make image // 描述信息
FROM busybox:latest // 第一个非注释行 FROM 指定 基于哪一个镜像 什么版本 制作
MAINTAINER "teo <teo@teo.com>" // 可选 选项 作者的信息 老版本有 新版本换成了 LABEL
# LABEL maintainer='teo <teo@teo.com>' // 新版本中
#FROM busybox@fdsaldkfj
COPY index.html /data/web/html/ // 把本地 index.html文件 复制到 容器的 /data/web/html/ 目录下
# COPY /data /data/web/ // 容器中目录必须以 / 结尾 本地不需要 把本地 /data下的所有文件
// ↑ 不包括data的目录 复制到容器的/data/web/ web或data可以不存在 会自动创建
# vim index.html // 测试网页 需放在 Dockerfile同目录 或 子目录
<h1>Busybox httpd server. </h1>
# docker build -t teo1:v1 ./ // 在当前目录 制作镜像 -t 镜像的名字及标签 名字为teo1 标签v1
# docker image ls // 查看 已 制作的镜像 ↓ 相当于 传递cat命令 代替 原本的命令
# docker run --name t1 --rm teo1:v1 cat /data/web/html/index.html // 启动cat只是查看文件在此用于检测 执行之后 就退出
③. 使用 copy 命令 复制目录
# cp -a /etc/yum.repos.d ./ // COPY 命令 把目录 放到 容器中
# vim Dockerfile
# Description: test image
COPY yum.repos.d /etc/yum.repos.d/ // 复制目录 制作镜像 每一条指令都会多生成一个镜像层 尽量少写命令能合并最好合并
# docker build -t teo1:v2 ./
# docker image ls
# docker run --name t1 --rm teo1:v2 ls /etc/yum.repos.d // 运行镜像 ls仅为 测试使用
④. 使用add 命令 下载url文件放到镜像目录
# vim Dockerfile // 演示ADD 命令 ADD 和COPY基本相同都可以复制 但ADD可以复制url 及 tar的压缩文件
ADD http://nginx.org/download/nginx-1.18.0.tar.gz /usr/local/ // 下载url文件 放到镜像目录 /usr/local/ 中
# docker build -t teo1:v3 ./ // 创建镜像 ↑ 没有此路径会自动创建
# docker image ls
# docker run --name t1 --rm teo1:v3 ls /usr/local/ // 验证 此压缩包 不会被解压
nginx-1.18.0.tar.gz
⑤. 使用add 命令 把本地tar压缩文件 解压到镜像目录
使用workdir 命令 指定 工作目录
# vim Dockerfile
WORKDIR /usr/local/ // 在此 指定了工作目录 只对以后的命令生效 以后的 ./ 都是 /usr/local/
ADD nginx-1.18.0.tar.gz ./ // 这里的 ./ 就是/usr/local/ 就是 workdir指定的工作目录了
WORKDIR /data/ // workdir 可以有多个 从此往下命令的工作目录 为 /data/
# docker build -t teo1:v4 ./
# docker image ls
# docker run --name t1 --rm teo1:v4 ls /usr/local/nginx-1.18.0 // 里面会有 解压完的 文件
⑥. 使用 volume 命令 指定 存储卷 只能为 默认主机路径的存储卷
# vim Dockerfile
VOLUME /data/mysql/
# docker build -t teo1:v5 ./
# docker image ls
# docker run --name t1 --rm teo1:v5 sleep 60 // 睡 60 秒
# docker inspect t1 // 新开窗口 可以看到 存储卷的 信息
"Source": "/var/lib/docker/volumes/77243741ecef8377572526881b321a1503e08249d734b24729a54e108356bd03/_data",
"Destination": "/data/mysql",
⑦. 使用 expose 暴露端口 // 是动态绑定的 不能指定宿主机的指定地址与指定端口 动态绑定宿主机的随机端口
# vim Dockerfile
EXPOSE 80/tcp 65522/tcp // expose 暴露端口 能有多个 默认为tcp 可以不用指/tcp
# docker build -t teo1:v6 ./ // 创建镜像
# docker image ls
# docker run --name t1 --rm teo1:v6 /bin/httpd -f -h /data/web/html
teo1:v6 /bin/httpd // 运行 镜像的 /bin/httpd 程序 -f 前台运行 -h /data/web/html 主页目录 上面已经有创建
# docker inspect t1 // 新开窗口 可看到ip
# curl 172.17.0.2 // 可以访问
# docker port t1 // 查看 t1 容器是否有暴露端口 这里看不到有暴露端口
# docker kill t1 // 干掉 t1 容器
# docker run --name t1 --rm -P teo1:v6 /bin/httpd -f -h /data/web/html // -P 暴露所有该暴露的端口
# docker port t1 // 会有 两个端口暴露
65522/tcp -> 0.0.0.0:49153
80/tcp -> 0.0.0.0:49154
http://192.168.10.12:49154/ // 访问 宿主机 即可
⑧. 使用 env 定义dockfile中的环境变量
# vim Dockerfile
ENV DOC_ROOT /data/web/html/ // 方法1 每一行只能指定一个环境变量 用 空格 隔开既可 后再在出现空格也视为变量的一部分
COPY index.html $DOC_ROOT // 引用环境变量
COPY a.txt ${DOC_ROOT:-/data/web/html/} // 引用环境变量 -号为 如变量不存在使用 /data/web/html/ 路径
ENV a1="nginx-1.18.0" a2=bbb \ // 方法2 一行可以定义多个 环境变量 使用等号连接 有空格需要反斜杠转义
a3=ccc // 此 反斜杠 是 连接下一行的作用 a3 与a2 为同一行
ADD $a1.tar.gz /usr/local/
# docker build -t teo1:v7 ./ // 制作镜像
# docker run --name t1 --rm teo1:v7 ls /data/web/html // 验证
# docker run --name t1 --rm teo1:v7 printenv // 可以看到 刚刚定义的变量 也都在 环境变量中
# docker run --name t1 --rm -e a1=nginx-1.19.0 teo1:v7 printenv // -e 会 取代 Dockerfile文件中定义的 环境变量
a1=nginx-1.19.0
# docker run --name t1 --rm -e a1=nginx-1.19.0 teo1:v7 ls /usr/local
nginx-1.18.0 // 还是1.18.0说明 -e 不能改变Dockerfile文件中已经执行过的命令中定义的环境变量
⑨. 使用 run 命令 在 dockfile 创建镜像的过程中 使用命令
1 run的第一种运行模式 RUN <命令> 会自动以shell的子进程启动 <命令>为 shell的一个命令 默认会以/bin/sh -c 来运行
# vim Dockerfile // ↑ -c 会把后面所有的当做一个字符串来处理
RUN cd /usr/local/ && \ // && and 前面的命令成功执行后面的命令 反斜杠是连接下一行的作用
tar xf nginx-1.18.0.tar.gz // 解压 这些运行的命令是基于 基础镜像的 如果基础镜像没有 则不能使用此命令
# docker build -t teo1:v8 ./ // RUN 可以有多个 但是 建议要 都写到一条里面 像上面的格式一样
# docker run --name t1 --rm -e a1=nginx-1.19.0 teo1:v8 ls /usr/local // 可看到解压后的文件夹
⑩. 使用 CMD 命令 // CMD命令 是 指定 制作完镜像 启动镜像时的 默认命令 可以定义多个cmd 但是 只有最后一个生效
方式一: 直接定义命令 CMD /bin/httpd -f -h /data/web/ 默认以shell启动 可以使用变量等 shell 所支持的命令
# cd /data/image1/ // 新目录 与上面 没有关系
# vim Dockerfile
# Description: teo2 httpd
FROM busybox
LABEL name="teo2" app="httpd"
ENV DIR="/data/web/"
RUN mkdir -p $DIR && \
echo '<h1>Busybot httpd server on teo2222222.</h1>' > $DIR/index.html
CMD /bin/httpd -f -h $DIR // 此时 默认命令 变为 启动 httpd 程序
# docker build -t teo2:v1 ./
# docker image inspect teo2:v1 // 查看镜像的 信息
"Cmd": [
"/bin/sh", // 自动使用 /bin/sh -c 来启动 给出的命令
"-c",
"/bin/httpd -f -h $DIR"
],
# docker run --name t1 -it --rm -P teo2:v1 // -it 交互式 然没有进入交互式 而是cmd生效 启动httpd httpd并没有交互接口
# docker ps // 新开窗口
# docker exec -it t1 /bin/sh // 额外新开窗口 可以登录进来
# ps // 会有 httpd 的进程
方式二: 使用json数组的形式定义 CMD ["/bin/sh","-c","/bin/httpd","-f","-h /data/web/"] 不支持shell的命令及变量
# vim Dockerfile
# Description: teo2 httpd
FROM busybox
LABEL name="teo2" app="httpd"
ENV DIR="/data/web/"
RUN mkdir -p $DIR && \
echo '<h1>Busybot httpd server on teo2222222.</h1>' > $DIR/index.htm
CMD ["/bin/httpd","-f","-h $DIR"] // 以 json 格式 创建 CMD命令 此格式 并不会 使用shell启动
# docker build -t teo2:v2 ./
# docker image inspect teo2:v2
"Cmd": [
"/bin/httpd", // 并不会使用 shell 运行
"-f",
"-h $DIR" // 不是 shell 程序启动的 系统不识别 此变量
],
# docker run --name t1 -it --rm -P teo2:v2 // 会报错 不识别 变量$DIR
httpd: can't change directory to ' $DIR': No such file or directory
# vim Dockerfile
CMD ["/bin/sh","-c","/bin/httpd","-f","-h /data/web/"] // 仅仅 修改此项 改成绝对路径 不识别变量$DIR
# docker build -t teo2:v3 ./
# docker run --name t1 -it --rm -P teo2:v3
# docker image inspect teo2:v3
"Cmd": [
"/bin/sh",
"-c",
"/bin/httpd",
"-f",
"-h /data/web/"
],
# docker run --name t1 -it --rm -P teo2:v3 // 启动 然而并没有 启动成功 是由于/bin/sh -c id号 导致的。。。
# docker run --name t1 -it --rm -P teo2:v3 ls / // 在这里 使用ls 替换了覆盖了 cmd中的命令
⑪. 使用 entrypoint 命令 和cmd基本功能类似 但使用它定义的命令 不允许被覆盖 会把命令行定义的命令 传递给它的后面当做参数来处理
# vim Dockerfile
# Description: teo2 httpd
FROM busybox
LABEL name="teo2" app="httpd"
ENV DIR="/data/web/"
RUN mkdir -p $DIR && \
echo '<h1>Busybot httpd server on teo2222222.</h1>' > $DIR/index.html
ENTRYPOINT /bin/httpd -f -h $DIR
# docker run --name t1 --rm -it -P teo2:v4 // 可以正常运行
# docker kill t1
# docker run --name t1 --rm -it -P teo2:v4 ls / // ls命令 并没有替换到 entrypoint中的命令
// 会把 ls / 当做参数 补充到 /bin/httpd -f -h $DIR 这个命令后面 只不过 httpd不识别 ls 没理会它而已
# docker kill t1
# docker run --name t1 --rm -it -P --entrypoint 'ls' teo2:v4 // --entrypoint 强制替换 ENTRYPOINT 中定义的命令
方式三: 为 entrypoint命令 传递参数 // cmd 与 entrypoint 命令 在json数组中 中括号里里面 要 使用 双引号
⑫. healthcheck 健康状态检查 // 用的时候 在详细查看
# vim Dockerfile
HEALTHCHECK --start-period=3s CMD wget -O -q http://${IP:-0.0.0.0}:80/ // 使用 wget 命令去检查网站的存活状态
⑬. age 命令 同 env 差不多 AGE可以在命令行使用 --build-arg aaa="teo.com"
# vim vim Dockerfile
AGE aaa="baidu.com"
# docker build --build-arg aaa="teo.com" -t teo1:v1 ./ // 在创建镜像的时候 传递参数给 aaa 替换掉aaa原有的参数
⑭. onbuild 在基于此镜像 做其他镜像的时候 执行 此命令
# vim Dockerfile
ONBUILD ADD http://www.baidu.com/a.mp4 /usr/local/ // 如 下载文件到 指定目录
注:
①. 关于Docker pid=1 的程序
Docker 容器启动时,默认会把容器内部第一个进程,也就是pid=1的程序,作为docker容器是否正在运行的依据,
如果 docker 容器pid=1的进程挂了,那么docker容器便会直接退出。
②. 关于 nginx -g daemon off 关闭 nginx 后台运行
nginx默认是以后台模式启动的,Docker未执行自定义的CMD之前,nginx的pid是1,执行到CMD之后,nginx就在后台运行,
bash或sh脚本的pid变成了1。所以一旦执行完自定义CMD,nginx容器也就退出了。为了保持nginx的容器不退出,应该关闭nginx后台运行
........................................................................................................................
❹. 关于 Docker 仓库
1. 使用 Harbor 在官方提供 docker-registry 基础上 开发的 开源项目 有web界面
# tar zxvf harbor-offline-installer-v2.1.3.tgz -C /usr/local/ // 二进制包 下载地址 看注释
# cd /usr/local/harbor/
# cp harbor.yml.tmpl harbor.yml
# vim harbor.yml // 安装配置文件
hostname: 192.168.10.13
harbor_admin_password: Harbor12345
location: /var/log/harbor
password: root123 // 关于mysql 会自动运行mysql容器 密码是root123
#https: // 如果不使用https 可以注释掉这些选项
# port: 443
# certificate: /your/certificate/path
# private_key: /your/private/key/path
# yum install epel*
# yum install docker-compose // 需要1.18以上的版本 在epel源中有
# ./install.sh // 运行安装脚本
# ss -tnl // 80 被监听
# vim /lib/systemd/system/harbor.service // 添加开机启动
[Unit]
Description=Harbor
After=docker.service systemd-networkd.service systemd-resolved.service
Requires=docker.service
Documentation=http://github.com/vmware/harbor
[Service]
Type=simple
Restart=on-failure
RestartSec=5
ExecStart=/usr/bin/docker-compose -f /usr/local/harbor/docker-compose.yml up
ExecStop=/usr/bin/docker-compose -f /usr/local/harbor/docker-compose.yml down
[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
# systemctl restart docker // 确保 docerk 是启动状态
# systemctl start harbor // harbor启动不了 一般是防火墙 docker会自动生成防火墙规则 如更改了防火墙 需要重启docker
# cd /usr/local/harbor // 要在此目录 才能执行
# docker-compose start // 启动 注意 要进入目录执行 如启动不了可以使用有错误提示
# docker-compose stop // 停止
# docker-compose pause // 暂停
# docker-compose unpause // 继续
# /usr/bin/docker-compose -f /usr/local/harbor/docker-compose.yml up // 如不进入目录 要加配置文件执行启动
# http://192.168.10.13/
admin
Harbor12345
用户管理 --> 创建用户
用户名 teo
密 码 teo@1234
仓库管理 --> 新建目标
提供者 Harbor
目标名 myproject
目标URL http://192.168.10.13/
访问ID teo // 上创建的 用户名和密码
访问密码 Teo@1234
推送镜像到服务器
# vim /etc/docker/daemon.json // 在其他机器上 推送 测试
{
"insecure-registries": ["192.168.10.13"] // 添加 非https认证地址 如果是https不用此项 如果非80端 需加端口
}
# systemctl restart docker
# docker images // 查看 镜像
# docker tag nginx1:v1 192.168.10.13/test1/nginx1:v1 // 为镜像 打标签 服务器地址/仓库名字/镜像名:版本号
# docker tag nginx1:v2 192.168.10.13/test1/nginx1:v2
# docker login 192.168.10.13 // 登录服务器
teo
Teo@1234
# docker push 192.168.10.13/test1/nginx1:v1 // 推送镜像 可以在浏览器中看到
# docker push 192.168.10.13/test1/nginx1:v2 // 拉取镜像 可以在网页上 查看 拉取的按钮
注: harbor 下载地址
git网址: https://github.com/goharbor/harbor
https://github.com/goharbor/harbor/releases // 可以下载 二进制版本
harbor-offline-installer-v2.1.3.tgz // 二进制包
2. 使用 Docker 自带的 私有仓库功能创建 私有仓库 docker registry 私有仓库
官网下载网址: https://hub.docker.com/_/registry/
# yum install docker-registry
# rpm -ql docker-distribution // 其实包名是docker-distribution 额外封装的名字docker-registry
# vim /etc/docker-distribution/registry/config.yml // 主配置文件
version: 0.1
log:
fields:
service: registry
storage:
cache:
layerinfo: inmemory
filesystem:
rootdirectory: /var/lib/registry // 镜像仓库的目录
http:
addr: :5000 // 默认端口是5000 应该改成80或者443
# systemctl restart docker-distribution.service
# docker image ls // 客户端 把镜像 上传到仓库
# docker tag nginx1:v2 192.168.10.12:5000/nginx1:v2
# vim /etc/docker/daemon.json // 修改本机配置文件
{
"insecure-registries": ["192.168.10.12:5000"] // 启用不安全仓库 可以使用http协议
}
# systemctl restart docker
# docker push 192.168.10.12:5000/nginx1:v2 // 推到 自建仓库
# ls /var/lib/registry/docker/registry/v2/repositories // 生成镜像的地址
3. 使用Docker官方镜像仓库 建立个人仓库
a. 登录hub.docker.com 创建个人仓库
# docker info // 可以看到 镜像网址 登录信息等
# docker login -h
# docker login // 登录 9276529937 不指仓库地址 默认为hub.docker.com
# docker logout // 退出
# docker push 9276529937/teo:latest // 上传镜像 到个人仓库
b. 如果使用阿里云 作为个人仓库 需要注册阿里云账号 --> 搜 容器镜像服务器 --> 创建个人仓库
# docker login registry.cn-qingdao.aliyuncs.com // 里面会给地址及以下地址只是演示 此密码不是登录密码是设置的密码
# docker tag 809bfb775a7c registry.cn-qingdao.aliyuncs.com/teo/httpd:v01 // 打标签 服务器地址/用户名/仓库名:标签
# docker push registry.cn-qingdao.aliyuncs.com/teo/httpd:v01 // 关于密码 需要设置 Registry密码
........................................................................................................................
❺. 关于Docker网络
手动创建 两个名称空间的虚拟网卡 互相通信 // 把1个网卡 分成 两半 一个放在r1 一个放在r2
# ip netns help // 查看 ip netns 帮助
# ip netns add r1 // 添加 名称空间r1
# ip netns add r2
# ip netns list // 查看 名称空间
# ip netns exec r1 ifconfig -a // 在名称空间里执行命令 只能查看到lo网卡 -a查看所有网卡 此网卡为未激活状态
# ip link help
# ip link add name veth1.1 type veth peer name veth1.2 // 添加网卡 veth1.1 另一半名字peer name veth1.2
# ip link show // 可以看到 新添加的 veth1.1 与veth1.2
# ip link set dev veth1.2 netns r1 // 把 veth1.2 移到 名称空间r1中
# ip link show // 只能看到 veth1.1
# ip netns exec r1 ifconfig -a // 可以看到 veth1.2的网卡 -a查看所有网卡 此网卡为未激活状态
# ip netns exec r1 ip link set dev veth1.2 name eth0 // 把 名称空间r1中的网卡veth1.2改名为 eth0
# ip netns exec r1 ifconfig -a // 查看
# ifconfig veth1.1 10.1.0.1/24 up // 激活 veth1.1
# ifconfig
# ip netns exec r1 ifconfig eth0 10.1.0.2/24 up // 激活名称空间r1中的eth0网卡并配置ip地址
# ip netns exec r1 ifconfig
# ping 10.1.0.2
# ip link set dev veth1.1 netns r2 // 把veth1.1 移到 r2的名称空间
# ip netns exec r2 ifconfig -a
# ip netns exec r2 ifconfig veth1.1 10.1.0.3/24 up
# ip netns exec r2 ping 10.1.0.2
# docker run --name t1 -it --network none --rm busybox:latest
# ifconfig // 只有lo接口 不创建网络设备 封闭式容器
# docker run --name t1 -it --rm busybox:latest // 默认 为 桥接模式
# ifconfig // 默认网络 会有网卡 ↓ 不能通外网
# docker run --name t1 -it --network bridge --rm busybox:latest // 同上 一样 桥接模式 可以和当前主机及其他容器的通信
# ifconfig
# hostname
46c024b2e616 // 此为容器的主机名 默认为容器的ID 可用 # docker ps 查看
# docker run --name t1 -it --network bridge -h t1.teo.com --rm busybox:latest // -h 指明主机名为 t1.teo.com
# hostname
t1.teo.com
# cat /etc/hosts
172.17.0.2 t1.teo.com t1 // 对自己的解析
# cat /etc/resolv.conf
nameserver 192.168.10.254 // DNS为 主机的 DNS
# docker run --name t1 -it --network bridge -h t1.teo.com --dns 8.8.8.8 --rm busybox:latest
# cat /etc/resolv.conf // 指定 dns
# docker run --name t1 -it --network bridge -h t1.teo.com --dns 172.17.0.1 --dns-search ilinux.io --rm busybox:latest
# cat /etc/resolv.conf // 指定 搜索域
# docker run --name t1 -it --network bridge -h t1.teo.com --dns 172.17.0.1 --dns-search ilinux.io --add-host www.teo.com:1.1.1.1 --rm busybox:latest
# cat /etc/hosts // 加 host 解析
1.1.1.1 www.teo.com
映射端口
# docker run --name t1 --rm -p 80 nginx // 启动nginx镜像 -p 要映射出去的端口 默认为tcp端口 会随机使用主机的端口映射
# iptables -t nat -vnL // 查看 防火墙的 转发
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:8
# docker container port t1 // 查看容器端口的映射关系
80/tcp -> 0.0.0.0:49155 // 监听 所有ip的 49155端口上
# curl 192.168.10.12:49153 // 新开主机同一网段的 访问
# docker run --name t1 --rm -p 192.168.10.12::80 nginx // 虚拟机80端口 映射到 192.168.10.12的随机端口
# docker container port t1
80/tcp -> 192.168.10.12:49153 // 只监听在192.168.10.12 此ip上
# docker run --name t1 --rm -p 80:80 nginx // 不给地址 指的是 宿主机所有地址的80端口 映射 为虚拟机的80端口
# docker container port t1
80/tcp -> 0.0.0.0:80
# curl 192.168.10.12 // 可直接访问
联盟式容器 // 隔离文件 共享网络
# docker run --name b1 -it --rm busybox
# ifconfig
# mkdir /tmp/testdir
# ls /tmp/ // 会有刚创建的文件夹
# echo "hello aaaaaa" > /tmp/index.html // 创建测试页面
# httpd -h /tmp/ // 启动httpd
# netstat -tnl // 80端口被监听
# docker run --name b2 --network container:b1 -it --rm busybox // 新窗口 启动b2容器 网络基于 容器b1
# ifconfig // ↑ ip地址会和b1的一样 共享b1的名称空间
# ls /tmp/ // 没有 b1 上创建的文件夹 文件不共享
# wget -O- -q 127.0.0.1 // 可以访问到 b1创建的测试页面 网络可以共享 相当于curl功能 因为busybox没有curl
# docker run --name b2 --network host -it --rm busybox // 网络基于 宿主机 创建 ip地址会和 宿主机一样
# echo "hello container" > /tmp/index.html
# httpd -h /tmp/
# netstat -tnl
修改docker0 网段
# vim /etc/docker/daemon.json // 修改配置文件 最后一行不能加 ","结尾 其他行必须以 "," 结尾
{
"bip": "10.0.0.1/16"
}
# systemctl restart docker
修改docker TCP监听端口
dockerd 守护进程 默认仅监听Unix socker格式的地址 /var/run/docker.sock 如果使用TCP套接字
# vim /usr/lib/systemd/system/docker.service // 修改启动文件
ExecStart=/usr/bin/dockerd
# systemctl daemon-reload
# systemctl reset-failed docker.service
# systemctl restart docker
# vim /etc/docker/daemon.json
"bip": "10.0.0.1/16",
"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
# ss -tnl // 2375端口被监听
# docker -H 192.168.10.12:2375 image ls // 其他机器 远程 连接 执行命令
创建 桥
# docker network --help // docker network 命令的参数选项
# docker network create --help // docker network create 命令的参数选项
# docker network create --driver bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" mybr0
# docker network ls
# ifconfig // 会多了网卡br-53edc22a792a
# docker run --name t2 -it --network mybr0 busybox:latest // 基于新建的网络 创建容器
# ifconfig // mybr0 同一网段
# docker run --name t3 -it --network bridge busybox:latest
// t2 t3基于两个网卡创建的容器 只要宿主机开启核心转发 就可以通信 不能通信的原因是防火墙默认生成阻断的规则 需修改规则
Docker 网络其他命令
# yum install bridge-utils // 网络查看工具 查看桥接工具
# brctl show // 可看到 docker0上 桥接的网卡
# iptables -t nat -vnL // 会看到 原地址 172.17.0.0 不是从 docker0出去的 都做 MASQUERADE地址伪装
Chain POSTROUTING (policy ACCEPT 222 packets, 21512 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
注:
①. 使用docker 需要首先开启 地址转发功能
# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
# sysctl -p
②. 报错 docker: Error response from daemon: driver failed programming external connectivity on endpoint
运行 # docker run --name t1 --rm -p 80 nginx 有时会报错 是由于docker启动时定义的自定义链DOCKER由于某种原因被清掉
# systemctl restart docker // 重启docker服务及可重新生成自定义链DOCKER 即可解决
........................................................................................................................
❻. 关于 Docker 存储
volume 存储卷 // 分两种 一种为 在主机的默认路径 另一种为 执行主机的目录
1. 创建卷 主机的默认路径
# docker run --name t1 -it -v /data busybox // -v 创建 卷 目录为 容器的 /data 目录 删除容器 在主机上的目录也不会没
# docker inspect t1 // 查看 容器的详细信息
"Mounts": [ // ↓ 此路径为 主机的 物理路径
"Source": "/var/lib/docker/volumes/20a53875f16cf53b77dd8325e239168850925ddde02977f686399272e5860d02/_data",
"Destination": "/data", // 此为 容器的路径 关联了 上面的物理路径
2. 创建卷 主机的指定路径
# docker run --name t2 -it --rm -v /data/b2:/data busybox // 创建卷 把主机的 /data/b2 目录 关联到 容器的 /data
# docker inspect t2
"Mounts": [
"Source": "/data/b2", // 主机的路径 没有此路径 会自动创建 删除容器 在主机上的目录也不会没
"Destination": "/data", // 容器的路径
注: inspect 格式详解
# docker inspect t2 // go模板的格式 可以使用模板的方式来过滤信息
[ // 中括号为 列表
{ // 大括号为 映射 哈希 关联数组 json数组
"Id": "....." // 键 键值
"State": { // 内部的嵌套 其中值为 另一个 json数组 json文档 上一级 为 根
"Status": "running", // 二级键 为 State.Status 键值为 running 上一级为 State
}
}
]
# docker inspect -f {{.Mounts}} t2 // 调用 数值
3. 两个容器 共享 同一个存储卷
# docker run --name t1 -it --rm -v /data1:/data1 busybox
# docker run --name t2 -it --rm -v /data1:/data1 busybox // 和 t1 一样的 目录
基础支撑的容器 infracon
# docker run --name d1 -it -v /data/:/data/ busybox // 基础容器 可以不启动 存在就可以 -it 只是为了看效果
# docker container ls -a // --volumes-from 复制d1 容器的 卷
# docker run --name nginx --network container:d1 --volumes-from d1 -it busybox // 复制基础容器的卷 网络空间
........................................................................................................................
❼. 关于 Docker 系统限制
docker 默认 没有限制内存 和 cpu
内存
物理内存 和 交换内存
-m 可用物理内存的大小 // 可单独使用
--memory-swap * 可用交换分区的大小 // 不可单独使用 一定要先设置物理内存的使用大小 才能使用此项设置交换分区的使用大小
关于交换分区的设置 --memory-sqap=S --memory=M S一定要大于M
1. 容器可用内存总空间为S 其中 物理内存为 M 交换分区为S-M 若S=M则无可用交换分区资源
2. 如果--memory-swap=0 相当于未设置交换分区 未设置交换分区:如果宿主机启用了交换分区 则容器可用交换分区为 2*M
3. 如果--memory-swap=-1 如果宿主机启用了交换分区 则容器可用所有宿主机的交换分区
4. 在容器中 使用free命令 可以看到的交换空间并不具有其所展现出的空间的意义 就是 不准
--memory-swappiness 使用交换分区的倾向性 0-100 0为能不用就不用 100为能用就用
CPU
--cpu--shares= cpu资源共享 按比例切分当前系统上所有的cpu资源
--cpus= 分配多少核心
--cpuset-cpu= 指定使用哪些核心
--cpu-period= 限制多长时间
使用压力测试工具 限制内存 CPU // https://hub.docker.com/r/lorel/docker-stress-ng
# docker pull lorel/docker-stress-ng:latest // 容器压力测试工具
# docker run --name t1 --rm -m 128m lorel/docker-stress-ng stress --vm 2 // --vm 2 对内存做压力测试启动2个进程
-m 128m 给容器最多128m内存 // ↑ 默认每个进程最大内存256m
--oom-kill-disable // 无论使用多少内存都不会被kill掉
--oom-score-adj 0 // -1000 - 1000 取值 越小 越不容易被kill掉
# docker top t1 // 可以看到 内存的使用情况 新开窗口
# docker stats // 可以看到 cpu 使用情况
# docker run --name t1 --rm --cpus 2 lorel/docker-stress-ng stress --vm 8
--rm --cpus 2 限制cpu的核心数
# docker run --name t1 --rm --cpuset-cpus 0,2 lorel/docker-stress-ng stress --vm 4
--cpuset-cpus 0,2 限制cpu只能用0和2号的cpu
# docker run --name t1 --rm --cpu-shares 1024 lorel/docker-stress-ng stress --vm 4
--cpu-shares 1024 给cpu基础的 1份 相当于没有限制cpu
# docker run --name t2 --rm --cpu-shares 512 lorel/docker-stress-ng stress --vm 4 // 相当于上面 2:1 的分配方式
........................................................................................................................
❽. 其他的一些关于Docker 的镜像制作
使用 commit 制作镜像
使用 busybox里的httpd 制作 web服务器
# docker run -d -it --name t1 busybox /bin/sh
# docker container exec -it t1 /bin/sh
# mkdir -p /data/html
# cd /data/html
# echo "the server is busybox server..." > index.html
①.基于在运行的容器 制作镜像 未指定 任何信息
# docker container commit -p b1 // 新开窗口 制作镜像
# docker image ls // 会看到 自建的镜像 仓库为空 标签为空
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 809bfb775a7c About a minute ago 1.24MB
# docker image tag 809bfb775a7c teo/httpd:v01 // 基于id创建仓库及标签 仓库为teo/httpd 标签为v01
# docker image tag teo/httpd:v01 teo/httpd:v0.11 // 在打一个标签
# docker image ls // 这两个 id会一样
REPOSITORY TAG IMAGE ID CREATED SIZE
teo/httpd v0.11 809bfb775a7c 10 minutes ago 1.24MB
teo/httpd v01 809bfb775a7c 10 minutes ago 1.24MB
# docker image rm teo/httpd:v01 // 删除 其中一个标签
# docker image ls
# docker run --name t1 -it teo/httpd:v0.11 // 运行 自建的镜像
cat /data/html/index.html // 刚刚写入的 网页文件
②.基于在运行的容器 制作镜像 指定信息
# docker commit -a "teo" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p b1 teo/httpd:v0.2
-a 指定作者等信息
-c 修改原有的启动命令
/bin/httpd 要执行的命令
-f 在容器的前台执行命令 此为 httpd的选项
-h 指明 网页路径
执行的目
-p 制作时暂停容器
基于 b1 镜像 制作 仓库名:标签
# docker image ls
# docker run -d --name t2 -p 80:80 teo/httpd:v0.2 // 启动
# docker container ls
# curl 192.168.10.11
# docker inspect t2 // 如果不映射 查看docker内部ip
# curl 172.17.0.5 // 测试访问
Dockerfile 制作 Nginx 镜像 基于 nginx:stable-alpine 镜像 制作 需要的nginx镜像
# cd /data/image2/ // 新目录 与上面的没有关系
# docker pull nginx:stable-alpine // 下载 nginx alpine版 镜像
# docker run --name n1 -it nginx:stable-alpine /bin/sh // 可以运行nginx 先看一下 里面有什么目录
# which nginx // nginx 位置
/usr/sbin/nginx
# ls /etc/nginx/ // nginx 配置文件路径
# docker container ls -a
# docker container rm n1
# vim Dockerfile // 创建 Dockerfile
FROM nginx:stable-alpine
LABEL maintainer="teo <teo@teo.com>"
ENV NGX_DOC_ROOT='/data/web/html/'
ADD index.html ${NGX_DOC_ROOT} // 拷贝 主页 文件
ADD entrypoint.sh /bin/ // 把自定义的脚本 拷贝到 镜像里面
CMD ["/usr/sbin/nginx","-g","daemon off;"] // 在此 cmd 为 entrypoint的参数 详情看 注1 注2
ENTRYPOINT ["/bin/entrypoint.sh"] // 制作完镜像 启动镜像时的 执行 自定义脚本
# vim entrypoint.sh // 创建自定义脚本 初始化一个自定义的nginx 配置文件
#!/bin/sh
#
cat > /etc/nginx/conf.d/www.conf << EOF
server
{
server_name $HOSTNAME;
listen ${IP:-0.0.0.0}:${PORT:-80};
root ${NGX_DOC_ROOT:-/data/};
}
EOF
exec "$@" // exec替代shell进程 容器里面只有/usr/sbing/nginx 唯一的一个进程 $@调用所有参数 执行cmd 传递来的参数
# vim index.html // 创建 自定义的主页文件
aaaaaaaaaaaaaaaaaaa
# docker image build -t nginx1:v1 ./ // 制作镜像
# docker container run --name t1 --rm -P nginx1:v1 // 启动
# docker exec -it t1 /bin/sh // 新开窗口 连接到里面
/ # cat /etc/nginx/conf.d/www.conf // 自定义配置文件
server_name 4e30edd91e4c;
listen 0.0.0.0:80;
root /data/web/html/;
/ # netstat -tnl // 80端口被监听
/ # wget -O - -q localhost // 相当于 curl 命令 依然是默认的页面
/ # wget -O - -q 4e30edd91e4c // 主机名访问 可以访问到 自定义的页面
# docker kill t1 // 干掉
# docker run --name t1 --rm -P -e "PORT=8080" nginx1:v1 // -e 设置环境变量 会 取代 Dockerfile文件中定义的 环境变量
# docker exec -it t1 /bin/sh
/ # netstat -tnl // 8080 被监听
Dockerfile 部署 nginx 镜像
# docker search nginx // 老的网址 需要写进镜像的 可以用此配置
# docker pull nginx:latest
# cd /data
# rz nginx.conf // 主配置文件 写进镜像
# rz www.tar.gz // 网页文件目录 写进镜像
# rz vhost.tar.gz // 配置文件目录 写进镜像
# rz live.tar.gz // SSL证书目录 写进镜像
# vim Dockerfile
# nginx 1.19.6
FROM nginx:latest
LABEL maintainer="teo <teo@teo.com>"
ADD nginx.conf /etc/nginx/ // 可以替换掉原有的配置文件
ADD www.tar.gz /data/
ADD vhost.tar.gz /etc/nginx/
ADD live.tar.gz /etc/letsencrypt/
# docker build -t nginx:v1 ./ // 制作镜像
# docker image ls
# docker run --name t1 -d nginx:v1
# docker cp t1:/etc/nginx/ /etc/
# docker cp t1:/data/www /data/
# docker cp t1:/var/log/nginx /var/log
# docker rm -f t1
# docker run -d --name t1 -p 80:80 -p 443:443 -v /data/www/:/data/www/ -v /etc/nginx/:/etc/nginx/ -v /var/log/nginx:/var/log/nginx -v /etc/letsencrypt/live/:/etc/letsencrypt/live/ nginx:v1
# docker inspect t1 // 查看正常 运行的容器的配置
"Mounts": [ // 主要查看 Mounts 目录 映射关系
],
目前为止有一条评论