# Docker
www.docker.com
hub.docker.com
虚拟机缺点:
1. 资源占有多
2. 冗余步骤多
3. 启动慢
容器化技术:不是完整的操作系统,只保留了最核心的部分。直接运行在操作系统之上。容器之间相互隔离
传统虚拟机:虚拟出一套硬件,运行一套完整的操作系统,再运行软件
容器内的应用直接运行在宿主机的内核,是没有自己内核的,也没有虚拟硬件,所以轻便。每个容器相互隔离,都有属于自己的文件系统
更高效的资源应用
更见的系统运维
更便捷的升级和扩缩容
应用更快速的交付和部署
# docker 安装
镜像 :image 类似于模板,可以通过模板创建容器服务。镜像 run 之后就是一个容器,用于提供服务。通过这个镜像可以创建多个容器,项目运行就是在容器中
容器 :container docker 利用容器,独立运行一个或者一组应用,通过镜像来创建 ,可以启动,删除,停止等。可以把容器理解为一个简易的 linux 系统
仓库 :repository 存放镜像的地方。分为共有和私有仓库,比如 docker hub。国内需要配置镜像加速,利用阿里云容器服务器或者其他
环境:centos7 + 华为云 + xshell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@hecs-346515 ~]# uname -r 3.10.0-1160.53.1.el7.x86_64 [root@hecs-346515 ~]# cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7"
1. 卸载旧版本
1 2 3 4 5 6 7 8 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
2. 安装基本环境
1 sudo yum install -y yum-utils
3. 设置镜像仓库
1 2 3 yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
1 2 更新软件包索引 yum makecache fast
4. 安装 docker 相关内容
1 sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
5. 启动 docker
1 2 systemctl start docker docker version
6. 测试 docker 安装是否成功
7. 查看 hello-world 镜像
8. 卸载 docker
1 2 3 4 5 卸载依赖 sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 删除资源,也就是docker的默认工作路径 sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
# 内核参数调优
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 内核参数修改:br_netfilter模块用于将桥接流量转发至iptables链,br_netfilter内核参数需要开启转发。 [root@xianchaomaster1 ~] [root@xianchaomaster1 ~] net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF [root@xianchaomaster1 ~] [root@hecs-346515 ngsql] br_netfilter 22256 0 bridge 151336 2 br_netfilter,ebtable_broute 重启后模块失效,下面是开机自动加载模块的脚本 在/etc/新建rc.sysinit 文件 cat /etc/rc.sysinitfor file in /etc/sysconfig/modules/*.modules ; do [ -x $file ] && $file done 在/etc/sysconfig/modules/目录下新建文件如下 cat /etc/sysconfig/modules/br_netfilter.modulesmodprobe br_netfilter 增加权限 [root@xianchaomaster1 ~] 重启机器模块也会自动加载 [root@localhost ~] br_netfilter 22209 0 bridge 136173 1 br_netfilter 注: Docker 安装后出现:WARNING: bridge-nf-call-iptables is disabled 的解决办法: net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1: 将Linux系统作为路由或者VPN服务就必须要开启IP转发功能。当linux主机有多个网卡时一个网卡收到的信息是否能够传递给其他的网卡 ,如果设置成1 的话 可以进行数据包转发,可以实现VxLAN 等功能。不开启会导致docker部署应用无法访问。 [root@xianchaomaster1 ~]
# 镜像加速
cr.console.aliyun.com
1 2 3 4 5 6 7 8 9 10 您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://fn5y0qpk.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
# docker run 之后发生了什么
1. 本机寻找镜像
2.1 本机有镜像,使用镜像运行
2.2 去 dockerhub 上下载
3.1 dockerhub 找不到镜像 - 返回错误
3.2dockerhub 找到镜像,下载到本地
4. 运行
docker 是一个 cs 结构的系统,docker 的守护进程运行在主机上。通过 socket 从客户端访问
docker server 接收到 client 指定,就会执行这个命令
docker 有着比虚拟机更少的抽象层
docker 用的是宿主机的内核,vm 需要 guest os
docker 不需要重新加载操作系统内核,避免引导。
# docker 命令
1 2 3 docker version/info # 版本信息,系统信息 docker --help # 帮助命令
# 镜像命令
docker images # 查看所有镜像
1 2 3 4 5 6 7 8 9 10 11 12 [root@hecs-346515 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE loadbalancejsp_lbsnode1 latest 8d19a7525948 3 months ago 240MB loadbalancejsp_lbsnode2 latest 8d19a7525948 3 months ago 240MB tomcat 8-jre8 f0e282263192 3 months ago 240MB 仓库源 标签 镜像ID 创建时间 镜像大小 -a 显示全部镜像 -q 只显示镜像ID
docker search # 搜索镜像
1 2 3 4 5 6 7 [root@hecs-346515 ~]# docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 13988 [OK] mariadb MariaDB Server is a high performing open sou… 5333 [OK] percona Percona Server is a fork of the MySQL relati… 602 [OK] docker search mysql --filter=STARS=9000 STARS>9000
docker pull #下载镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 [root@hecs-346515 ~]# 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 # 真实地址 == docker pull docker.io/library/mysql:latest 分层可以实现层的共用 [root@hecs-346515 ~]# docker pull mysql:5.7 5.7: Pulling from library/mysql 72a69066d2fe: Already exists 93619dbc5b36: Already exists 99da31dd6142: Already exists 626033c43d70: Already exists 37d5d7efb64e: Already exists ac563158d721: Already exists d2ba16033dad: Already exists 0ceb82207cd7: Pull complete 37f2405cae96: Pull complete e2482e017e53: Pull complete 70deed891d42: Pull complete Digest: sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94 Status: Downloaded newer image for mysql:5.7 docker.io/library/mysql:5.7
docker rmi # 删除镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@hecs-346515 ~]# docker rmi c20 Untagged: mysql:5.7 Untagged: mysql@sha256:f2ad209efe9c67104167fc609cca6973c8422939491c9345270175a300419f94 Deleted: sha256:c20987f18b130f9d144c9828df630417e2a9523148930dc3963e9d0dab302a76 Deleted: sha256:6567396b065ee734fb2dbb80c8923324a778426dfd01969f091f1ab2d52c7989 Deleted: sha256:0910f12649d514b471f1583a16f672ab67e3d29d9833a15dc2df50dd5536e40f Deleted: sha256:6682af2fb40555c448b84711c7302d0f86fc716bbe9c7dc7dbd739ef9d757150 Deleted: sha256:5c062c3ac20f576d24454e74781511a5f96739f289edaadf2de934d06e910b92 [root@hecs-346515 ~]# docker rmi c20 321 # 删除多个镜像 #docker删除全部容器 [root@hecs-346515 ~]# docker rmi -f $(docker images -qa)
# 容器命令
1 [root@hecs-346515 ~]# docker pull centos
新建容器并启动
docker run
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 参数说明 --name="Name" 容器名字,用于区分容器 -d 以后台运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器端口 -p 8080:8080 -p ip:主机端口:容器端口 -p 主机端口:容器端口 -p 容器端口 容器端口 -P 随机指定端口 [root@hecs-346515 ~]# docker run -it centos /bin/bash # 启动并进入容器 [root@3505a169c989 /]# exit
列出所有运行的容器
docker ps -a
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@hecs-346515 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3505a169c989 centos "/bin/bash" 2 minutes ago Exited (0) About a minute ago lucid_hypatia efe24d96f682 hello-world "/hello" 23 hours ago Exited (0) 23 hours ago goofy_lichterman 85c7b4c3d350 nginx:1.17 "nginx -g 'daemon of…" 3 months ago Exited (1) 3 months ago loadbalancejsp_nginx_1 -a 列出历史容器和当前运行的容器 -n=? 显示最近创建的容器个数 -q 只显示容器编号 docker ps -qa
退出容器
1 2 exit 停止并退出 ctrl + q + p 容器不停止退出
删除容器
1 2 3 docker rm id docker rm -f $(docker ps -aq) # 删除所有容器 docker ps -aq | xargs docker rm # 删除所有容器
启动和停止容器
1 2 3 4 docker start id docker restart id docker stop id docker kill id
后台启动容器
1 2 3 docker run -d centos 启动完之后因为没有前台进程,容器发现没有应用,自动停止
查看日志
1 2 3 4 docker logs [root@hecs-346515 ~]# docker logs -f -t 741 [root@hecs-346515 ~]# docker logs -f -t --tail 10 741
查看容器中的进程信息
1 2 3 4 5 [root@hecs-346515 ~]# docker top 741 UID PID PPID C STIME TTY TIME CMD root 8024 8006 0 14:05 ? 00:00:00 nginx: master process nginx -g daemon off; 101 8075 8024 0 14:05 ? 00:00:00 nginx: worker process
查看镜像元数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@hecs-346515 ~] [ { "Id" : "741038301edd946e2f2e193803d8e29aa31897212a310730c85f8b8194dbf45f" , "Created" : "2023-03-30T06:05:28.540089191Z" , "Path" : "/docker-entrypoint.sh" , "Args" : [ "nginx" , "-g" , "daemon off;" ], "State" : { "Status" : "running" , "Running" : true , "Paused" : false , "Restarting" : false , "OOMKilled" : false , "Dead" : false , "Pid" : 8024, "ExitCode" : 0, "Error" : "" , "StartedAt" : "2023-03-30T06:05:28.79217804Z" , "FinishedAt" : "0001-01-01T00:00:00Z" }, "Image" : "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85" ,
进入当前运行容器
1 2 3 4 5 6 7 8 9 10 [root@hecs-346515 ~]# docker exec -it 741 /bin/bash root@741038301edd:/# # 进入容器后开启新终端 -i:以交互模式运行容器 -t:为容器重新分配一个伪输入终端 [root@hecs-346515 ~]# docker attach 8cf [root@8cf0c194eae8 /]# # 进入容器正在执行的终端,不会启动新的进程
容器内拷贝文件到主机上
1 2 3 4 5 docker cp id:/root/ /home docker cp id:/容器目录 /本机目录 docker 容器内命令 -v 卷可以实现自动同步
# 使用 docker
# 安装 nginx
1 2 3 4 5 6 7 docker search nginx docker pull nginx docker run -d --name=nginx01 -p 8991:80 nginx curl 121.37.191.89:8991 whereis nginx 找到nginx
# 安装 tomcat
1 2 3 4 docker run -it --rm tomcat /bin/bash # rm用完就删,一般用于测试 docker run -d -p 8877:8080 --name=tomcat01 tomcat docker exec -it tomcat01 /bin/bash
# 安装 es+kibana
1 2 3 4 5 6 docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch docker stats # 查看cpu状态 docker run -d --name es2 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch
# 可视化
portainer
Rancher
portainer docker 图形化界面管理工具
1 docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
选择 local
# 联合文件系统
UnionFS
UnionFS (联合文件系统):Union 文件系统 (UnionFS) 是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来壬层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下 (unite several directories into a single virtualfilesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性∶一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
bootfs (boot file system) 主要包含 bootloader 和 kernel, bootloader 主要是引导加载 kernel, Linux 刚启动时会加载 bootfs 文件系统,在 Docker 镜像的最底层 bootfs。这一层与我们典型的 LinuxlUnix 系统是一样的,包含 boot 加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。
roots (root fle system),在 boots 之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, letc 等标准目录和文件。rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,centos 等等。
对于一个精简的 OS , rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用 Host 的 kernel , 自己只需要提供 rootfs 就可以了。由此可见对于不同的 linux 发行版,bootfs 基本是一致的,rootfs 会有差别,因此不同的发行版可以公用
bootfs。
# 分层原理
1 2 3 4 5 6 7 8 9 10 11 12 13 "RootFS": { "Type": "layers", "Layers": [ "sha256:6515074984c6f8bb1b8a9962c8fb5f310fc85e70b04c88442a3939c026dbfad3", "sha256:4f169ae5a253d68d25f3f5fdd0deb31af20096bcffdec1fdda5cf8810d507d1f", "sha256:edae32ac2ac2a7f24eebb4b62ad2fa0a9434f47f4b56a3739106e1da4cb1aa6a", "sha256:f05805c5815d0394d09d3b64e3a58727f8d647f2c5a4d1fbb5e40ed5f8424e84", "sha256:460c946f1b353b51ebb7548ea8f8127118d9bdc7be5f8f2c3c4e73fc9968d705", "sha256:3241d073343d5c09cb9854032919de8fe88433c2867fac073a61ed5669e8cae8", "sha256:f5c79923df4c5c22157139e199d0143e8af29ac0f11f73fd4a56759c1f080c05", "sha256:a5d2135a0fbf3b167b687e40028e54e271588a2ece546bcdcf8da5751c4ba828" ] },
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含 3 个文件,而镜像包含了来自两个镜像层的 6 个文件。
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有 6 个文件,这是因为最上层中的文件 7 是文件 5 的一个更新版本。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。Docker 通过存储引擎 (新版本采用快照机制) 的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。
Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。
Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分层和 CoW [1]。下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。
Docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下的都叫镜像层!
# commit
1 2 3 4 5 6 7 8 9 docker commit # 提交容器称为新的副本 docker commit -m="descriptor" -a="author" id name:tag docker run -it -p 8898:8080 tomcat docker exec -it ffcc /bin/bash docker commit -a="shabi" -m="webapp/" ffccc tomcatshabi:1.22
通过 commit 提交后,在原始 tomcat 上面又增加了一层,所以文件会稍微变大一些
# 容器数据卷
如果数据都在容器中,容器删除数据就会丢失,不能持久化
容器之间需要一个数据共享技术。docker 容器中产生的数据同步到本地,防止数据丢失
其实就是目录挂载。将我们容器内的目录,挂载到虚拟机上
1 2 3 4 5 1.数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会被拷贝到新初始化的数据卷中 2.数据卷可以在容器之间共享和重用 3.可以对数据卷里的内容直接进行修改 4.数据卷的变化不会影像镜像的更新 5.卷会一直存在,即使挂载数据卷的容器已经被删除
容器间数据也是可以共享的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker run -it -v 主机目录:容器目录 -p 8767:8080 docker run -it -v /home/testing:/home -p 8767:8080 tomcat /bin/bash "Mounts": [ { "Type": "bind", "Source": "/home/testing", //主机地址 "Destination": "/home", //docker内地址 "Mode": "", "RW": true, "Propagation": "rprivate" } ],
同步不受容器停止影响
1 docker run -it -v /usr/local/nginx/conf/nginx.conf:/usr/local/nginx/conf/nginx.conf -p 80:80 nginx /bin/bash
以后只需要本地修改即可,容器自动同步
安装 mysql,并挂载数据卷
1 2 3 docker run -d -v /home/mysql_conf:/etc/mysql/conf.d/ -v /home/mysql_data:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=mysql002 mysql mysql -uroot -p123456 -h121.37.191.89 -p3307
删除容器也不会丢失数据,但会占用两倍内存
这就实现了容器持久化功能
具名挂载、匿名挂载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -v 容器内路径 docker run -d -P --name nginx01 -v /etc/nginx nginx # 查看卷的情况 [root@hecs-346515 ~]# docker volume ls DRIVER VOLUME NAME local 879266c77b0964e9bca1b3a1f6cf4d6089eb18d9b9c9e549d0c41357f6dc5a35 local dirtycow-vdso local ee9d314e1c5f3010b8d64108293246853c90d3d820c20332c338ed9bdd3f168b local f3924de885d11729faa0c5869488fd0aefca9e3f6bcaddc36c9ce95f4e891603 local fd3d617a1c288349a4717e3a73e63dbbcf900c51f2d69fe30f9fa726ac82a08d 没有名称的就是匿名挂载 # 具名挂载 docker run -d -P --name nginx01 -v juming_nginx:/etc/nginx nginx [root@hecs-346515 ~]# docker volume inspect juming_nginx [ { "CreatedAt": "2023-04-02T21:42:24+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/juming_nginx/_data", "Name": "juming_nginx", "Options": null, "Scope": "local" } ] # 所有docker内的卷,没有指定目录的情况下都在/var/lib/docker/volumes/ 我们通过具名挂载可以方便的找到一个卷
如何区分指定路径和匿名挂载
1 2 3 -v 容器内路径 匿名 -v 卷名:容器内路径 具名 -v /usr/local:/etc/nginx/ 路径
1 2 3 4 5 6 -v 容器内路径:rw/ro 改变读写权限 docker run -d -P --name nginx01 -v juming_nginx:/etc/nginx:ro nginx readonly readwrite 一旦设置了容器容器权限,对我们挂载出来的内容有限定 默认是rw,ro说明只能通过宿主机操作,容器内部无法操作
# Dockerfile 挂载
dockerfile 就是用来构建 docker 镜像的文件
镜像是一层层的,命令也是一层层的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 FROM centos VOLUME ["voume01","volume02"] CMD echo "---------------" CMD /bin/bash [root@hecs-346515 docker-test]# docker build -f ./dockerfile1 -t hahaha . [+] Building 0.1s (5/5) FINISHED => [internal] load build definition from dockerfile1 0.1s => => transferring dockerfile: 123B 0.0s => [internal] load .dockerignore 0.1s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:latest 0.0s => [1/1] FROM docker.io/library/centos 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:29755edf1ce7d5c71c2c7cbbf8b0bd54f02ce72a4ebcaccdfd857aa0dcb99e 0.0s => => naming to docker.io/library/hahaha 0.0s # 这里的每个命令都是镜像的一层 [root@hecs-346515 docker-test]# docker run -it hahaha /bin/bash [root@74ee4cc3e927 /]# ls bin etc lib lost+found mnt proc run srv tmp var voume01 dev home lib64 media opt root sbin sys usr volume02 "Mounts": [ { "Type": "volume", "Name": "eb0e7a226b19aa2e8811eabaf339cf3cee05f3fec433af62212607e0010bda2e", "Source": "/var/lib/docker/volumes/eb0e7a226b19aa2e8811eabaf339cf3cee05f3fec433af62212607e0010bda2e/_data", "Destination": "volume02", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "8b52d9050ada34758bacfe403a63a5b6a06e0c96cadb86830fa16aa9533a6fc8", "Source": "/var/lib/docker/volumes/8b52d9050ada34758bacfe403a63a5b6a06e0c96cadb86830fa16aa9533a6fc8/_data", "Destination": "voume01", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],
构建镜像的时候没有挂载均,需要手动 - v 挂载
# 数据卷容器
实现容器之间同步数据
1 2 3 4 5 docker run -it --name docker01 hahaha docker run -it --name docker02 --volumes-from docker01 hahaha
父容器删除,其他容器的文件依然在
所有父容器和子容器都挂载在宿主机的文件中,如果宿主机挂载目录没了,三个容器都没了
数据卷的声明周期一直到没有容器使用位置
1 2 3 4 rm -rf /etc/yum.repos.d/* curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo yum install wget -y yum install nginx -y
# docker 数据卷备份与还原
1 2 3 4 5 6 7 8 9 10 docker run --volumes-from [container name] -v $(pwd):/backup centos tar czvf /backup/backup.tar [container data volume] 例子:备份datavolume6 到/backup docker run --volumes-from data-volume2 -v /root/backup:/backup --name datavolume-copy centos tar zcvf /backup/data-volume2.tar.gz /datavolume6 还原备份 docker run --volumes-from [container name] -v $(pwd):/backup centos tar xzvf /backup/backup.tar.gz [container data volume] 例: docker run --volumes-from data-volume2 -v /root/backup/:/backup centos tar zxvf /backup/data-volume2.tar.gz -C /datavolume6
# Dockerfile
dockerfile 是用来构建 dockerfile 的镜像文件,命令参数脚本
一个基本 dockerfile
1 2 3 4 5 6 7 8 9 10 FROM centos MAINTAINER xianchao RUN rm -rf /etc/yum.repos.d/* COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/ RUN yum install wget -y RUN yum install nginx -y COPY index.html /usr/share/nginx/html/ EXPOSE 80 ENTRYPOINT ["/usr/sbin/nginx" ,"-g" ,"daemon off;" ]
1. 编写 dockerfile
2.docker build 构建成为镜像
3.docker run 运行镜像
4.docker push 发布镜像
每个关键字都是大写字母
执行从上到下
#表示注释
每一个指令都会创建一个新的镜像层,并提交
发布项目都要发布 dockerfile
dockerfile 构建文件,定义了一切的步骤,源代码
dockerimages 通过 dockerfile 生成的镜像,最终发布和运行的版本
docker 容器:容器就是镜像运行起来提供服务
# dockerfile 指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 FROM # 基础镜像 MAINTAINER # 维护者信息 RUN # 镜像构建的时候需要运行的命令 包含两种模式 1、Shell RUN <command> (shell模式,这个是最常用的,需要记住) RUN echo hello 2、exec模式 RUN [“executable”,“param1”,“param2”](exec模式) RUN [“/bin/bash”,”-c”,”echo hello”] 等价于/bin/bash -c echo hello RUN yum install wget -y等价于 RUN [“/bin/bash”,”-c”,”yum install wget -y”] WORKDIR # 镜像工作目录 进容器之后的目录 docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。 volume # 设置容器卷,挂载到那个位置 1、避免重要的数据,因容器重启而丢失,这是非常致命的。 2、避免容器不断变大。 VOLUME ["/data"] 物理机随机生成一个目录映射到容器中/data 在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点 EXPOSE # 指定暴露端口 1、帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。 2、在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。 3、可以是一个或者多个端口,也可以指定多个EXPOSE CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代 1、CMD 在docker run 时运行。 2、RUN 是在 docker build构建镜像时运行的 ENTRYPOINT # 指定容器启动的时候要运行的命令,可以追加命令 类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。 但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 entrypoint指令指定的程序。 优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。 注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。 注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。 可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参 ENTRYPOINT ["nginx", "-c"] # 定参 CMD ["/etc/nginx/nginx.conf"] # 变参 不传参运行会 运行nginx -c /etc/nginx/nginx.conf 参参运行 docker run --name nginx nginx:test /etc/nginx/new.conf 会运行nginx -c /etc/nginx/new.conf ONBUILD # 当构建一个被继承Dockerfile,这个时候就会运行ONBUILD指令 用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这时执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令。 ONBUILD COPY index.html /usr/share/nginx/html/ docker build -t="onbuild-nginx:v1" . --load 只有当某一个dockerfile把onbuild-nginx作为基础镜像时ONBUILD才会执行 CPOY # 将文件拷贝到镜像中 COPY [--chown=<user>:<group>] <源路径1>... <目标路径> COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"] COPY hom* /mydir/ COPY hom?.txt /mydir/ ADD # 步骤:如果搭建tomcat,压缩包就需要add ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。 ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。 ADD 指令和 COPY 的使用格式一致 ENV # 构建的时候设置环境变量 ENV <key> <value> ENV <key>=<value>... ENV NODE_VERSION 6.6.6 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \ && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" USER 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。 格式: USER <用户名>[:<用户组>]
dockerhub 中大部分镜像都是从 FROM scratch 来的,然后配置需要的软件和配置来进行构建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 FROM centos:7 MAINTAINER shabi<21111 @qq.com>ENV MYPATH /usr/localWORKDIR $MYPATH RUN yum install epel* -y RUN yum install -y vim RUN yum install -y net-tools EXPOSE 80 CMD echo $MYPATH CMD /bin/bash docker build -f dockerfile -t centoshaha:0.5 . [root@hecs-346515 dockerfile] [+] Building 199.4 s (5 /7 ) [+] Building 200.1 s (5 /7 ) [+] Building 200.6 s (5 /7 ) [+] Building 200.9 s (5 /7 ) [+] Building 228.0 s (8 /8 ) FINISHED => [internal] load build definition from dockerfile 0.0 s => => transferring dockerfile: 219 B 0.0 s => [internal] load .dockerignore 0.0 s => => transferring context: 2 B 0.0 s => [internal] load metadata for docker.io/library/centos:7 16.0 s => [1 /4 ] FROM docker.io/library/centos:7 @sha256:9 d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0 50.2 s => => resolve docker.io/library/centos:7 @sha256:9 d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e09 0.0 s => => sha256:9 d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 1.20 kB / 1.20 kB 0.0 s => => sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839686a31da35a3b532f 529 B / 529 B 0.0 s => => sha256:eeb6ee3f44bd0b5103bb561b4c16bcb82328cfe5809ab675bb17ab3a16c517c9 2.75 kB / 2.75 kB 0.0 s => => sha256:2 d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc 76.10 MB / 76.10 MB 46.3 s => => extracting sha256:2 d473b07cdd5f0912cd6f1a703352c82b512407db6b05b43f2553732b55df3bc 3.6 s => [2 /4 ] WORKDIR /usr/local 0.0s => [3 /4 ] RUN yum install -y vim 156.1s => [4 /4 ] RUN yum install -y net-tools 2.9s => exporting to image 2.7 s => => exporting layers 2.7 s => => writing image sha256:1 c525b4438024495ebbbf1f19a3e3ea730826dfcab5cb8337ea0fa0a0de853ad 0.0 s => => naming to docker.io/library/centoshaha:0.5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@hecs-346515 dockerfile]# docker history 1c5 IMAGE CREATED CREATED BY SIZE COMMENT 1c525b443802 4 minutes ago CMD ["/bin/sh" "-c" "/bin/bash"] 0B buildkit.dockerfile.v0 <missing> 4 minutes ago CMD ["/bin/sh" "-c" "echo $MYPATH"] 0B buildkit.dockerfile.v0 <missing> 4 minutes ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0 <missing> 4 minutes ago RUN /bin/sh -c yum install -y net-tools # bu… 176MB buildkit.dockerfile.v0 <missing> 4 minutes ago RUN /bin/sh -c yum install -y vim # buildkit 259MB buildkit.dockerfile.v0 <missing> 7 minutes ago WORKDIR /usr/local 0B buildkit.dockerfile.v0 <missing> 7 minutes ago ENV MYPATH=/usr/local 0B buildkit.dockerfile.v0 <missing> 7 minutes ago MAINTAINER shabi<21111@qq.com> 0B buildkit.dockerfile.v0 <missing> 18 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 18 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 18 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB [root@hecs-346515 dockerfile]# docker history 5d0 IMAGE CREATED CREATED BY SIZE COMMENT 5d0da3dc9764 18 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 18 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 18 months ago /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0… 231MB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 FROM centos:7 CMD ["ls","-a"] [root@hecs-346515 dockerfile]# docker build -f cmd -t cmd:0.5 . [+] Building 0.3s (5/5) FINISHED => [internal] load build definition from cmd 0.0s => => transferring dockerfile: 60B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:7 0.2s => CACHED [1/1] FROM docker.io/library/centos:7@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:3ced42c5b7de1bbe7659ef7bd2349ebf83eb13eab6d1afe69f029ef65a88f9ab 0.0s => => naming to docker.io/library/cmd:0.5 0.0s [root@hecs-346515 dockerfile]# docker run -it cmd:0.5 . .dockerenv bin etc lib media opt root sbin sys usr .. anaconda-post.log dev home lib64 mnt proc run srv tmp var CMD # 指定容器启动的时候要运行的命令,只有最后一个会生效,可被替代 docker run 3e -l # -l不是命令所以报错 docker run 3e ls -al ls -al 替换了ls -a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 vim entry FROM centos:7 ENTRYPOINT ["ls","-a"] [root@hecs-346515 dockerfile]# docker run entry:0.5 . .. .dockerenv anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var [root@hecs-346515 dockerfile]# docker run entry:0.5 -l total 64 drwxr-xr-x 1 root root 4096 Apr 4 03:18 . drwxr-xr-x 1 root root 4096 Apr 4 03:18 .. -rwxr-xr-x 1 root root 0 Apr 4 03:18 .dockerenv -rw-r--r-- 1 root root 12114 Nov 13 2020 anaconda-post.log lrwxrwxrwx 1 root root 7 Nov 13 2020 bin -> usr/bin drwxr-xr-x 5 root root 340 Apr 4 03:18 dev drwxr-xr-x 1 root root 4096 Apr 4 03:18 etc drwxr-xr-x 2 root root 4096 Apr 11 2018 home lrwxrwxrwx 1 root root 7 Nov 13 2020 lib -> usr/lib lrwxrwxrwx 1 root root 9 Nov 13 2020 lib64 -> usr/lib64 drwxr-xr-x 2 root root 4096 Apr 11 2018 media drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt drwxr-xr-x 2 root root 4096 Apr 11 2018 opt dr-xr-xr-x 134 root root 0 Apr 4 03:18 proc dr-xr-x--- 2 root root 4096 Nov 13 2020 root drwxr-xr-x 11 root root 4096 Nov 13 2020 run lrwxrwxrwx 1 root root 8 Nov 13 2020 sbin -> usr/sbin drwxr-xr-x 2 root root 4096 Apr 11 2018 srv dr-xr-xr-x 13 root root 0 Apr 4 03:18 sys drwxrwxrwt 7 root root 4096 Nov 13 2020 tmp drwxr-xr-x 13 root root 4096 Nov 13 2020 usr drwxr-xr-x 18 root root 4096 Nov 13 2020 var ENTRYPOINT # 指定容器启动的时候要运行的命令,可以追加命令
entrypoint 是追加,CMD 是覆盖
# 制作 nginx 镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 FROM centosMAINTAINER xianchaoRUN rm -rf /etc/yum.repos.d/* COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/ RUN yum install wget -y RUN yum install nginx -y COPY index.html /usr/share/nginx/html/ EXPOSE 80 ENTRYPOINT ["/usr/sbin/nginx" ,"-g" ,"daemon off;" ] docker build -t="shinya/shabi:v1" . docker run -d -p 80 --name html2 shinya/shabi:v1
# 制作 tomcat 镜像
1、准备安装包
2、Dockerfile 是官方命名,构建时会自动寻找,就不需要 - f 指定了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 FROM centos:7 MAINTAINER shshshs<110 @110 .com>COPY readme.txt /usr/local/readme.txt ADD apache-tomcat-10.1.7.tar.gz /usr/local/ ADD jdk-20_linux-x64_bin.tar.gz /usr/local/ RUN yum install -y vim ENV MYPATH /usr/local/WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk-20 ENV CLASS_PATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-10.1 .7 /ENV CATALINA_BASE /usr/local/apache-tomcat-10.1 .7 /ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/binEXPOSE 8080 CMD /usr/local/apache-tomcat-10.1.7/bin/startup.sh && tail -F /usr/local/apache-tomcat-10.1.7/logs/catalina.out
3. 构建镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 [root@hecs-346515 dockerfile]# docker build -t ddcat:1.0 . [+] Building 61.4s (11/11) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 690B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/centos:7 15.3s => CACHED [1/6] FROM docker.io/library/centos:7@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426 0.0s => [internal] load build context 2.3s => => transferring context: 203.75MB 2.3s => [2/6] COPY readme.txt /usr/local/readme.txt 0.5s => [3/6] ADD apache-tomcat-10.1.7.tar.gz /usr/local/ 0.4s => [4/6] ADD jdk-20_linux-x64_bin.tar.gz /usr/local/ 4.6s => [5/6] RUN yum install -y vim 34.4s => [6/6] WORKDIR /usr/local/ 0.0s => exporting to image 3.8s => => exporting layers 3.8s => => writing image sha256:620e725ff485b1cae36720ea191ba0692cc5f2a857e516528e5b65653e752913 0.0s => => naming to docker.io/library/ddcat:1.0 0.0s 4.启动镜像 [root@hecs-346515 dockerfile]# docker run -d -p 8877:8080 --name=catcatcat -v /root/dockerfile/build/tomcat/test:/usr/local/apache-tomcat-10.1.7/webapps/test -v /root/dockerfile/build/tomcat/logs:/usr/local/apache-tomcat-10.1.7/logs ddcat:1.1 4357a9cda1d960125ac7d4ab052902ec04848c0dbbce3beb26bccf4eaff84fa4
5、访问测试
6. 发布项目
1 2 3 4 5 6 7 <?xml version="1.0" encoding="UTF-8" ?> <web-app version ="2.4" xmlns ="http://java.sun.com/xml/ns/j2ee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" ></web-app >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <%-- <meta charset="UTF-8" >--%> <%-- <meta http-equiv="X-UA-Compatible" content="IE=edge" >--%> <%-- <meta name="viewport" content="width=device-width, initial-scale=1.0" >--%> <title>Title</title> <link rel="stylesheet" href="css/bootstrap.min.css" > <link rel="stylesheet" href="css/bootstrap.min.css.map" > <script type="text/javascript" src="js/jquery-3.5.1.js" ></script> <script type="text/javascript" src="js/bootstrap.min.js" ></script> <script type="text/javascript" > $(function () { $.ajax({ url: "${pageContext.request.contextPath}/type?method=findAllType" , type: "GET" , dataType: "json" , success: function (data) { for (var i in data) { var a = "<li><a href='${pageContext.request.contextPath}/product?method=show&tid=" + data[i].tid + "'>" + data[i].tname + "</a></li>" ; $("#goodsType" ).append(a); } }, error: function () { alert("失败" ); } }) }) </script> </head> <body> <div> <nav class="navbar navbar-default" > <div class="container-fluid" > <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header" > <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false" > <span class="sr-only" >Toggle navigation</span> <span class="icon-bar" ></span> <span class="icon-bar" ></span> <span class="icon-bar" ></span> </button> <a class="navbar-brand" href="#" >myShop商城</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1" > <ul class="nav navbar-nav" > <li class="active" ><a href="${pageContext.request.contextPath}/Login.jsp" >登录<span class="sr-only" >(current)</span></a> </li> <li><a href="${pageContext.request.contextPath}/Register.jsp" >注册</a></li> <li><a href="${pageContext.request.contextPath}/user?method=loginOut" >注销</a></li> </ul> <form class="navbar-form navbar-left" > <div class="form-group" > <input type="text" class="form-control" placeholder="搜索一下" > </div> <button type="submit" class="btn btn-default" >搜索</button> </form> <ul class="nav navbar-nav navbar-right" > <li><a href="#" >购物车</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <nav class="navbar navbar-default" > <p> <ul id="goodsType" > </ul> </p> </nav> </div> </body> </html> [root@hecs -346515 test]# pwd /root/dockerfile/build/tomcat/test [root@hecs -346515 test]# ls index.jsp WEB_INF
# go 代码 dockerfile 做成镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 yum install go -y cat main.go import ( "net/http" "github.com/gin-gonic/gin" ) func statusOKHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status" : "success~welcome to study" }) } func versionHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"version" : "v1.1版本" }) } func main() { router := gin.New() router.Use(gin.Recovery()) router.GET("/" , statusOKHandler) router.GET("/version" , versionHandler) router.Run(":8080" ) } go mod init test go env -w GOPROXY=https://goproxy.cn,direct go mod tidy CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o k8s-demo main.go ./k8s-demo FROM alpineWORKDIR /data/app ADD k8s-demo /data/app/ CMD ["/bin/sh" ,"-c" ,"./k8s-demo" ] docker build -t dashabi:v1 . docker run -d --name go2 -p 30188:8083 dashabi:v1 curl localhost:30188 /version
# python dockerfile 构建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 tar zxvf hello-python.tar.gz FROM python:3.7 RUN mkdir /app WORKDIR /app ADD . /app/ RUN /usr/local/bin/python -m pip install --upgrade pip RUN pip install -r requirements.txt EXPOSE 5000 CMD ["python" ,"/app/main.py" ] docker build -t hello-python:v1 . docker run -d --name python -p 30050:5000 hello-python:v1
# 发布镜像
dockerhub
1 2 3 4 5 6 #登录dockerhub [root@hecs-346515 test]# docker login -u kbshire -p [root@hecs-346515 test]# docker build -t kbshire/avcat:2.333 . [root@hecs-346515 test]# docker push kbshire/avcat:2.333
阿里云
1. 创建命名空间
2. 创建容器镜像
# Docker 网络
1 2 3 4 bridge模式:使--net =bridge指定,默认设置; host模式:使--net =host指定; none模式:使--net =none指定; container模式:使用--net =container:NAME orID指定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@hecs-346515 dockerfile]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether fa:16:3e:8b:e2:28 brd ff:ff:ff:ff:ff:ff inet 192.168.0.69/24 brd 192.168.0.255 scope global noprefixroute dynamic eth0 valid_lft 67882sec preferred_lft 67882sec inet6 fe80::f816:3eff:fe8b:e228/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:27:32:a6:49 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:27ff:fe32:a649/64 scope link valid_lft forever preferred_lft forever
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 docker run -d -P --name tomcat01 tomcat docker exec -it tomcat01 ip addr # yum install iproute [root@29ede5d03d63 local]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 161: eth0@if162: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever linux是可以ping通容器内部的
每启动一个 docker 容器,docker 就会给 docker 容器分配一个 ip,我们只要安装了 docker 就会有一个网卡 docker0
桥接模式,就是 evth-pair 技术
1 2 3 4 162: vetha5d997c@if161: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 82:60:95:bc:a3:22 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::8060:95ff:febc:a322/64 scope link valid_lft forever preferred_lft forever
容器带来的网卡都是一对一对的
evth-pair 就是一队虚拟设备接口,他们是成对出现的,一端连着协议,一端彼此相连
evth-pair 连接各种网络设备
OpenStack,docker 容器之间,ovs 的连接都是使用 evth-pair
容器和容器之间可以互相通信
容器之间通信共用的 docker0,可以理解为一个路由器
不指定容器网络的情况下,都是 docker0 路由的,docker 回给我们的容器分配一个默认 ip
/16 的掩码最多可以有 65535 个地址
docker 使用 linux 桥接,宿主机中是一个 docker 网络的网桥 docker0
docker 中所有网络接口都是虚拟的,转发效率高
容器删除,veth-pair 也就被删除了
1 2 yum install bridge-utils brctl show
# –link
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [root@hecs-346515 dockerfile]# docker run -it -P --name centos05 --link gallant_poincare centoshaha:0.5 [root@hecs-346515 ~]# docker exec -it centos05 ping gallant_poincare 通过link实现可以通过服务名ping [root@hecs-346515 ~]# docker exec -it gallant_poincare ping centos05 ping: centos05: Name or service not known docker network inspect id [root@5e0c29c45f15 local]# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.3 gallant_poincare cef544877c1d 172.17.0.4 5e0c29c45f15
–link 就是在 hosts 中增加了 gallant_poincare 的映射
不建议使用–link
docker0 的问题,他不支持容器名进行连接访问
# 自定义网络
1 2 3 4 5 6 [root@hecs-346515 dockerfile]# docker network ls NETWORK ID NAME DRIVER SCOPE ef281869253b bridge bridge local 81efa88be64b host host local 57ffa6ffd57d loadbalancejsp_default bridge local 55243546bae4 none null local
网络模式
bridge:docker 之间搭桥,自己创建也使用桥接
none:不配置网络,一般不用
Docker 网络 none 模式是指创建的容器没有网络地址,只有 lo 网卡
host:和宿主机共享网络
container:容器内网络连通,局限很大
创建新容器的时候,通过–net container 参数,指定其和已经存在的某个容器共享一个 Network Namespace。两个容器的进程通过 lo 网卡设备通信。
docker run --name container2 --net=container:none -it --privileged=true centos
1 2 docker run -it --net=none --privileged=true centos 特权模式下才是真正的root 在容器内部
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 直接启动的命令默认--net bridge 这就是docker0 docker0是默认的,不能通过域名访问 [root@hecs-346515 dockerfile]# docker network create --driver bridge --subnet 10.1.0.0/16 --gateway 10.1.0.1 sbnet 82c4a8b68c66715f88003b8ba4ef65de670286de1c73abee49ab26f9fceb063a [root@hecs-346515 dockerfile]# docker network ls NETWORK ID NAME DRIVER SCOPE ef281869253b bridge bridge local 81efa88be64b host host local 57ffa6ffd57d loadbalancejsp_default bridge local 55243546bae4 none null local 82c4a8b68c66 sbnet bridge local [root@hecs-346515 dockerfile]# docker network inspect sbnet [ { "Name": "sbnet", "Id": "82c4a8b68c66715f88003b8ba4ef65de670286de1c73abee49ab26f9fceb063a", "Created": "2023-04-04T18:25:48.537296679+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "10.1.0.0/16", "Gateway": "10.1.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": {}, "Labels": {} } ] docker run -it -P --name=centos11 --net sbnet centos docker run -it -P --name=centos12 --net sbnet centos docker exec -it centos11 ping centos12 不使用--link也能ping通
我们自定义的网络 docker 已经帮我们维护好了关系
可以使不同集群使用不同的网络,保证集群的安全和健康
# 网络连通
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 docker netowrk connect sbnet centos13 [root@hecs-346515 ~]# docker network connect sbnet centos13 [root@hecs-346515 ~]# docker network inspect sbnet [ { "Name": "sbnet", "Id": "82c4a8b68c66715f88003b8ba4ef65de670286de1c73abee49ab26f9fceb063a", "Created": "2023-04-04T18:25:48.537296679+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "10.1.0.0/16", "Gateway": "10.1.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "872404abcfc68d09a65ec820c986aa2003737629a0bdf83406152793dc72f228": { "Name": "centos12", "EndpointID": "e393d20c796d4c081b726787210dc5a05d645d33c1a75fd6da529ac11db6e0c1", "MacAddress": "02:42:0a:01:00:03", "IPv4Address": "10.1.0.3/16", "IPv6Address": "" }, "974c928cc0854549c5cf9b8e257adf025bf9e1499b1169b46bf56c1632565bbe": { "Name": "centos13", "EndpointID": "a571e55079a80a2f36ff6e181194cadc1ec49b76bd51bb4485be030201a718c7", "MacAddress": "02:42:0a:01:00:04", "IPv4Address": "10.1.0.4/16", "IPv6Address": "" }, "ed93b6d1202d8953cd9ae12450e44538d1647620423a7cbf63d1bcd9f023e7a6": { "Name": "centos11", "EndpointID": "820d037e8faaad9c8a19cd0a58629c1ec1881cc2b9e5e26a21420a1bb8724ccd", "MacAddress": "02:42:0a:01:00:02", "IPv4Address": "10.1.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ] 将centos13放到了bridge下,一个容器此时有两个地址
要跨网络操作容器,需要 docker connect 连通
# Redis 集群
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for port in $(seq 1 6); \ do \ mkdir -p /mydata/redis/node-${port}/conf touch /mydata/redis/node-${port}/conf/redis.conf cat << EOF >/mydata/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF done
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 docker run -p 6376:6379 -p 16376:16379 --name redis-6 -v /mydata/redis/node-6/data:/data -v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf -d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf redis-cli --cluster create 172.38 .0.11 :6379 172.38 .0.12 :6379 172.38 .0.13 :6379 172.38 .0.14 :6379 172.38 .0.15 :637 9 172.38 .0.16 :6379 --cluster-replicas 1 /data 127.0 .0.1 :6379 > CLUSTER INFOcluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:6 cluster_size:3 cluster_current_epoch:6 cluster_my_epoch:1 cluster_stats_messages_ping_sent:82 cluster_stats_messages_pong_sent:82 cluster_stats_messages_sent:164 cluster_stats_messages_ping_received:77 cluster_stats_messages_pong_received:82 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:164 127.0 .0.1 :6379 > CLUSTER NODESb75997d0df1dafbbf8db3642f424eedc0cd9695f 172.38 .0.15 :6379 @16379 slave 73 a37cfa8c760c3069bd4fb69f9b2a411f556124 0 1680661677823 5 connected 73 a37cfa8c760c3069bd4fb69f9b2a411f556124 172.38 .0.11 :6379 @16379 myself,master - 0 1680661677000 1 connected 0 -5460 51 c02482b19b9ab5dc20ff1852f375ada2f68986 172.38 .0.12 :6379 @16379 master - 0 1680661677522 2 connected 5461 -10922 ba2557b0959bed1cc5a446bcd0403721bcb8d002 172.38 .0.14 :6379 @16379 slave 3794 de303a95a3718988f3d313f332241b364d7c 0 1680661677000 4 connected 3794 de303a95a3718988f3d313f332241b364d7c 172.38 .0.13 :6379 @16379 master - 0 1680661676822 3 connected 10923 -16383 73007 d040ed6ca3c093fb5061a3358d1ae47a18a 172.38 .0.16 :6379 @16379 slave 51 c02482b19b9ab5dc20ff1852f375ada2f68986 0 1680661676000 6 connected127.0 .0.1 :6379 > set a b -> Redirected to slot [15495 ] located at 172.38 .0.13 :6379 OK 172.38 .0.13 :6379 > get a ^C /data 127.0 .0.1 :6379 > get a -> Redirected to slot [15495 ] located at 172.38 .0.14 :6379 "b" 172.38 .0.14 :6379 > CLUSTER NODESb75997d0df1dafbbf8db3642f424eedc0cd9695f 172.38 .0.15 :6379 @16379 slave 73 a37cfa8c760c3069bd4fb69f9b2a411f556124 0 1680661856417 5 connected 73 a37cfa8c760c3069bd4fb69f9b2a411f556124 172.38 .0.11 :6379 @16379 master - 0 1680661856517 1 connected 0 -5460 ba2557b0959bed1cc5a446bcd0403721bcb8d002 172.38 .0.14 :6379 @16379 myself,master - 0 1680661855000 7 connected 10923 -16383 73007 d040ed6ca3c093fb5061a3358d1ae47a18a 172.38 .0.16 :6379 @16379 slave 51 c02482b19b9ab5dc20ff1852f375ada2f68986 0 1680661856016 6 connected51 c02482b19b9ab5dc20ff1852f375ada2f68986 172.38 .0.12 :6379 @16379 master - 0 1680661855415 2 connected 5461 -10922 3794 de303a95a3718988f3d313f332241b364d7c 172.38 .0.13 :6379 @16379 master,fail - 1680661784244 1680661782238 3 connected
# springboot 微服务打包 docker 镜像
1. 构建 springboot 项目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 创建package controller 创建class HelloControllerpackage com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String hello() { return "hello,shabi"; } } package com.example.demo.controller; import org.springframework.web.bind.annotation.RequestMapping; public class HelloController { @RequestMapping("/hello") public String hello() { return "hello,shabi"; } }
2. 打包应用
3. 编写 dockerfile
1 2 3 4 5 6 7 8 9 10 FROM hzkjhub/java17:17.0.4 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"] ~
4. 构建镜像
1 2 3 4 5 docker build -t shabi . docker run -P -it --name docker333 shabi curl 127.0.0.1:32778/hello
5. 发布运行
https://www.bilibili.com/video/BV1og4y1q7M4
# docker 资源配额
Docker 通过 cgroup 来控制容器使用的资源限制,可以对 docker 限制的资源包括 CPU、内存、磁盘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker run --help | grep cpu-shares -c, --cpu-shares int CPU shares (relative weight) CPU shares (relative weight) 在创建容器时指定容器所使用的CPU份额值。cpu-shares的值不能保证可以获得1个vcpu或者多少GHz的CPU资源,仅仅只是一个弹性的加权值。 默认每个docker容器的cpu份额值都是1024。在同一个CPU核心上,同时运行多个容器时,容器的cpu加权的效果才能体现出来。 cgroups只在多个容器同时争抢同一个cpu资源时,cpu配额才会生效。因此,无法单纯根据某个容器的cpu份额来确定有多少cpu资源分配给它,资源分配结果取决于同时运行的其他容器的cpu分配和容器中进程运行情况。 docker run -it --cpu-shares 512 centos /bin/bash [root@df176dd75bd4 /] 512 container_A 的 cpu share 1024,是 container_B 的两倍。当两个容器都需要 CPU 资源时,container_A 可以得到的 CPU 是 container_B 的两倍。 需要注意的是,这种按权重分配 CPU只会发生在 CPU资源紧张的情况下。如果 container_A 处于空闲状态,为了充分利用 CPU资源,container_B 也可以分配到全部可用的 CPU。 docker run --name "container_B" -c 512 ubuntu
对多核 CPU 的服务器,docker 还可以控制容器运行限定使用哪些 cpu 内核和内存节点,即使用–cpuset-cpus 和–cpuset-mems 参数。对具有 NUMA 拓扑(具有多 CPU、多内存节点)的服务器尤其有用,可以对需要高性能计算的容器进行性能最优的配置。如果服务器只有一个内存节点,则–cpuset-mems 的配置基本上不会有明显效果。
1 2 3 4 docker run -itd --name docker10 --cpuset-cpus 0,1 --cpu-shares 512 centos /bin/bash docker run -itd --name docker20 --cpuset-cpus 0,1 --cpu-shares 1024 centos /bin/bash 指定docker20只能在cpu0和cpu1上运行,而且docker20的使用cpu的份额1024,比dcker10多一倍
1 2 3 4 5 6 7 Docker提供参数-m, --memory=""限制容器的内存使用量。 docker run -it -m 128m centos cat /sys/fs/cgroup/memory/memory.limit_in_bytes docker run -it --cpuset-cpus 0,1 -m 128m centos
1 2 3 4 5 6 7 8 9 10 --device-write-bps value Limit write rate (bytes per second) to a device (default []) --device-read-bps value 情景:防止某个 Docker 容器吃光你的磁盘 I / O 资源 docker run -it -v /var/www/html/:/var/www/html --device /dev/sda:/dev/sda --device-write-bps /dev/sda:2mb centos /bin/bash time dd if =/dev/sda of=/var/www/html/test.out bs=2M count=50 oflag=direct,nonblock
1 2 docker run -it --rm --name xianchao centos sleep 6 当容器命令运行结束后,自动删除容器,自动释放资源
# Harbor
Harbor 是由 VMware 公司开源的企业级的 Docker Registry 管理项目,它包括权限管理 (RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能。
https://github.com/goharbor/harbor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 openssl genrsa -out ca.key 3072 openssl req -new -x509 -days 3650 -key ca.key -out ca.pem 生成域名的证书: openssl genrsa -out harbor.key 3072 openssl req -new -key harbor.key -out harbor.csr openssl x509 -req -in harbor.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out harbor.pem -days 3650 yum install -y wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y yum-utils device-mapper-persistent-data lvm2 yum install docker-ce -y 内核参数修改:br_netfilter模块用于将桥接流量转发至iptables链,br_netfilter内核参数需要开启转发。 [root@ harbor~] [root@ harbor~] net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF sysctl -p /etc/sysctl.d/docker.conf https://github.com/goharbor/harbor/releases/tag/v2.8.0 tar xzvf harbor-offline-installer-v2.8.0.tgz cp harbor.yml.tmpl harbor.ymlvim harbor.yml hostname: 192.168.13.155 http: port: 80 https: port: 443 certificate: /data/ssl/harbor.pem private_key: /data/ssl/harbor.key admin/Harbor12345 ./prepare ./install.sh [+] Running 10/10 ✔ Network harbor_harbor Created 0.2s ✔ Container harbor-log Started 0.5s ✔ Container registryctl Started 2.0s ✔ Container harbor-db Started 2.0s ✔ Container harbor-portal Started 1.3s ✔ Container registry Started 1.9s ✔ Container redis Started 1.9s ✔ Container harbor-core Started 2.3s ✔ Container nginx Started 3.3s ✔ Container harbor-jobservice Started 3.0s ✔ ----Harbor has been installed and started successfully.----
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 vim /etc/docker/daemon.json { "registry-mirrors" : ["https://fn5y0qpk.mirror.aliyuncs.com" ], "insecure-registries" : ["121.37.191.89" ] } [root@master ~] [root@master ~] [root@master ~] Username: admin 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/ Login Succeeded docker tag hello-world:latest 121.37.191.89/test/hello-world:v1 docker push 121.37.191.89/test/hello-world:v1 docker pull 121.37.191.89/test/hello-world:v1
# Docker Compose
高效的管理容器。定义运行多个容器。使用 yaml 配置
编写 dockerfile 保证我们的项目在任何地方可以运行
定义服务在 docker-compose.yml 中
docker-compose up
批量容器编排
docker-compose 是 docker 的开源项目,需要安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 version: "3.9" services: web: build: . ports: - "8000:5000" volumes: - .:/code - logvolume01:/var/log depends_on: - redis redis: image: redis volumes: logvolume01: {}
service 容器,应用
项目 project。一组关联的容器
# 安装 docker compose
1 2 3 4 5 6 7 8 9 curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose docker-compose -version docker-compose version 1.29.2, build 5becea4c
1. 应用 app.py
2.dockerfile 将应用打包为镜像
3.docker-compose yaml 文件 定义整个服务,需要的环境
4. 启动 compose
流程
1. 创建网络
2. 执行 dockercompose.yaml
3. 启动服务
默认的服务名 文件名_服务名_num
_num 代表副本数量
docker-compose 自动维护一个网络,项目中的内容都在同个网络下,实现域名访问
启动 docker-compose up -d
停止 docker-compose down ctrl+c
# yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 version: '' services: 服务1:web images build network 服务2:redis ... volumes: networks: configs:
Compose file version 3 reference (docker.com)
# docker-compose 搭建 WordPress
awesome-compose/compose.yaml at master · docker/awesome-compose (github.com)
1. 下载项目 (docker-compose.yml)
2. 如果需要 dockerfile
3. 文件准备齐全,一键启动
# 实战
1. 编写微服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package com.example.demo.controller;import jakarta.annotation.Resource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;@RestController public class HelloController { @Autowired StringRedisTemplate stringRedisTemplate; @GetMapping("/hello") public String hello () { Long views = stringRedisTemplate.opsForValue().increment("views" ); return "hello" + views; } }
2.dockerfile 构建镜像
1 2 3 4 5 6 7 8 9 10 FROM hzkjhub/java17:17.0.4 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
3.docker-compose.yml 编排项目
1 2 3 4 5 6 7 8 9 10 11 12 version: "3.9" services: web: build: . image: haha depends_on: - redis ports: - "8080:8080" redis: image: "redis:alpine3.8"
4. 服务器 up 启动
使用 docker-compose 搭建 nextcloud+Nginx+MySQL+Redis | Case of Xeon (chensmallx.top)
docker-compose 搭建 nginx+php+redis+mysql 环境 - 腾讯云开发者社区 - 腾讯云 (tencent.com)
(66 条消息) Docker-compose 部署 nginx+mysql 模板_docker 部署 nginx mysql_仓鼠 小白的博客 - CSDN 博客
# docker-compose network
# 类型
# default
当我们运行 docker-compose up 时,将会执行以下几步:
创建一个名为 myapp_default 的网络;
使用 web 服务的配置创建容器,它以 “web” 这个名称加入网络 myapp_default;
使用 db 服务的配置创建容器,它以 “db” 这个名称加入网络 myapp_default。
默认情况下 docker-compose 会建立一个默认的网络,名称为 docker-compose.yml 所在目录名称小写形式加上 “_default”,我们的 TFLinux 环境就是 “tflinux_default”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@hecs-346515 ~] [root@hecs-346515 ngsql] app cache db docker-compose.yml proxy [root@hecs-346515 ~] NETWORK ID NAME DRIVER SCOPE 5ed45bf78d6f app_default bridge local 2eea384bdd95 bridge bridge local 73c5128a4cfc com-nginx_default bridge local 362bcfa74398 composetest_default bridge local a919986fdc8c host host local a1c8315f1897 my_wordpress_default bridge local d1e6b687dcd0 ngsql_default bridge local a0d53da9cf10 none null local
这个默认网络会对所有 services 下面的服务生效,所以 services 下面的各个服务之间才能够通过 service 名称互相访问。
如果要自定义默认网络可以针对 “default” 网络进行设置,这样就会影响导默认网络了。
1 2 3 4 networks: default: driver: bridge
# 自定义
除了默认网络之外,我们也可以建立自定义的网络,这个网络名称就比较随意了。
1 2 3 4 networks: persist: driver: bridge
# 已存在网络
通过 docker network create 创建好的网络,而不是让 docker-compose 创建一个新的,这个时候就需要用到 “external” 关键字了。
1 2 3 4 5 networks: persist: external: name: bridge2
Docker Compose 网络设置 - 掘金 (juejin.cn)
docker-compose 的网络 networks 的使用技巧 - 知乎 (zhihu.com)
使用 docker-compose 搭建 nextcloud+Nginx+MySQL+Redis | Case of Xeon (chensmallx.top)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 version: '3.4' services: db: image: mariadb restart: unless-stopped expose: - "3306" volumes: - ./db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=root_password - MYSQL_DATABASE=nextcloud - MYSQL_USER=user_name - MYSQL_PASSWORD=user_password cache: image: redis restart: unless-stopped expose: - "6379" volumes: - ./cache:/data command: redis-server --requirepass 'redis_password' app: image: nextcloud:fpm restart: unless-stopped expose: - "9000" volumes: - ./app/html:/var/www/html - ./app/data:/var/www/html/data - ./app/config:/var/www/html/config - ./app/custom_apps:/var/www/html/custom_apps links: - db:db - cache:cache depends_on: - db - cache proxy: image: nginx restart: unless-stopped expose: - "80" ports: - 7788 :443 volumes: - ./app/html:/var/www/html - ./proxy/conf.d:/etc/nginx/conf.d:ro - ./proxy/ssl_certs:/etc/nginx/ssl_certs:ro links: - app:app depends_on: - app
# docker swarm
集群的方式部署
操作都在 manager
# 搭建集群
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 初始化管理节点 [root@iZuf6dzrpxpwleuxiysmvrZ ~]# docker swarm init --advertise-addr 172.26.35.5 Swarm initialized: current node (amsigufjp7n6t878um697rtxx) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-378os4pztqynptic0b8kdsgysg21lq6x1u7ru4nxrv99ym9mgc-1hwbeetgvza2ympnj0s9kep3l 172.26.35.5:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. 加入节点 docker swarm join 获取令牌 docker swarm join-token manager docker swarm join-token worker [root@iZuf6dzrpxpwleuxiysmvrZ ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION amsigufjp7n6t878um697rtxx * iZuf6dzrpxpwleuxiysmvrZ Ready Active Leader 23.0.3 cg0dbg0k739u58yybwwlowr3z iZuf6dzrpxpwleuxiysmvsZ Ready Active 23.0.3 systemctl stop firewalld systemctl disable firewalld
1. 生成主节点 inti
2. 加入 (manager , worker)
# raft
保证大多数节点存活才可以用,集群至少 > 3 台主节点,必须保证大多数节点存活才可以使用,>1
双主双从的情况下:
manager 停止一个,另一个 manager 也不能用了
其他 worker 随便离开
work 只是工作,需要在管理节点操作
三主一从
至少有两个主存活集群还能使用
# 弹性创建服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@iZuf6dzrpxpwleuxiysmvrZ ~]# docker service --help Usage: docker service COMMAND Manage Swarm services Commands: create Create a new service inspect Display detailed information on one or more services logs Fetch the logs of a service or task ls List services ps List the tasks of one or more services rm Remove one or more services rollback Revert changes to a service's configuration scale Scale one or multiple replicated services update Update a service
灰度发布:金丝雀发布 升级不影响使用
1 2 3 4 5 6 [root@iZuf6dzrpxpwleuxiysmvrZ ~] vrs4gx1m5dyydclezt4bbwnkj overall progress: 1 out of 1 tasks 1/1: running verify: Service converged
1 2 docker run docker service
1 2 3 4 5 6 7 8 9 10 11 12 [root@iZuf6dzrpxpwleuxiysmvrZ ~] ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 2eewg8do04rd nginx001.1 nginx:latest iZuf6dzrpxpwleuxiysmvrZ Running Running about a minute ago [root@iZuf6dzrpxpwleuxiysmvrZ ~] ID NAME MODE REPLICAS IMAGE PORTS vrs4gx1m5dyy nginx001 replicated 1/1 nginx:latest *:8888->80/tcp [root@iZuf6dzrpxpwleuxiysmvrZ ~] [root@iZuf6dzrpxpwleuxiysmvrZ ~] [root@iZuf6dzrpxpwleuxiysmvrZ ~] [root@iZuf6dzrpxpwleuxiysmvrZ ~] [root@iZuf6dzrpxpwleuxiysmvrZ ~]
swarm
集群的管理和编排,docker 可以初始化一个集群,其他节点可以加入
加入时由 manager 和 worker 角色
node
就是一个 docker 节点,多个节点组成了网络集群
service
任务,可以在管理节点或工作节点运行。用户访问的就是他
task
容器内的命令
命令 -> 管理 ->api -> 调度 -> 工作节点 (创建 task 容器维护)
调整 service 以什么方式运行
1 2 3 4 5 6 --mode string global server / replicated service [root@iZuf6dzrpxpwleuxiysmvrZ ~] [root@iZuf6dzrpxpwleuxiysmvrZ ~]
global 能在任何节点运行,replicated 只能在 worker 运行,默认 replicated
1 [root@iZuf6dzrpxpwleuxiysmvrZ ~]# yum install bridge-utils.x86_64
swarm 中有三个网络,ingress,overlay,
ingress:特殊的 overlay,具有负载均衡功能
# Docker Stack
集群部署项目,相当于集群版的 docker-compose
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 docker stack deploy 111.yml [root@iZuf6dzrpxpwleuxiysmvrZ ~] Usage: docker stack COMMAND Manage Swarm stacks Commands: config Outputs the final config file, after doing merges and interpolations deploy Deploy a new stack or update an existing stack ls List stacks ps List the tasks in the stack rm Remove one or more stacks services List the services in the stack
# docker secret
安全,证书,配置密码
1 2 3 4 5 6 7 8 9 10 11 12 13 [root@iZuf6dzrpxpwleuxiysmvrZ ~]# docker secret --help Usage: docker secret COMMAND Manage Swarm secrets Commands: create Create a secret from a file or STDIN as content inspect Display detailed information on one or more secrets ls List secrets rm Remove one or more secrets
# docker config
配置
1 2 3 4 5 6 7 8 9 10 11 12 [root@iZuf6dzrpxpwleuxiysmvrZ ~]# docker config --help Usage: docker config COMMAND Manage Swarm configs Commands: create Create a config from a file or STDIN inspect Display detailed information on one or more configs ls List configs rm Remove one or more configs
# ctr && crictl
Containerd 也有 namespaces 的概念,对于上层编排系统的支持,主要区分了 3 个命名空间分别是 k8s.io 、 moby 和 default ,以上我们用 crictl 操作的均在 k8s.io 命名空间完成如查看镜像列表就需要加上 -n 参数
1 ctr -n k8s.io images list