[Cloud]/OpenStack

폐쇄환경에서 OSP16.1 레포지토리 및 컨테이너 이미지 레지스트리 구축하기

ByoungHee Lee 2020. 9. 28. 18:02

  OSP16.1는 기본적으로 인터넷이 되는 환경을 기반으로 구성되어 있고 컨테이너 이미지 저장소는 Satellite을 통해 관리하도록 매뉴얼화되어 있습니다. 하지만, 대부분의 고객사의 환경은 Satellite을 수용하지 않거나 폐쇄된 환경에서의 설치가 요구되어 집니다. 때문에, 이러한 대부분의 고객 요건을 만족하기 위해서는 폐쇄된 환경의 패키지 레포지토리 및 컨테이너 이미지 레지스트리에 대한 준비가 꼭 필요합니다. 이번 장에서는 OSP16.1 환경에서 패키지 레포지토리와 컨테이너 이미지 레지스트리를 어떻게 구성하고 사용하는지에 대해 주로 다루도록 하겠습니다.    

사전 준비사항 :

  • RHEL 8 image 준비 및 OS 설치
  • sudo stack 계정 생성
  • subscribtion 및 pool 등록
  • 초기에는 패키지와 컨터에너 이미지를 다운로드 받기위해 인터넷 사용 필수

1. 우선 RHEL8 기반의 OS를 설치하고 충분한 디스크 용량을 확보한 후 인터넷 접근이 가능하도록 설정 합니다.  
그런 후, 아래의 repositories를 enalble 합니다.

$ sudo subscription-manager repos --disable=* \
--enable=rhceph-4-tools-for-rhel-8-x86_64-rpms \
--enable=rhel-8-for-x86_64-baseos-rpms \
--enable=rhel-8-for-x86_64-appstream-rpms \
--enable=rhel-8-for-x86_64-highavailability-rpms \
--enable=ansible-2.8-for-rhel-8-x86_64-rpms \
--enable=openstack-16-for-rhel-8-x86_64-rpms \
--enable=fast-datapath-for-rhel-8-x86_64-rpms


2. reposync.sh 쉘을 실행하여 언더크라우드 및 오버클라우드 설치에 필요한 패키지를 로컬에 다운 받습니다. 
RHEL8에서는 최신의 패키지만 받으면 패키지 의존성 있는 경우가 종종 있습니다. 때문에, 저는 개인적으로 패키지 모두 받는것을 권장합니다.

$ cat reposync.sh 
#!/bin/bash
REPO_LIST=(
rhel-8-for-x86_64-baseos-eus-rpms 
rhel-8-for-x86_64-appstream-eus-rpms 
rhel-8-for-x86_64-highavailability-eus-rpms 
ansible-2.9-for-rhel-8-x86_64-rpms 
openstack-16.1-for-rhel-8-x86_64-rpms 
fast-datapath-for-rhel-8-x86_64-rpms
rhceph-4-tools-for-rhel-8-x86_64-rpms

)
REPO_DIR="/data/repo/osp16"
for i in "${REPO_LIST[@]}"; do
reposync --repoid="$i" -p "${REPO_DIR}" --downloadcomps --download-metadata
done

3. 컨테이너 이미지 저장소 환경을 구성하기 위해 필요한 템플릿을 사용할 수 있도록 python3-tripleoclient 툴을 설치 합니다.

$ sudo yum install -y python3-tripleoclient

4. python3-tripleoclient 툴을 통해 필요한 ansible role 들이 구성되었으며, 이를 활용할 수 있는  ansible 실행 환경을 구성합니다.

$ mkdir ansible
$ cd ansible
$ mkdir roles
$ cp -r /usr/share/ansible/roles/tripleo-image-serve roles
$ cat inventory 
[local]
172.x.x.11
$ cat ansible.cfg | egrep -v '^#|^$'
[defaults]
inventory      = /home/stack/ansible/inventory
[inventory]
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
[stack@rhel8-repo ansible]$ ansible -m ping local
172.17.1.11 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

 

5. 컨테이너 이미지 저장소를 구축하기 위해 role을 정의하고 playbook을 로컬에서 실행합니다.

$ cat image-serve.yaml 
---
- hosts: local
  tasks:
  - name: Install, Configure and Run Apache to serve container images
    include_role:
      name: roles/tripleo-image-serve
    vars:
      container_registry_host: "*"

$ ansible-playbook image-serve.yaml

 

6. undercloud 또는 overcloud 설치시 먼저16.1을 체크하고 그 다음 릴리즈가 붙은 버전을 찾기 때문에, 컨테이너 16.1과 16.1-{릴리즈} 두가지 버전을 꼭 같이 받아서 저장소에 저장해야만 합니다.

$ openstack tripleo container image prepare default \
  --local-push-destination \
  --output-env-file containers-prepare-parameter.yaml

$ cat ~/containers-prepare-parameter.yaml
parameter_defaults:
  ContainerImagePrepare:
  - push_destination: true
    set:
      ceph_alertmanager_image: ose-prometheus-alertmanager
      ceph_alertmanager_namespace: registry.redhat.io/openshift4
      ceph_alertmanager_tag: 4.1
      ceph_grafana_image: rhceph-4-dashboard-rhel8
      ceph_grafana_namespace: registry.redhat.io/rhceph
      ceph_grafana_tag: 4
      ceph_image: rhceph-4-rhel8
      ceph_namespace: registry.redhat.io/rhceph
      ceph_node_exporter_image: ose-prometheus-node-exporter
      ceph_node_exporter_namespace: registry.redhat.io/openshift4
      ceph_node_exporter_tag: v4.1
      ceph_prometheus_image: ose-prometheus
      ceph_prometheus_namespace: registry.redhat.io/openshift4
      ceph_prometheus_tag: 4.1
      ceph_tag: latest
      name_prefix: openstack-
      name_suffix: ''
      namespace: registry.redhat.io/rhosp-rhel8
      neutron_driver: ovn
      rhel_containers: false
      tag: '16.1'
    tag_from_label: '{version}-{release}'
  ContainerImageRegistryCredentials:
    registry.redhat.io:
      <username>: 'password'
  ContainerImageRegistryLogin: true
# 16.1-{릴리즈}에 해당하는 이미지를 로컬 레지스트리에 업로드
$ sudo openstack tripleo container image prepare -e ~/containers-prepare-parameter.yaml

$ cat ~/containers-prepare-parameter.yaml
parameter_defaults:
  ContainerImagePrepare:
  - push_destination: true
    set:
      ceph_alertmanager_image: ose-prometheus-alertmanager
      ceph_alertmanager_namespace: registry.redhat.io/openshift4
      ceph_alertmanager_tag: 4.1
      ceph_grafana_image: rhceph-4-dashboard-rhel8
      ceph_grafana_namespace: registry.redhat.io/rhceph
      ceph_grafana_tag: 4
      ceph_image: rhceph-4-rhel8
      ceph_namespace: registry.redhat.io/rhceph
      ceph_node_exporter_image: ose-prometheus-node-exporter
      ceph_node_exporter_namespace: registry.redhat.io/openshift4
      ceph_node_exporter_tag: v4.1
      ceph_prometheus_image: ose-prometheus
      ceph_prometheus_namespace: registry.redhat.io/openshift4
      ceph_prometheus_tag: 4.1
      ceph_tag: latest
      name_prefix: openstack-
      name_suffix: ''
      namespace: registry.redhat.io/rhosp-rhel8
      neutron_driver: ovn
      rhel_containers: false
      tag: '16.1'
    tag_from_label: '{version}'
  ContainerImageRegistryCredentials:
    registry.redhat.io:
      <username>: 'password'
  ContainerImageRegistryLogin: true
# 16.1에 해당하는 이미지를 로컬 레지스트리에 업로드
$ sudo openstack tripleo container image prepare -e ~/containers-prepare-parameter.yaml

 

7. 컨테이너 이미지 저장소 및 패키지 레포지 토리 HTTP 환경 설정을 확인 합니다.

$ cat /etc/httpd/conf.d/image-serve.conf
Listen 8787
<VirtualHost *:8787>
    DocumentRoot /var/lib/image-serve
    ErrorLog "/var/log/httpd/image_serve_error.log"
    ServerSignature Off
    CustomLog "/var/log/httpd/image_serve_access.log" combined
    SetEnvIf X-Forwarded-Proto https HTTPS=1
    RedirectMatch ^/$ /v2

    <Directory /var/lib/image-serve>
        # This assumes a file exists containing {} at
        # /var/lib/image-serve/index.json
        DirectoryIndex index.json

        Options FollowSymLinks MultiViews
        AllowOverride FileInfo
        Require all granted

        Header set Docker-Distribution-Api-Version registry/2.0
    </Directory>

    <LocationMatch "^/v2/.*/.*/blobs/sha256:.*$">
        SetEnvIf Request_URI "sha256:(.*)$" digest=sha256:$1
        Header set Docker-Content-Digest "%{digest}e"
        Header set ETag "%{digest}e"
        Header set Cache-Control "max-age=31536000"
        Header set Content-Type "application/octet-stream"
    </LocationMatch>
</VirtualHost>
$ cat /etc/httpd/conf.d/repo.conf 
Listen 80
<VirtualHost *:80>
  #ServerName 172.17.1.11
  DocumentRoot /data/repo/osp16
  CustomLog "logs/http_repo.log" combined
  <Directory /data/repo/osp16>
        DirectoryIndex index.html
        Options FollowSymLinks MultiViews
        AllowOverride FileInfo
        Require all granted
  </Directory>
</VirtualHost>

8. 로컬 레지트스트에 저장된 이미지를 확인 합니다.

$ curl 172.17.1.11:8787/v2/_catalog
{"repositories": ["rhosp-rhel8/openstack-panko-api", "rhosp-rhel8/openstack-designate-producer", "rhosp-rhel8/openstack-ceilometer-compute", "rhosp-rhel8/openstack-mistral-api", "rhosp-rhel8/openstack-ovn-nb-db-server", "rhosp-rhel8/openstack-memcached", "rhosp-rhel8/openstack-designate-api", "rhosp-rhel8/openstack-aodh-evaluator", "rhosp-rhel8/openstack-gnocchi-metricd", "rhosp-rhel8/openstack-aodh-notifier", "rhosp-rhel8/openstack-neutron-dhcp-agent", "rhosp-rhel8/openstack-octavia-housekeeping", "rhosp-rhel8/openstack-ovn-sb-db-server", "rhosp-rhel8/openstack-barbican-api", "rhosp-rhel8/openstack-multipathd", "rhosp-rhel8/openstack-ec2-api", "rhosp-rhel8/openstack-neutron-server-ovn", "rhosp-rhel8/openstack-mistral-event-engine", "rhosp-rhel8/openstack-swift-container", "rhosp-rhel8/openstack-cron", "rhosp-rhel8/openstack-nova-compute", "rhosp-rhel8/openstack-designate-sink", "rhosp-rhel8/openstack-gnocchi-statsd", "rhosp-rhel8/openstack-neutron-metadata-agent", "rhosp-rhel8/openstack-cinder-scheduler", "rhosp-rhel8/openstack-etcd", "rhosp-rhel8/openstack-ironic-pxe", "rhosp-rhel8/openstack-mistral-executor", "rhosp-rhel8/openstack-ceilometer-central", "rhosp-rhel8/openstack-ceilometer-notification", "rhosp-rhel8/openstack-ironic-conductor", "rhosp-rhel8/openstack-iscsid", "rhosp-rhel8/openstack-nova-novncproxy", "rhosp-rhel8/openstack-rsyslog", "rhosp-rhel8/openstack-glance-api", "rhosp-rhel8/openstack-designate-worker", "rhosp-rhel8/openstack-heat-api-cfn", "rhosp-rhel8/openstack-nova-libvirt", "rhosp-rhel8/openstack-barbican-keystone-listener", "rhosp-rhel8/openstack-mariadb", "rhosp-rhel8/openstack-designate-backend-bind9", "rhosp-rhel8/openstack-octavia-api", "rhosp-rhel8/openstack-horizon", "rhosp-rhel8/openstack-swift-account", "rhosp-rhel8/openstack-octavia-health-manager", "rhosp-rhel8/openstack-keystone", "rhosp-rhel8/openstack-neutron-metadata-agent-ovn", "rhosp-rhel8/openstack-swift-object", "rhosp-rhel8/openstack-rabbitmq", "rhosp-rhel8/openstack-haproxy", "rhosp-rhel8/openstack-manila-api", "rhosp-rhel8/openstack-heat-engine", "rhosp-rhel8/openstack-zaqar-wsgi", "rhosp-rhel8/openstack-qdrouterd", "rhosp-rhel8/openstack-neutron-openvswitch-agent", "rhosp-rhel8/openstack-nova-conductor", "rhosp-rhel8/openstack-ironic-api", "rhosp-rhel8/openstack-designate-central", "rhosp-rhel8/openstack-heat-api", "rhosp-rhel8/openstack-cinder-volume", "rhosp-rhel8/openstack-aodh-api", "rhosp-rhel8/openstack-gnocchi-api", "rhosp-rhel8/openstack-ironic-neutron-agent", "rhosp-rhel8/openstack-neutron-l3-agent", "rhosp-rhel8/openstack-ovn-northd", "rhosp-rhel8/openstack-ironic-inspector", "rhosp-rhel8/openstack-barbican-worker", "rhosp-rhel8/openstack-manila-share", "rhosp-rhel8/openstack-placement-api", "rhosp-rhel8/openstack-aodh-listener", "rhosp-rhel8/openstack-manila-scheduler", "rhosp-rhel8/openstack-ovn-controller", "rhosp-rhel8/openstack-cinder-api", "rhosp-rhel8/openstack-designate-mdns", "rhosp-rhel8/openstack-octavia-worker", "rhosp-rhel8/openstack-redis", "rhosp-rhel8/openstack-swift-proxy-server", "rhosp-rhel8/openstack-nova-compute-ironic", "rhosp-rhel8/openstack-keepalived", "rhosp-rhel8/openstack-cinder-backup", "rhosp-rhel8/openstack-collectd", "rhosp-rhel8/openstack-mistral-engine", "rhosp-rhel8/openstack-neutron-server", "rhosp-rhel8/openstack-tempest", "rhosp-rhel8/openstack-nova-api", "rhosp-rhel8/openstack-nova-scheduler", "rhceph/rhceph-4-rhel8", "rhceph/rhceph-4-dashboard-rhel8", "openshift4/ose-prometheus-node-exporter", "openshift4/ose-prometheus", "openshift4/ose-prometheus-alertmanager"]}

9. 특정 컨테이너 이미지의 태그 정보를 조회 합니다.

$ curl 172.17.1.11:8787/v2/rhosp-rhel8/openstack-panko-api/tags/list
{"name": "rhosp-rhel8/openstack-panko-api", "tags": ["16.1-49", "16.1"]}

10. /etc/yum.repos.d/ 에 repo 파일을 생성한후 패키지 리스트를 확인 합니다.

$ yum repolist
repo id                                                 repo name
ansible-2.9-for-rhel-8-x86_64-rpms                      ansible-2.9-for-rhel-8-x86_64-rpms
fast-datapath-for-rhel-8-x86_64-rpms                    fast-datapath-for-rhel-8-x86_64-rpms
openstack-16.1-for-rhel-8-x86_64-rpms                   openstack-16.1-for-rhel-8-x86_64-rpms
rhceph-4-tools-for-rhel-8-x86_64-rpms                   rhceph-4-tools-for-rhel-8-x86_64-rpms
rhel-8-for-x86_64-appstream-eus-rpms                    rhel-8-for-x86_64-appstream-eus-rpms
rhel-8-for-x86_64-baseos-eus-rpms                       rhel-8-for-x86_64-baseos-eus-rpms
rhel-8-for-x86_64-highavailability-eus-rpms             rhel-8-for-x86_64-baseos-eus-rpms

11. 마지막으로 registry.redhat.io를 private 레지스트리 정보로 치환 한후, Undercloud 및 Overcloud  배포시 치환된 로컬레지스트리에서 이미지를 참조하도록 합니다.

$ cat ~/containers-prepare-parameter.yaml
parameter_defaults:
  ContainerImagePrepare:
  - set:
      ceph_alertmanager_image: ose-prometheus-alertmanager
      ceph_alertmanager_namespace: 172.17.1.11:8787
      ceph_alertmanager_tag: 4.1
      ceph_grafana_image: rhceph-4-dashboard-rhel8
      ceph_grafana_namespace: 172.17.1.11:8787
      ceph_grafana_tag: 4
      ceph_image: rhceph-4-rhel8
      ceph_namespace: 172.17.1.11:8787
      ceph_node_exporter_image: ose-prometheus-node-exporter
      ceph_node_exporter_namespace: 172.17.1.11:8787
      ceph_node_exporter_tag: v4.1
      ceph_prometheus_image: ose-prometheus
      ceph_prometheus_namespace: 172.17.1.11:8787
      ceph_prometheus_tag: 4.1
      ceph_tag: latest
      name_prefix: openstack-
      name_suffix: ''
      namespace: 172.17.1.11:8787
      neutron_driver: ovn
      rhel_containers: false
      tag: '16.1'
    tag_from_label: '{version}-{release}'

 

[ 참고 ]
1 언더클라우드 또는 오버클라우드 배포시 컨터이너 이미지가 없는 경우에는 컨테이너 이미지를 레드햇 사이트에서 조회한 후 Private 레지스트리에 수동으로 등록할 수 있습니다. 이미지를 조회하고 각각의 이미지를 수동 등록하는 방법은 아래의 절차를 따릅니다.  

1-1. access.redhat.com에서 컨테이너 이미지를 조회하고 태그 정보를 조회합니다. 

 

1-2. 특정 컨네이너의 태깅된 이미지를 pull하여 로컬에 가져옵니다.

$ sudo podman pull registry.redhat.io/rhosp-rhel8/openstack-nova-libvirt:16.1
Trying to pull registry.redhat.io/rhosp-rhel8/openstack-nova-libvirt:16.1...
Getting image source signatures
Copying blob ec1681b6a383 skipped: already exists
Copying blob c4d668e229cd skipped: already exists
Copying blob 6bf69e4071a3 skipped: already exists
Copying blob 1e960433c1b1 done
Copying config 62e31f6e83 done
Writing manifest to image destination
Storing signatures
62e31f6e83b6c04f54809ebd1ac7adca05d3e67b900e81ed6ceea68fbd135545

1-3. 로컬에 있는 이미지를 Private 레지스트리에 push(업로드) 합니다.

$ sudo openstack tripleo container image push registry.redhat.io/rhosp-rhel8/openstack-nova-libvirt:16.1 --local
INFO[0000] created - from /var/lib/containers/storage/overlay/c48d55ebf58fab22f62cd75b2dfac6b96ef981d02a9929f3c8cdfbc1408ee53b/diff and /var/lib/containers/storage/overlay-layers/c48d55ebf58fab22f62cd75b2dfac6b96ef981d02a9929f3c8cdfbc1408ee53b.tar-split.gz (wrote 20480 bytes)

1-4. 마지막으로 정상적으로 로컬레지스트리에 업로드되었는지 컨터이너 이미지 및 태그 정보를 조회 합니다. 

$ curl 172.17.1.11:8787/v2/_catalog | jq . | grep libvirt
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3576  100  3576    0     0  3492k      0 --:--:-- --:--:-- --:--:-- 3492k
    "rhosp-rhel8/openstack-nova-libvirt",
[stack@rhel8-repo ansible]$ curl 172.17.1.11:8787/v2/rhosp-rhel8/openstack-nova-libvirt/tags/list | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    75  100    75    0     0  75000      0 --:--:-- --:--:-- --:--:-- 75000
{
  "name": "rhosp-rhel8/openstack-nova-libvirt",
  "tags": [
    "16.1"
  ]
}

2. registry.redhat.io에서 컨테이너 이미지에 액세스하기 위해서는 인증 정보가 필요합니다. 개별 사용자 인증 정보를 사용하는 대신, 레지스트리 서비스 계정을 생성하고 해당 인증 정보를 사용하여 registry.redhat.io 콘텐츠에 액세스하는 것이 좋습니다. 자세한 내용은 "Red Hat Container Registry Authentication" 에서 계정을 등록하고 토큰을 발급받는 방법을 참조 바랍니다. 

2-1 레지스트리를 사용하기 위한 계정을 생성합니다. 

3. registry.redhat.io에서 이미지를 다운 받을 수 있는 지 확인하기 위해서는 로그인이 되는지 확인 합니다.

$ sudo podman login registry.redhat.io
Username: <username>
Password: <password>
Login Succeeded!