ARTICLE DETAIL

资讯详情

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

CentOS 7安装Docker全流程:从yum源配置到MySQL/Redis容器实战

CentOS 7安装Docker全流程:从yum源配置到MySQL/Redis容器实战 最近又有同事来问我 CentOS7 上装 Docker 的命令我干脆把整套流程和踩过的坑都整理出来。这事真不是简单复制几条 yum 命令就完事我自己一开始也是照着教程敲结果启动 docker 时报错、拉镜像时超时、容器跑起来之后网络又不通一个下午全耗进去了。这篇就写写我实测下来最顺的安装路径从系统检查、yum 源配置、安装 docker-ce 开始覆盖最常用的 docker 命令、高频问题排查最后用一个部署 MySQL 和 Redis 的小实战收尾。不管你是刚接触 Linux 容器的新手还是已经在用 docker 想系统补一遍的运维这份笔记应该都能直接“抄作业”。1. 安装前的准备系统检查与思路拆解1.1 先确认系统版本和内核很多人上来就装装完发现一堆兼容性问题根源在没先确认机器配置。在 root 下执行cat /etc/redhat-release uname -r第一行看系统版本第二行看内核版本。CentOS 7 的最新小版本是 7.9内核一般停在 3.10.0-1160。这个内核版本对 Docker 来说不算新所以后面选 Docker 版本时要特别注意。我建议先把这两条命令的跑一遍心里有底再做后续操作。如果你的机器还是 CentOS 7.0 到 7.2 这种老版本先yum update -y升到 7.9不然很多依赖包版本太老装 docker 的过程中容易卡住。1.2 网络和 yum 源要提前捋顺安装过程需要从远程仓库下载软件包网络不通会非常痛苦。先测一下ping -c 3 baidu.com如果 ping 不通先检查网卡和 DNS。ip addr看网卡有没有获取到 IPcat /etc/resolv.conf看 DNS 配置。CentOS 7 网络不通的常见原因就是网卡没启动或者 DNS 没配好跟 Docker 本身没关系别在错误的路上排查半天。另外我强烈建议先把 yum 源换成国内源比如阿里云或者清华的 CentOS 镜像源。官方源在国内网络下经常慢得像蜗牛换源之后安装速度能快一个量级。换源的命令网上很多改了之后记得yum makecache fast刷新缓存。1.3 卸载历史遗留的旧版本 Docker如果你之前用yum install docker装过系统自带的 docker 包或者装过老版本的 docker-engine建议先清掉再装新版yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine -y注意区分两个包名系统自带的docker包是旧版功能残缺我们真正要装的是docker-ce这是 Docker 官方维护的社区版。两者不能混装否则会冲突。卸载之后可以顺手清一下/var/lib/docker目录这是 Docker 默认的数据目录不过要是里面有你想保留的容器数据就别删。2. 完整安装步骤从 yum 源到 hello-world2.1 安装依赖工具并添加 Docker 仓库CentOS 7 默认的仓库里没有 docker-ce需要手动加一个 yum 源。先装辅助工具yum install -y yum-utils device-mapper-persistent-data lvm2yum-utils提供yum-config-manager命令用来管理仓库配置device-mapper-persistent-data和lvm2是存储驱动相关的依赖。虽然现在 Docker 推荐 overlay2 存储驱动但这两个包装上没坏处很多老教程里都用它们。然后添加 Docker 的 yum 仓库。我一般直接用阿里云的镜像源yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo这里用了 HTTPS 地址避免因为网络协议问题导致仓库文件下载失败。添加完检查一下cat /etc/yum.repos.d/docker-ce.repo能看到内容就说明仓库添加成功。接着刷新缓存yum makecache fast这一步会把仓库元数据拉到本地后续安装时不需要每次联网解析速度会快一些。2.2 安装 docker-ce 并锁定版本先把可用的版本列出来看看yum list docker-ce --showduplicates | sort -r不出意外能看到一串版本号。在 CentOS 7 上我比较推荐装20.10.9-3.el7这个版本因为它是 20.10 系列里和 CentOS 7 默认内核 3.10 兼容性比较好的一个版本。再往后的新版本在旧内核上启动容器时很可能报 runc 相关的错误这一点后面问题排查部分会细说。安装命令yum install -y docker-ce-20.10.9-3.el7注意版本号不能写错yum会严格匹配。如果提示找不到包可能是仓库没有刷新干净重新跑一次yum makecache fast再试。安装完成后建议顺手锁定版本防止以后yum update把 Docker 自动升级成和内核不匹配的新版yum install -y yum-plugin-versionlock yum versionlock docker-ce如果你确实想尝鲜用最新版 Docker也可以直接yum install -y docker-ce但这台机器如果内核保持 3.10 不动后面大概率会遇到麻烦。2.3 启动 Docker 并验证安装完成后启动服务systemctl start docker systemctl enable docker systemctl status docker第一次启动如果没报错status应该显示active (running)。接着看版本信息docker versionClient和Server两段都能显示出版本号才说明客户端和服务端都正常。如果Server段报错连不上多半是服务没起来或者当前用户不在 docker 用户组里。经典的验证方式还是跑一个 hello-worlddocker run hello-world这个镜像极小本地没有它会自动从 Docker Hub 拉取。能正常输出 “Hello from Docker!” 说明整个安装链路基本没问题。如果卡在拉取镜像这一步说明网络到 Docker Hub 不太顺畅直接去 4.2 节配置镜像加速器。3. 核心命令速查镜像、容器与日常运维3.1 镜像管理的高频命令镜像可以理解成容器的“模板”掌握镜像操作是使用 docker 的第一步。我平时最常用的就这么几个docker images # 或者 docker image ls列出本地镜像 docker search mysql # 在 Docker Hub 上搜索镜像 docker pull mysql:8.0 # 拉取指定 tag 的镜像 docker rmi 镜像ID # 删除本地镜像 docker image prune # 清理悬空镜像没有 tag 的残留有个细节容易忽略docker search看到的结果不代表本地有只有docker pull拉下来之后才能在docker images里看到。镜像名后面的:tag一定要带好比如mysql:8.0和mysql:latest是完全不同的东西没指定 tag 默认拉 latest但对生产环境来说显式指定版本更稳妥。3.2 容器运行、进入和日志查看容器的生命周期操作是使用率最高的部分配合参数能实现绝大多数场景需求。先用一条完整命令感受一下docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD你的密码 \ -v /data/mysql:/var/lib/mysql \ --restart always \ mysql:8.0逐一解释参数含义-d表示后台运行--name给容器起名-p 3306:3306把宿主机的 3306 端口映射到容器的 3306 端口-e设置环境变量这里用来指定 MySQL 的 root 密码-v挂载数据卷把容器里的数据目录映射到宿主机--restart always让容器异常退出后自动重启。日常管理用这些命令就够了docker ps # 只看运行中的容器 docker ps -a # 看所有容器包括已退出的 docker exec -it mysql8 bash # 进入容器内部 docker logs -f mysql8 # 跟踪查看容器日志 docker stop mysql8 # 停止容器 docker start mysql8 # 启动已停止的容器 docker restart mysql8 # 重启容器 docker rm -f mysql8 # 强制删除容器注意exec和attach的区别。exec是在容器里新开一个进程退出这个进程不影响主进程而attach是直接附加到容器的主进程上在里面执行exit很可能把容器主进程也终止掉导致容器停止。所以日常进容器调试优先用exec。3.3 资源清理命令与禁忌容器和镜像越堆越多磁盘迟早报警。先看占用情况docker system df清理命令看场景选docker system prune # 清理停止的容器、悬空镜像、无用网络、构建缓存 docker system prune -a # 更激进会清理所有未使用的镜像 docker rm $(docker ps -aq) # 删除所有已停止的容器一条命令搞定批量清理这里有个血的教训docker system prune -a会把你本地所有没有被容器使用的镜像全部删掉如果这台机器上别人也在用极可能误删他们接下来要用的镜像。多人在同一台服务器上协作时尽量别用-a参数或者先和所有人确认一遍再执行。4. 常见问题与排查技巧实录4.1 启动 Docker 失败内核与 Docker 版本不匹配这是 CentOS 7 上最经典的一个坑。现象是安装完 Docker 后执行systemctl start docker服务没起来用journalctl -u docker看日志报错类似Error: failed to start shim: start failed with ioctl: Inappropriate ioctl for device问题根源是 CentOS 7 默认的 3.10 内核太老和新版 Docker 内置的 runc 组件不兼容。通常出现在 Docker 20.10.9 之后的版本上。解决办法有两条路一是升级内核。CentOS 7 可以用 ELRepo 源装长期版内核rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm yum --enablerepoelrepo-kernel install -y kernel-lt awk -F\ $1menuentry {print i : $2} /etc/grub2.cfg # 查看内核列表 grub2-set-default 0 reboot二是退回兼容版本直接安装docker-ce-19.03.8-3.el7。对于不想折腾内核的测试环境我推荐先走这条路最省事。如果你没升级内核的打算后续安装 Docker 时就要有意识地选择 20.10.9 之前的版本避免踩这个坑。4.2 拉取镜像失败或超时配置镜像加速器docker pull卡在 “Pulling fs layer” 或者直接报 timeout是国内网络环境下最常见的问题。解决办法是给 Docker 配置镜像加速器也就是 registry mirror。编辑配置文件mkdir -p /etc/docker vim /etc/docker/daemon.json写入{ registry-mirrors: [https://docker.mirrors.aliyun.com] }不同云厂商提供不同的加速器地址具体以当前可用的为准。如果某个地址失效了换一个再用。修改后重启systemctl daemon-reload systemctl restart docker验证加速器是否生效docker info | grep -A 5 Registry Mirrors能列出配置的地址就说明生效了。加速器只影响 docker pull 拉取的环节不影响容器内部的网络通信。另外提醒一句拉取失败不全是网络问题。如果报错提示 manifest unknown 或 tag not found那是镜像名或 tag 写错了先去 Docker Hub 或镜像仓库页面确认正确的版本号再操作。4.3 端口不通防火墙与 SELinux 的干扰容器里服务正常宿主机curl也通但外部机器就是连不上这种问题十有八九是防火墙或 SELinux 拦了。排查思路按顺序来ss -lntp | grep 3306 # 先确认端口在监听 curl 127.0.0.1:3306 # 本地访问测试 firewall-cmd --list-all # 查看防火墙放行的端口如果是 firewalld 拦截放行对应端口firewall-cmd --zonepublic --add-port3306/tcp --permanent firewall-cmd --reload测试环境图省事也可以直接停掉防火墙systemctl stop firewalld systemctl disable firewalldSELinux 那边的问题通常表现更隐蔽比如容器里写的文件宿主机读不了或者挂载目录权限异常。可以用getenforce查看状态临时调整用setenforce 0生产环境不建议直接禁用 SELinux但测试机可以先临时关掉验证问题是否出在它身上。如果确认是 SELinux 导致再去配对应的策略或添加规则别一锤子全关。4.4 磁盘暴涨Docker 数据目录迁移默认情况下容器镜像、容器日志、数据卷全都存在/var/lib/docker下面而/分区通常不会分太大跑几个数据库容器就把磁盘塞满了。先看谁占用了空间du -sh /var/lib/docker docker system df如果根分区确实紧张最直接的办法是把 Docker 数据目录挪到数据盘。操作步骤systemctl stop docker rsync -avP /var/lib/docker/ /data/docker/ vim /etc/docker/daemon.json在 daemon.json 里加上{ data-root: /data/docker }然后重新启动systemctl start docker启动后确认容器和镜像都还在再考虑把原目录清理掉。迁移过程一定要先停止 Docker否则 rsync 同步时数据还在写入拷贝出来的目录是不一致的容器启动后数据损坏风险很高。这个我踩过一次容器里数据库起不来最后只能从备份恢复教训深刻。5. 进阶实战用容器跑起 MySQL 与 Redis5.1 安装 Docker Compose 的两种方式容器一多一条条docker run就有点管不过来了这时候需要用 Compose 做编排。CentOS 7 上装 Compose 主要有两种方式。第一种是下载二进制文件这种方式最干净curl -L https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose chmod x /usr/local/bin/docker-compose docker-compose --version如果从 GitHub 下载速度不理想可以使用国内镜像加速下载地址每年可能会变以当前可用的为准。第二种是用 pip 安装yum install -y epel-release python2-pip pip install docker-composeCentOS 7 默认的 Python 还是 2.7 环境用 pip 装 Compose 可能会遇到依赖冲突所以我更推荐二进制方式。5.2 部署 MySQL 8.0 并持久化数据以 MySQL 8.0 为例直接跑docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD你的密码 \ -e TZAsia/Shanghai \ -v /data/mysql:/var/lib/mysql \ --restart always \ mysql:8.0-e TZAsia/Shanghai设置容器时区不设置的话 MySQL 默认用 UTC 时间和你本机时间容易对不上。挂载数据卷是最关键的部分/data/mysql是宿主机目录/var/lib/mysql是容器内数据库真实存放数据的目录两者关联起来容器删了数据还在。验证数据库可以这样docker ps docker exec -it mysql8 mysql -uroot -p输入密码后进入 MySQL 命令行执行show databases;能正常返回就说明部署成功。这里有个很容易踩的坑MySQL 8.0 默认的认证插件是caching_sha2_password如果你的客户端是 5.x 时代的工具连接时会报认证错误。需要在容器里创建专门用户并指定旧版认证方式CREATE USER app% IDENTIFIED WITH mysql_native_password BY 你自己的密码; GRANT ALL PRIVILEGES ON *.* TO app%; FLUSH PRIVILEGES;5.3 容器重启策略和数据卷的建议顺手把 Redis 也部署起来docker run -d \ --name redis7 \ -p 6379:6379 \ -v /data/redis:/data \ --restart always \ redis:7-alpineRedis 的数据目录/data也挂载出来避免容器重建丢失数据。--restart always和--restart unless-stopped的区别很多人搞混。always是只要 Docker 服务启动容器无论因为什么退出都会拉起包括你手动docker stop之后Docker 一重启它还是会自动跑unless-stopped则是手动停止过的容器不会被自动拉起。对数据库这类需要长期在线的服务建议用always对可能需要手动维护、暂停部署的容器用unless-stopped更合理。投入生产的容器我建议统一规划宿主机目录比如/data/mysql、/data/redis、/data/app每个容器独立挂载自己的数据卷不要混在一起。这样后面做备份、迁移、扩容操作起来都清爽很多。这套流程从 CentOS 7 系统检查开始到 docker 安装、常用命令、问题排查再到数据库容器化部署基本覆盖了日常使用的大部分场景。我个人在实际操作中的体会是CentOS 7 上用 Docker最大的成本不是学会命令而是解决好内核版本跟 Docker 版本的匹配问题以及提前想清楚数据放在哪里。版本选对了、数据目录规划好了后面能少折腾很多。以后装新机器升级 Docker 时不妨先看一眼内核版本再决定装哪个版本的 docker-ce能省下不少排查时间。
返回列表