docker —— 关键技术记录
docker
docker
docker基础信息
docker的优点
- 统一了基础设施环境 —— 硬件配置、操作系统、软件环境等
- 统一了程序打包方式 —— 以 docker 镜像的方式
- 统一了程序部署的方式 —— 通过 docker 容器部署
- 统一了程序的运行方式 —— 各语言均使用命令 docker run
docker的缺点
- 集群性支持一般
- 随着容器数量的上升,管理成本攀升
- 没有有效的容灾/自愈机制
- 没有预设编排模板,无法实现快速、大规模的容器调度
- 没有统一的配置管理中心工具
- 没有容器生命周期的管理工具
- 没有图形化运维管理工具
docker能解决的问题
- 由于运行环境不一致导致的运行异常
- 由于其他程序干扰所导致的运行异常(不同 docker 间的进程级隔离)
- 大批量部署时,可以快速扩展、快速部署
docker层级结构

docker镜像分层
功能:将每个镜像按照其需要的依赖进行分层,如 nginx 需要一个 linux 系统、gnn-c++,那就把 nginx 拆分成 nginx 软件层、linux层、gnn-c++层,当有其他镜像使用相同依赖的时候,则共用相同的层
Volume数据卷
功能:用于将数据持久化到宿主机上,实现 docker 容器与宿主机的数据共享,以免出现容器丢失时数据丢失的情况
注册中心
功能:类似github,镜像中心
docker安装
操作系统预设置
网络设置
设置固定ip
$ vim /etc/sysconfig/network-scripts/ifcfg-ens33
修改内容如下:
- BOOTPROTO —— 默认 “dhcp”,改为 “none"或"static”
- ONBOOT —— 改为"yes"
- IPADDR(添加) —— 添加固定ip
- NETMASK(添加) —— 添加子网掩码
- GATEWAY(添加) —— 添加网关
- DNS1(添加) —— 添加DNS1,使用默认网关
- DNS2(添加) —— 添加DNS2,使用114.114.114.114
- DNS3(添加) —— 添加DNS3,使用8.8.8.8
重启网卡
$ systemctl restart network
查看默认网关
$ ip route show
yum安裝
卸載之前版本的 docker
$ yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
rpm 下载地址
$ yum install -y yum-utils
添加 docker 镜像地址(官方)与镜像二选一
$ yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
添加 docker 镜像地址(阿里镜像)
$ yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装 docker
$ yum install -y docker-ce docker-ce-cli containerd.io
启动并测试docker
$ systemctl start docker
$ docker run hello-world
docker基本命令
镜像基本命令
# docker帮助
$ docker 命令(如search) --help
# 查看内容器的运行状态
$ docker stats
# 查看 docker 概要信息
$ docker info
# 查看帮助文档
$ docker --help
# 删除镜像
$ docker rm 镜像名:TAG
$ docker rmi 镜像ID
# 镜像搜索
$ docker search 镜像名
# 删除所有容器
docker rm $(docker ps -a -q)
# 删除所有卷
docker volume rm $(docker volume ls -q)
容器基本命令
# 查看正在运行的容器
$ docker ps
# 查看所有容器
$docker ps -a
# 查看停止的容器
$ docker ps -f status=exited
# 查看最后一次运行的容器
$ docker ps -l
# 查看最后创建的5个容器
$ docker ps -n 5
# 查看容器详细信息
$ docker inspect 容器名
创建并进入容器
$ docker run 容器名
# 基本命令如下
$ docker run [option] IMAGE [COMMAND] [ARG]
option
- -i :运行容器
- -t :启动容器后,进入容器内的命令行。如 docker 启动一个 centos ,使用 -it 命令则会进入 docker 内部 centos 的命令行
- --name :创建容器名
- -v :表示目录映射(前者是宿主机,后者是映射到宿主机上的目录),可以使用多个 -v 做多个目录映射或文件映射
- -d :创建一个守护进程(后台运行 docker 容器)
- -p :端口映射(前者是宿主机端口,后者是 docker 容器端口,如 -p 8080:80),可以使用多个 -p 来映射多个端口
- -P :对宿主机随机使用可用的端口进行端口映射
# 进入守护进程的 docker 容器
$ docker exec 容器名或容器id(通过 docker ps 查看)
如:
# 进入守护进程的 nginx
$ docker exec -it mynginx /bin/bash
# 启动 / 停止 docker 容器
$ docker start / stop 容器名
docker复制容器
docker export name/id > xxx.tar
docker import xxx.tar 新容器:v1
docker run -it 新容器:v1
docker run参数
| option | 功能 |
|---|---|
| -a stdin | 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR |
| -d | 后台运行容器,并返回容器ID |
| -i | 以交互式运行容器,通常与 -t 同时使用 |
| -P | 将容器内指定的端口映射至主机的随机端口,如 -P 80 —— 将容器内 80 端口映射至主机随机端口 |
| -p | 指定端口映射,如 -p 8088:80 将容器的 80 端口映射至本机的 8088 |
| -t | 为容器重新分配一个伪输入终端,通常与 -i 同时使用 |
| –name “newDocker” | 指定当前容器的名称 |
| –dns 8.8.8.8 | 指定容器使用的DNS服务器,默认和宿主一致 |
| -h “hostname” | 指定容器的 hostname |
| -e username=“user1” | 设置容器的环境变量 |
| –env-file=[] | 从指定文件读入环境变量 |
| –cpuset=“0-2” 或 --cpuset=“0,1,2” | 绑定容器到指定 CPU 运行 |
| -m | 设置容器使用最大内存值 |
| –net “bridge” | 指定容器的网络连接类型,支持 bridge/host/none/container 四种类型 |
| –link=[] | 添加链接到另外一个容器 |
| –expose=[] | 开放一个端口或一组端口,该功能用于 link 之后的 container 通信,若使用 -p/-P 则相当于先使用了 --expose |
| –volume / -v | 挂载卷,将 container 内部的目录同步到宿主机的指定目录上 |
| –rm | 容器停止则自动删除容器 |
| –workdir / -w | 指定工作目录 |
运行容器命令
# 运行nginx容器,且该容器的名称为 mynginx,并且将docker容器的80端口映射到宿主机的8080端口上
$ docker run --name mynginx -p 8080:80 nginx
# 运行nginx容器,且该容器的名称为 mynginx,并且将docker容器的80端口映射到宿主机的随机端口上
$ docker run --name mynginx -P nginx
# 查看端口映射的情况
$ docker ps
如下代表将 nginx 容器的 80 端口映射到宿主机的 49153 端口
文件拷贝
# 将文件从 宿主机 复制到 docker 容器中
$ docker cp 需要拷贝的文件或目录 容器名称:容器目录
# 将文件从 docker 容器中 复制到 宿主机
$ docker cp 容器名称:容器目录 需要拷贝的文件或目录
设置docker镜像
国内镜像地址
https://docker.mirrors.ustc.edu.cn
修改镜像文件
$ vim /etc/docker/daemon.json
添加内容如下:
{
"registry-mirrors": ["http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"]
}
重新加载配置文件
$ systemctl daemon-reload
$ systemctl restart docker
目录挂载(数据卷)
正常挂载
功能:我们在创建容器的时候,将宿主机的目录与容器内的目录进行映射(双向绑定),这样我们可以通过修改宿主机某个目录的文件从而去影响容器,同样在容器中的修改也会同步到宿主机,由此特性可以实现数据的备份功能
注意事项:
- 数据卷是从外界挂载到容器内部中的,所以可以脱离容器的生命周期
- 数据卷的生命周期会一直持续到没有容器使用它为止
使用方法:
$ docker run -di -v 宿主机目录:容器目录 镜像名
# 也可以对多个目录配置挂载
$ docker run -di -v 宿主机目录1:容器目录1 -v 宿主机目录2:容器目录2 镜像名
匿名挂载
功能:将容器目录在 /var/lib/docker/volumes 中进行映射,并且在宿主机中生成的目录使用的是创建容器时给的一个随机名
使用方法:
$ docker run -di -v 容器目录 镜像名
# 查看数据卷信息
$ docker volume ls
具名挂载
功能:容器目录依旧在 /var/lib/docker/volumes 中进行映射,只是名字按照命令进行指定
使用方法:
$ docker run -di -v this_name:容器目录 镜像名
配置权限挂载目录
功能:对宿主机或者docker容器中对应的目录设置读写权限
使用方法:
# 下方命令中 容器目录 后的 :ro 即代表权限设置,设置 docker 容器对此目录的只读权限
$ docker run -di -v 宿主机目录:容器目录:ro 镜像名
权限类型:
- ro —— 只读
- rw —— 读写
挂载继承
功能:在创建新的 docker 容器时,从已经创建的容器中继承其目录卷
使用方法:
$ docker run -di --volumes-from 被继承的容器名 镜像名
注:在继承的时候可以进行 只读/读写 的权限设置,方法为 被继承的容器名:ro/rw
查看目录卷被挂载的容器
功能:查看某个目录卷,是被哪个容器所挂载
使用方法:
$ docker volume inspect 目录卷名
注:
- 若在 /var/lib/docker/volumes 下,则直接输入该目录下的映射名(即目录名)
- 若指定了宿主机目录,则将目录卷名改为目录名
创建自己的docker镜像
docker commit
功能:将修改后的容器打包为新的镜像
使用方法:
$ docker commit -a=“作者” -m=“描述信息” 容器名 镜像名
以创建一个具有 jdk环境和tomcat 的centos7为例,操作步骤:
1、创建 centos7 容器
$ docker run -di --name centos7 centos:7
2、将 jdk、tomcat 复制到宿主机
3、将jdk从宿主机复制到 docker 容器中
$ docker cp /usr/local/softs/jdk-8u281-linux-x64.tar.gz centos7:/usr/local/
$ docker cp /usr/local/softs/apache-tomcat-8.5.63.tar.gz centos7:/usr/local/
4、进入 docker 容器的 bash
$ docker exec -it centos7 bash
5、解压 jdk 并配置环境变量
$ tar -zxvf jdk-8u281-linux-x64.tar.gz
$ vi /etc/profile
export JAVA_HOME=/usr/local/softs/jdk1.8.0_281
export PATH=$PATH:$JAVA_HOME/bin
$ source /etc/profile
6、解压并启动 tomcat
$ tar -zxvf apache-tomcat-8.5.63.tar.gz
$ cd apache-tomcat-8.5.63/bin
$ ./startup.sh
$ curl http://localhost:8080
7、关闭 tomcat、删除 jdk 及 tomcat 的软件包
8、退出容器
$ exit
9、打包镜像
$ docker commit -a=“alun” -m=“centos7 with jdk8 and tomcat8” centos7 centos7_jdk8_tomcat8
docker file
功能:类似 shell 脚本,将构建自定义镜像的一系列操作,以流程控制的形式写下来,使 dcoker 按照预定好的逻辑进行进行
使用方法:
- FROM —— FROM centos:7 —— 指定基础镜像
- LABEL —— LABEL maintainer="" —— 注定一些标签信息
- RUN —— RUN mkdir -p /usr/local/tomcat —— 在容器中执行一些命令
- ADD —— ADD <src> <dest> —— 将文件或者目录拷贝到 docker 容器中并进行解压,若src为一个url,则自动下载并解压
- COPY —— COPY <src> <dest> —— 将文件或目录拷贝到 docker 容器中,不进行解压,也不支持 url
- EXPOSE —— EXPOSE <port> [<port>/<protocol>] —— 暴露容器运行时的监听端口给外部。若想要使容器与宿主机有端口映射关系,必须在容器启动时加上 -P 参数
- ENV —— ENV <key> <value> —— 设置容器内的环境变量
- CMD —— 启动容器时执行的 shell 命令,每个 dockerfile 中只可存在一个 CMD,若存在多个则仅有最后一个生效,且当创建容器时若使用了 -it (即创建后进入容器 shell 则 CMD 不会被执行)
- CMD [“executable”, “param1”, “param2”] —— 如 CMD ["/usr/local/tomcat/bin/catalina.sh", “run”]
- CMD [“param1”, “param2”] —— 如 CMD [“echo”, “$JAVA_HOME”]
- CMD command param1 param2 —— 如 CMD echo $JAVA_HOME
- ENTRYPOINT —— 类似CMD,启动容器时执行 shell 命令,不会被创建容器时的 shell 覆盖。但是一个 docker file 中只能有一条 ENTRYPOINT 指令,如果设置了多条的 ENTRYPOINT,则只有最后一条生效
- ENTRYPOINT [“executable”, “param1”, “param2”]
- ENTRYPOINT command param1 param2
- WORKDIR —— WORKDIR 工作目录 —— 为 RUN、CMD、ENTRYPOINT、COPY和AND设置工作目录(类似默认目录,作用于 docker 容器)
- VOLUME —— VOLUME ["/var/lib/mysql"] —— 一般不在 docker file 中使用 VOLUME,更多的是在创建容器时,通过 docker run 来使用
如:
1、创建 Dockerfile 文件(通常都叫 Dockerfile)
$ vi Dockerfile
2、写入如下命令
# 指定初始镜像的来源
FROM centos:7
# 声明标签信息
LABEL maintainer="some body"
# 设置工作目录
WORKDIR /usr/local
# 在 docker 容器中创建目录
RUN mkdir -p /usr/local/java && mkdir -p /usr/local/tomcat
# 拷贝文件到 docker 容器中并解压
ADD apache-tomcat-8.5.63.tar.gz /usr/local/tomcat
ADD jdk-8u281-linux-x64.tar.gz /usr/local/java
# 暴露容器的 8080 端口
EXPOSE 8080
# 设置 docker 容器的环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_281
ENV PATH $PATH:$JAVA_HOME/bin
# 启动容器时,启动 tomcat。这里要使用 catalina.sh,因为若使用 startup.sh 则 docker 容器中的 tomcat 是在后台运行的
# 当 docker 容器中找不到正在执行的命令时,就会自动退出容器。类似 hello-world,执行一次 执行完毕后就退出容器,不会持续运行
# 使用 ./catalina.sh run 则会执行 1、启动 tomcat ,2、阻塞控制台,3、将日志持续在控制台中输出。由此可以保持容器的持续运行
CMD ["/usr/local/tomcat/apache-tomcat-8.5.63/bin/catalina.sh", "run"]
3、执行 Dockerfile
# docker build —— 执行 Dockerfile
# -f —— 指定 Dockerfile
# -t 执行生成的镜像的名称、/usr/local/softs 指定执行 Dockerfile 时,宿主机的默认工作空间,用于ADD、CP等去寻找资源
$ docker build -f /usr/local/dockerfile/Dockerfile -t mycentos7 /usr/local/softs
.
镜像备份
功能:将 docker image 备份为 tar 文件
使用方法:
$ docker save [OPTIONS] IMAGE [IMAGE … ]
# 例如
$ docker save -o /root/mycentos7_jdk8_tomcat8.tar mycentos7_jdk8_tomcat8
镜像还原
功能:将 tar 包还原为 docker 镜像
使用方法:
$ docker load -i image压缩的tar包
docker hub 上传镜像
1、登录 docker hub
$ docker login
2、给镜像添加标签并上传
$ docker tag 本地镜像:镜像TAG 新仓库(一般都是用户名)/上传镜像名
$ docker push 新仓库/上传镜像名
例如:
上传前

生成 tag ,并上传

上传完成后

3、拉取镜像
$ docker pull 新仓库/上传镜像名
4、退出 docker hub
$ docker logout
搭建 docker 私有仓库
功能:构建一个私有的类 docker hub 仓库
步骤:
1、拉取registry
$ docker pull registry
2、修改 daemon.json 文件
$ vi /etc/docker/daemon.json
添加如下内容,用于在此处创建私有仓库
{
"insecure-registries": ["192.168.182.132:5000"]
}

3、重新加载配置文件并重启 docker
$ systemctl daemon-reload
$ systemctl restart docker
4、创建 registry 容器
$ docker run -di --name registry -p 5000:5000 -v /mydata/docker_registry:/var/lib/registry registry
5、打开浏览器并访问注册页面
http://192.168.182.132:5000/v2/_catalog
# 出现如下界面则表示创建成功
6、推送镜像到私有仓库
$ docker tag hello-world:latest 192.168.182.132:5000/test-hello-world:1.0.0
$ docker push 192.168.182.132:5000/test-hello-world:1.0.0
配置私有仓库认证
功能:要求用户以账户密码登录后才可以进行 pull 或者 push
步骤如下:
1、创建证书存储目录
$ mkdir -p /usr/local/registry/certs
2、生成自签名证书
$ openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/registry/certs/domain.key -x509 -days 365 -out /usr/local/registry/certs/domain.crt
含义:
- openssl req —— 创建证书的请求
- -newkey —— 创建 CSR 证书签名文件和 RSA 私钥文件
- rsa:2048 —— 指定创建的 RSA 私钥长度为2048
- -nodes —— 对私钥不进行加密
- -sha256 —— 使用 SHA256 算法加密
- -keyout —— 创建私钥的位置及名称
- -x509 —— 自签发证书格式
- -days —— 整数有效期
- -out —— 指定 CSR 证书输出的位置及名称
要注意 Common Name(hostname)一定要写创建 docker 的 registry 容器的宿主机的 ip,其他可以随意填写
3、生成鉴权密码文件
# 创建存储鉴权密码文件目录
$ mkdir -p /usr/local/registry/auth
# 如果没有 htpasswd 功能需要安装 httpd
$ yum install -y httpd
# 创建用户密码
$ htpasswd -Bbn root 0403 > /usr/local/registry/auth/htpasswd
注:htpasswd 是 apache http 的基本认证文件,使用 htpasswd 命令可以生成用户及密码文件
4、删除已经创建的私有仓库,重新创建
# 停止并删除没有权限验证的 registry 容器
$ docker stop registry
$ docker rm registry
# 重新创建具有权限的 registry
$ docker run -di --name registry -p 5000:5000 \
-v /mydata/docker_registry:/var/lib/registry \
-v /usr/local/registry/certs:/certs \
-v /usr/local/registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry

此时访问 http://192.168.182.132:5000/v2/_catalog 则无法访问,因为需要权限验证

5、尝试上传镜像
$ docker tag hello-world:latest 192.168.182.132:5000/test-hello-world:1.0.0
$ docker push 192.168.182.132:5000/test-hello-world:1.0.0
上传失败,提示没有进行用户验证
6、正确的上传姿势
$ docker login 192.168.182.132:5000
$ docker tag hello-world:latest 192.168.182.132:5000/test-hello-world:1.0.0
$ docker push 192.168.182.132:5000/test-hello-world:1.0.0
docker的网络模式
查看当前具有的网络模式
$ docker network ls
docker中基本的网络模式
| 网络模式 | 简介 |
|---|---|
| bridge(默认模式) | 为每一个容器分配一个IP,并将容器连接到一个 docker0 虚拟网桥 |
| host | 容器不配置虚拟网卡,直接使用主机的 ip 和 端口 |
| none | 禁用网络功能,容器有独立的 network namespace,但没有对其他网络进行任何设置 |
| container | 新创建的容器,不创建自己的网卡和ip,共享使用一个指定容器的 ip 、端口范围 |
设置 bridge 模式
在创建容器时,使用 --net bridge 或者 --network bridge 或者不添加(默认使用 bridge)
设置 host 模式
在创建容器时,使用 --net host 或者 --network host
设置 none 模式
在创建容器时,使用 --net none 或者 --network none
设置 container 模式
在创建容器时,使用 --net container:容器名 或者 --network container:容器名
自定义网络模式(容器间通信)
前言:bridge网络模式,各容器使用 docker0 虚拟网卡进行桥接,所以可以直接通过 ip 进行通信。但是由于容器的 ip 重启以后就有很大可能会发生变化,所以使用 ip 进行通信是不稳定的。自定义网络模式就是要让容器间可以通过容器名进行通信,这样无论 ip 怎么变化,容器间的通信都是稳定的
从 docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS Server,使容器可以通过容器名称进行通信。
使用方法:在创建容器时,使用 --name 指定了名字的容器,都可以使用自定义网络进行通信
1、创建自定义网络
$ docker network create 自定义网络名
2、创建容器时,指定网络为自定义网络
$ docker run --network 自定义网络名 --name …
连接网络(为容器连接新的网络模式)
$ docker network connect 网络名称 容器名称
断开网络
$ docker network disconnect 网络名称 容器名称
移除网络
$ docker network rm 网络名
docker 构建 redis 集群
系统环境
虚拟机:两台 192.168.182.132 192.168.182.133
系统环境:docker + redis 容器
搭建步骤
dcoker 实例
windows平台
1、启动 postgresql
docker run -di --name postgres_arcsde_postgis -p 5432:5432 -e POSTGRES_PASSWORD=Hs_123456 postgres:11.11
2、进入 docker
docker exec -it postgres_arcsde_postgis bash
3、更新 apt 并安装 postgis
# docker 的 postgres:11.11 默认是使用 debian 系统,所以此处要使用 apt 进行安装
$ apt-get update
$ apt-get install -y postgresql-11-postgis-3
4、复制 arcsde 的空间支持文件
docker cp D:\softs\soft\GIS\ArcMap1071\Desktop10.7\DatabaseSupport\PostgreSQL\11\Linux64\PGSQLEngine.so postgres_arcsde_postgis:/usr/lib/postgresql/11/lib
docker cp D:\softs\soft\GIS\ArcMap1071\Desktop10.7\DatabaseSupport\PostgreSQL\11\Linux64\st_geometry.so postgres_arcsde_postgis:/usr/lib/postgresql/11/lib
5、分别创建 postgis 和 arcsde 库
-- 创建postgis库
CREATE DATABASE postgis
WITH
OWNER = postgres
ENCODING = 'UTF8'
CONNECTION LIMIT = -1;
-- 创建postgis库的空间扩展
CREATE EXTENSION postgis;
-- 创建 arcsde 库
CREATE DATABASE arcsde
WITH
OWNER = postgres
ENCODING = 'UTF8'
CONNECTION LIMIT = -1;
6、通过 arcgis 创建 arcsde











.











浙公网安备 33010602011771号