Docker

文章目录

    • 1. Docker 安装方式
      • 1.1 script 脚本安装
      • 1.2 yum 源 安装
      • 1.3 rpm 安装包
    • 2. 实际安装 Docker
      • 2.1 使用 rpm 安装包进行 Docker 安装的系统配置
      • 2.2 根据官方文档正常安装 docker
      • 2.3 卸载 docker
    • 3. Docker 加速配置 (RPM 安装包 用)
      • 3.1 阿里云镜像加速器
    • 4. 底层原理
    • 5. docker 常用命令
      • 5.1 基础命令
      • 5.2 镜像命令
        • (1) docker images 查看本地主机上的所有镜像
        • (2) docker search 搜索镜像
        • (3) docker pull 镜像名[:tag] 下载镜像
        • (4) docker rmi 删除镜像
      • 5.3 容器命令
        • 5.3.1 拉取一个 centos 容器
        • 5.3.2 运行容器
        • 5.3.3 进入容器
        • 5.3.4 退出容器
        • 5.3.5 列表查看运行过的容器
        • 5.3.6 删除容器
        • 5.3.7 启动和停止容器
        • 5.3.8 容器的导入和导出
      • 5.4 其他常用命令
        • 5.4.1 日志的查看
        • 5.4.2 查看容器中的进程信息
        • 5.4.3 查看容器的元数据
        • 5.4.4 进入当前正在运行的容器
        • 5.4.5 拷贝操作
            • (1) 拷贝操作的命令
            • (2) 拷贝测试
        • 5.4.6 其他容器管理命令
            • (1) docker pause
            • (2) docker port
            • (3) docker rename
            • (4) docker stats
            • (5) docker top
            • (6) docker unpause
    • 6. 常用容器部署
      • 6.1 部署 nginx
        • (1) 搜索并下载镜像
        • (2) 运行镜像
        • (3) 配置文件
        • (4) 访问测试
        • (5) 容器内安装 vim
      • 6.2 部署 tomcat
        • (1) 下载镜像并运行
        • (2) 进入容器
        • (3) 访问测试
    • ! Docker容器使用问题:Failed to get D-Bus connection: Operation not permitted
            • 解决方案 以特权模式运行容器
    • 7. Docker 镜像 详解
      • 7.1 什么是镜像
      • 7.2 docker 镜像 加载原理
      • 7.3 镜像的分层
        • 7.3.1 分层解析
      • 7.4 提交镜像
        • 7.4.1 提交测试
        • (1) 启动一个官方 tomcat 镜像
        • (2) 发现这个默认的 tomcat 没有 webapps 应用(官方镜像默认 webapps 下没有文件)
        • (3) 手动将 webapps.dist 下的文件递归拷贝至 webapps 目录下
        • (4) 将操作过的容器通过 commit 提交为一个新的镜像
        • (5) 运行提交的新镜像
        • (6) 镜像的导入和导出
    • 8. 图形化管理工具 Portaninter 安装
    • 9. 容器数据卷
      • 9.1 文件挂载方式
      • 9.2 安装 MySQL 并建立数据卷同步技术
      • 9.3 数据卷常用命令
            • 1. 创建数据卷
            • 2. 查看所有的数据卷
            • 3. 查看指定数据卷的信息
            • 4. 删除数据卷
            • 5. 删除容器时删除相关的卷
            • 6. 无主的数据卷可能会占据很多控件,清理时的命令
      • 9.4 Dockerfile 中设置数据卷
      • 9.5 通过数据卷实现容器间的数据同步(数据卷容器,备份)
    • 10. Dockerfile
      • 10.1 Dockerfile 介绍
      • 10.2 Dockerfile 指令说明
      • 10.3 通过 Dockerfile 构建一个 centos镜像
    • 11. 发布自己的镜像
    • 12. Docker 网络
      • 12.1 docker 网络模式
            • host 模式
            • none 模式
      • 12.2 单向通信 --link
      • 12.3 创建桥接网络实现容器间的双向通信
      • 12.4 更改 docker0 默认网桥的 IP 段
      • 12.5 创建网络/容器时指定 IP
    • 13. Docker-compose 编排工具
      • 13.1 compose 工具的安装与卸载
            • 安装
            • 卸载
      • 13.2 compose 常用命令
            • 列出容器 ps
            • 查看服务日志输出 logs
            • 输出绑定的公共端口 port
            • 重新构建服务 build
            • 启动服务 start
            • 停止服务 stop
            • 删除已停止服务的容器 rm
            • 创建和启动容器 up
            • 进入运行中的容器 exec
            • 其他管理命令
      • 13.3 docker-compose.yml 文件
            • 编写规则
      • 13.4 docker-compose.yml 一键部署 WP 博客
    • 14. docker swarm 编排工具
      • 14.1 相关概念
            • swarm
            • 节点
            • 服务
            • 任务
      • 14.2 swarm 常用命令
        • docker swarm 管理 swarm 集群
        • docker service 管理服务
        • docker node 管理 swarm 集群中的节点
      • 14.3 排空容器,删除节点
      • 14.4 docker swarm 创建 nginx 集群
      • 14.5 节点宕机情况
    • ?. Docker 拉取 WordPress 应用
      • ?.1 centos 7 Docker容器启动报WARNING: IPv4 forwarding is disabled. Networking will not work
    • 云课堂 Dockerfile 构建 Java网站镜像
            • 1. 准备两个必要的压缩安装包放入指定路径,创建 dockerfile 文件 与两个压缩安装包在同一路径
            • 2. 编辑 dockerfile 文件 内容
            • 3. 构建镜像,生成容器
    • 云课堂 Dockerfile 构建 nginx 镜像

1. Docker 安装方式

1.1 script 脚本安装

yum update
$ curl -sSL https://get.docker.com/ | sh
systemctl start docker
systemctl enable docker
docker run hello-world

1.2 yum 源 安装

yum update
cat >/etc/yum.repos.d/docker.repo <<-EOF
[dockerrepo]
name=Docker Repository
baseurl=http://yum.dockerproject.org/repo/main/centos/7
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg EOF

1.3 rpm 安装包

yum update
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

2. 实际安装 Docker

官方文档:https://docs.docker.com/

2.1 使用 rpm 安装包进行 Docker 安装的系统配置

关闭 firewalld 防火墙
systemctl stop firewalld
systemctl disable firewalld

禁用 selinux		 /etc/selinux/config
getenforce   -->    Disabled    

开启 iptables (Docker 环境需要)
systemctl start iptables
		如果没有可以安装	yum -y install iptables-services
systemctl start iptables
systemctl enable iptables
清空原 iptables 安全规则后再保存配置
iptables -F
service iptables save

最后 reboot 重启虚拟机,重启后默认会采用最新版本的内核

[root@localhost ~]# mkdir docker
将 两个 rpm 安装包移动到 docker 目录下	
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ 下的两个 rpm 安装包
   docker-ce-17.03.0.ce-1.el7.centos.x86_64.rpm	docker-ce-selinux-17.03.0.ce-1.el7.centos.noarch.rpm
[root@localhost ~]# cd docker/
[root@localhost docker]# yum -y install * 

安装完毕后启用 docker 服务
systemctl start docker
systemctl enable docker
systemctl status docker
docker version

成功开启服务后,利用 docker 官方给出的测试镜像来检测 docker 安装
[root@localhost docker]# docker run hello-world

使用 docker images 命令 可以查看当前系统中使用 docker 下载好的所有镜像文件

2.2 根据官方文档正常安装 docker

1.卸载旧的版本
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2.需要的安装包
sudo yum install -y yum-utils

3.设置镜像的仓库
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo		# 默认是国外镜像
	
sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo		# 国内阿里云镜像
	
4.更新 yum 软件包索引(非必需)
yum makecache fast

5.安装 docker 	docker-ce 社区版	docker-ee 企业版
yum install docker-ce docker-ce-cli containerd.io

6.启动 docker
systemctl start docker

7.查看 docker 版本号,运行 hello-world 测试镜像
docker version
docker run hello-world

8.查看下载好的 hello-world 镜像
docker images

2.3 卸载 docker

1.删除依赖
yum remove docker-ce docker-cd-cli containerd.io

2.删除资源
rm -rf /var/lib/docker		# docker 的默认工作路径

3. Docker 加速配置 (RPM 安装包 用)

为了加速下载国外的镜像文件

阿里云 Docker 官网: https://dev.aliyun.com/search.html
cp /lib/systemd/system/docker.service	/etc/systemd/system/docker.service
chmod 777 /etc/systemd/system/docker.service
vim /etc/systemd/system/docker.service
	ExecStart=/user/bin/dockerd-current	 --registry-mirror=https://kfp63jaj.mirror.aliyuncs.com  
systemctl daemon-reload
systemctl restart docker
ps -ef | grep docker

3.1 阿里云镜像加速器

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://be1oqm8e.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

4. 底层原理

1. docker 是怎么工作的
	docker 是一个 client-server 结构的系统,docker 的守护进程运行在主机上,通过 socket 从 客户端 访问
	docker server 接收到 docker-client 的指令,就会执行这个命令
	
2. docker 为什么比 VM 快
	(1) docker 有着比虚拟机更少的额抽象层
	(2) docker 利用的是宿主机的内核,VM 则是需要 Guest OS
  在新建一个容器的时候,docker 不需要像虚拟机一样重新加载一个操作系统内核,可以避免引导,而虚拟机需要加载 Guest OS,docker 利用宿主机的操作系统可以省略这个过程,所以会更快速更高效

5. docker 常用命令

官方帮助文档:https://docs.docker.com/engine/reference/commandline

5.1 基础命令

docker version          #查看docker的版本信息
docker info             #查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help       #帮助命令(可查看可选的参数)
docker COMMAND --help

命令的帮助文档地址: https://docs.docker.com/engine/reference/commandline/docker/

5.2 镜像命令

(1) docker images 查看本地主机上的所有镜像

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    bf756fb1ae65   11 months ago   13.3kB

#解释:
1.REPOSITORY  镜像的仓库源
2.TAG  镜像的标签
3.IMAGE ID 镜像的id
4.CREATED 镜像的创建时间
5.SIZE 镜像的大小

# 可选参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id

(2) docker search 搜索镜像

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search mysql
NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql                             MySQL is a widely used, open-source relation…   10308     [OK]
mariadb                           MariaDB is a community-developed fork of MyS…   3819      [OK]
mysql/mysql-server                Optimized MySQL Server Docker images. Create…   754                  [OK]
percona                           Percona Server is a fork of the MySQL relati…   517       [OK]
centos/mysql-57-centos7           MySQL 5.7 SQL database server                   86
mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   79
centurylink/mysql                 Image containing mysql. Optimized to be link…   60                   [OK]


#可选参数
Search the Docker Hub for images

Options:
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print search using a Go template
      --limit int       Max number of search results (default 25)
      --no-trunc        Don't truncate output
           
# 搜索收藏数大于3000的镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search mysql --filter=STARS=3000
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
mysql     MySQL is a widely used, open-source relation…   10308     [OK]
mariadb   MariaDB is a community-developed fordockerk of MyS…   3819      [OK]

(3) docker pull 镜像名[:tag] 下载镜像

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull mysql
Using default tag: latest            #如果不写tag默认就是latest
latest: Pulling from library/mysql
6ec7b7d162b2: Pull complete          #分层下载,docker image的核心-联合文件系统
fedd960d3481: Pull complete
7ab947313861: Pull complete
64f92f19e638: Pull complete
3e80b17bff96: Pull complete
014e976799f9: Pull complete
59ae84fee1b3: Pull complete
ffe10de703ea: Pull complete
657af6d90c83: Pull complete
98bfb480322c: Pull complete
6aa3859c4789: Pull complete
1ed875d851ef: Pull complete
Digest: sha256:78800e6d3f1b230e35275145e657b82c3fb02a27b2d8e76aac2f5e90c1c30873 	#签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest  		
#下载来源的真实地址  #docker pull mysql 等价于 docker pull docker.io/library/mysql:latest

指定版本下载

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
6ec7b7d162b2: Already exists
fedd960d3481: Already exists
7ab947313861: Already exists
64f92f19e638: Already exists
3e80b17bff96: Already exists
014e976799f9: Already exists
59ae84fee1b3: Already exists
7d1da2a18e2e: Pull complete
301a28b700b9: Pull complete
529dc8dbeaf3: Pull complete
bc9d021dc13f: Pull complete
Digest: sha256:c3a567d3e3ad8b05dfce401ed08f0f6bf3f3b64cc17694979d5f2e5d78e10173
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

(4) docker rmi 删除镜像

#1.删除指定的镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id

#2.删除多个镜像id
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  镜像id 镜像id 镜像id

#3.删除全部的镜像id (采用镜像ID的方式一次性删除所有镜像)
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker rmi -f  $(docker images -aq)

5.3 容器命令

5.3.1 拉取一个 centos 容器

docker pull centos

5.3.2 运行容器

docker run [可选参数] image

#参数说明
--name="名字"           指定容器名字
-d                     后台方式运行
-it                    使用交互方式运行,进入容器查看内容
-p                     指定容器的端口
	(
		-p ip:主机端口:容器端口  配置主机端口映射到容器端口
		-p 主机端口:容器端口
		-p 容器端口
					)
-P                     随机指定端口(大写的P)

5.3.3 进入容器

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -it centos /bin/bash
[root@bd1b8900c547 /]# ls      
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

5.3.4 退出容器

#exit 停止并退出容器
#Ctrl+P+Q  不停止容器并退出(容器于后台运行)
[root@bd1b8900c547 /]# exit
exit
[root@iZwz99sm8v95sckz8bd2c4Z ~]#

5.3.5 列表查看运行过的容器

#docker ps 
     # 列出当前正在运行的容器
-a   # 列出所有容器的运行记录
-n=? # 显示最近创建的n个容器
-q   # 只显示容器的编号

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS                     PORTS     NAMES
bca129320bb5   centos         "/bin/bash"   4 minutes ago   Exited (0) 3 minutes ago             optimistic_shtern
bd1b8900c547   centos         "/bin/bash"   6 minutes ago   Exited (0) 5 minutes ago             cool_tesla
cf6adbf1b506   bf756fb1ae65   "/hello"      5 hours ago     Exited (0) 5 hours ago               optimistic_darwin

5.3.6 删除容器

docker rm 容器id                 	   #删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
docker rm -f $(docker ps -aq)   	#删除所有的容器
docker rm -v 容器ID                  #删除容器挂载的数据卷
docker ps -a -q|xargs docker rm 	#删除所有的容器

5.3.7 启动和停止容器

docker start 容器id          #启动容器
docker restart 容器id        #重启容器
docker stop 容器id           #停止当前运行的容器
docker kill 容器id           #强制停止当前容器

5.3.8 容器的导入和导出

导出容器:如果要导出某个窗口到本地,可以用 docker export 命令,可将容器导出为 tar 文件格式

docker export [options] container

options 为 -o 参数,表示指定导出的 tar 文件名

将容器名为 mycentos 的容器导出,文件格式为 "cent-日期"
	docker export -o centos-`date +%y%m%d`.tar mycentos

导入容器:可以用 docker import 命令导入一个镜像,类型为 tar 文件

docker import [option] [repository[:tag]]

5.4 其他常用命令

5.4.1 日志的查看

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker logs --help

Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
  -n, --tail string    Number of lines to show from the end of the logs (default "all")
  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

常用:
docker logs -tf 容器id
docker logs --tail number 容器id #num为要显示的日志条数


#docker容器后台运行,必须要有一个前台的进程,否则会自动停止

#编写shell脚本循环执行,使得centos容器保持运行状态
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d centos /bin/sh -c "while true;do echo hi;sleep 5;done"
c703b5b1911ff84d584390263a35707b6024816e1f46542b61918a6327a570dc
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
c703b5b1911f   centos    "/bin/sh -c 'while t…"   13 seconds ago   Up 10 seconds             pedantic_banach
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker logs -tf --tail 10 c703b5b1911f
2020-12-27T03:34:07.255599560Z hi
2020-12-27T03:34:12.257641517Z hi
2020-12-27T03:34:17.259706294Z hi
2020-12-27T03:34:22.261693707Z hi
2020-12-27T03:34:27.262609289Z hi
2020-12-27T03:34:32.267862677Z hi
2020-12-27T03:34:37.270382873Z hi
2020-12-27T03:34:42.272414182Z hi
2020-12-27T03:34:47.274823243Z hi
2020-12-27T03:34:52.277419274Z hi

5.4.2 查看容器中的进程信息

docker top 容器ID

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker top c703b5b1911f
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                11156               11135               0                   11:31               ?                   00:00:00            /bin/sh -c while true;do echo hi;sleep 5;done
root                11886               11156               0                   11:43               ?                   00:00:00            /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5

5.4.3 查看容器的元数据

docker inspect 容器ID

[root@localhost /]# docker inspect 675d09b7df1b
[
    {
        "Id": "675d09b7df1b8dca7eb2134e73fbc020bdaf12dc2eaf1e9861d71152c5305199",
        "Created": "2022-02-01T09:20:22.252323295Z",
        "Path": "/bin/bash",
        "Args": [],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 66230,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2022-02-01T09:20:22.672433457Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
        "ResolvConfPath": "/var/lib/docker/containers/675d09b7df1b8dca7eb2134e73fbc020bdaf12dc2eaf1e9861d71152c5305199/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/675d09b7df1b8dca7eb2134e73fbc020bdaf12dc2eaf1e9861d71152c5305199/hostname",
        "HostsPath": "/var/lib/docker/containers/675d09b7df1b8dca7eb2134e73fbc020bdaf12dc2eaf1e9861d71152c5305199/hosts",
        "LogPath": "/var/lib/docker/containers/675d09b7df1b8dca7eb2134e73fbc020bdaf12dc2eaf1e9861d71152c5305199/675d09b7df1b8dca7eb2134e73fbc020bdaf12dc2eaf1e9861d71152c5305199-json.log",
        "Name": "/practical_taussig",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "no",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "host",
            "Dns": [],
            "DnsOptions": [],
            "DnsSearch": [],
            "ExtraHosts": null,
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
                0,
                0
            ],
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": [],
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [],
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": false,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/af71e698811be67ff55a08c7a1938231558d182394284b0c75ef1e3ac1e4cfac-init/diff:/var/lib/docker/overlay2/b70e8f6a60b06f9b9e169ef6ca7a98c929d7eab1928f3c4ebce6526424356223/diff",
                "MergedDir": "/var/lib/docker/overlay2/af71e698811be67ff55a08c7a1938231558d182394284b0c75ef1e3ac1e4cfac/merged",
                "UpperDir": "/var/lib/docker/overlay2/af71e698811be67ff55a08c7a1938231558d182394284b0c75ef1e3ac1e4cfac/diff",
                "WorkDir": "/var/lib/docker/overlay2/af71e698811be67ff55a08c7a1938231558d182394284b0c75ef1e3ac1e4cfac/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [],
        "Config": {
            "Hostname": "675d09b7df1b",
            "Domainname": "",
            "User": "",
            "AttachStdin": true,
            "AttachStdout": true,
            "AttachStderr": true,
            "Tty": true,
            "OpenStdin": true,
            "StdinOnce": true,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/bash"
            ],
            "Image": "centos",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "org.label-schema.build-date": "20210915",
                "org.label-schema.license": "GPLv2",
                "org.label-schema.name": "CentOS Base Image",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.vendor": "CentOS"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "5fd8e445494927618208d865fda171ce7174b12283566cd4980c5cba8417b9a1",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/5fd8e4454949",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "40802064511bf3fce2ada78ebb2b9cd2a7115e4c70bfed84de9335bebaf0c475",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "3dd3de8122786c84dd38296e7a11f5a48410397adf761cf83db9683f7ef9c852",
                    "EndpointID": "40802064511bf3fce2ada78ebb2b9cd2a7115e4c70bfed84de9335bebaf0c475",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

5.4.4 进入当前正在运行的容器

通常容器都是后台运行,有时需要进入容器修改配置

# 方式一 docker exec -it 容器ID /bin/bash
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker exec -it c703b5b1911f /bin/bash
[root@c703b5b1911f /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@c703b5b1911f /]# ps -ef      
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 03:31 ?        00:00:00 /bin/sh -c while true;do echo hi;sleep 5;done
root       279     0  0 03:54 pts/0    00:00:00 /bin/bash
root       315     1  0 03:56 ?        00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5
root       316   279  0 03:56 pts/0    00:00:00 ps -ef

# 方式二 docker attach 容器ID
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker attach c703b5b1911f

docker exec    进入容器后开启一个新的终端,可以在里面操作
docker attach  进入容器正在执行的终端,不会启动新的进程

5.4.5 拷贝操作

(1) 拷贝操作的命令
# 拷贝容器的文件到主机上
docker cp 容器ID:容器内路径 目的主机路径

# 拷贝宿主机的文件到容器中
docker cp 目的主机路径 容器ID:容器内路径
(2) 拷贝测试
# 宿主机创建测试文件
[root@localhost home]# ls
test.txt

# 查看正在运行的容器
[root@localhost home]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
8d458d38140c   centos    "/bin/bash"   7 minutes ago   Up 7 minutes             peaceful_boyd

#拷贝操作
[root@localhost home]# docker cp /home/test.txt 8d458d38140c:/home

#进入正在运行的容器
[root@localhost home]# docker exec -it 8d458d38140c /bin/bash

#进入拷贝路径查看测试文件
[root@8d458d38140c /]# cd /home
[root@8d458d38140c home]# ls
test.txt

5.4.6 其他容器管理命令

(1) docker pause
docker pause 命令 用于暂停容器进程

暂停 centos 容器中的进程
	docker pause centos
(2) docker port
docker port 命令 用于查看容器与宿主机端口映射的信息
docker port 容器ID/容器名
(3) docker rename
docker rename 命令 用于更改容器名称

将 centos 容器 更名为 centos7
docker rename centos centos7
(4) docker stats
docker stats 命令 用于动态显示容器的资源消耗情况
docker stats 容器ID/容器名
(5) docker top
docker top 命令 用于查看容器中运行的进程信息
docker top 容器ID/容器名
(6) docker unpause
docker unpause 命令 用于恢复容器内暂停暂停的进程

恢复 centos 容器中的进程
	docker unpause centos

6. 常用容器部署

6.1 部署 nginx

(1) 搜索并下载镜像

可以到dockerhub官网查看Nginx的详细版本信息 :https://hub.docker.com/_/nginx

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search nginx
NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nginx                              Official build of Nginx.                        14207     [OK]       
jwilder/nginx-proxy                Automated Nginx reverse proxy for docker con…   1932                 [OK]
richarvey/nginx-php-fpm            Container running Nginx + PHP-FPM capable of…   797                  [OK]
linuxserver/nginx                  An Nginx container, brought to you by LinuxS…   137                  
jc21/nginx-proxy-manager           Docker container for managing Nginx proxy ho…   123                  
tiangolo/nginx-rtmp                Docker image with Nginx using the nginx-rtmp…   107                  [OK]

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
6ec7b7d162b2: Already exists 
cb420a90068e: Pull complete 
2766c0bf2b07: Pull complete 
e05167b6a99d: Pull complete 
70ac9d795e79: Pull complete 
Digest: sha256:4cf620a5c81390ee209398ecc18e5fb9dd0f5155cd82adcbae532fec94006fb9
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
mysql        5.7       f07dfa83b528   5 days ago    448MB
nginx        latest    ae2feff98a0c   11 days ago   133MB
centos       latest    300e315adb2f   2 weeks ago   209MB

(2) 运行镜像

docker run -d --name nginx001 -p 3333:80 nginx

-d			 后台运行
--name		  给容器命名
-p 3333:80	  将宿主机的3333号端口映射到该容器的80号端口

运行结果

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d --name nginx001 -p 3333:80 nginx
20c896637ff5de8be835797109d62ee2465e28d9d716be5a8d550ef7d547fcf5
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
20c896637ff5   nginx     "/docker-entrypoint.…"   7 seconds ago   Up 5 seconds   0.0.0.0:3334->80/tcp   nginx001	

(3) 配置文件

进入容器后自定义配置文件

主配置文件 /etc/nginx/nginx.conf

html 页面配置文件 /usr/share/nginx/html/index.html

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker exec -it nginx001 /bin/bash
root@20c896637ff5:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@20c896637ff5:/# cd /etc/nginx
root@20c896637ff5:/etc/nginx# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params	uwsgi_params  win-utf

(4) 访问测试

本地主机访问测试,curl命令发起请求,如果使用阿里云服务器需要设置安全组

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
20c896637ff5   nginx     "/docker-entrypoint.…"   7 minutes ago   Up 7 minutes   0.0.0.0:3333->80/tcp   nginx001
[root@iZwz99sm8v95sckz8bd2c4Z ~]# curl localhost:3333
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>./>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

(5) 容器内安装 vim

使用Nginx往往需要编写配置文件,但是Nginx官方镜像没有安装vim,需要手动进行安装。使用以下命令进行安装:

apt-get install vim

如果执行上述命令出现提示:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package vim

则需要先同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包。执行以下命令来更新:

apt-get update	

更新完毕再安装即可。修改了配置文件,只要重新启动容器docker restart 容器id,改动就可以生效了

解决 vim 在终端不能复制的问题:

在 vim 中输入 :set mouse=r

6.2 部署 tomcat

(1) 下载镜像并运行

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
6c33745f49b4: Pull complete 
ef072fc32a84: Pull complete 
c0afb8e68e0b: Pull complete 
d599c07d28e6: Pull complete 
e8a829023b97: Pull complete 
d04be46a31d1: Pull complete 
db6007c69c35: Pull complete 
e4ad4c894bce: Pull complete 
248895fda357: Pull complete 
277059b4cba2: Pull complete 
Digest: sha256:57dae7dfb9b62a413cde65334c8a18893795cac70afc3be589c8336d8244655d
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -p 3334:8080 --name tomcat01 tomcat
7136295a6082cb0f805b025a1471bde02ead4864be3e2c9dcd337b1dde0a3113

(2) 进入容器

阿里云镜像默认下载的是最小的镜像,保证最小的运行环境

# 进入正在运行的容器
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker exec -it tomcat01 /bin/bash

root@7136295a6082:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work

root@7136295a6082:/usr/local/tomcat# cd webapps

root@7136295a6082:/usr/local/tomcat/webapps# ls

root@7136295a6082:/usr/local/tomcat/webapps# cp -r /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps/

root@7136295a6082:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

root@7136295a6082:/usr/local/tomcat/webapps# exit
exit

(3) 访问测试

[root@iZwz99sm8v95sckz8bd2c4Z ~]# curl localhost:3334

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/9.0.41</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

    <body>
        <div id="wrapper">
            <div id="navigation" class="curved container">
                <span id="nav-home"><a href="https://tomcat.apache.org/">Home</a></span>
                <span id="nav-hosts"><a href="/docs/">Documentation</a></span>
                <span id="nav-config"><a href="/docs/config/">Configuration</a></span>
                <span id="nav-examples"><a href="/examples/">Examples</a></span>
                <span id="nav-wiki"><a href="https://wiki.apache.org/tomcat/FrontPage">Wiki</a></span>
                <span id="nav-lists"><a href="https://tomcat.apache.org/lists.html">Mailing Lists</a></span>
                <span id="nav-help"><a href="https://tomcat.apache.org/findhelp.html">Find Help</a></span>
                <br class="separator" />
            </div>

! Docker容器使用问题:Failed to get D-Bus connection: Operation not permitted

使用centos7镜像创建容器后,在里面使用systemctl启动服务报错

# docker run -itd --name centos7 centos:7

# docker attach centos7

# yum install vsftpd

# systemctl start vsftpd

Failed to get D-Bus connection: Operation not permitted

// 不能启动服务

Docker的设计理念是在容器里面不运行后台服务,容器本身就是宿主机上的一个独立的主进程,也可以间接的理解为就是容器里运行服务的应用进程。一个容器的生命周期是围绕这个主进程存在的,所以正确的使用容器方法是将里面的服务运行在前台

解决方案 以特权模式运行容器
创建容器:

# docker run -d --name centos7 --privileged=true centos:7 /usr/sbin/init

进入容器:

# docker exec -it centos7 /bin/bash

这样可以使用systemctl启动服务了

7. Docker 镜像 详解

7.1 什么是镜像

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件

所有的应用,直接打包 docker 镜像,就可以直接运行起来

7.2 docker 镜像 加载原理

docker 的镜像 实际由一层一层的文件系统组成,这种层级的文件系统是 UnionFS 联合文件系统

UnionFS(联合文件系统),是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union 文件系统 是 docker 镜像的基础,镜像可以通过分层来继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
	特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

7.3 镜像的分层

[root@localhost ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
72a69066d2fe: Pull complete 
93619dbc5b36: Pull complete 
99da31dd6142: Pull complete 
626033c43d70: Pull complete 
37d5d7efb64e: Pull complete 
ac563158d721: Pull complete 
d2ba16033dad: Pull complete 
688ba7d5c01a: Pull complete 
00e060b6d11d: Pull complete 
1c04857f594f: Pull complete 
4d7cfa90e6ea: Pull complete 
e0431212d27d: Pull complete 
Digest: sha256:e9027fe4d91c0153429607251656806cc784e914937271037f7738bd5b8e7709
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest

镜像分层的特点:
	资源共享,如有多个镜像都从相同的 Base 镜像 构建而来,那么宿主机只需在磁盘上保留一份 base 镜像,同时内存中也只需要加载一份 base 镜像,这样就可以为所有的容器服务,而且镜像的每一层都可以被共享

利用 docker image inspect 命令 可以查看镜像的元数据,其中包括镜像的分层信息(“RootFS” 段信息)

[root@localhost ~]# docker image inspect nginx
[
    {
        "Id": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
        "RepoTags": [
            "nginx:latest"
        ],
        "RepoDigests": [
            "nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-12-29T19:28:29.892199479Z",
        "Container": "ca3e48389f7160bc9d9a892d316fcbba459344ee3679998739b1c3cd8e56f7da",
        "ContainerConfig": {
            "Hostname": "ca3e48389f71",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.5",
                "NJS_VERSION=0.7.1",
                "PKG_RELEASE=1~bullseye"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
            ],
            "Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers "
            },
            "StopSignal": "SIGQUIT"
        },
        "DockerVersion": "20.10.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.5",
                "NJS_VERSION=0.7.1",
                "PKG_RELEASE=1~bullseye"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers "
            },
            "StopSignal": "SIGQUIT"
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 141479488,
        "VirtualSize": 141479488,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/0844f5dd75390fc20bd9414132f96a28e4ee36d9428ce2d6e00938c9bb99e2c2/diff:/var/lib/docker/overlay2/2b4d92b2c834b589506ca935f3f78e0f2c2a260157a4801ca6d4d61d1490b69d/diff:/var/lib/docker/overlay2/b2472912de17ec9ae405c2bf1806f7b017d517020305e92d016ff71187f36fa1/diff:/var/lib/docker/overlay2/b31d7226f8b6b509c35ede14f41e2ad706d43cfb84c969874a8293b41a2d00e3/diff:/var/lib/docker/overlay2/0d637b215441c7b80e10df15e534ab20d1d1f644df2f46f45b8d6533e8366673/diff",
                "MergedDir": "/var/lib/docker/overlay2/8d65a322e97adbeaff3230c826b53fb8f942d89a73bb80546e0092301b2f1935/merged",
                "UpperDir": "/var/lib/docker/overlay2/8d65a322e97adbeaff3230c826b53fb8f942d89a73bb80546e0092301b2f1935/diff",
                "WorkDir": "/var/lib/docker/overlay2/8d65a322e97adbeaff3230c826b53fb8f942d89a73bb80546e0092301b2f1935/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
               "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",                "sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8",
               "sha256:b8d6e692a25e11b0d32c5c3dd544b71b1085ddc1fddad08e68cbd7fda7f70221",
               "sha256:f1db227348d0a5e0b99b15a096d930d1a69db7474a1847acbc31f05e4ef8df8c",
               "sha256:32ce5f6a5106cc637d09a98289782edf47c32cb082dc475dd47cbf19a4f866da",
                "sha256:d874fd2bc83bb3322b566df739681fbd2248c58d3369cb25908d68e7ed6040a6"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

7.3.1 分层解析

所有的 docker 镜像 都起始于一个基础镜像曾,当进行修改过增加心得内容时,就会在当前镜像曾之上,创建心得镜像层
	如:基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像得第一层,如果在该镜像中添加 Python 包,就会在基础镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层

在添加额外的镜像层的同时,镜像始终会保持当前所有镜像的组合,即镜像内的文件总个数不变
正常情况下,上层镜像层中的文件覆盖了底层镜像层中的文件,这样就使得文件的更新版本作为一个新镜像层添加到镜像当中

特点

docker 镜像都是只读的(通过 docker pull 远程下载的镜像都是只读的),当容器启动时(docker run),一个新的可写层就会被加载到 docker 原镜像的顶部,这一层就是容器层,容器之下的都叫镜像层,用户在该容器内所作的所有操作都会被保存到容器层内,最后通过 (容器层加镜像层) 的方式将所有文件都合成为一个大的完整的镜像并可发布

7.4 提交镜像

docker commit 提交容器成为一个新的副本

# 命令与 git 原理 类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG](tag名 即 版本号)

7.4.1 提交测试

(1) 启动一个官方 tomcat 镜像

[root@localhost ~]# docker run -d -p 3334:8080 tomcat
328380092e812711f1022c31cf6f64105776245a91e903b1c4ed10734c18725e

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
328380092e81   tomcat    "catalina.sh run"   4 seconds ago   Up 2 seconds   0.0.0.0:3334->8080/tcp, :::3334->8080/tcp   zealous_kare

(2) 发现这个默认的 tomcat 没有 webapps 应用(官方镜像默认 webapps 下没有文件)

[root@localhost ~]# docker exec -it 328380092e81 /bin/bash

root@328380092e81:/usr/local/tomcat# pwd
/usr/local/tomcat

root@328380092e81:/usr/local/tomcat# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE	NOTICE	README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  native-jni-lib  temp  webapps  webapps.dist  work

root@328380092e81:/usr/local/tomcat# cd webapps

root@328380092e81:/usr/local/tomcat/webapps# ls

(3) 手动将 webapps.dist 下的文件递归拷贝至 webapps 目录下

root@328380092e81:/usr/local/tomcat/webapps# cp -r /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps/

root@328380092e81:/usr/local/tomcat/webapps# pwd
/usr/local/tomcat/webapps

root@328380092e81:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager

(4) 将操作过的容器通过 commit 提交为一个新的镜像

root@328380092e81:/usr/local/tomcat/webapps# read escape sequence

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
328380092e81   tomcat    "catalina.sh run"   4 minutes ago   Up 4 minutes   0.0.0.0:3334->8080/tcp, :::3334->8080/tcp   zealous_kare

[root@localhost ~]# docker commit -a='slh' -m='add webapps/' 328380092e81 new_tomcat:0.1
sha256:600afb6991ab7a9c4728847344dac06d8830a839e7b6bc842dd32bb9584c1c4b

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
328380092e81   tomcat    "catalina.sh run"   6 minutes ago   Up 6 minutes   0.0.0.0:3334->8080/tcp, :::3334->8080/tcp   zealous_kare

[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
new_tomcat    0.1       600afb6991ab   9 seconds ago   684MB
nginx         latest    605c77e624dd   5 weeks ago     141MB
tomcat        latest    fb5657adc892   6 weeks ago     680MB
mysql         latest    3218b38490ce   6 weeks ago     516MB
hello-world   latest    feb5d9fea6a5   4 months ago    13.3kB
centos        latest    5d0da3dc9764   4 months ago    231MB

(5) 运行提交的新镜像

[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
new_tomcat    0.1       600afb6991ab   5 minutes ago   684MB
nginx         latest    605c77e624dd   5 weeks ago     141MB
tomcat        latest    fb5657adc892   6 weeks ago     680MB
mysql         latest    3218b38490ce   6 weeks ago     516MB
hello-world   latest    feb5d9fea6a5   4 months ago    13.3kB
centos        latest    5d0da3dc9764   4 months ago    231MB

[root@localhost ~]# docker run -d -p 3334:8080 --name tomcat01 new_tomcat:0.1
dba99ef64d83c511aa0aa1cb4af8bcbe4776516f639a02870b1302e15854f85d

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE            COMMAND             CREATED         STATUS         PORTS                                       NAMES
dba99ef64d83   new_tomcat:0.1   "catalina.sh run"   6 seconds ago   Up 6 seconds   0.0.0.0:3334->8080/tcp, :::3334->8080/tcp   tomcat01

(6) 镜像的导入和导出

利用 docker save 和 docker load 命令可实现镜像的导入和导出

将 ubuntu:lastest 镜像导出生成 ubuntu.tar 文件
	docker save -o ubuntu.tar ubuntu:lastest

将 ubuntu.tar 文件导入
	docker load --input ubuntu.tar

8. 图形化管理工具 Portaninter 安装

Portaninter 是 docker 的图形化管理工具,类似的还有 Rancher

[root@localhost ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
Unable to find image 'portainer/portainer:latest' locally
latest: Pulling from portainer/portainer
94cfa856b2b1: Pull complete 
49d59ee0881a: Pull complete 
a2300fd28637: Pull complete 
Digest: sha256:fb45b43738646048a0a0cc74fcee2865b69efde857e710126084ee5de9be0f3f
Status: Downloaded newer image for portainer/portainer:latest
201ad0ff46926abf339092bebc54c2700bdccb05caadaf6ca7a55fb8a7c128cd

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND        CREATED          STATUS          PORTS                                       NAMES
201ad0ff4692   portainer/portainer   "/portainer"   24 seconds ago   Up 23 seconds   0.0.0.0:8088->9000/tcp, :::8088->9000/tcp   kind_babbage

9. 容器数据卷

docker 将应用和环境打包成一个镜像,那么将容器删除,容器内的数据也会丢失,需求:数据可以持久化

容器之间可以有一个数据共享的技术,docker 容器中产生的数据,可以同步到本地,也就是卷技术,相当于是将 linux 系统内的文件目录与容器内的目录双向绑定

9.1 文件挂载方式

通过查看容器的元数据来查看容器的挂载信息

[root@localhost test]# docker inspect centos01

"Mounts": [                                      // 挂载 -v
            {
                "Type": "bind",
                "Source": "/home/test",          // 宿主机的文件地址 
                "Destination": "/home",          // 容器内的文件地址
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

直接使用命令来挂载 -v

docker run -it -v 宿主机目录:容器内目录
// 宿主机的本地目录必须是绝对路径,如果宿主机中不存在该目录,则 docker 会自动创建该目录

[root@localhost ~]# docker run -it -v /home/test:/home --name centos01 centos /bin/bash

[root@66283c54c2d8 /]# cd /home
[root@66283c54c2d8 home]# ls
[root@66283c54c2d8 home]# 

在容器内的 home 目录下创建文件,退回到宿主机上查看挂载目录
[root@66283c54c2d8 /]# cd /home
[root@66283c54c2d8 home]# ls
[root@66283c54c2d8 home]# touch test.html

[root@localhost home]# pwd
/home
[root@localhost home]# ls
test
[root@localhost home]# cd test/
[root@localhost test]# ls
test.html

在宿主机的文件内写入内容,再进入容器内的文件里查看
[root@localhost test]# pwd
/home/test
[root@localhost test]# ll
总用量 0
-rw-r--r-- 1 root root 0 212 13:45 test.html
[root@localhost test]# vim test.html 
[root@localhost test]# more test.html 
docker run -it -v /home/test:/home --name centos01 centos /bin/bash

[root@localhost test]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED         STATUS         PORTS     NAMES
66283c54c2d8   centos    "/bin/bash"   7 minutes ago   Up 7 minutes             centos01
[root@localhost test]# docker attach centos01
[root@66283c54c2d8 home]# ls
test.html
[root@66283c54c2d8 home]# more test.html 
docker run -it -v /home/test:/home --name centos01 centos /bin/bash
1. 停止容器
[root@localhost test]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
66283c54c2d8   centos    "/bin/bash"   15 minutes ago   Up 15 minutes             centos01
[root@localhost test]# docker attach centos01
[root@66283c54c2d8 home]# exit
exit
[root@localhost test]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

2. 宿主机上修改文件
[root@localhost test]# pwd
/home/test
[root@localhost test]# ll
总用量 4
-rw-r--r-- 1 root root 68 212 13:50 test.html
[root@localhost test]# vim test.html 
[root@localhost test]# more test.html 
test again

3. 启动容器
[root@localhost test]# docker start centos01
centos01
[root@localhost test]# docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS         PORTS     NAMES
66283c54c2d8   centos    "/bin/bash"   20 minutes ago   Up 2 seconds             centos01

4. 容器内的数据依旧是同步的
[root@localhost test]# docker attach centos01
[root@66283c54c2d8 /]# cd /home/
[root@66283c54c2d8 home]# ls
test.html
[root@66283c54c2d8 home]# more test.html 
test again

9.2 安装 MySQL 并建立数据卷同步技术

在Linux下的MySQL默认的数据文档存储目录为/var/lib/mysql,默认的配置文件的位置/etc/mysql/conf.d,为了预防MySQL镜像或容器删除后,造成的数据丢失,下面建立数据卷保存MySQL的数据和文件

# 宿主机内启动镜像,建立两个配置文件的数据卷
[root@localhost ~]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql
367f1d89e8a35813c777dbd8f98a78f41fc01912259ae34f9414615a77faa424

# 查看容器
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
367f1d89e8a3   mysql     "docker-entrypoint.s…"   3 seconds ago   Up 2 seconds   33060/tcp, 0.0.0.0:3310->3306/tcp, :::3310->3306/tcp   mysql01

# 宿主机内查看文件
[root@localhost ~]# cd /home/
[root@localhost home]# ls
mysql  
[root@localhost home]# cd mysql/
[root@localhost mysql]# ls
conf  data
[root@localhost mysql]# cd conf/
[root@localhost conf]# ls
[root@localhost conf]# cd ..
[root@localhost mysql]# cd data/
[root@localhost data]# ls
auto.cnf       binlog.index  client-cert.pem    #ib_16384_1.dblwr  ib_logfile0  #innodb_temp  performance_schema  server-cert.pem  undo_001
binlog.000001  ca-key.pem    client-key.pem     ib_buffer_pool     ib_logfile1  mysql         private_key.pem     server-key.pem   undo_002
binlog.000002  ca.pem        #ib_16384_0.dblwr  ibdata1            ibtmp1       mysql.ibd     public_key.pem      sys

# 查看容器
[root@localhost data]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
367f1d89e8a3   mysql     "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   33060/tcp, 0.0.0.0:3310->3306/tcp, :::3310->3306/tcp   mysql01

# 进入容器
[root@localhost data]# docker exec -it mysql01 /bin/bash

# 容器内登录 mysql
root@367f1d89e8a3:/# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.27 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> create database test;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> exit
Bye
root@367f1d89e8a3:/# read escape sequence

# 退回到宿主机后进入挂载目录内查看文件
[root@localhost data]# pwd
/home/mysql/data

# 容器内的 mysql 中创建的 test库 已同步
[root@localhost data]# ls
auto.cnf       binlog.index  client-cert.pem    #ib_16384_1.dblwr  ib_logfile0  #innodb_temp  performance_schema  server-cert.pem  test
binlog.000001  ca-key.pem    client-key.pem     ib_buffer_pool     ib_logfile1  mysql         private_key.pem     server-key.pem   undo_001
binlog.000002  ca.pem        #ib_16384_0.dblwr  ibdata1            ibtmp1       mysql.ibd     public_key.pem      sys              undo_002

# 此时将部署 mysql 的容器删除,再回到宿主机的挂载目录中查看,数据库的数据依然存在
[root@localhost data]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
367f1d89e8a3   mysql     "docker-entrypoint.s…"   5 minutes ago   Up 5 minutes   33060/tcp, 0.0.0.0:3310->3306/tcp, :::3310->3306/tcp   mysql01

[root@localhost test]# docker stop mysql01
mysql01
[root@localhost test]# docker rm mysql01
mysql01

[root@localhost test]# cd /home/mysql/data/
[root@localhost data]# ls
auto.cnf       binlog.index  client-cert.pem    #ib_16384_1.dblwr  ib_logfile0   mysql               private_key.pem  server-key.pem  undo_001
binlog.000001  ca-key.pem    client-key.pem     ib_buffer_pool     ib_logfile1   mysql.ibd           public_key.pem   sys             undo_002
binlog.000002  ca.pem        #ib_16384_0.dblwr  ibdata1            #innodb_temp  performance_schema  server-cert.pem  test

9.3 数据卷常用命令

1. 创建数据卷
docker volume create 数据卷名
2. 查看所有的数据卷
docker volume ls
3. 查看指定数据卷的信息
docker volume inspect 数据卷名
4. 删除数据卷
docker volume rm 数据卷名
// 只有当没有任何容器使用数据卷时,该数据卷才会被删除
5. 删除容器时删除相关的卷
docker rm -v ...
docker run --rm		// --rm 参数 会在容器停止运行时删除容器及容器所挂载的数据卷
6. 无主的数据卷可能会占据很多控件,清理时的命令
docker volume prune

9.4 Dockerfile 中设置数据卷

可以在 Dockerfile 中使用 VOLUME 指令来给镜像添加一个或多个数据卷

// 使用 VLOUME 指令向容器中添加数据卷
VOLUME /data
// 在利用 docker build 命令 生成镜像后并以该镜像启动容器时,会挂载一个数据卷到 /data 命令下,如果镜像中存在 /data 命令,则该目录中的内容将全部被复制到宿主机中对应的目录中,也可以使用 VOLUME 指令 添加多个数据卷
VOLUME ["/data1","data2"]
# 使用 Dockerfile 构建一个新的镜像,dockerfile01文件的内容,匿名挂载了 volume01 和 volume02 两个目录
	FROM centos
	VOLUME ["volume01","volume02"]
	CMD echo "----end----"
	CMD /bin/bash
	
# 执行构建镜像
	[root@iZwz99sm8v95sckz8bd2c4Z docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile01 -t ethan/centos:1.0 .
	[root@iZwz99sm8v95sckz8bd2c4Z docker-test-volume]# docker images
	REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
	ethan/centos          1.0       1df90e6fd790   13 minutes ago   209MB
	mytomcat              1.0       f189aac861de   25 hours ago     653MB
	mysql                 5.7       f07dfa83b528   7 days ago       448MB
	tomcat                latest    feba8d001e3f   11 days ago      649MB
	nginx                 latest    ae2feff98a0c   13 days ago      133MB
	centos                latest    300e315adb2f   3 weeks ago      209MB
	portainer/portainer   latest    62771b0b9b09   5 months ago     79.1MB
	elasticsearch         7.6.2     f29a1ee41030   9 months ago     791MB
	
# 完成镜像的生成后,启动自己生成的容器
[root@iZwz99sm8v95sckz8bd2c4Z docker-test-volume]# docker run -it 1df90e6fd790 /bin/bash
[root@828d43dba78e /]# ls -l
drwxr-xr-x   2 root root 4096 Dec 29 15:41 volume01
drwxr-xr-x   2 root root 4096 Dec 29 15:41 volume02

9.5 通过数据卷实现容器间的数据同步(数据卷容器,备份)

如果用户需要在多个容器之间共享一些持久化的数据,则可以使用数据卷容器,数据卷容器是一个容器,专门用于提供数据卷供其他容器挂载

数据卷容器操作的思想:定制生成一个容器来挂载某个沐浴露,该容器并不需要运行,其他容器可以利用 --volumes-from 命令来挂载

利用前写的 Dockerfile 文件,首先启动容器1,volume01、volume02为挂载目录

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -it --name centos01 ethan/centos:1.0
[root@731d53b8c3d5 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01	volume02

然后启动容器2,通过参数--volumes-from,设置容器2和容器1建立数据卷挂载关系

[root@iZwz99sm8v95sckz8bd2c4Z /]# docker run -it --name centos02 --volumes-from centos01 ethan/centos:1.0
[root@7f90d4147511 /]# ls -l
total 56
lrwxrwxrwx   1 root root    7 Nov  3 15:22 bin -> usr/bin
drwxr-xr-x   5 root root  360 Dec 30 14:58 dev
drwxr-xr-x   1 root root 4096 Dec 30 14:58 etc
drwxr-xr-x   2 root root 4096 Nov  3 15:22 home
lrwxrwxrwx   1 root root    7 Nov  3 15:22 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3 15:22 lib64 -> usr/lib64
drwx------   2 root root 4096 Dec  4 17:37 lost+found
drwxr-xr-x   2 root root 4096 Nov  3 15:22 media
drwxr-xr-x   2 root root 4096 Nov  3 15:22 mnt
drwxr-xr-x   2 root root 4096 Nov  3 15:22 opt
dr-xr-xr-x 108 root root    0 Dec 30 14:58 proc
dr-xr-x---   2 root root 4096 Dec  4 17:37 root
drwxr-xr-x  11 root root 4096 Dec  4 17:37 run
lrwxrwxrwx   1 root root    8 Nov  3 15:22 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3 15:22 srv
dr-xr-xr-x  13 root root    0 Dec 29 15:41 sys
drwxrwxrwt   7 root root 4096 Dec  4 17:37 tmp
drwxr-xr-x  12 root root 4096 Dec  4 17:37 usr
drwxr-xr-x  20 root root 4096 Dec  4 17:37 var
drwxr-xr-x   2 root root 4096 Dec 30 14:54 volume01
drwxr-xr-x   2 root root 4096 Dec 30 14:54 volume02

# volume01,volume02 两个数据卷目录已同步

首先在容器2中的volume01中添加文件

[root@7f90d4147511 /]# cd volume01
[root@7f90d4147511 volume01]# touch test
[root@7f90d4147511 volume01]# ls
test

然后就可以看到容器1的文件也会添加上了,仅有两个数据卷目录下的文件可实现容器间的数据同步,其他目录文件不可以

同步两个MySQL的数据库和配置文件,与上面的操作相同,首先建立数据卷,然后给另一个MySQL容器建立容器数据卷挂载

[root@iZwz99sm8v95sckz8bd2c4Z home]# docker run -d -p 6603:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

[root@iZwz99sm8v95sckz8bd2c4Z home]# docker run -d -p 6604:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

10. Dockerfile

10.1 Dockerfile 介绍

Dockerfile 是用来构建 Docker 镜像的文本文件,也可以说是命令参数脚本docker build命令用于从 Dockerfile 中构建镜像,可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile

Docker 镜像发布的步骤:

  1. 编写一个 dockerfile 文件
  2. docker build 构建成为一个镜像
  3. docker run 镜像
  4. docker push 镜像 (发布镜像到 DockerHub、阿里云镜像仓库)

关于 Dockerfile 文件的注意点:

  1. 每个保留关键字(指令)都必须是大写

  2. 文件中的指令从上到下顺序执行,第一个指令必须是 FROM

  3. 每一个指令都会创建提交一个新的镜像层并提交

10.2 Dockerfile 指令说明

指令 说明
FROM FROM 指定基础镜像(必填)
MAINTAINER 声名镜像作者(姓名+邮箱)
RUN RUN 镜像构建时需要运行的命令
CMD 指定这个容器启动时要运行的命令(只有最后一个会生效)
ENTRYPOINT ENTRYPOINT 指定这个容器启动时要运行的命令,可以追加命令
ENV ENV 设置环境变量
ADD ADD … 将本地文件添加到容器中,将添加后的文件自动解压
COPY 功能类似ADD,但不会自动解压文件,不能访问网络资源
VOLUME VOLUME 可实现挂载功能,将本地文件或其他容器的文件挂载到某容器中
EXPOSE EXPOSE <端口1> 用于声明运行时的容器服务端口
WORDDIR WORDDIR <工作目录> 用于设置容器的工作目录

10.3 通过 Dockerfile 构建一个 centos镜像

通过编写 Dockerfile 文件来制作 centos 镜像,并在官方镜像的基础上添加 vim 和 net-tools 工具,首先在 /home 目录下新建 mydockerfile-centos 文件没然后使用上述指令编写该文件

[root@bogon home]# cat mydockerfile-centos
# 基础镜像
FROM centos:7
# 作者姓名+邮箱
MAINTAINER s<1205294754@qq.com>
# 环境变量
ENV MYPATH /user/local
# 工作目录,登录容器后默认进入该目录
WORKDIR @MYPATH
# 构建镜像时需要运行的命令
RUN yum install openssh-server net-tools vim -y
# 构建镜像时需要暴露的端口
EXPOSE 21 
EXPOSE 22
EXPOSE 80
EXPOSE 3306

CMD echo $MYPATH
CMD /bin/bash
[root@bogon home]# docker build -f mydockerfile-centos -t mycentos:0.1 .
Successfully built 288438e49c09
Successfully tagged mycentos:0.1

[root@bogon home]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
mycentos              0.1       288438e49c09   27 seconds ago   570MB

另外可以通过docker history 容器id命令来查看镜像的构建步骤

[root@bogon home]# docker history mycentos:0.1 
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
288438e49c09   3 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "/bin…   0B        
85535d1dd3a0   3 minutes ago   /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "echo…   0B        
4b4688eeadb2   3 minutes ago   /bin/sh -c #(nop)  EXPOSE 3306                  0B        
7c179e6f9fff   3 minutes ago   /bin/sh -c #(nop)  EXPOSE 80                    0B        
a7ea18e51f1d   3 minutes ago   /bin/sh -c #(nop)  EXPOSE 22                    0B        
530468f5823b   3 minutes ago   /bin/sh -c #(nop)  EXPOSE 21                    0B        
cc62de051517   3 minutes ago   /bin/sh -c yum install vim -y                   210MB     
d3eea6ea9c0e   4 minutes ago   /bin/sh -c yum install net-tools -y             156MB     
2e5cc94e8a1b   5 minutes ago   /bin/sh -c #(nop) WORKDIR /usr/local            0B        
f71b45fa6ebb   5 minutes ago   /bin/sh -c #(nop)  ENV MYPATH=/usr/local        0B        
441a81382478   5 minutes ago   /bin/sh -c #(nop)  MAINTAINER s<1205294754@q0B        
eeb6ee3f44bd   5 months ago    /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      5 months ago    /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      5 months ago    /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB  

11. 发布自己的镜像

DockHub

地址 https://hub.docker.com/ 注册个人账号

在宿主机上提交本地镜像

[root@bogon ~]# docker login --help

Usage:  docker login [OPTIONS] [SERVER]

Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.

Options:
  -p, --password string   Password
      --password-stdin    Take the password from stdin
  -u, --username string   Username

[root@bogon ~]# docker login -u windex120
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

登录完毕后,利用 docker push 命令 提交镜像

[root@bogon ~]# docker push nginx-image:0.1 
The push refers to repository [docker.io/library/nginx-image]
59121ac32162: Preparing 
bd34336b82a1: Preparing 
ed1673be73ef: Preparing 
174f56854903: Preparing 
denied: requested access to the resource is denied
// 上传连接被拒绝,push 本地镜像时需要加上作者名

[root@bogon ~]# docker push windex120/nginx-image:0.1
The push refers to repository [docker.io/windex120/nginx-image]
An image does not exist locally with the tag: windex120/nginx-image
// 提示本地镜像有问题
// 解决方法:给该镜像添加一个 tag

[root@bogon ~]# docker tag 309caa66f807 windex120/nginx-image:0.1
[root@bogon ~]# docker images
REPOSITORY              TAG       IMAGE ID       CREATED          SIZE
nginx-image             0.1       309caa66f807   30 minutes ago   479MB
windex120/nginx-image   0.1       309caa66f807   30 minutes ago   479MB

[root@bogon ~]# docker push windex120/nginx-image:0.1

[root@bogon ~]# docker push windex120/nginx-image:0.1
The push refers to repository [docker.io/windex120/nginx-image]
59121ac32162: Pushed 
bd34336b82a1: Pushed 
ed1673be73ef: Pushed 
174f56854903: Pushed 
0.1: digest: sha256:41614028e42f54a240c7efa117ce066ada30df58cb5126620ae95fcdeb819580 size: 1160
 
 // 提交成功

12. Docker 网络

12.1 docker 网络模式

当使用 docker run 命令创建 docker 容器时,可以使用 --net 选项指定容器的网络模式,docker 有以下 4 种 网络模式:

  • host 模式,使用 --net=host 指定

  • container 模式,使用 --net=conatiner:NAME_or_ID 指定

  • none 模式:使用 --net=none 指定

  • bridge 模式:使用 --net=bridge 指定,是 docker 容器的默认设置

host 模式

容器不会虚拟出网卡并配置 IP 地址,而是使用宿主机的 IP 地址和端口

[root@bogon Nginximage]# docker run -itd --net=host --name centos01 mycentos:0.1

[root@bogon Nginximage]# docker attach centos01

[root@bogon local]# ifconfig 
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:8fff:fe3b:28b  prefixlen 64  scopeid 0x20<link>
        ether 02:42:8f:3b:02:8b  txqueuelen 0  (Ethernet)
        RX packets 17163  bytes 697379 (681.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 19459  bytes 82883190 (79.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.154.101  netmask 255.255.255.0  broadcast 192.168.154.255		// 宿主机的 IP
        inet6 fe80::b6ce:ef2c:f233:5ed4  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:fa:8b:2e  txqueuelen 1000  (Ethernet)
        RX packets 307980  bytes 249384363 (237.8 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 171928  bytes 251783207 (240.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

// 退出容器后,在宿主机内查看容器的元数据
[root@bogon Nginximage]# docker inspect centos01
"Networks": {
                "host": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "f306fe51af11ed4f88a584bd74b548f44870c83e3388df3e16367fd12c8ee274",
                    "EndpointID": "3904ccc3a65dddeb91ae5869810b22b0d51ac842dcbcfda18e334e02e226d568",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }

none 模式

该模式下,docker 容器 不会进行任何网络配置(关闭了容器的网络功能),此时的容器内没有网卡,IP 地址,路由等信息

[root@bogon Nginximage]# docker run -itd --name centos02 --net=none mycentos:0.1
    
[root@bogon Nginximage]# docker attach centos02
    
[root@c41fee83afe6 local]# ifconfig 
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

// 退出容器后,在宿主机内查看容器的元数据
[root@bogon Nginximage]# docker inspect centos02
 "Networks": {
                "none": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "841c3c72f8e93ff71bf90547e7d0c7c0b9c1069260a0a2c6943bba5cf8679cfa",
                    "EndpointID": "2c1274fb91e5ad3c19cbd3a9ccb1db73db7fb53ab6ee1868ecb0b6df98ed3e12",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 0,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "",
                    "DriverOpts": null
                }
            }

12.2 单向通信 --link

[root@bogon Nginximage]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
mycentos      0.1       288438e49c09   3 days ago     570MB

[root@bogon Nginximage]# docker run -itd --name mycentos mycentos:0.1 
[root@bogon Nginximage]# docker run -itd --name centos01 --link mycentos mycentos:0.1 
[root@bogon Nginximage]# docker run -itd --name centos02 --link mycentos mycentos:0.1 
    
[root@bogon Nginximage]# docker attach centos01

[root@86c37874c0c6 local]# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 16  bytes 1261 (1.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 14  bytes 782 (782.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 4  bytes 448 (448.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4  bytes 448 (448.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@86c37874c0c6 local]# ping 172.17.0.1					// ping 通 mycentos 容器
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.047 ms

[root@86c37874c0c6 local]# ping 172.17.0.2					// ping 通 centos02 容器
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.073 ms

// 单向通信,只能是 centos01 和 centos02 可以直接 ping 通 mycentos 容器
[root@86c37874c0c6 local]# ping mycentos
PING mycentos (172.17.0.2) 56(84) bytes of data.
64 bytes from mycentos (172.17.0.2): icmp_seq=1 ttl=64 time=0.100 ms

[root@86c37874c0c6 local]# ping centos02
ping: centos02: Name or service not known

12.3 创建桥接网络实现容器间的双向通信

// 创建一个桥接网络,将需要互相通信的容器都连接到该桥接网络中,即可实现容器之间的双向通信
 
[root@bogon Nginximage]# docker network create -d bridge my_bridge
0aadd8bc0b7fcb8c79a945b92119093dc9c63fdf7074ef5c4ee0c64567fc0814

[root@bogon Nginximage]# docker network ls
NETWORK ID     NAME        DRIVER    SCOPE
7bf687ce6728   bridge      bridge    local
f306fe51af11   host        host      local
0aadd8bc0b7f   my_bridge   bridge    local
841c3c72f8e9   none        null      local

[root@bogon Nginximage]# docker run -itd --name centos01  mycentos:0.1 
[root@bogon Nginximage]# docker run -itd --name centos02  mycentos:0.1 
    
[root@bogon Nginximage]# docker network connect my_bridge centos01
[root@bogon Nginximage]# docker network connect my_bridge centos02
    
[root@bogon Nginximage]# docker attach centos01
    
[root@86c37874c0c6 local]# ping centos02
PING centos02 (172.18.0.3) 56(84) bytes of data.
64 bytes from centos02.my_bridge (172.18.0.3): icmp_seq=1 ttl=64 time=0.045 ms

[root@bogon Nginximage]# docker attach centos02
    
[root@86c37874c0c6 local]# ping centos01
PING centos02 (172.18.0.3) 56(84) bytes of data.
64 bytes from centos01.my_bridge (172.18.0.2): icmp_seq=1 ttl=64 time=0.045 ms
    
// 删除 my_bridge 桥接网络
[root@bogon Nginximage]# docker network rm my_bridge 
my_bridge
    
[root@bogon Nginximage]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
7bf687ce6728   bridge    bridge    local
f306fe51af11   host      host      local
841c3c72f8e9   none      null      local

12.4 更改 docker0 默认网桥的 IP 段

Docker 服务启动后默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络

Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置

[root@localhost ~]# vim /etc/docker/daemon.json

// 修改文件 /etc/docker/daemon.json 添加内容 "bip": "ip/netmask" [ 切勿与宿主机同网段 ]
{
# "registry-mirrors": ["https://beloqm8e.mirror.aliyuncs.com"]	// 原有默认的docker0 IP 网段,172.17.0.1
  "bip": "192.168.100.1/24"
}

// 重启 docker 服务
[root@localhost ~]# systemctl status docker
[root@localhost ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 四 2022-03-10 08:52:16 CST; 7s ago

12.5 创建网络/容器时指定 IP

// 创建网络时指定 IP 段 子网掩码 默认网关
[root@bogon ~]# docker network create -d bridge --subnet 192.168.200.0/24  --gateway 192.168.200.2 test
e5ac0bafb4ac0e9f8922ac389c270500847b1303dfcfe8830d7da5cdb0ac2ccc

[root@bogon ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
44a4f2310dfc   bridge    bridge    local
f306fe51af11   host      host      local
841c3c72f8e9   none      null      local
e5ac0bafb4ac   test      bridge    local

[root@bogon ~]# docker network inspect test
"IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.200.0/24",
                    "Gateway": "192.168.200.1"
                }
            ]
        },

// -------------------------------------------------------------
 
// 创建容器时手动直接指定容器 IP 地址
[root@bogon ~]# docker run -it --name centos01 --network test --ip 192.168.200.100 mycentos:0.1 
    
[root@5a7094a4c658 local]# ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.200.100  netmask 255.255.255.0  broadcast 192.168.200.255
        ether 02:42:c0:a8:c8:64  txqueuelen 0  (Ethernet)
        RX packets 17  bytes 1926 (1.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

13. Docker-compose 编排工具

compose 是 docker 官方的开源项目,其通过 YMAL 配置文件来创建和运行所有服务

13.1 compose 工具的安装与卸载

安装
# Docker Compose 目前托管到了 GitHub,需要前往 GitHub,由于存放在 GitHub,国内网络限制导致不太稳定,不推荐使用
	sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 推荐使用 道客 提供的 Docker 极速下载 进行安装
	curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
	
# 添加可执行权限
 
	chmod +x /usr/local/bin/docker-compose
 
# 测试安装结果
	docker-compose --version
# 通过 pip 安装 compose 工具

# 没有 python-pip 包时需执行命令
	yum install -y epel-release

# 安装 python2-pip
	yum install -y python2-pip
	
# 安装好之后更新 pip 工具
	pip install --upgrade pip
	
# 安装 compose 工具
	pip install docker-compose
	
# 测试安装结果
	docker-compose --version
卸载
卸载 compose 工具

如果是通过二进制包安装的,则删除二进制文件即可
	rm /usr/local/bin/docker-compose
	
如果是通过 pip 工具安装的,则可执行命令删除 compose 工具
	pip uninstall docker-compose

13.2 compose 常用命令

docker-compose 主命令 格式

docker-compose [-f <arg>...] [option] [command] [args]
-f	指定 compose 配置文件,默认为 docker-compose.yml
-p	指定项目名称,默认为目录名
列出容器 ps
// 列出所有运行的容器
docker-compose ps
    
    -q	只显示 ID
查看服务日志输出 logs
// 查看 nginx 的实时日志
docker-compose logs -f nginx
    
    -f,--follow		实时输出日志
    -t,--timestamps	显示时间戳
    --tail="all"	从日志末尾显示行
输出绑定的公共端口 port
// 输出 eureka 服务 8761 端口所绑定的公告端口
docker-compose port eureka 8761
重新构建服务 build
// 构建镜像或重新构建服务
docker-compose build 
    
    --no-cache			  不使用缓存构建镜像
    --build-arg key=val	  设置构建时变量
启动服务 start
// 启动指定服务已存在的容器
docker-compose start [容器名/容器ID]
停止服务 stop
// 停止指定服务已存在的容器
docker-compose stop [容器名/容器ID]
删除已停止服务的容器 rm
// 删除指定服务的容器
docker-compose rm [容器名/容器ID]
    
    -f,--force		强制删除
    -v				删除与容器相关的任何匿名卷
创建和启动容器 up
docker-compose up -d [容器名/容器ID]
    
    -d		后台运行
    -t		只当超时时间
    --build	启动容器并构建镜像
进入运行中的容器 exec
docker exec [容器名/容器ID] bash
    
    -d		后台运行
    -u		作为该用户运行该命令
其他管理命令
restart		重启服务
kill		停止指定服务的容器
pause		挂起容器
image		列出本地 docker 的镜像
down		停止容器和删除容器、网络、数据卷及镜像
create		创建一个服务
pull		下载镜像
push		推送镜像
help 		查看帮助文档

13.3 docker-compose.yml 文件

编写规则
// 版本
version: ''
    
// 服务
services:
	服务1: web
      images
      build
      network
      ......
    服务2: redis
      ......
    服务3: redis
      ......
        
// 其他配置,如 网络/卷,全局规则 等
volumes: ...
network: ...
configs: ...

13.4 docker-compose.yml 一键部署 WP 博客

// 创建 wordpress 目录 
[root@bogon home]# pwd
/home
    
[root@bogon home]# ll
总用量 4
drwxr-xr-x 2 root root  32 226 17:07 docker-compose-wordpress
drwxr-xr-x 2 root root  97 223 19:59 JAVAimage
-rw-r--r-- 1 root root 394 221 17:11 mydockerfile-centos
drwxr-xr-x 2 root root  81 224 19:02 Nginximage

[root@bogon home]# cd docker-compose-wordpress/

// 编写 docker-compose.yml 文件
version: "3.9"
    
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}

// 通过命令启动容器
[root@bogon home]# docker-compose up -d

// 成功启动后,通过 宿主机 IP 的 8000 端口 即可访问到 WP 安装页面
    
// 可以通过 docker-compse down 命令 停止并删除容器及 docker-compse images  中的相关镜像

14. docker swarm 编排工具

14.1 相关概念

swarm

集群的管理和编排使用了嵌入到 docker 引擎中的 SwarmKit,可以在 docker 初始化时启动 swarm 模式或者加入已存在的 swarm

节点

node 是加入 swarm 集群中的一个 docekr 引擎实体,可以在一台物理机上运行多个 node,node 可以分为 管理节点 manager节点工作节点 worker节点 两类

服务

服务是在工作节点上执行任务的定义,在工作节点上执行,创建服务时,需要指定容器镜像

任务

任务是指在 docker 容器中执行的命令,管理接待你根据指定数量的任务副本来分配任务给工作节点

14.2 swarm 常用命令

常用命令有 docker swarm , docker service , docker node

docker swarm 管理 swarm 集群

命令 说明
docker swarm init 初始化一个 swarm 集群
docker swarm join 加入集群作为工作节点或管理节点
docker swarm join-token 管理用于加入集群的令牌
docker swarm leave 离开 swarm 集群
docker swarm unlock 解锁 swarm 集群
docker swarm unlock-key 管理解锁钥匙
docker swarm update 更新 swarm 集群

docker service 管理服务

命令 说明
docker service create 创建服务(创建集群节点内的容器)
docker service inspect 显示一个或多个服务(容器)的详细信息
docker service logs 获取服务(容器)的日志
docker service ls 列出服务(容器)
docker service ps 查看指定服务(容器)的副本
docker service rm 删除服务(容器)
docker service scale 设置服务的数量(增删容器)
docker service update 更新服务
docker service rollback 恢复服务到更新之前的配置

docker node 管理 swarm 集群中的节点

命令 说明
docker node demote 从 swarm 集群管理器中降级一个或多个节点
docker node inspect 显示一个或多个节点的详细信息
docker node ls 列出 swarm 集群中的节点
docker node promote 将一个或多个节点加入集群管理器中
docker node ps 列出一个或多个在节点上运行的任务,默认为当前节点
docker node rm 从 swarm 集群中删除一个或多个节点
docker node update 更新一个节点

14.3 排空容器,删除节点

有时临时在 docker swarm 集群上增加节点(node3),过后需要删除节点

// 获取 node 信息
docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
j52o5frhmphiksqz0xq1mkbbh *   node1               Ready               Active              Leader              18.09.7
nq6v8dog0xzgpzx51x7bv59bp     node2               Ready               Active                                  18.09.7
6whtoqrhkzv3ax4xy9ab20gmy     node3               Ready               Active                                  18.09.7

// 让 node3 离开,排空 node3 的容器(在 master 上操作)
// 将 node3 节点设置为 drain 状态,这样当任务指派时就不会将任务分配给 node3 节点了
docker node update --availability drain 6whtoqrhkzv3ax4xy9ab20gmy

// 让 node3 主动离开集群,让节点处于down状态 (在 node3 上操作)
docker swarm leave

// 删除 node节点(在 master 上操作)
docker node rm 6whtoqrhkzv3ax4xy9ab20gmy

14.4 docker swarm 创建 nginx 集群

// 两台主机,分别作为 docker 节点 和 Ubuntu 节点,docker 节点 为 manager 节点,Ubuntu 节点 为 worker 节点

// docker 节点中 初始化 集群
[root@docker ~]# docker swarm init --advertise-addr 192.168.154.101
    
//利用 worker 令牌 将 Ubuntu 节点 加入 集群
[root@docker ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
fkjkch85itf95h59y8myn6nek *   docker     Ready     Active         Leader           20.10.12
j2akx13ibts8q7buz0gcmlk8b     ubuntu     Ready     Active                          20.10.12

// docker 节点 中 创建 overlay 网络
[root@docker ~]# docker network create -d overlay test
k2cxenbgc4mb17z6gxrjuo8pm
    
[root@docker ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
4ae2910457c9   bridge            bridge    local
f25d1ea5fac7   docker_gwbridge   bridge    local
f306fe51af11   host              host      local
ownjp1e7dy5m   ingress           overlay   swarm
841c3c72f8e9   none              null      local
k2cxenbgc4mb   test              overlay   swarm

// 在 docker 节点 的 swarm 中部署 nginx 服务,在 dokcer 节点 上创建一个副本数为 2 的 nginx 容器
[root@docker ~]# docker service create --replicas 2 --network test --name nginx -p 80:80 nginx
f6l2t4im4tlr9jef6jouzb2ew
overall progress: 2 out of 2 tasks 
1/2: running   [==================================================>] 
2/2: running   [==================================================>] 
verify: Service converged 
    
[root@docker ~]# docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
f6l2t4im4tlr   nginx     replicated   2/2        nginx:latest   *:80->80/tcp

// 利用 docker service ps 命令 查询指定服务在哪个节点运行 nginx 容器
[root@docker ~]# docker service ps nginx
ID        NAME    IMAGE      NODE      DESIRED STATE         CURRENT STATE      ERROR     PORTS
ev2kx8fj8k4q   nginx.1   nginx:latest   ubuntu    Running    Running about a minute ago             
3xg3iisxck01   nginx.2   nginx:latest   docker    Running    Running about a minute ago 

// 测试 ip 的 80 端口是否开启 nginx
[root@docker ~]# curl 192.168.154.101
[root@docker ~]# curl 192.168.154.222
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>./>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

// docker service 创建 tomcat 服务,默认运行在 docker 节点 上
[root@docker ~]# docker service create --replicas 1 --network test -p 8080:8080 java-image:v1 
image java-image:v1 could not be accessed on a registry to record
its digest. Each node will access java-image:v1 independently,
possibly leading to different nodes running different
versions of the image.

pvowylrtignegvoc5xnnscema
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 
    
[root@docker ~]# docker service ls
ID             NAME              MODE         REPLICAS   IMAGE           PORTS
pvowylrtigne   adoring_satoshi   replicated   1/1        java-image:v1   *:8080->8080/tcp
f6l2t4im4tlr   nginx             replicated   2/2        nginx:latest    *:80->80/tcp

[root@docker ~]# docker service ps adoring_satoshi
ID               NAME               IMAGE     NODE      DESIRED STATE   CURRENT STATE  ERROR     PORTS
yq3osrmkk8fz   adoring_satoshi.1 java-image:v1  docker    Running         Running 44 seconds ago     

// 测试 docker 节点 上的 tomcat 服务
[root@docker ~]# curl 192.168.154.101:8080

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.75</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

// 伸缩容器,将 tomcat 容器 扩展到 2个
// docker 节点 上 执行命令 
[root@docker ~]# docker service scale adoring_satoshi=2
adoring_satoshi scaled to 2
overall progress: 2 out of 2 tasks 
1/2: running   [==================================================>] 
2/2: running   [==================================================>] 
verify: Service converged 

// 查看 tomcat 容器 的 节点运行
[root@docker ~]# docker service ps adoring_satoshi
ID        NAME           IMAGE         NODE    DESIRED STATE   CURRENT STATE       ERROR      PORTS
yq3osrmkk8fz   adoring_satoshi.1       java-image:v1   docker    Running         Running 5 minutes ago                                      
yy8llkldi6xt   adoring_satoshi.2       java-image:v1   docker    Running         Running 29 seconds ago                                     
sa5j6mn8yfo1    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 35 seconds ago   "No such image: java-image:v1"   
340xfm6nirc3    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 40 seconds ago   "No such image: java-image:v1"   
34k6x1h8nzcb    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 45 seconds ago   "No such image: java-image:v1"   
euzxl08qbjcv    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 51 seconds ago   "No such image: java-image:v1"  
// 此时,Ubuntu 容器 的 8080 端口 也已成功开启 tomcat 服务    

// 至此,docker 节点 和 Ubuntu 节点 上的 nginx 和 tomcat 均已成功部署

14.5 节点宕机情况

如果一个节点出现了当即情况,则该节点会从 swarm 集群中被移出,利用 docker node ls 命令查看,此时,在宕机节点上运行的容器会被调度到其他节点上,以满足指定数量的副本保持运行状态

// 将 Ubuntu 节点 排空,把 Ubuntu 节点 的 blockchain 状态 改为 drain,而非 active
[root@docker ~]# docker node update --availability drain ubuntu 
ubuntu
    
[root@docker ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
fkjkch85itf95h59y8myn6nek *   docker     Ready     Active         Leader           20.10.12
j2akx13ibts8q7buz0gcmlk8b     ubuntu     Ready     Drain                           20.10.12

// 此时查看 swarm 集群 中的 service 服务
[root@docker ~]# docker service ls
ID             NAME              MODE         REPLICAS   IMAGE           PORTS
pvowylrtigne   adoring_satoshi   replicated   2/2        java-image:v1   *:8080->8080/tcp
f6l2t4im4tlr   nginx             replicated   2/2        nginx:latest    *:80->80/tcp

// 查看 nginx 容器的 节点运行情况
[root@docker ~]# docker service ps nginx 
ID             NAME          IMAGE          NODE      DESIRED STATE   CURRENT STATE                 ERROR     PORTS
49mhgbstl1wq   nginx.1       nginx:latest   docker    Running         Running about a minute ago              
ev2kx8fj8k4q    \_ nginx.1   nginx:latest   ubuntu    Shutdown        Shutdown about a minute ago             
3xg3iisxck01   nginx.2       nginx:latest   docker    Running         Running 19 minutes ago           // 原本运行在 Ubuntu 节点 上的 nginx 容器 已自动调度到 docekr 节点 上      

// 查看 tomcat 容器的 节点运行情况
[root@docker ~]# docker service ps adoring_satoshi
ID             NAME                    IMAGE           NODE      DESIRED STATE   CURRENT STATE             ERROR                            PORTS
yq3osrmkk8fz   adoring_satoshi.1       java-image:v1   docker    Running         Running 14 minutes ago                                     
yy8llkldi6xt   adoring_satoshi.2       java-image:v1   docker    Running         Running 10 minutes ago                                     
sa5j6mn8yfo1    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 10 minutes ago   "No such image: java-image:v1"   
340xfm6nirc3    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 10 minutes ago   "No such image: java-image:v1"   
34k6x1h8nzcb    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 10 minutes ago   "No such image: java-image:v1"   
euzxl08qbjcv    \_ adoring_satoshi.2   java-image:v1   ubuntu    Shutdown        Rejected 10 minutes ago   "No such image: java-image:v1"   
// 原本运行在 Ubuntu 节点 上的 tomcat 容器 已自动调度到 docekr 节点 上 

?. Docker 拉取 WordPress 应用

WordPress 运行环境需要如下软件的支持:
PHP 5.6 或 更新软件
MySQL 5.6 或 更新版本
Apache 和 mod_rewrite 可读写 模块
docker pull wordpress
docker pull mariadb

docker run --name db --env MYSQL_ROOT_PASSWORD=example -d mariadb
--name db 指定数据库名称
-d        守护进程后台运行
--env MYSQL_ROOT_PASSWORD=example   向 mariadb 容器里注入 环境变量
								 MYSQL_ROOT_PASSWORD 表示 环境变量的键(名称)
								 example 表示 环境变量的值

docker run --name MyWordPress --link db:mysql -p 80:80 -d wordpress
--link   链接多个容器的选项,WordPress 容器链接到之前启动的 mariadb 容器
-p       将主机 IP 映射到容器 IP 的选项,容器端口80(HTTP)映射到主机端口8080

?.1 centos 7 Docker容器启动报WARNING: IPv4 forwarding is disabled. Networking will not work

解决方法:
# vim etc/sysctl.conf
或者
# vim /user.lib.sysctl.d/00-system.conf
添加如下代码:
net.ipv4.ip_forward=1

重启 network 服务
# systemctl restart network

查看是否修改成功
# systemctl net.ipv4.ip_forward

如果返回为"net.ipv4.ip_forward = 1"则表示成功了
此时重启容器即可

云课堂 Dockerfile 构建 Java网站镜像

1. 准备两个必要的压缩安装包放入指定路径,创建 dockerfile 文件 与两个压缩安装包在同一路径
[root@localhost JAVAimage]# pwd
/home/JAVAimage
[root@localhost JAVAimage]# ll
总用量 200776
-rw-r--r-- 1 root root  10595855 223 19:49 apache-tomcat-8.5.75.tar.gz
-rw-r--r-- 1 root root       425 223 19:59 dockerfile-jdk
-rw-r--r-- 1 root root 194990602 223 19:49 jdk-8u211-linux-x64.tar.gz
2. 编辑 dockerfile 文件 内容
vim dockerfile-jdk

FROM centos:7												// 基础镜像
ADD jdk-8u211-linux-x64.tar.gz /usr/local					// 将本地 jdk 包复制到容器内并解压
RUN mv /usr/local/jdk1.8.0_211 /usr/local/jdk				// 将 jdk 包移动到指定路径
ENV JAVA_HOME=/usr/local/jdk								// 设置环境变量
ENV JRE_HOME=$JAVA_HOME/jre
ENV CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
ENV PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
ADD apache-tomcat-8.5.75.tar.gz /usr/local					// 将本地 tomcat 包复制到容器内并解压
RUN mv /usr/local/apache-tomcat-8.5.75 /usr/local/tomcat	// 将 tomcat 包移动到指定路径
EXPOSE 8080													// 暴露 8080号 端口
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]		// 通过命令以前台形式启动文件
3. 构建镜像,生成容器
[root@localhost JAVAimage]# docker build -f dockerfile-jdk -t java-image:v1 .

[root@localhost JAVAimage]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
java-image            v1        9ba6b6ed0a1a   14 minutes ago   1.05GB

[root@localhost JAVAimage]# docker run -itd -p 80:8080 java-image:v1 /bin/bash
274ba8fbdfb45581ea52135b51208763b106ed50c36af322ac675fcd92abd239

[root@localhost JAVAimage]# docker ps
CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS         PORTS                                   NAMES
274ba8fbdfb4   java-image:v1   "/usr/local/tomcat/b…"   2 seconds ago   Up 2 seconds   0.0.0.0:80->8080/tcp, :::80->8080/tcp   happy_davinci

云课堂 Dockerfile 构建 nginx 镜像

[root@localhost Nginximage]# pwd
/home/Nginximage

[root@localhost Nginximage]# ll
总用量 200776
-rw-r--r-- 1 root root  10595855 223 19:49 nginx-1.18.0.tar.gz
-rw-r--r-- 1 root root       425 223 19:59 dockerfile-nginx
-rw-r--r-- 1 root root 194990602 223 19:49 nginx_install.sh

[root@localhost Nginximage]# more dockerfile-nginx
FROM centos:7
ADD nginx-1.18.0.tar.gz /usr/local
COPY nginx_install.sh /usr/local
RUN sh /usr/local/nginx_install.sh
EXPOSE 80 
ENTRYPOINT ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

[root@localhost Nginximage]# more nginx_install.sh
#!/bin/bash
yum install -y gcc gcc-c++ make pcre pcre-devel zlib zlib-devel
cd /usr/local/nginx-1.18.0
./configure --prefix=/usr/local/nginx && make && make install

[root@bogon Nginximage]# docker build -f dockerfile-nginx -t nginx-image:0.1 .

你可能感兴趣的:(docker,容器,centos)