En primer lugar realizaremos una build a partir de la release que queramos (las anteriores a la 1.0.2 son inválidas).
El la carpeta del proyecto hay tres scripts para borrar, generar la imagen y el contenedor.
La imagen también puede obtenerse desde:
Ahora vienen las trampas.
El primer problema es que nuestro Dockerfile está basado en una imagen de openjdk:
FROM openjdk:8u141-jdk
Y esto tiene el problema de que utiliza el usuario root y esto no está permitido por las políticas de seguridad por defecto.
Para ello tendremos que crear el proyecto de la siguiente manera:
oc new-project myproject
oc project myproject
oc new-app labcabrera/http-network-diagnostic:1.0.2
oadm policy add-scc-to-user anyuid -z default
oc deploy image --latest
oc get pods
Donde hemos cambiado el contexto de seguridad a nivel del proyecto para permitir cualquier usuario.
Posteriormente tendremos que asignar los puertos editando directamente el YAML del deployment (se puede ver un ejemplo en el directorio openshift/deployment.xml):
ports:
- containerPort: 9043
protocol: TCP
- containerPort: 9443
protocol: TCP
Una vez generado el deployment veremos que no ha generado correctamente el servicio, de modo que tendremos que crearlo desde la consola (no he visto la opción de hacerlo desde la interface web):
oc expose dc some-name --name=some-name-service
Una vez creado tendremos que asociarle el puerto. Para ello desde la opción Applications >> Services seleccionaremos el servicio que acabamos de crear y editaremos el YAML añadiendo los puertos que queremos exponer:
spec:
clusterIP: 172.30.166.77
ports:
- name: 9009-tcp
port: 9009
protocol: TCP
targetPort: 9009
Una vez modificado nuestro servicio tendremos que crear una ruta, esto podemos hacerlo desde la web:
-
name: el nombre que queramos darle a nuestro servicio
-
hostname: sin rellenar
-
path: /
-
service: el servicio que hemos creado anteriormente. Si aparece un warning en esta casilla es porque en el fichero anterior no hemos establecido el nombre del puerto.
En nuestro ejemplo la aplicación funciona utilizando HTTPS de modo que tenemos que marcar la opción Secure route, escogiendo el valor Passthrough para la opción TLS Termination.
También marcamos que el tráfico HTTP se redirija al puerto seguro.
Si tenemos problemas y no sabemos que está haciendo nuestro pod podemos acceder a la consola de este desde la web a trabés de la opción Applications >> Pods. Seleccionaremos nuestro pod y veremos una pestaña llamada Terminal.
Una vez accedemos podemos comprobar si la aplicación está correctamente levantada a través del comando (la imagen de openjdk apenas tiene nada instalado):
ss -nptl
Y con eso tenemos nuestra app desplegada:
$ curl --insecure "https://secure-training.apps.openshiftexamplehost/api/date"
"2018-03-06T15:01:48.337+0000"
Por fortuna al actualizar la aplicación esta configuración se mantiene, de modo que no hay que volver a estar toqueteando a mano las configuraciones anteriores.
Para ello iremos a Applications >> Deployments, seleccionaremos el que deseamos actualizar y pulsaremos la opcón Edit. Una vez ahí simplemente desmarcaremos la opcion Deploy images from an image stream tag y copiaremos la imagen que queremos desplegar, por ejemplo labcabrera/http-network-diagnostic:1.0.3.
Guardamos y esperamos a que se refresque nuestro pod.
La aplicación web es muy sencilla. Simplemente tiene un controlador que comprueba si un determinado host es accesible utilizando la api de HttpClient:
public Map<String, Object> check(RequestInfo request) {
Map<String, Object> result = new LinkedHashMap<>();
CloseableHttpClient client;
try {
client = buildClient(request);
}
catch (Exception ex) {
log.error("Client build error", ex);
result.put("httpClientBuildError", ex.getMessage());
return result;
}
try {
HttpHost target = new HttpHost( //@formatter:off
request.getTargetHost(),
request.getTargetPort(),
request.getTargetSchema().name()); //@formatter:on
HttpHost proxy = null;
if (request.getProxyHost() != null) {
proxy = new HttpHost(request.getProxyHost(), request.getProxyPort());
}
RequestConfig config = RequestConfig.custom().setProxy(proxy).build();
HttpGet httpget = new HttpGet(request.getUri());
httpget.setConfig(config);
CloseableHttpResponse response = client.execute(target, httpget);
result.put("statusLine", response.getStatusLine().toString());
try {
result.put("content", readContent(response.getEntity().getContent()));
}
catch (Exception ex) {
result.put("errorReadingContent", ex.getMessage());
}
}
catch (Exception ex) {
log.error("HTTP error", ex);
result.put("exception", ex.getClass().getName());
result.put("exceptionMessage", ex.getMessage());
}
return result;
}
Este servicio se expone vía SSL a partir de la configuración de Spring Boot:
server:
port: ${APP_PORT:9009}
ssl:
key-store-type: PKCS12
key-store: classpath:certificate.p12
key-store-password: changeit
key-password: changeit
Podemos crear el certificado a partir del script create-self-signed-cert.sh del repositorio.