1. 环境准备与离线包获取
兄弟们,今天咱们来聊一个非常实际的场景:在完全没有外网的Kylin V10服务器上,怎么把Docker和Docker-Compose这一整套容器化环境给搭起来。我猜你可能是做军工、金融或者某些对网络隔离要求极高的项目,机器就摆在那儿,但就是连不上互联网。别慌,这种离线部署我干过不下十次了,踩过的坑都帮你填平了,跟着我的步骤走,保证你能从零到一把环境跑起来。
首先,你得搞清楚你的Kylin V10是啥架构。这很重要,因为装错了包,后面的活全白干。打开终端,输入uname -m。如果返回的是x86_64,那说明你是英特尔或AMD的64位CPU;如果返回的是aarch64,那你用的是ARM架构的CPU,比如鲲鹏处理器。我遇到过不少朋友看都不看,直接下x86的包,结果在ARM机器上死活装不上,折腾半天才反应过来。确认好架构,咱们就去“搬砖”——把安装包从有网的机器上下载下来。
Docker的离线包,官方提供了一个静态二进制版本的下载地址。这个版本特别适合离线环境,因为它把所有依赖都打包在一起了,解压就能用,不需要联网安装一堆乱七八糟的依赖库。对于x86_64架构,你需要找类似docker-<版本号>.tgz这样的文件。版本选择上,我建议别一味追新,尤其是生产环境。可以选一个比最新版稍旧一两个的稳定版本,比如写这篇文章的时候,最新是28.x,你可以选择26.x或27.x的稳定版,出问题的概率会小很多。下载地址在Docker官网的静态发布页。
至于Docker-Compose,自从v2版本之后,它本身就是一个单独的二进制文件了,这反而让离线安装变得更简单。你需要去GitHub的Docker Compose发布页面,找到对应你系统架构的文件,比如docker-compose-linux-x86_64。这里有个小细节要注意:GitHub的发布页面有时候访问不太稳定,如果你在有网的机器上用浏览器下载慢,可以试试用wget或者curl命令直接下载,速度可能会快不少。把这两个“宝贝”压缩包和文件下载到你的本地电脑或者跳板机上,接下来就是用U盘或者内部文件服务器,把它们传到那台离线的Kylin V10服务器上。我一般会在服务器上专门建一个目录,比如/opt/software/docker_offline,把所有需要的安装材料都放这里,方便管理。
2. Docker引擎的离线安装与深度配置
包传过去了,现在开始动手安装。第一步,解压Docker的压缩包。用tar -xzvf docker-xxx.tgz这个命令,它会解压出一个docker文件夹,里面包含了dockerd、docker、containerd、runc等所有核心二进制文件。接下来,我们需要把这些可执行文件放到系统路径下,让任何用户都能调用。通常的做法是复制到/usr/bin/目录。你可以用sudo mv docker/* /usr/bin/一句命令搞定。这里有个我踩过的坑:移动文件时,确保你有足够的权限,并且最好先检查一下/usr/bin目录下有没有旧版本的docker文件,如果有,建议先备份再覆盖。
光有可执行文件还不够,我们需要让Docker作为一个系统服务在后台运行,并且开机自启。这就需要用上Systemd了。在/usr/lib/systemd/system/目录下,创建一个名为docker.service的文件。这个文件的内容是个模板,我直接给你一个经过我多次验证、在Kylin V10上运行稳定的配置:
[Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=infinity LimitNPROC=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target创建好文件后,依次执行下面几个命令,它们的作用分别是:给服务文件执行权限、让Systemd重新加载配置、启动Docker服务、设置开机自启。
sudo chmod +x /usr/lib/systemd/system/docker.service sudo systemctl daemon-reload sudo systemctl start docker sudo systemctl enable docker执行完,赶紧验证一下。输入sudo docker version。如果安装成功,你会看到Client和Server两部分的版本信息都打印出来了。这里有个关键点:只有Server部分也正常显示,才说明Docker引擎(也就是dockerd)真的启动成功了。如果只看到Client信息,说明二进制文件装好了,但后台服务没起来。这时候别急,用sudo systemctl status docker查看服务状态,或者用sudo journalctl -u docker --no-pager -f查看实时日志,通常能很快定位问题,比如权限不足、端口冲突等。
3. Docker-Compose的部署与权限优化
Docker装好了,接下来搞定Docker-Compose,它是我们管理多容器应用的“指挥棒”。安装过程简单得令人发指:直接把之前下载的那个二进制文件(比如docker-compose-linux-x86_64)复制到/usr/bin/目录,并改名为docker-compose,然后赋予执行权限就行。
sudo cp docker-compose-linux-x86_64 /usr/bin/docker-compose sudo chmod +x /usr/bin/docker-compose安装完,照例验证:docker-compose version。看到版本号输出,就说明成功了。但是,这里我想分享一个实际运维中非常重要,但很多教程不提的点:用户权限和组管理。默认情况下,只有root用户或者有sudo权限的用户才能执行docker命令。这在实际开发协作中很不方便,也存在安全隐患(给用户sudo权限过大)。
更优雅的做法是把需要使用docker的普通用户加入到docker用户组中。首先,确保docker服务在安装过程中已经创建了这个组(通常会自动创建)。然后,将你的用户加入该组:
sudo usermod -aG docker $你的用户名重要提示:执行完这个命令后,用户需要完全退出当前终端会话,并重新登录,这个组权限变更才会生效。之后,这个用户就可以直接运行docker ps、docker-compose up等命令,而不用每次都加sudo了。这既方便了日常操作,也遵循了最小权限原则。
4. 实战:编写你的第一个docker-compose.yml
工具都齐活了,我们来点真格的。Docker-Compose的核心就是一个YAML格式的配置文件,通常命名为docker-compose.yml。这个文件里,你定义了整个应用栈需要哪些服务(容器)、它们之间怎么连接、用什么镜像、端口怎么映射、数据存哪里等等。我以一个最经典的“WordPress博客网站”为例,它需要MySQL数据库和WordPress本身两个容器。
在你项目的根目录下,创建一个docker-compose.yml文件:
version: '3.8' services: db: image: mysql:8.0 container_name: my_wordpress_db restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress volumes: - db_data:/var/lib/mysql networks: - wp-network wordpress: image: wordpress:latest container_name: my_wordpress restart: always depends_on: - db environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress volumes: - wp_data:/var/www/html ports: - "8080:80" networks: - wp-network volumes: db_data: wp_data: networks: wp-network: driver: bridge我来拆解一下这个文件里的关键部分。services下面定义了两个服务:db(数据库)和wordpress(网站)。每个服务都指定了使用的镜像,比如mysql:8.0。container_name给容器起个名字,方便管理。restart: always确保容器意外退出时自动重启,这对于服务可靠性很重要。
environment部分设置了环境变量,相当于给容器传递配置参数。比如这里设置了MySQL的root密码、创建的数据库名和用户。volumes是数据持久化的关键。你看我用了命名卷db_data和wp_data。这样做的好处是,即使你把容器删了,数据库里的文章和上传的图片文件都还保留在宿主机的某个地方,下次启动新容器挂载这个卷,数据就回来了。ports把容器内部的端口映射到宿主机,这里把WordPress容器的80端口映射到了宿主机的8080端口,这样你访问服务器IP:8080就能看到网站了。
最后,networks定义了一个自定义的桥接网络wp-network,让db和wordpress两个容器在同一个网络内,它们可以通过服务名(db)直接互相访问,不需要知道对方的IP地址,这比用默认网络方便和安全得多。
5. 离线环境下的镜像迁移与项目启动
在离线环境里,最大的挑战不是安装工具,而是怎么把需要的Docker镜像弄进去。因为docker-compose.yml里写的image: mysql:8.0,执行时会尝试从互联网拉取,这在离线环境显然会失败。所以,我们需要在有网的环境先把镜像“下载”下来,再“搬运”到离线服务器。
在有网的机器上,使用docker save命令将镜像打包成一个tar文件:
docker pull mysql:8.0 docker pull wordpress:latest docker save -o my-offline-images.tar mysql:8.0 wordpress:latest这条命令会把mysql:8.0和wordpress:latest两个镜像及其所有层,打包成一个名为my-offline-images.tar的文件。把这个tar文件用U盘或内网传输到Kylin V10服务器上。
在离线服务器上,使用docker load命令加载这个镜像包:
docker load -i my-offline-images.tar加载完成后,用docker images命令检查一下,应该能看到这两个镜像已经安静地躺在你的镜像列表里了。
万事俱备,现在可以启动你的完整应用了。进入存放docker-compose.yml文件的目录,执行一个简单的命令:
docker-compose up -d那个-d参数代表“后台模式”(detached)。执行后,Docker-Compose会按照文件定义,依次创建网络、卷,然后启动MySQL和WordPress容器。你可以用docker-compose ps查看这两个容器的运行状态,看到状态都是“Up”就说明成功了。这时候,打开浏览器,访问http://你的服务器IP:8080,你应该就能看到WordPress著名的安装界面了。
6. 日常运维命令与故障排查锦囊
环境跑起来了,日常怎么管理呢?我把我最常用的几条命令分享给你,掌握了这些,基本就能应对80%的场景。
查看服务状态和日志:
docker-compose ps一眼看清所有服务的状态。docker-compose logs查看所有服务的合并日志。如果想看某个特定服务(比如db)的日志,或者实时跟踪日志输出,可以这样:docker-compose logs db # 查看数据库日志 docker-compose logs -f wordpress # 实时跟踪WordPress日志(类似tail -f)启停与重启: 想临时关闭所有服务,但保留容器和数据?用
docker-compose stop。 想重新启动停止的服务?用docker-compose start。 如果修改了docker-compose.yml配置文件,需要重启所有服务以使更改生效,用docker-compose restart。 想彻底停止并移除所有容器、网络(但保留数据卷和镜像)?用docker-compose down。这个命令在你想清理环境重新部署时非常有用。进入容器内部: 有时候需要到容器里看看,比如检查MySQL的配置文件,或者调试WordPress的PHP环境。可以用
docker-compose exec:docker-compose exec db bash # 进入数据库容器的bash shell docker-compose exec wordpress sh # 进入WordPress容器的shell故障排查思路:
- 服务起不来:首先
docker-compose logs看错误日志。最常见的是镜像不存在(离线环境没load)、端口被占用、或者环境变量配置错误。 - 容器不断重启:用
docker-compose ps看退出代码,再用docker inspect <容器ID>看详细状态。往往是应用本身启动失败(比如数据库密码不对)。 - 网络不通:确保
docker-compose.yml里定义的服务在同一个自定义网络下。可以用docker network ls和docker network inspect <网络名>来检查网络详情和连接的容器。 - 数据卷权限问题:特别是MySQL或Nginx这类容器,如果挂载的宿主机目录权限不对,容器可能没有写入权限而启动失败。确保宿主机目录对容器内进程的用户(通常是root或特定的非root用户)是可写的。
- 服务起不来:首先
最后,关于离线环境的镜像更新。当需要升级镜像版本时,你需要在有网环境拉取新镜像,重新save成tar包,传到离线服务器load进来。然后修改docker-compose.yml中的镜像标签,最后执行docker-compose down和docker-compose up -d来更新服务。这个过程虽然比在线环境麻烦点,但在严格的内网环境中,这是标准且安全的工作流程。