사전 준비를 끝내고 본격적으로 Openshift 설치를 시작한다. Disconnected 환경에서 Openshift를 설치하고 사용하기 위하여 다음과 같은 구성 요소들을 설치한다.
Private Registry
Yum repository
DNS
Chrony
Haproxy
인터넷이 되지 않는 disconnected 환경에서는 설치에 필요한 이미지를 인터넷에서 가져올 수 없다. 따라서, 폐쇄망 내에 Private Registry를 구축하여 OCP 설치에 필요한 이미지들을 사용하도록 한다. 또한, Operator 이미지를 사용하여 폐쇄망에서 클러스터를 구성한다.
1. OpenShfit CLI( oc ) 설치
-
Infrastructure Provider 에서 oc 다운로드
-
다운로드한 압축파일 해제
tar -xvzf <file>
-
PATH 설정
cp ./oc /usr/local/bin/ cp ./kubectl /usr/local/bin/
2. httpd-tools, podman 설치
-
httpd-tools를 통해 htpasswd 프로그램 사용
-
컨테이너 런타임인 podman을 통해 mirror registry 이미지 생성
yum -y install podman httpd-tools
3. jq 설치
-
pull-secret을 json 형식으로 저장하기 위하여 설치
curl -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -o /usr/local/bin/jq chmod a+x /usr/local/bin/jq
4. 작업 Directory 생성
-
원하는 경로에 auth, data, certs 세가지 Directory를 생성
mkdir -p /opt/registry/{auth,data,certs}
5. OpenSSL 인증서 생성
-
Private registry의 보안을 위해 openssl 명령어로 인증서를 생성하여 사용
-
bastion의 호스트네임과 pull-secret을 받은 RedHat 이메일 계정 정보 사용
cd /opt/registry/certs openssl req -newkey rsa:4096 -nodes -sha256\ -keyout domain.key -x509 -days 3650 -out domain.crt cp /opt/registry/certs/domain.crt /etc/pki/ca-trust/source/anchors/ update-ca-trust extract
6. private registry에 등록할 계정 생성 및 base64 인코딩
-
Redhat mirror registry에서 private registry로 mirroring 할 수 있도록 credentials 생성
-
/opt/registry/auth/htpasswd 파일에 credentials 등록
-
base64로 인코딩한 credentials 확인 및 저장
htpasswd -bBc /opt/registry/auth/htpasswd <USER_NAME> <PASSWORD> echo -n '<USER_NAME>:<PASSWORD>' | base64 -w0 BGVtbYk3ZHAtqXs= # credentials
7. pull-secret 다운 및 JSON 포맷 변환
-
Red Hat Openshift Cluster Manager 홈페이지에서 pull-secret 다운로드
-
다운로드한 pull-secret 과 동일한 내용의 파일 생성
-
pull-secret은 24시간 동안만 유효함을 주의
vim pull-secret ... "auth": {... ... cat pull-secret | jq . > ./pull-secret.json vim pull-secret.json ... "auths": { ... "<local_registry_host_name>:<local_registry_host_port>": { "auth": "<credentials>", "email": "REDHAT_ACCOUNT_EMAIL" }, ... ...
8. Private registry 컨테이너 생성
-
컨테이너 생성
podman run --name mirror-registry -p 5000:5000 \ -v /opt/registry/data:/var/lib/registry:z \ -v /opt/registry/auth:/auth:z \ -v /opt/registry/certs:/certs:z \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ -e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true \ -d docker.io/library/registry:2
-
확인 ( 아직 아무 이미지도 넣지 않았으므로 빈 repository가 나오면 맞다 )
curl -u <USERNAME:PASSWORD> -k https://<local_registry_host_name>:<local_registry_host_port>/v2/_catalog {"repositories":[]}
9. Mirroring (Redhat registry → Private Registry)
-
미러링에 필요한 환경변수 설정
-
OpenShift Release version 확인은 Repository Tags에서 진행
export OCP_RELEASE=<release_version> export LOCAL_REGISTRY='<local_registry_host_name>:<local_registry_host_port>' export LOCAL_REPOSITORY='<local_repository_name>' export PRODUCT_REPO='openshift-release-dev' export LOCAL_SECRET_JSON='<path_to_pull_secret>' export RELEASE_NAME="ocp-release" export ARCHITECTURE=<server_architecture>
-
미러링
oc adm -a ${LOCAL_SECRET_JSON} release mirror \ --from=quay.io/${PRODUCT_REPO}/${RELEASE_NAME}:${OCP_RELEASE}-${ARCHITECTURE} \ --to=${LOCAL_REGISTRY}/${LOCAL_REPOSITORY} \ --to-release-image=${LOCAL_REGISTRY}/${LOCAL_REPOSITORY}:${OCP_RELEASE}-${ARCHITECTURE} --dry-run
-
미러링 출력 결과 중 imageContentSources 부분 저장 ( install-config.yaml에 사용)
# Example ... imageContentSources: - mirrors: - bastion.redhat2.cccr.local:5000/ocp4/openshift4 source: quay.io/openshift-release-dev/ocp-release - mirrors: - bastion.redhat2.cccr.local:5000/ocp4/openshift4 source: quay.io/openshift-release-dev/ocp-v4.0-art-dev ...
10. 미러링한 콘텐츠 바탕으로 openshift-install 바이너리 프로그램 파일 생성
oc adm -a ${LOCAL_SECRET_JSON} release extract --command=openshift-install "${LOCAL_REGISTRY}/${LOCAL_REPOSITORY}:${OCP_RELEASE}-${ARCHITECTURE}"
11. 미러링한 이미지 및 설치도구 압축 및 저장
-
이미지 및 설치 도구 압축
-
설치 도구 : pull-secret, OpenShift Client( oc ), kubectl, openshift-install
tar -czvf <INSTALL_FILE>.tar.gz oc kubectl /opt/* openshift-install
-
podman image save
podman images podman save -o <PODMAN_IMAGE>.tar docker.io/library/registry:2
-
USB에 저장
mount <DISK> <MOUNTPOINT> mv <FILE_NAME>.tar.gz <MOUNTPOUINT> mv <FILE_NAME>.tar <MOUNTPOINT>
1. Host에서 Bastion으로 tar파일 전송
scp <LOCAL_HDD_MOUNT_POINT>/<INSTALL_FILE>.tar.gz root@<BASTION IP>:/opt
scp <LOCAL_HDD_MOUNT_POINT>/<PODMAN_IMAGE>.tar root@<BASTION'S IP>:~/
2. 압축 해제 및 podman load
-
압축 해제
tar -xzvf /opt/<INSTALL_FILE>.tar.gz oc kubectl openshift-install ./auth ./certs ./data
-
podman load
podman load -i <PODMAN_IMAGE>.tar REPOSITORY TAG IMAGE ID CREATED SIZE ... ... 2d4f....
3. Private registry 컨테이너 생성
-
컨테이너 생성
podman run --name mirror-registry -p 5000:5000 \ -v /opt/registry/data:/var/lib/registry:z \ -v /opt/registry/auth:/auth:z \ -v /opt/registry/certs:/certs:z \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ -e REGISTRY_COMPATIBILITY_SCHEMA1_ENABLED=true \ -d 2d4f # <IMAGE ID>
-
확인
curl -u <USERNAME:PASSWORD> -k https://<local_registry_host_name>:<local_registry_host_port>/v2/_catalog {"repositories":["ocp4/openshift4"]}
인터넷이 되지 않는 폐쇄망 내부의 다른 노드들이 Yum Repository를 사용할 수 있도록 한다. Bastion에 Httpd를 통한 File Server를 구축하여 Yum Repository 서비스를 제공한다.
1. yum-utils, createrepo 다운로드
-
Repository 동기화에 사용
yum -y install yum-utils createrepo
2. rpm repository 다운로드 및 repodata 생성
-
repodata : yum repo의 index정보를 담고있는 metadata
for repo in \ rhel-7-server-extras-rpms \ rhel-7-server-ose-4.4-rpms \ rhel-7-server-rpms do reposync --repoid=${repo} --download_path=<DOWNLOAD_PATH> createrepo -o <DOWNLOAD_PATH> <DOWNLOAD_PATH> done
3. 다운받은 rpm과 생성된 repodata 사용 준비
-
tar로 압축하여 usb로 옮기기
tar -czvf <FILE_NAME>.tar.gz <DOWNLOAD_PATH>/* mount <DISK> <MOUNTPOINT> mv <FILE_NAME>.tar.gz <MOUNTPOUINT>
1. Host에서 Guest(Bastion)로 tar파일 전송
-
파일서버로 사용할 httpd서비스의 DocumentRoot 경로 : /var/www/html/repo
scp <LOCAL_HDD_MOUNT_POINT>/<FILE_NAME>.tar.gz root@<BASTION'S IP>:/var/www/html/repo
2. 압축해제 및 /etc/yum.repo.d/local.repo 수정
-
file:https:// : yum repository를 위한 httpd서비스를 구축하기 전이므로 file프로토콜을 사용해 bastion 스스로 yum repo사용이 가능하도록 함
tar -xzvf /var/www/html/repo/<FILE_NAME>.tar.gz vi /etc/yum.repo.d/local.repo [base] name=local repo baseurl=file:https:///var/www/html/repo enabled=1 gpgcheck=0
3. httpd 파일서버 구축
-
yum repolist 확인
yum repolist yum install -y httpd
-
사용할 포트 수정
vi /etc/httpd/conf/httpd.conf ... Listen 8080 ... systemctl enable --now httpd
4. /etc/yum.repo.d/local.repo baseurl 프로토콜 변경
-
구축한 웹서버의 http 프로토콜을 사용하여 폐쇄망 내의 다른 노드들도 yum 사용 가능하게 함
vi /etc/yum.repo.d/local.repo [base] name=local repo baseurl=https://localhost/repo enabled=1 gpgcheck=0
5. selinux 컨텍스트 설정
-
RHEL7 부터 httpd 프로세스는 httpd_sys_content_t 가 설정된 자원에는 read만 가능
-
read/write 가능한 컨텍스트인 httpd_sys_rw_content_t 컨텍스트를 적용
chcon -R -t httpd_sys_rw_content_t /var/www/html/repo
OCP 클러스터 내의 노드들은 서로의 FQDN을 사용하여 통신한다. 클러스터 내부에서 FQDN기반의 통신이 가능하도록 내부 DNS를 설정한다.
- cluster domain name : redhat2
- base domain : cccr.local
1. DNS 서버 설치
-
bind 를 통해 DNS 서버 설치
sudo yum install -y bind bind-utils
2. DNS 설정 파일 수정
-
경로 : /etc/named.conf
-
기본 DNS 설정 파일을 수정하여 실제 사용할 환경에 맞춤
-
사용하지 않는 ipv6를 막고 DNS 쿼리를 허용할 대상을 설정
vi /etc/named.conf 13 listen-on port 53 { any; }; 14 listen-on-v6 port 53 { none; }; 21 allow-query { any; };
-
확인
named-checkconf /etc/named.conf
3. 정방향 DNS Zone 설정
-
정방향 조회 Zone 파일을 /var/named 하위에 설정
-
cluster 내 모든 구성요소의 이름과 ip 를 선언
-
ocp4에서는 Kubernetes API 요소로 사용되는 api.<cluster_name>, api-int.<cluster_name>와 Route 요소로 사용되는 *.apps.<cluster_name> 을 반드시 선언해야함
# zone file Example vi /var/named/cccr.local.zone $TTL 1H @ IN SOA cccr.local. root.cccr.local. ( 2020090900 ; serial 1H ; refresh 15M ; retry 1W ; expiry 15M ) ; minimum @ IN NS cccr.local. IN A 10.10.10.17 ns IN A 10.10.10.17 ;cluster name redhat2 IN CNAME @ ; -------------------------------------------------------------------------------------- ; ---- OCP DNS Records ----------------------------------------------------------------- ; -------------------------------------------------------------------------------------- api.redhat2 IN A 10.10.10.17 api-int.redhat2 IN A 10.10.10.17 *.apps.redhat2 IN A 10.10.10.17 bastion.redhat2 IN A 10.10.10.17 ; -------------------------------------------------------------------------------------- ; ---- Bootstrap ----------------------------------------------------------------------- ; -------------------------------------------------------------------------------------- bootstrap.redhat2 IN A 10.10.10.10 ; -------------------------------------------------------------------------------------- ; ---- Master -------------------------------------------------------------------------- ; -------------------------------------------------------------------------------------- master-1.redhat2 IN A 10.10.10.11 master-2.redhat2 IN A 10.10.10.12 master-3.redhat2 IN A 10.10.10.13 ; -------------------------------------------------------------------------------------- ; ---- Service ------------------------------------------------------------------------- ; -------------------------------------------------------------------------------------- service-1.redhat2 IN A 10.10.10.18 service-2.redhat2 IN A 10.10.10.19 ; -------------------------------------------------------------------------------------- ; ---- Infra ------------------------------------------------------------------------- ; -------------------------------------------------------------------------------------- infra-1.redhat2 IN A 10.10.10.14 infra-2.redhat2 IN A 10.10.10.15 ; -------------------------------------------------------------------------------------- ; ---- Router ------------------------------------------------------------------------- ; -------------------------------------------------------------------------------------- router.redhat2 IN A 10.10.10.16 ; -------------------------------------------------------------------------------------- ; ---- SCM ------------------------------------------------------------------------- ; -------------------------------------------------------------------------------------- scm.redhat2 IN A 10.10.10.20
4. 역방향 DNS Zone 설정
-
역방향 조회 Zone 파일을 /var/named 하위에 설정
-
역방향 DNS를 설정해주지 않으면, 노드들이 자신의 hostname을 찾지못하는 오류가 날 수 있으므로 필요
-
ocp4에서는 사용되는 모든 노드들과 api, api-int 를 선언
vi /var/named/reverse.cccr.local $TTL 86400 @ IN SOA cccr.local. ns.cccr.local. ( 20201005 ; Serial 3H ; Refresh 1H ; Retry 1W ; Expire 1H ) ; Minimum @ IN NS cccr.local. IN A 10.10.10.17 17 IN PTR bastion.redhat2.cccr.local. 10 IN PTR bootstrap.redhat2.cccr.local. 11 IN PTR master-1.redhat2.cccr.local. 12 IN PTR master-2.redhat2.cccr.local. 13 IN PTR master-3.redhat2.cccr.local. 18 IN PTR service-1.redhat2.cccr.local. 19 IN PTR service-2.redhat2.cccr.local. 14 IN PTR infra-1.redhat2.cccr.local. 15 IN PTR infra-2.redhat2.cccr.local. 16 IN PTR router.redhat2.cccr.local. 20 IN PTR scm.redhat2.cccr.local. 17 IN PTR api.redhat2.cccr.local. 17 IN PTR api-int.redhat2.cccr.local.
5. DNS Zone 추가
-
DNS zone 파일을 등록하는 설정파일에 앞서 생성한 Zone을 추가
vi /etc/named.rfc1912.zones ... zone "cccr.local" IN { type master; file "cccr.local.zone"; allow-update { none; }; }; zone "10.10.10.in-addr.arpa" IN { type master; file "reverse.cccr.local"; allow-update { none; }; }; ...
-
확인
named-checkzone cccr.local /var/named/cccr.local.zone named-checkzone cccr.local /var/named/reverse.cccr.local
6. DNS 서비스 시작
-
서비스 시작
systemctl start named systemctl enable named
-
확인
nslookup master-1.redhat2.cccr.local Server: 10.10.10.17 Address: 10.10.10.17#53 Name: master-1.redhat2.cccr.local Address: 10.10.10.11 dig api-int.redhat2.cccr.local +short 10.10.10.17 nslookup 10.10.10.18 18.10.10.10.in-addr.arpa name = service-1.redhat2.cccr.local. dig -x 10.10.10.11 +short master-1.redhat2.cccr.local.
OCP 클러스터 내 노드들의 시간동기화를 위하여 사용한다. disconnected 환경에서는 인터넷에 접속하여 외부 타임 서버를 사용할 수 없으므로 Bastion 노드를 Chrony Server로 설정하여 로컬 타임으로 시간을 동기화 한다.
- 시간 기준 : 협정세계시(UTC) 사용
1. Chrony 설치
yum -y install chrony
2. Chrony 설정 파일 수정
-
로컬에서의 모든 권한을 허용
-
클러스터 내 노드의 ip 대역인 10.10.10.0/24 에게 chrony 서비스를 허용
vi /etc/chrony.conf driftfile /var/lib/chrony/drift makestep 1.0 3 rtcsync allow 127.0.0.1 allow 10.10.10.0/24 local stratum 10 logdir /var/log/chrony
3. chrony 서비스 시작
-
chrony 시작
systemctl enable --now chronyd systemctl start chronyd
-
확인
timedatectl Local time: 수 2020-09-30 01:32:59 UTC Universal time: 수 2020-09-30 01:32:59 UTC RTC time: 월 2020-10-05 00:53:28 Time zone: UTC (UTC, +0000) NTP enabled: yes NTP synchronized: no RTC in local TZ: no DST active: n/a
1. Chrony 설치
yum -y install chrony
2. Chrony 설정 파일 수정
-
bastion 노드(10.10.10.17)를 chrony server 로 설정
vi /etc/chrony.conf server 10.10.10.17 iburst driftfile /var/lib/chrony/drift makestep 1.0 3 rtcsync logdir /var/log/chrony
3. chrony 서비스 시작
-
chrony 서비스 시작
systemctl enable --now chronyd systemctl start chronyd
-
확인
timedatectl Local time: 수 2020-09-30 01:32:59 UTC Universal time: 수 2020-09-30 01:32:59 UTC RTC time: 월 2020-10-05 00:53:28 Time zone: UTC (UTC, +0000) NTP enabled: yes NTP synchronized: no RTC in local TZ: no DST active: n/a
OCP 클러스터 내 노드 간에 통신이 가능하도록 프로토콜을 제공하는 로드밸런서를 생성하기 위해 사용한다. API 로드밸런서 역할과 클러스터 외부에서 유입되는 트래픽을 라우터로 리다이렉트하는 역할을 수행한다.
- 6443 포트 : Kubernetes API Server
- 22623 포트 : Machine Config Server
- 80 포트 : HTTP
- 443 포트 : HTTPS
1. Haproxy 설치
yum -y install haproxy
2. Haproxy 설정 파일 수정
-
Kubernetes API Server 포트와 Machine Config Server 포트 에는 부트스트랩과 컨트롤 플레인을 설정. ( 단, 부트스트랩은 마스터 설치가 끝난 후 제거해도 무방 )
-
클러스터 외부에서 유입되는 트래픽은 기본적으로 라우터에서 처리되므로 HTTP, HTTPS 포트에는 라우터 노드를 설정
# haproxy.cfg file Example vi /etc/haproxy/haproxy.cfg #--------------------------------------------------------------------- # Global settings #--------------------------------------------------------------------- global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block #--------------------------------------------------------------------- defaults mode tcp log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 #--------------------------------------------------------------------- # main frontend which proxys to the backends #--------------------------------------------------------------------- frontend api bind *:6443 default_backend controlplaneapi option tcplog frontend machineconfig bind *:22623 default_backend controlplanemc option tcplog frontend tlsrouter bind *:443 default_backend secure option tcplog frontend insecurerouter bind *:80 default_backend insecure option tcplog #--------------------------------------------------------------------- # static backend #--------------------------------------------------------------------- backend controlplaneapi balance source server bootstrap 10.10.10.10:6443 check server master-0 10.10.10.11:6443 check server master-1 10.10.10.12:6443 check server master-2 10.10.10.13:6443 check backend controlplanemc balance source server bootstrap 10.10.10.10:22623 check server master-0 10.10.10.11:22623 check server master-1 10.10.10.12:22623 check server master-2 10.10.10.13:22623 check backend secure balance source server router 10.10.10.16:443 check backend insecure balance source server router 10.10.10.16:80 check
3. Haproxy 서비스 시작
setsebool -P haproxy_connect_any 1
systemctl enable haproxy
systemctl start haproxy
Chapter 3. Installation configuration OpenShift Container Platform 4.5 | Red Hat Customer Portal