Openshift — красношляпые поделки +14


OpenShift


  1. Развертка Openshift.
  2. Конфигурация после установки.
  3. Создание и подключение PV.
  4. Создание и разворачивание проекта Red Hat Decision Manager (enterprise аналог kie-workbench).
  5. Создание и разворачивание проектов AMQ (red hat active mq) и postgressql c использованием персистентных хранилищ.
  6. Создание отдельных проектов для сервисов, шаблонов к ним, pipeline, интеграция с gitlab, gitlab regestry.

1. Развертка Openshift


Требования к серверам, подготовка dns серверов, список имен серверов, требования к серверам.

Минимальные требования кратко — все сервера должны иметь минимум 16Gb Ram 2 ядра и минимум 100 гигабайт для нужд docker.

dns на базе Bind должен иметь следующую конфигурацию.
dkm — мастер, dk0 — исполняющие, ifr — инфраструктурные, bln — балансировщик, shd — nfs, dkr — управляющая нода с которой происходила конфигурация кластера, так же планировалась как отдельная нода под docker regestry.

db.osh

$TTL 1h
@ IN SOA test.osh. root.test.osh. (
2008122601 ; Serial
28800 ; Refresh
14400 ; Retry
604800 ; Expire - 1 week
86400 ) ; Minimum
@ IN NS test.osh.
@ IN A 127.0.0.1
rnd-osh-dk0-t01 IN A 10.19.86.18
rnd-osh-dk0-t02 IN A 10.19.86.19
rnd-osh-dk0-t03 IN A 10.19.86.20
rnd-osh-dkm-t01 IN A 10.19.86.21
rnd-osh-dkm-t02 IN A 10.19.86.22
rnd-osh-dkm-t03 IN A 10.19.86.23
rnd-osh-ifr-t01 IN A 10.19.86.24
rnd-osh-ifr-t02 IN A 10.19.86.25
rnd-osh-ifr-t03 IN A 10.19.86.26
rnd-osh-bln-t01 IN A 10.19.86.27
rnd-osh-shd-t01 IN A 10.19.86.28
rnd-osh-dkr-t01 IN A 10.19.86.29
lb IN A 10.19.86.27
openshift IN A 10.19.86.27
api-openshift IN A 10.19.86.27
*.apps.openshift IN A 10.19.86.21
*.apps.openshift IN A 10.19.86.22
*.apps.openshift IN A 10.19.86.23

db.rv.osh

$TTL 1h
@ IN SOA test.osh. root.test.osh. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN NS test.osh.
@ IN A 127.0.0.1
18 IN PTR rnd-osh-dk0-t01.test.osh.
19 IN PTR rnd-osh-dk0-t02.test.osh.
20 IN PTR rnd-osh-dk0-t03.test.osh.
21 IN PTR rnd-osh-dkm-t01.test.osh.
22 IN PTR rnd-osh-dkm-t02.test.osh.
23 IN PTR rnd-osh-dkm-t03.test.osh.
24 IN PTR rnd-osh-ifr-t01.test.osh.
25 IN PTR rnd-osh-ifr-t02.test.osh.
26 IN PTR rnd-osh-ifr-t03.test.osh.
27 IN PTR rnd-osh-bln-t01.test.osh.
28 IN PTR rnd-osh-shd-t01.test.osh.
29 IN PTR rnd-osh-dkr-t01.test.osh.
27 IN PTR lb.test.osh.
27 IN PTR api-openshift.test.osh.
named.conf.default-zones

zone "test.osh" IN {
type master;
file "/etc/bind/db.osh";
allow-update { none; };
notify no;
};



zone "86.19.10.in-addr.arpa" {
type master;
file "/etc/bind/db.rv.osh";
};

Подготовка серверов

После подключения подписки. Включение репозиториев и установка необходимых изначально пакетов.

rm -rf /etc/yum.repos.d/cdrom.repo
subscription-manager repos --disable="*"
subscription-manager repos --enable="rhel-7-server-rpms" --enable="rhel-7-server-extras-rpms" --enable="rhel-7-server-ose-3.10-rpms" --enable="rhel-7-server-ansible-2.4-rpms"
yum -y install wget git net-tools bind-utils yum-utils iptables-services bridge-utils bash-completion kexec-tools sos psacct
yum -y update
yum -y install docker

Конфигурация хранилища докера (отдельным диском).

systemctl stop docker
rm -rf /var/lib/docker/*
echo "STORAGE_DRIVER=overlay2" > /etc/sysconfig/docker-storage-setup
echo "DEVS=/dev/sdc" >> /etc/sysconfig/docker-storage-setup
echo "CONTAINER_ROOT_LV_NAME=dockerlv" >> /etc/sysconfig/docker-storage-setup
echo "CONTAINER_ROOT_LV_SIZE=100%FREE" >> /etc/sysconfig/docker-storage-setup
echo "CONTAINER_ROOT_LV_MOUNT_PATH=/var/lib/docker" >> /etc/sysconfig/docker-storage-setup
echo "VG=docker-vg" >> /etc/sysconfig/docker-storage-setup
systemctl enable docker
docker-storage-setup
systemctl is-active docker
systemctl restart docker
docker info | grep Filesystem

Установка остальных необходимых пакетов.

yum -y install atomic
atomic trust show
yum -y  install docker-novolume-plugin
systemctl enable docker-novolume-plugin
systemctl start docker-novolume-plugin
yum -y install openshift-ansible

Создание, добавление пользователя, а также ключей.

useradd --create-home --groups users,wheel ocp
sed -i 's/# %wheel/%wheel/' /etc/sudoers
mkdir -p /home/ocp/.ssh
echo "ssh-rsa AAAAB3NzaC........8Ogb3Bv ocp SSH Key" >> /home/ocp/.ssh/authorized_keys

В случае конфликта с уже используемыми подсетями — изменить адресацию по умолчанию внутри контейнеров.

echo '{ "bip": "172.26.0.1/16" }' > /etc/docker/daemon.json
systemctl restart docker

Конфигурация network manager. (dns должен уметь froward во внешний мир)

nmcli  connection modify ens192 ipv4.dns 172.17.70.140
nmcli connection modify ens192 ipv4.dns-search cluster.local +ipv4.dns-search test.osh  +ipv4.dns-search cpgu
systemctl stop firewalld
systemctl disable firewalld
systemctl restart network

Правка в случае необходимости имени машины на полное имя.

hhh=$(cat /etc/hostname)
echo "$hhh".test.osh > /etc/hostname

После выполненных действий перезагрузить сервера.

Подготовка управляющей ноды dkr


Отличие управляющей ноды от остальных — нет необходимости подключать docker на отдельный диск.

Также есть необходимость настройки ntp.

yum install ntp -y
systemctl enable ntpd
service ntpd start
service ntpd status
ntpq -p
chmod 777 -R /usr/share/ansible/openshift-ansible/

Также нужно добавить закрытый ключ пользователю ocp.

Зайти по ssh под пользователем ocp на все ноды.

Подготовка Inventory file и развертка кластера.

host-poc.yaml

[OSEv3:children]
masters
nodes
etcd
lb
nfs
 
[OSEv3:vars]
ansible_ssh_user=ocp
ansible_become=yes
openshift_override_hostname_check=True
openshift_master_cluster_method=native
openshift_disable_check=memory_availability,disk_availability,package_availability
openshift_deployment_type=openshift-enterprise
openshift_release=v3.10
oreg_url=registry.access.redhat.com/openshift3/ose-${component}:${version}
debug_level=2
os_firewall_use_firewalld=True
openshift_install_examples=true
openshift_clock_enabled=True
openshift_router_selector='node-role.kubernetes.io/infra=true'
openshift_registry_selector='node-role.kubernetes.io/infra=true'
openshift_examples_modify_imagestreams=true
os_sdn_network_plugin_name='redhat/openshift-ovs-multitenant'
openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', 'challenge': 'true', 'kind': 'HTPasswdPasswordIdentityProvider'}]
openshift_master_htpasswd_users={'admin': '$apr1$pQ3QPByH$5BDkrp0m5iclRske.M0m.0'}
 
openshift_master_default_subdomain=apps.openshift.test.osh
openshift_master_cluster_hostname=api-openshift.test.osh
openshift_master_cluster_public_hostname=openshift.test.osh
 
 
openshift_enable_unsupported_configurations=true
 
openshift_use_crio=true
openshift_crio_enable_docker_gc=true
 
 
# registry
 
openshift_hosted_registry_storage_kind=nfs
openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
openshift_hosted_registry_storage_nfs_directory=/exports
openshift_hosted_registry_storage_nfs_options='*(rw,root_squash)'
openshift_hosted_registry_storage_volume_name=registry
openshift_hosted_registry_storage_volume_size=30Gi
 
# cluster monitoring
 
openshift_cluster_monitoring_operator_install=true
openshift_cluster_monitoring_operator_node_selector={'node-role.kubernetes.io/master': 'true'}
 
#metrics
openshift_metrics_install_metrics=true
openshift_metrics_hawkular_nodeselector={"node-role.kubernetes.io/infra": "true"}
openshift_metrics_cassandra_nodeselector={"node-role.kubernetes.io/infra": "true"}
openshift_metrics_heapster_nodeselector={"node-role.kubernetes.io/infra": "true"}
openshift_metrics_storage_kind=nfs
openshift_metrics_storage_access_modes=['ReadWriteOnce']
openshift_metrics_storage_nfs_directory=/exports
openshift_metrics_storage_nfs_options='*(rw,root_squash)'
openshift_metrics_storage_volume_name=metrics
openshift_metrics_storage_volume_size=20Gi
 
#logging
openshift_logging_kibana_nodeselector={"node-role.kubernetes.io/infra": "true"}
openshift_logging_curator_nodeselector={"node-role.kubernetes.io/infra": "true"}
openshift_logging_es_nodeselector={"node-role.kubernetes.io/infra": "true"}
openshift_logging_install_logging=true
openshift_logging_es_cluster_size=1
openshift_logging_storage_kind=nfs
openshift_logging_storage_access_modes=['ReadWriteOnce']
openshift_logging_storage_nfs_directory=/exports
openshift_logging_storage_nfs_options='*(rw,root_squash)'
openshift_logging_storage_volume_name=logging
openshift_logging_storage_volume_size=20Gi
 
#ASB
ansible_service_broker_install=true
openshift_hosted_etcd_storage_kind=nfs
openshift_hosted_etcd_storage_nfs_options="*(rw,root_squash,sync,no_wdelay)"
openshift_hosted_etcd_storage_nfs_directory=/opt/osev3-etcd
openshift_hosted_etcd_storage_volume_name=etcd-vol2
openshift_hosted_etcd_storage_access_modes=["ReadWriteOnce"]
openshift_hosted_etcd_storage_volume_size=30G
openshift_hosted_etcd_storage_labels={'storage': 'etcd'}
ansible_service_broker_local_registry_whitelist=['.*-apb$']
 
#cloudforms
#openshift_management_install_management=true
#openshift_management_app_template=cfme-template
 
 
# host group for masters
[masters]
rnd-osh-dkm-t0[1:3].test.osh
 
# host group for etcd
[etcd]
rnd-osh-dkm-t0[1:3].test.osh
[lb]
rnd-osh-bln-t01.test.osh containerized=False
 
[nfs]
rnd-osh-shd-t01.test.osh
 
[nodes]
rnd-osh-dkm-t0[1:3].test.osh openshift_node_group_name='node-config-master'
rnd-osh-ifr-t0[1:3].test.osh openshift_node_group_name='node-config-infra'
rnd-osh-dk0-t0[1:3].test.osh openshift_node_group_name='node-config-compute'

Запуск поочередно плейбуков.

ansible-playbook -i host-poc.yaml /usr/share/ansible/openshift-ansible/playbooks/prerequisites.yml
ansible-playbook -i host-poc.yaml /usr/share/ansible/openshift-ansible/playbooks/openshift-checks/pre-install.yml
ansible-playbook -i host-poc.yaml /usr/share/ansible/openshift-ansible/playbooks/deploy_cluster.yml

Если все хорошо в конце будет примерно следующие.



Правка локального файла хост для проверки после установки работу oprenshift по веб интерфейсу.

10.19.86.18 rnd-osh-dk0-t01.test.osh
10.19.86.19 rnd-osh-dk0-t02.test.osh
10.19.86.20 rnd-osh-dk0-t03.test.osh
10.19.86.21 rnd-osh-dkm-t01.test.osh 
10.19.86.22 rnd-osh-dkm-t02.test.osh
10.19.86.23 rnd-osh-dkm-t03.test.osh
10.19.86.24 rnd-osh-ifr-t01.test.osh 
10.19.86.25 rnd-osh-ifr-t02.test.osh 
10.19.86.26 rnd-osh-ifr-t03.test.osh 
10.19.86.27 rnd-osh-bln-t01.test.osh openshift.test.osh 
10.19.86.28 rnd-osh-shd-t01.test.osh
10.19.86.29 rnd-osh-dkr-t01.test.osh

Проверка по url openshift.test.osh:8443

2. Конфигурация после установки


Зайти на dkm.

oc login
oc adm policy add-cluster-role-to-user cluster-admin admin --rolebinding-name=cluster-admin

Проверить что есть возможность видеть в web интерфейсе скрытые ранее project (openshift, например).

3. Создание и подключение PV


Создание persistent volume на сервере nfs.

mkdir -p  /exports/examplpv
chmod -R 777 /exports/examplpv 
chown nfsnobody:nfsnobody -R  /exports/examplpv
echo '"/exports/examplpv" *(rw,root_squash)' >> /etc/exports.d/openshift-ansible.exports
exportfs -ar
restorecon -RvF

Добавление pv в openshift.

Необходимо создать проект oc new-project examplpv-project.

Если проект уже создан перейти в него oc project examplpv-project. Создать yaml следующего содержания.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: examplpv-ts1
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteOnce
  nfs:
    path: /exports/examplpv
    server: rnd-osh-shd-t01
  persistentVolumeReclaimPolicy: Recycle

И применить. oc apply -f filename.yaml

После выполнения

oc get pv

созданный pv будет виден в списке.

4. Создание и разворачивание проекта Red Hat Decision Manager (enterprise аналог kie-workbench)


Проверить наличие шаблонов.

oc get imagestreamtag -n openshift | grep rhdm



Добавление шаблонов — ссылку и более полное описание можно найти

unzip rhdm-7.2.1-openshift-templates.zip -d ./rhdm-7.2.1-openshift-templates

Создадим новый проект:

oc new-project rhdm72

Добавление авторизации на сервер docker registry.redhat.io:

docker login registry.redhat.io
cat ~/.docker/config.json
oc create secret generic pull-secret-name   --from-file=.dockerconfigjson=/root/.docker/config.json   --type=kubernetes.io/dockerconfigjson
oc secrets link default pull-secret-name --for=pull
oc secrets link builder pull-secret-name

Импорт imagetream, создание ключей Decision Server, Decision Central.

keytool -genkeypair -alias jboss -keyalg RSA -keystore keystore.jks -storepass mykeystorepass --dname "CN=STP,OU=Engineering,O=POC.mos,L=Raleigh,S=NC,C=RU"
oc create -f rhdm72-image-streams.yaml
oc create secret generic kieserver-app-secret --from-file=keystore.jks
oc create secret generic decisioncentral-app-secret --from-file=keystore.jks

Создание persistent volume на сервере nfs.

mkdir -p  /exports/rhdm72 
chmod -R 777 /exports/rhdm72  
chown nfsnobody:nfsnobody -R  /exports/rhdm72
echo '"/exports/rhamq72" *(rw,root_squash)' >> /etc/exports.d/openshift-ansible.exports
exportfs -ar
restorecon -RvF

Добавить pv в проект:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: rhdm72-pv1
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteMany
  nfs:
    path: /exports/rhdm72
    server: rnd-osh-shd-t01
  persistentVolumeReclaimPolicy: Recycle

В rhdm70 требовались параметры PV
accessModes:
— ReadWriteOnce
но в 7.2 требуется уже
accessModes:
— ReadWriteMany
Применить — oc apply -f filename.yaml
+ проверить что созданный pv стал доступен.

создать приложение из шаблонов согласно официальной документации.

oc new-app -f rhdm-7.2.1-openshift-templates/templates/rhdm72-authoring.yaml -p DECISION_CENTRAL_HTTPS_SECRET=decisioncentral-app-secret -p KIE_SERVER_HTTPS_SECRET=kieserver-app-secret

Приложение автоматически развернется по завершению Pull образов в docker-registry.
До этого момента статус будет таким.



В случае перехода по ссылке на образ будет следующая ошибка



Необходимо изменить url загрузки образов выбрав edit yaml с registry.redhat.io на registry.access.redhat.com



Для перехода в развернутый сервис в его web интерфейс необходимо добавить в файл hosts следующие url
на на любую из infra nodes
10.19.86.25 rnd-osh-ifr-t02.test.osh myapp-rhdmcentr-rhdm72.apps.openshift.test.osh




5. Создание и разворачивание проектов AMQ (red hat active mq) и postgressql c использованием персистентных хранилищ



RHAMQ

Создадим новый проект

oc new-project rhamq-and-pgsql

Импортируем образы в случае их отсутствия.

oc replace --force  -f https://raw.githubusercontent.com/jboss-container-images/jboss-amq-7-broker-openshift-image/72-1.1.GA/amq-broker-7-image-streams.yaml
oc replace --force -f https://raw.githubusercontent.com/jboss-container-images/jboss-amq-7-broker-openshift-image/72-1.1.GA/amq-broker-7-scaledown-controller-image-streams.yaml
oc import-image amq-broker-72-openshift:1.1
oc import-image amq-broker-72-scaledown-controller-openshift:1.0

Установка шаблонов

for template in amq-broker-72-basic.yaml amq-broker-72-ssl.yaml amq-broker-72-custom.yaml amq-broker-72-persistence.yaml amq-broker-72-persistence-ssl.yaml amq-broker-72-persistence-clustered.yaml amq-broker-72-persistence-clustered-ssl.yaml;
 do
 oc replace --force -f https://raw.githubusercontent.com/jboss-container-images/jboss-amq-7-broker-openshift-image/72-1.1.GA/templates/${template}
 done

Добавление роли сервис аккаунту.

oc policy add-role-to-user view -z default

Создание pv на сервере nfs

mkdir -p  /exports/pgmq
chmod -R 777 /exports/pgmq  
chown nfsnobody:nfsnobody -R  /exports/pgmq  
echo '"/exports/pgmq" *(rw,root_squash)' >> /etc/exports.d/openshift-ansible.exports
exportfs -ar
restorecon -RvF

Создаем yaml

pgmq_storage.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pgmq-ts1
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteOnce
  nfs:
    path:  /exports/pgmq
    server: rnd-osh-shd-t01
  persistentVolumeReclaimPolicy: Recycle

Применяем pv

oc apply -f pgmq_storage.yaml

Создаем из шаблона



готово



Для других вариантов с ssl кластеризацие и т.д. можно обратиться к документации access.redhat.com/documentation/en-us/red_hat_amq/7.2/html/deploying_amq_broker_on_openshift_container_platform

Postgresql

Создаем еще один PV аналогично тому как делали для MQ.

mkdir -p  /exports/pgmq2
chmod -R 777 /exports/pgmq2  
chown nfsnobody:nfsnobody -R  /exports/pgmq2  
echo '"/exports/pgmq2" *(rw,root_squash)' >> /etc/exports.d/openshift-ansible.exports
exportfs -ar
restorecon -RvF

pgmq_storage.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pgmq-ts2
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteOnce
  nfs:
    path:  /exports/pgmq2
    server: rnd-osh-shd-t01
  persistentVolumeReclaimPolicy: Recycle



Заполняем необходимые параметры





готово.

6. Создание отдельных проектов для сервисов, шаблонов к ним, pipeline, интеграция с gitlab, gitlab regestry


Первый делом необходимо создать проект.

oc new-project ttttt


Первично не имея шаблона можно создать в ручную приложение.
Есть два способа.
Первый просто используя готовый образ, но тогда не будет доступна версионность образов и т.д., но в некоторых случаях будет актуально.

Прежде всего, нужно получить данные для аутентификации к registry. На примере собранного образа в Gitlab это делается вот так.


Для начала надо создать секреты по доступу к docker registry — посмотреть варианты и синтаксис.

oc create secret docker-registry

Затем создадим секрет

oc create secret docker-registry gitlabreg --docker-server='gitlab.xxx.com:4567'  --docker-username='gitlab+deploy-token-1' --docker-password='syqTBSMjHtT_t-X5fiSY'  --docker-email='email'

Затем создадим наше приложение.

oc new-app --docker-image='gitlab.xxx.com:4567/oko/oko-service:latest'

Если что-то пошло не так, и образ не тянется в свойставх приложения указать секрет к нашему regestry.



Затем добавляем необходимые переменные окружения.



Готово — контейнер живой.

Затем нажмем справа edit yaml и укажем порты.



Затем чтобы получить доступ к нашему контейнеру необходимо создать route, но создать его без сервиса невозможно, потому первым делом необходимо создать сервис.

service.yaml

kind: Service
apiVersion: v1
metadata:
  name: oko-service
spec:
  type: ClusterIP
  ports:
  - port: 9000
    protocol: TCP
    targetPort: 9000
  selector:
    app: oko-service
  sessionAffinity: None
status:
  loadBalancer: {}

oc apply -f service.yaml

Создаем Route.



прописываем url в hosts на своей машине смотрящим на одну из infra nodes.



прописываем url в hosts на своей машине смотрящим на одну из infra nodes.

Готово.

Шаблон.

Шаблон создается методом выгрузки в yaml по отдельности всех компонентов которые относятся к сервису.

А именно в данном случае это secrets dc Service Route.

Посмотреть все что сделано в конкретном проекте можно

oc get all

выгрузить интересующие

oc get deploymentconfig.apps.openshift.io oko-service -o yaml

или

oc get dс oko-service -o yaml

Затем можно взять за основу любой шаблон для opensihft и интегрировать то что было получено для получения шаблона.

В данном случае результат будет выглядеть так:

template.yaml

kind: "Template"
apiVersion: "v1"
metadata:
  name: oko-service-template
 
objects:
- kind: DeploymentConfig
  apiVersion: v1
  metadata:
    name: oko-service
    annotations:
      description: "ImageStream Defines how to build the application oko-service"
    labels:
      app: oko-service
  spec:
    replicas: 1
    revisionHistoryLimit: 10
    selector:
    matchLabels:
      app: oko-service
      deploymentconfig: oko-service
    template:
      metadata:
        labels:
          app: oko-service
      spec:
        selector:
          app: oko-service
          deploymentconfig: oko-service
        containers:
        - env:
          - name: serverPort
            value: "9000"
          - name: storeLogin
            value: "iii"
          - name: storePassword
            value: "trCsm5"
          - name: storeApiUrl
            value: "http://14.75.41.20/custom-api-2.0/CustomWebService2"
          - name: storeWsdlUrl
            value: "http://14.75.41.20/custom-api-2.0/CustomWebService2/CustomWebService2.wsdl"
          - name: logLevel
            value: "INFO"
          - name: logPath
            value: "/var/log/efp-oko.log"
          ports:
          - containerPort: 9000
            name: acces
            protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /
              port: 9000
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          image: gitlab.xxx.com:4567/oko/oko-service
          imagePullPolicy: Always
          name: oko-service
        imagePullSecrets:
        - name: gitlab.xxx.com
        type: ImageChange
    strategy:
      activeDeadlineSeconds: 21600
      resources: {}
      rollingParams:
        intervalSeconds: 1
        maxSurge: 25%
        maxUnavailable: 25%
        timeoutSeconds: 600
        updatePeriodSeconds: 5
      type: Rolling
 
  triggers:
  - type: "ImageChange"
    imageChangeParams:
    automatic: true
    containerNames:
    - "oko-service"
    from:
      kind: ImageStream
      name: 'oko-service:latest'
 
- kind: ImageStream
  apiVersion: v1
  metadata:
    name: oko-service
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    labels:
      app: oko-service
      deploymentconfig: oko-service
    spec:
      dockerImageRepository: gitlab.xxx.com:4567/oko/oko-service
      tags:
      - annotations:
          openshift.io/imported-from: gitlab.xxx.com:4567/oko/oko-service
        from:
          kind: DockerImage
          name: gitlab.xxx.com:4567/oko/oko-service
        importPolicy:
          insecure: "true"
        name: latest
        referencePolicy:
          type: Source
        forcePull: true
 
- kind: Service
  apiVersion: v1
  metadata:
    name: oko-service
  spec:
    type: ClusterIP
    ports:
    - port: 9000
      protocol: TCP
      targetPort: 9000
    selector:
      app: oko-service
    sessionAffinity: None
  status:
    loadBalancer: {}
- kind: Route
  apiVersion: route.openshift.io/v1
  metadata:
    name: oko-service
  spec:
    host: oko-service.moxs.ru
    to:
      kind: Service
      name: oko-service
      weight: 100
    wildcardPolicy: None
  status:
    ingress:
    - conditions:
      host: oko-service.xxx.com
      routerName: router
      wildcardPolicy: None

Можно добавить сюда и secret-ы, в следующем примере рассмотрим вариант сервиса со сборкой на стороне openshift где secret-ы будут в шаблоне.

Второй способ

Создание проекта с полными стадиями сборки образов, простому pipeline и сборкой по Push.

Первым делом создадим новый проект.

Для начала нужно создать Buildconfig из гита (в данном случае в проекте есть три докер файла, обычный докер файл который рассчитан на docker версии 1.17 выше используя два FROM, и два отдельных dockerfile для сборки базового образа и целевого.)

Для доступа в гит если он приватный нужна авторизация. Создадим secret со следующим содержанием.

oc create secret generic sinc-git --from-literal=username=gitsinc --from-literal=password=Paaasssword123

Дадим сервис аккаунту builder доступ к нашему секрету

oc secrets link builder sinc-git

Привяжем секрет к url git

oc annotate secret sinc-git 'build.openshift.io/source-secret-match-uri-1=https://gitlab.xxx.com/*'

И наконец попробуем создать приложение из гита с ключем --allow-missing-images, так как у нас нет еще собранного базового образа.

oc new-app gitlab.xxx.com/OKO/oko-service.git --strategy=docker --allow-missing-images
Затем нужно в созданном buildconfig поправить сборку на необходимый нам dockerfile.

Правим


Также меняем параметры для того чтобы сделать базовый контейнер.

Попробуем сделать из этого одного Buildcconfig два Под базовый образ выгрузив в yaml и забрав необходимое.

На выходе можно получить два вот таких шаблона.

bc-py

kind: "BuildConfig"
apiVersion: "v1"
metadata:
  name: "oko-service-build-pyton-ml"
  labels:
    app: oko-service
spec:
  completionDeadlineSeconds: 2400
  triggers:
    - type: "ImageChange"
  source:
    type: git
    git:
      uri: "https://gitlab.xxx.com/OKO/oko-service.git"
      ref: "master"
    sourceSecret:
      name: git-oko
  strategy:
    type: Docker
    dockerStrategy:
      dockerfilePath: Dockerfile-python-ml
      forcePull: true
  output:
    to:
      kind: "ImageStreamTag"
      name: "python-ml:latest"

bc-oko

kind: "BuildConfig"
apiVersion: "v1"
metadata:
  name: "oko-service-build"
  labels:
    app: oko-service
spec:
  completionDeadlineSeconds: 2400
  triggers:
    - type: "ImageChange"
  source:
    type: git
    git:
      uri: "https://gitlab.xxx.xom/OKO/oko-service.git"
      ref: "master"
    sourceSecret:
      name: git-oko
  strategy:
    type: Docker
    dockerStrategy:
      dockerfilePath: Dockerfile-oko-service
      from:
        kind: ImageStreamTag
        name: "python-ml:latest"
      forcePull: true
      env:
        - name: serverPort
          value: "9000"
        - name: storeLogin
          value: "iii"
        - name: storePassword
          value: "trCsn5"
        - name: storeApiUrl
          value: "http://14.75.41.20/custom-api-2.0/CustomWebService2"
        - name: storeWsdlUrl
          value: "http://14.75.41.20/custom-api-2.0/CustomWebService2/CustomWebService2.wsdl"
        - name: logLevel
          value: "INFO"
        - name: logPath
          value: "/var/log/efp-oko.log"
  output:
    to:
      kind: "ImageStreamTag"
      name: "oko-service:latest"


Также нам понадобится создать deploymentconfig два imagestream и для завершения развертки service и route.
Я предпочел не плодить отдельно все конфиги, а сразу делать шаблон, включающий все компоненты для сервиса. за основу взяв предыдущий шаблон для варианта без сборки.

template
kind: "Template"
apiVersion: "v1"
metadata:
  name: oko-service-template
 
objects:
- kind: Secret
  apiVersion: v1
  type: kubernetes.io/basic-auth
  metadata:
    name: git-oko
    annotations:
      build.openshift.io/source-secret-match-uri-1: https://gitlab.xxx.com/*
  data:
    password: R21ZFSw==
    username: Z2l0cec==
 
- kind: "BuildConfig"
  apiVersion: "v1"
  metadata:
    name: "oko-service-build-pyton-ml"
    labels:
      app: oko-service
  spec:
    completionDeadlineSeconds: 2400
    triggers:
      - type: "ImageChange"
    source:
      type: git
      git:
        uri: "https://gitlab.xxx.com/OKO/oko-service.git"
        ref: "master"
      sourceSecret:
        name: git-oko
    strategy:
      type: Docker
      dockerStrategy:
        dockerfilePath: Dockerfile-python-ml
        forcePull: true
    output:
      to:
        kind: "ImageStreamTag"
        name: "python-ml:latest"
 
- kind: "BuildConfig"
  apiVersion: "v1"
  metadata:
    name: "oko-service-build"
    labels:
      app: oko-service
  spec:
    completionDeadlineSeconds: 2400
    triggers:
      - type: "ImageChange"
    source:
      type: git
      git:
        uri: "https://gitlab.xxx.com/OKO/oko-service.git"
        ref: "master"
      sourceSecret:
        name: git-oko
    strategy:
      type: Docker
      dockerStrategy:
        dockerfilePath: Dockerfile-oko-service
        from:
          kind: ImageStreamTag
          name: "python-ml:latest"
        forcePull: true
        env:
          - name: serverPort
            value: "9000"
          - name: storeLogin
            value: "iii"
          - name: storePassword
            value: "trC"
          - name: storeApiUrl
            value: "http://14.75.41.20/custom-api-2.0/CustomWebService2"
          - name: storeWsdlUrl
            value: "http://14.75.41.20/custom-api-2.0/CustomWebService2/CustomWebService2.wsdl"
          - name: logLevel
            value: "INFO"
          - name: logPath
            value: "/var/log/efp-oko.log"
    output:
      to:
        kind: "ImageStreamTag"
        name: "oko-service:latest"
 
- kind: DeploymentConfig
  apiVersion: v1
  metadata:
    name: oko-service
    annotations:
      description: "ImageStream Defines how to build the application oko-service"
    labels:
      app: oko-service
  spec:
    replicas: 1
    revisionHistoryLimit: 10
    selector:
    matchLabels:
      app: oko-service
      deploymentconfig: oko-service
    template:
      metadata:
        labels:
          app: oko-service
      spec:
        selector:
          app: oko-service
          deploymentconfig: oko-service
        containers:
        - env:
          - name: serverPort
            value: "9000"
          - name: storeLogin
            value: "iii"
          - name: storePassword
            value: "trCsn5"
          - name: storeApiUrl
            value: "http://14.75.41.20/custom-api-2.0/CustomWebService2"
          - name: storeWsdlUrl
            value: "http://14.75.41.20/custom-api-2.0/CustomWebService2/CustomWebService2.wsdl"
          - name: logLevel
            value: "INFO"
          - name: logPath
            value: "/var/log/efp-oko.log"
          ports:
          - containerPort: 9000
            name: acces
            protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /
              port: 9000
              scheme: HTTP
            initialDelaySeconds: 5
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          image: docker-registry.default.svc:5000/oko-service-p/oko-service
          imagePullPolicy: Always
          name: oko-service
        type: ImageChange
    strategy:
      activeDeadlineSeconds: 21600
      resources: {}
      rollingParams:
        intervalSeconds: 1
        maxSurge: 25%
        maxUnavailable: 25%
        timeoutSeconds: 600
        updatePeriodSeconds: 5
      type: Rolling
 
  triggers:
  - type: "ImageChange"
    imageChangeParams:
    automatic: true
    containerNames:
    - "oko-service"
    from:
      kind: ImageStreamTag
      name: 'oko-service:latest'
 
- kind: ImageStream
  apiVersion: v1
  metadata:
    name: oko-service
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    labels:
      app: oko-service
      deploymentconfig: oko-service
    spec:
      dockerImageRepository: ""
      tags:
      - annotations:
          openshift.io/imported-from: oko-service
        from:
          kind: DockerImage
          name: oko-service
        importPolicy:
          insecure: "true"
        name: latest
        referencePolicy:
          type: Source
 
- kind: ImageStream
  apiVersion: v1
  metadata:
    name: python-ml
    spec:
      dockerImageRepository: ""
      tags:
      - annotations:
          openshift.io/imported-from: oko-service-build
        from:
          kind: DockerImage
          name: python-ml
        importPolicy:
          insecure: "true"
        name: latest
        referencePolicy:
          type: Source
 
 
- kind: Service
  apiVersion: v1
  metadata:
    name: oko-service
  spec:
    type: ClusterIP
    ports:
    - port: 9000
      protocol: TCP
      targetPort: 9000
    selector:
      app: oko-service
    sessionAffinity: None
  status:
    loadBalancer: {}
- kind: Route
  apiVersion: route.openshift.io/v1
  metadata:
    name: oko-service
  spec:
    host: oko-service.xxx.com
    to:
      kind: Service
      name: oko-service
      weight: 100
    wildcardPolicy: None
  status:
    ingress:
    - conditions:
      host: oko-service.xxx.com
      routerName: router
      wildcardPolicy: None

Данный шаблон сделан для проекта oko-service-p поэтому нужно учитывать это.
Можно использовать переменные для автоматической подстановки нужных значений.
Еще раз повторюсь что базовый Yaml можно получить выгрузив данные с помощью oc get… -o yaml

Использовать данный шаблон для развертки можно так

oc process -f oko-service-templatebuild.yaml | oc create -f -

Затем создадим Pipeline

oko-service-pipeline.yaml

kind: "BuildConfig"
apiVersion: "v1"
type: "GitLab"
gitlab:
  secret: "secret101"
metadata:
  name: "oko-service-sample-pipeline"
spec:
  strategy:
    jenkinsPipelineStrategy:
      jenkinsfile: |-
        // path of the template to use
        // def templatePath = 'https://raw.githubusercontent.com/openshift/nodejs-ex/master/openshift/templates/nodejs-mongodb.json'
        // name of the template that will be created
        def templateName = 'oko-service-template'
        // NOTE, the "pipeline" directive/closure from the declarative pipeline syntax needs to include, or be nested outside,
        pipeline {
        agent any
        environment {
        DEV_PROJECT = "oko-service";
        }
        stages {
        stage('deploy') {
        steps {
        script {
            openshift.withCluster() {
                openshift.withProject() {
                     echo "Hello from project ${openshift.project()} in cluster ${openshift.cluster()}"
                     def dc = openshift.selector('dc', "${DEV_PROJECT}")
                     openshiftBuild(buildConfig: 'oko-service-build', waitTime: '3000000')
                     openshiftDeploy(deploymentConfig: 'oko-service', waitTime: '3000000')
                }
            }
        }
        }
        }
             } // stages
        } // pipeline
      type: JenkinsPipeline
 
  triggers:
    - type: GitLab
      gitlab:
        secret: ffffffffk

После применения конфигурации Pipeline, запустив

oc describe buildconfig oko-service-sample-pipeline

Можно получить url для webhook в gitlab.



Секрет заменить на указанный секрет в конфиге.


Так же после применения Pipeline openshift сам начнет установку jenkins в проекте для запуска Pipeline. Первичный запуск длительный, так что необходимо подождать некоторое время.

Затем в Gitlab в нашем проекте:



Заполнить Url, secret, убрать Enable SSL verificationю И наш webhook готов.

Можно сделать тестовый push и посмотреть на ход ведения сборки



Не забудьте прописывать в host url чтобы попасть в тот же jenkins на infranode.



Так же можно посмотреть ход сборки.



P.S. Надеюсь данная статья поможет многим понять как и с чем едят openshift, разяснит многие не очевидные с первого взгляда моменты.

P.S.S. некоторые решения для решения некоторых проблем


Проблемы с запуском билда сборки и т.д.
— создать сервис аккаунт для проекта

oc create serviceaccount oko-serviceaccount
oc adm policy add-scc-to-user privileged system:serviceaccount:Имя_вашего_проекта:oko-serviceaccount
oc adm policy add-scc-to-group anyuid system:authenticated
oc adm policy add-scc-to-user anyuid system:serviceaccount:Имя_вашего_проекта:oko-serviceaccount

Проблемы с подвисом проекта и не удалением его
— скрипт принудительного завершения (болезнь врожденная)

for i in $(oc get projects  | grep Terminating| awk '{print $1}'); do echo $i; oc get serviceinstance -n $i -o yaml | sed "/kubernetes-incubator/d"| oc apply -f - ; done

Проблемы с загрузкой образов.

oc adm  policy add-role-to-group system:image-puller system:serviceaccounts:Имя_вашего_проекта
oc adm policy add-role-to-user system:image-puller system:serviceaccount:Имя_вашего_проекта::default
oc adm  policy add-role-to-group system:image-puller system:serviceaccounts:Имя_вашего_проекта
oc policy add-role-to-user system:image-puller system:serviceaccount:Имя_вашего_проекта::default
oc policy add-role-to-group system:image-puller system:serviceaccounts:Имя_вашего_проекта



Также переопределить разрешения на папку для registry на nfs. (в логах registry ошибки на запись, билд же висит на пуше).

chmod 777 -r /exports/registry/docker/registry/
chmod -R 777 /exports/registry/docker/registry/
chown nfsnobody:nfsnobody -R  /exports/registry/
сhown -R 1001  /exports/registry/
restorecon -RvF
exportfs -ar




К сожалению, не доступен сервер mySQL