OpenShift4.5.x离线环境OperatorHub和ImageStream配置实战技巧
1 . 前言
在离线环境使用UPI(UserProvisioned Infrastructure)方式安装OpenShift,相对于在联网环境采用IPI(Installer Provisioned Infrastructure)完全自动安装方式OpenShift,的确要相对复杂的多,比如要设置离线镜像仓库、将需要的镜像上传到离线镜像仓库、定制CoreOS的点火文件等。
本文的目的不是描述OpenShift 4.5.x的完整离线安装过程,如果要了解OpenShift 4.5.x的完整离线安装过程,可以参考OpenShift的官方安装手册,或者本文附录中的参考文档。
在标准离线环境的OpenShift安装完成后,系统是没有OperatorHub的,同时,系统自带的ImageStream也下载不了公网环境的镜像。这个时候,你既不能创建Operator,也不能采用服务模板(Catalog)方式部署应用。因此,希望能够通过本文对离线Operator安装配置和ImageSteam的配置工作的描述,能够帮助我们解决上面提到的两个问题。
2 我们从哪儿开始
我们的后安装配置工作起始于一个安装已经成功的OpenShift的集群。如果你在运行命令openshift-install wait-for install-complete 看到如下输出,恭喜你!您的OpenShift集群已经安装完毕,我们可以开始我们下一步的工作了。
[root@helper install]# openshift-install wait-forinstall-complete
INFO Waiting up to 30m0s for the cluster athttps://api.ocp4.example.com:6443 to initialize...
INFO Waiting up to 10m0s for the openshift-consoleroute to be created...
INFO Install complete!
INFO To access the cluster as the system:admin userwhen using 'oc', run 'export KUBECONFIG=/root/ocp4/install/auth/kubeconfig'
INFO Access the OpenShift web-console here:https://console-openshift-console.apps.ocp4.example.com
INFO Login to the console with user:"kubeadmin", and password: "xMS9Y-KLmda-nxa6i-IniEB"
当然,为了确保一切正常,你可以使用oc命令或者web控制台查看该集群是否一切正常。下面是用oc 命令查询集群的一个操作:
在正式配置OperatorHub和服务模板需要的ImageStream之前,我们首先做一些基本的设置。
2.1 创建用户
安装程序默认创建了一个kubeadmin的用户,这个用户的密码是超长。一般情况下,从安全考虑出发,我们建议创建新的管理员用户,并且在新的管理员用户创建后,将kubeadmin删除。
除了支持本地认证,OpenShift也可以支持跟企业的LDAP服务器对接,具体用户相关的认证操作过程请参见产品文档了解OpenShift认证配置。
下面的脚本我们使用HTPasswd方式创建了2个用户,其中用户admin是系统管理用户,可以管理整个集群;而用户user1只是一个普通用户。
## 使用命令行工具htpasswd在本地文件users.htpasswd创建两个用户
htpasswd -c -B -b users.htpasswd admin passw0rd
htpasswd -b users.htpasswd user1 passw0rd
## 将users.htpasswd的内容导入一个secrt
oc create secret generic htpass-secret--from-file=htpasswd=./users.htpasswd -n openshift-config
## 创建一个认证提供器,其认证内容指向刚刚创建的secret
cat << EOF > htpass.yaml
apiVersion: config.openshift.io/v1
kind: OAuth
metadata:
name:cluster
spec:
identityProviders:
- name: my_htpasswd_provider
mappingMethod: claim
type:HTPasswd
htpasswd:
fileData:
name:htpass-secret
EOF
oc apply -f htpass.yaml
## 给用户admin赋予集群管理员权限
oc adm policy add-cluster-role-to-usercluster-admin admin
现在你可以用创建的用户登录Web控制台或者oc命令行工具了。
2.2 加入离线镜像仓库的CA证书
我们在安装离线OpenShift的时候已经设置了一个离线的镜像仓库,因此,在安装OperatorHub和服务模板的时候,我们也希望把下载的镜像上传到该离线仓库。如果该离线镜像仓库的证书是采用自签名的证书,我们需要让OpenShift信任该证书。因此,我们需要将该离线仓库的CA证书加入OpenShift的信任证书列表里面去。
OpenShift里面存储镜像仓库相关配置信息的是在一个叫做image.config.openshift.io/cluster的客户定义资源(CustomerResource)里面,我们需要在这个CR里面加载相关证书,具体的操作如下:
## 创建一个configmap以存放证书
## 下面的registry.ocp4.example.com是内部离线仓库的域名,5443是端口后,需要根据情况替换
## /etc/crts/ocp4.example.com.crt是证书文件名,需要根据实际情况替换
oc create configmap registry-cas -nopenshift-config \
--from-file=registry.ocp4.example.com..5443=/etc/crts/ocp4.example.com.crt
## 修改image.config.openshift.io/cluster以引用证书
oc patch image.config.openshift.io/cluster--patch'{"spec":{"additionalTrustedCA":{"name":"registry-cas"}}}'--type=merge
到现在为止,你已经可以在OpenShift上用内部的镜像仓库里面的镜像来部署应用了。
注意:我在某一个4.5.x小版本中发现,尽快经过上述配置,但镜像仓库的证书还是不能被OpenShift信任。如果你在配置过程中发现上述问题,可以简单通过增加一个非安全镜像仓库方式绕过该问题,具体操作如下:
## 创建一个非安全镜像仓库
oc patch image.config.openshift.io/cluster -p'{"spec":{"registrySources":{"insecureRegistries":["registry.ocp4.example.com:5443"]}}}' --type=merge
3. OperatorHub的安装
我们知道,OpenShift 4.5.x默认有4类的Operator:分别是:
类 别 |
描 述 |
Red Hat Operators |
由红帽公司分发并提供技术支持的Operator。 |
Certified Operators |
由领先的独立软件开发商开发的并经过红帽认证的Operator,技术支持由独立开发商提供。 |
Community Operators |
开源社区提供的Operator,没有技术支持。 |
Marketplace Operators |
可以在红帽软件商店网站(Red Hat Marketplace)购买的Operator。 |
当然,如果客户需要加入自己的Operator,那么就会有第5个种类:客户自己定制类。
为了安装OperatorHub,首先要把上面4类的目录镜像安装上,然后再将每一类目录镜像中引用到的Operator中的镜像同步进离线仓库。
在刚安装好的OpenShift集群中,OpenShift默认是向一个公网的URL获取OperatorHub信息,由于我们的集群是在离线环境中,这个操作当然不能成功。我们需要执行下面的命令来禁止这个默认行为。
## Disable the default OperatorSources
oc patch OperatorHub cluster --type json \
-p '[{"op":"add", "path": "/spec/disableAllDefaultSources","value": true}]'
## Review OperatorHub configuration
oc get OperatorHub cluster -o yaml
为了同步Operators的镜像,我们需要有一台RHEL服务器能够连接到Internet,我们将会在该服务器下载镜像。
podman login registry.redhat.io
## <registry_host_name>is your hostname
podman login <registry_host_name>:<port>
3.1 红帽提供Operator的安装
3.1.1安装Red Hat Operators目录镜像
为了安装Red Hat Operators目录镜像,我们需要将该镜像下载到本地的一个目录并打包成一个tar文件。在外网服务器执行以下命令:
## create a catalog image for redhat operators
## To a local folder
oc adm catalog build \
--appregistry-org redhat-operators \
--from=registry.redhat.io/openshift4/ose-operator-registry:v4.5 \
--filter-by-os="linux/amd64" \
--to=file://offline/redhat-operators:4.5 \
--insecure
## Save the operator image
tar cvf rh-operator.tar v2
将该tar文件复制到可以访问内部离线镜像仓库的服务器上,解压文件,采用下列命令同步进离线镜像仓库。其中,registry.ocp4.example.com:5443是内部离线镜像仓库的URL(下同,不再重复说明)。
## 复制文件到内网
## Load the catalog image
##
oc image mirrorfile://offline/redhat-operators:4.5registry.ocp4.example.com:5443/offline/redhat-operators:4.5
## Verify whether theoperator catalog image is uploaded
curl -u dummy:dummy https://registry.ocp4.example.com:5443/v2/catalog/redhat-operators/tags/list
## sample successful result: {"name":"catalog/redhat-operators","tags":["4.5.2-20200726"]}
然后我们创建一个CatalogSource:
cat <<EOF > redhat-operator-catalog.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name:redhat-operator-catalog
namespace:openshift-marketplace
spec:
displayName: Red Hat Operators
sourceType:grpc
image:registry.ocp4.example.com:5443/offline/redhat-operators:4.5
publisher:Red Hat
EOF
oc create -f redhat-operator-catalog.yaml
## check the result
oc get pods -n openshift-marketplace
oc get catalogsource -n openshift-marketplace
oc get packagemanifest -n openshift-marketplace
如果现在你登录OperatorHub, 你应该能过看到Red Hat Operators已经成功显示出来了,但是,到现在为止,如果你尝试安装一个Operator, 安装会失败。那是因为我们只安装了一个Operator目录镜像,而这个目录中引用的真正Operator进行还没有被导入,接下来我们来做这一部分工作。
3.1.2 同步Red Hat 提供Operators中引用到的镜像
在能够访问内部离线仓库的服务器上面,我们通过执行下面的这个命令,来获取需要同步的镜像列表:
oc adm catalog mirror \
registry.ocp4.example.com:5443/offline/redhat-operators:4.5 \
registry.ocp4.example.com:5443 \
--insecure \
--filter-by-os="linux/amd64" \
--manifests-only
执行完该命令后,当前目录下会创建一个redhat-operators-manifests的子目录,子目录下面有2个文件:
mapping.txt – 用来同步镜像的文件
imageContentSourcePolicy.yaml –用来进行镜像重定向的文件
首先,我们来看一下mapping.txt的文件内容(以下为文件片段):
registry.redhat.io/openshift-service-mesh/prometheus-rhel8@sha256:68d47c477bb9b1a4cae6432361326efd0f75146ecf104c84b9c23afb09e77f09
=registry.ocp4.example.com:5443/openshift-service-mesh/prometheus-rhel8:27f4a38e
registry.redhat.io/container-native-virtualization/kubevirt-kvm-info-nfd-plugin:v2.2.0-3=registry.ocp4.example.com:5443/container-
native-virtualization/kubevirt-kvm-info-nfd-plugin:v2.2.0-3
文件内容是以“SoureImage=DestinationImage”,表示将镜像从前面的原地址同步到后面的目的地址。因此,我们注意到,文件中的每一行内容都是可以作为参数直接传递给oc image mirror进行同步的。但是,在当前的网络配置下,由于Internet和内部的镜像仓库不联通,我们不能直接用oc image mirror进行同步,因此,需要引入一个中转站。鉴于现在已经有了一个公网的服务器,因此,我们可以考虑将该服务器的本地目录作为一个中转站。其思路是:我们首先将镜像下载到公网服务器的本地目录;然后本地目录打包通过U盘或移动硬盘复制到内部服务器,从内部服务器在同步到内部离线仓库。
第一步:同步镜像到公网服务器的本地目录。
观察mapping.txt,将目的地址改为本地目录:
registry.redhat.io/openshift-service-mesh/prometheus-rhel8@sha256:68d47c477bb9b1a4cae6432361326efd0f75146ecf104c84b9c23afb09e77f09
=file://offline/openshift-service-mesh/prometheus-rhel8:27f4a38e
registry.redhat.io/container-native-virtualization/kubevirt-kvm-info-nfd-plugin:v2.2.0-3=file://offline/container-
native-virtualization/kubevirt-kvm-info-nfd-plugin:v2.2.0-3
我们可以通过执行以下命令进行同步:
## 创建downloading.txt
sed 's/registry.ocp4.example.com:5443/file:\/\/offline/g'mapping.txt > downloading.txt
## 创建下载的shell文件
cat << EOF >download-rh-op.sh
#!/usr/bin/env bash
STAGEING_FOLDER="localrep"
IMAGE_LIST="downloading.txt"
x=0
echo `date` "- Starting to download image tolocal directory : " $STAGEING_FOLDER
echo `date` "- The image list name is :" $IMAGE_LIST
cat $IMAGE_LIST | whileread line; do
x=$(( x+1 ))
echo"--------------------------------------------- No ${x} Started...---------------------------------------------"
echo `date` $TIMESTAMP "- The image to be loaded is :"
echo $line
oc image mirror $line --dir=$STAGEING_FOLDER --filter-by-os=.*
echo `date` $TIMESTAMP "- The imageloading is completed."
echo"--------------------------------------------- No ${x} Completed ---------------------------------------------"
echo
done
echo `date` "- All images are downloaded intothe local folder! Please check the local directory:" $STAGEING_FOLDER
EOF
chmod u+xdownload-rh-op.sh
nohup ./download-rh-op.sh >> download-rh-operators.out2>&1 &
第二步:将目录localrep打包压缩复制到内网服务器
第三步:从本地目录同步镜像到内部离线镜像仓库。
再次观察mapping.txt,将原地址改为本地目录:
file://offline/openshift-service-mesh/prometheus-rhel8@sha256:68d47c477bb9b1a4cae6432361326efd0f75146ecf104c84b9c23afb09e77f09
=registry.ocp4.example.com:5443/openshift-service-mesh/prometheus-rhel8:27f4a38e
file://offline/container-native-virtualization/kubevirt-kvm-info-nfd-plugin:v2.2.0-3=registry.ocp4.example.com:5443/container-
native-virtualization/kubevirt-kvm-info-nfd-plugin:v2.2.0-3
我们可以通过执行以下命令进行同步:
## 创建uploading.txt
sed's/registry.redhat.io/file:\/\/offline/g' mapping.txt > uploading-all.txt
## 创建上传的shell文件
cat << EOF >upload-rh-op.sh
#!/usr/bin/env bash
STAGEING_FOLDER="localrep"
IMAGE_LIST="uploading.txt"
x=0
echo `date` "- Starting to mirror image tolocal image repository from local directory: " $STAGEING_FOLDER
echo `date` "- The image list name is :" $IMAGE_LIST
cat $IMAGE_LIST | whileread line; do
x=$(( x+1 ))
echo"--------------------------------------------- No ${x} Started...---------------------------------------------"
echo `date` $TIMESTAMP "- The image to be loaded is :"
echo $line
echo "oc image mirror" $line"--dir="$STAGEING_FOLDER "--filter-by-os=.*"
oc image mirror $line --dir=$STAGEING_FOLDER --filter-by-os=.*
# sleep 1
echo `date` $TIMESTAMP "- The imageloading is completed."
echo "---------------------------------------------No ${x} Completed ---------------------------------------------"
echo
done
echo `date` "- All images are pushed to thelocal image repository! "
EOF
chmod u+xupload-rh-op.sh
nohup ./upload-rh-op.sh >> upload-rh-operators.out 2>&1&
到这一步为止,Red Hat Operators目录镜像引用到的镜像都已经成功同步进本地镜像仓库了,你可以创建需要的operator了。比如,现在你就可以利用Operator创建OpenShift的日志组件了。
3.2 其他类Operators的安装
3.2.1安装其他类Operators目录镜像
安装其他Operators的目录镜像与3.1.1节非常类似,唯一的区别是Operator目录镜像名称不一致。
以下是创建红帽认证Operators的步骤:
## create a catalogimage for certificated operators
## To a local folder
oc adm catalog build \
--appregistry-org certified-operators \
--from=registry.redhat.io/openshift4/ose-operator-registry:v4.5 \
--filter-by-os="linux/amd64" \
--to=file://offline/certified-operators:4.5\
--insecure
# Save the operatorimage
tar cvf rh-operator.tarv2
# 复制文件到内网
# Load the catalog image
oc image mirrorfile://offline/certified-operators:4.5registry.ocp4.example.com:5443/offline/certified-operators:4.5
## create aCatalogSource
cat <<EOF >certified-operator-catalog.yaml
apiVersion:operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: certified-operator-catalog
namespace: openshift-marketplace
spec:
displayName: Certified Operators
sourceType: grpc
image:registry.ocp4.example.com:5443/offline/certified-operators:4.5
publisher: Red Hat
EOF
oc create -f certified-operator-catalog.yaml
以下是创建红帽认证Operators的步骤:
## create a catalogimage for certificated operators
## To a local folder
oc adm catalog build \
--appregistry-org certified-operators \
--from=registry.redhat.io/openshift4/ose-operator-registry:v4.5 \
--filter-by-os="linux/amd64" \
--to=file://offline/certified-operators:4.5\
--insecure
# Save the operatorimage
tar cvfcertified-operator.tar v2
## 复制文件到内网
# Load the catalog image
oc image mirrorfile://offline/certified-operators:4.5registry.ocp4.example.com:5443/offline/certified-operators:4.5
## create aCatalogSource
cat <<EOF >certified-operator-catalog.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: certified-operator-catalog
namespace: openshift-marketplace
spec:
displayName: Certified Operators
sourceType: grpc
image:registry.ocp4.example.com:5443/offline/certified-operators:4.5
publisher: Red Hat
EOF
oc create -f certified-operator-catalog.yaml
以下是创建社区Operators的步骤:
## create a catalogimage for community operators
## To a local folder
oc adm catalog build \
--appregistry-org community-operators \
--from=registry.redhat.io/openshift4/ose-operator-registry:v4.5\
--filter-by-os="linux/amd64" \
--to=file://offline/community-operators:4.5\
--insecure
# Save the operatorimage
tar cvfcommunity-operator.tar v2
## 复制文件到内网
# Load the catalog image
oc image mirrorfile://offline/community-operators:4.5registry.ocp4.example.com:5443/offline/community-operators:4.5
## create aCatalogSource
cat <<EOF >community-operator-catalog.yaml
apiVersion:operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: community-operator-catalog
namespace: openshift-marketplace
spec:
displayName: Community Operators
sourceType: grpc
image:registry.ocp4.example.com:5443/offline/community-operators:4.5
publisher: Red Hat
EOF
oc create -f community-operator-catalog.yaml
以下是创建红帽Market Place Operators的步骤:
## create a catalogimage for redhat-marketplace operators
## To a local folder
oc adm catalog build \
--appregistry-org redhat-marketplace \
--from=registry.redhat.io/openshift4/ose-operator-registry:v4.5 \
--filter-by-os="linux/amd64" \
--to=file://offline/redhat-marketplace:4.5\
--insecure
#
# Save the operatorimage
tar cvfredhat-marketplace.tar v2
## 复制文件到内网
# Load the catalog image
oc image mirrorfile://offline/redhat-marketplace:4.5registry.ocp4.example.com:5443/offline/redhat-marketplace:4.5
## create aCatalogSource
cat <<EOF >redhat-marketplace-catalog.yaml
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: redhat-marketplace-catalog
namespace: openshift-marketplace
spec:
displayName: Marketplace
sourceType: grpc
image:registry.ocp4.example.com:5443/offline/community-operators:4.5
publisher: Red Hat
EOF
oc create -f redhat-marketplace-catalog.yaml
4.导入ImageStram
OpenShift 4.5.x中的绝大多数ImageSteam都是通过Sample Operator管理的,因此,我们需要通过管理SampleOperator来导入ImageStream
4.1 同步镜像
首先,我们需要知道ImageStream到底使用了哪些镜像。我们可以通过执行下列脚本获取:
oc get is -o json -nopenshift | jq '.items[].spec.tags[] |select(.from.kind=="DockerImage").from.name' | sed 's/\"//g' | grepregistry.redhat.io > is-images.list
## 如果镜像不包含tag,加上一个默认的latest tag
sed '/:/! s/$/:latest/g' is-images.list >my-is-images.list
## 构建SourceImage=DestinationImage格式的文件
cat my-is-images.list | awk -F '=' '{print$0"=file://offline/TAG"$1}' | sed 's/TAGregistry.redhat.io\///g' >download-sample-images.list
到这一步,你如果看文件download-sample-images.list,格式如下:
$ catdownload-sample-images.list
registry.redhat.io/3scale-amp21/apicast-gateway:1.4-2=file://offline/3scale-amp21/apicast-gateway:1.4-2
registry.redhat.io/3scale-amp22/apicast-gateway:1.8=file://offline/3scale-amp22/apicast-gateway:1.8
registry.redhat.io/3scale-amp23/apicast-gateway:latest=file://offline/3scale-amp23/apicast-gateway:latest
registry.redhat.io/3scale-amp24/apicast-gateway:latest=file://offline/3scale-amp24/apicast-gateway:latest
registry.redhat.io/3scale-amp25/apicast-gateway:latest=file://offline/3scale-amp25/apicast-gateway:latest
registry.redhat.io/3scale-amp26/apicast-gateway:latest=file://offline/3scale-amp26/apicast-gateway:latest
registry.redhat.io/3scale-amp2/apicast-gateway-rhel7:3scale2.7=file://offline/3scale-amp2/apicast-gateway-rhel7:3scale2.7
registry.redhat.io/fuse7/fuse-apicurito:1.2=file://offline/fuse7/fuse-apicurito:1.2
看起来是不是很熟悉?的确,这个文件格式就是刚才我们导入离线Operator镜像的格式,采用类似的方法,我们可以把这些镜像下载到公网服务器的本地目录;然后打包复制到内网服务器的本地目录,最后再用类似的方法上传到内部的离线仓库,这里面就不重复描述
4.2修改Sample Operator指向内部仓库
修改Sample Operator的配置资源,将镜像仓库指向内部的离线镜像仓库
ocpatch configs.samples.operator.openshift.io/cluster -p'{"spec":{"samplesRegistry":"registry.ocp4.example.com:5443"}}'--type=merge
在修改之后,Sample Operator会修改ImageStream的定义,ImageStream将会自动从内部离线仓库下载镜像。如果此时再管理界面切换成开发人员视图,就可以发现Catalog服务目录现在已经可以显示了,我们现在可以利用服务模板创建应用。