精彩推荐 | 【深入浅出Docker原理及实战】「原理实战体系」零基础+全方位带你学习探索Docker容器开发实战指南(实战技术总结)

news2024/11/28 18:49:11

Dockerfile实战总结

  • 前提介绍
  • 实战总结方案
    • 创建容器时传入环境变量
    • 调整宿主机和容器的时间差异
      • 解决办法
    • 指定容器的rootfs的大小
    • 快速管理容器和镜像
      • 快速删除容器的原理
        • --format格式化输出
        • 输出所有容器的name
        • 输出所有容器名包含test的容器
        • 查看退出状态的容器
        • 删除所有容器
        • 删除/启动所有退出的容器
      • 快速删除容器的原理
        • 删除所有镜像
      • 容器的自动重启机制
    • 如何动态修改容器的内存和cpu限制
    • 使用alias来预定义常用的命令
    • 容器label的使用
    • 快速查看容器的相关配置信息
      • 查看容器的devicemapper设备
      • 查看容器的PID
      • 查看容器name
      • 获取容器的ID:

前提介绍

在使用Docker时,管理维护工作可能会显得复杂。然而,实际上,Docker提供了许多便捷且人性化的工具,这些工具的使用技巧可以大大简化维护工作,并提升效率。通过掌握这些技巧,你不仅能够更轻松地管理Docker环境,还能展现出专业的能力。接下来我们就给大家介绍一下对于我在工作当中对于Docker容器使用的技术实战总结

实战总结方案

创建容器时传入环境变量

在现实应用中,出于安全和配置灵活性的考虑,许多参数适宜通过环境变量进行设置,例如数据库连接信息、时区设置以及字体支持等。在创建容器时,您可以使用 -e 参数为这些环境变量指定键值对,从而实现参数的传递和配置。这样的方式不仅方便灵活,还有助于提高应用的安全性。

root# docker run -itd --name add-env -e TZ='Asia/Shanghai' centos7.2-jdjr-add-app 
de20b44301e27c16eae63dab243d293054178dd5f819c23d44bd9e534208bb42

在Docker命令中,你可以使用环境变量来配置应用的行为。你给出的命令是一个Docker运行的示例,其中使用了-e参数来设置环境变量TZ的值为Asia/Shanghai,这表示将时区设置为上海。

root# docker exec -it test-env date
2024年 01月 17日 星期三 10:35:17 CST
root# date
Tue Jan 17 10:35:21 CST 2024

可以看到加了时区环境变量的容器已经和宿主机在同一个时区(CST),并且时间和宿主机基本同步,我们再来看一下不加入时区设置的。

root# docker run -itd --name add-env centos7.2-jdjr-add-app
d6a02874b999fd5eea79e3b302148b42043af01c89a5d31e5d858e0806f9077a
root# docker exec -it add-env date

大家可以看到容器的时间是:2024年 01月 20日 星期六 01:43:48 Asia,没有加时区环境变量的容器还是Asia。

调整宿主机和容器的时间差异

对于Docker容器来说,宿主和容器之间的时间差异并不存在,因为它们共享同一个内核和时钟。这意味着它们的时间是同步的,不存在需要特别处理的时间同步问题。通常,时间问题更多是由时区差异引起。你可以使用date命令来查看容器当前的时区设置。

通用协调时(UTC)是国际标准0时区,与格林尼治平均时(GMT)相同,即英国伦敦的本地时间。而CST通常表示中国标准时间,与UTC相差8小时。

在类Unix系统中,存在硬件时钟系统时钟两个概念。
在这里插入图片描述
Unix和Linux系统的时钟时间是从格林威治时间(GMT)开始计算的当前秒数,即从1970年1月1日凌晨零点零分零秒至今的时间。这是一个全球统一的标准,不受地理位置差异的影响。

时区是为了克服时间上的混乱,根据地理位置和行政区域划分的。全球共划分为24个时区,我国属于东八区,并采用协调世界时(UTC)作为标准时间。

解决办法

创建容器的时候,使用-e 将时区信息传入到容器内部。

其实使用单纯的环境变量来改变容器内部的TIME ZONE,只会影响当前容器用户的时区,一旦切换到真正的root用户就会发现时区依然是不正确的,比如以下栗子:

root#
root# docker run -itd --name test-env -e TZ='Asia/Shanghai' images
root# docker exec -it test-env bash
root# date
2024年 01月 17日 星期三 20:45:54 CST
root# sudo su -c date
2024年 01月 18日 星期三 08:46:02 EDT
root# 

那么如何真正解决时区这个问题呢?其实是/etc/localtime在作怪,用户只需要将容器内部的localtime改成你想要的时区就行了。

root# ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
root# date
2024年 01月 17日 星期三 20:49:54 CST
root# sudo su -c date
2024年 01月 17日 星期三 20:49:54 CST
root# 

在使用Dockerfile构建镜像的时候将/usr/share/zoneinfo/Asia/Shanghai强制软连接到/etc/localtime就可以永久修复时区的问题了。

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime;\
    rm /bin/sh && ln -s /bin/bash /bin/sh;\
    echo 'Asia/Shanghai' >/etc/timezone

指定容器的rootfs的大小

在使用Docker时,CPU和内存可以灵活地动态调整,但默认的rootfs大小却是固定的,默认为10GB。对于需要扩展存储的用户,可以通过挂载volume来实现。

对于需要调整rootfs大小的用户,Docke提供了两种方式:在启动Docker时加载参数--storage-opt dm.basesize=40G来调整默认容器的rootfs大小;在创建容器时使用参数--storage-opt size=70G来设置特定容器的rootfs大小。这些调整方法使得用户可以根据实际需求来定制和优化容器存储空间。

docker run -itd --name add-test --storage-opt size=70G centos7.2-jdjr-add-app

接下来,我们看到容器被成功创建并开始运行:

18d47e69802aa84df00182885b256c50ebc56e15d8e6990fc1e187ffe254171e

然后,我们使用以下命令来检查容器的磁盘使用情况:

docker exec -it add-test df -H | grep rootfs

进入到名为add-test的容器,并执行df -H命令来查看磁盘使用情况,然后通过grep rootfs来筛选出与rootfs相关的结果。结果显示rootfs的大小为76G,已使用1.5G,还剩74G,使用率为2%。

root# docker run -itd --name add-test --storage-opt size=70G centos7.2-jdjr-add-app
18d47e69802aa84df00182885b256c50ebc56e15d8e6990fc1e187ffe254171e
root# docker exec -it add-test df -H | grep rootfs
rootfs                 76G  1.5G   74G   2% /
root# docker exec -it add-env df -H | grep rootfs
rootfs                 11G  1.5G  9.3G  14% /

快速管理容器和镜像

在Docker中,删除容器需要指定容器名或容器ID。当容器数量众多且状态各异时,删除容器需要更加谨慎。然而,Docker的docker ps命令提供了许多实用的功能,方便用户管理容器。在创建容器时,通过添加标签(label)可以进一步简化容器的管理。

快速删除容器的原理

Docker的原理是使用container id来唯一标识一个容器,因此可以通过获取所有容器的container id来批量删除它们。使用docker ps -a -q命令可以输出所有容器的container id,其中-a参数表示输出所有容器,-q参数表示只输出container id。然后,将这些id作为参数传递给docker rm命令进行批量删除。这样可以快速地清理不再需要的容器,提高管理效率。

–format格式化输出

在Docker的底层实现中,各种容器的组织信息确实存储在结构体中,其中*formatter.containerContext可能是与容器格式化输出相关的结构体之一。这个结构体可能包含了用于生成容器输出所需的字段和数据。

通过使用--format选项,用户可以定义自己的模板,并利用Go模板语法来格式化容器的输出。这使得用户可以根据自己的需求定制化输出,更加灵活地展示容器信息。

输出所有容器的name
root# docker ps --format='{{.Names}}'
test-env
test-app
test-run
输出所有容器名包含test的容器
root# docker ps -f name=test --format='{{.Names}}'
test-env
test-app
test-run
查看退出状态的容器
root# docker ps -f status=exited --format="{{.Names}}"
thirsty_brahmagupta
clever_mestorf
hopeful_morse
stoic_morse
elated_williams
tender_jepsen
reverent_mirzakhani
删除所有容器
root# docker rm -f -v $(docker ps -a -q)
删除/启动所有退出的容器
root# docker rm $(docker ps -qf status=exited) 

会删除所有已退出的容器。

docker start $(docker ps -qf status=exited) 

会启动所有已退出的容器。

快速删除容器的原理

只列出镜像的id以及仓库名称:

sh-4.2# docker images --format “{{.ID}}: {{.Repository}}”

67591570dd29: centos
0a18f1c0ead2: rancher/server

只列出容器的相关id,image,status和name

sh-4.2# docker ps --format “{{.ID}}: {{.Image}} : {{.Status}} : {{.Names}}”
66b60b72f00e: centos : Up 7 days : pensive_poincare
或者自己重新定义列,就和原生差不多:

sh-4.2# docker ps --format “table {{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Names}}”
CONTAINER ID IMAGE STATUS NAMES
66b60b72f00e centos Up 7 days pensive_poincare

删除所有镜像
root# docker rmi $(docker images -q)

容器的自动重启机制

您可以使用--restart参数来配置Docker容器的重启策略。其中,--restart=always选项表示容器将始终自动重启,无论容器是否正常退出。

要使容器随着Docker守护进程的启动而一同启动,您可以在运行容器时加上--restart=always参数,例如:

docker run --restart=always <image_name>

这将使容器在Docker守护进程启动时自动创建并启动。即使容器正常退出或发生错误,它也会自动重新启动。

注意,使用--restart=always可能会对系统资源造成一定的负担,因为容器会不断地重新启动。如果不需要容器始终自动重启,您可以考虑使用其他重启策略,如--restart=on-failure--restart=unless-stopped,以仅在容器退出状态不为0或您手动停止容器时重启。

如何动态修改容器的内存和cpu限制

root# docker exec add-env cat /sys/fs/cgroup/memory/memory.limit_in_bytes
9223372036854775807
root# cat /sys/fs/cgroup/memory/memory.limit_in_bytes 
9223372036854775807

可以看到,默认没有给容器限制内存,它会共享宿主机的所有内存动态调整内存为2014M:

root# docker update -m 2014M add-env
add-env
root# docker exec test-env cat /sys/fs/cgroup/memory/memory.limit_in_bytes
2111832064

使用alias来预定义常用的命令

docker管理命令经常需要指定各种参数,通过linux的alias命令将默认的参数预定义起来,可以很方便的进行管理容器。

root# alias dockerrm='docker rm -f -v'
root# alias dockerexec='docker exec -it'
root# alias dockerrmimage='docker rmi'

root# dockerrm volume-test
volume-test

root# dockerexec volume-test ls
bin   dev  export  lib    media  opt   root  selinux  sys  usr
boot  etc  home    lib64  mnt    proc  sbin  srv      tmp  var

容器label的使用

在运维工作中,随着容器的增多,管理和维护的复杂性也相应增加。然而,借助label这一功能,可以轻松地对容器进行分类和标识。

label不仅仅用于简单的标识,它还贯穿于Docker的整个生命周期,从创建到管理,再到运行。通过为容器设置不同的label,可以清晰地划分出不同业务、不同模板的容器,从而更方便地进行分组和运维。因此,合理使用label功能,可以大大提高容器管理的效率和便捷性。

root# docker run -itd --name volume-test --storage-opt size=70G --label zone=test centos7.2-jdjr-test-app
c3772397e58e663095c2c0fd8d688b3d41b494097999ec2b6d6b7c509d23a138

创建容器的时候定义一个label,表示该容器在test这个区域使用定义的label进行快速检索容器,并进行下一步操作。

root# docker ps -qf label=zone=test
c3772397e58e
root# docker ps -f label=zone=test --format='{{.Names}}'
volume-test

快速查看容器的相关配置信息

查看容器的devicemapper设备

root# docker inspect -f '{{.GraphDriver.Data.DeviceName}}' nginx 
docker-18:1-67411759-7c9d6d3327b02659c81bcb70bf6a4c7a45df6a589af2a2d42a387dc0e90d4913

查看容器的PID

root# docker inspect -f '{{.State.Pid}}' nginx 
27521

查看容器name

root# docker inspect -f '{{.Name}}' nginx 
/nginx

获取容器的ID:

root# docker inspect --format {{.Id}} nginx
53214bc9cd001f2c548edcce0c42fe51f1a118c08941406d43122a8348055843

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1392597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

transbigdata笔记:其他方法

1 出租车相关 1.1 taxigps_to_od 提取出租车OD信息 transbigdata.taxigps_to_od(data, col[VehicleNum, Stime, Lng, Lat, OpenStatus]) 输入出租车GPS数据&#xff0c;提取OD信息 data出租车GPS数据col[VehicleNum, Time, Lng, Lat, OpenStatus]五列 比如GPS数据长这样&am…

docker screen 常用基础命令

1.docker基础命令 1.1开启docker systemctl start docker #开启docker service docker restart #重启docker systemctl stop docker #关闭docker 1.2查看命令 docker images #查看docker镜像docker ps #查看正在运行的镜像或者容器docker ps -a #查看所有容器1.3运…

信驰达科技参与《汽车玻璃集成UWB数字钥匙发展研究白皮书》编制工作

为进一步探索汽车数字钥匙技术路线及开发思路&#xff0c;中国智能网联汽车产业创新联盟&#xff08;CAICV&#xff09;、福耀玻璃工业集团股份有限公司联合发起了《汽车玻璃集成UWB数字钥匙发展研究白皮书》研究工作。 2023年12月20日&#xff0c;由中国智能网联汽车产业创新…

Linux:/proc/kmsg 与 /proc/sys/kernel/printk_xxx

目录 前言一、/proc/kmsg1、简介2、如何修改内核日志缓冲区3、dmesgklogctl 函数&#xff08;来源于 man 手册&#xff09; 4、扩展阅读 二、 /proc/sys/kernel/printk_xxx三、/dev/kmsg 前言 本篇文章将为大家介绍与 Linux 内核日志相关的一些控制文件&#xff0c;共同学习&am…

C语言总结十二:文件操作详细总结

在操作系统中&#xff0c;为了统一对各种硬件的操作&#xff0c;简化接口&#xff0c;不同的硬件设备也都被看成一个文件。对这些文件的操作&#xff0c;等同于对磁盘上普通文件的操作。我们不去探讨硬件设备是如何被映射成文件的&#xff0c;把任意 I/O 设备&#xff0c;转换成…

ResNet论文翻译和精读

1:论文原文 论文原文&#xff1a; ResNet 2&#xff1a;该论文解决了什么问题&#xff1f; 改论文解决了深层的神经网络训练时的梯度消失和梯度爆炸的问题&#xff1b; 3&#xff1a;该论文的创新点&#xff1f; 将快捷连接应用到了网络中构建成了残差网络块&#xff1b;…

【嘉立创EDA-PCB设计指南】3.网络表概念解读+板框绘制

前言&#xff1a;本文对网络表概念解读板框绘制&#xff08;确定PCB板子轮廓&#xff09; 网络表概念解读 在本专栏的上一篇文章【嘉立创EDA-PCB设计指南】2&#xff0c;将设计的原理图转为了PCB&#xff0c;在PCB界面下出现了所有的封装&#xff0c;以及所有的飞线属性&…

代码随想录算法训练营29期|day 22 任务以及具体安排

235. 二叉搜索树的最近公共祖先 class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root null) return null;//向左遍历if(root.val > p.val && root.val > q.val){TreeNode left lowestCommonAncestor(roo…

Redis和MySQL如何保持数据一致性

前言 在高并发的场景下&#xff0c;大量的请求直接访问Mysql很容易造成性能问题。所以&#xff0c;我们都会用Redis来做数据的缓存&#xff0c;削减对数据库的请求。但是&#xff0c;Mysql和Redis是两种不同的数据库&#xff0c;如何保证不同数据库之间数据的一致性就非常关键…

基于springboot+vue的在线拍卖系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

redis数据安全(四)复制

关系数据库通常会使用一个主服务器向多个从服务器发送更新&#xff0c;并使用从服务器来处理所有读请求&#xff0c;Redis也采用了同样的方法来实现自己的复制特性&#xff0c;并将其用做扩展性能的一种手段。 一、特点&#xff1a; 1、异步复制&#xff1a;Redis默认使用的是…

Liunx:线程

我们先说一个程序是怎么执行的&#xff1a; 我们编写好一个代码&#xff0c;经过预编译&#xff0c;编译&#xff0c;汇编&#xff0c;连接&#xff0c;形成一个二进制文件被写进磁盘中&#xff0c;通常我们把他叫做可执行程序。 我们可以双击运行&#xff0c;运行需要经过几个…

Modern C++ std::mutex底层原理

前言 我时常有这样的疑问&#xff1a; std::mutex怎么就能保证后面的语句100%安全哪&#xff1f;CPU reordering就不会把这些语句重排到mutex前面执行&#xff1f;而且各个CPU都是有L1、L2缓存的&#xff0c;如果mutex后面要访问的的变量在这些缓存中怎么办&#xff1f; 带着…

sqlilabs第五十七五十八关

Less-57(GET - challenge - Union- 14 queries allowed -Variation 4) 手工注入 Less-58(GET - challenge - Double Query- 5 queries allowed -Variation 1) 手工注入 报错注入就可以&#xff08;布尔注入的话次数不够&#xff09;(所以我们前面需要做够足够的数据支持) 最后…

whistle代理+mock轻松解决“页面端“测试接口没数据难题

0、whistle是什么&#xff1f;怎么用&#xff1f; 自行百度&#xff0c;此处不再赘述&#xff01; 1、示例演示&#xff08;交易订单测试&#xff09; 背景和痛点最近在测试一个小需求&#xff0c;需要涉及订单侧服务商品库侧服务库存侧服务财务侧线下交易服务。痛点主要在订…

abap 将xstring转换成PDF展示

收到外围系统的xstring之后&#xff0c;如何在sap中将其打开呢 1.创建一个屏幕 2.绘制一个customer control 3.创建流逻辑 4.流逻辑如下&#xff1a; DATA: go_html_container TYPE REF TO cl_gui_custom_container, go_html_control TYPE REF TO cl_gui_html_viewer, lv_u…

66.Go从零搭建一个orm框架【简版】

文章目录 一&#xff1a;前置学习1、 为什么要用orm2、Golang里面是如何原生连接MySQL的3、ORM框架构想 二: 开始造1、连接Connect2、设置/读取表名Table/GetTable3、新增/替换Insert/Replace4、条件Where5、条件OrWhere6、删除Delete7、修改Update8、查询9、设置查询字段Field…

序列到序列模型

一.序列到序列模型的简介 序列到序列&#xff08;Sequence-to-Sequence&#xff0c;Seq2Seq&#xff09;模型是一类用于处理序列数据的深度学习模型。该模型最初被设计用于机器翻译&#xff0c;但后来在各种自然语言处理和其他领域的任务中得到了广泛应用。 Seq2Seq模型的核…

介绍下Redis?Redis有哪些数据类型?

一、Redis介绍 Redis全称&#xff08;Remote Dictionary Server&#xff09;本质上是一个Key-Value类型的内存数据库&#xff0c;整个数据库统统加载在内存当中进行操作&#xff0c;定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作&#xff0c;Redis的性…

Spring框架的背景学习

Spring 的前世今生 相信经历过不使用框架开发 Web 项目的 70 后、80 后都会有如此感触&#xff0c;如今的程序员开发项目太轻松了&#xff0c;基本只需要关心业务如何实现&#xff0c;通用技术问题只需要集成框架便可。早在 2007 年&#xff0c;一个基于 Java语言的开源框架正…