Acerca del contrato

La dirección IBM Cloud Hyper Protect Virtual Servers para VPC está obsoleta. A partir del 28 de febrero de 2026, no se podrán crear nuevas instancias. Las instancias existentes se admitirán hasta el 20 de febrero de 2027. Se eliminarán todas las instancias que aún existan en esa fecha. Puede redistribuir sus cargas de trabajo utilizando IBM Confidential Computing Container Runtime(antes conocido como Hyper Protect Virtual Servers) o IBM Confidential Computing Container Runtime para soluciones de virtualización Red Hat(anteriormente conocido como Hyper Protect Container Runtime para soluciones de virtualización Red Hat). Para obtener información sobre la migración de datos, consulte la Guía de migración. Para más información, consulte el anuncio de eliminación de servicios.

Cuando se crea una IBM CloudHyper Protect Virtual Servers para una instancia VPC con la imagen IBM Hyper Protect Container Runtime (HPCR), se debe especificar un contrato como parte del campo Datos de usuario.

¿Qué es un contrato?

El contrato es un archivo de definición en el formato YAML que es específico de la instancia de Hyper Protect Virtual Servers para VPC. El usuario de nube debe crear este archivo como requisito previo para crear una instancia. Después de crear este archivo, se debe pasar como una entrada como parte del campo Datos de usuario cuando se crea una instancia. No puede crear una instancia sin un contrato válido. Si crea una instancia sin un contrato, el despliegue se inicia y, a continuación, falla, y la instancia pasa a un estado de conclusión. El contrato es específico de la creación de una instancia de Hyper Protect Virtual Servers para VPC y es una extensión de la tecnología IBM Secure Execution by Hyper Protect.

Si la carga de trabajo revela los tokens descifrados a través de SSH o API REST, entonces los datos descifrados contienen tanto la carga de trabajo como los secretos del entorno. Sin embargo, no contiene las semillas que se utilizaron para el cifrado de volumen.

Secciones de contrato

Un archivo de contrato puede tener las siguientes cuatro secciones de alto nivel válidas, de las cuales las secciones workload y env son obligatorias.

  • workload es una sección obligatoria.
  • env es una sección obligatoria.
  • attestationPublicKey es una sección opcional. Puede proporcionar una clave RSA pública como parte del contrato, que se utiliza para cifrar el documento de testificación y el atributo debe denominarse attestationPublicKey.
  • envWorkloadSignature es una sección opcional y contiene la firma de las otras secciones del contrato.

Las dos secciones principales de un contrato son las secciones workload y env. Estas dos secciones son necesarias porque la información que se añade al contrato proviene de dos personas diferentes, a saber, la "carga de trabajo" y la persona "deployer".

La persona de carga de trabajo proporciona información sobre el contenedor (o carga de trabajo) que se debe poner en marcha en la instancia de Hyper Protect Virtual Servers para VPC. Incluye información sobre el nombre del contenedor, el Container Registry donde reside, credenciales del Container Registry, el resumen de la imagen, la información del servidor notario (requerida para la validación de la imagen), las variables de entorno que deben pasarse al contenedor y el archivo de composición de la ventana acoplable o los descriptores del Pod con la información del contenedor.

Si utiliza un archivo de composición de docker, sólo se da soporte a un contenedor. Los descriptores de pod dan soporte a uno o varios contenedores.

El perfil del implementador trabaja en estrecha colaboración con IBM Cloud. Esta persona recibe la información de carga de trabajo (preferiblemente una sección de carga de trabajo cifrada) de la persona de carga de trabajo. A continuación, el desplegador crea la sección env del contrato. La env sección contiene información específica sobre el entorno IBM Cloud. Normalmente, es información que la persona de la carga de trabajo no tiene y no necesita saber. Un ejemplo es información sobre la instancia de registro de IBM Cloud, que crea la persona desplegadora, antes de añadir información a la sección env del contrato.

La sección de carga de trabajo

Esta sección es una de las más importantes del contrato. La sección workload puede tener varias subsecciones y la finalidad de las subsecciones es proporcionar la información necesaria para generar la carga de trabajo. La sección workload es la sección padre que puede tener las subsecciones siguientes:

  • type: carga de trabajo. Esta subsección es obligatoria.
  • auths. Esta subsección es opcional.
  • compose (para contenedor único) o play (para contenedor único o varios contenedores). Son mutuamente excluyentes; debe existir una de las secciones.
  • images. Esta subsección es opcional.
  • volumes. Esta subsección es opcional.

El fragmento de código siguiente muestra un ejemplo de alto nivel de la sección de carga de trabajo del contrato. El mínimo que necesita una sección de carga de trabajo es la sección de composición. Las otras secciones se pueden añadir basándose en el requisito.

workload: |
  type: workload
  auths:
    <registry url>:
      password: <password>
      username: <user name>
    <registry url>:
      password: <password>
      username: <user name>
  compose:
    archive: <base64 encoded of tgz of docker-compose.yaml>
  images:
    dct:
      <docker image name (without the tag, an example is docker.io/redbookuser/s390x:)>:
        notary: "<notary URL>"
        publicKey: <docker content trust signed public key>
      <docker image name>:
        notary: "<notary URL>"
        publicKey: <docker content trust signed public key>
  volumes:
    <volume key>:
      mount: "<data volume mount path>"
      seed: "<Passphrase of the LUKS encryption>"
      filesystem: "ext4"

La subsección auths

La sección auths consta de información sobre el registro del contenedor. Si se utiliza una imagen pública en el contrato, no necesita la sección auths porque no se necesitan credenciales. La subsección auths sólo es necesaria si las imágenes de contenedor son privadas. Esta subsección no tiene ninguna información de imagen, como se muestra en el ejemplo siguiente. Esta subsección debe contener el nombre del registro de imágenes y las credenciales como username-password para el mismo. La clave debe ser el nombre de host del Container Registry o la siguiente cadena para el registro de Docker predeterminado:

https://index.docker.io/v1/

El siguiente fragmento de código muestra un ejemplo para IBM Cloud Registry. Para obtener más información sobre cómo utilizar la clave de API, consulte Utilización del software de cliente para autenticarse en la automatización.

auths:
  us.icr.io:
    password: <apikey>
    username: iamapikey

La subsección compose

Consta de una subsección de archivado. La subsección de archivado contiene el archivo TGZ codificado en Base64 del archivo docker-compose.yaml. Puesto que la imagen de Hyper Protect Container Runtime utiliza Docker Engine y Docker Compose para iniciar el contenedor, primero se debe crear la información sobre el contenedor utilizando un archivo docker-compose estándar. Este archivo se archiva y se codifica c Base64, y el resultado de este proceso se proporciona como el valor de la subsección de archivo, dentro de la sección de redacción. Para obtener más información, consulte Visión general de Docker Compose.

Los puntos de montaje especificados bajo la información de volúmenes del archivo docker-compose pueden estar alineados con el punto de montaje de volumen especificado en la sección de carga de trabajo del contrato.

No se da soporte a la ejecución de una compilación como parte de un archivo de composición de docker. Asegúrese de que el archivo de composición de docker no tenga una sección build.

Los formatos "yaml" y "yml" están soportados para el archivo docker-compose. Consulta el siguiente ejemplo de un archivo docker-compose.

version: '3'
services:
  nginx:
    image: nginx@sha256:e73ba8654ba7fd1834e78a3d4e9d72ffaaa3372d42996af5c34ba3e1abc293e8
    privileged: true
    user: 0:0
    restart: always
    ports:
    - 80:80

Existen casos de uso en los que no se conoce el registro cuando la sección de carga de trabajo está precodificada. Por ejemplo, cuando el proveedor de carga de trabajo desea permitir que el implementador utilice un espejo de registro o un registro privado Container Registry, es posible anular dinámicamente el registro y las credenciales de extracción. Este esfuerzo debe ser coordinado entre el proveedor de la carga de trabajo y el implementador. Para obtener más información, consulte Utilización de una referencia de registro dinámico.

Complete los siguientes pasos para obtener el Base64 archivo de almacenamiento codificado. El Base64 La salida está disponible en el compose.b64 archivo. Vaya a <COMPOSE_Folder> y ejecute los mandatos siguientes:

tar czvf compose.tgz docker-compose.yml
base64 -w0 compose.tgz > compose.b64

Asegúrese de que el archivo tgz de redacción contenga solo directorios y archivos normales. Los enlaces o conductos no están soportados.

Copie el contenido de compose.b64 como un valor de compose-> archive.

compose:
  archive: <paste the content of compose.b64 >

Para este ejemplo, obtendría una respuesta similar a la salida siguiente:

compose:
  archive: H4sIAKOFmGIAA+2RTW6DMBBGs84pRuyB8Q8k+DIRwZOGtmBkkyrcvhgnLVVV1EWkqhJv4ZHt8ednWZvqhWxcmaYzjpKhed08HETMpQRfd3k2VeRhPpEJCUxymTPkIuOALBOIG8DHq3zn4vrSjiqdLY/nsv+xb2w7nRZywlPgo/4THNm3uiKntgCWdO1aowmZnwLUTflECpwo8Jpu9NyZ2zvQgdADFEudoXyQzSu+fPPzseSvedo6qjV7mDa2anZbdH8totL6somtUlvX8K4SJshDsFKU2NmFvAZuMc9U37wceeys+Y6BI8Fi6+6vxK5RS+YFDh6RNu//tuVlZWVJd4BcjKckQAIAAA=

La subsección play

En el play subsección, puede definir la carga de trabajo a través de Descriptores de pod. Cada pod puede contener una o más definiciones de contenedor. Los descriptores pueden proporcionarse de una de las siguientes formas:

  • En formato YAML sin formato en la subsección resources de play. Esta sección es una matriz de descriptores y da soporte a dos tipos de descriptores: Pods y ConfigMaps.

    El ejemplo siguiente ilustra cómo utilizar la sección resources:

    workload: |
      type: workload
      play:
        resources:
          - apiVersion: v1
            kind: Pod
            metadata:
              name: busybox
            spec:
              containers:
              - name: main
                image: ...
                command:
                - printenv
                envFrom:
                - configMapRef:
                    name: contract.config.map
                    optional: false
              restartPolicy: Never
    

    El siguiente ejemplo ilustra cómo utilizar initcontainers con la sección resources:

    workload: |
      type: workload
      play:
        resources:
          - apiVersion: v1
            kind: Pod
            metadata:
              name: busybox
            spec:
              initContainers:
              - name: attest
                image: ...
                volumeMounts:
                - mountPath: /var/hyperprotect
                  name: datavolume
              containers:
              - name: main
                image: ...
                command:
                - printenv
                envFrom:
                - configMapRef:
                    name: contract.config.map
                    optional: false
              restartPolicy: Never
    
  • En el archive subsección de play, el archivo es un Base64 archivo tar codificado y comprimido con gzip. Los pods o ConfigMaps se representan como archivos YAML, en el nivel superior de este archivo tar. El archivo también puede contener archivos adicionales y todos los archivos se extraen al sistema de archivos del host antes de que se inicien los Pods. El directorio de trabajo actual es el directorio en el que se han extraído los archivos, por lo que es posible utilizar un montaje de volumen con una vía de acceso relativa para montar los archivos o directorios del archivo YAML.

    Ejemplo:

    workload: |
      type: workload
      play:
        archive: ${COMPOSE_VALUE}
      auths:
        us.icr.io:
          username: iamapikey
          password: Eqx0TS....
      volumes:
        test-volume:
          mount: /var/hyperprotect
          seed: "workload_phrase"
          filesystem: ext4
    
  • En un formato de plantilla en la subsección templates de play. Esta sección es una matriz de descriptores en formato YAML. Las cápsulas o ConfigMaps pueden tener puntos de variabilidad (POV) que no se conocen en el momento de redactar los descriptores. Estos POV pueden representarse como plantillas y los valores se completan en el momento de la implementación a partir de la información del contrato. Utilizamos go templates como sintaxis de plantillas, que es la misma que se utiliza para diagramas de Helm, para que las plantillas se puedan intercambiar fácilmente con k8s. Damos soporte a los siguientes objetos de Built-In:

    • Entorno: este objeto contiene las variables de entorno fusionadas entre la carga de trabajo y la sección de entorno. El objeto está disponible como {{ .Env }}.

    Ejemplo:

    workload: |
      type: workload
      auths:
       docker.io:
        password: <password>
        username: test
      play:
        templates:
          - apiVersion: v1
            kind: Pod
            metadata:
              name: busybox
            spec:
              initContainers:
              - name: initcontainer
                image: docker.io/library/init-config@sha256:b1306efee704017b0e02efadc011d374063a4e9c47b86bdc57744fc3f0666383
              containers:
              - name: main
                image: "{{ .Env.REGISTRY }}/hpse-docker-busybox-s390x@sha256:732efa374f1e6c964caeacab0bcb370385ee386041a14d4a32176462e3f75c7b"
                command:
                - printenv
                envFrom:
                - configMapRef:
                    name: contract.config.map
                    optional: false
              restartPolicy: Never
    env: |
      type: env
      logging:
        logRouter:
          hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
          iamApiKey: <iamApiKey of the service instance> / xxxx
          port: 443
      env:
        REGISTRY: docker-io/test
    

    La expresión {{ .Env REGISTRY }} hace referencia a la variable de entorno REGISTRY que en este ejemplo se define en la sección env del contrato.

    Las plantillas deben ser YAMLválidas, por lo que se debe escapar una expresión de sustitución si aparece como la primera parte de una serie. De lo contrario, choca con el mapeo de bloques sintaxis. Esto es diferente de las plantillas de control, en las que las expresiones se aplican a la representación textual del documento en lugar de a la representación del modelo.

Variables de entorno

En el contrato, puede definir variables de entorno en las secciones workload y env. Ambos conjuntos de variables se fusionan junto con workload que tiene prioridad. Los pods utilizan el concepto de un ConfigMap para definir la configuración, por lo que HPCR representa las secciones de entorno fusionadas como un ConfigMap especial denominado contract.config.map. El ejemplo siguiente monta todas las variables de entorno del contrato en el contenedor:

apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - name: main
    image: ...
    command:
    - printenv
    envFrom:
    - configMapRef:
        name: contract.config.map
        optional: false
  restartPolicy: Never

Comunicación de pod

  • Contenedor a contenedor

    Los contenedores dentro de un Pod se comunican entre sí a través de localhost. Cada contenedor debe escuchar en un puerto diferente porque comparten la dirección IP por diseño.

  • Pod a host

    Por lo general, un Pod necesita exponer al menos uno de sus contenedores al host para que el contenedor sea accesible a través de la dirección IP en el host a través de un puerto mapeado. Para este caso de uso, utilice el hostPort Característica en un contenedor. Tenga en cuenta que esto no es una buena práctica en el mundo de la arquitectura orientada a servicios ( Kubernetes ), en la que se utilizaría un servicio en su lugar.

    Especifique hostPort y containerPort explícitamente. Si sólo especifica containerPort, los puertos no están enlazados.

    Ejemplo:

    apiVersion: v1
    kind: Pod
    metadata:
        name: nginx-with-busybox
    spec:
        containers:
            - image: ...
              name: frontend
              ports:
                - containerPort: 80
                  hostPort: 80
              volumeMounts:
                - mountPath: /etc/nginx
                  name: local-frontend
                  readOnly: true
            - command:
                - httpd
                - -vv
                - -f
                - -p
                - "8080"
                - -h
                - /www
              image: ...
              name: backend
              volumeMounts:
                - mountPath: /www
                  name: local-backend
                  readOnly: true
        volumes:
            - hostPath:
                path: ./www
                type: Directory
              name: local-backend
            - hostPath:
                path: ./nginx
                type: Directory
              name: local-frontend
    
  • Pod a pod

    Para llegar de un pod a otro, exponga un hostPort en el pod de destino. A continuación, el pod de origen puede realizar una solicitud al host en el puerto expuesto para obtener el pod de destino.

    El Pod de origen puede encontrar la dirección IP del host mediante el siguiente comando:

    ip route | awk '/default/ { print $3 }'
    

Volúmenes

Para Hyper Protect Container Runtime, los volúmenes se gestionan mediante la sección volumes del contrato. Según esta información, HPCR cifra y monta dispositivos de bloque externos en el host. Para montar estos volúmenes en el pod, utilice la opción de montaje hostPath en el volumen.

Ejemplo:

apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - name: main
    image: ...
    volumeMounts:
    - name: test-volume
      readOnly: true
      mountPath: /fromHost
  volumes:
  - name: test-volume
    hostPath:
      path: /var/hyperprotect
      type: Directory
  restartPolicy: Never

El campo volumes aquí define los datos del host que se van a montar en el pod. Es diferente de volumes en el contrato de HPCR.

La subsección images

Docker ha anunciado la retirada de Docker Content Trust (DCT). Dado que DCT se basa en el legado Notario v1 marco, que ya no se mantiene activamente, no se considera una solución sostenible o preparada para el futuro para la firma y verificación de imágenes. En consecuencia, se anima a los clientes a abandonar la tecnología DCT y adoptar tecnologías de verificación y firma por imagen conformes con la OCI que se ajusten a las normas actuales de seguridad de la cadena de suministro. Puede migrar imágenes de contenedor a IBM Cloud Container Registry (ICR). ICR se integra con Red Hat Signing Service (RHS) como raíz de firma de confianza, lo que proporciona un modelo de confianza respaldado por el proveedor y se ajusta a las mejores prácticas actuales de seguridad de contenedores y cadena de suministro. Para más información, consulte Retirar Docker Content Trust.

La subsección images sólo está pensada para una imagen firmada.

Imágenes descritas por docker compose

La imagen de contenedor que se lista en el archivo docker-compose se puede firmar o no se puede firmar utilizando Docker Content Trust (DCT).

El siguiente ejemplo muestra una imagen URL:

<container registry>/<username or namespace>/<image name>
eg- us.icr.io/mynamespace/my-haproxy:

A continuación se muestra un ejemplo de un URL notarial:

notary: "https://notary.us.icr.io"

publicKey es la clave pública correspondiente por la que se firma la imagen utilizando DCT. Utiliza el siguiente comando para obtener la clave pública:

cat ~/.docker/trust/tuf/us.icr.io/<username>/<imagename>/metadata/root.json

El siguiente fragmento es un ejemplo:

images:
  dct:
    us.icr.io/mynamespace/my-haproxy:
      notary: "https://notary.us.icr.io"
      publicKey: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpRENDQVM2Z0F3SUJBZ0lSQUxCMXBPYlpEQlRRc09GSFlxazMzaWd3Q2dZSUtvWkl6ajBFQXdJd0tqRW8KTUNZR0ExVUVBeE1mZFhNdWFXTnlMbWx2TDNCeVlXSm9ZWFF4TWpNdmJYa3RhR0Z3Y205NGVUQWVGdzB5TWpBMApNVE14TURFd01ETmFGdzB6TWpBME1UQXhNREV3TUROYU1Db3hLREFtQmdOVkJBTVRIM1Z6TG1samNpNXBieTl3CmNtRmlhR0YwTVRJekwyMTVMV2hoY0hKdmVIa3dXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CQndOQ0FBU1AKWGsrelE2MlFZNjI3MWQ1cTBMZHY3SGc3QzZkMGZOUlRsQmJXekhOWWFDZzlpU0piYnVNdjVBY0JmMjlqQi83eApqYzhzVitxMksyemtkTHV4QWxGWm96VXdNekFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJCkt3WUJCUVVIQXdNd0RBWURWUjBUQVFIL0JBSXdBREFLQmdncWhrak9QUVFEQWdOSUFEQkZBaUIzd0JTa0IxaXAKZHZZYlBMbFBmS3RZT0hsYnZzUllKa0FZM2hnY0xuNWhwQUloQUt6cmhsU3p4K1I5bmdtMTBlZVkyaFNCRmgrawpMWHp6SFkwaktTVzhyM1FhCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K

Para una imagen que no está firmada, no es necesaria ninguna entrada en la subsección de imágenes. Sin embargo, para imágenes sin firmar, se requiere un resumen. Sigue estos pasos para obtener el resumen:

  1. Inicia sesión en el panel de control de Container Registry.
  2. Abra la imagen.
  3. Pulse Etiqueta y, a continuación, pulse Resumen.

Después de obtener el resumen, añada este resumen en el archivo docker-compose.yaml. Consulte el ejemplo siguiente:

services:
  <imagename>:
    image: s390x/redis@sha256:db467ab5c53bdeef65762a7534e26fecb94a0f218bd38afd2eaba1a670c472b1

Imágenes descritas por descriptores de pod

Las imágenes de contenedores que se describen mediante descriptores Pod pueden validarse mediante firma simpl Red Hat.

Si un resumen hace referencia a la imagen, el servicio permite su uso sin comprobaciones adicionales.

Las imágenes sin un resumen necesitan una clave GPG para ser validadas. La clave se transfiere en un formato binario codificado e Base64, que se puede crear. Consulte el ejemplo siguiente:

gpg -a --export ${KEY_ID}|base64 -w0

Esta clave se transmite a través de la rhs subsección de la images sección. Esta sección es un mapa con el identificador de imagen como clave y la clave GPG en el campo publicKey:

Ejemplo:

images:
  rhs:
      OCI-image-identifier:
        publicKey: abcdef

La subsección workload- volumes

La sección volumes debe proporcionarse en el contrato sólo si un volumen de datos está conectado a la instancia en el momento de la creación. La información que se proporciona en esta sección se utiliza para montar el volumen de datos adjunto (proporcionado por el usuario) y posteriormente se cifra utilizando las "semillas" proporcionadas en las secciones workload y env. Puede proporcionar cualquier ruta de su elección para el campo "mount". La ruta que proporciona el usuario se utiliza internamente para montar el volumen de datos. La ruta de montaje que se proporciona en el contrato debe coincidir con la ruta que se proporciona en la sección de volúmenes del archivo docker-compose.yaml para que todos los datos asociados con la carga de trabajo del contenedor se almacenen en este volumen de datos.

La subsección volumes tiene soporte para el cifrado automático del volumen de datos con semillas proporcionadas por el usuario. Si un volumen de datos está conectado a la instancia de Hyper Protect Virtual Servers, se cifra automáticamente con las semillas que se proporcionan a través del campo "semilla" en las subsecciones volumes del contrato. Por lo tanto, se deben proporcionar dos semillas, una a través de la sección workload (por la persona de la carga de trabajo) y la otra a través de la sección env (por la persona del desplegador). Estas dos semillas se convierten internamente en secuencias UTF8 y, a continuación, se concatenan. Posteriormente, el hash (SHA256) de la secuencia concatenada se calcula como un hexdigest, que se utiliza como frase de contraseña LUKS para cifrar el volumen de datos.

Actualmente, las semillas env y workload requieren una longitud mínima de 3 caracteres. A partir de marzo de 2026, este mínimo aumentará a 15 caracteres. Cualquier valor de semilla inferior a 15 caracteres después de marzo de 2026 puede dar lugar a errores o a despliegues fallidos. Para evitar interrupciones, actualice lo antes posible todos los valores de las semillas a una longitud de al menos 15 caracteres. Las normas se definen en la sección siguiente.

A partir de marzo de 2026, deberás seguir estas normas para crear semillas:

  • No se permiten espacios.
  • Debe tener al menos 15 caracteres. A continuación se indican los caracteres permitidos:
    • Letras minúsculas (a-z)
    • Letras mayúsculas (A-Z)
    • Números (0-9)
    • Caracteres especiales !@#$%^&*(),.?":{}|<>_-

Puedes utilizar el siguiente comando para validar el hexdigest:

echo -n "seed1seed2" | sha256sum

Aquí puede aprender cómo se puede proporcionar la "semilla" en la sección de carga de trabajo del contrato. Para obtener más información sobre cómo se puede proporcionar la entrada "semilla" a través de la sección env, consulte La sección env. Es obligatorio proporcionar ambas semillas para el cifrado. El cifrado falla si sólo se proporciona una instancia de semilla.

Puede añadir un mayor nivel de protección y control mediante cifrado a sus datos en reposo mediante la integración con Hyper Protect Crypto Services. A partir de ibm-hyper-protect-container-runtime-1-0-s390x-11, puede utilizar Hyper Protect Crypto Services para generar un valor aleatorio como tercera semilla y envolverlo con su clave raíz. La frase de contraseña LUKS se genera utilizando tres semillas: la semilla en la partición de metadatos y las dos semillas del contrato. Puede obtener información adicional consultando Protección de datos.

El siguiente fragmento de código es un ejemplo para la sección de volúmenes:

volumes:
  test:
    filesystem: ext4
    mount: /mnt/data
    seed: "workload_phrase"

A partir de la versión de ibm-hyper-protect-container-runtime-1-0-s390x-9 imagen HPCR, para las Hyper Protect Virtual Servers nuevas instancias VPC, el volumen de datos se divide en dos partes. La primera partición ( 100Mib ) está reservada para metadatos internos; la segunda partición permanece como volumen de datos para la carga de trabajo. Sólo se particionan los volúmenes nuevos y no puede utilizar el volumen particionado con una versión anterior de la imagen HPCR. El suministro con un volumen cifrado existente también funciona. La diferencia es que el volumen existente no se particiona, y también puede volver a una imagen más antigua con este volumen.

A partir de ibm-hyper-protect-container-runtime-1-0-s390x-12, el desplegador y el proveedor pueden utilizar la característica "rotación de semillas". Se proporciona una opción para rodar o rotar las semillas para aumentar la postura de seguridad, o si la semilla está comprometida. Cuando el desplegador o el proveedor o ambos desean retrotraer las semillas, la información de semilla actual debe especificarse en el parámetro previousSeed, y la nueva información de semilla debe especificarse en el parámetro seed.

El siguiente fragmento de código es un ejemplo para la sección de volúmenes:

volumes:
  test:
    filesystem: ext4
    mount: /mnt/data
    seed: "workload_phrase1"
    previousSeed: "workload_phrase"

A partir de ibm-hyper-protect-container-runtime-1-0-s390x-13, puede conectar varios volúmenes al iniciar la instancia de servidor virtual. Los volúmenes que se adjuntan cuando la instancia se está ejecutando se ignoran.

El siguiente fragmento de código es un ejemplo para la sección de volúmenes:

volumes:
  test1:
    filesystem: "ext4"
    mount: "/mnt/data"
    seed: "seed_value_with_minimum_15_characters"
  test2:
    filesystem: "ext4"
    mount: "/mnt/test2"
    seed: "seed_value_with_minimum_15_characters"
  test3:
    filesystem: "ext4"
    mount: "/mnt/test3"
    seed: "seed_value_with_minimum_15_characters"

La sección env

La sección env también es una de las secciones más importantes de un contrato. La sección env de un contrato se ocupa de la información específica del entorno de nube y no es conocida por la persona de la carga de trabajo. Esta sección la crea la persona del desplegador.

Las subsecciones para la sección env son:

  • type: aprox. Esta subsección es obligatoria.
  • logging. Esta subsección es obligatoria.
  • volumes. Esta subsección sólo se debe utilizar cuando se conecta un volumen de datos.
  • signingKey. Esta subsección sólo se debe utilizar cuando desee utilizar una firma de contrato.
  • env. Esta subsección se utiliza para especificar valores para las variables env si están definidas por el proveedor de carga de trabajo.

La subsección logging

ICL

La subsección mínima que se requiere para esta sección es logRouter. Para obtener más información, consulte Logging para Hyper Protect Virtual Servers para VPC.

El fragmento de código siguiente es un ejemplo de la subsección ICL:

 env:
   logging:
     logRouter:
       hostname: <host name of the service instance> /
       iamApiKey: <iamApiKey of the service instance> / xxxx
       port: <port of the service instance(443)

La subsección env- volumes

Lea la subsección workload-volumes de la sección de carga de trabajo antes de continuar con esta sección. Como ya se ha mencionado, para el cifrado de disco automático del volumen de datos adjunto, debe proporcionar dos semillas de cliente, una en la subsección workload- volumes y la otra en la subsección env- volumes. Las semillas pueden ser cualquier texto aleatorio de su elección.

Vea el siguiente ejemplo de la subsección env- volumes:

volumes:
  test:
    seed: "seed_value_with_minimum_15_characters"

Cuando utiliza la característica "rolado de semillas", puede utilizar el fragmento de código siguiente como ejemplo:

volumes:
  test:
    seed: "seed_value_with_minimum_15_characters"
    previousSeed: "env_phrase12345"

Cuando se utilizan varios volúmenes, el desplegador debe asegurarse de que los volúmenes se crean por adelantado y también especificar el ID de volumen en el archivo de contrato. De lo contrario, debe especificarse el nombre de volumen y el volumen debe crearse con el mismo nombre. Si no se especifican ambos, la tecla de volumen se considera como el nombre del volumen y el volumen debe crearse con el mismo nombre mientras se crea la instancia del servidor virtual o antes. El siguiente fragmento es un ejemplo:

 env: |
   logging:
     logRouter:
       hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
       iamApiKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
       port: 443
   volumes:
     test1:
       apiKey: "L4SsSE32xxxxxjAgfHCVkdW8xl_CiqMn4Lpc1dzTD"
       volumeID: "r006-f7b44467-01af-xxx-xxxx-xxxxxxx"
       seed: "seed_value_with_minimum_15_characters"
     test2:
       apiKey: "L4SsSE32xxxxxjAgfHCVkdW8xl_CiqMn4Lpc1dzTD"
       volumeName: "volume2"
       seed: "seed_value_with_minimum_15_characters"
     test3:
       apiKey: "L4SsSE32xxxxxjAgfHCVkdW8xl_CiqMn4Lpc1dzTD"
       seed: "seed_value_with_minimum_15_characters"

Donde:

  • Nombre del volumen: es el nombre que especificó cuando creó el volumen en el VPC.
  • ID de volumen: es el ID de volumen generado por el sistema del volumen creado.
  • Clave de volumen: es el nombre de volumen exclusivo para cada volumen.

La clave de volumen debe ser la misma que la clave en la subsección de carga de trabajo - volúmenes.

Como se ha mencionado, puede integrar con Hyper Protect Crypto Services para generar una tercera semilla y envolverla con la clave raíz. Vea el ejemplo siguiente. Puede obtener información adicional consultando Protección de datos.

volumes:
 test:
   kms:
     - apiKey: "L4SsSE32xxxxxjAgfHCVkdW8xl_CiqMn4Lpc1dzTD"
       crn: "crn:v1:bluemix:public:hs-crypto:us-south:a/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
       type: "public"
     - apiKey: "L4SsSE32xxxxxjAgfHCVkdW8xl_CiqMn4Lpc1dzTD"
       crn: "crn:v1:bluemix:public:hs-crypto:us-south:a/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
       type: "private"
   seed: "seed_value_with_minimum_15_characters"
   apiKey: "**********************"
   kmsTimeout: 10

Subsección signingKey

Para obtener más información sobre cómo utilizar signingKey, consulte Firma de contrato.

Subsección env

  • Si se utilizan descriptores Pod en la sección workload:

    Consulte el ejemplo del formato de plantilla en la subsección play.

  • Si se utiliza un archivo de composición de docker en la sección workload:

    Si el archivo de composición de docker tiene una sección de entorno, puede utilizar el fragmento de código siguiente como ejemplo:

    environment:
      KEY1: "${Value1}"
      KEY2: "${Value2}"
    

    Cuando el archivo de composición de Docker tiene una sección de entorno, como se muestra en el ejemplo anterior, puede pasar los valores en la sección de configuración ( env ) del implementador. El ejemplo siguiente muestra cómo especificar los valores para las variables env:

    env:
     value1: "abc"
     value2: "xyz"
    

Cifrado de contrato

Puede cifrar el contenido de un contrato. Aunque también puede pasar el contrato a través de los Datos de usuario sin cifrado, se recomienda que cifre el contrato. También se recomienda que inicialmente intente utilizar un contrato no cifrado para fines de prueba, y después de que funcione como se esperaba, puede utilizar un contrato cifrado para el entorno de producción.

Puede decidir qué secciones del contrato necesitan cifrado. Por ejemplo, puede elegir cifrar sólo la sección workload o cifrar sólo la sección env.

Cuando Hyper Protect Virtual Servers para arranques de instancia de VPC, el cargador de arranque descifra el contrato. Toma el valor de cada una de las secciones del contrato y lo descifra si está cifrado. Si encuentra que una sección no está cifrada, la considera tal como está sin ningún descifrado. Debe utilizar la clave pública para cifrar el contrato antes de pasarlo como entrada a través de la sección Datos de usuario.

Los certificados de cifrado y atestación están firmados por el certificado intermedio de la Autoridad de Certificación de la Unión Europea ( IBM ). El certificado intermedio de IBM está firmado por el certificado intermedio de Digicert de IBM, que a su vez está firmado por el certificado raíz de confianza de DigiCert ( G4 ). Para obtener más información sobre los certificados, consulte Certificados de autoridad raíz de confianza de DigiCert.

Descarga del certificado de cifrado y extracción de la clave pública

  1. Descargue el certificado. En la siguiente tabla se indican las fechas de caducidad de los certificados de cifrado y las fechas de fin de soporte o de obsolescencia de las imágenes, según la versión de cada una.
Fechas de caducidad de los certificados de cifrado y fechas de caducidad y obsolescencia de las imágenes
Versión de imagen Enlace de certificado Fecha de caducidad de certificado de cifrado Fecha de desuso
ibm-hyper-protect-container-runtime-1-0-s390x-29 certificate 6 de julio de 2027 6 de febrero de 2027
ibm-hyper-protect-container-runtime-1-0-s390x-28 certificate 24 de febrero de 2027 24 de septiembre de 2026
ibm-hyper-protect-container-runtime-1-0-s390x-26 certificate 24 de febrero de 2027 24 de septiembre de 2026
ibm-hyper-protect-container-runtime-1-0-s390x-25 certificate 06 agosto 2026 31 de marzo de 2026

Nota

  • Obsoleto- Puede utilizar la imagen para crear una instancia desde la CLI IBM Cloud. El estado obsoleto puede desalentar el uso de la imagen antes de que su estado cambie a obsoleto. El catálogo de imágenes mantiene siempre las dos versiones de imagen más recientes: n y n-1. Cuando una nueva versión ( n+1 ) está disponible, el sistema deja obsoleta la versión más antigua ( n-1 ).
  • Obsoleto: Cuando el certificado asociado a la imagen caduca, la imagen no está disponible para aprovisionar una instancia.
  • Descargue siempre los certificados de cifrado correspondientes a la imagen y cifre los contratos.

Para comprobar la imagen en desuso o el estado obsoleto, también puede utilizar el mandato IBM Cloud image list.

Puede consultar la documentación del mandato de lista de imágenes para obtener el estado de la imagen.

  1. Valide el certificado de cifrado siguiendo las instrucciones del tema Validación del certificado de cifrado del contrato.

Creación de la sección workload cifrada de un contrato

El valor de cualquier sección de un contrato puede ser texto sin formato o cifrado. Complete los siguientes pasos en un sistema de cifrado de claves asimétricas ( Ubuntu ) para cifrar la sección de carga de trabajo utilizada en un contrato:

  1. Cree el archivo docker-compose.yaml basándose en los requisitos de carga de trabajo. Por ejemplo:

    services:
      redisnode01:
        image: s390x/redis@sha256:db467ab5c53bdeef65762a7534e26fecb94a0f218bd38afd2eaba1a670c472b1
        ports:
          - "6379:6379"
    

    Para obtener más información, consulte Visión general de Docker Compose.

  2. Cree la sección de carga de trabajo del contrato y añada el contenido en el archivo workload.yaml.

    A continuación se muestra un ejemplo ​workload.yaml de:

    type: workload
    auths:
      us.icr.io:
       password: ${API_KEY}
       username: iamapikey
    compose:
     archive: ${COMPOSE_VALUE}
    volumes:
     test0:
       mount: "/mnt/data"
       seed: "workload_seed12"
       filesystem: "ext4"
     env:
       key: "value"
    
  3. Exporte la vía de acceso completa del archivo workload.yaml y ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt:

    WORKLOAD="<PATH to workload.yaml>"
    CONTRACT_KEY="<PATH to ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt>"
    
  4. Utiliza el siguiente comando para crear una contraseña aleatoria. El contrato se cifra mediante AES simétrico con una contraseña aleatoria.

    PASSWORD="$(openssl rand 32 | base64 -w0)"
    
  5. A partir de OpenSSL 3.0, el comando OpenSSL rsautl queda obsoleto y se sustituye por el comando pkeyutl. Utilice uno de los siguientes comandos para cifrar la contraseña con ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt:

    • Uso de rsautl (obsoleto):
       ENCRYPTED_PASSWORD="$(echo -n "$PASSWORD" | base64 -d | openssl rsautl -encrypt -inkey $CONTRACT_KEY -certin | base64 -w0)"
    
    • Utilizando pkeyutl (recomendado):

      ENCRYPTED_PASSWORD="$(echo -n "$PASSWORD" | base64 -d | openssl pkeyutl -encrypt -inkey $CONTRACT_KEY -certin -pkeyopt rsa_padding_mode:pkcs1 | base64 -w0)"
      
  6. Utilice el mandato siguiente para cifrar el archivo workload.yaml con una contraseña aleatoria:

    ENCRYPTED_WORKLOAD="$(echo -n "$PASSWORD" | base64 -d | openssl enc -aes-256-cbc -pbkdf2 -pass stdin -in "$WORKLOAD" | base64 -w0)"
    
  7. Utilice el mandato siguiente para obtener la sección cifrada del contrato:

    echo "hyper-protect-basic.${ENCRYPTED_PASSWORD}.${ENCRYPTED_WORKLOAD}"
    
  8. Obtenga la salida del paso 7 y añádala al archivo user-data.yaml.

    workload: hyper-protect-basic.js7TGt77EQ5bgTIKk5C0pViFTRHqWtn..............
    

    El prefijo hyper-protect-basic es obligatorio.

Creación de la sección env cifrada de un contrato

Complete los siguientes pasos en un sistema Ubuntu para cifrar la sección env utilizada en un contrato:

  1. Cree la sección env del contrato y añada el contenido en el archivo env.yaml.

    A continuación se muestra un ejemplo de env.yaml:

    type: env
      logging:
      syslog:
        hostname: ${RSYSLOG_SERVER_IP}
        port: 6514
        server: "${RSYSLOG_SERVER_ROOT_CA}"
        cert: "${RSYSLOG_CLIENT_CA}"
        key: "${RSYSLOG_CLIENT_KEY}"
      volumes:
        test0:
          seed: "stsolutiontest1"
    
  2. Exporte la vía de acceso completa del archivo env.yaml y ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt:

    ENV="<PATH to env.yaml>"
    CONTRACT_KEY="<PATH to ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt>"
    
  3. Utiliza el siguiente comando para crear una contraseña aleatoria:

    PASSWORD="$(openssl rand 32 | base64 -w0)"
    
  4. A partir de OpenSSL 3.0, el comando OpenSSL rsautl queda obsoleto y se sustituye por el comando pkeyutl. Utilice uno de los siguientes comandos para cifrar la contraseña con ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt:

    • rsautl (obsoleto):
       ENCRYPTED_PASSWORD="$(echo -n "$PASSWORD" | base64 -d | openssl rsautl -encrypt -inkey $CONTRACT_KEY -certin | base64 -w0)"
    
    • pkeyutl (recomendado):

      ENCRYPTED_PASSWORD="$(echo -n "$PASSWORD" | base64 -d | openssl pkeyutl -encrypt -inkey $CONTRACT_KEY -certin -pkeyopt rsa_padding_mode:pkcs1 | base64 -w0)"
      
  5. Utilice el mandato siguiente para cifrar env.yaml con una contraseña aleatoria:

    ENCRYPTED_ENV="$(echo -n "$PASSWORD" | base64 -d | openssl enc -aes-256-cbc -pbkdf2 -pass stdin -in "$ENV" | base64 -w0)"
    
  6. Utilice el mandato siguiente para obtener la sección cifrada del contrato:

    echo "hyper-protect-basic.${ENCRYPTED_PASSWORD}.${ENCRYPTED_ENV}"
    
  7. Para cifrar la sección de carga de trabajo, consulte Creación de la sección workload cifrada de un contrato.

  8. Obtenga la salida del paso 6 y añádala al archivo user-data.yaml.

    env: hyper-protect-basic.VWg/5/SWE+9jLfhr8q4i.........
    

Firma de contrato

La firma del contrato es una función opcional que puede utilizar con el contrato. Puede elegir firmar un contrato antes de que se pase como entrada. También puede establecer la caducidad del contrato durante la firma. Los contratos que están en texto sin formato o cifrados se pueden firmar. La validación de la firma del contrato la realiza Hyper Protect Virtual Servers para la imagen de VPC. La finalidad de esta característica de firma es asegurarse de que las secciones workload y env se utilizan siempre juntas y no son manipuladas por terceros. Esta característica también da soporte a la caducidad de valores para el contrato. Es decir, si la instancia se inicia después de que la firma haya caducado, el proceso de arranque falla. La firma de las secciones workload y env se añaden como valor a la sección envWorkloadSignature. A continuación se muestran dos secciones de un contrato que son relevantes al crear y añadir una firma de contrato:

  • envWorkloadSignature: En esta sección se añade la firma de las otras secciones del contrato. Esta sección no es necesaria para un contrato que no está firmado.
  • signingKey: Esta subsección debe añadirse a la sección de « env » (Información sobre el producto) del contrato. Esta subsección contiene el valor de la clave pública generada por el usuario, cuya clave privada correspondiente se utilizó para crear la firma del contrato. Una clave pública o un certificado también pueden analizarse como una cadena de texto ( Base64 ).

Complete los siguientes pasos en un sistema de firma electrónica ( Ubuntu ) para crear la firma del contrato:

  1. Utilice el mandato siguiente para generar el par de claves para firmar el contrato (tenga en cuenta que "test1234" es la frase de contraseña para generar claves, puede utilizar la suya propia):

    openssl genrsa -aes128 -passout pass:test1234 -out private.pem 4096
    openssl rsa -in private.pem -passin pass:test1234 -pubout -out public.pem
    
  2. El mandato siguiente es un ejemplo de cómo puede obtener la clave de firma:

    key=$(awk -vRS="\n" -vORS="\\\n" '1' public.pem)
    echo ${key%\\n}
    
  3. Opcionalmente, si desea pasar la clave de firma como Base64:

    key=$(cat public.pem | base64 -w 0)
    echo $key
    
  4. Opcionalmente, si desea habilitar la expiración del contrato, siga estos pasos:

    1. Utiliza el siguiente comando para generar una solicitud de certificado:
       openssl req -new -key private.pem -passin pass:test1234 -out csr.pem
    
    1. El mandato genera el certificado.
      • Utilice el siguiente comando para generar una clave privada para la CA:
      openssl genrsa -out personal_ca.key 2048
      
      • Genera un certificado de CA autofirmado utilizando el siguiente comando :
      openssl req -new -x509 -key personal_ca.key -out personal_ca.crt
      
      • El siguiente comando firma el CSR con un certificado de CA autofirmado junto con el número de días de validez del certificado. La fecha de finalización del certificado generado es la fecha de caducidad del contrato:
      openssl x509 -req -in csr.pem -CA personal_ca.crt -CAkey personal_ca.key -CAcreateserial -out certificate.pem -days 365
      
    2. El mandato siguiente es un ejemplo para obtener el certificado:
      certificate=$(awk -vRS="\n" -vORS="\\\n" '1' certificate.pem)
      echo ${certificate%\\n}
      
    3. Opcionalmente, utilice el siguiente comando como ejemplo para obtener el certificado en Base64 formato:
       certificate=$(cat certificate.pem | base64 -w 0)
       echo $certificate
    
  5. Crea el archivo env.yaml. Consulte el ejemplo siguiente:

    1. Si signingkey es una clave pública:
       env: |
         type: env
         logging:
           logRouter:
             hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
             iamApiKey: <iamApiKey of the service instance> / xxxx
             port: 443
         volumes:
           test:
           seed: "seed_value_with_minimum_15_characters"
         signingKey: "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLaeSA8Nc3p99HNUMwon\n5lMMALAsIxRRpWUaEZ5IcUky2sgCi/rSmxU2sm6FK/BmCftk33f5W2BsYHdY9R/0\nELZ9A4POQcJsPF3ronU2QHwnRjcqYuUFXmf1VqfPPLpELriFNoCb2FN2zCa+VUmu\n+fGhroZ3Fr9kBPwJhGr917E5jeCQ+MzsGkulcTvr0SfvThiZQQ/KlU0R35ThamF3\n8C0F5IQBpqDUwDFmWvD5lF2SmprpluDBFEj8LLfLxvW9M2Qwku6nGUnnFReg3vNH\n7IF0SRr1K1AdO5hEmevCdyG9hgTdUY6dXcjntiN/kbqXErILknvzDnb4jyPZZRdK\ndrOzVt8hjbdmkS396SrMFtA++QrV3GNZl5zCscpn6d8S7BEA8mDzroo2UAbrypVP\n9l9AmzUnmnPCpZQySUUHoY0xG2vgMSA50CWH7Uwjmpixr02Td4/LU8fE7NWCO6ci\nx4++ANSaxu+uuZ2Pe1OjjgV98r06ZUs38eaxptLZqLpn3N6w8WAJxGwSLapZwNtP\ng2spUXu2Eh/TN5t4/ly5iXOsyIy8IPtTrUPX7rpaaqFZ72P6BJLj3WLEvOG/eF/8\nBTjrsZAjb8YjkO1uGk10IPa63sniZWe5vlm9w9UKy2uGuy6RhWxwoVHRRbfhboQF\nsO20dsVwgTZn8c46HMD2PoMCAwEAAQ==\n-----END PUBLIC KEY----"
    
    1. Si signingkey es un certificado:
         env: |
           type: env
           logging:
             logRouter:
               hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
               iamApiKey: <iamApiKey of the service instance> / xxxx
               port: 443
           volumes:
             test:
             seed: "seed_value_with_minimum_15_characters"
           signingKey: "-----BEGIN CERTIFICATE-----\nMIIFETCCAvkCFBAMxyO6Cl7BNKBGxtlAzHpI2oiNMA0GCSqGSIb3DQEBCwUAMEUx\nCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl\ncm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjQwMTMwMDM1ODMzWhcNMjQwNTA5MDM1\nODMzWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE\nCgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOC\nAg8AMIICCgKCAgEAv5h6i7Fn1DMUM+3AnPPZUNMe1ss3KL/AmUmptwlAPErVoH1k\naiqTUsSNjXctj+nk95I+e2nugw/HlaVT1eRgEtvjssheXKboFn+zW/i31Nq9USgQ\nZA325VtchYlgJLXMPaH/ukBUr0UI4LnjC/dNdAQzKwWPNF2Jlv5wKX8OBVOQO9Df\nExVmcEkKDoh0nZk5eOA8vzJGhfr8TvQx9FQFsP4OXTwQgcdZV26mLm0bMkqEt3o5\n8OSpisqNGY1XnMHjOWNqSbErkpbIKEFAQSnWmzEvJdHsQX+7eTF7CisHJREseT4s\nUSuIFBZKXbS3qq6EL/EYviu0EGnY/rkJJcIRb8hycqHRgoITT2bWT7PSMUyXoX3G\nVKfp/xKFhkYzoRDSb5S0lh8sugmoRkioAkw6G56CP2hablPZRUMmUKceFfOG/k4L\nei8qJtbfQJ9BlCNRPpjqY3sGSdeXI4zefyQ8xxcus9Sl5wXZV86lz2lO/fz3Cvpd\n0eKvfv5uXyvF3O36lrlEERmSukaZYaEJECjxOUeafc7E1DVyIaMpc2SOum1crwMG\nRKhnU1JShDON0yClnKOlACfjFIpdpEMpE4lLps1x+PXV+x21zGBMUvXYa4xpbyWR\nK1gfMWmuvGOivl9y0mPSIeyJ9R/7bSRAbcYJR4N99TrtWxZU1yQi7HSRV5cCAwEA\nATANBgkqhkiG9w0BAQsFAAOCAgEAg006zJ4ZKwT8moOOl3PdThFUcf8rrIlec9Iy\nqPcWSqt5UTeYLIe58oGhhQmcaIRUOQaib5JqH2ukzqpo+gsJ3zZb3eIn4FB7cKef\nLqaiemOveEe1/qSwAGqMZyZELssiOflhnJdzuYSRWO8DO6Q6JMqQthDcw20budjO\nzP4nhXQqT+s8ljzqSJW77hDbrNAezTz/0SJFDtaMBs5UweX//7/4sXtJ8kBIBSxd\n7y4w8tuuxUaXOtYMjNrJAYLwFVeeO8CFURpbEuv7ABT0k8U4E8C6j4U4Jysx4XVP\nZj36rIAtvctchh0yAhHz8whXe1tvaFw9wzRDATnThFAuJG4Z07K2/rlDP9kO9wmn\ng8hHxKeqQMJDp29e0sGkz8oDi6Mz24k9CqFJJ0CUz1ntz7rrDkA3QwQbFRzk938y\n3rSfePO5qXlUQ9mm05hYr1EKKceTLEowc4XOouNLlUWGiRshRR1szMw5C29prFJ2\nyYuV9tBaFYkq7dnh8JnmrreEvAnsKyyECxMmtV/W701OSUYBcThwgAo+hkEeOJ+/\nwrOS7yoJqDF1y+5LLQJmUlrLCPXem3ZTa4UMe1p2g7ge7Dg6Zud9NDBcMigdHByt\nJP/i9PcJSEWrccWJ1ajToUCZ0wqfJ3Z4KqoEd0fadQhb32AuDUbu7E12EUFNPGIH\n8rQKbDU=\n-----END CERTIFICATE-----"
    
    1. Si signingkey es un Base64 clave de firma codificada o certificado:
         env: |
           type: env
           logging:
             logRouter:
               hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
               iamApiKey: <iamApiKey of the service instance> / xxxx
               port: 443
           volumes:
             test:
             seed: "seed_value_with_minimum_15_characters"
           signingKey: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXG5NSUlGRVRDQ0F2a0NGQkFNeHlPNkNsN0JOS0JHeHRsQXpIcEkyb2lOTUEwR0NTcUdTSWIzRFFFQkN3VUFNRVV4XG5DekFKQmdOVkJBWVRBa0ZWTVJNd0VRWURWUVFJREFwVGIyMWxMVk4wWVhSbE1TRXdId1lEVlFRS0RCaEpiblJsXG5jbTVsZENCWGFXUm5hWFJ6SUZCMGVTQk1kR1F3SGhjTk1qUXdNVE13TURNMU9ETXpXaGNOTWpRd05UQTVNRE0xXG5PRE16V2pCRk1Rc3dDUVlEVlFRR0V3SkJWVEVUTUJFR0ExVUVDQXdLVTI5dFpTMVRkR0YwWlRFaE1COEdBMVVFXG5DZ3dZU1c1MFpYSnVaWFFnVjJsa1oybDBjeUJRZEhrZ1RIUmtNSUlDSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DXG5BZzhBTUlJQ0NnS0NBZ0VBdjVoNmk3Rm4xRE1VTSszQW5QUFpVTk1lMXNzM0tML0FtVW1wdHdsQVBFclZvSDFrXG5haXFUVXNTTmpYY3RqK25rOTVJK2UybnVndy9IbGFWVDFlUmdFdHZqc3NoZVhLYm9Gbit6Vy9pMzFOcTlVU2dRXG5aQTMyNVZ0Y2hZbGdKTFhNUGFIL3VrQlVyMFVJNExuakMvZE5kQVF6S3dXUE5GMkpsdjV3S1g4T0JWT1FPOURmXG5FeFZtY0VrS0RvaDBuWms1ZU9BOHZ6SkdoZnI4VHZReDlGUUZzUDRPWFR3UWdjZFpWMjZtTG0wYk1rcUV0M281XG44T1NwaXNxTkdZMVhuTUhqT1dOcVNiRXJrcGJJS0VGQVFTbldtekV2SmRIc1FYKzdlVEY3Q2lzSEpSRXNlVDRzXG5VU3VJRkJaS1hiUzNxcTZFTC9FWXZpdTBFR25ZL3JrSkpjSVJiOGh5Y3FIUmdvSVRUMmJXVDdQU01VeVhvWDNHXG5WS2ZwL3hLRmhrWXpvUkRTYjVTMGxoOHN1Z21vUmtpb0FrdzZHNTZDUDJoYWJsUFpSVU1tVUtjZUZmT0cvazRMXG5laThxSnRiZlFKOUJsQ05SUHBqcVkzc0dTZGVYSTR6ZWZ5UTh4eGN1czlTbDV3WFpWODZsejJsTy9mejNDdnBkXG4wZUt2ZnY1dVh5dkYzTzM2bHJsRUVSbVN1a2FaWWFFSkVDanhPVWVhZmM3RTFEVnlJYU1wYzJTT3VtMWNyd01HXG5SS2huVTFKU2hET04weUNsbktPbEFDZmpGSXBkcEVNcEU0bExwczF4K1BYVit4MjF6R0JNVXZYWWE0eHBieVdSXG5LMWdmTVdtdXZHT2l2bDl5MG1QU0lleUo5Ui83YlNSQWJjWUpSNE45OVRydFd4WlUxeVFpN0hTUlY1Y0NBd0VBXG5BVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBZzAwNnpKNFpLd1Q4bW9PT2wzUGRUaEZVY2Y4cnJJbGVjOUl5XG5xUGNXU3F0NVVUZVlMSWU1OG9HaGhRbWNhSVJVT1FhaWI1SnFIMnVrenFwbytnc0ozelpiM2VJbjRGQjdjS2VmXG5McWFpZW1PdmVFZTEvcVN3QUdxTVp5WkVMc3NpT2ZsaG5KZHp1WVNSV084RE82UTZKTXFRdGhEY3cyMGJ1ZGpPXG56UDRuaFhRcVQrczhsanpxU0pXNzdoRGJyTkFlelR6LzBTSkZEdGFNQnM1VXdlWC8vNy80c1h0SjhrQklCU3hkXG43eTR3OHR1dXhVYVhPdFlNak5ySkFZTHdGVmVlTzhDRlVScGJFdXY3QUJUMGs4VTRFOEM2ajRVNEp5c3g0WFZQXG5aajM2cklBdHZjdGNoaDB5QWhIejh3aFhlMXR2YUZ3OXd6UkRBVG5UaEZBdUpHNFowN0syL3JsRFA5a085d21uXG5nOGhIeEtlcVFNSkRwMjllMHNHa3o4b0RpNk16MjRrOUNxRkpKMENVejFudHo3cnJEa0EzUXdRYkZSems5Mzh5XG4zclNmZVBPNXFYbFVROW1tMDVoWXIxRUtLY2VUTEVvd2M0WE9vdU5MbFVXR2lSc2hSUjFzek13NUMyOXByRkoyXG55WXVWOXRCYUZZa3E3ZG5oOEpubXJyZUV2QW5zS3l5RUN4TW10Vi9XNzAxT1NVWUJjVGh3Z0FvK2hrRWVPSisvXG53ck9TN3lvSnFERjF5KzVMTFFKbVVsckxDUFhlbTNaVGE0VU1lMXAyZzdnZTdEZzZadWQ5TkRCY01pZ2RIQnl0XG5KUC9pOVBjSlNFV3JjY1dKMWFqVG9VQ1owd3FmSjNaNEtxb0VkMGZhZFFoYjMyQXVEVWJ1N0UxMkVVRk5QR0lIXG44clFLYkRVPVxuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVxu
    
  6. Crea el archivo env.yaml. Consulte el ejemplo siguiente:

     env: |
       type: env
       logging:
         logRouter:
           hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
           iamApiKey: <iamApiKey of the service instance> / xxxx
           port: 443
       volumes:
         test:
         seed: "seed_value_with_minimum_15_characters"
       signingKey: "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLaeSA8Nc3p99HNUMwon\n5lMMALAsIxRRpWUaEZ5IcUky2sgCi/rSmxU2sm6FK/BmCftk33f5W2BsYHdY9R/0\nELZ9A4POQcJsPF3ronU2QHwnRjcqYuUFXmf1VqfPPLpELriFNoCb2FN2zCa+VUmu\n+fGhroZ3Fr9kBPwJhGr917E5jeCQ+MzsGkulcTvr0SfvThiZQQ/KlU0R35ThamF3\n8C0F5IQBpqDUwDFmWvD5lF2SmprpluDBFEj8LLfLxvW9M2Qwku6nGUnnFReg3vNH\n7IF0SRr1K1AdO5hEmevCdyG9hgTdUY6dXcjntiN/kbqXErILknvzDnb4jyPZZRdK\ndrOzVt8hjbdmkS396SrMFtA++QrV3GNZl5zCscpn6d8S7BEA8mDzroo2UAbrypVP\n9l9AmzUnmnPCpZQySUUHoY0xG2vgMSA50CWH7Uwjmpixr02Td4/LU8fE7NWCO6ci\nx4++ANSaxu+uuZ2Pe1OjjgV98r06ZUs38eaxptLZqLpn3N6w8WAJxGwSLapZwNtP\ng2spUXu2Eh/TN5t4/ly5iXOsyIy8IPtTrUPX7rpaaqFZ72P6BJLj3WLEvOG/eF/8\nBTjrsZAjb8YjkO1uGk10IPa63sniZWe5vlm9w9UKy2uGuy6RhWxwoVHRRbfhboQF\nsO20dsVwgTZn8c46HMD2PoMCAwEAAQ==\n-----END PUBLIC KEY----"
    
  7. Utilice el mandato siguiente para exportar la vía de acceso completa de env.yaml y ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt:

    ENV="<PATH to env.yaml>"
    CONTRACT_KEY="<PATH to ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt>"
    
  8. Utiliza el siguiente comando para crear una contraseña aleatoria:

    PASSWORD="$(openssl rand 32 | base64 -w0)"
    
  9. A partir de OpenSSL 3.0, el comando OpenSSL rsautl queda obsoleto y se sustituye por el comando pkeyutl. Utilice uno de los siguientes comandos para cifrar la contraseña con ibm-hyper-protect-container-runtime-1-0-s390x-29-encrypt.crt:

    • Uso de rsautl (obsoleto):
        ENCRYPTED_PASSWORD="$(echo -n "$PASSWORD" | base64 -d | openssl rsautl -encrypt -inkey $CONTRACT_KEY -certin | base64 -w0)"
        ```
    - Utilizando `pkeyutl` (recomendado):
    
    ```yaml {: pre}
        ENCRYPTED_PASSWORD="$(echo -n "$PASSWORD" | base64 -d | openssl pkeyutl -encrypt -inkey $CONTRACT_KEY -certin -pkeyopt rsa_padding_mode:pkcs1 | base64 -w0)"
        ```
    
  10. Utilice el mandato siguiente para cifrar env.yaml con una contraseña aleatoria:

    ENCRYPTED_ENV="$(echo -n "$PASSWORD" | base64 -d | openssl enc -aes-256-cbc -pbkdf2 -pass stdin -in "$ENV" | base64 -w0)"
    
  11. Utilice el mandato siguiente para extraer la sección env cifrada:

    echo "hyper-protect-basic.${ENCRYPTED_PASSWORD}.${ENCRYPTED_ENV}"
    

Los pasos 7 - 11 se utilizan para cifrar la sección env. Si elige no cifrar esta sección, omita estos pasos.

Se envía una notificación sobre la expiración del contrato a su servicio de registro. Las líneas de tiempo para la notificación son las siguientes:

  • El primero de cada mes
  • Todos los días durante 30 días antes de la expiración
  • Una vez cada 4 horas si el contrato está a punto de caducar en 7 días
  • Cada hora si el contrato ha expirado o está a punto de expirar en 1 día

Registros de aviso de caducidad de certificados de cifrado y atestación

HPVS registra mensajes de advertencia en el servicio de registro configurado sobre certificados de cifrado y atestación próximos y caducados.

A continuación figura el calendario de notificaciones:

  • 30 días antes de la expiración: Se genera un mensaje de advertencia una vez cada 24 horas, notificando que el certificado caducará en un mes.

    Ejemplo:

    HPL12011W: The Encryption certificate is going to expire -> Warning: The encryption certificate will expire on 12 February 2026 at 16:17:41 UTC, over 20 days. Upgrade to the latest image to unlock the latest features and avoid potential security vulnerabilities!!!
    
  • 7 días antes de la fecha de caducidad: Los mensajes de advertencia se registran cada 12 horas a medida que se acerca la fecha de caducidad, resaltando la necesidad de actuar.

    Ejemplo:

    HPL12011W: The Encryption certificate is going to expire -> Warning: The encryption certificate will expire on 27 January 2026 at 16:17:41 UTC, over 4 days. Upgrade to the latest image to unlock the latest features and avoid potential security vulnerabilities!!!
    
  • Tras la caducidad del certificado: Si el certificado ha caducado, HPVS registra mensajes de advertencia cada 4 horas hasta que se actualice la imagen HPVS.

    Ejemplo:

    HPL12013W: The Encryption certificate expired -> Urgent: The encryption certificate expired on 15 June 2025 at 17:15:59 UTC, over 7 months. Immediate upgrade to the latest image is required to unlock the latest features and prevent serious security breaches.
    

Preparación de la sección de testificación

El certificado es una función opcional que puede utilizar con un contrato. attestationPublicKey: la clave pública proporcionada por el usuario que se utiliza para cifrar el documento de certificación. Esto se puede proporcionar como una clave RSA pública o Base64 codificado de la clave RSA pública como parte del contrato.

  • Si utiliza la clave RSA pública de texto sin formato para attestationPublicKey en el archivo yaml, utilice el ejemplo siguiente:

    attestationPublicKey: "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvLaeSA8Nc3p99HNUMwon\n5lMMALAsIxRRpWUaEZ5IcUky2sgCi/rSmxU2sm6FK/BmCftk33f5W2BsYHdY9R/0\nELZ9A4POQcJsPF3ronU2QHwnRjcqYuUFXmf1VqfPPLpELriFNoCb2FN2zCa+VUmu\n+fGhroZ3Fr9kBPwJhGr917E5jeCQ+MzsGkulcTvr0SfvThiZQQ/KlU0R35ThamF3\n8C0F5IQBpqDUwDFmWvD5lF2SmprpluDBFEj8LLfLxvW9M2Qwku6nGUnnFReg3vNH\n7IF0SRr1K1AdO5hEmevCdyG9hgTdUY6dXcjntiN/kbqXErILknvzDnb4jyPZZRdK\ndrOzVt8hjbdmkS396SrMFtA++QrV3GNZl5zCscpn6d8S7BEA8mDzroo2UAbrypVP\n9l9AmzUnmnPCpZQySUUHoY0xG2vgMSA50CWH7Uwjmpixr02Td4/LU8fE7NWCO6ci\nx4++ANSaxu+uuZ2Pe1OjjgV98r06ZUs38eaxptLZqLpn3N6w8WAJxGwSLapZwNtP\ng2spUXu2Eh/TN5t4/ly5iXOsyIy8IPtTrUPX7rpaaqFZ72P6BJLj3WLEvOG/eF/8\nBTjrsZAjb8YjkO1uGk10IPa63sniZWe5vlm9w9UKy2uGuy6RhWxwoVHRRbfhboQF\nsO20dsVwgTZn8c46HMD2PoMCAwEAAQ==\n-----END PUBLIC KEY----"
    
  • Si usas el Base64 clave de firma codificada para el attestationPublicKey en el archivo yaml, use el siguiente comando y ejemplo.

    base64 -w0 <public RSA key file>
    

    Debe sustituir <public RSA key file> por la vía de acceso al archivo de claves RSA público real.

    attestationPublicKey: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJpRENDQVM2Z0F3SUJBZ0lSQUxCMXBPYlpEQlRRc09GSFlxazMzaWd3Q2dZSUtvWkl6ajBFQXdJd0tqRW8KTUNZR0ExVUVBeE1mZFhNdWFXTnlMbWx2TDNCeVlXSm9ZWFF4TWpNdmJYa3RhR0Z3Y205NGVUQWVGdzB5TWpBMApNVE14TURFd01ETmFGdzB6TWpBME1UQXhNREV3TUROYU1Db3hLREFtQmdOVkJBTVRIM1Z6TG1samNpNXBieTl3CmNtRmlhR0YwTVRJekwyMTVMV2hoY0hKdmVIa3dXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CQndOQ0FBU1AKWGsrelE2MlFZNjI3MWQ1cTBMZHY3SGc3QzZkMGZOUlRsQmJXekhOWWFDZzlpU0piYnVNdjVBY0JmMjlqQi83eApqYzhzVitxMksyemtkTHV4QWxGWm96VXdNekFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJCkt3WUJCUVVIQXdNd0RBWURWUjBUQVFIL0JBSXdBREFLQmdncWhrak9QUVFEQWdOSUFEQkZBaUIzd0JTa0IxaXAKZHZZYlBMbFBmS3RZT0hsYnZzUllKa0FZM2hnY0xuNWhwQUloQUt6cmhsU3p4K1I5bmdtMTBlZVkyaFNCRmgrawpMWHp6SFkwaktTVzhyM1FhCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    
  • Si ha cifrado el attestationPublicKey en el archivo yaml, debe seguir los mismos pasos que se mencionan en el cifrado de contratos.

    Para descifrar el documento de testificación, siga las instrucciones de Descifrado del documento de testificación.

Preparación de la firma

Complete los siguientes pasos en un sistema de firma electrónica ( Ubuntu ) para preparar la firma:

Si tienes el cifrado user-data.yaml Desde la creación del cifrado workload Sección de un contrato y Creación del cifrado env sección de un contrato secciones, salte al paso 3.

  1. Obtenga los archivos cifrados workload.yaml y cifrados env.yaml.

  2. Añádalos al archivo user-data.yaml.

    workload: hyper-protect-basic.js7TGt77EQ5bgTIKk5C0pViFTRHqWtn..............
    env: hyper-protect-basic.VWg/5/SWE+9jLfhr8q4i.........
    
  3. Crea el archivo contract.txt. Añada primero el valor de workload y, a continuación, añada el valor de env del archivo user-data.yaml. Asegúrese de que no haya espacios ni líneas nuevas después de workload y antes de env. Además, asegúrese de que no se añada ninguna línea o espacio nuevo al final del archivo. Se recomienda realizar una comprobación cruzada del contenido binario del archivo contract.txt con herramientas como, por ejemplo, hexdump. En el volcado del archivo binario, asegúrese de que no ve el valor ASCII de 0a como la última entrada.

    hyper-protect-basic.js7TGt77EQ5bgTIKk5C0pViFTRHqWtn..............hyper-protect-basic.VWg/5/SWE+9jLfhr8q4i.........
    
  4. Utilice el mandato siguiente para generar la firma:

    echo $(cat contract.txt | tr -d "\n\r" | openssl dgst -sha256 -sign private.pem | openssl enc -base64) | tr -d ' '
    
  5. Añada la firma al archivo user-data.yaml:

    workload: hyper-protect-basic.js7TGt77EQ5bgTIKk5C0pViFTRHqWtn..............
    env: hyper-protect-basic.VWg/5/SWE+9jLfhr8q4i.........
    envWorkloadSignature: Icbm1D/CVpLNYkWRC9e .....
    

Iniciación a un contrato simple de Hyper Protect Virtual Servers para VPC

Los siguientes ejemplos de mandatos se ejecutan en un sistema Ubuntu.

1. Obtener los detalles de la instancia de registro

Puede configurar el registro con IBM Log Analysis o un programa de fondo syslog genérico. Este ejemplo utiliza IBM Log Analysis. Puede elegir entre diferentes planes. Para comprender cómo obtener los detalles necesarios, como el nombre de host y la clave de ingestión, consulte Registro para Hyper Protect Virtual Servers para VPC.

2. Cree la sección env

Asegúrese de no omitir el símbolo de barra vertical «|» si utiliza un contrato de texto sin formato. No es necesario si tiene previsto cifrar la sección.

env: |
  type: env
  logging:
    logRouter:
      hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
      iamApiKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      port: 443

3. Preparar el archivo docker-compose

Suponiendo que tiene los detalles de registro, busque un archivo de composición de docker simple. El siguiente ejemplo tiene un contenedor público NGINX. Cree un docker-compose.yaml utilizando el ejemplo.

services:
  nginx:
    image: docker.io/library/nginx@sha256:b1306efee704017b0e02efadc011d374063a4e9c47b86bdc57744fc3f0666383
    ports:
    - 80:80
    - 443:443

4. Obtener la versión base64-encoded del archivo docker-compose

tar -czvf compose.tgz docker-compose.yaml
base64 -i compose.tgz > compose.b64

5. Crear la sección de composición con ella

  compose:
    archive: H4sIADXNg2IAA+3W326CMBQGcK59it555XbanraMq70KlOLIJhjqzPb2q6g3S9xiIi7T75eQlj+hDYcP6vvVuo/hMZsQJc6YsU2+t2NfsmKyyhHLjKRUSmbCTDmpo/e4KQchsqHvNz9d99v5f8of6l/3/jUMi8Puw+fq7XJj7ApsmU/WX2m7r7/j9Abs6s/W2kzQ5aZw2p3XfxuG2PZdIeZ6Poth2LY+xGImRLdsu49dR4h2VS5DsT/yHF9KZWxRSU02NCGkxJJ0FQVSoSlrn8Jba5eyrEsOT55dlduq9sY55sbrhlJpda7HG6/7YRP3YyxETkVOhz6zLtI2++unc/tO5b+84AfgrPyn4JM0pDXyfw3I/32bMvdH5+SfOK0TpdZWIv/XgPzftynX/Udn/f/NmH+l8P+/CuQfAAAAAAAAAAAAAOD2fAEPQbuiACgAAA==

6. Llenar la sección de carga de trabajo

Asegúrese de que no se le pasa el símbolo de barra vertical (|) si está utilizando un contrato de texto sin formato.

workload: |
  type: workload
  compose:
    archive: H4sIADXNg2IAA+3W326CMBQGcK59it555XbanraMq70KlOLIJhjqzPb2q6g3S9xiIi7T75eQlj+hDYcP6vvVuo/hMZsQJc6YsU2+t2NfsmKyyhHLjKRUSmbCTDmpo/e4KQchsqHvNz9d99v5f8of6l/3/jUMi8Puw+fq7XJj7ApsmU/WX2m7r7/j9Abs6s/W2kzQ5aZw2p3XfxuG2PZdIeZ6Poth2LY+xGImRLdsu49dR4h2VS5DsT/yHF9KZWxRSU02NCGkxJJ0FQVSoSlrn8Jba5eyrEsOT55dlduq9sY55sbrhlJpda7HG6/7YRP3YyxETkVOhz6zLtI2++unc/tO5b+84AfgrPyn4JM0pDXyfw3I/32bMvdH5+SfOK0TpdZWIv/XgPzftynX/Udn/f/NmH+l8P+/CuQfAAAAAAAAAAAAAOD2fAEPQbuiACgAAA==

7. Su contrato simple está listo

env: |
  type: env
  logging:
    logRouter:
      hostname: 34be57c7-6ff2-903921e90ab9.ingress.jp-tok.logs.cloud.ibm.com
      iamApiKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      port: 443
workload: |
  type: workload
  compose:
    archive: H4sIADXNg2IAA+3W326CMBQGcK59it555XbanraMq70KlOLIJhjqzPb2q6g3S9xiIi7T75eQlj+hDYcP6vvVuo/hMZsQJc6YsU2+t2NfsmKyyhHLjKRUSmbCTDmpo/e4KQchsqHvNz9d99v5f8of6l/3/jUMi8Puw+fq7XJj7ApsmU/WX2m7r7/j9Abs6s/W2kzQ5aZw2p3XfxuG2PZdIeZ6Poth2LY+xGImRLdsu49dR4h2VS5DsT/yHF9KZWxRSU02NCGkxJJ0FQVSoSlrn8Jba5eyrEsOT55dlduq9sY55sbrhlJpda7HG6/7YRP3YyxETkVOhz6zLtI2++unc/tO5b+84AfgrPyn4JM0pDXyfw3I/32bMvdH5+SfOK0TpdZWIv/XgPzftynX/Udn/f/NmH+l8P+/CuQfAAAAAAAAAAAAAOD2fAEPQbuiACgAAA==

Próximos pasos