Dockerfile命令.
Dockerfile命令
FROM
!!! note 基本信息
- 用途
- 所有的镜像都通过基础镜像而来,该语句指定基础镜像是谁,基于什么镜像来做。
- 格式
-
FROM [--platform=<platform>] <image> [AS <name>]
-
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
-
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
-
--platform
指定镜像的平台,比如:linux/amd64
,linux/arm64
, orwindows/amd64
-
tag
和digest
是可选项,如果不指定,默认为latest
!!!
-
!!! tip 常见用法
-
完全自建镜像,需要空镜像
FROM scratchscratch是一切镜像的起源,它本身无具体的操作系统,可以理解为一个占位符
它本质上是一个 0 字节的镜像
对于静态编译中,多阶段编译有奇效# 使用 golang 基础镜像进行构建 FROM golang:1.16 AS builder # 设置工作目录 WORKDIR /app # 复制 Go 项目文件到容器中 COPY . . # 静态编译 Go 程序 RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp . # 使用 scratch 空白镜像作为最终镜像 FROM scratch # 从构建阶段复制编译好的可执行文件到最终镜像 COPY --from=builder /app/myapp / # 定义容器启动时执行的命令 CMD ["/myapp"]
-
从精简操作系统的基础下构建
FROM busybox / FROM alpine精简操作系统一般在
10M
之内,这些系统具备最基础的功能能够胜任一般的错误排查
不至于如空白镜像,需要自行对工具进行选型、依赖解决等、可以较好地完成部署任务
是一个性价比极高的基础镜像 -
从完整操作系统镜像下构建
FROM ubuntu / FROM Rockylinux这些一般为主流操作系统,用户最为熟悉,拥有的系统工具丰富,对于故障和配置排查提供了基础
一般具备主流的bash,而不是精简系统的sh
大小一般在100M
到500M
之间 -
从应用镜像构建
FROM redis / FROM jenkins这类镜像已经是完整的应用,其空间大小与应用和其选择的系统基座相关
从这一类镜像进行构建,一般是为了实现告警的自定义功能或精简配置
!!!
!!! warning 注意事项
- 应尽量选择体积小的镜像构建,有助于提升性能和资源的使用比
!!!
LABEL
!!! note 基本信息
- 用途
- 指定元数据,用于标识系统地址、用户、帐号、维护者等公开信息
- 格式
- LABEL <key>=<value> <key>=<value> <key>=<value> ...
!!!
- LABEL <key>=<value> <key>=<value> <key>=<value> ...
!!! tip 常见用法
- 维护者信息
LABEL maintainer="alfiecheung <root@alfiecheung.com>"
!!!
!!! warning 注意事项
无
!!!
RUN
!!! note 基本信息
- 用途
- 用来在
构建镜像
阶段需要执行 FROM 指定镜像所支持的Shell命令
- 用来在
- 格式
#shell 格式: 相当于 /bin/sh -c <命令> 此种形式支持环境变量 RUN <命令> #exec 格式: 此种形式不支持环境变量,注意:是双引号,不能是单引号 RUN ["executable","param1","param2"...] #exec格式可以指定其它shell RUN ["/bin/bash","-c","echo hello wang"]
!!!
!!! tip 常见用法
# 多个命令通过 && 操作符联合,为的是减少构建时的层数
RUN yum -y install epel-release \
&& yum -y install nginx \
&& rm -rf /usr/share/nginx/html/*
&& echo "<h1> docker test nginx </h1>" > /usr/share/nginx/html/index.html
!!!
!!! warning 注意事项
-
shell格式命令,默认使用
/bin/sh
去解析,具有较多的限制性 -
exec格式命令,可通过修改
第一个变量
为所需的shell
进行命令那个解析 -
命令执行没有上下文,如下执行是错误的
#world.txt并不存放在/app内
RUN cd /app
RUN echo "hello" > world.txt
# 应修改为
RUN echo "hello" > /app/world.txt
!!!
ENV
!!! note 基本信息
- 用途
- 环境变量的设置
- 格式
#变量赋值格式1 #此格式只能对一个key赋值,<key>之后的所有内容均会被视作其<value>的组成部分 ENV <key> <value> #变量赋值格式2 #此格式可以支持多个key赋值,定义多个变量建议使用,减少镜像层 ENV <key1>=<value1> <key2>=<value2>
!!!
!!! tip 常见用法
-
配置应用程序参数
ENV DATABASE_HOST=localhost ENV DATABASE_PORT=5432 ENV API_KEY=abc123
-
指定工作目录
ENV APP_HOME=/app WORKDIR $APP_HOME
-
设置语言环境
ENV LANG=en_US.UTF-8 ENV LC_ALL=en_US.UTF-8
-
传递构建参数
ARG VERSION ENV APP_VERSION=$VERSION
!!!
!!! warning 注意事项
- ENV 可以定义环境变量和值
- 能被后续指令(如:ENV,ADD,COPY,RUN等)通过$KEY或${KEY}
进行引用
,并在容器运行时保持
FROM rockylinux:9.3 LABEL maintainer="alfiecheung <root@alfiecheung.com>" ENV name="leslie" age=20 RUN echo "${name}:${age}" > /tmp/test.txt # 通过运行容器,查看 /tmp/test.txt # docker run --rm rocky:env-test2 cat /tmp/test.txt # leslie:20
!!!
COPY
!!! note 基本信息
- 用途
- 本地宿主机与容器之间文件的互相复制
- 格式
COPY [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] #路径中有空白字符时,建议使用此格式
!!!
!!! tip 常见用法
-
复制单个文件:
COPY source.txt /app/destination.txt
将主机上的
source.txt
文件复制到容器中的/app/destination.txt
。 -
复制整个目录:
COPY source_directory /app/destination_directory
将主机上的
source_directory
目录及其所有内容递归地复制到容器中的/app/destination_directory
。 -
复制多个文件:
COPY file1.txt file2.txt /app/
将主机上的
file1.txt
和file2.txt
文件复制到容器中的/app/
目录。 -
使用通配符复制多个文件:
COPY *.txt /app/
将主机上所有以
.txt
结尾的文件复制到容器中的/app/
目录。 -
复制远程文件:
COPY https://example.com/file.txt /app/
从远程 URL 下载文件
file.txt
并复制到容器中的/app/
目录。 -
复制文件并更改权限:
COPY --chown=user:group source.txt /app/destination.txt
将主机上的
source.txt
文件复制到容器中的/app/destination.txt
,并将文件的所有者设置为user
,组设置为group
。 -
复制文件到特定构建阶段:
FROM builder as build COPY source.txt /app/destination.txt
在多阶段构建中,将
source.txt
文件从builder
阶段复制到build
阶段的容器中。
!!!
!!! warning 注意事项
源文件路径
- COPY 命令的第一个参数是源文件或目录的路径。
- 在指定路径时,可以是相对于
Dockerfile
所在目录的相对路径,也可以是一个绝对路径
。
目标路径
- COPY 命令的第二个参数是目标路径,表示要将源文件或目录复制到容器中的位置。
- 这个路径可以是容器内的绝对路径,也可以是相对于容器工作目录的路径。如果目标路径不存在,则会
自动创建
。
目录复制
- 如果源路径是一个目录,COPY 命令将
递归地复制该目录及其所有内容
,但不复制目录自身
。 - 目标路径必须是一个已存在的目录,或者在构建过程中已经创建。
- 如果源路径是一个目录,COPY 命令将
文件权限
- 使用 COPY 命令复制文件时,文件的
权限将保持不变
。 - 如果需要更改文件的权限,可以
使用 RUN 命令在 Dockerfile 中进行相应的权限
更改操作。
- 使用 COPY 命令复制文件时,文件的
使用通配符
- COPY 命令支持使用通配符来复制多个文件。
- 例如,
COPY *.txt /app/
将复制所有以.txt
结尾的文件到容器的/app/
目录。
多个复制操作
- 可以在 Dockerfile 中使用多个 COPY 命令来复制不同的文件或目录到容器中。
- 这些复制操作将按照在 Dockerfile 中的顺序依次执行。
文件排除
- 可以使用
.dockerignore
文件来排除不需要复制到镜像中的文件和目录。 .dockerignore
文件的格式类似于 .gitignore 文件,可以通过添加规则来过滤文件和目录。
- 可以使用
!!!
ADD
!!! note 基本信息
- 用途
- 支持将压缩文件进行复制解压
- 格式
ADD [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
!!!
!!! warning 注意事项
- 如果是一个
URL
,下载后的文件权限自动设置为600
- 如果是一个本地文件系统上的打包文件,如: gz, bz2 ,xz ,它将被解包 ,其行为类似于"tar -x"命令, 但是
通过URL获取到的tar文件
将不会自动展开
!!!
CMD
!!! note 基本信息
- 用途
- 设置容器启动时要执行的
默认命令
- 设置容器启动时要执行的
- 格式
# 使用 exec 执行,推荐方式,第一个参数必须是命令的全路径,此种形式不支持环境变量 CMD ["executable","param1","param2"] # 在 /bin/sh 中执行,提供给需要交互的应用;此种形式支持环境变量 CMD command param1 param2 # 提供给 ENTRYPOINT 命令的默认参数 CMD ["param1","param2"]
!!!
!!! tip 常见用法
-
执行单个命令:
CMD echo "Hello, Docker!"
在容器启动时执行
echo "Hello, Docker!"
命令。 -
执行可执行文件:
CMD ./myapp
在容器启动时执行名为
myapp
的可执行文件。 -
指定命令和参数:
CMD ["python", "app.py"]
在容器启动时执行
python app.py
命令。 -
使用 Shell 执行命令:
CMD bash -c "echo Welcome; echo to Docker"
在容器启动时使用 Shell 执行复杂的命令或命令序列。
-
覆盖 CMD:
在运行容器时,可以使用docker run
命令的参数来覆盖CMD
命令。例如:docker run myimage echo "Hello, World!"
这将在容器运行时覆盖默认的
CMD
命令,并执行echo "Hello, World!"
。 -
作为ENTRYPOINT的参数:
ENTRYPOINT ["echo", "Hello,"] CMD ["Docker!"]
!!!
!!! warning 注意事项
- 作为默认执行命令
dockerfile
里面没有ENTRYPOINT命令
且docker run
没有指定执行命令时
- 最有最后一条生效
- 如果在
dockerfile
中添加多个CMD
命令,后添加的CMD
命令将覆盖前面添加的
- 如果在
- 可以被替换
docker run
运行容器的过程中,可以指定需要执行的命令
,这个命令将替代dockerfile CMD
命令
!!!
ENTRYPOINT
!!! note 基本信息
- 用途
- 用于指定在容器启动时要
执行的可执行命令或脚本
。
- 用于指定在容器启动时要
- 格式
# 使用 exec 执行 ENTRYPOINT ["executable", "param1", "param2"...] # shell中执行 ENTRYPOINT command param1 param2
!!!
!!! tip 常见用法
-
运行环境配置
FROM rockylinux:9.3 LABEL maintainer="alfiecheung <root@alfiecheung.com>" RUN sed -e 's|^mirrorlist=|#mirrorlist=|g' \ -e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \ -i.bak /etc/yum.repos.d/rocky-*.repo RUN dnf install -y nginx && rm -rf /var/cache/dnf/* COPY entry.sh /tmp RUN chmod a+x /tmp/entry.sh ENTRYPOINT ["/tmp/entry.sh"] CMD ["nginx", "-g", "daemon off;"]
#!/bin/sh # 创建nginx配置文件 # 变量可以使用默认变量值(即 :- 后的内容) # 或通过 ENV / docker run -e 提供变量内容进行覆盖 cat > /etc/nginx/conf.d/custome.conf <<EOF server { server_name ${HOSTNAME:-"wwww.alopex.com"}; listen ${IP:-"0.0.0.0"}:${PORT:-8080}; root ${DOC_ROOT:-"/usr/share/nginx/html"}; } EOF # 创建目录 mkdir -p ${DOC_ROOT:-/usr/share/nginx/html} # 自定义主页 echo ${HOSTNAME:-"www.alopex.com"} > ${DOC_ROOT:-/usr/share/nginx/html}/index.html # 通过exec接受CMD“参数”/ docker run “命令” # 由于exec 内建命令可替换当前shell,因此首命令可由用户指定需要执行的命令,而不仅仅只是参数传递 # 提高了脚本的灵活性,是一个约定成俗的操作 exec "$@"
# 创建镜像 docker build -t rocky-nginx:entry-v2 . # 启动容器 ## 自定义hostname和port变量,能够在配置中修改 docker run -d -e PORT=9090 \ -e HOSTNAME="www.leslie.com" \ -e DOC_ROOT="/tmp/cc" rocky-nginx:entry-v2 # 测试容器 curl ip.ip.ip.ip:9090
!!!
!!! warning 注意事项
- ENTRYPOINT接收docker run参数
docker run
提供的命令无法替换ENTRYPOINT
,相反该命令将作为参数传递给ENTRYPOINT
- 参数优先级
docker run
CMD
- 最有最后一条生效
- 如果在
dockerfile
中添加多个ENTRYPOINT
命令,后添加的ENTRYPOINT
命令将覆盖前面添加的
!!!
- 如果在
ARG
!!! note 基本信息
- 用途
- Build 阶段指定变量
- 格式
- ARG <name>[=<default value>]
!!!
- ARG <name>[=<default value>]
!!! tip 常见用法
- 与FROM结合,在构建时始终使用追新的images
ARG CODE_VERSION=latest FROM base:${CODE_VERSION}
!!!
!!! warning 注意事项
- 唯一可以放置在
FROM
命令前的指令 - ARG指令在build 阶段指定变量
- 和ENV不同的是,容器运行时并不存在ARG定义的环境变量
- 可以用 docker build --build-arg <参数名>=<值> 来覆盖
!!!
VOLUME
!!! note 基本信息
- 用途
- 创建匿名卷
- 容器删除后默认将删除容器内数据,匿名卷是数据持久话的一个实现手段
- 持久化可以使得容器在删除后,挂载的匿名卷目录将继续保留
- 更多详细内容 0x06 docker/存储管理
- 格式
VOLUME <容器内路径> VOLUME ["<容器内路径1>", "<容器内路径2>"...] 注意: <容器内路径>如果在容器内不存在,在创建容器时会自动创建 <容器内路径>如果是存在的,同时目录内有内容,将会把此目录的内容复制到宿主机的实际目录
!!!
!!! tip 常见用法
- 挂载两个匿名卷
- VOLUME [ "/data1","/data2" ]
!!!
- VOLUME [ "/data1","/data2" ]
!!! warning 注意事项
- 匿名卷默认路径
/var/lib/docker/volumes
- 数据存储目录
/var/lib/docker/volumes/<container-id>/_data
- 匿名卷创建宿主机和镜像都
不需要要事先存在真实目录
- 挂载的匿名卷目录将在容器内自动创建
- 匿名卷无有效名称虽然
可保留数据
但复用性不强
,容器删除后难以获取卷名称 (即数据保留的匿名卷)- 容器挂载卷名称获取:
docker inspect --format '{{range .Mounts}}{{.Name}}{{end}}' <container-id>
- 名称例子:
9bcb9d85be8480d83e31ba6f08ba08c5669220c424a6313b318b2850e24353ba
!!!
- 容器挂载卷名称获取:
EXPOSE
!!! note 基本信息
- 用途
- 用于启动容器时,端口暴露的标识
- 格式
EXPOSE <port>[/ <protocol>] [<port>[/ <protocol>] ..]
!!!
!!! tip 常见用法
- 暴露特定端口和协议
- EXPOSE 11211/udp 11211/tcp
!!!
- EXPOSE 11211/udp 11211/tcp
!!! warning 注意事项
- EXPOSE仅仅只是一个便捷标识,并不意味这容器就使用其暴露的端口
- EXPOSE主要是和
—P
临时端口映射配合使用,使用端口并非一定需要通过该语句暴露,也可以使用-p host-port:container-port
!!!
WORKDIR
!!! note 基本信息
- 用途
- 指定工作目录
- 为后续的
RUN, CMD, ENTRYPOINT
指令配置工作目录,当容器运行后,进入容器内WORKDIR指定的默认目录
- 格式
!!!
!!! tip 常见用法
- 指定当前的工作目录
- WORKDIR /path/to/workdir
!!!
- WORKDIR /path/to/workdir
!!! warning 注意事项
- 指定存在的
workdir
将会被自动创建 - 在RUN可以生效,在CMD、ENTRYPOINT可能会有问题
!!!
ONBUILD
!!! note 基本信息
- 用途
- 子镜像调用父镜像是执行的命令
- 格式
- ONBUILD [INSTRUCTION]
!!!
- ONBUILD [INSTRUCTION]
!!! tip 常见用法
- 通过该父镜像创建的子镜像都需要打上标签
- ONBUILD RUN echo "alopex copyright C" > /etc/parent-os
!!!
- ONBUILD RUN echo "alopex copyright C" > /etc/parent-os
!!! warning 注意事项
- ONBUILD不能自我能套,且不会触发FROM和MAINTAINER指令
- 推荐在标签中注明,例如
ruby:1.9-onbuild
- ONBUILD命令只能实现单次传递(直接继承的子代),不会持续传递(间接继承的子代)
!!!
USER
!!! note 基本信息
- 用途
- 指定默认的容器运行用户名称或UID
- 后续dockerfile中的 RUN ,CMD和ENTRYPOINT指令时使用此用户
- 格式
USER <user>[:<group>] USER <UID>[:<GID>]
!!!
!!! tip 常见用法
- 为数据库用户创建
musql
用户RUN groupadd -r mysql && useradd -r -g mysql mysql USER mysql
!!!
!!! warning 注意事项
!!!
HEALTHCHECK
!!! note 基本信息
- 用途
- 容器启动后的状态检测,确认容器是否按照预订要求运行
- 格式
HEALTHCHECK [选项] CMD <命令> #设置检查容器健康状况的命令,如果命令执行失败,则返回1,即 unhealthy HEALTHCHECK NONE #如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令 HEALTHCHECK 支持下列选项: --interval=<间隔> #两次健康检查的间隔,默认为 30 秒 --timeout=<时长> #健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒 --retries=<次数> #当连续失败指定次数后,则将容器状态视为 unhealthy,默认3次 --start-period=<FDURATION> #default: 0s #检查结果返回值: 0 #success the container is healthy and ready for use 1 #unhealthythe container is not working correctly 2 #reserveddo not use this exit code
!!!
!!! tip 常见用法
- 检测80请求是否正常
HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://127.0.0.1:90/
!!!
!!! warning 注意事项
- healthcheck 是认为设定检测规则,unhealthy表示检测状态异常但不代表容器服务不可用
- 对于启动时间较长的容器,建起增大
timeout
时间 - 容器检查会造成额外的内部资源消耗
!!!
.dockerignore 文件
!!! note 基本信息
- 用途
- 生成构建上下文时Docker客户端
忽略指定模式文件和文件夹
- 生成构建上下文时Docker客户端
- 格式
# #以#开头的行为注释 * #匹配任何非分隔符字符序列 ? #匹配任何单个非分隔符 \\ #表示 ** #匹配任意数量的目录(包括零)例如,**/*.go将排除在所有目录中以.go结尾的所有文件,包括构建上下文的根。 ! #表示取反,可用于排除例外情况
!!!
!!! tip 常见用法
#排除 test 目录下的所有文件
test/*
#排除 md 目录下的 xttblog.md 文件
md/xttblog.md
#排除 xttblog 目录下的所有 .md 的文件
xttblog/*.md
#排除以 xttblog 为前缀的文件和文件夹
xttblog?
#排除所有目录下的 .sql 文件夹
**/*.sql
!!!
!!! warning 注意事项
- 通过创建
.dockerignore
文件实现
!!!
Docker 网络模式
默认网络.
容器间通信
- 容器之间默认互联互通,使用参数
--icc=true
- 修改容器之间不互联互通
- 启动文件修改
/usr/lib/systemd/system/docker.service
ExecStart=usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --icc=false
systemctl daemon-reload && systemctl restart docker
- 配置文件修改
/etc/docker/daemon.json
{ "icc": false }
- 启动文件修改
自定义IP段
- 默认IP段:
172.17.0.1/16
- 查看默认网段
-
ip addr show docker0
-
docker network inspect <bridge-name>
-
- 修改方式
- 启动文件修改
/usr/lib/systemd/system/docker.service
ExecStart=usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=192.168.100.1/24
systemctl daemon-reload && systemctl restart docker
- 配置文件修改
/etc/docker/daemon.json
{ "bip": "192.168.100.1/24" }
- 启动文件修改
自定义网桥
- 默认网桥名称:
docker0
- 内容查看
brctl show
- 自定义网桥
# 自定义网桥 my-br0 brctl addbr my-br0 # 为网桥设定IP地址段 192.168.100.1/24 ip a a 192.168.100.1/24 dev my-br0
- 默认网桥修改
- 配置文件 ``
- 启动文件
/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -b my-br0
容器间互联
让数据库和wordpress两个容器实现互联
!!! info 互联方式
-
环境准备
mkdir -p /tmp/cc/lamp_docker/mysql mkdir -p /tmp/cc/{mysql,wordpress} cat > lamp_docker/env_mysql.list <<EOF MYSQL_ROOT_PASSWORD=alopex MYSQL_DATABASE=wordpress MYSQL_USER=wpuser MYSQL_PASSWORD=alopex EOF cat > lamp_docker/env_wordpress.list <<EOF WORDPRESS_DB_HOST=mysql:3306 # 此处 mysql为容器名称,将被接写为IP地址在(/etc/hosts中被定义) WORDPRESS_DB_NAME=wordpress WORDPRESS_DB_USER=wpuser WORDPRESS_DB_PASSWORD=alopex WORDPRESS_TABLE_PREFIX=wp_ EOF cat > lamp_docker/mysql/mysql_test.cnf <<EOF [mysqld] server-id=100 log-bin=mysql-bin EOF tree /tmp/cc/ /tmp/cc/ ├── lamp_docker │ ├── env_mysql.list │ ├── env_wordpress.list │ └── mysql │ └── mysql_test.cnf ├── mysql └── wordpress 3 directories, 3 files
-
名称互联
-
使用
--link
选项实现容器名称的引用 -
其本质为在容器内的/etc/hosts中添加
--link
后指定的容器的IP和主机名的对应关系,从而实现名称解析 -
格式
--link list #Add link to another container 格式: docker run --name <容器名称> #先创建指定名称的容器 docker run --link <目标通信的容器ID或容器名称> #再创建容器时引用上面容器的名称
-
例子
docker run --name mysql \ -d -p 3306:3306 \ -v /tmp/cc/mysql:/var/lib/mysql \ -v /tmp/cc/lamp_docker/mysql/:/etc/mysql/conf.d \ --env-file=/tmp/cc/lamp_docker/env_mysql.list \ mysql:8.0 # 前端容器使用名称互联连接到mysql, # 当前端需要访问mysql时,可通过其名称(mysql)访问,解决IP漂移问题 docker run --name wordpress \ -d -p 80:80 \ --link mysql \ -v /tmp/cc/wordpress:/var/www/html/wp-content \ --env-file=/tmp/cc/lamp_docker/env_wordpress.list \ wordpress:php7.4-apache
由于配置已经在容器阶段完成,因此登录页面填写好信息后,即会跳转到登录页面
-
-
别名互联
-
容器名称是自身的一个特性,容器可对其进行修改,因此具备不稳定性
-
客户容器如果需要调用容器,应该为其配置一个别名
-
这样可以保证
被引用容器
修改名称时,不影响调用容器
对被引容器名称的继续使用 -
格式
# 先创建指定名称的容器 docker run --name <容器名称> #给上面创建的容器起别名,来创建新容器 docker run --name <容器名称> --link <目标容器名称>:"<容器别名1> <容器别名2> ..."
-
实例
# 创建容器A,别名为 demo docker run -d --name demo rocky:demo tail -f /etc/hosts # 创建容器B,关联容器A的别名 (A的别名为 my-demo) docker run -d --name client --link demo:"my-demo" rocky:demo tail -f /etc/hosts # 查看容器B上的hosts docker exec client cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 my-demo 1330796cbbdc demo 172.17.0.3 474584380ed6 # 修改容器A的名称 为 new-demo docker rename demo new-demo # 容器B ping 容器A别名 my-demo 依然生效 docker exec -it client /bin/bash ping my-demo PING my-demo (172.17.0.2) 56(84) bytes of data. 64 bytes from my-demo (172.17.0.2): icmp_seq=1 ttl=64 time=0.160 ms 64 bytes from my-demo (172.17.0.2): icmp_seq=2 ttl=64 time=0.108 ms ...
-
!!!
网络连接模式.
- 模式语法
docker run --network <mode> docker run --net=<mode> <mode>: none bridge host container:<容器名或容器ID> <自定义网络名称>
Bridge (桥接模式)
!!! tip 场景说明
-
语法声明
- docker run --network= [docker0 | my-bridge] ...
-
工作方式
- 宿主机上创建默认的桥接器
docker0
,创建容器时将为容器
创建veth
并将该接口关联至桥接器上
- 宿主机上创建默认的桥接器
-
配置查看
-
本质
-
通过启用
ipforward
实现包在主机内转发- cat /proc/sys/net/ipv4/ip_forward
-
通过
iptables NAT chain
对docker0
网段IP进行SNAT
实现与外部网络通信 -
实例说明,
nginx
容器内开启80
端口,且使用宿主机49153
端口docker port dazzling_margulis 80/tcp -> 0.0.0.0:49153 80/tcp -> :::49153
# PREROUTING 的 NAT 表转发 # 目的地址是本机的数据包,都转发给 DOCKER 链处理 sudo iptables -t nat -nL PREROUTING Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL # DOCKER 链的内容 # RETURN 规则:对于不匹配任何其他规则的数据包,应该立即返回到调用链的上一级 # DNAT 规则: 对于匹配 tcp协议目的端口 49153 的流量,转发到 172.17.0.2 主机的 80 端口 sudo iptables -t nat -L DOCKER Chain DOCKER (2 references) target prot opt source destination RETURN all -- anywhere anywhere DNAT tcp -- anywhere anywhere tcp dpt:49153 to:172.17.0.2:80 # MASQUERADE 改写包来源 IP 为防火墙 网卡 IP # 功能与 SNAT 略有不同,当进行 IP 伪装时,不需指定要伪装成哪个 IP,IP 会从网卡直接读取 sudo iptables -t nat -nvL POSTROUTING | column -t | awk 'NR >1 {print}' pkts bytes target prot opt in out source destination 0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0 0 0 MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:80 # 查看路由表 # 对于172.17.0.0网段,通过docker0接口访问 route -n | column -t | awk 'NR >1 {print}' Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.16.102.254 0.0.0.0 UG 600 0 0 wlp5s0 169.254.0.0 0.0.0.0 255.255.0.0 U 1000 0 0 wlp5s0 172.16.102.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp5s0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
-
-
配置参数
{ "hosts": ["tcp://0.0.0.0:2375", "fd://"], "bip": "192.168.100.100/24", #分配docker0网卡的IP "fixed-cidr": "192.168.100.128/26", #分配容器IP范围,26不是容器IP的子网掩码,只表示地址范围 "fixed-cidr-v6": "2001:db8::/64", "mtu": 1500, "default-gateway": "192.168.100.200", #网关必须和bip在同一个网段 "default-gateway-v6": "2001:db8:abcd::89", "dns": [ "1.1.1.1", "8.8.8.8"] }
-
通信
- 内网 (默认可达)
- 容器间通信由网桥的
icc
参数决定"com.docker.network.bridge.enable_icc": "true"
- 宿主机与容器的联通性由
bridge
的路由决定
- 容器间通信由网桥的
- 外网 (默认可达)
- 外网的通信由
iptable 的 SNAT
规则决定
- 外网的通信由
- 内网 (默认可达)
-
特点
- 缺省
默认配置
: 容器默认自动获取172.17.0.0/16的IP地址,此地址可以修改 - 可
访问外网
: 利用宿主机的物理网卡,SNAT连接外网 - 外部主机无法直接访问容器: 可以通过
配置DNAT
接受外网的访问 - 低性能较低: 通过
NAT转换
有转换消耗 - 端口管理繁琐: 每个容器必须手动指定唯一的端口容器产生端口冲容
- 缺省
-
小结
Bridge (桥接)
是默认网络链接模式,可实现内网和外网的通信- 适用于希望
容器之间相互通信
,并且与外部网络隔离
的场景
!!!
Host (主机模式)
!!! tip 场景说明
- 语法声明
- docker run --network=host ...
- 工作方式
- 共享网络资源,访问主机地址即访问容器
- 配置查看
- 本质
- 与
宿主机
共享网络地址、端口等信息,即不对容器进行网络命名空间资源
进行隔离
- 与
- 通信
- 内网 (无)
- 外网
- 跨主机间通信,只要能与
宿主机
通信即可访问容器 宿主机
可访问外网的前提下,容器可访问外网
- 跨主机间通信,只要能与
- 特点
- 使用参数
--network host
指定 - 共享宿主机网络,各容器网络无隔离
- 网络性能无损耗
- 网络故障排除相对简单
- 容易产生
端口冲突
- 网络资源无法分别统计
不支持端口映射
- 使用参数
- 小结
- 适用于希望容器
直接使用主机网络栈
,与主机共享网络
的场景
!!!
- 适用于希望容器
none (无网络)
!!! tip 场景说明
- 语法声明
- docker run --network=none ...
- 工作方式
- 将容器置于一个
隔离的网络环境
中,该环境没有任何网络连接。
- 将容器置于一个
- 内容查看
- 本质
- 在容器运行时
禁用容器的网络功能
,使得容器无法进行网络通信
。
- 在容器运行时
- 通信
- 内网 (无)
- 外网 (无)
- 特点
- 使用参数
--network none
指定 - 默认无网络功能,
无法和外部通信
- 无法实现
端口映射
- 适用于
测试环境
- 使用参数
- 小结
- 适用于
不需要网络连接
的容器,用于隔离容器与网络的场景
。
!!!
- 适用于
container (容器网络)
!!! tip 场景说明
- 语法声明
- docker run --net=container:mycontainer ...
- 工作方式
- 创建容器时,需要关联指定容器,并与该容器
共享网络资源
- 端口
不能和被指定容器的端口冲突
,除了网络之外的文件系统、进程信息等仍然保持相互隔离 - 两个容器的进程可以通过
lo网卡
进行通信
- 创建容器时,需要关联指定容器,并与该容器
- 本质
- 新建的容器与
被指定的容器
网络资源共享,其他NS
资源保持独立
- 新建的容器与
- 通信
- 内网 (与关联容器保持一致)
- 外网 (与关联容器保持一致)
- 特点
- 使用参数
--network container:名称
或ID
指定 - 与宿主机网络空间隔离
- 容器间共享网络空间,直接
使用对方的网络
- 第一个容器的网络可能是
bridge
,none
,host
,而第二个容器模式依赖于第一个容器 - 如果第一个容器
停止
,将导致无法创建第二个容器
- 第二个容器可以直接
使用127.0.0.1访问第一个容器
- 适合
频繁的容器间的网络通信
- 默认
不支持端口映射
,较少使用
- 使用参数
- 小结
- 适用于希望
多个容器共享相同网络栈
,直接通信的场景。
- 适用于希望
- 案例
# 创建前端容器 wordpress,开放宿主机端口80 docker run -d \ -p 80:80 --name wordpress \ -v /data/wordpress:/var/www/html \ wordpress:php7.4-apache # 创建数据库容器 mysql,共享前端wordpress的网络 # 由于使用了 --network,后续链接数据库可使用 127.0.0.1 docker run --network container:wordpress \ -e MYSQL_ROOT_PASSWORD=alopex \ -e MYSQL_DATABASE=wordpress \ -e MYSQL_USER=wordpress \ -e MYSQL_PASSWORD=alopex \ -v /data/mysql:/var/lib/mysql \ --name mysql -d \ mysql:8.0
!!!
自定义网络
!!! tip 场景说明
- 语法声明
docker network create -d <mode> --subnet <CIDR> --gateway <网关> <自定义网络名称> # 注意mode不支持host和none 默认是bridge模式 -d <mode> 可省略,默认为bridge
- docker run --net= my-network ...
- 工作方式
- 使用自定义网络模式, 实现
不同集群应用的独立网络管理
, 而互不影响在网一个网络内, 可以直接利用容器名相互访问
- 使用自定义网络模式, 实现
- 案例
# 创建一个subnet 选择使用桥接模式,网段为 172.27.0.0/16 docker network create -d bridge \ --subnet=172.27.0.0/16 \ --gateway=172.27.0.1 mynet # 查看自建网络 [ { "Name": "mynet", "Id": "38214b8ba881d2b919bf59c1e5e27d838c973967bd04b4456333388a93c1bc18", "Created": "2024-04-26T16:10:55.214517178+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.27.0.0/16", "Gateway": "172.27.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] # 创建容器使用自定义网络 docker run --network=mynet -d rocky:demo tail -f /etc/hosts # 查看其网络配置 "Networks": { "mynet": { "IPAMConfig": null, "Links": null, "Aliases": [ "75be6bd6aaf4" ], "NetworkID": "38214b8ba881d2b919bf59c1e5e27d838c973967bd04b4456333388a93c1bc18", "EndpointID": "89fd76bd5dd18ac24f89b498d3336901058171ec817eae905b7fc9c1eb5b3e55", "Gateway": "172.27.0.1", "IPAddress": "172.27.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:1b:00:02", "DriverOpts": null }
!!!
Harbor私有仓库
基本操作
上传镜像
-
harbor创建项目和用户
- 创建项目
Projects
- 创建用户
Administration
->User
- 将现有用户
alfie
成为项目member
赋予权限Project Admin
- 创建项目
-
登录harbor
- docker login http://192.168.66.101:80
-
本地镜像打标签
- 标签格式
Harbor-host:port/project-name/image:tag
- 端口不能省略
- docker tag alpine:latest 192.168.66.101:80/alfie-app/alpine:v1
- 标签格式
-
insecurity设置
{ "insecure-registries": ["10.0.0.10:80","10.0.0.11:80"] #说明: ":80"端口可省略 } systemctl daemon-reload systemctl restart docker
-
上传镜像
- docker push 192.168.66.101:80/alfie-app/alpine:v1
-
harbor查看镜像
-
查看上传日志
下载镜像
-
docker security 开启(对于非443服务)
{ "insecure-registries": ["10.0.0.10:80","10.0.0.11:80"] #说明: ":80"端口可省略 } OR /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.66.101 systemctl daemon-reload systemctl restart docker
-
登录harbor
- docker login http://192.168.66.101:80
-
拉去镜像
- docker pull 192.168.66.101:80/alfie-app/alpine@sha256:6457d53fb065d6f250e1504b9bc42d5b6c65941d57532c072d929dd0628977d0
更新配置
-
关闭harbor
cd /apps/harbor && docker-compose down -
修改harbor配置文件
harbor.yml
-
配置重新生成
./prepare Clearing the configuration file: /config/portal/nginx.conf Clearing the configuration file: /config/log/logrotate.conf Clearing the configuration file: /config/log/rsyslog_docker.conf Clearing the configuration file: /config/nginx/nginx.conf Clearing the configuration file: /config/core/env Clearing the configuration file: /config/core/app.conf Clearing the configuration file: /config/registry/passwd Clearing the configuration file: /config/registry/config.yml Clearing the configuration file: /config/registry/root.crt Clearing the configuration file: /config/registryctl/env Clearing the configuration file: /config/registryctl/config.yml Clearing the configuration file: /config/db/env Clearing the configuration file: /config/jobservice/env Clearing the configuration file: /config/jobservice/config.yml Generated configuration file: /config/portal/nginx.conf Generated configuration file: /config/log/logrotate.conf Generated configuration file: /config/log/rsyslog_docker.conf Generated configuration file: /config/nginx/nginx.conf Generated configuration file: /config/core/env Generated configuration file: /config/core/app.conf Generated configuration file: /config/registry/config.yml Generated configuration file: /config/registryctl/env Generated configuration file: /config/registryctl/config.yml Generated configuration file: /config/db/env Generated configuration file: /config/jobservice/env Generated configuration file: /config/jobservice/config.yml loaded secret from file: /data/secret/keys/secretkey Generated configuration file: /compose_location/docker-compose.yml
-
启动harbor
docker-compose up -d
https请求实现.
- 配置域名
hostnamectl set-hostname www.my-harbor.com
sed -i '$a 192.168.66.101 www.my-harbor.com' /etc/hosts
-
生成证书
0x07 SSL/签署证书#制作根证书
0x07 SSL/签署证书#生成服务端证书#创建证书相关数据的目录 mkdir -p /data/harbor/certs cd /data/harbor/certs #生成ca的私钥 openssl genrsa -out ca.key 4096 #生成ca的自签名证书 openssl req -x509 -new -nodes -sha512 -days 3650 \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=ca.harbor.com" \ -key ca.key \ -out ca.crt #生成harbor主机的私钥 openssl genrsa -out my-harbor.key 4096 #生成harbor主机的证书申请 openssl req -sha512 -new \ -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=www.my-harbor.com" \ -key my-harbor.key \ -out my-harbor.csr #创建x509 v3 扩展文件(新版新增加的要求) cat > v3.ext <<-EOF authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = ip:192.168.66.101, DNS:www.my-harbor.com #[alt_names] #DNS.1=www.my-harbor.com #此处必须和和harbor的网站名称一致 #DNS.2=my-harbor.com #可选 EOF #给 harbor主机颁发证书 openssl x509 -req -sha512 -days 3650 \ -extfile v3.ext \ -CA ca.crt -CAkey ca.key -CAcreateserial \ -in my-harbor.csr \ -out my-harbor.crt # 证书查看 openssl x509 -in my-harbor.crt -noout -text
-
服务器使用证书
# 在应用下创建证书目录 mkdir /apps/harbor/certs # 复制证书到该路径下 cp my-harbor.crt my-harbor.key /apps/harbor/certs/ # 修改配置 harbor.yml https: # https port for harbor, default is 443 port: 443 # The path of cert and key files for nginx certificate: /apps/harbor/certs/my-harbor.crt private_key: /apps/harbor/certs/my-harbor.key # 使配置生效 cd /apps/harbor/ ./prepare docker-compose down -v docker-compose up -d
-
客户端使用证书
-
浏览器使用证书
c:\Windows\System32\Drivers\etc\hosts
- 追加主机解析记录
- 192.168.66.101 www.my-harbor.com
*
- 证书导入
- 再次访问
-
客户端配置证书
# 转换客户端证书(即后缀为 my-harbor.cert) cd /data/harbor/certs openssl x509 -inform PEM -in my-harbor.crt -out my-harbor.cert # 创建和harbor服务器同名目录 mkdir -pv /etc/docker/certs.d/www.my-harbor.com/ # 将.cert, .key, ca.key 复制到该目录下 cp my-harbor.cert my-harbor.key ca.crt /etc/docker/certs.d/www.my-harbor.com/
-
推送镜像测试
- 登录账号
- docker login www.my-harbor.com
- 修改镜像标签
- docker tag busybox:latest www.my-harbor.com/alfie-app/busybox:v1
- 推送镜像
- docker push www.my-harbor.com/alfie-app/busybox:v1
- 获得镜像
- docker pull www.my-harbor.com/alfie-app/busybox@sha256:db16cd196b8a37ba5f08414e6f6e71003d76665a5eac160cb75ad3759d8b3e29
- 登录账号
JumpServer安装和使用
部署
离线部署
脚本部署
curl -sSL https://resource.fit2cloud.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash
!!! tip 密钥和token信息
1. Configure Private Key
SECRETE_KEY: 216aa1a921346036377a317f007a50330c84a85dea56d145
BOOTSTRAP_TOKEN: jz0nNnx1Kts9v45233O8bHbZ
complete
# 应对此进行备份,因迁移请保证 SECRET_KEY和BOOTSTRAP_TOKEN与旧环境一致
!!!
!!! tip 提示信息
首次安装后需要修改配置文件,定义 DOMAINS
字段后即可正常使用。
如果服务器是一键安装并且旧版本就已经使用 JumpServer
开启了 HTTPS
,则不需要进行任何更改。
需要使用 IP 地址来访问 JumpServer
的场景,可以根据自己的 IP
类型来填写 config.txt
配置文件中 DOMAINS
字段为公网 IP 还是内网 IP。
默认安装路径:/opt/jumpserver
vim /opt/jumpserver/config/config.txt
# 可信任 DOMAINS 定义,
# 定义可信任的访问 IP, 请根据实际情况修改, 如果是公网 IP 请改成对应的公网 IP,
# DOMAINS="demo.jumpserver.org" # 使用域名访问
# DOMAINS="172.17.200.191" # 使用 IP 访问
# DOMAINS="demo.jumpserver.org,172.17.200.191" # 使用 IP 和 域名一起访问
DOMAINS="www.my-harbor.com,192.168.66.101:80"
!!!
访问方式
!!! info 访问登录
地址: http://<JumpServer服务器IP地址>:<服务运行端口>
如上面配置:http://www.my-harbor.com:80
用户名: admin
密码: admin
!!!
服务管理
/opt/jumpserver-installer-v3.10.9/jmsctl.sh
JumpServer Deployment Management Script
Usage:
./jmsctl.sh [COMMAND] [ARGS...]
./jmsctl.sh --help
Installation Commands:
install Install JumpServer
Management Commands:
config Configuration Tools
start Start JumpServer
stop Stop JumpServer
restart Restart JumpServer
status Check JumpServer
down Offline JumpServer
uninstall Uninstall JumpServer
More Commands:
load_image Loading docker image
backup_db Backup database
restore_db [file] Data recovery through database backup file
raw Execute the original docker-compose command
tail [service] View log
常用功能
管理员
创建用户组
配置用户 (登录名称 leslie)
创建资产
账户模板
账户推送
用户登录
创建授权策略
命令执行限制
操作员
登录账户
webshell登录用户
webshell命令限制
审计员
会话查看
命令记录
查看录制视频
- 对于下载的是视频,我们需要用特定的工具对其进行打开
- VideoPlayer