一、Docker介绍
1.1 什么是docker
Docker是一个开源的应用容器引擎,基于go语言开发,用于运行容器里的应用。
Docker也可以作为管理容器和镜像的一种工具。
1.2 docker与虚拟机的区别***
Docker容器 | 虚拟机 | |
特性 | 所有容器共享宿主机内核 | 每个虚拟机都有独立的操作系统和内核 |
隔离性 | 通过namespace实现资源隔离,通过cgroup实现限制资源的最大使用量 | 完全隔离,每个虚拟机都有独立的硬件资源 |
启动速度 | 秒级启动速度 | 分钟级启动速度 |
性能损耗 | 容器相当于宿主机的进程,性能几乎没有损耗 | 需要通过hypervisor虚拟机管理程序对宿主机资源虚拟访问,至少有20%~50%的性能损耗 |
系统支持量(单机) | 单机容量能够支持成百上千个容器 | 单机容量最多支持几十个虚拟机 |
1.3 docker核心概念
- 镜像
- 容器
- 仓库
1.3.1 镜像
镜像是创建容器的基础。
镜像是一个只读的模板文件,里面包含运行容器中的应用程序所有需要的所有内容(应用程序文件、配置文件、运行库文件、依赖包等)
1.3.2 容器
容器是用镜像运行的实例。
容器可以被创建、启动、停止、删除,每个容器之间默认是相互隔离的。
1.3.3 仓库
仓库是用来保存镜像的地方。
仓库有公有仓库和私有仓库之分。
1.4 docker容器之间的隔离namespace***
namespace | 系统调用参数 | 隔离内容 |
---|---|---|
UTS Namespace | CLONE_NEWUTS | 主机名与域名 |
IPC Namespace | CLONE_NEWWIPC | 信号量、消息队列和共享内存 |
PID Namespace | CLONE_NEWPID | 进程编号 |
Net Namespace | CLONE_NEWNET | 网络设备、网络栈、端口等 |
MNT namespace | CLONE_NEWNS | 挂载点(文件系统) |
User Namespace | CLONE_NEWUSER | 用户和用户组(3.8以后的内核才支持) |
Controlgroup(cgroup)Namespace | CLONE_NEWCGROUP | 进程所属的控制组的身份隔离,限制使用资源 |
二、Docker的安装
systemctl stop firewalld
setenforce 0
#不一定有用,自行下载
wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.5.tgz
#解压
tar xzvf
#将二进制文件移动到可执行路径上的目录,例如/usr/bin/
cp docker/* /usr/bin/
vim /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start docker.service
#镜像加速 访问该https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors获取
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
#获取后的加速地址填写至以下
"registry-mirrors": ["https://23b9pwsw.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
#查看docker版本
docker version
三、Docker镜像和容器操作
3.1 镜像基础操作
命令 | 含义 |
---|---|
docker images -q 只输出镜像的ID | 查看镜像 |
docker pull | 下载镜像拉取镜像 |
docker push 新标签名 | 上传镜像 |
docker login | 登录镜像仓库 |
docker search | 搜索镜像 |
docker tag 镜像名 新标签名 | 打上新的标签 |
docker save -o 目录/包名 镜像id(标签会为空)/镜像标签(建议使用此方式) | 打包镜像到本地文件 |
docker load -i 镜像包的名称 | 导入镜像 |
docker rmi docker rmi `docker images -q` | 删除镜像 删除所有镜像 |
docker info | docker 软件信息 |
docker version | 查看版本信息 |
docker inspect 镜像id或者容器id | 查看详细信息 |
3.2 容器基础操作
查看容器状态
#docker ps docker ps -a #查看容器状态,包括退出的和运行的 docker ps -a -s #查看容器的状态,-s可以查看容器的大小 docker ps -l #查看最近的一个容器状态 docker ps -f status=exited #显示退出状态的容器 docker ps -qf status=exited | xargs -n1 docker rm #删除退出状态的容器并只显示容器的id #docker top docker top 容器ID或容器名 #查看容器中的进程状态 #docker stats docker stats --no-stream #查看容器中的各个状态 #docker inspect docker inspect 容器或镜像的ID/名 #查看docker各种对象的详细信息 docker inspect -f "{{.NetworkSettings.IPAddress}}" 容器ID/名 #查看IP #docker network ls docker network ls #查看默认的网络模式
启动容器基本命令
#docker cp #docker容器与宿主机传递文件 docker cp [选项] 容器ID/名:文件路径 宿主机文件路径 docker cp [选项] 宿主机文件路径 容器ID/名:文件路径 选项: -a 保留所有元信息 -L 复制软连接指向的文件,不使用-L则只复制软连接本身 #docker logs docker logs --tail 数字n -t 容器ID/名 #查看容器日志,最后n行,-t显示时间戳 docker logs -f 容器ID/名 #实时追踪容器日志 #docker rm docker rm -f 容器ID/名 #强行删除容器,没有-f只会删除退出状态的容器 docker start|stop|restart|pause|unpause 容器ID #开启关闭重启暂停容器 #docker exec docker exec [选项] 容器 命令 [参数...] #用于进入正在运行的容器中 前提:docker run -itd --name c7-1 centos:7 docker exec c7-1 cat /etc/passwd #一次性操作 docker exec -it c7-1 sh #进入sh命令模式,持久性操作 #docker run docker run [选项] [镜像名] [shell命令] [参数] docker run busybox echo "hello" #一次性命令,因为没有持续性命令维持容器运行,所以执行一次后就会退出 选项: -i 即使没有连接,也要保持STDIN打开,通常和-t一起使用 -t 分配一个终端,通常和-i一起使用,注意对应的容器必须运行shell才支持进入 docker run -it centos:7 bash #开启容器并且进入容器 exit #使用exit容器就会停止 同时按ctrl + p + q,容器依然存在 -d 后台运行,默认为前台 docker run -d httpd #直接运行会在后台执行 --name 为容器取名 docker run --name web1 nginx #为容器取名为web1,便于后续操作 -h 为容器设置主机名 docker run -it -h cxk centos:7 bash #为容器设置主机名为cxk --rm 删除容器,一般用于测试,即一次性命令测试 docker run --rm -it centos:7 bash #执行一次性命令后,退出容器并删除 -P 真机产生32768到61000的随机端口与容器的指定端口进行映射 docker run -P nginx docker port 容器ID/名 #查看容器的端口映射关系 #访问真机IP:随机端口,等于访问容器的80端口 -p 指定真机端口与容器端口映射 docker run -p 80 --name web1 nginx #指定真机80与容器80映射 docker run -p 9527:80 --name web2 httpd #指定真机9527与容器80映射 --restart always 容器意外退出,会自动启动容器,手动停止容器不会重启 docker run --restart always -it nginx -e 传递参数 变量参考链接: https://hub.docker.com/_/mysql docker run --name m1 -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpuser -e MYSQL_PASSWORD=123456 -d -p 3306:3306 mysql:5.7.29 --env-file=参数文件位置 准备参数文件 docker -run --env-file=env.file -d -p 3306:3306 mysql:5.7 参数优先级:-e > --env-file > dockerfile中的ENV -v 指定地址进行数据卷绑定 --network <指定网络模式> #默认为网桥bridge模式 --net=<指定网络模式> 指定容器的网络模式 --volumes-from 容器ID或名。用于共享或复用已存在的容器中的数据卷实现数据持久化和共享
3.2.2 docker案例,修改已经端口映射的关系
前提,不可以删除容器重新设置
案例环境还原:
docker run -d --name web1 -p 80:80 nginx
a28dca68a99de20aabc6a1df46e76127961894f288c1f2612d51532ee1e145ad
#将容器的80 和宿主机之间的80 做上对应关系
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a28dca68a99d nginx "/docker-entrypoint.…" 29 seconds ago Up 28 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web1
解决方法:
#先停止docker程序
systemctl stop docker
#找到容器文件位置
ls /var/lib/docker/containers/a28dca68a99de20aabc6a1df46e76127961894f288c1f2612d51532ee1e145ad
a28dca68a99de20aabc6a1df46e76127961894f288c1f2612d51532ee1e145ad-json.log config.v2.json hostname mounts resolv.conf.hash
checkpoints hostconfig.json hosts resolv.conf
#修改此文件,此文件中保存了端口映射关系
vim hostconfig.json
PortBindings":{"80/tcp":[{"HostIp":"","HostPort":"80"}]}
#PortBindings后80/tcp对应的是容器内部的80端口,HostPort对应的是映射到宿主机的端口80 修改此处为8000
"PortBindings":{"80/tcp":[{"HostIp":"","HostPort":"8000"}]}
#开启docker服务
systemctl start docker
#查看docker容器
docker ps -a
#开启容器
docker start web1
#查看端口映射
docker port web1
成功修改
3.2.3 docker容器的DNS解析添加方式
#################方法一:容器中的本地host文件添加DNS解析##################
--add-host 域名 ip地址 #在/etc/hosts下加入dns解析
docker run -it --rm --name test1 --add-host www.ab.com:6.6.6.6 alpine
/ # 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
6.6.6.6 www.ab.com #添加DNS成功
172.17.0.3 5b19d91e01d7
/ # exit
##########方法二:容器的DNS服务器中添加,默认采用的宿主机的DNS服务器#########
--dns 地址 #在建立容器时,在/etc/resolv.conf下添加dns地址
docker run -it --rm --dns 1.1.1.1 --dns 2.2.2.2 centos bash
#进入命令行
cat /etc/resolv.conf
nameserver 1.1.1.1 #添加DNS成功
nameserver 2.2.2.2 #添加DNS成功
search .
#########################方法三:配置文件指定DNS#####################
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://23b9pwsw.mirror.aliyuncs.com"],
"dns" : [ "114.114.114.114", "1.1.1.1" ],
"dns-search": [ "kcg.com" , "kgc.org" ]
}
#重启docker
systemctl restart docker
docker run -it --rm centos bash
cat /etc/resolv.conf
nameserver 114.114.114.114
nameserver 1.1.1.1
search kgc.com kgc.org
3.3 docker镜像制作
3.3.1 手动制作commit
手动制作流程:
下载一个系统的官方基础镜像,如: CentOS 或 Ubuntu
基于基础镜像启动一个容器,并进入到容器
在容器里面做配置操作
安装基础命令
配置运行环境
安装服务和配置服务
放业务程序代码
提交为一个新镜像 docker commit
基于自己的的镜像创建容器并测试访问
docker commit [选项] CONTAINER容器名 [REPOSITORY软件名[:TAG版本号]]
#选项 OPTIONS
-a, 指定作者名
-c, 指定执行的命令
-m, 指定描述信息
-p, 暂停容器
#说明:
制作镜像和CONTAINER状态无关,停止状态也可以制作镜像
如果没有指定[REPOSITORY[:TAG]],REPOSITORY和TAG都为<none>
提交的时候标记TAG号: 生产当中常用,后期可以根据TAG标记创建不同版本的镜像以及创建不同版本的容器
使用commit基于busybox制作httpd镜像
1.基于busybox镜像创建容器
docker run -it --name b1 busybox
2.在容器中配置httpd,busybox镜像自带httpd
/ # httpd --help #查看httpd命令
/ # mkdir -p /data/html #建立httpd工作目录,方便后续配置
/ # echo "docker busybox httpd" > /data/html/index.html #默认页面
/ # httpd -f -h /data/html #-f前台启动 -h指定主站点
3.提交新镜像
docker commit -a "btw" -c 'CMD /bin/httpd -fv -h /data/html/' -c 'EXPOSE 80' b1 busybox-httpd:v1.0
#-a指定作者 -c指定执行命令 EXPOSE 80为暴露80端口 b1为容器名 最后为镜像名:标签
4.查看新镜像
docker images
5.启动制作好的镜像并且测试
docker run -d --name busy-web1 -P busybox-httpd:v1.0
docker port busy-web1 #查看该容器的端口映射关系
curl 宿主机ip:映射关系的随机端口
"docker busybox httpd"即成功
3.3.2 docker镜像自动搭建——build
docker build命令使用Dockerfile文件创建镜像
docker build [OPTIONS] PATH | URL | -
说明:
PATH | URL | - #可以使是本地路径,也可以是URL路径。若设置为 - ,则从标准输入获取Dockerfile的内容
-f, --file string #Dockerfile文件名,默认为 PATH/Dockerfile
--force-rm #总是删除中间层容器,创建镜像失败时,删除临时容器
--no-cache #不使用之前构建中创建的缓存
-q --quiet=false #不显示Dockerfile的RUN运行的输出结果
--rm=true #创建镜像成功时,删除临时容器
-t --tag list #设置注册名称、镜像名称、标签。格式为 <注册名称>/<镜像名称>:<标签>(标签默认为latest)
示例:
docker build . #.代表当前目录下的Dockerfile文件
docker build /usr/local/src/nginx
docker build -f /path/to/a/Dockerfile .
docker build -t shykes/myapp .
docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
docker build -t test/myapp .
docker build -t nginx:v1 /usr/local/src/nginx
3.4 Dockerfile介绍
Dockerfile 文件说明
-
每一行以Dockerfile的指令开头,指令不区分大小写,但是惯例使用大写
-
使用 # 开始作为注释
-
每一行只支持一条指令,每条指令可以携带多个参数,可用&&合并多条指令为一条
-
指令按文件的顺序从上至下进行执行
-
每个指令的执行会生成一个新的镜像层,为了减少分层和镜像大小,尽可能将多条指令合并成一条指令
-
制作镜像一般可能需要反复多次,每次执行dockfile都按顺序执行,从头开始,已经执行过的指令已经缓存,不需要再执行,如果后续有一行新的指令没执行过,其往后的指令将会重新执行,所以为加速镜像制作,将最常变化的内容放下dockerfile的文件的后面
Dockerfile 相关指令
dockerfile 文件中的常见指令:
FROM
LABEL
ADD
COPY
ENV
(ARG) 有ENV则此条不生效,同样可以设置参数,但是优先级低于ENV
EXPOSE
STOPSIGNAL
USER
VOLUME
WORKDIR
CMD
ENTRYPOINT
Dockerfile指令解析
FROM #指定基础镜像,此指令通常必需放在Df文件第一个非注释行,可以理解为运行环境
LABEL #指定说明信息,如镜像元数据中的作者等
RUN #用于指定基础镜像支持的Shell命令,每个RUN之间相互独立,用`&&`,`||`,`;`合并
ENV #用于指定变量,多个变量之间空格隔开,如k1=v1 k2=v2 优先级低于`docker run -e ***`所指定的变量
ARG #有ENV则此条不生效,同样可以设置参数,但是优先级低于ENV。与ENV不同的是,容器运行时不会存在这些环境变量,只有在build阶段生效。
######################FROM,LABEL,RUN,ENV#########################
#ARG可以写在FROM前面,容器运行时不会存在这些环境变量
FROM centos:7.9.2009 #指定基础镜像
LABEL author="zhou cloud" \ #可以通过inspect看到,指定作者
version="1.0" \ #版本
description="test" #描述
RUN rm -rf /etc/yum.repos.d/* #删除yum源
RUN mkdir /app && cd /app #创建app文件夹并进入
RUN echo "hello" > test.txt #在根目录下,创建test.txt并增加内容hello
ENV version="1.0" user=mysql\ #指明变量,多个变量间空格隔开
name=zhou
RUN touch $name.txt #在根目录下,创建zhou.txt文件
##################################################################
WORKDIR #将默认的绝对路径从根目录改为指定目录
WORKDIR /data
COPY #支持多个和通配符;只能复制Dockerfile同级或下一级;目录不存在会自动建立;配合--chown user.user可以修改属主属组;若多个文件或通配符文件则需要在指定保存的目的目录后加上/
COPY hom?.txt /mydir/ #通配符,目标目录后必须加/
ADD #增强版COPY,支持自动解压(容器内需内含解压工具)
ADD a.gz /data/testdir/
ADD --chown=55:mygroup files* /somedir/
CMD #在启动容器时执行CMD默认命令;给前台分配一个默认执行的任务;若docker run没有指定命令且没有ENTRYPOINT则执行CMD的命令;只能指定一条,多条只执行最后一条
CMD tail -f /etc/hosts
ENTRYPOINT #前面有CMD则CMD为ENTRYPOINT的参数;不会被docker run覆盖,且run的参数也作为ENTRYPOINT的参数;一个Dockerfile只能有一个ENTRYPOINT,有多个只执行最后一个
CMD [-g","daemon off;"] #作为ENTRYPOINT的参数
ENTRYPOINT ["/apps/nginx/sbin/nginx"] #结合CMD,nginx -g daemon off
VOLUME #匿名卷指定容器内的目录(可多个);需要docker run -v指定宿主机目录,来关联;删除时使用docker rm -fv可以同时删除关联的匿名卷
VOLUME [ "/data1","/data2" ]
EXPOSE #暴露端口
EXPOSE 80 443
四、Docker数据管理
4.1 容器的数据管理介绍
Docker镜像是分层设计的,镜像层是只读的,通过镜像启动的容器添加了一层可读写的文件系统,用户写入的数据都保存在这一层中。
4.2 容器的分层
容器的数据分层目录
-
LowerDir: image 镜像层,即镜像本身,只读
-
UpperDir: 容器的上层,可读写 ,容器变化的数据存放在此处
-
MergedDir: 容器的文件系统,使用Union FS(联合文件系统)将lowerdir 和 upperdir 合并完成后给容器使用,最终呈现给用户的统一视图
-
WorkDir: 容器在宿主机的工作目录,挂载后内容会被清空,且在使用过程中其内容用户不可见
4.3 容器数据持久保存方式
如果要将写入到容器的数据永久保存,则需要将容器中的数据保存到宿主机的指定目录
Docker的数据类型分为两种:
-
数据卷(Data Volume): 直接将宿主机目录挂载至容器的指定的目录 ,推荐使用此种方式,此方式较常用
-
数据卷容器(Data Volume Container): 间接使用宿主机空间,数据卷容器是将宿主机的目录挂载至一个专门的数据卷容器,然后让其他容器通过数据卷容器读写宿主机的数据 ,此方式不常用
4.4 数据卷
数据卷使用场景
-
数据库
-
日志输出
-
静态web页面
-
应用配置文件
-
多容器间目录或文件共享
数据卷的特点
-
数据卷是目录或者文件,并且可以在多个容器之间共同使用,实现容器之间共享和重用对数据卷更改数据在所有容器里面会立即更新。
-
数据卷的数据可以持久保存,即使删除使用使用该容器卷的容器也不影响。
-
在容器里面的写入数据不会影响到镜像本身,即数据卷的变化不会影响镜像的更新
-
依赖于宿主机目录,宿主机出问题,上面容器会受影响,当宿主机较多时,不方便统一管理
-
匿名和命名数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,会拷贝到新初始化的数据卷中
数据卷使用方法
启动容器时,可以指定使用数据卷实现容器数据的持久化,数据卷有三种
-
指定宿主机目录或文件: 指定宿主机的具体路径和容器路径的挂载关系
-
容器和真机共用空间, 把容器的文件挂载到 真机的文件夹
-
-
匿名卷: 不指定数据名称,只指定容器内目录路径充当挂载点,docker自动指定宿主机的路径进行挂载
-
命名卷: 指定数据卷的名称和容器路径的挂载关系 和匿名卷在一个目录 , 只是取了一个自定义的名字
4.5 三种创建数据卷及管理方式
方式一:指定宿主机目录或文件格式(不存在会自动创建)
docker run -d -v /data/testdir/:/opt nginx
如需删除,只能手动删除
方式二:匿名卷,只指定容器内路径,宿主机自动生成/var/lib/docker/volumes/...
docker run -d -v /etc/nginx nginx
如需删除,使用` docker rm -v 容器ID/名 `删除容器及其匿名卷,此方法只能删匿名卷
方式三:命名卷,指定宿主机生成文件夹的名称,指定容器内路径
docker run -d -v vol1:/opt/nginx nginx
#在/var/lib/docker/volumes/vol1与/opt/nginx关联
#############################管理方式###############################
docker volume [CMD]
CMD:
create 创建
inspect 展示信息
ls 查看所有卷
prune 删除所有未使用的本地卷
rm 删除卷
#################################################################
五、Docker网络管理
5.1 docker的几种网络模式
1. 默认网桥bridge,容器基于SNAT进行地址转换访问宿主机以外的环境,若暴露端口,则会多加一条DNAT以实现端口映射。
// 此模式需要宿主机开启ip_forward路由转发功能,通过SNAT访问外网,通过DNAT让容器被外部主机访问,此模式也被称为NAT模式
#特点#
//不同宿主机的容器无法直接通信。性能低,网络转换消耗性能。
#配置示例#
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
"bip": "192.168.100.100/24", #配置了Docker网桥的IP地址和子网范围
"fixed-cidr": "192.168.100.128/26", #限制了容器可以使用的IP地址范围
"default-gateway": "192.168.100.200" #设置默认网关
}
2. host网络,直接使用宿主机的网络(不创建net namespace),性能最好,但是容器端口不能冲突
#特点#
//无需网络转换,性能最高。各容器内使用的端口不能相同,适用于运行端口较为固定的业务
#示例#
docker run -d --network host --name web1 nginx
3. none空网络,容器不会分配有效的IP地址(只有一个回环网卡用于内部通信),用于离线数据处理等场景
#特点#
//无法与外部通信。只有回环网卡。
#示例#
docker run -d --network none --name c1 centos:7
4. container新建容器和已存在的某个容器共享网络,两个容器共用一块网卡(较少使用)
#特点#
//与宿主机网络隔离。新容器的端口不能与被指定容器的端口冲突。两个容器通过lo网卡通信
#示例#
docker run -d --name web2 --network container:web1 nginx #端口冲突
docker run -d --name c2 --network container:c1 centos:7 bash
5. network-name自定义模式
5.2 docker容器通信知识
1.每次新建容器后:
- 宿主机多了一个虚拟网卡,和容器的网卡组合成一个网卡,比如: 137:veth8ca6d@if136,而在容器内的网卡名为136,可以看出和宿主机的网卡之间的关联
- 容器会自动获取一个172.17.0.0/16网段的随机地址,默认从172.17.0.2开始,第二次容器为172.17.0.3,以此类推
- 容器获取的地址并不固定,每次容器重启,可能会发生地址变化
2.默认情况下,同一个宿主机的不同容器之间可以相互通信
5.3 docker网络默认设置修改
#新建容器默认使用docker0的网络配置,可以修改默认指向自定义的网桥网络
#范例: 用自定义的网桥代替默认的docker0
brctl addbr docker1
brctl show
#结果
docker1 8000.000000000000 no
ip a a 192.168.1.1/24 dev docker1 #给网桥置地址
ip a #即可看到docker1
#为容器使用新建的docker1网桥
#修改service文件,在`ExecStart=`的末尾添加`-b docker1`
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -b docker1
systemctl daemon-reload
systemctl restart docker #重启服务生效
docker run -d nginx #后台启动一个服务
brctl show #可以看到docker1
#范例:修改docker 0 默认的网段
#修改service文件,在`ExecStart=`的末尾添加`-bip 自定义IP/子网掩码`
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -bip 192.168.2.1/24
systemctl daemon-reload
systemctl restart docker #重启服务生效
5.5 docker容器之间通过名称单向连接
流程:
1.为容器1添加名称的别名
2.在容器2启动时,添加--link 容器1的ID或别名
docker run it --name c1 centos:7 bash #容器1
docker run it --name c2 --link c1 centos:7 bash #容器2,--link c1
ping c1
cat /etc/hosts
#发现c1的IP与c1被做了本地解析,但是若改变了c1的IP则无法同步
#注意!!!此方法只能实现c2对c1的通信,而c1对c2需要手动添加
六、Docker仓库管理
6.1 Harbor介绍
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,由VMware开源,其通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有Registry服务器,Harbor 提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有 Registry 中,确保数据和知识产权在公司内部网络中管控,另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等
6.2 Harbor的组成
Harbor 的每个组件都是以 Docker 容器的形式构建的,因此,使用 Docker Compose 来对它进行部署。 总共分为7个容器运行,通过在docker-compose.yml所在目录中执行 docker-compose ps 命令来查看, 名称分别为:nginx、harbor-jobservice、harbor-ui、harbor-db、harbor-adminserver、registry、harbor-log。 其中 harbor-adminserver 主要是作为一个后端的配置数据管理,并没有太多的其他功能。harbor-ui 所要操作的所有数据都通过 harbor-adminserver 这样一个数据配置管理中心来完成。
6.3 Harbor的安装
下载地址: Releases · goharbor/harbor · GitHub
安装文档: https://github.com/goharbor/harbor/blob/master/docs/install-config/_index.md
#############安装docker-compose工具####################
lszrz docker-compose-Linux-x86_64-1.27.4
chmod +x docker-compose-Linux-x86_64-1.27.4
cp -a docker-compose-Linux-x86_64-1.27.4 /usr/bin/docker-compose
docker-compose version
docker-compose version 1.27.4, build 40524192
docker-py version: 4.3.1
CPython version: 3.7.7
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
####################安装harbor#########################
tar xf harbor-offline-installer-v1.2.2.tgz
cd harbor/
vim harbor.cfg
5 hostname = 192.168.254.40 # 主机
69 harbor_admin_password = 123456 # 密码
#执行前,先关闭防火墙
./prepare
#执行脚本前将 端口号占用的 清理清理
./install.sh
Creating harbor-log ... done
Creating harbor-db ... done
Creating redis ... done
Creating registryctl ... done
Creating registry ... done
Creating harbor-adminserver ... done
Creating harbor-core ... done
Creating harbor-jobservice ... done
Creating harbor-portal ... done
Creating nginx ... done
✔ ----Harbor has been installed and started successfully.----
Now you should be able to visit the admin portal at http://192.168.91.106 .
For more details, please visit https://github.com/goharbor/harbor .
#####################去真机访问192.168.254.40###################
登录harbor
新建项目
#####################返回虚拟机########################
#linux中默认是走https 协议无法登录
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --insecure-registry 192.168.254.40
systemctl daemon-reload
systemctl restart docker
#linux中登录
docker login 192.168.254.40
#查看镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 years ago 141MB
#给镜像打标签
docker tag 605c77e624dd 192.168.254.40/test/nginx:latest
#上传镜像
docker push 192.168.254.40/test/nginx:latest
The push refers to repository [192.168.254.40/test/nginx]
#上传至harbor成功
七、单机编排Docker Compose
7.1 介绍
docker-compose 是 docker 容器的一种单机编排服务,docker-compose 是一个管理多个容器的工具,比如: 可以解决容器之间的依赖关系,就像启动一个nginx 前端服务的时候会调用后端的tomcat,那就得先启动tomcat,但是启动tomcat 容器还需要依赖数据库,那就还得先启动数据库,docker-compose 可以用来解决这样的嵌套依赖关系,并且可以替代docker命令对容器进行创建、启动和停止等手工的操作
7.2 yaml注意事项
-
大小写敏感
-
通过缩进表示层级关系
-
不支持制表符 tab 键缩进,只能使用空格缩进
-
缩进的空格数目不重要,只要相同层级左对齐,通常开头缩进2个空格
-
用 # 号注释
-
符号字符后缩进1个空格,如冒号 : 、逗号 , 、横杠 -
-
如果包含特殊字符用单引号('')引起来会作为普通字符串处理,双引号(""): 特殊字符作为本身想表示的意思
7.3 docker compose命令
命令只能在docker-compose.yml的同级目录下执行
命令 | 解释 |
---|---|
build | #构建镜像 |
bundle | #从当前docker compose 文件生成一个以<当前目录>为名称的json格式的Docker Bundle 备份文件 |
config -q | #查看当前配置,没有错误不输出任何信息 |
create | #创建服务,较少使用 |
down | #停止和删除所有容器、网络、镜像和卷 |
events | #从容器接收实时事件,可以指定json 日志格式,较少使用 |
exec | #进入指定容器进行操作 |
help | #显示帮助细信息 |
images | #显示镜像信息,较少使用 |
kill | #强制终止运行中的容器 |
logs | #查看容器的日志 |
pause | #暂停服务 |
port | #查看端口 |
ps | #列出容器,较少使用 |
pull | #重新拉取镜像,镜像发生变化后,需要重新拉取镜像,较少使用 |
push | #上传镜像 |
restart | #重启服务,较少使用 |
rm | #删除已经停止的服务 |
run | #一次性运行容器 |
scale | #设置指定服务运行的容器个数 |
start | #启动服务 ,较少使用 |
stop | #停止服务,较少使用 |
top | #显示容器运行状态 |
unpause | #取消暂定 |
up | #创建并启动容器 ,较少使用 |
docker-compose.yml文件中的命令
指令 | 作用 | 演示 |
---|---|---|
build | 指定构建上下文和可选的Dockerfile用于构建镜像。 | build: context: /opt/test dockerfile: Dockerfile |
dockerfile | 指定Dockerfile的路径。通常在build部分中使用。 | dockerfile: Dockerfile.prod |
context | 指定构建上下文的路径,即包含Dockerfile和构建上下文的目录路径 | context: /opt/test |
image | 指定用于服务/容器的镜像名称。 | image: myapp:latest |
command | 覆盖由镜像指定的默认命令 | command: ["python", "app.py"] |
container_name | 为容器指定自定义名称。 | container_name: my_container |
deploy | 指定部署选项,如副本和放置 | deploy: replicas: 3 |
environment | 为服务指定环境变量 | environment: - DEBUG=true |
networks | 指定连接服务的网络 | networks: - frontend - backend |
network_mode | 指定容器的网络模式 | network_mode: "host" |
ports: | 将容器端口映射到主机端口 | ports: - "8080:80" |
volumes | 挂载主机或其他容器的卷 | volumes: - "nginx-data:/usr/local/nginx/html |
volumes_from | 从另一个服务/容器挂载卷 | volumes_from: - data-container |
hostname: | 指定主机名 | hostname: my-container |
sysctls | 为容器设置内核参数 | sysctls: - net.core.somaxconn=1024 |
restart | 重启策略 | restart: always |
depends_on | 指定该服务依赖的其他服务 | depends_on: - mysql |
7.4 docker-compose安装与使用
##################二进制安装####################
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin
######################命令#####################
格式:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
选项说明:
-f,–file FILE #指定Compose 模板文件,默认为docker-compose.yml
-p,–project-name NAME #指定项目名称,默认将使用当前所在目录名称作为项目名。
--verbose #显示更多输出信息
--log-level LEVEL #定义日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
--no-ansi #不显示ANSI 控制字符
-v, --version #显示版本
7.5 docker-compose案例
mkdir /mnt/docker-compose
cd /mnt/docker-compose/
vim docker-compose.yml
server-nginx-web: #自定义名字
image: nginx #选择nginx镜像
container_name: web1 #定义容器名为web1
expose: #暴露80和443端口
- 80
- 443
ports: #端口映射
- "80:80"
- "443:443"
docker-compose config #检测语法
#若没问题则显示version: '1',否则error
docker-compose up #前台启动
docker-compose up -d #后台启动
docker-compose down #将容器直接删除 镜像也会删除
docker-compose kill #只是退出容器
docker-compose rm #只删除停止的容器
7.6 调用 dockerfile文件 执行编排
FROM centos:centos7.9.2009
LABEL author="zhou cloud" \
version="1.0" \
description="test"
RUN rm -rf /etc/yum.repos.d/
ADD qh.repo /etc/yum.repos.d/
RUN yum -y install gcc gcc-c++ make automake pcre pcre-devel zlib zlib-devel openssl openssl-devel wget
ADD nginx-1.18.0.tar.gz /usr/local/src
RUN cd /usr/local/src/nginx-1.18.0 && ./configure --prefix=/apps/nginx && make && make install
COPY index.html /apps/nginx/html
EXPOSE 80
CMD ["-g","daemon off;"]
ENTRYPOINT ["/apps/nginx/sbin/nginx"]
docker build -t c7:n3 .
docker run -d -p 80:80 --name web1 c7:n1
#########################################################
编写 compose 文件
vim /opt/compose_nginx/docker-compose.yml
services:
nginx:
container_name: web1
hostname: nginx
build:
context: /data/dockerfile/system/centos/centos7/
dockerfile: Dockerfile
ports:
- 1216:80
- 1217:443
networks:
mynet:
ipv4_address: 172.18.0.10
volumes:
- ./wwwroot:/usr/local/nginx/html
networks:
mynet:
driver: bridge
ipam:
config:
- subnet: 172.18.0.0/16
services: 定义了要运行的服务。
nginx: Nginx 服务的配置。
container_name: 指定容器的名称为 web1。
hostname: 指定容器的主机名为 nginx。
build: 指定了构建 Nginx 容器所需的上下文和 Dockerfile。
ports: 将主机端口 1216 映射到容器的 80 端口,将主机端口 1217 映射到容器的 443 端口。
networks: 将服务连接到名为 lnmp 的自定义网络。
volumes: 将主机上的 ./wwwroot 目录挂载到容器中的 /usr/local/nginx/html 目录。
networks: 定义了自定义网络。
lnmp: 自定义网络的配置。
driver: 网络驱动程序为 bridge。
ipam: IP 地址管理配置。
config: 子网配置,指定了 IP 地址范围。
cd /opt/compose_nginx/
docker-compose -f docker-compose.yml up -d
----------------------------------------------------------------------------------------------------------
-f, --file FILE :使用特定的 compose 模板文件,默认为 docker-compose.yml
-p, --project-name NAME :指定项目名称,默认使用目录名称
-d :在后台运行
----------------------------------------------------------------------------------------------------------
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b48dceee248f compose_nginx_nginx "/run.sh" About a minute ago Up About a minute 0.0.0.0:1216->80/tcp, 0.0.0.0:1217->443/tcp compose_nginx_nginx_1
cd /opt/compose_nginx/
docker-compose ps #必须在docker-compose.yml所在目录执行此命令
docker-compose -f docker-compose.yml up -d