小工具知识网

当前位置: 首页 > 行业知识 > 云时代【6】—— 镜像 与 容器

行业知识

云时代【6】—— 镜像 与 容器

2026-11-05 22:31:09 来源:互联网转载

云时代【6】—— 镜像 与 容器

  • 四、Docker
    • (三)镜像 与 容器
      • 1. 镜像
        • (1)定义
        • (2)相关指令
        • (3)实战演习
          • 镜像容器基本操作
          • 离线迁移镜像
          • 镜像的压缩与共享
          • 2. 容器
            • (1)定义
            • (2)容器的生命周期
            • (3)基本指令
              • 与容器交互
              • 容器的资源使用
              • 容器与宿主机
              • 容器与镜像
              • (4)实战演习
                • A. 实际操作案例
                • B. MySQL 与 Redis的容器化安装
                • C. Java 程序的容器制作
                • D. 容器资���更新

                  四、Docker

                  (三)镜像 与 容器

                  1. 镜像

                  (1)定义

                  镜像 的作用可以看成:纳戒 + 模板。 镜像”模板“很好理解,它指的是:镜像可以被快速复制(拉取);而镜像”纳戒“的本质是: **Union FS** 联合文件系统。
                  它可以将几层目录挂载到一起,形成一个虚拟文件系统。每一层文件系统我们叫做一层 layer。联合文件系统可以对每一层文件系统设置三种权限:只读**(readonly)**、读写**(readwrite)**和写出**(whiteout-able)**,但是** ****docker**镜像中每一层文件系统都是只读的。 构建镜像的时候,从一个最基本的操作系统开始,每个构建的操作都相当于做一层的修改,增加了一层文件系统。一层层往上叠加,上层的修改会覆盖底层该位置的可见性。当你使用的时候,你只会看到一个完全的整体,你不知道里面有几层,也不清楚每一层所做的修改是什么。

                  理解了镜像”纳戒“的本质是联合文件系统之后,我们就能很好的理解镜像的优缺点了。

                  • 优点:

                    • 屏蔽了环境的差异
                    • 分层的存储:可以充分利用共享层(减少存储空间的占用)
                    • 快速分发(只添加缺失的层)
                    • 缺点:

                      • 镜像添加的依赖占用机器的空间
                      • 寻找文件只能一层一层找,会带来一定的性能损失
                        (2)相关指令
                        docker rmi [镜像]:[版本]docker rmi 'IMAGE ID'# --no-prune 不移除该镜像的过程镜像
                        docker run -it --name mybusybox busybox:1.35.0 shdocker rmi busybox:1.35.0 # errordocker rmi -f busybox:1.35.0 # 但是强制删除也没必要,可以先删除容器,再删除镜像

                        docker save -o xxx.tar [镜像]:[版本]# 下图大小没有发生变化主要原因是:打了同一个镜像!(IMAGE ID相同)
                        docker load -i xxx.tar
                        docker load -i xxx.tar -q # -q 是安静模式(不显示进度条)

                        docker history [镜像]:[版本号]# --no-trunc 不做截断(显示全部信息)

                        # 该层镜像不被任何一层镜像使用docker image prune# -a 删除全部不被容器使用的镜像
                        (3)实战演习
                        镜像容器基本操作
                        docker search busyboxdocker pull busybox:1.36.0docker images busybox# 查看镜像的下载位置cd /data/var/lib/docker # 在 /etc/docker/daemon.jsoncd overlay2cat repositories.json# 查看镜像的详细信息docker image inspect busybox:1.36.0# 查看镜像的分层docker history busybox:1.36.0# 给镜像打标签docker tag busybox:1.36.0 lllzxx/fortest:v1.36.0docker push lllzxx/fortest:v1.36.0 -a# 查看登录站点cat /root/.docker/config.json# 拉取镜像docker pull lllzxx/fortest:v1.36.0# 运行容器docker run -it -d --name mybusybox -h myweb -e myenv=test lllzxx:v1.36.0 shifconfigexit# 查看所有容器docker ps -a# 删除镜像docker rmi lllzxx/fortest:v1.36.0docker rm 'IAMGE ID' # 删除容器
                        离线迁移镜像
                        # A服务器docker pull lllzxx/fortest:v1.36.0cd /data/lllzxxdocker imagesdocker save -o mybusybox.tar lllzxx/fortest:v1.36.0# B服务器docker version # 检查是否安装Docker,没有则安装mkdir -p /data/lllzxxcd /data/lllzxxll# A服务器scp mybusybox.tar root@IP:/data/lllzxx # 需要输入密码# B服务器lldocker load -i mybusybox.tardocker imagesdocker run -it lllzxx/fortest:v1.36.0 shifconfigping www.baidu.comexit
                        镜像的压缩与共享
                        docker images nginxdocker pull [镜像]:[版本号] # 查看远端和本地的大小是否一样?# 不一样。远端:①节省存储空间 ②减少网络带宽# 如果远端的镜像是相同的,只是不同别名的话并不会真正上传,只会标示出不同镜像

                        2. 容器

                        (1)定义

                        容器是镜像的运行实体。镜像是静态的只读文件,而是容器带有运行时需要的可写文件层,并且容器中的进程属于运行状态。容器本质上是主机运行的一个进程,但是该进程被进行了各种各样的限制,无法看到主机的进程、环境变量、网络等信息。
                        注:不同角度理解会对容器做出不同定义,其他角度见”云时代【1】“。

                        (2)容器的生命周期
                        (3)基本指令
                        docker create --name mywebs1 -p 8080:80 nginx:1.23.4 # 创建容器(拧钥匙)docker ps -a | grep mywebs1docker start mywebs1 # 启动容器(踩油门)docker ps -a | grep mywebs1
                        docker container inspect mywebs2docker container inspect -s mywebs2 # -s 显示总的文件大小
                        docker stop mywebs2 # 停止-踩刹车# 使用 stop 超时也会杀***容器docker start mywebs2 # 开启-踩油门
                        docker ps -a | grep mywebs2docker logs -f -n 5 mywebs2docker restart mywebs2docker restart -s 9 mywebs2
                        docker kill mywebs2
                        docker wait mywebs3
                        docker run -d --name mywebs3 nginx:1.23.4docker ps -adocker stop mywebs3docker container prunedocker ps -a
                        docker rm -f [容器名] # -f 强制删除运行中的容器# 重新 docker run 的话,名称和端口相同也不会冲突
                        docker logs mywebs2# -f 跟踪日志输出# -since="2099-01-01"# -n x 多少条数据

                        与容器交互
                        docker attach mywebs2# 使用 ctrl + c 之后会直接退出容器(熄火)docker attach --sig-proxy=false mywebs2# --sig-proxy 使用 ctrl + c 之后不会退出容器
                        docker exec -it mywebs2 bash
                        docker exec -it -d mywebs2 nginx -V # 在后台运行容器docker exec -it -e mynginx=lllzxx mywebs2 bash # 设置容器的环境变量docker exec -it mywebs2 cat /etc/passwddocker exec -it -u nginx mywebs2 nginx -v # 指定用户docker exec -it -w /etc mywebs2 bash # 指定工作目录

                        容器的资源使用
                        docker top mywebs2 docker top mywebs2 aux # aux 能够查看资源使用情况
                        docker pause mywebs3docker unpause mywebs3
                        docker stats -a --no-stream --no-trunc mywebs2# -a 所有容器(停止的也打印)# --format 打印模式,默认是表格,可以使用json# --no-stream 不实时更新# --no-trunc 不截断输出
                        docker stats --format json
                        docker rename [旧名字] [新名字]
                        free -mdocker stats mywebs2docker update --memory 500m --memory-swap 500m mywebs2docker stats mywebs2# 一般来说都是会在创建容器的时候就规划好的

                        容器与宿主机
                        docker port mywebs2 docker port mywebs2 80/tcp # 使用tcp协议的
                        docker cp mywebs2:/usr/share/nginx/html/index.html .# .表示当前目录,即当前工作目录。# ..表示父目录,即当前目录的上一级目录。docker cp ./index.html mywebs2:/usr/share/nginx/html/index.html/
                        mkdir -p /data/lllzxx/textexport # -p 是递归地创建目录cd /data/lllzxx/textexportls -ldocker export -o myweb3.tar mywebs3docker import -m '将文件转回为镜像' mywebs3.tar mywebs3:v1.0 # 与 save 和 load 相比会丢失信息
                        # A服务器docker pull lllzxx/fortest:v1.36.0cd /data/lllzxxdocker imagesdocker save -o mybusybox.tar lllzxx/fortest:v1.36.0# B服务器docker version # 检查是否安装Docker,没有则安装mkdir -p /data/lllzxxcd /data/lllzxxll# A服务器scp mybusybox.tar root@IP:/data/lllzxx # 需要输入密码# B服务器lldocker load -i mybusybox.tardocker imagesdocker run -it lllzxx/fortest:v1.36.0 shifconfigping www.baidu.comexit
                        docker exec -it mywebs2 bashecho "Hello World!" > /test.htmlls -ldocker diff mywebs2

                        容器与镜像
                        docker imagesdocker run -d --name mywebsforcommit nginx:1.23.4docker ps | grep mywebsforcommitdocker images mywebsforcommitdocker commit mywebsforcommit mywebsforcommit:v1.0 # docker commit [容器] [镜像名]:[版本号]docker images mywebsforcommit
                        docker exec -it mywebsforcommit bashecho "Hello World!" > /testforcommit.txtls -lexitdocker diff mywebsforcommitdocker commit mywebsforcommit mywebsforcommit:v2.0docker run -it --rm mywebsforcommit:v2.0 bashls -lcat testforcommit.txtexit
                        docker commit -a 'lzxx' -m 'create by lzxx' -p mywebsforcommit mywebsforcommit:v3.0# -a 指定创建者# -m 描述信息# -p 创建镜像时停止
                        docker commit -a 'lzxx' -m 'create by lzxx' -c 'CMD ["tail","-f","/etc/hosts"]' -p mywebsforcommit mywebsforcommit:v4.0docker images mywebsforcommitdocker run -d --rm --name mywebsforcommit2 mywebsforcommit:v4.0docker ps --no-trunc | grep mywebsforcommit

                        (4)实战演习
                        A. 实际操作案例
                        docker images nginxdocker run -d --name mynginx01 -p 8101:80 nginx:1.22.0docker psdocker container inspet mynginx01docker logs -f -n 10 mynginx01docker rm mynginx01docker stop mynginx01docker ps -a | grep mynginx01
                        docker create --name mynginx02 -p 8102:80 nginx:1.22.0docker ps -a | grep mynginx02docker start mynginx02docker ps -a | grep mynginx02docker kill mynginx02docker ps -a | grep mynginx02docker start mynginx02docker ps -a | grep mynginx02docker stop mynginx02docker ps -a | grep mynginx02docker start mynginx02docker ps -a | grep mynginx02docker ps -a | grep mynginx02docker restart mynginx02docker ps -a | grep mynginx02docker pause mynginx02docker ps -a | grep mynginx02docker unpause mynginx02docker ps -a | grep mynginx02
                        # 批量过滤# ps : Process Status,即进程状态。docker ps -adocker stop mywebs1 mywebs2docker psdocker ps -f name=mywebs1docker ps -f status=exiteddocker ps -f ancestor=nginx:1.23.4docker ps -q# 批量操作docker stop `docker ps -q`docker ps -a
                        # A-1.attached模式--该模式是在前台运行,按 ctrl + c 就会退出容器,会简化开发的过程,但不能用于生产docker run --name mynginx03 -p 8103:80 nginx:1.22.0 docker ps | mynginx03# A-2.detached模式--在后台运行docker run -d --name myngine04 -p 8104:80 nginx:1.22.0docker ps | mynginx04exit # 断开连接docker ps | mynginx04 # 依旧在运行docker logs -f mynginx04# B.attach 会把 attached模式 转为 detached模式docker attach mynginx04ctrl + c docker ps -a | mynginx04 # C.interactive模式# C-1.创建一个可交互的容器docker run -it --name mynginx05 -p 8105:80 nginx:1.22.0 bashls /cat /etc/*release*nginx -vnginx # 正式启动nginxctrl + c # 没有影响exit # shell退出,也意味着:容器退出# C-2.与后台运行的容器交互docker run -it -d --name mynginx06 -p 8106:80 nginx:1.22.0docker exec -it mynginx06 bashcurl 127.0.0.1exit # shell退出,但容器依然正常运行
                        # 容器内部没有vim编辑器docker run -it -d --name mynginx07 -p 8107:80 nginx:1.22.0docker exec -it mynginx07 bashcd /usr/share/nginx/htmlls -lcat index.htmlvi index.html # refuseexitmkdir -p /data/lllzxx/testcpcd /data/lllzxx/testcpls -ldocker cp mynginx07:/usr/share/nginx/html/index.html .vi index.htmldocker cp ./index.html mynginx07:/usr/share/nginx/html/docker exec -it mynginx07 bashcd /usr/share/nginx/htmlcat index.html# 注意:cp 不支持容器与容器之间的拷贝
                        docker run -it --rm --name mynginx08 -p 8108:80 nginx:1.22.0 bashnginx -vexitdocker ps -a | grep mynginx08 # 查找不到docker run -d --rm --name mynginx08 -p 8108:80 nginx:1.22.0 # 一停止就删除docker ps | grep mynginx08docker stop mynginx08docker ps -a | grep mynginx08 # 同样查找不到
                        # restart: # no-不重启(默认);on-failure:3 指定重启次数;# always-总是重启;unless-stopped-中途退出也重启docker run -d --name mynginx09 -p 8109:80 --restart=always nginx:1.22.0docker exec -it mynginx09 bashnginx -s quit # 停止nginx服务docker ps | mynginx09 # 发生重启docker stop mynginx09 # 无法再次拉起
                        docker run -it --rm -e MYTEST1=1 -e MYTEST2=2 nginx:1.22.0 bashenv | grep MYTESTexit# 通过配置文件 设置环境变量mkdir -p /data/lllzxx/mytestenvcd /data/lllzxx/mytestenvvi myenv.txtdocker run -it --rm --env-file=./myenv.txt nginx:1.22.0 bashenv | grep MYTEST
                        docker run --rm busybox ifconfig # 查看容器的docker run --rm --net host busybox ifconfig # 使用宿主机的网络,查看宿主机的
                        # A服务器docker run -d --name mynginx10 -p 8110:80 nginx:1.22.0docker psdocker exec -it mynginx10cd /usr/share/nginx/html/echo "Hello World" > index.htmlcat index.htmlexitmkdir -p /data/lllzxx/testtarcd /data/lllzxx/testtardocker export -o mynginx10.tar mynginx10ls -l# B服务器mkdir -p /data/lllzxx/testtarcd /data/lllzxx/testtar# A服务器scp mynginx10.tar root@IP:/data/lllzxx/testtar # scp 在跨云的时候会有速度限制# B服务器docker import mynginx10.tar mynginx10:v10.0docker images mynginex10docker run -d --name mynginx10 -p 8010:80 mynginx10:v10.0 # refuse:CMD丢失。docker inspect mynginx10:v10.0 # 还有很多其他源数据丢失docker run -d --name mynginx10 -p 8010:80 nginx -g "daemon off" mynginx10:v10.0 

                        docker save 与 docker export 的区别可看下方文章:
                        docker save与docker export的区别_docker版本不同导致save-CSDN博客

                        docker run -d --name mynginx11 -p 8011:80 nginx:1.22.0 docker logs -f mynginx11# 流的重定向docker logs mynginx11 > info.log 2>err.log # info.log 是标准信息流;err.log 是标准错误流# 直接看Docker后台的目录cd /data/var/lib/docker/containerslsdocker pscd xxxxxxxlscat xxxxx-json.log
                        docker run -d --name mynginx12 -p 8012:80 nginx:1.22.0 docker stats mynginx12 # 整个容器总的资源占用docker top mynginx12 aux # 容器中具体进程占用的资源

                        B. MySQL 与 Redis的容器化安装
                        docker run --name mysql -e MYSQL_ROOT_PASSWORD=lzxx@mysql -p 8201:3306 -d mysql:5.7docker imagesdocker ps | grep mysqldocker exec -it mysql bashmysql -u root -p # lzxx@mysqlexit # 退出 MySQLexit # 退出 容器
                        docekr run --name redis -d -p 8300:6379 redis:7docker ps | grep redisdocker exec -it redis bashredis-cliset sellcount 1get sellcountexit # 退出Redisexit # 退出容器

                        C. Java 程序的容器制作
                        docker pull ubuntu:22.04docker images | grep ubuntudocker run -it --name myjava -p 8080:80 ubuntu:22.07 bash# 使用中科大源拉取镜像,记得更新缓存apt search jdkapt-get install java-1.8.0-openjdk.x86_64 -yjava -versionexitmkdir -p /data/lllzxx/myappcd /data/lllzxx/myapp# 上传 .jar 包 :scp mynginx10.tar root@IP:/data/lllzxx/testtarls -ldocker cp ./myapp.jar myjava:/docker exec -it myjava bashls /java -jar myapp.jar# 访问地址:IP:8080/hello/dockerexit # 现在是以前台方式运行,可以写 run 指令,也可以写 DockerFile
                        D. 容器资源更新
                        # A窗口docker pull java:8docker run -it --name myjava2 java:8 bash# B窗口cd /data/lllzxx/myappls -ldocker cp myapp.java myjava2:/# A窗口ls -ljava -jar myapp.jar# C窗口docker stats myjava2# D窗口docker update -m 200m --memory-swap 200m myjava2 # 两者一样即只能使用物理内存而不能使用交换内存# A窗口ctrl + c# D窗口docker update -m 10m --memory-swap 10m myjava2# A窗口java -jar myapp.jar # OOM-Kill 因为申请的内存太多了,无法给这么多资源
                        # A窗口docker run -it --name myjava3 java:8 bash# B窗口docker stats myjava3# A窗口for i in `seq 1 $(cat /proc/cpuinfo |grep "physical id" |wc -l)`do dd if=/dev/zero of=/dev/null &done#说明:#cat /proc/cpuinfo |grep “physical id” | wc -l 可以获得 CPU 的个数,我们将其表示为 N#seq 1 N 用来生成1到N之间的数字#for i in seq 1 N; 就是循环执行命令,从1到N#dd if=/dev/zero of=/dev/null 执行 dd 命令, 输出到/dev/null, 实际上只占用 CPU, 没有 IO 操作#由于连续执行N个(N是 CPU 个数)的 dd 命令, 且使用率为 100%, 这时调度器会调度每个 dd 命令在不同的 CPU 上处理,最终就实现所有CPU占用率 100%# C窗口docker update --cpu-quota 分子 --cpu-period 分母 myjava3

上一篇:网上销售怎么定位?

下一篇:CarPlay发音指南与实用操作技巧揭秘