Limitazioni della migrazione

Il software Migrate to Containers automatizza l'utilizzo del IBM WebSphere Application Server Migration Toolkit for Application Binary nel tuo cluster Anthos o GKE per individuare, valutare e generare rapporti di migrazione e script di configurazione. Tu sei l'unico responsabile dell'acquisizione, della concessione in licenza e dell'uso del toolkit.

Lo strumento di scansione binario presenta alcune limitazioni di cui è necessario essere a conoscenza prima di iniziare a eseguire la migrazione delle app tradizionali WAS. Questo documento descrive queste limitazioni e fornisce soluzioni alternative che consentono di eseguire la migrazione delle app tradizionali WAS.

Per ogni app tradizionale WAS di cui esegui la migrazione, Migrate to Containers crea un file di script Python .py utilizzato durante la creazione del container dell'app. Le soluzioni alternative per questi limiti richiedono la modifica dello script Python .py prima di eseguire il deployment di un container dell'app. Lo script Python .py fa parte degli artefatti di migrazione. Per istruzioni su come accedervi e scaricarlo, vedi Prima di iniziare.

Configurazione SSL JMS non estratta

Le informazioni della configurazione SSL di JMS non vengono estratte dallo strumento di scansione binario per la specifica di attivazione e di connessione della coda. Questa procedura descrive come eseguire la migrazione di una configurazione SSL JMS quando si utilizzano certificati SSL gestiti a livello centrale su WAS tradizionale.

Per saperne di più, consulta la documentazione di IBM qui.

Soluzione alternativa di configurazione SSL

Modifica lo script Python .py per l'app per aggiungere informazioni di configurazione SSL aggiungendo il flag -sslType=CENTRAL a livello di specifica di attivazione o di configurazione della connessione in coda.

Di seguito sono riportati degli esempi di specifica di attivazione e connessione di coda in coda nello script Python .py:

Specifica dell'attivazione:

AdminTask.createWMQActivationSpec(Node, ["-name", "BrownActivationSpecification",
 "-jndiName", "jms/BrownActivationSpecification", "-authAlias", "m4a-twas-ndNode01/BrownAuthAlias",
 "-destinationJndiName", "jms/BrownRequestQueue", "-destinationType", "javax.jms.Queue",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal", "-qmgrName", "LQM1",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT"])

Configurazione della connessione in coda:

AdminConfigVar_0=AdminTask.createWMQConnectionFactory(Node, ["-name", "BrownConnectionFactory",
 "-jndiName", "jms/BrownConnectionFactory", "-type", "QCF", "-mappingAlias",
 "DefaultPrincipalMapping", "-containerAuthAlias", "m4a-twas-ndNode01/BrownAuthAlias", "-qmgrName", "LQM1",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT"])

L'esempio seguente mostra le modifiche necessarie per aggiungere il flag -sslType=CENTRAL. Devi solo soddisfare una di queste specifiche

Specifica dell'attivazione:

AdminTask.createWMQActivationSpec(Node, ["-name", "BrownActivationSpecification",
 "-jndiName", "jms/BrownActivationSpecification", "-authAlias", "m4a-twas-ndNode01/BrownAuthAlias",
 "-destinationJndiName", "jms/BrownRequestQueue", "-destinationType", "javax.jms.Queue",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal", "-qmgrName", "LQM1",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT", "-sslType", "CENTRAL"])

Configurazione della connessione in coda:

AdminConfigVar_0=AdminTask.createWMQConnectionFactory(Node, ["-name", "BrownConnectionFactory",
 "-jndiName", "jms/BrownConnectionFactory", "-type", "QCF", "-mappingAlias",
 "DefaultPrincipalMapping", "-containerAuthAlias", "m4a-twas-ndNode01/BrownAuthAlias", "-qmgrName", "LQM1",
 "-qmgrHostname", "m4a-db2-mq.c.velos-auto-1.internal",
 "-qmgrPortNumber", "1414", "-qmgrSvrconnChannel", "CLOUD.APP.SVRCONN",
 "-wmqTransportType", "BINDINGS_THEN_CLIENT", "-sslType", "CENTRAL"])

Informazioni di autenticazione LDAP omesse

Quando un'app utilizza l'autenticazione LDAP, lo script Python .py per l'app omette le informazioni LDAP. Come soluzione alternativa, modifica lo script Python .py per aggiungere le informazioni necessarie.

Le informazioni LDAP vengono scritte nei file appname_server.xml e appname_server_sensitiveData.xml creati per l'app. Questi file vengono scritti nella cartella /deploy del bucket Cloud Storage contenente gli artefatti di migrazione.

Le informazioni necessarie sono contenute in un insieme di variabili in questi file. Ad esempio, da appname_server.xml:

<!-- The following variables, which often differ between environments
     have been extracted from the migrated configuration to allow
     for easy substitution. -->
    <variable defaultValue="9080" name="httpEndpoint_port_4"/>
    <variable defaultValue="1389" name="ldapRegistry_port_4"/>
    <variable defaultValue="m4a-db2-mq.c.my-co.internal" name="ldapRegistry_host_4"/>
    <variable defaultValue="9443" name="httpEndpoint_secure_port_4"/>
    <variable defaultValue="*" name="httpEndpoint_host_4"/>
    <variable defaultValue="ou=users,dc=example,dc=org" name="ldapRegistry_baseDN_4"/>

E di appname_server_sensitiveData.xml:

<!-- The following variables are used to replace sensitive data in the
     server.xml file for the application. -->
    <variable name="ldapRegistry_bindDN_1" defaultValue="cn=admin,dc=example,dc=org"/>
    <variable name="ldapRegistry_bindPassword_1" defaultValue="PASSWORD"/>

Modifica lo script Python .py per l'app per aggiungere definizioni delle variabili e comandi aggiuntivi per creare e configurare LDAPUserRegistry e impostarlo come registro predefinito in Global Security. Aggiungi queste righe dopo la riga NodeName=AdminControl.getNode():

. . .
NodeName=AdminControl.getNode()

# The following variables are used to replace sensitive data in the
# configuration for the application.
# ============================================================
ldapRegistry_bindDN='cn=admin,dc=example,dc=org'
ldapRegistry_bindPassword='PASSWORD'
# ============================================================

# LDAP related variables
# ============================================================
ldapRegistry_port='1389'
#ldapRegistry_host='m4a-db2-mq.c.my-co.internal'
ldapRegistry_host='35.241.207.81'
ldapRegistry_baseDN='ou=users,dc=example,dc=org'
ldapRegistry_primaryAdminId='cn=user01,ou=users,dc=example,dc=org'
ldapRegistry_userFilter='(&(uid=%v)(objectclass=posixAccount))'
# ============================================================

print 'Starting Creating LDAP Registry'
# https://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.iseries.doc/ae/rxml_7securityconfig.html#rxml_7securityconfig__SecurityConfigurationCommands.cmd7
AdminTask.configureAdminLDAPUserRegistry(['-autoGenerateServerId', 'true', '-primaryAdminId', ldapRegistry_primaryAdminId, '-ldapServerType', 'CUSTOM', '-ldapHost',
 ldapRegistry_host, '-ldapPort', ldapRegistry_port, '-baseDN', ldapRegistry_baseDN, '-bindDN', ldapRegistry_bindDN, '-bindPassword', ldapRegistry_bindPassword,
 '-userFilter', ldapRegistry_userFilter, '-groupFilter', '(&(cn=%v)(|(objectclass=groupOfNames)(objectclass=groupOfUniqueNames)))', '-userIdMap',
 '*:uid', '-groupIdMap', '*:cn', '-groupMemberIdMap', 'ibm-allGroups:member;ibm-allGroups:uniqueMember;groupOfNames:member;groupOfUniqueNames:uniqueMember'])

AdminConfig.save()

print 'Starting Creating Admin Security Settings'

# https://www.ibm.com/support/knowledgecenter/SSEQTP_8.5.5/com.ibm.websphere.base.iseries.doc/ae/rxml_7securityconfig.html#rxml_7securityconfig__SecurityConfigurationCommands.cmd8
AdminTask.setAdminActiveSecuritySettings(['-enableGlobalSecurity', 'true', '-cacheTimeout', '300', '-enforceJava2Security', 'false', '-appSecurityEnabled', 'true', '-activeUserRegistry', 'LDAPUserRegistry'])

AdminConfig.save()

. . .

Informazioni sul controllo dell'accesso basate sui ruoli (RBAC) omesse

Quando un'app WAS è configurata per utilizzare l'autorizzazione di controllo dell'accesso basata sui ruoli (RBAC), devi mappare i ruoli dell'applicazione a utenti, gruppi o utenti speciali, ad esempio Tutti o Nessuno. Questa configurazione non viene estratta dallo strumento di scansione binario, ma è obbligatoria per il funzionamento e l'applicazione dell'autorizzazione come previsto.

Per configurare RBAC per l'app, modifica il comando di installazione dell'applicazione nello script Python .py per l'app.

Di seguito è riportato un comando di installazione di applicazione di esempio nello script Python .py senza i ruoli per la mappatura degli utenti:

AdminApp.install('/work/config/SuperSnoop.ear', ["-node", NodeName, "-server", "server1", "-appname", "SuperSnoop.ear"])

Per applicare le regole di mappatura dei ruoli, modifica lo script Python .py per l'app per aggiungere il flag -MapRolesToUsers come mostrato di seguito:

AdminApp.install('/work/config/SuperSnoop.ear', ["-node", NodeName, "-server", "server1", "-appname", "SuperSnoop.ear",
 "-MapRolesToUsers", [["Manager", "AppDeploymentOption.No", "AppDeploymentOption.No",
 "cn=user02,ou=users,dc=example,dc=org", "some_group_name"]]])

Per saperne di più, consulta la documentazione di IBM qui.

Modifica del caricamento della classe di applicazioni

Le applicazioni WebSphere possono utilizzare file JAR in conflitto con i file JAR forniti da WebSphere. Per superare i conflitti con i file JAR, puoi controllare l'ordine del caricatore della classe per un'applicazione o un modulo WAR.

Ad esempio, puoi specificare di utilizzare prima il caricatore della classe dell'applicazione o un solo caricamento classe per l'intera applicazione, anziché utilizzare sia il caricatore della classe WebSphere che il caricamento della classe dell'applicazione.

Le modifiche al caricatore della classe di applicazioni non vengono estratte dallo strumento di scansione binario, pertanto devi applicare il comando di installazione delle applicazioni nello script Python .py affinché l'app possa applicare queste modifiche.

Esempio di configurazione del server

Per un'applicazione con impostazioni di caricamento della classe modificate, le modifiche vengono memorizzate nel file descrittore dell'applicazione, deployment.xml. Ad esempio, il descrittore di deployment ha le impostazioni del caricatore di classe come indicato di seguito:

<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi" xmi:id="Deployment_1614732697">
  <deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1614732697"
    deploymentId="0" startingWeight="1" binariesURL="CurrenciesServices/CurrenciesServices.ear"
    useMetadataFromBinaries="false" enableDistribution="true" warClassLoaderPolicy="SINGLE"
    createMBeansForResources="true" reloadEnabled="false" appContextIDForSecurity="href:was-nd-2Cell01/CurrenciesServices"
    filePermission=".*\.dll=755#.*\.so=755#.*\.a=755#.*\.sl=755" allowDispatchRemoteInclude="false"
    allowServiceRemoteInclude="false" asyncRequestDispatchType="DISABLED" standaloneModule="true" enableClientModule="false">
    <targetMappings xmi:id="DeploymentTargetMapping_1614732697" enable="true" target="ClusteredTarget_1614732697"/>
    <classloader xmi:id="Classloader_1614732697" mode="PARENT_LAST"/>
    <modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1614732697" deploymentId="1" startingWeight="10000" uri="CurrenciesServices.war" containsEJBContent="0">
      <targetMappings xmi:id="DeploymentTargetMapping_1614732698" target="ClusteredTarget_1614732697"/>
      <classloader xmi:id="Classloader_1614732698"/>
    </modules>
    <properties xmi:id="Property_1614732697" name="metadata.complete" value="true"/>
  </deployedObject>
  <deploymentTargets xmi:type="appdeployment:ClusteredTarget" xmi:id="ClusteredTarget_1614732697" name="Cluster1"/>
</appdeployment:Deployment>

Le due sezioni pertinenti nel descrittore del deployment sono i valori SINGLE e PARENT_LAST che devi sottoporre a migrazione manualmente. Per applicare le modifiche al caricatore di classe, modifica lo script Python .py.

Di seguito è riportato un comando di installazione di applicazione di esempio nello script Python .py:

AdminApp.install('/work/app/CurrenciesServices.war',
  [ "-node", NodeName, "-server", "server1", "-appname", "CurrenciesServices.war",
    "-contextroot", "/CurrenciesServices", "-CtxRootForWebMod",
    [["TafnitCurrenciesServices", "CurrenciesServices.war,WEB-INF/web.xml", "/CurrenciesServices"]]])

AdminConfig.save()

Per applicare le modifiche al caricatore di classe, modifica lo script Python .py per l'app per aggiungere le impostazioni come mostrato di seguito:

AdminApp.install('/work/app/CurrenciesServices.war',
  ["-node", NodeName, "-server", "server1", "-appname", "CurrenciesServices.war",
    "-contextroot", "/CurrenciesServices", "-CtxRootForWebMod",
    [["TafnitCurrenciesServices", "CurrenciesServices.war,WEB-INF/web.xml", "/CurrenciesServices"]]])

dep = AdminConfig.getid('/Deployment:CurrenciesServices.war/')
depObject = AdminConfig.showAttribute(dep, 'deployedObject')
classldr = AdminConfig.showAttribute(depObject, 'classloader')
print AdminConfig.showall(classldr)
print AdminConfig.show(depObject, 'warClassLoaderPolicy')
AdminConfig.modify(classldr, [['mode', 'PARENT_LAST']])
AdminConfig.modify(depObject, [['warClassLoaderPolicy', 'SINGLE']])

AdminConfig.save()