一.首先配置软件仓库并安装docker-ce
tips:RHEL9 系统官方软件源不自带 Docker,不配置这个仓库,dnf install docker-ce 会提示找不到软件包,创建阿里云 Docker YUM 仓库:给 DNF/YUM 提供 Docker 软件安装源,用来下载安装 docker-ce、docker-compose-plugin 等 Docker 相关 rpm 安装包。
1. 创建阿里云 Docker YUM 仓库
root@docker1 \~# cat > /etc/yum.repos.d/docker.repo << EOF
docker
name = docker
baseurl = https://mirrors.aliyun.com/docker-ce/linux/rhel/9.8/x86_64/stable/
gpgcheck = 0 #关闭 rpm 签名校验,省去导入密钥步骤
EOF
2. 生成软件缓存
root@docker1 \~# dnf makecache
3. 删除 podman
root@docker1 \~# dnf remove podman #RHEL9 默认自带 podman,podman 与 docker 存在冲突,卸载避免冲突。
4.搜索 docker 相关软件包
root@docker-node1 \~# dnf search docker
5. 安装 Docker 社区版
root@docker1 \~# dnf install docker-ce -y
6. 修改 docker.service 启动参数
root@docker1 \~# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true #--iptables=true
作用:允许 Docker 自动操作宿主机 iptables 防火墙,实现端口转发、容器网络互通,修改 systemd 单元文件后,记得重载配置systemctl daemon-reload
7. 加载网桥内核模块 br_netfilter
root@docker1 \~# echo br_netfilter > /etc/modules-load.d/docker_mod.conf
root@docker1 \~# modprobe -a br_netfilter # /etc/modules-load.d/ 目录:开机自动加载内核模块配置
#br_netfilter:网桥过滤模块;容器跨主机通信、kubernetes 必须依赖
#modprobe:立即手动加载模块,无需重启生效
8. 内核网络参数优化(容器网络必备)
root@docker1 \~# cat > /etc/sysctl.d/docker.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF #net.bridge.bridge-nf-call-iptables=1
网桥流量交给 iptables 处理,实现容器端口转发、SNAT/DNAT
#net.bridge.bridge-nf-call-ip6tables=1
IPv6 网桥流量交给 ip6tables
#net.ipv4.ip_forward=1
开启宿主机 IP 转发,容器能够访问外网
root@docker1 \~# sysctl --system #加载所有 sysctl 配置,让其生效
root@docker1 \~# systemctl enable --now docker #启动并设置开机自启
二.搭建自己的私有仓库
tips:因为我本地有文件压缩包,把离线打包好的 registry 镜像导入本机 Docker,导入成功后,你就可以启动 Docker 私有仓库(Registry),有了registry私有镜像仓库,就用来存放、管理自己的容器镜像,类似简化版 Docker Hub,企业内网服务器可以从这台私有仓库 docker pull / docker push 上传下载镜像,不用访问外网。
1.离线环境导入镜像
root@docker1 \~# docker load -i registry-202608.tar
Loaded image: registry:latest root@docker1 \~# docker images
registry:latest 1be55279f18a 83.3MB 20.4MB
2.启动私有仓库容器
root@docker-node1 \~# docker run -d --name registry \
--restart=always -p 5000:5000 registry:latest
8f396bcbd54788350011de8def2ad79a2724ca1e480c4b8494b9208cdddfb0da #宿主机 5000 端口对外提供仓库服务
#-v 挂载目录:持久化保存上传的镜像
root@docker-node1 \~# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f396bcbd547 registry:latest "/entrypoint.sh /etc..." 3 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp registry
3.使用私有仓库
root@docker1 \~# docker tag nginx-llj:v1 172.25.254.10:5000/nginx-llj:v1
root@docker1 \~# docker push 172.25.254.10:5000/nginx-llj:v1
The push refers to repository 172.25.254.10:5000/nginx-llj
44136fa355b3: Waiting
7b6582e7794f: Waiting
failed to do request: Head "https://172.25.254.10:5000/v2/nginx-llj/blobs/sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a": http: server gave HTTP response to HTTPS client
#报错原因:Docker 客户端默认使用 HTTPS 协议 去连接私有仓库 172.25.254.10:5000,但是我的 registry 私有仓库只开启了普通 HTTP 服务,没有配置 SSL 证书,服务返回 HTTP 报文,客户端当成 HTTPS 解析,直接握手失败 #解决报错方式,编辑 docker 守护进程配置,别的机器想要从 172.25.254.10:5000 pull 镜像,都需要配置这个参数
root@docker1 \~# vim /etc/docker/daemon.json
{
"insecure-registries" : "172.25.254.10:5000"
} root@docker1 \~systemctl daemon-reload
root@docker1 \~# systemctl restart docker.service root@docker1 \~# docker push 172.25.254.10:5000/nginx-llj:v1
The push refers to repository 172.25.254.10:5000/nginx-llj
d6b1b89eccac: Pushed
2d4d7adf6272: Pushed
cf397222899a: Pushed
v1: digest: sha256:e341a1d73ee2e5155e06215e4e000633ef071f29d0012848dbfc12b2aac2a37
这样我们就将私有仓库配置好了,别的机器拉取docker pull 172.25.254.10:5000/nginx-llj:v1就行root@docker2 \~# docker pull 172.25.254.10:5000/nginx-llj:v1
v1: Pulling from nginx-llj
453588a9b039: Pull complete
cac2ae0193cb: Pull complete
44136fa355b3: Download complete
7b6582e7794f: Download complete
Digest: sha256:e341a1d73ee2e5155e06215e4e000633ef071f29d0012848dbfc12b2aac2a374
Status: Downloaded newer image for 172.25.254.10:5000/nginx-llj:v1
172.25.254.10:5000/nginx-llj:v1
root@docker2 \~# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
172.25.254.10:5000/nginx-llj:v1 e341a1d73ee2 74MB 18.1MB
三.构建企业级docker镜像仓库
1.解压harbor离线安装包
tips:harbor企业级仓库底层内置了 registry,两套都是镜像仓库,作用重叠,既然要升级使用功能更强的 Harbor,不再需要独立外置 registry 容器,保留属于多余服务。 运维规范上:业务升级替换组件时,下线旧服务,避免环境冗余、冲突、混淆。
root@docker1 harbor# docker rm -f registry
registry root@docker1 \~# tar zxf harbor-offline-installer-v2.14.0.tgz -C /opt/
root@docker1 harbor# ls
common.sh harbor.v2.14.0.tar.gz harbor.yml.tmpl install.sh LICENSE prepare
2.建立数据目录和认证文件
tips:先生成加密传输时所需要的key证书,使用 OpenSSL 生成一套自签名 SSL 证书,用于给 Harbor 配置 HTTPS。
root@docker1 \~# mkdir certs
root@docker1 \~# openssl req -newkey rsa:4096 -nodes \
-keyout certs/llj.org.key \
-addext "subjectAltName = DNS:reg.llj.org" \
-x509 -days 365 -out certs/llj.org.crt
req:#证书请求工具 -newkey rsa#4096新建密钥对,加密算法 RSA,密钥长度 4096 位
-nodes#私钥不设置密码。(如果不加这个,启动 Harbor 每次都要手动输入私钥密码,容器无法后台自动启动)
-keyout certs/llj.org.key#输出私钥文件(私钥,严格保护)
-addext "subjectAltName = DNS:reg.llj.org"#扩展 SAN 域名(重中之重!)新版 Docker 校验证书强制检查 SAN 扩展;只写 CN 域名会报错证书不匹配。证书支持域名:reg.llj.org
-x509#直接生成自签名证书,不需要向 CA 机构申请
-days 365#证书有效期 365 天 -out certs/llj.org.crt#输出公钥证书文件
root@docker1 \~# docker run -d --name registry \
--restart=always -p 443:443 \
-v /root/certs:/certs -v lib/registry \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key \
registry
root@docker1 \~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c51b92b46c44 registry "/entrypoint.sh /etc..." About a minute ago Up About a minute 0.0.0.0:443->443/tcp, :::443->443/tcp, 5000/tcp registry
3.使用key和证书启动仓库
root@docker1 \~# docker run -d --name registry \
--restart=always -p 443:443 \ #端口注意别跟其他容器冲突
-v /root/certs:/certs -v /data/registry:/var/lib/registry \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/llj.org.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/llj.org.key \
registry
4.使用仓库上传镜像
tips:因为目前使用的是 OpenSSL 自签名证书,没有被全球可信 CA 颁发,Docker 客户端不信任这份证书,TLS 校验直接失败,无法 push 镜像,我们要么配置 Docker 不安全,要么把自签名证书加入系统信任列表,我更推荐各位彭于晏第二种,是标准规范方式
root@docker1 \~# vim /etc/hosts
172.25.254.10 docker1 reg.llj.org
root@docker-node1 \~# mkdir -p /etc/docker/certs.d/reg.timinglee.org #创建目录(Docker 识别自签名证书固定路径)
root@docker-node1 \~# cp certs/timinglee.org.crt /etc/docker/certs.d/reg.timinglee.org/ca.crt #复制证书(只需要 .crt 文件,不要 key!)Docker 单独从该目录加载私有仓库根证书,完成信任,不再报未知机构签名
root@docker1 \~#systemctl restart docker root@docker-node1 \~# docker push reg.llj.org/busybox:latest
5.使用仓库下载镜像
root@docker2 \~# vim /etc/hosts
172.25.254.10 reg.llj.org #必须填写 Harbor 服务器的 IP!建立网络连接,访问 docker1 的 Harbor 服务
root@docker1 \~# scp -r /etc/docker/certs.d/ root@172.25.254.20:/etc/docker/ca.crt #新机器手动搭建时不要放错目录名称、文件名必须是 ca.crt,不能随意改名,Docker 固定识别该目录下 ca.crt 作为根证书(Docker 规定信任私有仓库证书标准路径) ,把 Harbor 自签名证书远程拷贝到 docker-node2,让 node2 的 Docker 能够信任私有仓库的 HTTPS 证书。把自签名根证书加入 Docker 信任列表,完整 TLS 校验。
root@docker2 \~# systemctl restart docker.service
root@docker2 \~# docker pull reg.llj.org/busybox:latest
6.生成harbor.yml
首先创建/data 统一数据目录,规范存放持久化数据、证书,将生成好的自签名证书(公钥 crt、私钥 key)复制到 /data/certs/,后续 harbor.yml 内直接填写路径
root@docker1 \~# mkdir /data
root@docker1 \~# cp -r /root/certs/ /data/ #Harbor 服务端使用(harbor.yml 读取,存放生成好的自签名证书crt+key 整套)
root@docker-node1 \~cd /opt/harbor root@docker-node1 harbor# cp harbor.yml.tmpl harbor.yml
root@docker-node1 harbor# vim harbor.yml hostname: reg.timinglee.org https:
port: 443
certificate: /data/certs/llj.org.crt
private_key: /data/certs/llj.org.key harbor_admin_password: llj
后续修改 harbor.yml 配置,修改 yml 证书、域名等配置,必须先执行 ./prepare,再启动docker compose up -d 生效
7.网页访问harbor
tips:网页登录 Harbor,先手动创建项目(例如 llj)
root@docker-node1 harbor# docker tag busybox:latest reg.llj.org/llj/busybox:latest root@docker-node1 harbor# docker push reg.llj.org/llj/nginx-debian13:latest