Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/aws-application-networking-k8s/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func main() {
TaggingServiceAPIDisabled: config.DisableTaggingServiceAPI,
}, metrics.Registry)
if err != nil {
setupLog.Fatal("cloud client setup failed: %s", err)
setupLog.Fatalf("cloud client setup failed: %s", err)
}

// do not create the webhook server when running locally
Expand Down
10 changes: 0 additions & 10 deletions config/rbac/cluster-role-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,9 @@ rules:
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
Expand Down
13 changes: 13 additions & 0 deletions docs/guides/pod-readiness-gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ This prevents the rolling update of a deployment from terminating old pods until
## Setup
Pod readiness gates rely on [»admission webhooks«](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/), where the Kubernetes API server makes calls to the AWS Gateway API controller as part of pod creation. This call is made using TLS, so the controller must present a TLS certificate. This certificate is stored as a standard Kubernetes secret. If you are using Helm, the certificate will automatically be configured as part of the Helm install.

For Helm installs, certificate validity is controlled by `webhookTLS.validityDays`.
The default is `36500` days to preserve existing behavior. You can opt in to
`365` days for annual certificate rotation:

```bash
helm upgrade --install gateway-api-controller \
oci://public.ecr.aws/aws-application-networking-k8s/aws-gateway-controller-chart \
--namespace aws-application-networking-system \
--set webhookTLS.validityDays=365
```

When using `365`, plan and automate annual certificate rotation.

If you are manually deploying the controller using the ```deploy.yaml``` file, you will need to either patch the ```deploy.yaml``` file (see ```scripts/patch-deploy-yaml.sh```) or generate the secret following installation (see ```scripts/gen-webhook-secret.sh```) and manually enable the webhook via the ```WEBHOOK_ENABLED``` environment variable.

Note that, without the secret in place, the controller cannot start successfully, and you will see an error message like the following:
Expand Down
5 changes: 3 additions & 2 deletions helm/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ caCert: {{ .Values.webhookTLS.caCert }}
cert: {{ .Values.webhookTLS.cert }}
key: {{ .Values.webhookTLS.key }}
{{- else -}}
{{- $ca := genCA "aws-gateway-controller-ca" 36500 -}}
{{- $certValidityDays := int (default 36500 .Values.webhookTLS.validityDays) -}}
{{- $ca := genCA "aws-gateway-controller-ca" $certValidityDays -}}
{{- $serviceDefaultName:= printf "webhook-service.%s.svc" .Release.Namespace -}}
{{- $secretName := "webhook-cert" -}}
{{- $altNames := list ($serviceDefaultName) (printf "%s.cluster.local" $serviceDefaultName) -}}
{{- $cert := genSignedCert $serviceDefaultName nil $altNames 36500 $ca -}}
{{- $cert := genSignedCert $serviceDefaultName nil $altNames $certValidityDays $ca -}}
caCert: {{ $ca.Cert | b64enc }}
cert: {{ $cert.Cert | b64enc }}
key: {{ $cert.Key | b64enc }}
Expand Down
10 changes: 0 additions & 10 deletions helm/templates/cluster-role-controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,9 @@ rules:
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
Expand Down
6 changes: 6 additions & 0 deletions helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ spec:
ports:
- name: http
containerPort: {{ .Values.deployment.containerPort }}
{{- if .Values.webhookEnabled }}
- name: webhook-server
containerPort: 9443
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
livenessProbe:
Expand All @@ -75,9 +77,11 @@ spec:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
{{- if .Values.webhookEnabled }}
- mountPath: /etc/webhook-cert
name: webhook-cert
readOnly: true
{{- end }}
env:
- name: REGION
value: {{ .Values.awsRegion | quote }}
Expand All @@ -104,10 +108,12 @@ spec:

terminationGracePeriodSeconds: 10
volumes:
{{- if .Values.webhookEnabled }}
- name: webhook-cert
secret:
defaultMode: 420
secretName: webhook-cert
{{- end }}
nodeSelector: {{ toYaml .Values.deployment.nodeSelector | nindent 8 }}
{{ if .Values.deployment.tolerations -}}
tolerations: {{ toYaml .Values.deployment.tolerations | nindent 8 }}
Expand Down
4 changes: 3 additions & 1 deletion helm/templates/webhook.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{- if .Values.webhookEnabled }}
{{ $tls := fromYaml ( include "aws-gateway-controller.webhookTLS" . ) }}
---
apiVersion: admissionregistration.k8s.io/v1
Expand Down Expand Up @@ -59,4 +60,5 @@ type: kubernetes.io/tls
data:
ca.crt: {{ $tls.caCert }}
tls.crt: {{ $tls.cert }}
tls.key: {{ $tls.key }}
tls.key: {{ $tls.key }}
{{- end }}
9 changes: 7 additions & 2 deletions helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,13 @@ webhookEnabled: true
disableTaggingServiceApi: false
routeMaxConcurrentReconciles:

# TLS cert/key for the webhook. If specified, values must be base64 encoded
# TLS cert/key for the webhook. If specified, values must be base64 encoded.
# When not provided, Helm generates self-signed certs using webhookTLS.validityDays.
webhookTLS:
caCert:
cert:
key:
key:
# Validity in days for generated webhook certificates.
# Default preserves existing behavior for installed clusters.
# Set to 365 to opt in to annual certificate rotation.
validityDays: 36500
19 changes: 14 additions & 5 deletions pkg/config/controller_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ var ServiceNetworkOverrideMode = false
var RouteMaxConcurrentReconciles = 1

func ConfigInit() error {
sess, _ := session.NewSession()
sess, err := session.NewSession()
if err != nil {
return fmt.Errorf("failed to create aws session: %w", err)
}
metadata := NewEC2Metadata(sess)
return configInit(sess, metadata)
}
Expand Down Expand Up @@ -128,10 +131,16 @@ func getClusterName(sess *session.Session) (string, error) {
return "", err
}
ec2Client := ec2.New(sess, &aws.Config{Region: aws.String(region)})
tagReq := &ec2.DescribeTagsInput{Filters: []*ec2.Filter{{
Name: aws.String("resource-id"),
Values: []*string{aws.String(instanceId)},
}}}
tagReq := &ec2.DescribeTagsInput{Filters: []*ec2.Filter{
{
Name: aws.String("resource-id"),
Values: []*string{aws.String(instanceId)},
},
{
Name: aws.String("key"),
Values: []*string{aws.String("aws:eks:cluster-name")},
},
}}
tagRes, err := ec2Client.DescribeTags(tagReq)
if err != nil {
return "", err
Expand Down
3 changes: 1 addition & 2 deletions pkg/controllers/pod_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ func RegisterPodController(log gwlog.Logger, mgr ctrl.Manager) error {
return err
}

//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch
//+kubebuilder:rbac:groups=core,resources=pods/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=core,resources=pods/finalizers,verbs=update

func (r *podReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
pod := &corev1.Pod{}
Expand Down
13 changes: 7 additions & 6 deletions scripts/gen-webhook-secret.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,30 @@
# Generates a certificate for use by the controller webhook
# You can also manually re-create the webhook secret using your own PKI

TEMP_KEY=`mktemp`
TEMP_CERT=`mktemp`
TEMP_KEY="$(mktemp)"
TEMP_CERT="$(mktemp)"

WEBHOOK_SVC_NAME=webhook-service
WEBHOOK_NAME=aws-appnet-gwc-mutating-webhook
WEBHOOK_NAMESPACE=aws-application-networking-system
WEBHOOK_SECRET_NAME=webhook-cert
WEBHOOK_CERT_VALIDITY_DAYS="${WEBHOOK_CERT_VALIDITY_DAYS:-36500}"

echo "Generating certificate for webhook"
HOST=${WEBHOOK_SVC_NAME}.${WEBHOOK_NAMESPACE}.svc
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout ${TEMP_KEY} -out ${TEMP_CERT} -subj "/CN=${HOST}/O=${HOST}" \
openssl req -x509 -nodes -days "${WEBHOOK_CERT_VALIDITY_DAYS}" -newkey rsa:2048 -keyout "${TEMP_KEY}" -out "${TEMP_CERT}" -subj "/CN=${HOST}/O=${HOST}" \
-addext "subjectAltName = DNS:${HOST}, DNS:${HOST}.cluster.local"

CERT_B64=`cat $TEMP_CERT | base64`
CERT_B64="$(base64 < "${TEMP_CERT}")"

echo "Recreating webhook secret"
kubectl delete secret $WEBHOOK_SECRET_NAME --namespace $WEBHOOK_NAMESPACE
kubectl create secret tls $WEBHOOK_SECRET_NAME --namespace $WEBHOOK_NAMESPACE --cert=${TEMP_CERT} --key=${TEMP_KEY}
kubectl create secret tls $WEBHOOK_SECRET_NAME --namespace $WEBHOOK_NAMESPACE --cert="${TEMP_CERT}" --key="${TEMP_KEY}"

echo "Patching webhook with new cert"
kubectl patch mutatingwebhookconfigurations.admissionregistration.k8s.io $WEBHOOK_NAME \
--namespace $WEBHOOK_NAMESPACE --type='json' \
-p="[{'op': 'replace', 'path': '/webhooks/0/clientConfig/caBundle', 'value': '${CERT_B64}'}]"

rm $TEMP_KEY $TEMP_CERT
rm -f "${TEMP_KEY}" "${TEMP_CERT}"
echo "Done"