一.安装和连接1.建立ssh连接sudo apt update sudo apt install -y ssh这两条命令都是Debian/Ubuntu 系列 Linux 系统中的包管理命令用于「更新软件源信息」和「安装 SSH 服务」最终实现让你的虚拟机可以被远程 SSH 连接。2.下载docker执行以下命令卸载所有冲突包sudo apt remove $(dpkg --get-selections docker.io docker-compose docker-compose-v2 docker-doc podman-docker containerd runc | cut -f1)搭建仓库第一次在新主机上安装Docker Engine之前你 需要搭建 Docker 仓库。之后你可以安装并更新 从仓库里拿到Docker。# Add Dockers official GPG key: sudo apt update sudo apt install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc # Add the repository to Apt sources: sudo tee /etc/apt/sources.list.d/docker.sources EOF Types: deb URIs: https://download.docker.com/linux/ubuntu Suites: $(. /etc/os-release echo ${UBUNTU_CODENAME:-$VERSION_CODENAME}) Components: stable Signed-By: /etc/apt/keyrings/docker.asc EOF sudo apt update安装docker#安装最新版本 想使用别的版本的话使用https://docs.docker.com/engine/install/ubuntu/获取 sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin #Docker 服务在安装后会自动启动。验证这一点 Docker 正在运行请使用 sudo systemctl status docker #有些系统可能关闭了该行为需要手动启动 sudo systemctl start docker #验证安装 sudo docker run hello-world成功显示配置使用加速镜像sudo mkdir -p /etc/docker sudo nano /etc/docker/daemon.json #将以下内容粘到daemon.json中 { registry-mirrors: [ https://docker.m.daocloud.io ] } #然后应用配置二.镜像管理1.镜像导出与导入命令docker save将一个或多个镜像打包成tar文件docker load从tar文件加载镜像到本地仓库当两台服务器中有一台可以拉取镜像而另外一个不能拉取镜像可以使用这两个命令将已安装的镜像压缩或者不压缩发送到未安装的服务器中演示注意事项必须使用-o参数指定输出文件否则会输出到终端支持同时导出多个镜像docker save -o all.tar 镜像1 镜像2直接添加.gz后缀不会自动压缩需要使用gzip命令处理压缩方法先导出后压缩管道流式压缩压缩效果示例中7.79MB的alpine镜像压缩后变为3.5MB将文件发送给另一台导出2.导入镜像时名称丢失问题3.镜像删除sudo docker images//查看镜像 sudo docker rmi hello-world:latest //删除镜像rmi后镜像名字4.自动补全sudo curl http://www.wangxiaochun.com:8888/testdir/docker/docker_completion.sh -o /etc/bash_completion.d/docker.sh //执行后可实现docker的自动补全功能 使用Tab建5.贴镜像标签sudo docker tag hello-world:latest ab3.1三.docker的常用命令帮助命令docker version //打印基本信息 docker info //显示系统信息 docker --hele 万能命令镜像命令docker images //查看镜像 -a //显示所有镜像 -q //只显示id搜索镜像docker search mz //搜索 --filterSTARS3000 //搜索stars大于3000的下载镜像docker pull name //下载镜像删除镜像docker rmi -f id id //删除指定images docker rmi -f $(docker images -aq) //删除所有说明有镜像才可以创建容器下载一个cenrtos示例docker pull centos //新建并启动 docker run {可选参数} images //参数 --name -d //后台启动 -i -t //交互方式 -p //指定端口 -P //随机指定端口 //测试 nikenike-VMware-Virtual-Platform:~$ docker run -it centos:7 /bin/bash [rootc1d97604e8ff /]# //启动并测试 exit //退出 //列出容器 docker ps //运行的 -a //正在运行 和曾经 -n /限制个数 -q //只显示编号退出容器exit //直接退出 Ctrl p Q //容器不停止退出 删除容器 docker rm //删除指定容器不能删除正在运行的容器 docker rm -f docker ps -aq //删除所有容器 docker ps -a -q|xargs docker rm //删除所有容器启动和停止容器docker start docker restart docker stop docker kill //强制停止常用其他命令docker run -d name //发现docker ps name 停止了 //常见的问题docker容器使用后台运行就必须要有一个前台进程 docker logs -f -t --tail //查看日志 --tail shuzi //显示条数 -tf //显示日志 //查看进程 docker top id //查看进程 docker inspect id //查看元数据 ##进入当前正在运行的容器 docekr exec -it id //进入容器开启一个新终端 docker attach id //进入容器原有终端 拷贝容器文件到主机 docker cp id路劲 目的路劲练习 安装Nginxdocker pull nginx docker run -d --name nginx01 -p 3344:80 nginx:latest docker run -it --rm tomcat //rm 用完就删除 docker run -d -p 3355:80 --name tomcat01 tomcat练习 安装elscsearchdocker run -d --name elasticsearch -p 9300:9200 -p 9300:9300 -e discovery.typesingle-node elasticsearch:7.6.2 docker stats --查看cpu的状态综合案例wordpress博客系统镜像 wordpress docker run --name wordrepess -d --restart always -p 80:80 registry.cn-beijing.aliyuncs.com/wangxiaochun/wordpress:php8.2-apache mysql: docker run --name mysql -d --restart always --env-file env.txt -p 3306:3306 registry.cn-beijing.aliyuncs.com/wangxiaochun/mysql:8.0.29-oracle 端口暴露之后就可以使用宿主机地址 创建env.txt文件 # 创建 env.txt 并写入一行示例内容可自定义 echo MYSQL_ROOT_PASSWORD123456 env.txt # 追加多行内容用 不会覆盖原有内容 echo MYSQL_DATABASEwordpress env.txt echo MYSQL_USERwordpress env.txt echo MYSQL_PASSWORD654321 env.txt docker inspect //查看容器端口四.可视化portainer图形化管理工具docker run -d -p 8088:9000 --restartalways -v /var/run/docker.sock:/var/run/docker.sock --privilegedtrue portainer/portainer测试IP地址 8088commit镜像docker commit 提交一个镜像实战测试先运行tomcat docker run -p 8080:8080 tomcat //启动后没有webapps应用 在另外一个会话中打开 docker exec -it e61884c3c5a9 /bin/bash 复制webapps到 cp -r webapps.dist/* webapps 提交镜像 docker commit -akaikai -madd webapps app e61884c3c5a9 tomcat02:1.0容器数据卷什么是容器数据卷数据如果数据都在容器中容器删除那么数据也会丢失那么就要使用容器数据卷将数据同步到本地作用容器持久化和同步作用使用方式一直接使用命令挂载 -v docker run -it -v 主机目录容器内目录 docker run -it -v /home/ceshi:/home centos /bin/bash --测试 docker inspect 72d550954e7a --查看挂载信息挂载信息数据同步双向操作实战安装mysql--运行容器时进行容器挂载 docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD123456 --name mysql001 mysql:5.7 -d -p -v -e --name具名挂载和匿名挂载-v 时只写容器内路径是匿名加上卷名字就是具名不指定目录都在/var/lib/docker/volumes/下dockerfile构建docker镜像的镜像文件使用脚本生成镜像测试创建一个构建文件建议起名为 dockerfile 将以下内容写到该文件中 sudo vim dockerfile1 FROM centos VOLUME[volume01,volume02] CMD echo----end----- CMD /bin/bash ~创建镜像 docker build -f dockerfile1 -t kk/centos:1.0 .刚才挂载的卷有显示docker inspect 315606e0cdc5 通过这个可查看外部挂载的目录数据卷容器多个mysql同步数据启动第一个docker run -it --name docker02 --volumes-from docker01 kk/centos:1.0 第二个继承第一个02挂载了01dockerfile核心构建步骤1编写一个dockerfile文件2dockerbuild构建成为一个镜像‘3docker run 运行镜像4docker push 发布镜像hub,,阿里云dockerfile构建过程基础知识1每一个保留关键字都必须是大写字母2执行从上到下3#表示注释4每一指令都会创建提交一个新的镜像曾并提交dockerfile是面向开发的以后发布项目就要编写dockerfile文件十分简单docker镜像成为企业交付的标准dockerfile指令FROM #基础镜像 MAINTAINER //维护者的信息 姓名邮箱 RUN //镜像构建是需要运行的命令 ADD //步骤tomact镜像添加内容 WORKDIR //镜像的工作目录 VOLUME //挂载的目录 EXPOST //暴露端口使用的时候不由-p CMD //启动容器启动的时候要运行的命令只有最后一个会生效 ENTRYPOINT //启动容器启动的时候要运行的命令,可以追加命令 ONBUILD //当构建一个被继承的dockerfile这时候就会运行 COPY //类似add 将我们的文件拷贝到境相当中 ENV //构建时设置环境变量实战测试vim mydockerfile-centos //编辑文件 ///dockerfile 文件内容 FROM sentos MAINTAINER kakai18422460qq.com ENV MYPATH /usr/local WORKDIR $MYPATH RUN yun -y install vim RUN yun -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo ---end--- CMD /bin/bash docker build -f mydockerfile-centos -t mycentos:0.1 . //构建镜像cmd和entrypoint的区别cmdvim mydockerfile-cmd-text FROM centos CMD [ls,-a] docker build -f mydockerfile-cmd-text -t cmdtest . //cmd最后一行生效 nikenike-VMware-Virtual-Platform:~/dockerfile$ docker run aa7856038557 . .. .dockerenv anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var ///想追加一个-l 。。。报错 nikenike-VMware-Virtual-Platform:~/dockerfile$ docker run -l flag needs an argument: l in -l Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run docker run --help for more information测试entrpoint与cmd不同它可以直接追加nikenike-VMware-Virtual-Platform:~/dockerfile$ docker run e85f96bc7be9 . .. .dockerenv anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var nikenike-VMware-Virtual-Platform:~/dockerfile$ docker run e85f96bc7be9 -l total 64 drwxr-xr-x 1 root root 4096 Mar 23 11:50 . drwxr-xr-x 1 root root 4096 Mar 23 11:50 .. -rwxr-xr-x 1 root root 0 Mar 23 11:50 .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 Mar 23 11:50 dev drwxr-xr-x 1 root root 4096 Mar 23 11:50 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 349 root root 0 Mar 23 11:50 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 Mar 23 11:50 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实战tomcat镜像先下载压缩包wget https://repo.huaweicloud.com/java/jdk/17.0.107/jdk-17.0.10_linux-x64_bin.tar.gz wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.88/bin/apache-tomcat-9.0.88.tar.gz编写dockerfileFROM centos:centos7 MAINTAINER kaikai184220460qq.com # 把 JDK 压缩包 解压到 /usr/local ADD jdk-8u202-linux-x64.tar.gz /usr/local/ # 把 Tomcat 压缩包 解压到 /usr/local ADD apache-tomcat-8.5.99.tar.gz /usr/local/ # 安装必要工具 RUN yum -y install vim # 设置工作目录 ENV MYPATH /usr/local WORKDIR $MYPATH # JDK 环境变量 ENV JAVA_HOME/usr/local/jdk1.8.0_202 ENV PATH$PATH:$JAVA_HOME/bin # Tomcat 环境变量 ENV CATALINA_HOME/usr/local/apache-tomcat-8.5.99 ENV PATH$PATH:$CATALINA_HOME/bin EXPOSE 8080 CMD /usr/local/apache-tomcat-8.5.99/bin/startup.sh tail -F /url/local//usr/local/apache-tomcat-8.5.99/bin/logs/catalina.out ~ Tomcat$ docker build -t diytomcat .构建Dockerfilenikenike-VMware-Virtual-Platform:~/dockerfile/Tomcat$ docker run -d -p 9090:8080 --name kaikaitomcat -v /home/nike/dockerfile/Tomcat/test:/url/local/apache-tomcat-8.5.99/webapps/test -v /home/nike/dockerfile/Tomcat/test:/url/local/apache-tomcat-8.5.99/logs diytomcat 23669f944787b31f02b2e5db00a8b89e0f030164e2ba90d0e7a0763e5f343a6f发布镜像1地址hub.docker.com2,确定这个帐号可以登录3在我们的服务器上提交Docker网络理解Docker网络测试本机回环地址阿里云内网地址docker0地址三个网络问题docker怎么处理网络地址访问测试docker run -d -P --name tomcat01 tomcat查看容器ip外部可以ping同且多了网络多个容器之间也可以ping通只要容器删除网桥就会消失自定义网络查看所有的docker网络网络模式brige桥接none不配置网络host和宿主公用container容器网络联通测试docker run -d -P --name tomcat01 --net bridge tomcat //命令中默认自带--net bridge而这个就是docker0 docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet //创建网络 docker network inspect mynet //查看网络 nikenike-VMware-Virtual-Platform:~$ docker run -d -P --name tomcat01-net-01 --net mynet tomcat 26d8ca0ac331d97f2bb5148374d9ba2bd949d02e3bc9f129ed17f9776c9a473f nikenike-VMware-Virtual-Platform:~$ docker run -d -P --name tomcat01-net-02 --net mynet tomcat 574f58d5147a91ed619a63db958a6c43abbcfc08fbf46276ac53337e8ce835ef 用自己的网络启动容器查看网络nikenike-VMware-Virtual-Platform:~$ docker network inspect mynet[{Name: mynet,Id: be3e2552750422f2be4f95e3f9c8e645c02f8ff0e81d284391531d9634847327,Created: 2026-03-24T21:01:36.23808922608:00,Scope: local,Driver: bridge,EnableIPv4: true,EnableIPv6: false,IPAM: {Driver: default,Options: {},Config: [{Subnet: 192.168.0.0/16,IPRange: ,Gateway: 192.168.0.1}]},Internal: false,Attachable: false,Ingress: false,ConfigFrom: {Network: },ConfigOnly: false,Options: {},Labels: {},Containers: {26d8ca0ac331d97f2bb5148374d9ba2bd949d02e3bc9f129ed17f9776c9a473f: {Name: tomcat01-net-01,EndpointID: 42e70208bf7b1f071a9e5b8e5555550390358ba57f24739146cab58236359122,MacAddress: a6:75:63:b8:95:bb,IPv4Address: 192.168.0.2/16,IPv6Address: },574f58d5147a91ed619a63db958a6c43abbcfc08fbf46276ac53337e8ce835ef: {Name: tomcat01-net-02,EndpointID: f5c32bf4d0870c5c4f41086ec83ade07ddad8c95c8981b0e29d37a20fcf84e1e,MacAddress: a2:22:a7:00:d8:8b,IPv4Address: 192.168.0.3/16,IPv6Address: }},Status: {IPAM: {Subnets: {192.168.0.0/16: {IPsInUse: 5,DynamicIPsAvailable: 65531}}}}}]多了两个IP现在可以直接ping容器名字就可以成功结构实现一个容器连接一个网络那么tomcat01就可以和tomcat-net01平通docker network connect [OPTIONS] NETWORK CONTAINERdocker network connect mynet tomcat01 //网络名容器名字连通后就是将tomcat加入到网络mynet中结论如果跨网络的化就要使用上述操作实战部署redis集群架构图docker network create redis --subnet 172.38.0.0/16 //创建网卡for port in $(seq 1 6); \do \mkdir -p /mydata/redis/node-${port}/conftouch /mydata/redis/node-${port}/conf/redis.confcat EOF /mydata/redis/node-${port}/conf/redis.confport 6379bind 0.0.0.0cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000cluster-announce-ip 172.38.0.1${port}cluster-announce-port 6379cluster-announce-bus-port 16379appendonly yesEOFdone####创建redis的脚本使用脚本创建6个redis成功for port in $(seq 1 6); do docker run -d --name redis-$port -p 637$port:6379 -p 1637$port:16379 -v /mydata/redis/node-$port/data:/data -v /mydata/redis/node-$port/conf/redis.conf:/etc/redis/redis.conf --net redis --ip 172.38.0.1$port redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; done##一键启动六个redisdocker exec -it redis-1 /bin/sh #进入redisredis-cli --cluster create 192.38.0.11:6379 192.38.0.12:6379 192.38.0.13:6379 192.38.0.14:6379 192.38.0.15:6379 192.38.0.16:6379 --cluster-replicas 1#创建集群#创建成功/data # 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:6379 172.38.0.16:6379 --cluster-replicas 1 Performing hash slots allocation on 6 nodes...Master[0] - Slots 0 - 5460Master[1] - Slots 5461 - 10922Master[2] - Slots 10923 - 16383Adding replica 172.38.0.15:6379 to 172.38.0.11:6379Adding replica 172.38.0.16:6379 to 172.38.0.12:6379Adding replica 172.38.0.14:6379 to 172.38.0.13:6379M: 72f98c556c06e2710096d667221d1b7b8aedd0d7 172.38.0.11:6379slots:[0-5460] (5461 slots) masterM: 2c0417be55096e2728fae757e42bc0a34c8cf632 172.38.0.12:6379slots:[5461-10922] (5462 slots) masterM: bd86c1b6c02e04676a4fb50b005ac4f831247eb8 172.38.0.13:6379slots:[10923-16383] (5461 slots) masterS: 8c4eaa3181d89a51fd57e8d05cd4ff108feb442b 172.38.0.14:6379replicates bd86c1b6c02e04676a4fb50b005ac4f831247eb8S: c7c1d0db3e4137182c4e768bab8f30f73688f27f 172.38.0.15:6379replicates 72f98c556c06e2710096d667221d1b7b8aedd0d7S: 0e7e0395dbb6fdf09e4d27cd7a869cba60bb0ff6 172.38.0.16:6379replicates 2c0417be55096e2728fae757e42bc0a34c8cf632Can I set the above configuration? (type yes to accept): yes Nodes configuration updated Assign a different config epoch to each node Sending CLUSTER MEET messages to join the clusterWaiting for the cluster to join.. Performing Cluster Check (using node 172.38.0.11:6379)M: 72f98c556c06e2710096d667221d1b7b8aedd0d7 172.38.0.11:6379slots:[0-5460] (5461 slots) master1 additional replica(s)M: 2c0417be55096e2728fae757e42bc0a34c8cf632 172.38.0.12:6379slots:[5461-10922] (5462 slots) master1 additional replica(s)S: 0e7e0395dbb6fdf09e4d27cd7a869cba60bb0ff6 172.38.0.16:6379slots: (0 slots) slavereplicates 2c0417be55096e2728fae757e42bc0a34c8cf632M: bd86c1b6c02e04676a4fb50b005ac4f831247eb8 172.38.0.13:6379slots:[10923-16383] (5461 slots) master1 additional replica(s)S: 8c4eaa3181d89a51fd57e8d05cd4ff108feb442b 172.38.0.14:6379slots: (0 slots) slavereplicates bd86c1b6c02e04676a4fb50b005ac4f831247eb8S: c7c1d0db3e4137182c4e768bab8f30f73688f27f 172.38.0.15:6379slots: (0 slots) slavereplicates 72f98c556c06e2710096d667221d1b7b8aedd0d7[OK] All nodes agree about slots configuration. Check for open slots... Check slots coverage...[OK] All 16384 slots covered./data #测试集群/data # redis-cli -c127.0.0.1:6379 cluster infocluster_state:okcluster_slots_assigned:16384cluster_slots_ok:16384cluster_slots_pfail:0cluster_slots_fail:0cluster_known_nodes:6cluster_size:3cluster_current_epoch:6cluster_my_epoch:1cluster_stats_messages_ping_sent:139cluster_stats_messages_pong_sent:145cluster_stats_messages_sent:284cluster_stats_messages_ping_received:140cluster_stats_messages_pong_received:139cluster_stats_messages_meet_received:5cluster_stats_messages_received:284#查看基础信息127.0.0.1:6379 cluster nodes2c0417be55096e2728fae757e42bc0a34c8cf632 172.38.0.12:637916379 master - 0 1774440782000 2 connected 5461-109220e7e0395dbb6fdf09e4d27cd7a869cba60bb0ff6 172.38.0.16:637916379 slave 2c0417be55096e2728fae757e42bc0a34c8cf632 0 1774440782000 6 connectedbd86c1b6c02e04676a4fb50b005ac4f831247eb8 172.38.0.13:637916379 master - 0 1774440782109 3 connected 10923-163838c4eaa3181d89a51fd57e8d05cd4ff108feb442b 172.38.0.14:637916379 slave bd86c1b6c02e04676a4fb50b005ac4f831247eb8 0 1774440782518 4 connected72f98c556c06e2710096d667221d1b7b8aedd0d7 172.38.0.11:637916379 myself,master - 0 1774440781000 1 connected 0-5460c7c1d0db3e4137182c4e768bab8f30f73688f27f 172.38.0.15:637916379 slave 72f98c556c06e2710096d667221d1b7b8aedd0d7 0 1774440782622 5 connected##主从信息127.0.0.1:6379 set a b- Redirected to slot [15495] located at 172.38.0.13:6379OK172.38.0.13:6379 gat a^C/data # get a/bin/sh: get: not found/data # redis-cli -c127.0.0.1:6379 gat a(error) ERR unknown command gat, with args beginning with: a,127.0.0.1:6379 get a- Redirected to slot [15495] located at 172.38.0.14:6379b#13挂了之后从节点14接替了13