Openshift 4.4 静态 IP 离线安装系列(一):准备离线资源

本系列文章描述了离线环境下以 UPI (User Provisioned Infrastructure) 模式安装 Openshift Container Platform (OCP) 4.4.5 的步骤,我的环境是 VMware ESXI 虚拟化,也适用于其他方式提供的虚拟机或物理主机。离线资源包括安装镜像、所有样例 Image StreamOperatorHub 中的所有 RedHat Operators。

本系列采用静态 IP 的方式安装 OCP 集群,如果你可以随意分配网络,建议采用 DHCP 的方式。

1. 离线环境

单独准备一台节点用来执行安装任务和离线资源准备,这台节点最好具备魔法上网的能力,以便可以同时访问内外网。我们称这台节点为基础节点

需要部署一个私有镜像仓库,以供 OCP 安装和运行时使用,要求支持 version 2 schema 2 (manifest list),我这里选择的是 Harbor 2.0

很多人误以为必须联系 Red Hat 销售,签单之后才能使用 OCP4,其实不然,注册一个开发者账号[1]后就可以获得 quay.ioregistry.redhat.io 的拉取密钥了。

2. 准备离线安装介质

获取版本信息

目前最新的 OCP 版本是 4.4.5,可以从这里下载客户端:

  • https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest-4.4/[2]

解压出来的二进制文件放到基础节点的 $PATH 下,看下版本信息:

创建内部镜像仓库

内部镜像仓库用于存放部署 OCP 集群所需的镜像,仓库本身使用 Harbor 部署,目前最为流行的私有镜像仓库便是 CNCF 的毕业生之一的 Harbor(中文含义:港口)。

首先修改基础节点的主机名:

$ hostnamectl set-hostname bastion.openshift4.example.com

所有节点主机名都要采用三级域名格式,如 master1.aa.bb.com

Docker 安装步骤就不写了,略过。接着安装 docker-compose

$ curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose

下载 Harbor 离线安装包并解压:

$ wget https://github.com/goharbor/harbor/releases/download/v2.0.0/harbor-offline-installer-v2.0.0.tgz
$ tar -xvf harbor-offline-installer-v2.0.0.tgz -C /opt/

生成自签名证书:

$ mkdir /opt/harbor/certs
$ cd /opt/harbor/certs

# 生成私钥
$ openssl genrsa -out server.key 1024

根据私钥生成证书申请文件 csr

$ openssl req -new -key server.key -out server.csr

这里根据命令行向导来进行信息输入:

Common Name 可以输入:*.yourdomain.com,这种方式可以生成通配符域名证书。

使用私钥对证书申请进行签名从而生成证书

$ openssl req -new -key server.key -out server.csr

这样就生成了有效期为 10 年的证书文件,对于自己内网服务使用足够。

证书搞定了之后,就可以接着配置 Harbor 了。打开 /opt/harbor/harbor.yml 文件,修改 hostname 域名、https 证书等配置信息,具体如下:

# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: bastion.openshift4.example.com
# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 8080
# https related config
https:
  # https port for harbor, default is 443
  port: 8443
  # The path of cert and key files for nginx
  certificate: /opt/harbor/certs/server.crt
  private_key: /opt/harbor/certs/server.key

我这里把所有需要的基础服务都部署在同一个节点上,后面安装 OCP 时需要用到负载均衡器的 44380 端口,所以这里 Harbor 使用了非标准端口。如果你资源充足,可以将 Harbor 部署在不同的节点上。

接着执行下面的命令进行安装:

$ ./install.sh --with-clair

以上安装命令同时安装了 Clair 服务,一个用户镜像漏洞静态分析的工具。如果不需要,可以省略该选项。

安装成功后,将自签名的证书复制到默认信任证书路径:

$ cp /opt/harbor/certs/server.crt /etc/pki/ca-trust/source/anchors/
$ update-ca-trust extract

或者将其复制到 docker 的信任证书路径:

$ mkdir -p /etc/docker/certs.d/bastion.openshift4.example.com:8443
$ cp /opt/harbor/certs/server.crt /etc/docker/certs.d/bastion.openshift4.example.com:8443/
$ systemctl restart docker

现在可以通过 docker login 命令来测试仓库的连通性,看到如下字样即表示安装成功(也可以通过浏览器访问 Web UI):

???? → docker login bastion.openshift4.example.com:8443
Username: admin
Password: Harbor12345

Login Succeeded

下载镜像文件

准备拉取镜像权限认证文件。从 Red Hat OpenShift Cluster Manager 站点的 Pull Secret 页面[3]下载 registry.redhat.iopull secret

# 把下载的 txt 文件转出 json 格式,如果没有 jq 命令,通过 epel 源安装
$ cat ./pull-secret.txt | jq . > pull-secret.json

$ yum install epel-release
$ yum install jq

JSON 内容如下:

{
  "auths": {
    "cloud.openshift.com": {
      "auth": "b3BlbnNo...",
      "email": "you@example.com"
    },
    "quay.io": {
      "auth": "b3BlbnNo...",
      "email": "you@example.com"
    },
    "registry.connect.redhat.com": {
      "auth": "NTE3Njg5Nj...",
      "email": "you@example.com"
    },
    "registry.redhat.io": {
      "auth": "NTE3Njg5Nj...",
      "email": "you@example.com"
    }
  }
}

把本地仓库的用户密码转换成 base64 编码:

$ echo -n 'root:password' | base64 -w0 
cm9vdDpwYXNzd29yZA==

然后在 pull-secret.json 里面加一段本地仓库的权限。第一行仓库域名和端口,第二行是上面的 base64,第三行随便填个邮箱:

  "auths": {
...
    "registry.example.com:5000": {
      "auth": "cm9vdDpwYXNzd29yZA==",
      "email": "you@example.com"
   },
...

设置环境变量:

$ export OCP_RELEASE="4.4.5-x86_64"
$ export LOCAL_REGISTRY='bastion.openshift4.example.com:8443' 
$ export LOCAL_REPOSITORY='ocp4/openshift4'
$ export PRODUCT_REPO='openshift-release-dev'
$ export LOCAL_SECRET_JSON='/root/pull-secret.json'
$ export RELEASE_NAME="ocp-release"
  • OCP_RELEASE : OCP 版本,可以在这个页面[4]查看。如果版本不对,下面执行 oc adm 时会提示 image does not exist

  • LOCAL_REGISTRY : 本地仓库的域名和端口。

  • LOCAL_REPOSITORY : 镜像存储库名称,使用 ocp4/openshift4。

  • PRODUCT_REPORELEASE_NAME 都不需要改,这些都是一些版本特征,保持不变即可。

  • LOCAL_SECRET_JSON : 密钥路径,就是上面 pull-secret.json 的存放路径。

在 Harbor 中创建一个项目 ocp4 用来存放同步过来的镜像:

最后一步就是同步镜像,这一步的动作就是把 quay 官方仓库中的镜像,同步到本地仓库,如果失败了可以重新执行命令,整体内容大概 5G

$ oc adm -a ${LOCAL_SECRET_JSON} release mirror \
     --from=quay.io/${PRODUCT_REPO}/${RELEASE_NAME}:${OCP_RELEASE} \
     --to=${LOCAL_REGISTRY}/${LOCAL_REPOSITORY} \
     --to-release-image=${LOCAL_REGISTRY}/${LOCAL_REPOSITORY}:${OCP_RELEASE}

oc adm release mirror 命令执行完成后会输出下面类似的信息,保存下来,将来会用在 install-config.yaml 文件中:

imageContentSources:
- mirrors:
  - bastion.openshift4.example.com:8443/ocp4/openshift4
  source: quay.io/openshift-release-dev/ocp-release
- mirrors:
  - bastion.openshift4.example.com:8443/ocp4/openshift4
  source: quay.io/openshift-release-dev/ocp-v4.0-art-dev

本地镜像仓库缓存好镜像之后,通过 tag/list 接口查看所有 tag,如果能列出来一堆就说明是正常的:

$ curl -s -u admin:Harbor12345 -k https://bastion.openshift4.example.com:8443/v2/ocp4/openshift4/tags/list|jq .

{
  "name": "ocp4/openshift4",
  "tags": [
    "4.4.5-aws-machine-controllers",
    "4.4.5-azure-machine-controllers",
    "4.4.5-baremetal-installer",
    "4.4.5-baremetal-machine-controllers",
    "4.4.5-baremetal-operator",
    "4.4.5-baremetal-runtimecfg",
    "4.4.5-cli",
    "4.4.5-cli-artifacts",
    "4.4.5-cloud-credential-operator",
    "4.4.5-cluster-authentication-operator",
    "4.4.5-cluster-autoscaler",
    "4.4.5-cluster-autoscaler-operator",
    "4.4.5-cluster-bootstrap",
    "4.4.5-cluster-config-operator",
    "4.4.5-cluster-csi-snapshot-controller-operator",
    "4.4.5-cluster-dns-operator",
    "4.4.5-cluster-etcd-operator",
    "4.4.5-cluster-image-registry-operator",
    "4.4.5-cluster-ingress-operator",
    "4.4.5-cluster-kube-apiserver-operator",
    "4.4.5-cluster-kube-controller-manager-operator",
    "4.4.5-cluster-kube-scheduler-operator",
    "4.4.5-cluster-kube-storage-version-migrator-operator",
    "4.4.5-cluster-machine-approver",
    "4.4.5-cluster-monitoring-operator",
    "4.4.5-cluster-network-operator",
    "4.4.5-cluster-node-tuned",
    "4.4.5-cluster-node-tuning-operator",
    "4.4.5-cluster-openshift-apiserver-operator",
    "4.4.5-cluster-openshift-controller-manager-operator",
    "4.4.5-cluster-policy-controller",
    "4.4.5-cluster-samples-operator",
    "4.4.5-cluster-storage-operator",
    "4.4.5-cluster-svcat-apiserver-operator",
    "4.4.5-cluster-svcat-controller-manager-operator",
    "4.4.5-cluster-update-keys",
    "4.4.5-cluster-version-operator",
    "4.4.5-configmap-reloader",
    "4.4.5-console",
    "4.4.5-console-operator",
    "4.4.5-container-networking-plugins",
    "4.4.5-coredns",
    "4.4.5-csi-snapshot-controller",
    "4.4.5-deployer",
    "4.4.5-docker-builder",
    "4.4.5-docker-registry",
    "4.4.5-etcd",
    "4.4.5-gcp-machine-controllers",
    "4.4.5-grafana",
    "4.4.5-haproxy-router",
    "4.4.5-hyperkube",
    "4.4.5-insights-operator",
    "4.4.5-installer",
    "4.4.5-installer-artifacts",
    "4.4.5-ironic",
    "4.4.5-ironic-hardware-inventory-recorder",
    "4.4.5-ironic-inspector",
    "4.4.5-ironic-ipa-downloader",
    "4.4.5-ironic-machine-os-downloader",
    "4.4.5-ironic-static-ip-manager",
    "4.4.5-jenkins",
    "4.4.5-jenkins-agent-maven",
    "4.4.5-jenkins-agent-nodejs",
    "4.4.5-k8s-prometheus-adapter",
    "4.4.5-keepalived-ipfailover",
    "4.4.5-kube-client-agent",
    "4.4.5-kube-etcd-signer-server",
    "4.4.5-kube-proxy",
    "4.4.5-kube-rbac-proxy",
    "4.4.5-kube-state-metrics",
    "4.4.5-kube-storage-version-migrator",
    "4.4.5-kuryr-cni",
    "4.4.5-kuryr-controller",
    "4.4.5-libvirt-machine-controllers",
    "4.4.5-local-storage-static-provisioner",
    "4.4.5-machine-api-operator",
    "4.4.5-machine-config-operator",
    "4.4.5-machine-os-content",
    "4.4.5-mdns-publisher",
    "4.4.5-multus-admission-controller",
    "4.4.5-multus-cni",
    "4.4.5-multus-route-override-cni",
    "4.4.5-multus-whereabouts-ipam-cni",
    "4.4.5-must-gather",
    "4.4.5-oauth-proxy",
    "4.4.5-oauth-server",
    "4.4.5-openshift-apiserver",
    "4.4.5-openshift-controller-manager",
    "4.4.5-openshift-state-metrics",
    "4.4.5-openstack-machine-controllers",
    "4.4.5-operator-lifecycle-manager",
    "4.4.5-operator-marketplace",
    "4.4.5-operator-registry",
    "4.4.5-ovirt-machine-controllers",
    "4.4.5-ovn-kubernetes",
    "4.4.5-pod",
    "4.4.5-prom-label-proxy",
    "4.4.5-prometheus",
    "4.4.5-prometheus-alertmanager",
    "4.4.5-prometheus-config-reloader",
    "4.4.5-prometheus-node-exporter",
    "4.4.5-prometheus-operator",
    "4.4.5-sdn",
    "4.4.5-service-ca-operator",
    "4.4.5-service-catalog",
    "4.4.5-telemeter",
    "4.4.5-tests",
    "4.4.5-thanos",
    "4.4.5-x86_64"
  ]
}

Harbor 中也能看到所有的镜像:

提取 openshift-install 命令

为了保证安装版本一致性,需要从镜像库中提取 openshift-install 二进制文件,不能直接从 https://mirror.openshift.com/pub/openshift-v4/clients/ocp/4.4.5 下载,不然后面会有 sha256 匹配不上的问题。

# 这一步需要用到上面的 export 变量
$ oc adm release extract \
  -a ${LOCAL_SECRET_JSON} \
  --command=openshift-install \
  "${LOCAL_REGISTRY}/${LOCAL_REPOSITORY}:${OCP_RELEASE}"

如果提示 error: image dose not exist,说明拉取的镜像不全,或者版本不对。

把文件移动到 $PATH 并确认版本:

$ chmod +x openshift-install
$ mv openshift-install /usr/local/bin/

$ openshift-install version
openshift-install 4.4.5
built from commit 15eac3785998a5bc250c9f72101a4a9cb767e494
release image bastion.openshift4.example.com:8443/ocp4/openshift4@sha256:4a461dc23a9d323c8bd7a8631bed078a9e5eec690ce073f78b645c83fb4cdf74

3. 准备 Image Stream 样例镜像

准备一个镜像列表,然后使用 oc image mirror 将镜像同步到私有仓库中:

cat sample-images.txt | while read line; do
  target=$(echo $line | sed 's/registry.redhat.io/bastion.openshift4.example.com:8443/')
  oc image mirror -a ${LOCAL_SECRET_JSON} $line $target
done

如果之前装过 OCP 4.4.5,把 openshift-cluster-samples-operator 项目下 cluster-samples-operator Pod 的 /opt/openshift 目录同步出来,简单 grep 一下就都有了完整的镜像列表。

完整列表参考这里[5]

4. 准备 OperatorHub 离线资源

首先在 Harbor 中创建一个 devinfra 项目,然后构建 RedHat Operators 的 catalog image, 保存为 bastion.openshift4.example.com:8443/devinfra/redhat-operators:v1

$ oc adm catalog build \
  -a ${LOCAL_SECRET_JSON} \
  --appregistry-endpoint https://quay.io/cnr \
  --from=registry.redhat.io/openshift4/ose-operator-registry:v4.4 \
  --appregistry-org redhat-operators \
  --to=bastion.openshift4.example.com:8443/devinfra/redhat-operators:v1

这个 catalog image 相当于 RedHat Operators 的一个目录,通过 catalog image 可以找到  RedHat Operators 的所有镜像。而且 catalog image 使用 sha256 digest 来引用镜像,能够确保应用有稳定可重复的部署。

然后使用 catalog image 同步 RedHat Operators 的所有镜像到私有仓库:

$ oc adm catalog mirror \
  -a ${LOCAL_SECRET_JSON} \
  bastion.openshift4.example.com:8443/devinfra/redhat-operators:v1 \
  bastion.openshift4.example.com:8443

如果执行过程中遇到 project not found 之类的错误,可根据报错信息到 Harbor 中创建相应的项目,不用中断任务。

这个命令结束后会产生 redhat-operators-manifests 目录,下面有两个文件:

  • imageContentSourcePolicy.yaml : 定义了一个 ImageContentSourcePolicy 对象,该对象可以配置节点将其对官方 Operator manifests 中镜像的引用改为对本地镜像仓库中镜像的引用。

  • mapping.txt : 包含了所有的源镜像在本地镜像仓库中的映射位置。oc image mirror 命令可以引用该文件进一步修改镜像配置。

然而目前这么做还是有问题 1800674[6]: 同步出来的镜像 manifest digest 不对,导致后面离线安装 Operator 时会报镜像无法获取的错误。

暂时可以使用上面 bugzilla 链接里给出的临时解决方案,先安装 skopeo:

$ yum install -y golang gpgme-devel libassuan-devel btrfs-progs-devel device-mapper-devel
$ git clone https://github.com/containers/skopeo
$ cd skopeo
$ make binary-local
$ mv skopeo /usr/local/bin/

pull-secret.json 中解码 quay.ioregistry.redhat.ioregistry.access.redhat.com 的用户名密码,然后通过下面的命令认证:

$ skopeo login -u <quay.io_user> -p <quay.io_psw> quay.io
$ skopeo login -u <registry.redhat.io_user> -p <registry.redhat.io_psw> registry.redhat.io
$ skopeo login -u <registry.access.redhat.com_user> -p <registry.access.redhat.com_psw> registry.access.redhat.com

最后同步镜像的 manifest digest:

cat redhat-operators-manifests/mapping.txt | while read line; do
  origin=$(echo $line | cut -d= -f1)
  target=$(echo $line | cut -d= -f2)
  if [[ "$origin" =~ "sha256" ]]; then
    tag=$(echo $origin | cut -d: -f2 | cut -c -8)
    skopeo copy --all docker://$origin docker://$target:$tag
  else
    skopeo copy --all docker://$origin docker://$target
  fi
done

不得不说,OCP 的安装真是个浩大的工程,这洋洋洒洒的一大篇也只是准备了离线资源,这只是安装的一小步,还有很长的步骤要写,心理素质不过关的同学切勿随意模仿。

5. 参考资料

  • 离线部署 Openshift Container Platform 4.3 - 1: 准备离线资源[7]

  • Chapter 9. Using Operator Lifecycle Manager on restricted networks[8]

脚注

[1]

开发者账号: https://developers.redhat.com/

[2]

https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest-4.4/: https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest-4.4/

[3]

Pull Secret 页面: https://cloud.redhat.com/openshift/install/pull-secret

[4]

这个页面: https://quay.io/repository/openshift-release-dev/ocp-release?tab=tags

[5]

这里: https://gist.github.com/yuanlinios/7eea8207083e649cbe07e108a22df00b

[6]

1800674: https://bugzilla.redhat.com/show_bug.cgi?id=1800674

[7]

离线部署 Openshift Container Platform 4.3 - 1: 准备离线资源: https://notes.yuanlinios.me/2020-03-15/%E7%A6%BB%E7%BA%BF%E9%83%A8%E7%BD%B2-Openshift-Container-Platform-4-3-1-%E5%87%86%E5%A4%87%E7%A6%BB%E7%BA%BF%E8%B5%84%E6%BA%90/

[8]

Chapter 9. Using Operator Lifecycle Manager on restricted networks: https://access.redhat.com/documentation/en-us/openshift_container_platform/4.4/html/operators/olm-restricted-networks


你可能还喜欢

点击下方图片即可阅读

什么?终止一个容器竟然用了 10 秒钟,这不能忍!

云原生是一种信仰 ????

码关注公众号

后台回复◉k8s◉获取史上最方便快捷的 Kubernetes 高可用部署工具,只需一条命令,连 ssh 都不需要!

点击 "阅读原文" 获取更好的阅读体验!

❤️给个「在看」,是对我最大的支持❤️
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值