Skip to content

Instantly share code, notes, and snippets.

@ruo91
Last active March 15, 2021 13:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruo91/a5f7c8f6585fc1750dfdc00934b564a0 to your computer and use it in GitHub Desktop.
Save ruo91/a5f7c8f6585fc1750dfdc00934b564a0 to your computer and use it in GitHub Desktop.
How to upgrade a disconnected cluster in OpenShift 4.x

How to upgrade a disconnected cluster in OpenShift 4.x

OpenShift v4.x 버전부터는 클라우드 환경에서 좀 더 유연하게 관리가 될 수 있도록,
OTA(Over The Air) 업그레이드 방식을 사용한다.

OTA 방식은 스마트폰 업데이트 방식을 생각하면 쉽게 이해가 가능하다.

즉, 사용중인 제품에서 제공하는 업데이트 기능을 통해 외부 업데이트 서버에 주기적으로 요청하여,
최신의 정보를 받아오면서, 해당 제품의 새로운 버전이나 특정 버전에 대한 취약점 또는 개선사항 등이 있을 경우,
사용자 동의를 얻어 업데이트를 진행 하는 방식이다.

RedHat에서는 Public Cloud 환경을 고려해 OTA 업데이트 방식을 채택한 것으로 보고있다.

하지만, 기업 고객들은 자신들의 데이터를 외부에 저장하는 부분에 대해서 상당히 민감하기 때문에,
Public Cloud 환경보다는 Private Cloud를 구성하여 사용하는게 대부분이다.

그래서, Private Cloud 환경에서는 고객사 정책에 따라, 외부와 단절된 네트워크 환경(disconnected)에서 구성하는 경우가 많기 때문에, 아쉽게도 온라인 OTA 방식은 허용 되지 않는다.

다만, 특수한 환경에서는 외부와 연결 하도록 해주는 고객사도 간혹 보이는데, 보안상 권고 하지 않는다.

따라서, 외부와 단절된 네트워크 환경(disconneted)에서 OTA를 Workaround를 통해 자체 구현하는 방법에 대해서 정리한다. (Cincinnati Operator를 사용하는 방법에 대해서는 OPM(Operator Package Manager)과 연관이 있으므로, 추후에 업데이트 할 예정이다.)

본 문서는 아래와 같은 환경에서 테스트 되었다.

테스트 환경

  • Bastion VM
    • RHEL 8.x
    • CRI-O Runtime
    • Podman
  • OpenShift Container Platform Enterprise v4.6.x

구성도

Upgrade

1. Update API 정보

Cluster Version API 정보를 확인하면, OTA가 바라볼 업데이트 서버의 주소 확인이 가능하다.
해당 서버는 일방향성을 가지는 비순환 그래프, DAG(Directed Acyclic Graph)를 사용하는 Cincinnati Protocol을 기반으로 동작한다.

이 문서에서는 Cincinnati를 다루지 않을 예정이므로 업데이트 서버 정보만 확인하는 것으로 한다.
(이런게 있구나 정도로 이해하고 넘어가도록 한다.)

[root@bastion ~]# oc get clusterversion -o yaml
apiVersion: v1
items:
- apiVersion: config.openshift.io/v1
  kind: ClusterVersion
  metadata:
    name: version
  spec:
    channel: stable-4.6
    clusterID: 8ee7c712-c0b8-4394-9a6d-48d371b6952a
    desiredUpdate:
      force: true
      image: registry.ybkim.ocp4.local/openshift4/release@sha256:6ae80e777c206b7314732aff542be105db892bf0e114a6757cb9e34662b8f891
      version: ""
    upstream: https://api.openshift.com/api/upgrades_info/v1/graph

2. Update Registry 서버 구성

업데이트 서버를 구성하기 위해서는 Container 이미지 기반의 Registry 서버가 필요하다.
RHEL 7.x 버전의 경우 yum을 통해 docker-distribution을 설치하여 사용 가능했지만,
RHEL 8.x 버전에서는 더 이상 지원하지 않기 때문에, Container 기반으로 구동하여 사용해야 한다.

2.1. Docker Registry 이미지 다운로드

[root@bastion ~]# podman pull docker.io/library/registry:2.7.1

2.2. Release 미러링

업데이트에 사용 될 release 정보를 quay.io에서 미러링 받는다.
(이 문서에서 cloud.redhat.com 에서 pull secret을 발급받아 구성하는 과정은 생략한다.)

- Update Registry 구동

[root@bastion ~]# mkdir -p /data/update-registry
[root@bastion ~]# podman run --detach --name update-registry -p 5000:5000 \
-v /data/update-registry:/var/lib/registry:z docker.io/library/registry:2.7.1

- Release 버전 미러링

[root@bastion ~]# oc adm release mirror --insecure=true \
--from=quay.io/openshift-release-dev/ocp-release:4.7.2-x86_64 \
--to=localhost:5000/openshift-release-dev/ocp-release \
--to-release-image=localhost:5000/openshift-release-dev/ocp-release:4.7.2

[root@bastion ~]# oc adm release mirror --insecure=true \
--from=quay.io/openshift-release-dev/ocp-release:4.7.2-x86_64 \
--to=localhost:5000/openshift-release-dev/ocp-v4.0-art-dev \
--to-release-image=localhost:5000/openshift-release-dev/ocp-v4.0-art-dev:4.7.2

3. Release 버전 업로드

기존에 구축되어 있는 Docker Registry 서버에 최신 릴리즈 이미지를 업로드 한다.

3.1. 임시 도메인 설정

OpenShift v4.x 버전에서는 릴리즈 이미지 버전을 quay.io에서 다운로드 받게 설정이 되어있으나,
Image Content Source Policies를 통해 미러링 서버를 구성하여도 원본은 quay.io를 찾게 되어있어 편법을 사용해야 한다.

즉, bastion vm에서 quay.io 도메인으로 쿼리시 localhost로 응답하게 설정하려면 /etc/hosts 파일을 수정해야 한다.

[root@bastion ~]# echo '127.0.0.1 quay.io' >> /etc/hosts

3.2. Update Registry - http 모드 설정

quay.io 서버를 대체하기 위해서는 http 모드로 구동해야 한다.

기존의 update-registry 이름으로 구동하였던 Container를 중지/삭제 한다.

[root@bastion ~]# podman stop update-registry
[root@bastion ~]# podman rm update-registry

이후 80번 포트로 Container를 구동 한다.

[root@bastion ~]# podman run --name update-registry -p 80:5000 \
-v /data/update-registry:/var/lib/registry:z -d docker.io/library/registry:2.7.1

3.3. 릴리즈 버전 업로드

oc 명령어를 통해 update-registry 서버로 부터 릴리즈 버전을 다운로드 받는다.

[root@bastion ~]# oc adm release mirror --insecure=true \
--from=quay.io/openshift-release-dev/ocp-release:4.7.2 \
--to=registry.ybkim.ocp4.local/openshift4/release \
--to-release-image=registry.ybkim.ocp4.local/openshift4/release:4.7.2

3.4. Update Registry 중지/삭제

Update Registry 서버는 더 이상 사용되지 않으므로 구동 중인 Container를 중지/삭제 한다.

[root@bastion ~]# podman stop update-registry
[root@bastion ~]# podman rm update-registry

4. Release 버전 서명

OpenShift v4.6 버전부터 signature를 통한 인증 방식으로 업그레이드 정책이 변경이 되었다.
이 작업을 진행하지 않으면, 릴리즈 버전이 유효한 버전인지 검증할 방법이 없으므로,
업그레이드가 무기한으로 진행이 되지 않는다.

4.1. Release Digest 정보 확인

CLI를 이용한 업그레이드는 digest 형식의 이미지 주소를 통해 강제 업그레이드가 진행 되는 형태이므로,
릴리즈 버전의 digest를 확인 한다.

Digest 정보와 Pull From 정보를 기억 해둔다.

[root@bastion ~]# oc adm release info registry.ybkim.ocp4.local/openshift4/release:4.7.2
Name:           4.7.2
Digest:         sha256:83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584
Created:        2021-03-10T11:32:57Z
OS/Arch:        linux/amd64
Manifests:      480
Metadata files: 1

Pull From: registry.ybkim.ocp4.local/openshift4/release@sha256:83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584

Release Metadata:
  Version:  4.7.2
  Upgrades: 4.6.15, 4.6.16, 4.6.17, 4.6.18, 4.6.19, 4.6.20, 4.6.21, 4.7.0-fc.1, 4.7.0-fc.2, 4.7.0-fc.3, 4.7.0-fc.4, 4.7.0-fc.5, 4.7.0-rc.1, 4.7.0-rc.2, 4.7.0-rc.3, 4.7.0, 4.7.1
  Metadata:
    url: https://access.redhat.com/errata/RHBA-2021:0749

Component Versions:
  kubernetes 1.20.0-beta.2
  machine-os 47.83.202103051045-0 Red Hat Enterprise Linux CoreOS

4.2. Signature ConfigMap 생성

릴리즈 버전의 서명을 생성하기 위해서는 Digest와 일치하는 signature 파일을 아래 주소에서 다운로드 받아야 한다.

[root@bastion ~]# DIGEST="83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584"
[root@bastion ~]# wget http://mirror.openshift.com/pub/openshift-v4/signatures/openshift/release/sha256=$DIGEST/signature-1

- base64 인코딩

configmap에 해당 signature 내용을 삽입하기 위해서는 base64 암호화 방식으로 인코딩 한다.

[root@bastion ~]# cat signature-1 | base64 | awk '{printf $1}' > signature-1.txt

- ConfigMap 생성

[root@bastion ~]# DIGEST="83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584"
[root@bastion ~]# SIGNATURE="$(cat signature-1.txt)"
[root@bastion ~]# cat << EOF > release-image-v4.7.2.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: release-image-v4.7.2
  namespace: openshift-config-managed
  labels:
    release.openshift.io/verification-signatures: ""
binaryData:
  sha256-$DIGEST: $SIGNATURE
EOF

YAML 파일을 통해 ConfigMap을 생성한다.

[root@bastion ~]# oc create -f release-image-v4.7.2.yaml

- ConfigMap 확인

[root@bastion ~]# oc get configmap release-image-v4.7.2 -o yaml -n openshift-config-managed
apiVersion: v1
binaryData:
  sha256-83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584: owGbwMvMwMEoOU9/4l9n2UDGtYxJSWLxRQW5xZnpukWphbrunlnpvkV6SZl5CR6njKuVkosySzKTE3OUrBSqlTJzE9NTwayU/OTs1CLd3MS8zLTU4hLdlMx0IAWUUirOSDQyNbOyME5LTjQ0SrU0NjIxSDI1ME6zsEhNNrQ0Sko1TUszSDFLSUs1NzVIszBMtUgyTU0zN0xMs7Q0NDY2TzFPNrUwUarVUVAqqSwAWaeUWJKfm5mskJyfV5KYmZdapAB0bV5iSWlRqhJQVWZKal5JZkklssOKUtNSi1LzksHaC0sTK/Uy8/XzC1LzijMy00qA0jmpicWpuimpZfr5yQUwvpWJnrmekW6FhVm8GdAFICfkF5Rk5udB/Z9clAp0ShHIzKDUFAWPxBIFf6CZwSAzFYKBbsrMS1dwLC3JyAeGWqWCgZ6BniHQmE4mUWZWBlB4wsOd4+AC/n/KLBVMrHc9Ps/JT52wpru76YvCwTuv3HVFDXOKOuRtfiplzpKYdspS8Ya32ZTPYRynCs4sOOi6+laZzM6ojnvSTk2bJ/I/qxJlWbM7N3HeZFOPa87agSeaWx9zb15W7TY/Vt4gV/O33enWzafM/urbeH9m+RpUZnj4uXt46bRsH7OSE38t4v2mpT25c26pwP/r+3R+/+gNrPt+9cqH84WuMwRZV+qqPIr2/Nhz36opYUWO5s3ztgttNmRNKgt2eXRMbOU259V7uxeJ+X/MCjRZ8my//PW7esZqbMwKkSkWWlPeFb50uTwnu979VOHMQMuJagsjv2ZUiDVV6pRldOqJvX7drNKzL/eG7Yl9vZ7PmhYefsLU0LBsZRpjt0F5Q4M6/+2nmYtbTes9xKaUFJgyu2V9WHuP61s76z/N6lvVT6Yo+nw4o3zWRu7BhfkP+3XZl/gFORqX6/3uNI06vWbyNy7D3JfMf/9Llrsez8rakuedulTBpmWO6s/9D/k3ivN2b63SWvDM7YrphMkW/2aqr3opz17raRv9YuO9QP7vSWHHk5cnFSSsl3povKDAxmDdlgjefkX5jY7/PGaaM1XYOG8N+m14/dKWiW4b0hpM1csKLh8XrX68/VblC7fzH695PuPiu8uYx9SaNy2qSCcu0y5Zcsfuo9VWfiHKnTV+p7pCr0yt/aQ2m6n607b0pa+L/iYZzlviIsgLAA==
kind: ConfigMap
metadata:
  labels:
    release.openshift.io/verification-signatures: ""
  name: release-image-v4.7.2
  namespace: openshift-config-managed

5. 업그레이드 진행

CLI를 통해 업그레이드를 진행하기 위해서는 2개의 옵션을 사용하여 진행 한다.

[root@bastion ~]# DIGEST="83fca12e93240b503f88ec192be5ff0d6dfe750f81e8b5ef71af991337d7c584"
[root@bastion ~]# oc adm upgrade \
--allow-explicit-upgrade --force \
--to-image=registry.ybkim.ocp4.local/openshift4/release@sha256:$DIGEST

- 옵션

--allow-explicit-upgrade
업그레이드 대상 목록에 없는 버전인 경우에도 업그레이드 진행.

--force
릴리즈 이미지의 유효성 검사 및 오류가 나와도 강제 업그레이드를 진행.

6. 업그레이드 진행 확인

릴리즈 업그레이드를 위해 이미지 버전을 다운로드 중이다.

[root@bastion update-registry]# oc get clusterversion
NAME      VERSION   AVAILABLE   PROGRESSING   SINCE   STATUS
version   4.6.21    True        True          6m1s    Working towards 4.7.2: 70 of 668 done (10% complete)

ocp4-upgrade-disconneted

이후 etcd -> kube-apiserver -> kube-scheduler -> kube-controller-manager -> config-operator 순서로
버전이 업그레이드 되고, 나머지 Operator 들이 랜덤하게 버전 업그레이드가 진행 된다.

[root@bastion update-registry]# oc get clusteroperators
NAME                                     VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE
authentication                           4.6.21    True        False         False      3m31s
baremetal
cloud-credential                         4.6.21    True        False         False      46h
cluster-autoscaler                       4.6.21    True        False         False      46h
config-operator                          4.6.21    True        False         False      46h
console                                  4.6.21    True        False         False      61m
csi-snapshot-controller                  4.6.21    True        False         False      61m
dns                                      4.6.21    True        False         False      46h
etcd                                     4.7.2     True        True          False      46h
image-registry                           4.6.21    True        False         False      44h
ingress                                  4.6.21    True        False         False      52m
insights                                 4.6.21    True        False         False      46h
kube-apiserver                           4.6.21    True        False         False      46h
kube-controller-manager                  4.6.21    True        False         False      46h
kube-scheduler                           4.6.21    True        False         False      46h
kube-storage-version-migrator            4.6.21    True        False         False      45h
machine-api                              4.6.21    True        False         False      46h
machine-approver                         4.6.21    True        False         False      46h
machine-config                           4.6.21    True        False         False      46h
marketplace                              4.6.21    True        False         False      51m
monitoring                               4.6.21    True        False         False      50m
network                                  4.6.21    True        False         False      46h
node-tuning                              4.6.21    True        False         False      46h
openshift-apiserver                      4.6.21    True        False         False      96s
openshift-controller-manager             4.6.21    True        False         False      44h
openshift-samples                        4.6.21    True        False         False      46h
operator-lifecycle-manager               4.6.21    True        False         False      46h
operator-lifecycle-manager-catalog       4.6.21    True        False         False      46h
operator-lifecycle-manager-packageserver 4.6.21    True        False         False      51m
service-ca                               4.6.21    True        False         False      46h
storage                                  4.6.21    True        False         False      46h

6. 업그레이드 완료

업그레이드 완료 시점은 약 2h 45m 정도 소요 되었으며, 클러스터 노드 수 및 네트워크, Disk IO등과 같은 인프라 환경 요소에 따라서 시간 차이가 발생한다.

- Kubernetes 버전

[root@bastion ~]# oc get node
NAME                        STATUS   ROLES    AGE    VERSION
master01.ybkim.ocp4.local   Ready    master   2d3h   v1.20.0+5fbfd19
master02.ybkim.ocp4.local   Ready    master   2d3h   v1.20.0+5fbfd19
master03.ybkim.ocp4.local   Ready    master   2d3h   v1.20.0+5fbfd19
router01.ybkim.ocp4.local   Ready    router   2d2h   v1.20.0+5fbfd19
router02.ybkim.ocp4.local   Ready    router   2d2h   v1.20.0+5fbfd19
router03.ybkim.ocp4.local   Ready    router   2d2h   v1.20.0+5fbfd19
worker01.ybkim.ocp4.local   Ready    worker   2d2h   v1.20.0+5fbfd19
worker02.ybkim.ocp4.local   Ready    worker   2d2h   v1.20.0+5fbfd19
worker03.ybkim.ocp4.local   Ready    worker   2d2h   v1.20.0+5fbfd19
worker04.ybkim.ocp4.local   Ready    worker   2d2h   v1.20.0+5fbfd19

- Cluster Operator 버전

[root@bastion ~]# oc get clusteroperators
NAME                                     VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE
authentication                           4.7.2     True        False         False      3h13m
baremetal                                4.7.2     True        False         False      5h7m
cloud-credential                         4.7.2     True        False         False      2d3h
cluster-autoscaler                       4.7.2     True        False         False      2d3h
config-operator                          4.7.2     True        False         False      2d3h
console                                  4.7.2     True        False         False      113m
csi-snapshot-controller                  4.7.2     True        False         False      4h52m
dns                                      4.7.2     True        False         False      114m
etcd                                     4.7.2     True        False         False      2d3h
image-registry                           4.7.2     True        False         False      2d2h
ingress                                  4.7.2     True        False         False      3h42m
insights                                 4.7.2     True        False         False      2d3h
kube-apiserver                           4.7.2     True        False         False      2d3h
kube-controller-manager                  4.7.2     True        False         False      2d3h
kube-scheduler                           4.7.2     True        False         False      2d3h
kube-storage-version-migrator            4.7.2     True        False         False      3h25m
machine-api                              4.7.2     True        False         False      2d3h
machine-approver                         4.7.2     True        False         False      2d3h
machine-config                           4.7.2     True        False         False      3h8m
marketplace                              4.7.2     True        False         False      114m
monitoring                               4.7.2     True        False         False      113m
network                                  4.7.2     True        False         False      4h36m
node-tuning                              4.7.2     True        False         False      5h2m
openshift-apiserver                      4.7.2     True        False         False      3h6m
openshift-controller-manager             4.7.2     True        False         False      2d2h
openshift-samples                        4.7.2     True        False         False      5h4m
operator-lifecycle-manager               4.7.2     True        False         False      2d3h
operator-lifecycle-manager-catalog       4.7.2     True        False         False      2d3h
operator-lifecycle-manager-packageserver 4.7.2     True        False         False      114m
service-ca                               4.7.2     True        False         False      2d3h
storage                                  4.7.2     True        False         False      2d3h

- Web Console 정보

Overview

About

Cluster Settings

Machine Configs

7. RefURL

[1]: RedHat Documentation - Updating a restricted network cluster
[2]: RedHat Knowledge base - How to Upgrade OpenShift 4 between different minor versions via "oc" cli
[3]: OpenShift Update Service - Update Manager for Your Cluster

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment