ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CentOS 7安装Docker完整教程:从环境检查到容器部署避坑指南

CentOS 7安装Docker完整教程:从环境检查到容器部署避坑指南 前阵子接了个活儿要把一台老旧的CentOS 7服务器改装成Docker宿主跑几个内部服务。说实话CentOS 7这套东西放到现在已经不算年轻了直接yum install docker默认装的是老版本配置docker官方源又容易遇到网络问题docker daemon起不来的情况也见了不少。我在这台机器上从环境检查到跑通Nginx容器来回折腾了不少时间把坑一个个填平了。这篇就是完整的centos7安装docker教程适合刚接触Linux的运维新人也适合公司内网环境里需要离线部署Docker的人。先把这篇流程走一遍后续再聊基于Docker的中间件部署、服务编排都会顺手很多。1. 安装前必做系统环境检查与旧版本清理1.1 确认CentOS 7版本与内核是否符合Docker要求Docker对系统的要求其实很挑剔尤其是老系统。CentOS 7默认内核是3.10只要超过这个版本Docker 20.10这条线基本都能跑。但也别什么都不看直接上手先花半分钟做三个检查cat /etc/centos-release uname -r arch第一行确认系统是CentOS 7.x第二行看内核版本第三行确认是x86_64架构。Docker官方要求64位系统如果你手里是32位的发行版别想了装不上。内核版本如果低于3.10建议先按常规方式把内核升级到3.10以上或者直接用CentOS 7的小版本。生产环境的话我一般不推荐随便升级内核内核一换很多第三方模块和驱动容易出兼容性问题所以更常用的做法是选一个兼容老内核的Docker版本比如docker-ce 20.10.x这个版本对CentOS 7的overlay2、devicemapper支持都比较成熟。另外如果系统是刚装的最好顺便确认一下时区、主机名这些基础配置虽然不影响Docker安装但后面排查日志时时间对不对、主机名会不会混淆容器都是潜在麻烦。CentOS 7默认用hostname命令能看到的短主机名装Docker后每个容器也有独立hostname建议提前想好命名规则别等到容器多了再去一个一个改。1.2 卸载系统自带的旧版本Docker组件CentOS 7自带的docker包名字叫docker不是docker-ce版本停留在1.13左右那个版本太老很多新特性和兼容性都有问题。如果装过一定要先卸载干净否则会和新的docker-ce冲突。卸载命令yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine如果之前是用二进制方式装的可能没有rpm包建议检查/usr/bin/docker、/usr/libexec/docker/这些路径直接删掉残余文件。卸载完之后再检查一下which docker || echo docker not found输出“docker not found”就说明环境干净了。这一步很多人会跳过结果装完docker-ce之后发现命令行调用的还是老版本或者两个版本互相打架排查半天。还有一种情况系统里装了podman、buildah这类容器工具。它们和Docker不冲突但会占用端口或者影响容器网络尤其是podman默认也会创建网桥。如果你只是想在CentOS 7上专心用Docker建议先把这些工具清理掉避免后面docker run的时候出现端口被占、网络模式混淆这些怪问题。1.3 网络与yum源准备安装前还要确认yum源是否能通否则后面在线安装会卡死。判断方法很简单yum repolist curl -I https://download.docker.com如果机器能访问外网但访问download.docker.com比较慢或者根本不通那就不要跟官方源硬磕直接切换成国内镜像的yum源后面第2.2节会讲。另外建议先把系统本身的依赖包检查一遍至少要把selinux-policy、container-selinux这些跟容器相关的包准备好Docker启动时需要用到。yum install -y yum-utils yum check-updateyum update在大项目升级前一般不做我是在测试环境先做一次。如果你在生产环境装至少先确认没有明显的依赖问题。yum-utils这个包必须装里面提供了yum-config-manager、yumdownloader这些工具后面配置Docker仓库和离线下载rpm包都会用到。2. CentOS 7安装Docker的三种方式与选择建议2.1 方式一官方YUM源在线安装Docker CE最推荐确认好网络和系统版本后最省心的方式就是直接加官方源安装。官方源里的rpm包和依赖关系维护得最完整后续升级也方便。我一步步说。先安装yum-config-manager工具yum install -y yum-utils然后加入官方仓库yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo加完源后把缓存刷新一遍再列出仓库里所有docker-ce版本yum makecache fast yum list docker-ce --showduplicates | sort -r输出里会看到很多版本比如docker-ce-3:20.10.21-3.el7.x86_64这种注意别直接装latest除非你确定内核完全兼容。我目前在CentOS 7上锁docker-ce 20.10.x用命令指定完整版本号安装yum install -y docker-ce-20.10.21 docker-ce-cli-20.10.21 containerd.io如果只要最新版也可以直接yum install docker-ce docker-ce-cli containerd.io但CentOS 7的内核较老最新版Docker对内核和依赖要求更高可能遇到container-selinux版本不足一类的报错。用了指定版本后只要依赖不出问题装完直接就能启动。启动命令下面一起给了systemctl start docker systemctl enable docker docker versiondocker version会分别显示Client和Server版本Server部分能看到Engine版本、OS/Arch、存储驱动这些信息后面会频繁用到。如果Server版本没出来基本都是daemon没起来直接跳到第6章排查。2.2 方式二通过国内镜像YUM源安装官方源在部分网络环境的访问速度不稳定遇到超时就很难受。如果等不起可以直接把docker-ce.repo里的download.docker.com替换成可用的镜像源地址。这里以阿里云为例yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i sdownload.docker.commirrors.aliyun.com/docker-ce /etc/yum.repos.d/docker-ce.repo换源后同样执行yum makecache fast再安装过程跟官方源一模一样。不过要注意这个镜像源只是提供了docker的rpm包跟后面要说的“镜像加速器”不是一回事一个是软件安装包的仓库一个是拉取容器镜像的加速通道别混淆了。镜像源地址选什么取决于你所在网络的实际情况。公司内网有自建yum源或者云厂商的yum源那就直接用内网地址速度最快还不会受出口带宽影响。如果没有用公共镜像源即可。公共源的版本同步会有轻微延迟总体不影响使用。2.3 方式三内网离线安装Docker RPM包很多公司生产环境是隔离内网不能直接访问外网这种时候先把rpm包都下载出来再拷进内网机器装。具体操作找一台能联网、系统版本也是CentOS 7的机器先配置好相同的docker yum源然后用yumdownloader把依赖全部拉下来yum install -y yum-utils mkdir -p /opt/docker-rpm cd /opt/docker-rpm yumdownloader --resolve docker-ce-20.10.21 docker-ce-cli-20.10.21 containerd.io如果依赖比较多用repotrack更全repotrack docker-ce docker-ce-cli containerd.io --destdir/opt/docker-rpm拷贝目录到内网机器后yum localinstall /opt/docker-rpm/*.rpm -ylocalinstall会自动解析目录里的rpm依赖关系比rpm -Uvh手动一个个装省事得多。需要注意的是内网机器本身得有个可用的基础yum源如果连基础依赖包比如libseccomp、systemd都需要离线解决那你就得把整个依赖链都拉到同一目录里传进去否则localinstall会提示缺少依赖。离线安装的版本锁定特别重要。你在一台有网的机器上下载了哪些版本的rpm内网就得装哪些不要混着来。不同版本的docker-ce和containerd.io可能有依赖版本要求混搭容易出现服务起不来的问题。下载完成后建议在目录里放一个清单文件记录版本号和下载时间方便后面追溯。3. 安装后的关键配置镜像加速、数据目录与开机自启3.1 配置Docker镜像加速器Docker装完默认的镜像拉取点是Docker Hub国内经常慢到怀疑人生。这里建议给Docker配置镜像加速器让docker pull的速度能正常起来。创建或修改/etc/docker/daemon.json{ registry-mirrors: [ https://你的阿里云加速地址.mirror.aliyuncs.com ] }如果你没有阿里云账号也可以使用其他公共镜像加速地址但务必要选择靠谱的服务商不要随便填不认识的第三方地址镜像源不安全的话拉下来的镜像可能被篡改。配置完后重启Docker让配置生效systemctl daemon-reload systemctl restart docker检查有没有生效docker info | grep -A 2 Registry Mirrors看到有地址输出就说明加速已经生效。我个人的建议是如果公司内网有自建的Harbor仓库或者云厂商的容器镜像服务其实不需要用公共加速器直接拉内网或私有仓库会更稳还能避免镜像源波动的影响。这个daemon.json文件是Docker引擎的核心配置文件后面加数据目录、日志轮转都在同一个文件里改注意JSON格式不能错改完一定检查一遍具体方法在第6.5节。3.2 规划Docker数据存储目录Docker默认会把所有镜像、容器、卷都放在/var/lib/docker下面。如果系统盘不大用着用着容易爆尤其是MySQL、Redis这些容器跑起来后数据卷会越占越大。在安装后的第一时间就把数据目录迁到大磁盘上是最划算的操作。比如磁盘/data是独立挂载的大分区那就先把原数据目录备份出来如果是刚装完其实只有空目录然后修改daemon.json{ data-root: /data/docker }重启Dockersystemctl restart docker docker info | grep Docker Root Dir顺手再检查一下磁盘空间df -h /data/docker这里有一个很多人踩过的坑直接rm -rf /var/lib/docker再软链或者在没有拷贝数据的情况下直接改data-root导致老镜像丢失。如果Docker里已经有容器了迁移前一定要先停掉Docker用rsync同步完整目录再切换别图省事。数据目录规划好之后后面再装镜像、跑容器都不会有系统盘写满的焦虑。尤其是你打算在Docker里跑日志采集、监控这类频繁写盘的服务时独立的数据盘能让你少操很多心。3.3 设置Docker开机自启与日志轮转安装完Docker如果你希望服务器重启后容器还能自己起来启动服务只是第一步还要设置开机自启systemctl enable docker systemctl enable --now docker这两个命令的区别enable只加开机自启enable --now是立即启动并加入开机自启。如果容器也想跟随Docker自动重启在docker run时加上--restart always参数或者在compose文件里写restart: always。日志也是个隐患。容器如果不限制日志大小/var/lib/docker/containers下的json日志文件会无限增长时间长了磁盘直接满。建议在daemon.json里加上日志轮转配置{ log-driver: json-file, log-opts: { max-size: 50m, max-file: 3 } }这样单个容器日志最多保存50MB、保留3个文件能避免很多磁盘报警。这个配置在你已经跑了容器之后再改需要重启Docker才会让新配置对容器生效旧容器要么重建要么按老配置继续写所以最好在部署业务容器之前就把日志轮转配好。4. 验证安装与第一个容器从hello-world到Nginx实战4.1 用hello-world容器做冒烟测试环境配置完先做最简单的冒烟测试。执行docker run hello-world如果一切正常终端会输出一段提示文字说明镜像拉取成功、容器创建运行都OK。如果拉取hello-world镜像超时说明镜像加速器配置没生效或网络有问题可以先用busybox代替docker pull busybox docker run --rm busybox echo docker ok--rm表示容器运行完就自己删除不会残留垃圾。这一步验证的是Docker引擎本身而不是具体业务所以越简单越好别一上来就拉MySQL这种大镜像。冒烟测试通过后你至少能确认Docker守护进程、containerd、网络栈、镜像加速这几条链路都是通的。4.2 用Nginx容器验证端口映射与后台运行冒烟测试过了再用Nginx做一次真实场景的验证顺便把端口映射和后台运行这两个最常用的点讲透。执行docker run -d --name web -p 8080:80 nginx:alpine这行命令的参数拆开看-d后台守护进程运行--name web给容器起个名字方便后续管理-p 8080:80把宿主机的8080端口映射到容器内的80端口nginx:alpine选择alpine版本镜像体积小。启动后看下容器状态docker ps然后curl一下curl -I http://127.0.0.1:8080看到HTTP/1.1 200 OK说明Nginx已经跑起来了。这时候如果从外部浏览器访问要检查防火墙有没有放行8080端口。CentOS 7默认用firewalld得先放行firewall-cmd --add-port8080/tcp --permanent firewall-cmd --reload用完之后清理测试容器docker stop web docker rm web如果连查看镜像、启动容器、端口映射、防火墙放行这一套流程都能顺利走下来那这台CentOS 7的Docker环境基本已经可用了。4.3 连续部署多个容器的注意事项测试环境还好真正上生产后容器一多有几点要特别注意。一个是端口规划多个容器共用一个宿主机时别把8080、3306、6379这些默认端口全部无脑映射出来容易被扫描攻击二是容器网络默认bridge网络下容器之间通过容器IP互访并不可靠建议后续项目用docker network create创建自定义网络让容器之间用服务名互访三是数据持久化容器本身是无状态设计MySQL、Redis这类服务一定要用挂载卷把数据落到宿主机。这几个点虽然和“安装”关系不大却是从Docker环境到Docker生产之间绕不过的门槛早规划比晚返工要好。后面第5章用Docker Compose编排MySQL和Redis时你会更直观地感受到这些配置怎么落地。5. 安装Docker Compose编排工具5.1 Compose v2插件与独立二进制的取舍单机部署多个容器时总用docker run命令命令会越来越长。Docker Compose就是解决这个问题的把容器、网络、卷、环境变量全写进一个yaml文件一键起停。目前Compose有两种常见形态。第一种是Docker 20.10及以后版本里推荐的compose v2插件安装后通过docker compose命令调用yum install -y docker-compose-plugin docker compose version第二种是老牌的docker-compose独立二进制通过发布包直接下载到/usr/local/bin/docker-compose命令是docker-compose。如果你用的是官方YUM源的docker-ce 20.10.x我推荐直接用插件方式依赖少、升级也方便。如果你需要独立二进制也有固定的安装姿势curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose docker-compose --version两种方式选一个就行不建议在同一台机器上同时装否则命令行里两个命令都能用时间长了容易搞混自己到底在用哪个版本。5.2 一个MySQLRedis的组合部署示例以最常见的MySQLRedis为例看看Compose怎么用。先建一个项目目录比如/data/stack写docker-compose.ymlversion: 3.8 services: mysql: image: mysql:8.0 container_name: mysql8 restart: always environment: MYSQL_ROOT_PASSWORD: root123456 ports: - 3306:3306 volumes: - ./mysql/data:/var/lib/mysql redis: image: redis:6.2 container_name: redis6 restart: always ports: - 6379:6379 command: [redis-server, --appendonly, yes]字段不多但都是重点image指定镜像container_name固定容器名方便管理restart: always开机自动重启environment注入环境变量MySQL的root密码就在这里设置volumes宿主机目录挂载进容器MySQL数据不会因容器删除而丢失command覆盖容器默认启动命令这里是让Redis开启AOF持久化。在docker-compose.yml所在目录执行docker compose up -d然后看一下状态docker compose ps要看实时日志docker compose logs -f停止组合docker compose down注意down默认不会删除卷但加上-v参数会连挂载卷一起删除操作前一定看清。容器里如果还有重要数据别随便加上-v。5.3 升级和卸载Docker Compose的方法Compose插件跟着Docker一起升级不需要单独处理。如果是独立二进制升级就是重新下载新版本替换/usr/local/bin/docker-compose同时chmod x保持可执行权限。卸载插件需要先确认当前没有compose项目在运行再执行yum remove docker-compose-plugin独立二进制直接rm文件即可。这里要提醒一点不管哪种方式安装的Compose都要保证yaml文件里的缩进正确。这个文件对格式极其敏感一个空格不对就报错而且报错信息经常很隐晦。建议写完后先用docker compose config命令校验一遍再up。6. 高频安装问题排查与实用避坑指南6.1 docker命令报Cannot connect to the Docker daemon装完Docker后执行docker ps如果提示Cannot connect to the Docker daemon at unix:///var/run/docker.sock先别懵。这句报错就三层意思Docker服务没启动或者启动失败或者当前用户没有访问socket的权限。排查顺序systemctl start docker看能不能正常启动systemctl status docker看服务状态是不是active (running)journalctl -u docker --no-pager | tail -50看daemon日志里有没有具体错误。如果服务正常但当前用户不是root还需要把用户加进docker组usermod -aG docker 你的用户名改完必须重新登录一次会话或者执行newgrp docker让组权限生效否则docker命令还是会报权限错误。6.2 Docker启动时报iptables NAT链创建失败CentOS 7上docker启动时偶尔会报类似Failed to create NAT chain: iptables failed: iptables --wait -t nat -A DOCKER这样的错误。原因多数是系统里的firewalld或iptables服务和Docker的规则冲突了。最直接的解决方法是重启Docker让它重新初始化自己的iptables规则systemctl restart docker如果还不行就要检查防火墙状态firewall-cmd --state有些环境是iptables服务常驻可以先临时停掉iptables或firewalld测试确认能启动后再按业务需求放行端口而不是关闭防火墙。生产环境做这类操作时最好在维护窗口期进行避免影响在跑的容器。6.3 镜像拉取超时的网络问题处理docker pull慢到一直转圈或者直接报net/http: TLS handshake timeout大概率是网络问题。先检查加速器是否生效docker info | grep -A 2 Registry Mirrors没有加速器就按前面第3.1节配置。如果加速器配了仍然超时还要看看宿主机的DNS。Docker拉镜像时要解析registry域名DNS不对一样卡死。检查/etc/resolv.conf改成正常可用的DNS地址比如公司内网DNS或者公共DNS然后再重启Docker。另外个别情况下yum源和Docker走的是同一个出口带宽如果出口本身很窄只能错峰拉取或者拉完存到本地私有仓库。6.4 CentOS 7内核过旧导致的兼容性问题CentOS 7默认内核3.10装最新版Docker可能会碰到一些奇怪问题比如容器起来后文件系统报错或者overlay2存储驱动初始化失败。这种时候优先考虑换用兼容性好的Docker版本在CentOS 7上我一般推荐docker-ce 20.10.x不要追求版本号最新。如果系统对内核升级没有强制限制也可以把内核升级到较新版本再重挂载overlay。但升级内核需要重启机器而且可能影响已安装的第三方驱动所以生产环境操作前一定要做完整备份和回滚预案。还有一种应急方案是把存储驱动临时切到vfs虽然性能很差但能先让容器跑起来只适合测试环境验证。6.5 daemon.json配置错误导致服务无法启动很多人改完daemon.json之后docker restart直接失败systemctl status docker显示的是配置文件解析错误。这种情况八成是JSON格式有问题比如多了一个逗号、少了一个引号。检查方法很简单python -m json.tool /etc/docker/daemon.json如果输出正常说明格式没问题如果报错根据提示修改。改完执行systemctl daemon-reload systemctl restart docker提醒一下daemon.json里不允许写注释别想着用#号注释一行。一个不小心在多个配置文件之间漏了逗号Docker就会直接罢工这也是新手最容易忽略的细节。6.6 跑了一段时间后容器命令失效或磁盘满Docker本身没问题但容器越来越多时磁盘满是很常见的。先用df -h看系统盘使用率再用docker system df统计Docker占用的空间。处理手段按优先级来docker container prune # 清理已停止的容器 docker image prune -a # 清理未被使用或悬挂的镜像 docker system prune -af # 更彻底的模式慎用特别是docker system prune -af会删除所有未使用的镜像如果之后还要用就得重新拉取。所以生产环境执行前确认镜像有没有在私有仓库里备份。这个操作我一般只在明确知道环境可以重建的时候才用平时更倾向用docker image ls按需要手动删。6.7 常见报错速查表常见报错可能原因处理方向Cannot connect to the Docker daemon服务未启动或当前用户无权限启动docker服务或把用户加入docker组Failed to create NAT chain防火墙或iptables规则冲突重启docker检查firewalld状态TLS handshake timeout网络不通或镜像加速未配置配置registry-mirrors检查DNSoverlay2 mount failed内核兼容性异常锁定docker 20.10或临时切vfsinvalid character in daemon.jsonJSON格式错误用python -m json.tool校验配置no space left on device磁盘空间不足清理无用镜像容器或迁移data-root7. 安装完Docker后我个人的几个实操习惯整套装完之后我自己的习惯是先把虚机快照或服务器备份打一个这样后面不管怎么折腾都有后悔药。然后确认一下docker info里显示的内核、存储驱动、数据目录都符合预期再往环境里部署中间件。线上镜像版本能锁就锁不要一直用latest。锁版本的好处是结果可复现出问题也能知道是哪个版本引入的。我见过太多因为latest飘了新版本第二天容器起不来的事故。另外日志和磁盘监控尽早做容器日志不限制会一直涨这个坑我踩过不止一次daemon.json里的log-opts一定配好配合crontab定期清理磁盘基本能稳住。如果你想在CentOS 7上跑GitLab、MySQL、Nginx或者Redis这些常见应用先把这篇安装流程吃透后面每个应用都是基于这个Docker底座来跑的。基础打牢用起来才会顺手。
返回列表