Operator Sidecar
A Kubernetes application may consist of a number of different components. These may include:
- Main application
- Security
- Logging
- Monitoring
- etc
Separating these components into their own container provides isolation and encapsulation. Each container provides a single capability without needing to know the intricate details of the other components.
In Kubernetes this pattern is known as a sidecar. Each sidecar container is attached to the main application and provides a specific function.
The IBM Application Gateway supports the sidecar pattern such that it can be configured to run alongside the main application providing authorization capabilities without the application needing to know the details.
Admission Controller
To allow the IBM Application Gateway to be used as an application sidecar the admission controller first needs to be deployed. The admission controller handles the management of the sidecar container in any application deployments that specify references to IBM Application Gateway.
For more information on Kubernetes admission controllers see A guide to Kubernetes Admission Controllers or search the Kubernetes documentation.
There are a series of steps that need to be followed to deploy the admission controller in Kubernetes:
- Configure the Kubernetes cluster to enable the MutatingAdmissionWebhook admission plugin.
- Create the certificate for communication between Kubernetes and the webhook server.
- Start the webhook server. This is a RESTful web server that handles requests to patch deployment requests prior to Kubernetes handling the requests.
- Create a service to allow the webhook server to be accessed.
- Deploy the webhook configuration. This registers the IBM Application Gateway admission controller with Kubernetes such that it will be called for each deployment request prior to Kubernetes handling the request.
Enabling the MutatingAdmissionWebhook admission plugin
The IBM Application Gateway admission controller is a mutating admission webhook and requires the MutatingAdmissionWebhook plugin to be enabled.
To enable the plugin pass the flag to the Kubernetes API server.
kube-apiserver --enable-admission-plugins=MutatingAdmissionWebhook
Depending on the environment the exact way to enable the plugin may differ. For example to enable the plugin in a Minikube cluster:
minikube start --extra-config=apiserver.enable-admission-plugins="MutatingAdmissionWebhook"
Create server certificate
The Kubernetes admission controller makes HTTPS calls to a webhook server to validate or patch the request object. This means that the admission controller client and the server need a set of predefined certificates to allow communication. See TLS Certificates for a short description of the requirements for the certificates.
The main requirement is that the common name (CN) of the must match the server name used by the Kubernetes API server. This will be of the form:
<service-name>.<namespace>.svc
where service-name is the name of the Kubernetes service that is created to access the webhook server and namespace is the Kubernetes namespace that the admission controller is deployed in.
The following sections show how to create a server certificate, which can be a certificate signed by Kubernetes or a self signed certificate.
Create Kubernetes Signed Certificate
The following steps describe how to create a certificate signed by the Kubernetes CA.
- Generate the CA key
openssl genrsa -out webhook-server-tls-key.pem 2048
- Generate a certificate signing request
Copy the following into a file named csr.conf and replace the values in brackets (<>) with the correct values:
- k8s_namespace is the Kubernetes namespace (eg: default)
- webhook_service_name is the name of the webhook service defined in Create the webhook service (eg: ibm-application-gateway-injector-webhook-svc)
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = <webhook_service_name>
DNS.2 = <webhook_service_name>.<k8s_namespace>
DNS.3 = <webhook_service_name>.<k8s_namespace>.svc
openssl req -new -key webhook-server-tls-key.pem -subj "/CN=ibm-application-gateway-injector-webhook-svc.default.svc" -out server.csr -config csr.conf
- Create a Certificate Signing Request object to send to the Kubernetes API
Replace the values in brackets (<>) with the correct values:
- k8s_namespace is the Kubernetes namespace (eg: default)
- webhook_service_name is the name of the webhook service defined in Create the webhook service (eg: ibm-application-gateway-injector-webhook-svc)
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: <webhook_service_name>.<k8s_namespace>
spec:
request: $(cat server.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
- Approve the certificate signing request
Replace <csr_name> with the name of the Kubernetes Certificate Signing Request in the previous step.
kubectl certificate approve <csr_name>
- Create the base64 encoded server certificate file
Replace <csr_name> with the name of the Kubernetes Certificate Signing Request in step 3.
kubectl get csr <csr_name> -o jsonpath='{.status.certificate}' | openssl base64 -d -A -out webhook-server-tls-crt.pem
- Create the Kubernetes secret
kubectl create secret generic ibm-application-gateway-webhook-certs --from-file=key.pem=webhook-server-tls-key.pem --from-file=cert.pem=webhook-server-tls-crt.pem --dry-run -o yaml | kubectl apply -f -
Create Self Signed Certificate
The following commands show how a self signed certificate can be created and added to a Kubernetes secret that can be used by the IBM Application Gateway admission controller.
Replace the values in brackets (<>) with the correct values:
- k8s_namespace is the Kubernetes namespace (eg: default)
- webhook_service_name is the name of the webhook service defined in Create the webhook service (eg: ibm-application-gateway-injector-webhook-svc)
openssl req -nodes -new -x509 -keyout ca.key -out ca.crt -subj "/CN=IBM Application Gateway Webhook CA"
openssl genrsa -out webhook-server-tls-key.pem 2048
openssl req -new -key webhook-server-tls-key.pem -subj "/CN=<webhook_service_name>.<k8s_namespace>.svc" | openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -out webhook-server-tls-crt.pem
kubectl create secret generic ibm-application-gateway-webhook-certs --from-file=key.pem=webhook-server-tls-key.pem --from-file=cert.pem=webhook-server-tls-crt.pem --dry-run -o yaml | kubectl apply -f -
Start the webhook server
The IBM Application Gateway admission controller webhook server runs as part of the IBM Application Gateway operator.
Starting the webhook server if the operator has already been deployed
The following steps will deploy and start the webhook server if the operator has already been deployed.
- Modify the operator Deployment YAML (eg: operator.yaml) to include the webhook application labels and the certificate volume source.
apiVersion: apps/v1
kind: Deployment
metadata:
name: ibm-application-gateway-operator
labels:
app: ibm-application-gateway-injector
spec:
replicas: 1
selector:
matchLabels:
name: ibm-application-gateway-operator
app: ibm-application-gateway-injector
template:
metadata:
labels:
name: ibm-application-gateway-operator
app: ibm-application-gateway-injector
spec:
serviceAccountName: ibm-application-gateway-operator
imagePullSecrets:
- name: regcred
containers:
- name: ibm-application-gateway-operator
image: ibmcom/ibm-application-gateway-operator:21.12.0
command:
- ibm-application-gateway-operator
imagePullPolicy: Never
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OPERATOR_NAME
value: "ibm-application-gateway-operator"
volumeMounts:
- name: webhook-certs
mountPath: /etc/webhook/certs
readOnly: true
volumes:
- name: webhook-certs
secret:
secretName: ibm-application-gateway-webhook-certs
- Restart the operator
kubectl apply -f operator.yaml
Starting the webhook server if the operator has NOT already been deployed
The following steps will deploy and start the webhook server if the operator has not already been deployed.
- Create the operator service account.
apiVersion: v1
kind: ServiceAccount
metadata:
name: ibm-application-gateway-operator
kubectl apply -f service_account.yaml
- Create the role binding
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: ibm-application-gateway-operator
rules:
- apiGroups:
- ""
resources:
- pods
- services
- services/finalizers
- endpoints
- persistentvolumeclaims
- events
- configmaps
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- deployments
- deployments/status
- daemonsets
- replicasets
- statefulsets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
verbs:
- get
- create
- apiGroups:
- apps
resourceNames:
- ibm-application-gateway-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resources:
- replicasets
- deployments
verbs:
- get
- apiGroups:
- ibm.com
resources:
- '*'
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ibm-application-gateway-operator
subjects:
- kind: ServiceAccount
name: ibm-application-gateway-operator
- kind: ServiceAccount
name: ibm-application-gateway
roleRef:
kind: Role
name: ibm-application-gateway-operator
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac.yaml
- Deploy the custom resource definition
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ibmapplicationgateways.ibm.com
spec:
group: ibm.com
names:
kind: IBMApplicationGateway
listKind: IBMApplicationGatewayList
plural: ibmapplicationgateways
singular: ibmapplicationgateway
scope: Namespaced
subresources:
status: {}
scale:
# specReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Spec.Replicas.
specReplicasPath: .spec.replicas
# statusReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Replicas.
statusReplicasPath: .status.replicas
# labelSelectorPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Selector.
labelSelectorPath: .status.labelSelector
validation:
openAPIV3Schema:
description: IAG is the Schema for the iags API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: IAGSpec defines the desired state of IAG.
type: object
properties:
replicas:
type: integer
description: The number of IBM Application Gateway replicas to create.
deployment:
type: object
description: Defines the IBM Application Gateway deployment properties.
properties:
image:
description: The name, tag and location of the IBM Application Gateway docker image.
type: string
imagePullPolicy:
description: The policy used to decide when to pull the IBM Application Gateway docker image from a remote server. Default value is IfNotPresent.
type: string
enum:
- Never
- Always
- IfNotPresent
imagePullSecrets:
type: array
description: A list of Kubernetes secrets that will be set on the IBM Application Gateway deployment.
items:
type: object
properties:
name:
type: string
description: The name of the Kubernetes secret that defines the required remote server authentication credentials.
required:
- name
serviceAccountName:
description: The Kubernetes service account that will run the IBM Application Gateway applications.
type: string
lang:
description: The language for the IBM Application Gateway application. Default value is English (en).
type: string
readinessProbe:
type: object
description: The settings for the readiness probe.
properties:
initialDelaySeconds:
description: The initial delay (in seconds) before starting the IBM Application Gateway application readiness poll. Default value is 0. Minimum value is 0.
type: integer
minimum: 0
periodSeconds:
description: The wait period (in seconds) between IBM Application Gateway application readiness polling. Default value is 10. Minimum value is 1.
type: integer
minimum: 1
failureThreshold:
description: The number of times the probe will be tried before failing. Failure will result in the Pod will be marked Unready. Default value is 3. Minimum value is 1.
type: integer
minimum: 1
successThreshold:
description: The number of consecutive successes for the probe to be considered successful after having failed. Default value is 1. Minimum value is 1.
type: integer
minimum: 1
timeoutSeconds:
description: The number of seconds after which the probe times out. Default value is 1. Minimum value is 1.
type: integer
minimum: 1
livenessProbe:
type: object
description: The settings for the liveness probe.
properties:
initialDelaySeconds:
description: The initial delay (in seconds) before starting the IBM Application Gateway application liveness poll. Default value is 0. Minimum value is 0.
type: integer
minimum: 0
periodSeconds:
description: The wait period (in seconds) between IBM Application Gateway application liveness polling. Default value is 10. Minimum value is 1.
type: integer
minimum: 1
failureThreshold:
description: The number of times the probe will be tried before failing. Failure will result in the container being restarted. Default value is 3. Minimum value is 1.
type: integer
minimum: 1
timeoutSeconds:
description: The number of seconds after which the probe times out. Default value is 1. Minimum value is 1.
type: integer
minimum: 1
required:
- image
configuration:
type: array
description: Defines the IBM Application Gateway configuration properties.
items:
type: object
properties:
type:
type: string
enum:
- configmap
- literal
- web
- oidc_registration
name:
type: string
description: The name of the config map that contains the IBM Application Gateway configuration. Required for configmap type.
dataKey:
type: string
description: The config map YAML entry that contains the IBM Application Gateway configuration. Required for configmap type.
value:
type: string
description: The IBM Application Gateway configuration YAML text. Required for literal type.
url:
type: string
description: The URL location of the remote IBM Application Gateway configuration. Required for web type.
discoveryEndpoint:
type: string
description: The discovery endpoint used to retrieve the OIDC OP registration endpoint to dynamically register a new client. Required for oidc_registration type.
postData:
type: array
description: A list of keys and values that will be added to the registration request as POST data. This must include the mandatory redirect_uris value. Required for oidc_registration type.
items:
type: object
properties:
name:
type: string
description: The key name of the data value to add to the request.
value:
type: string
description: A single data value to add to the request. If this property is specified the values property will be ignored. Required if the values property has not been specified.
values:
type: array
description: A list of data values to add to the request as an array. If the value property has been specified this property will be ignored. Required if the value property has not been specified.
items:
type: string
required:
- name
secret:
type: string
description: The name of a Kubernetes secret that contains any authorization data required for the OIDC client registration. The resulting client_id and secret will also be added to this secret. Required for oidc_registration type.
headers:
type: array
description: A list of headers to add to the HTTP request to retrieve the configuration source.
items:
type: object
properties:
type:
type: string
description: The value type. A literal type will add the value directly to the new header. A secret type will lookup a Kubernetes secret to retrieve the value.
enum:
- literal
- secret
name:
type: string
description: The name of the header that will be added to the HTTP request.
value:
type: string
description: The value of the header that will be added to the HTTP request. If the type is set as secret this will be the name of the Kubernetes secret.
secretKey:
type: string
description: The key name to retrieve the header value from the specified Kubernetes secret. Required if the type is set as secret.
required:
- type
- name
- value
required:
- type
status:
description: IAGStatus defines the observed state of IAG
type: object
type: object
version: v1
versions:
- name: v1
served: true
storage: true
kubectl apply -f crd.yaml
- Deploy the operator (webhook server)
apiVersion: apps/v1
kind: Deployment
metadata:
name: ibm-application-gateway-operator
labels:
app: ibm-application-gateway-injector
spec:
replicas: 1
selector:
matchLabels:
name: ibm-application-gateway-operator
app: ibm-application-gateway-injector
template:
metadata:
labels:
name: ibm-application-gateway-operator
app: ibm-application-gateway-injector
spec:
serviceAccountName: ibm-application-gateway-operator
imagePullSecrets:
- name: regcred
containers:
- name: ibm-application-gateway-operator
image: ibmcom/ibm-application-gateway-operator:21.12.0
command:
- ibm-application-gateway-operator
imagePullPolicy: Never
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OPERATOR_NAME
value: "ibm-application-gateway-operator"
volumeMounts:
- name: webhook-certs
mountPath: /etc/webhook/certs
readOnly: true
volumes:
- name: webhook-certs
secret:
secretName: ibm-application-gateway-injector-webhook-certs
kubectl apply -f operator.yaml
Create the webhook service
The webhook server is running and listening internally on port 443. A Kubernetes service needs to be created that will expose the internal port outside of the container.
Note
The name of the service that is created must match the common name prefix that was used to generate the certificates.
apiVersion: v1
kind: Service
metadata:
name: ibm-application-gateway-injector-webhook-svc
namespace: default
labels:
app: ibm-application-gateway-injector
spec:
ports:
- port: 443
targetPort: 8443
selector:
app: ibm-application-gateway-injector
kubectl apply -f service.yaml
Deploy the webhook configuration.
The IBM Application Gateway admission controller needs to be registered in Kubernetes so that it will be called as part of the deployment management process.
The clientConfig section of the webhook configuration must reference:
- The new service that was created so that the admission controller knows how to contact the webhook server.
- The certificate to use when communicating with the webhook server.
cat << EOF | kubectl apply -f -
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ibm-application-gateway-injector-webhook-cfg
labels:
app: ibm-application-gateway-injector
webhooks:
- name: ibm-application-gateway-injector.ibm.com
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: NoneOnDryRun
clientConfig:
service:
name: ibm-application-gateway-injector-webhook-svc
namespace: default
path: "/mutate"
caBundle: "$(kubectl get secrets/ibm-application-gateway-webhook-certs -o jsonpath="{.data.cert\.pem}")"
rules:
- operations: ["CREATE", "UPDATE", "DELETE"]
apiGroups: ["apps", ""]
apiVersions: ["v1"]
resources: ["deployments"]
EOF
At this point the IBM Application Gateway admission controller is running and ready to go.
Deployment sidecar annotations
Each registered admission controller will be called by Kubernetes for each deployment management request. This means that there needs to be a method by which the admission controller can determine whether or not to perform any mutation. The IBM Application Gateway admission controller will check the deployment annotations to decide whether or not to handle container modifications.
If any of the annotation keys has a prefix of "ibm-application-gateway.security.ibm.com/" the IBM Application Gateway admission controller will mutate the request. The annotation keys and values are used to determine how the IBM Application Gateway sidecar container will be configured.
The supported annotations are mapped in the following categories:
- Deployment
- Service
- Configuration
- Environment
Deployment annotations
Deployment annotations define how the IBM Application Gateway sidecar container is deployment will be generated. The supported deployment keys are:
Name | Description |
---|---|
ibm-application-gateway.security.ibm.com/deployment.image | The name, tag and location of the IBM Application Gateway docker image. This is a required value and if not specified or the value is incorrect the request will fail. |
ibm-application-gateway.security.ibm.com/deployment.imagePullPolicy | The policy used to decide when to pull the IBM Application Gateway docker image from a remote server. If not specified the value will be set to ifNotPresent. |
Note: If a imagePullSecret is required to pull the image it must be defined in the application deployment YAML.
Example:
ibm-application-gateway.security.ibm.com/deployment.image: ibmcom/ibm-application-gateway:21.12.0
ibm-application-gateway.security.ibm.com/deployment.imagePullPolicy: IfNotPresent
Service annotations
The IBM Application Gateway admission controller may add a new IBM Application Gateway sidecar container alongside the application. To be able to access the 8443 port of the sidecar container a new service may be required. If the service annotation is specified, the admission controller will create the new service exposing the port.
Note
This new service will be created by the admission controller. This means that the service will exist even if the Kubernetes deployment operation fails.
The supported service keys are:
Name | Description |
---|---|
ibm-application-gateway.security.ibm.com/service.port | The port to expose the internal 8443 port on. If not specified the service will not be created. |
Example:
ibm-application-gateway.security.ibm.com/service.port: "30441"
will result in a new service being created:
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2020-06-10T06:05:45Z"
generateName: appname-ibm-application-gateway-sidecar-svc
labels:
app: appname-ibm-application-gateway-sidecar-svc
name: appname-ibm-application-gateway-sidecar-svcrdfqh
namespace: default
spec:
ports:
- name: appname-ibm-application-gateway-sidecar-svc
nodePort: 30441
port: 8443
protocol: TCP
targetPort: 8443
selector:
app: appname-ibm-application-gateway-sidecar-pod
type: NodePort
Configuration annotations
The IBM Application Gateway sidecar container requires YAML configuration in order for it to run. The configuration can be created in one or more Kubernetes configmaps and/or one or more external web sources. The configuration sources are merged into a master configmap that is made available to the IBM Application Gateway sidecar container.
Note
The new master configmap will be created by the admission controller. This means that the configmap will exist even if the Kubernetes deployment operation fails.
The supported configuration keys are:
Name | Description |
---|---|
ibm-application-gateway.security.ibm.com/configuration.<id>.type | The type of the configuration source. The id must be unique for each separate source. The supported values are "configmap", "web" or "oidc_registration". Note that there can only be a single oidc_registration entry. |
ibm-application-gateway.security.ibm.com/configuration.<id>.order | The order in which to merge the configuration source into the master configmap. Later merges will overwrite any earlier values apart from array entries where the master configmap will contain all specified array entries from all sources. Note that the oidc_registration entry will always be merged last. |
ibm-application-gateway.security.ibm.com/configuration.<id>.name | The name of the config map that contains the IBM Application Gateway configuration. Required for configmap type. |
ibm-application-gateway.security.ibm.com/configuration.<id>.dataKey | The config map YAML entry that contains the IBM Application Gateway configuration. Required for configmap type. |
ibm-application-gateway.security.ibm.com/configuration.<id>.url | The URL location of the remote IBM Application Gateway configuration. Required for web type. |
ibm-application-gateway.security.ibm.com/configuration.<id>.header.<hdrid>.type | The type of header value to add to the request. A literal type will add the value directly to the new header. A secret type will lookup a Kubernetes secret to retrieve the value. The hdrid must be unique for each header. |
ibm-application-gateway.security.ibm.com/configuration.<id>.header.<hdrid>.name | The name of the header that will be added to the HTTP request. |
ibm-application-gateway.security.ibm.com/configuration.<id>.header.<hdrid>.value | The value of the header that will be added to the HTTP request. If the type is set as secret this will be the name of the Kubernetes secret. |
ibm-application-gateway.security.ibm.com/configuration.<id>.header.<hdrid>.secretKey | The key name to retrieve the header value from the specified Kubernetes secret. Required if the type is set as secret. |
ibm-application-gateway.security.ibm.com/configuration.<id>.discoveryEndpoint | The endpoint that can be used to discover the registration endpoint and token endpoint of the OIDC OP. Required for oidc_registration type. |
ibm-application-gateway.security.ibm.com/configuration.<id>.secret | Specifies a Kubernetes secret that may contain authorization data for the registration request. This is also the location where the resulting client ID and secret are stored upon successful registration. Required for oidc_registration type. |
ibm-application-gateway.security.ibm.com/configuration.<id>.postData.<pdid>.name | The name of a POST data entry that will be added to the registration request as POST data. Only valid for oidc_registration type. |
ibm-application-gateway.security.ibm.com/configuration.<id>.postData.<pdid>.value | A single value of the POST data entry that will be added to the registration request as POST data. Only valid for oidc_registration type. |
ibm-application-gateway.security.ibm.com/configuration.<id>.postData.<pdid>.values.<valueid> | A value that will be added to an array of values for the POST data entry that will be added to the registration request as POST data. This will be ignored if a single "value" has been set. Only valid for oidc_registration type. |
Example:
ibm-application-gateway.security.ibm.com/configuration.test.type: configmap
ibm-application-gateway.security.ibm.com/configuration.test.name: test-config
ibm-application-gateway.security.ibm.com/configuration.test.dataKey: config
ibm-application-gateway.security.ibm.com/configuration.test.order: "1"
ibm-application-gateway.security.ibm.com/configuration.sample.type: "web"
ibm-application-gateway.security.ibm.com/configuration.sample.url: https://raw.github.ibm.com/IAG/iag-config/master/test/sample1.yaml
ibm-application-gateway.security.ibm.com/configuration.sample.order: "2"
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.type: secret
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.name: Authorization
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.value: githubsecret
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.secretKey: value
ibm-application-gateway.security.ibm.com/configuration.oidc.type: oidc_registration
ibm-application-gateway.security.ibm.com/configuration.oidc.discoveryEndpoint: https://ibm-app-gw.verify.ibm.com/oidc/endpoint/default/.well-known/openid-configuration
ibm-application-gateway.security.ibm.com/configuration.oidc.secret: oidc-client
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.rduri.name: redirect_uris
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.rduri.values.value1: https://127.0.0.1:30112/pkmsoidc
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.cn.name: client_name
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.cn.value: OperatorTest
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.aue.name: all_users_entitled
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.aue.value: "true"
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.ep.name: enforce_pkce
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.ep.value: "false"
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.ca.name: consent_action
ibm-application-gateway.security.ibm.com/configuration.oidc.postData.ca.value: "never_prompt"
ibm-application-gateway.security.ibm.com/configuration.oidc.order: "3"
will result in a new master configmap being created:
apiVersion: v1
data:
config.yaml: |
identity:
oidc:
client_id: secret:oidc-client/client_id
client_secret: secret:oidc-client/client_secret
discovery_endpoint: https://ibm-app-gw.verify.ibm.com/oidc/endpoint/default/.well-known/openid-configuration
resource_servers:
- connection_type: tcp
path: /sample
servers:
- host: 10.0.0.12
port: 80
- connection_type: tcp
path: /eai
servers:
- host: 10.0.0.15
port: 8080
server:
local_applications:
cred_viewer:
enable_html: false
path_segment: creds
version: "21.12"
kind: ConfigMap
metadata:
creationTimestamp: "2020-06-10T06:05:47Z"
generateName: appname-ibm-application-gateway-sidecar-configmap
labels:
app: appname-ibm-application-gateway-sidecar-pod
name: appname-ibm-application-gateway-sidecar-configmap9c8dm
namespace: default
The config.yaml data value is a merging of the three defined configuration sources.
Environment annotations
The IBM Application Gateway sidecar container may require certain environment variables to be set to operate correctly. Environment annotations allow these environment variable values to be set.
The supported environment keys are:
Name | Description |
---|---|
ibm-application-gateway.security.ibm.com/env.<name> | This will result in a new environment variable being set where <name> specifies the name of the variable (case sensitive) and the specified value. |
Example:
ibm-application-gateway.security.ibm.com/env.LANG: fr
will result in a new environment variable being set "LANG=fr".
Deployment example
Assuming that the IBM Application Gateway admission controller has been setup and deployed the following deployment will result in an IBM Application Gateway sidecar container being created alongside the application:
apiVersion: apps/v1
kind: Deployment
metadata:
name: testapp
labels:
app: testapp
name: testapp
annotations:
ibm-application-gateway.security.ibm.com/env.LANG: en
ibm-application-gateway.security.ibm.com/configuration.test.type: configmap
ibm-application-gateway.security.ibm.com/configuration.test.name: test-config
ibm-application-gateway.security.ibm.com/configuration.test.dataKey: config
ibm-application-gateway.security.ibm.com/configuration.test.order: "1"
ibm-application-gateway.security.ibm.com/configuration.sample.type: "web"
ibm-application-gateway.security.ibm.com/configuration.sample.url: https://raw.github.ibm.com/IAG/iag-config/master/test/sample1.yaml
ibm-application-gateway.security.ibm.com/configuration.sample.order: "2"
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.type: secret
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.name: Authorization
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.value: githubsecret
ibm-application-gateway.security.ibm.com/configuration.sample.header.authz.secretKey: value
ibm-application-gateway.security.ibm.com/deployment.image: ibmcom/ibm-application-gateway:21.12.0
ibm-application-gateway.security.ibm.com/deployment.imagePullPolicy: IfNotPresent
ibm-application-gateway.security.ibm.com/service.port: "30441"
spec:
selector:
matchLabels:
app: testapp
name: testapp
replicas: 1
template:
metadata:
labels:
app: testapp
name: testapp
spec:
imagePullSecrets:
- name: regcred
containers:
- name: testapp
image: alpine
command:
- /bin/sh
- "-c"
- "sleep 70m"
imagePullPolicy: IfNotPresent
kubectl apply -f deployment.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
ibm-application-gateway-operator-58d7df64d9-848jz 1/1 Running. 1 1d
testapp-645db9c874-bmq4k 2/2 Running 1 1d
Note
The testapp pod has 2 containers that are both ready.
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
testapp-ibm-application-gateway-sidecar-svcrdfqh NodePort 10.109.167.144 <none> 8443:30441/TCP 1d
$ kubectl get configmaps
NAME DATA AGE
test-config 1 6d
testapp-ibm-application-gateway-sidecar-configmap9c8dm 1 1d
Supported RESTful operations
Create
When a deployment is first created the IBM Application Gateway admission controller will be called with a RESTful create operation. The admission controller will perform the following tasks:
- Check to see if the deployment annotations contains any keys with the prefix "ibm-application-gateway.security.ibm.com/". If not then the admission controller will make no changes and return.
- Run some validation on the annotations to try and ensure that no simple failures will occur leaving the environment in an intermediate state.
- Check to see if the annotations contain a service port. If so a new service will be created.
- Read and merge the configuration sources to create a new master configmap.
- Return a new IBM Application Gateway container patch as the response. This will result in the IBM Application Gateway sidecar being created alongside the application.
Update
When a deployment is modified the IBM Application Gateway admission controller will be called with a RESTful update operation. The admission controller will perform the following tasks:
- Check to see if the deployment annotations contains any keys with the prefix "ibm-application-gateway.security.ibm.com/". If not then the admission controller will make no changes and return.
- Run some validation on the annotations to try and ensure that no simple failures will occur leaving the environment in an intermediate state.
- Check to see if the annotations contain a service port. If so the service will be updated if the port has changed.
- Read and merge the configuration sources to create a new master configmap.
- Return a new IBM Application Gateway container patch as the response. This will result in the IBM Application Gateway sidecar being updated alongside the application.
Delete
When a deployment is deleted the IBM Application Gateway admission controller will be called with a RESTful delete operation. The admission controller will perform the following tasks:
- Check to see if the deployment annotations contains any keys with the prefix "ibm-application-gateway.security.ibm.com/". If not then the admission controller will make no changes and return.
- Delete the service if it exists.
- Delete the master configmap.
Updated 4 months ago