OpenShift在企业中的实践:PaaS DevOps微服务(第2版)
上QQ阅读APP看书,第一时间看更新

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部署成功