
3.2.4 OpenShift部署后的配置
本小节将介绍OCP4安装后的配置步骤。需要注意几点:
1.OCP4的监控组件是自动安装的,但需要为ES配置一个PV(PVC自动创建、手工创建对应的PV后,PVC和PV会自动绑定),以便时间监控数据的持久化。
2.OCP4.6开始支持AlertManager规则的自定义和告警日志的邮件转发。这部分内容请参考Repo中的“自定义Prometheus规则并触发邮件告警”。
3.为了实现S2I构建镜像的持久化,需要为Image Registry增加持久化存储,这部分内容请参考Repo中的“Image Registry增加持久化存储”。
1.OpenShift配置登录认证
在OpenShift集群部署完毕后,默认提供两种集群管理员权限身份验证的方法:
·使用kubeconfig文件登录,这个文件中包含一个永不过期的X.509 client certificate。
·使用被赋予了OAuth access token的kubeadmin虚拟用户和密码登录。
kubeconfig文件是在安装过程中创建的,它存储在OpenShift安装程序在安装过程中创建的auth目录中。该文件包含X.509证书。
我们需要设定kubeconfig文件的环境变量,然后就可以访问集群,如图3-24所示。
如果其他终端要通过kubeconfig文件访问OpenShift集群,必须将kubeconfig文件复制到这个终端,并且这个终端需要有OC客户端。通过kubeconfig文件只能执行命令行终端,无法登录WebConsole界面。

图3-24 设定kubeconfig文件的环境变量
OpenShift安装完成后会自动创建kubeadmin用户。kubeadmin被硬编码为集群管理员(权限不能被修改)。kubeadmin password是由安装程序动态生成的唯一的密码,这个密码会显示在安装日志中,通过这个用户名和密码可以登录命令行终端(oc login)和OpenShift WebConsole界面,如图3-25所示。

图3-25 使用kubeadmin登录OpenShift WebConsole界面
接下来,我们介绍如何配置Identity Provider。
(1)配置HTPasswd认证方式
在开发测试环境,我们可以配置HTPasswd认证方式。
创建一个admin用户,密码也指定为admin。
# htpasswd -cBb /root/users.htpasswd admin admin Adding password for user admin
接下来创建OpenShift的secret,htpasswd_provider。
# oc create secret generic htpass-secret --from-file=htpasswd=/root/users. htpasswd -n openshift-config secret/htpass-secret created
创建OAuth资源对象文件。
# 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 oauth.config.openshift.io/cluster configured
接下来,为admin用户授权,例如赋予cluster-admin role。
# oc adm policy add-cluster-role-to-user cluster-admin admin clusterrole.rbac.authorization.k8s.io/cluster-admin added: "admin"
然后,再度访问OpenShift WebConsole,现在就可以选择htpasswd provider的认证方式登录了,如图3-26所示。

图3-26 查看OpenShift WebConsole增加的认证方式
OpenShift安装后默认的kubeadmin用户,生产环境建议将其删除,但一定要在创建了有cluster-admin角色的用户以后再删除。
# oc delete secret kubeadmin -n kube-system
如果在使用集群管理员特权配置另一个用户(如admin用户)之前删除kubeadmin,则管理集群的唯一方法是使用kubeconfig文件。如果没有安装过程生成的kubeconfig文件的副本,则无法恢复对集群的管理访问,唯一的选择是销毁并重新安装集群。
(2)增加和删除HTPasswd认证用户
如果我们想添加一个user1用户,该怎么操作?
首先在HTPasswd用户名密码文件中增加新条目。
# htpasswd -b /root/users.htpasswd user1 passwd Adding password for user user1
然后更新OpenShift中的secret。
# oc set data secret/htpass-secret --from-file htpasswd=/root/users.htpasswd -n openshift-config secret/htpass-secret data updated
观察authentication Pod,会自动重新部署,如图3-27所示。
# watch oc get pods -n openshift-authentication

图3-27 authentication Pod重新部署
authentication Pod重新部署成功后,使用如下命令确认user1用户可以成功登录OpenShift集群。
# oc login https://api.weixinyucluster.bluecat.ltd:6443 -u user1 -p passwd
接下来,我们展示如何删除HTPasswd认证的用户,以user1为例。
首先将user1从认证文件中删除。
# htpasswd -D /root/users.htpasswd user1 Deleting password for user user1
更新OpenShift中的secret。
# oc set data secret/htpass-secret --from-file htpasswd=/root/users.htpasswd -n openshift-config secret/htpass-secret data updated
使用以下命令删除用户相关资源。
# oc delete user user1 user.user.openshift.io "user1" deleted # oc delete identity my_htpasswd_provider:user1 identity.user.openshift.io "my_htpasswd_provider:user1" deleted
(3)获取当前集群中的HTPasswd文件
如果我们原始创建的HTpasswd认证文件丢失了,该怎么处理呢?
我们可以通过OpenShift中的secret获取该文件。首先确认secret的名称,如图3-28所示。
# oc get secret -n openshift-config
然后将secret的内容提取到本地文件。
# oc extract secret/htpass-secret -n openshift-config --to /root/users.htpasswd –confirm
至此,我们获取到了HTpasswd的密钥文件。
2.配置持久化存储StorageClass
OpenShift中有很多组件需要使用持久化存储,这里我们使用NFS后端存储。NFS Server的配置不再赘述。

图3-28 获取secret名称
为了兼容集群中的其他StorageClass,尤其是集群中设置了默认的StorageClass,我们选择配置静态StorageClass来消费NFS类型的PV。如果集群中没有设置默认StorageClass,也可以直接使用静态PV。
通过下面的文件创建一个静态的StorageClass。
# cat sc.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: standard provisioner: kubernetes.io/no-provisioner volumeBindingMode: WaitForFirstConsumer
应用上述配置。
# oc apply -f sc.yaml
确认StorageClass创建成功,如图3-29所示。

图3-29 创建的静态StorageClass
接下来,我们为静态StorageClass创建PV,文件内容如下。
# cat static-storageclass-pv00001.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv00001 spec: storageClassName: standard capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle nfs: server: <nfs_server> path: /exports/pv00001
我们可以通过脚本批量创建PV,示例脚本请参考Repo中“create_pv.sh”。
创建指定了storageClassName的PVC,文件内容如下。
# cat static-storageclass-pvc00001.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: task-pv-claim spec: storageClassName: standard accessModes: - ReadWriteOnce resources: requests: storage: 3Gi
应用上述PV和PVC文件,等待绑定后,Pod就可以消费了。请读者根据上述示例创建集群中需要的PV和PVC,在此我们不再一一列出。
3.关闭CoreOS配置更新后自动重启
OpenShift对CoreOS操作系统节点的配置是通过Machine Config Operator(简称MCO)实现的。很多通过MCO对CoreOS操作系统进行修改的配置都需要CoreOS操作系统重启后生效。OpenShift安装完毕后,CoreOS配置变更后自动重启功能默认是开启的。
使用以下命令查看Master和Worker类型节点的自动重启功能设置。
# oc get mcp master -o yaml |grep -i pause paused: false # oc get mcp worker -o yaml |grep -i pause paused: false
可以通过以下命令,根据节点类型(master、worker或infra)将自动重启功能关闭。
# oc patch --type=merge --patch='{"spec":{"paused":true}}' machineconfigpool/master # oc patch --type=merge --patch='{"spec":{"paused":true}}' machineconfigpool/worker # oc patch --type=merge --patch='{"spec":{"paused":true}}' machineconfigpool/infra
在关闭CoreOS配置更新后自动重启后,需要关注OCP证书的轮换问题,详见5.5节的内容。
4.在OpenShift中启动Image Registry
OpenShift安装时的平台如果不提供共享的对象存储,OpenShift Image Registry Operator将会被标识成Removed状态。也就是说,默认安装完OpenShift后,Image Registry容器没有启动。
安装后,我们需要修改Image Registry Operator的配置,将ManagementState从Removed修改为Managed。
# oc edit configs.imageregistry.operator.openshift.io cluster
将managementState:Removed修改为managementState:Managed,然后保存退出。
如果此时在OpenShift中有可用的PV,Registry Pod将被自动创建。
等Pod正常运行后,我们为Registry创建路由,以便外部可以访问。
# oc patch configs.imageregistry.operator.openshift.io/cluster --type merge -p '{"spec":{"defaultRoute":true}}' config.imageregistry.operator.openshift.io/cluster patched
获取Registry访问地址。
# oc get route NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD default-route default-route-openshift-image-registry.apps.weixinyucluster. bluecat.ltd image-registry <all> reencrypt None
验证仓库登录。
# podman login -u admin -p $(oc whoami -t) --tls-verify=false default-route- openshift-image-registry.apps.weixinyucluster.bluecat.ltd Login Succeeded!
接下来我们将一个本地的镜像推入内部Registry中。
# podman images | grep -i tomcat docker.io/library/tomcat # oc new-project image-push # podman tag docker.io/library/tomcat:latest default-route-openshift-image- registry.apps.weixinyucluster.bluecat.ltd/image-push/tomcat:latest # podman push default-route-openshift-image-registry.apps.weixinyucluster. bluecat.ltd/image-push/tomcat --tls-verify=false
5.离线环境修复openshift-samples Operator
在前文我们提到,openshift-samples Operator的主要作用是提供安装和更新Image Streams与Template功能。虽然在OpenShift中我们可以通过OperatorHub对大量的有状态应用进行全生命周期管理,但Image Streams和Template依然会被大量使用。在本小节中,我们介绍离线安装OpenShift后修复openshift-samples Operator的方法。
使用离线方式安装OpenShift后,如果Image Streams没有正确导入,openshift-samples Operator会处于Degraded状态。
首先查看离线安装OpenShift后openshift-samples Operator的状态,发现显示为Degraded,Image Streams未成功导入(FailedImageImports)。
# oc get co openshift-samples -o yaml apiVersion: config.openshift.io/v1 kind: ClusterOperator [...] - lastTransitionTime: "2020-04-27T13:05:07Z" message: 'Samples installation in error at 4.3.0: FailedImageImports' status: "True" type: Progressing - lastTransitionTime: "2020-04-30T08:29:34Z" message: 'Samples installed at 4.3.0, with image import failures for these imagestreams: postgresql mysql rhdm74-decisioncentral-openshift jboss-processserver64- openshift jboss-webserver30-tomcat7-openshift dotnet-runtime java jboss-eap64-openshift [...] reason: FailedImageImports status: "True" type: Degraded
使用如下命令获取需要手动处理的整个Image Streams列表,如图3-30所示(只列出部分内容)。
# for i in `oc get is -n openshift --no-headers | awk '{print $1}'`; do oc get is $i -n openshift -o json | jq .spec.tags[].from.name | grep registry. redhat.io | sed -e 's/"//g' | cut -d"/" -f2-; done | tee imagelist.txt

图3-30 获取的Image Streams列表
我们可以对上面生成的imagelist.txt文件进行裁剪,删除我们用不到的Image Stream。如果无特殊情况,不建议删减。接下来,将imagelist.txt文件中列出的镜像缓存到Mirror Registry(离线安装OpenShift使用的Mirror Registry)中。执行命令时必须要指定pull secret(含有登录Mirror Registry和registry.redhat.io的Secret)。
# for i in `cat imagelist.txt`; do oc image mirror -a ~/pullsecret_config.json registry.redhat.io/$i repo.apps.weixinyucluster.bluecat.ltd:5000/$i; done
命令执行过程如图3-31所示(部分内容)。

图3-31 查看命令执行过程
导入成功后,在Operator中修改samplesRegistry的spec,以指向Mirror Registry并触发镜像重新导入过程。
# oc patch configs.samples.operator.openshift.io/cluster --patch '{"spec": {"samplesRegistry": "repo.apps.weixinyucluster.bluecat.ltd:5000" }}' --type=merge
执行上面的命令后,正常会触发imagestream的重新导入,如果没有触发,使用如下命令手动触发。
# oc patch configs.samples.operator.openshift.io/cluster --patch '{"spec": {"managementState": "Removed" }}' --type merge
等待10秒后(让状态变化被OpenShift集群探测到)。
# oc patch configs.samples.operator.openshift.io/cluster --patch '{"spec": {"managementState": "Managed" }}' --type merge
再用命令行查看,samples operator的状态已经正常。
# oc describe co openshift-samples
实际上,上述操作不仅导入了Images Streams,也将Images Stream对应的镜像同步到了离线镜像仓库中。通过命令行查看Mirror Registry中包含的应用基础镜像(部分内容),执行结果如图3-32所示。
# curl -u davidwei:davidwei -k https://repo.apps.weixinyucluster.bluecat.ltd: 5000/v2/_catalog

图3-32 查看Mirror Registry中包含的应用基础镜像
然后查看导入成功的Image Stream,镜像指向到Mirror Registry的地址,如图3-33所示。

图3-33 查看导入成功的Image Stream
6.日志系统的介绍与安装
OpenShift日志系统由以下五个组件组成,其完整的组件如图3-34所示。

图3-34 OpenShift日志系统组件
·LogStore:这是将存储日志的组件。当前的实现是Elasticsearch。
·Collection:这是从节点收集日志,对其进行格式化并将其存储在LogStore中的组件。当前的实现是Fluentd。
·Visualization:这是用于查看日志、图形、图表等的可视化组件。当前的实现是Kibana。
·Curation:这是按日期清理日志的组件。当前的实现是Curator。
·Event Routing:这是将事件转发到集群日志记录的组件。当前的实现是Event Router。
OpenShift使用Fluentd收集有关集群的数据。日志收集器在OpenShift容器平台中作为DaemonSet部署。日志记录是系统日志源,提供来自操作系统/容器运行时和OpenShift容器平台的日志消息。OpenShift使用Elasticsearch(ES)将Fluentd的日志数据组织到数据存储或索引中。Elasticsearch将每个索引细分为多个碎片,并将它们分散在Elasticsearch集群中的一组节点上。高度可用的Elasticsearch环境需要至少三个Elasticsearch节点,每个节点都在不同的主机上,如图3-35所示。

图3-35 OpenShift日志系统工作模式
OpenShift容器平台使用Kibana显示由Fluentd收集并由Elasticsearch索引的日志数据。Kibana是基于浏览器的控制台界面,可通过直方图、折线图、饼图、热图、内置地理空间支持和其他可视化查询,发现和可视化Elasticsearch数据。
为了防止日志大量增长把磁盘撑满,每个Elasticsearch集群部署一个Curator Pod即可,如图3-36所示。

图3-36 Curator Pod的作用
Curator基于配置,每天对日志系统进行检查。我们可以通过编辑openshift-logging项目中的Curator Configmap对其进行配置更改。在Configmap中编辑文件config.yaml,然后为Curator创建cronjob作业以强制清理。
在介绍了OpenShift日志系统的架构后,接下来介绍安装日志系统的步骤,需要指出的是,不同版本的日志系统的安装步骤可能略有差别,本步骤以OpenShift 4.4为例说明。其他版本可以参考红帽官网https://access.redhat.com/products/red-hat-openshift-container-platform。
OpenShift的日志系统安装可以采用半图形化和纯命令行两种安装方式,为了方便读者深入理解步骤和书写部署日志系统的脚本,我们介绍纯命令行的安装方式。
需要安装Elasticsearch Operator和Cluster Logging两个Operator。我们首先创建安装Operator的两个Namespace。编写创建openshift-operators-redhat namespace的yaml文件(启用cluster-monitoring),并应用配置。
# cat eo-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: openshift-operators-redhat annotations: openshift.io/node-selector: "" labels: openshift.io/cluster-monitoring: "true" # oc apply -f eo-namespace.yaml
编写创建openshift-logging namespace的yaml文件(启用cluster-monitoring),并应用配置。
# cat clo-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: openshift-logging annotations: openshift.io/node-selector: "" labels: openshift.io/cluster-monitoring: "true" # oc apply -f clo-namespace.yaml
安装Elasticsearch Operator。
# cat operator_group.yaml apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: openshift-operators-redhat namespace: openshift-operators-redhat spec: {} # oc apply -f operator_group.yaml
创建Elasticsearch Operator订阅文件。
# cat eo-sub.yaml apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: "elasticsearch-operator" namespace: "openshift-operators-redhat" spec: channel: "4.4" installPlanApproval: "Automatic" source: "redhat-operators" sourceNamespace: "openshift-marketplace" name: "elasticsearch-operator" # oc apply -f eo-sub.yaml
安装Cluster Logging Operator。
# cat clo-og.yaml apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: cluster-logging namespace: openshift-logging spec: targetNamespaces: - openshift-logging # oc create -f clo-og.yaml
创建Cluster Logging Operator订阅文件。
# cat clo-sub.yaml apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: cluster-logging namespace: openshift-logging spec: channel: "4.4" name: cluster-logging source: redhat-operators sourceNamespace: openshift-marketplace # oc create -f clo-sub.yaml
创建基于角色的访问控制(RBAC)对象文件(例如eo-rbac.yaml),以授予Prometheus访问openshift-operators-redhat命名空间的权限。
# cat rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: prometheus-k8s namespace: openshift-operators-redhat rules: - apiGroups: - "" resources: - services - endpoints - pods verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: prometheus-k8s namespace: openshift-operators-redhat roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: prometheus-k8s subjects: - kind: ServiceAccount name: prometheus-k8s namespace: openshift-operators-redhat # oc create -f rbac.yaml
创建Cluster Logging的CRD文件。创建CRD时需要指定StorageClass,然后点击Create,如下所示。我们需要关注CRD的下面几个配置:
·resources的limits和requests:需要让设置的数值匹配到OpenShift集群的节点(如果太大,可能选择不到节点;太小,则会影响运行性能)。
·nodeSelector:将EFK安装到哪个角色的节点,在下面的配置中,我们将其部署到worker节点。这个设置要与OpenShift的实际环境匹配,否则选择不上节点。
·storageClassName:OpenShift使用的持久化存储。如果没有设置默认的StorageClass,此处为空即可。但创建的PV需要一直匹配,也不指定StorageClass,否则PV和PVC会绑定不成功。
# cat clo-instance.yaml apiVersion: logging.openshift.io/v1 kind: ClusterLogging metadata: name: instance namespace: openshift-logging spec: managementState: Managed logStore: type: elasticsearch elasticsearch: resources: limits: memory: 2Gi requests: memory: 2Gi nodeCount: 1 nodeSelector: node-role.kubernetes.io/worker: "" redundancyPolicy: ZeroRedundancy storage: storageClassName: "" size: 50Gi visualization: type: kibana kibana: replicas: 1 nodeSelector: node-role.kubernetes.io/worker: "" curation: type: curator curator: schedule: 30 3 * * * nodeSelector: node-role.kubernetes.io/worker: "" collection: logs: type: fluentd fluentd: {} # oc create -f clo-instance.yaml
EFK的Pod开始创建,如图3-37所示。
# oc get pods -n openshift-logging

图3-37 查看Logging的pod
创建成功后,查看Kibana路由,通过浏览器可以登录访问,如图3-38所示。
# oc get route NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD kibana kibana-openshift-logging.apps.weixinyucluster.bluecat.ltd kibana <all> reencrypt/Redirect None
最后,我们配置Curator的Configmap实现如下需求:
·1周后清理所有项目日志。
·2周后清理所有以openshift开始的项目的日志。
·4周后清理所有操作日志。
# oc edit cm curator -n openshift-logging .defaults: delete: days: 7 # Keep OpenShift logs for 2 weeks .regex: - pattern: 'openshift-$' delete: weeks: 2 # to keep ops logs for a different duration: .operations: delete: weeks: 4
然后创建计划任务。
# oc create job --from=cronjob/curator cleanup -n openshift-logging

图3-38 Kibana界面显示
查看计划任务,创建成功,如图3-39所示。
关于Kibana索引的查看、创建等操作,请查看Repo中“Kibana安装后的配置”。

图3-39 查看计划任务
7.Infra节点的配置
OpenShift 3的安装是通过Ansible完成的,在Playbook的变量中可以指定某两三个节点是Infra角色,同时在Playbook中设置Router、EFK、监控相应的资源部署到Infra节点上。这样OpenShift部署完毕后Infra节点就自动配置好了。
而在OpenShift 4中无法在安装时指定Infra角色(只有Master和Woker两种节点角色)。那么在OpenShift 4中是否有必要配置Infra节点?
答案是肯定的。在开发测试环境,我们遇到过很多次由于没有配置Infra节点,当OpenShift升级后Router Pod很可能会漂移到其他节点上,造成解析报错,需要修改LB或HAproxy上的配置的情况。这种情况在开发测试或者POC环境中不会造成很大影响,但如果在生产环境,出现这种问题显然是不应该的。
另外,集群的基础组件最好与业务应用容器隔离,避免抢占资源导致基础组件不稳定或性能下降。因此在OpenShift 4中也需要配置Infra节点。下面我们就介绍具体的操作步骤。
(1)配置Node Label
以我们的环境为例,OpenShift集群包含3个Master、4个Worker节点。
# oc get nodes NAME STATUS ROLES AGE VERSION master-0 Ready master 26d v1.17.1 master-1 Ready master 26d v1.17.1 master-2 Ready master 26d v1.17.1 worker-0 Ready worker 26d v1.17.1 worker-1 Ready worker 26d v1.17.1 worker-2 Ready worker 26d v1.17.1 worker-3 Ready worker 26d v1.17.1
默认情况下,4个Worker的角色是一样的。为了说明过程,我们只将worker-3配置为Infra节点,在真实生产环境中,建议至少设置3个Infra节点。
首先将worker-3打标签为Infra节点。
# oc label node worker-3 node-role.kubernetes.io/infra="" node/worker-3 labeled
将其余三个节点配置为app节点。
# oc label node worker-0 node-role.kubernetes.io/app="" node/worker-0 labeled # oc label node worker-1 node-role.kubernetes.io/app="" node/worker-1 labeled # oc label node worker-2 node-role.kubernetes.io/app="" node/worker-2 labeled
确认Node Label如下。
# oc get nodes NAME STATUS ROLES AGE VERSION master-0 Ready master 26d v1.17.1 master-1 Ready master 26d v1.17.1 master-2 Ready master 26d v1.17.1 worker-0 Ready app,worker 26d v1.17.1 worker-1 Ready app,worker 26d v1.17.1 worker-2 Ready app,worker 26d v1.17.1 worker-3 Ready infra,worker 26d v1.17.1
(2)配置Default Selector
创建一个默认的Node Selector,也就是为没有设置nodeSelector的Pod分配部署的节点子集,例如,默认情况下部署在app标签的节点上。
编辑Scheduler Operator Custom Resource以添加defaultNodeSelector(下面内容中的加粗部分)。
# oc edit scheduler cluster spec: defaultNodeSelector: node-role.kubernetes.io/app= mastersSchedulable: false policy: name: "" status: {}
需要注意的是,配置保存退出后,API Server的Pod会重启,因此会有短暂的APIServer不可用(30s以内)。在Infra节点配置完成后,我们需要将已经运行的基础组件迁移到Infra节点上。
(3)迁移Router
迁移之前,两个Router分别运行在app标签的两个节点上,如图3-40所示。

图3-40 查看两个Router Pod所在的节点
修改openshift-ingress-operator的配置,如下所示。
# oc edit ingresscontroller default -n openshift-ingress-operator -o yaml spec: nodePlacement: nodeSelector: matchLabels: node-role.kubernetes.io/infra: "" replicas: 2
保存退出后,我们看到之前运行在worker-0和worker-1上的Pod会被终止,然后在Infra节点上重启,如图3-41所示。
# oc get pod -n openshift-ingress -o wide
过一会儿我们再次查看,有一个Router已经运行了,另外一个Router处于Pending状态。原因是一个Infra节点上只能运行一个Router,而我们现在只有一个Infra节点,如图3-42所示。

图3-41 Router在Infra节点启动

图3-42 一个Router处于Pending状态
在生产环境,我们建议设置三个节点为Infra节点。OpenShift默认安装后Router有两个副本,可以用如下命令查看。
# oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}' 2
通过如下方法可以将Router的副本数设置为3。
# oc patch -n openshift-ingress-operator ingresscontroller/default --patch '{"spec": {"replicas": 3}}' --type=merge ingresscontroller.operator.openshift.io/default patched
(4)迁移Image Registry
迁移之前,Registry运行在worker-1上,配置imageregistry.operator.openshift.io/v1的MachineSets。
# oc edit config/cluster
增加如下内容。
spec: nodeSelector: node-role.kubernetes.io/infra: ""
保存配置后,Register在Infra节点重启,如图3-43所示。

图3-43 Register在Infra节点重启
(5)迁移监控系统
默认情况下,OpenShift集群监控套件包含Prometheus、Grafana和AlertManager。它由Cluster Monitor Operator(CMO)管理。要将其组件移动到其他节点,我们需要创建并应用自定义ConfigMap。
# cat cluster-monitoring-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: name: cluster-monitoring-config namespace: openshift-monitoring data: config.yaml: |+ alertmanagerMain: nodeSelector: node-role.kubernetes.io/infra: "" prometheusK8s: nodeSelector: node-role.kubernetes.io/infra: "" prometheusOperator: nodeSelector: node-role.kubernetes.io/infra: "" grafana: nodeSelector: node-role.kubernetes.io/infra: "" k8sPrometheusAdapter: nodeSelector: node-role.kubernetes.io/infra: "" kubeStateMetrics: nodeSelector: node-role.kubernetes.io/infra: "" telemeterClient: nodeSelector: node-role.kubernetes.io/infra: "" openshiftStateMetrics: nodeSelector: node-role.kubernetes.io/infra: ""
应用配置前,我们看到Pod任意分布。应用上述配置。
# oc create -f cluster-monitoring-configmap.yaml
应用配置后,监控相关的Pod在Infra节点重启。
(6)迁移日志系统
我们修改日志ClusterLogging实例如下。
# oc edit ClusterLogging instance -n openshift-logging
增加如下加粗部分内容。
curator: nodeSelector: node-role.kubernetes.io/infra: '' resources: null schedule: 30 3 * * * type: curator logStore: elasticsearch: nodeCount: 3 nodeSelector: node-role.kubernetes.io/infra: '' redundancyPolicy: SingleRedundancy resources: limits: cpu: 500m memory: 16Gi requests: cpu: 500m memory: 16Gi storage: {} type: elasticsearch managementState: Managed visualization: kibana: nodeSelector: node-role.kubernetes.io/infra: ''
保存退出后,EFK相关的Pod会迁移到Infra节点。
8.离线环境导入OperatorHub
离线导入OperatorHub包含两个层面的内容:
·OperatorHub自身镜像资源:它负责支撑OperatorHub这个“壳”,也就是说,部署完毕后,OpenShift上可以看到OperatorHub,并且可以点击部署具体Operator的向导。
·Operator的镜像资源:我们在选择部署某个类型、版本的Operator时,OpenShift会找具体的Operator容器镜像(比如不同版本的ES Operator指向的容器镜像是不同的)。
首先我们离线同步OperatorHub自身的镜像资源,将OperatorHub的镜像从红帽官网镜像同步到管理机的本地镜像仓库,命令执行结果如图3-44所示。
# oc image mirror registry.redhat.io/openshift4/ose-operator-registry:v4.4 repo. apps.weixinyucluster.bluecat.ltd:5000/openshift4/ose-operator-registry -a ~/ pullsecret_config.json
注意:-a指定的认证要能同时访问registry.redhat.io和管理机镜像仓库repo.apps.weixinyucluster.bluecat.ltd:5000。
通过下面的命令构建本地的CatalogSource镜像,命令执行结果如图3-45所示。
# oc adm catalog build --appregistry-org redhat-operators --from=repo.apps. weixinyucluster.bluecat.ltd:5000/openshift4/ose-operator-registry:v4.4 --to= repo.apps.weixinyucluster.bluecat.ltd:5000/olm/redhat-operators:v1 -a ~/ pullsecret_config.json

图3-44 命令执行结果

图3-45 形成本地的CatalogSource镜像
命令中指定redhat-operators表示我们只构建redhat-operator CatalogSource。
获取要下载的具体Operator镜像的列表文件。
# oc adm catalog mirror --manifests-only repo.apps.weixinyucluster.bluecat. ltd:5000/olm/redhat-operators:v1 repo.apps.weixinyucluster.bluecat.ltd:5000 ~/pullsecret_config.json
上面的命令执行后,会生成redhat-operators-manifests目录,我们查看目录结构。
# tree redhat-operators-manifests/ redhat-operators-manifests/ ├── imageContentSourcePolicy.yaml └── mapping.txt
mapping.txt中包含CatalogSource为redhat-operator中所有镜像的映射关系,由于文件较长,我们查看其中elasticsearch operator的内容。
# cat mapping.txt |grep -i ose-elasticsearch-operator registry.redhat.io/openshift4/ose-elasticsearch-operator@sha256:13e233ff2dd419 67c55194724ba148868ed878232789ab616ea3a6f9a9219c97=repo.apps.weixinyucluster. bluecat.ltd:5000/openshift4/ose-elasticsearch-operator registry.redhat.io/openshift4/ose-elasticsearch-operator@sha256:06cc3bb2877403 60e4c0071dab8ea4254baa02a67205424241cfbfe8b2b8f375=repo.apps.weixinyucluster. bluecat.ltd:5000/openshift4/ose-elasticsearch-operator registry.redhat.io/openshift4/ose-elasticsearch-operator@sha256:e6c6a271910ba2 fbacc1f4b15cd538df588c1fbc32644ee984ae94bdaea56a23=repo.apps.weixinyucluster. bluecat.ltd:5000/openshift4/ose-elasticsearch-operator registry.redhat.io/openshift4/ose-elasticsearch-operator@sha256:9603cef2ceb515 0e7bf2b878a64cab30b3fa525e2a0dd3de93412c9baa3da2d5=repo.apps.weixinyucluster. bluecat.ltd:5000/openshift4/ose-elasticsearch-operator registry.redhat.io/openshift4/ose-elasticsearch-operator@sha256:aa0c7b11a65545 4c5ac6cbc772bc16e51ca5004eedccf03c52971e8228832370=repo.apps.weixinyucluster. bluecat.ltd:5000/openshift4/ose-elasticsearch-operator
我们看到在mapping.txt中一共有5行elasticsearch operator的内容,这是因为edhat-operator CatalogSource中有5个版本的elasticsearch operator。
很多时候,我们并不需要将mapping.txt中的镜像全部下载下来,只需要下载我们需要的种类和版本即可。为了方便操作,我们使用一个Shell脚本下载,这个脚本调用Skopeo命令行同步镜像(避免sha256发生变化)。
脚本如下所示:
# cat batchmirror.sh #!/bin/bash i=0 while IFS= read -r line do i=$((i + 1)) echo $i; source=$(echo $line | cut -d'=' -f 1) echo $source target=$(echo $line | cut -d'=' -f 2) echo $target skopeo copy --all docker://$source docker://$target sleep 20 done < es.txt
我们将从mapping中grep出来的elasticsearch operator五行内容贴到同目录es.txt中。
然后使用docker login分别登录registry.redhat.io和repo.apps.weixinyucluster.bluecat.ltd:5000,然后执行脚本。
# sh batchmirror.sh
执行成功后,会有5个elasticsearch operator的镜像被同步到repo.apps.weixinyucluster.bluecat.ltd:5000。
截至目前,我们已经有了OperatorHub“壳”的镜像,也有了redhat-operator CatalogSource中的elasticsearch Operator“瓤”(一共五个elasticsearch operator镜像)。
接下来形成离线的Operatorhub Catalog。OpenShift默认的OperatorHub的CatalogSource指向外网,我们需要将默认CatalogSource关闭,如下所示。
# oc patch OperatorHub cluster --type json \ > -p '[{"op": "add", "path": "/spec/disableAllDefaultSources", "value": true}]'
然后建立一个文件catalogsource.yaml,用于启动离线的CatalogSource,如下所示。
# export CHANNEL=redhat # oc apply -f - <<EOF apiVersion: operators.coreos.com/v1alpha1 kind: CatalogSource metadata: name: ${CHANNEL}-operators-internal namespace: openshift-marketplace labels: olm-visibility: hidden openshift-marketplace: "true" opsrc-datastore: "true" opsrc-owner-name: ${CHANNEL}-operators opsrc-owner-namespace: openshift-marketplace opsrc-provider: ${CHANNEL} spec: sourceType: grpc image: repo.apps.weixinyucluster.bluecat.ltd:5000/olm/redhat-operators:v1 displayName: ${CHANNEL}-operators-internal publisher: Red Hat EOF catalogsource.operators.coreos.com/redhat-operators-internal created
建立完成后检查OperatorHub界面是否可以访问,可以看到redhat-operator CatalogSource(Provider Type为Red Hat,与上面的指定步骤匹配),如图3-46所示:
我们查看承载OperatorHub这个“壳”的资源。
# oc get pods -n openshift-marketplace NAME READY STATUS RESTARTS AGE redhat-operators-internal-nvprb 1/1 Running 0 28s # oc get catalogsource -n openshift-marketplace NAME DISPLAY TYPE PUBLISHER AGE redhat-operators-internal redhat-operators-internal grpc Red Hat 33m

图3-46 查看OperatorHub界面
由于是离线环境,默认Operator的镜像地址指向外网,官方文档使用的是应用imageContentSourcePolicy.yaml文件,该方法要求所有的镜像使用sha256对镜像进行标记,但我们发现半数以上的镜像仍然采用Tag,这将导致Mirror失效,所以我们这里不采用imageContentSourcePolicy.yaml的方案,而采用通过MachineConfig为每个Node覆盖registries.conf配置的方法,设置mirror-by-digest-only=false,实现无论是使用sha256还是使用tag的镜像均可离线拉取。
首先书写sample-registres.conf文件,用于覆盖每个OpenShift的RHCOS节点/etc/containers/registries.conf,具体内容参考Repo中“sample-registres.conf”。
随后将sample-registres.conf通过base64加密,如下所示。
# export REG_CONF_BASE64=$(cat sample-registres.conf | base64 -w 0)
然后编写分别覆盖Master、Infra、App节点的配置的文件,如Repo中“3Xcontainer-registries”所示。
# oc apply -f 99-master-container-registries.yaml # oc apply -f 99-worker-container-registries.yaml # oc apply -f 99-infra-container-registries.yaml
应用配置文件后,应用配置的节点会发生重启,等待相应的服务器重启。
接下来,通过OpenShift OperatorHub选择elasticsearch operator,如图3-47所示。

图3-47 搜索Elasticsearch Operator
选择Elasticsearch Operator点击安装,选择如图3-48所示的内容。

图3-48 安装Elasticsearch Operator
很快,Elasticsearch Operator部署成功,如图3-49所示。

图3-49 Elasticsearch Operator部署成功