Limites concernant la migration
Le logiciel Migrate to Containers automatise l'utilisation du kit de migration IBM WebSphere Application Server pour les binaires d'application dans votre cluster Anthos ou GKE afin de découvrir, évaluer et générer des rapports de migration et des scripts de configuration. Vous êtes seul responsable de l'obtention, de la licence et de l'utilisation du kit.
L'outil d'analyse binaire présente plusieurs limites que vous devez connaître avant de commencer à migrer des applications WAS traditionnelles. Ce document décrit ces limites et propose des solutions de migration qui vous permettent de migrer vos applications traditionnelles WAS.
Pour chaque application WAS traditionnelle à migrer, Migrate to Containers crée un fichier de script Python .py
utilisé lors de la création du conteneur d'applications. Pour contourner ces limites, vous devez modifier le script Python .py
avant de déployer un conteneur d'applications.
Le script Python .py
fait partie des artefacts de migration.
Pour savoir comment y accéder et le télécharger, consultez la section Avant de commencer.
Configuration SSL JMS non extraite
Les informations de configuration SSL de JMS ne sont pas extraites par l'outil d'analyse binaire pour la configuration de la connexion à la file d'attente et la spécification d'activation. Cette procédure explique comment migrer une configuration SSL JMS lors de l'utilisation de certificats SSL gérés de manière centralisée sur le système WAS traditionnel.
Pour en savoir plus, consultez la documentation IBM ici.
Solution pour contourner la configuration SSL
Modifiez le script Python .py
de l'application pour ajouter les informations de configuration SSL en ajoutant l'option -sslType=CENTRAL
au niveau de la spécification d'activation ou au niveau de la configuration de la connexion à la file d'attente.
Vous trouverez ci-dessous des exemples de spécification d'activation et de configuration de connexions à la file d'attente à partir du script Python .py
:
Spécification d'activation :
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"])
Configuration de connexion de la file d'attente :
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'exemple suivant montre les modifications requises pour ajouter l'option -sslType=CENTRAL
. Vous devez simplement ajouter l'une de ces spécifications.
Spécification d'activation :
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"])
Configuration de connexion de la file d'attente :
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"])
Omission des informations d'authentification LDAP
Lorsqu'une application utilise l'authentification LDAP, le script Python .py
de l'application omet ces informations LDAP. Pour contourner ce problème, modifiez le script Python .py
pour ajouter les informations nécessaires.
Les informations LDAP sont écrites dans les fichiers appname_server.xml
et appname_server_sensitiveData.xml
créés pour l'application. Ces fichiers sont écrits dans le dossier /deploy
du bucket Cloud Storage contenant les artefacts de migration.
Les informations dont vous avez besoin se trouvent dans un ensemble de variables dans ces fichiers. Par exemple, sur 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"/>
Et sur 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"/>
Modifiez le script Python .py
pour que l'application ajoute des définitions de variables et des commandes supplémentaires pour créer et configurer le fichier LDAPUserRegistry
et définissez-le comme registre par défaut dans la sécurité globale. Ajoutez les lignes suivantes après la ligne 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() . . .
Omission des informations pour le contrôle des accès basé sur les rôles (RBAC)
Lorsqu'une application WAS est configurée pour utiliser l'autorisation RBAC (Role-Based Access Control), vous devez mapper les rôles de l'application aux utilisateurs, aux groupes ou aux utilisateurs spéciaux, tels que "Tous" ou "Aucun". Cette configuration n'est pas extraite par l'outil d'analyse binaire, mais elle est requise pour que l'application fonctionne et applique l'autorisation comme prévu.
Pour configurer le contrôle des accès basé sur les rôles pour l'application, modifiez la commande d'installation dans le script Python .py
de l'application.
Vous trouverez ci-dessous un exemple de commande d'installation d'application dans le script Python .py
sans les rôles pour le mappage d'utilisateurs :
AdminApp.install('/work/config/SuperSnoop.ear', ["-node", NodeName, "-server", "server1", "-appname", "SuperSnoop.ear"])
Pour appliquer des règles de mappage de rôles, modifiez le script Python .py
de l'application afin d'ajouter l'option -MapRolesToUsers
comme indiqué ci-dessous :
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"]]])
Pour en savoir plus, consultez la documentation IBM ici.
Modifier le chargeur de classe d'application
Les applications WebSphere peuvent utiliser des fichiers JAR qui sont en conflit avec les fichiers JAR fournis par WebSphere. Pour résoudre les conflits entre les fichiers JAR, vous pouvez contrôler l'ordre du chargeur de classe pour une application ou un module WAR.
Par exemple, vous pouvez spécifier d'utiliser d'abord le chargeur de classe d'application ou un seul chargeur de classe pour l'ensemble de l'application au lieu d'utiliser à la fois le chargeur de classe WebSphere et le chargeur de classe d'application.
Les modifications apportées au chargeur de classe d'application ne sont pas extraites par l'outil d'analyse binaire. Vous devez donc modifier la commande d'installation d'application dans le script Python .py
pour que l'application applique ces modifications.
Exemple de configuration d'un serveur
Pour une application dont les paramètres de chargeur de classe sont modifiés, les modifications sont stockées dans le fichier descripteur de l'application (deployment.xml
). Par exemple, dans le descripteur de déploiement, les paramètres du chargeur de classe sont les suivants :
<?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>
Les deux sections pertinentes du descripteur de déploiement sont les valeurs SINGLE
et PARENT_LAST
que vous devez migrer manuellement. Pour appliquer les modifications du chargeur de classe, modifiez le script Python .py
.
Vous trouverez ci-dessous un exemple de commande d'installation d'application dans le 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()
Pour appliquer les modifications du chargeur de classe, modifiez le script Python .py
de l'application afin d'ajouter les paramètres, comme indiqué ci-dessous :
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()