Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: apiserver.k8s.io/v1beta1
kind: EgressSelectorConfiguration
egressSelections:
- name: "cluster"
connection:
proxyProtocol: "HTTPConnect"
transport:
uds:
udsName: "/etc/kubernetes/config/konnectivity-server.socket"
- name: "controlplane"
connection:
proxyProtocol: "Direct"
- name: "etcd"
connection:
proxyProtocol: "Direct"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: kubecontrolplane.config.openshift.io/v1
kind: KubeAPIServerConfig
apiServerArguments:
egress-selector-config-file:
- "/etc/kubernetes/config/egress-selector-config.yaml"
234 changes: 233 additions & 1 deletion data/data/bootstrap/files/usr/local/bin/bootkube.sh.template
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ OPENSHIFT_HYPERKUBE_IMAGE=$(image_for hyperkube)
OPENSHIFT_CLUSTER_POLICY_IMAGE=$(image_for cluster-policy-controller)

CLUSTER_BOOTSTRAP_IMAGE=$(image_for cluster-bootstrap)
KONNECTIVITY_IMAGE=$(image_for apiserver-network-proxy)

mkdir --parents ./{bootstrap-manifests,manifests}

Expand Down Expand Up @@ -244,6 +245,133 @@ then
record_service_stage_success
fi

# Detect bootstrap node IP at runtime using the default route source address
# This is needed for Konnectivity agents to connect back to the bootstrap server.
{{- if .UseIPv6ForNodeIP }}
BOOTSTRAP_NODE_IP=$(ip -6 route get 2001:4860:4860::8888 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1); exit}')
{{- else }}
BOOTSTRAP_NODE_IP=$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") print $(i+1); exit}')
{{- end }}
echo "Detected bootstrap node IP: ${BOOTSTRAP_NODE_IP}"

# Generate Konnectivity certificates with self-signed CA (1-day validity)
# These are needed for mTLS between Konnectivity server and agents.
# We use a self-signed CA because root-ca.key is not available on the bootstrap node.
if [ ! -f konnectivity-certs.done ]
then
record_service_stage_start "konnectivity-certs"
echo "Generating Konnectivity certificates..."

KONNECTIVITY_CERT_DIR=/opt/openshift/tls/konnectivity
mkdir -p "${KONNECTIVITY_CERT_DIR}"

# Generate self-signed Konnectivity CA
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout "${KONNECTIVITY_CERT_DIR}/ca.key" \
-out "${KONNECTIVITY_CERT_DIR}/ca.crt" \
-days 1 \
-subj "/CN=konnectivity-signer/O=openshift"

# Server certificate for agent endpoint
openssl req -new -newkey rsa:2048 -nodes \
-keyout "${KONNECTIVITY_CERT_DIR}/server.key" \
-out "${KONNECTIVITY_CERT_DIR}/server.csr" \
-subj "/CN=konnectivity-server/O=openshift"

openssl x509 -req -in "${KONNECTIVITY_CERT_DIR}/server.csr" \
-CA "${KONNECTIVITY_CERT_DIR}/ca.crt" \
-CAkey "${KONNECTIVITY_CERT_DIR}/ca.key" \
-CAcreateserial \
-out "${KONNECTIVITY_CERT_DIR}/server.crt" \
-days 1 \
-extfile <(printf "extendedKeyUsage=serverAuth\nsubjectAltName=IP:${BOOTSTRAP_NODE_IP}")

# Agent client certificate (shared by all agents)
openssl req -new -newkey rsa:2048 -nodes \
-keyout "${KONNECTIVITY_CERT_DIR}/agent.key" \
-out "${KONNECTIVITY_CERT_DIR}/agent.csr" \
-subj "/CN=konnectivity-agent/O=openshift"

openssl x509 -req -in "${KONNECTIVITY_CERT_DIR}/agent.csr" \
-CA "${KONNECTIVITY_CERT_DIR}/ca.crt" \
-CAkey "${KONNECTIVITY_CERT_DIR}/ca.key" \
-CAcreateserial \
-out "${KONNECTIVITY_CERT_DIR}/agent.crt" \
-days 1 \
-extfile <(printf "extendedKeyUsage=clientAuth")

# Clean up CSR files
rm -f "${KONNECTIVITY_CERT_DIR}"/*.csr

echo "Generated Konnectivity certificates in ${KONNECTIVITY_CERT_DIR}"
touch konnectivity-certs.done
record_service_stage_success
fi

# Create Konnectivity server static pod manifest
# This runs on the bootstrap node and provides a proxy for the bootstrap KAS
# to reach webhooks in the cluster's pod network.
if [ ! -f konnectivity-server-bootstrap.done ]
then
record_service_stage_start "konnectivity-server-bootstrap"
echo "Creating Konnectivity server static pod manifest..."

cat > /etc/kubernetes/manifests/konnectivity-server-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: konnectivity-server
namespace: kube-system
labels:
app: konnectivity-server
spec:
hostNetwork: true
priorityClassName: system-node-critical
containers:
- name: konnectivity-server
image: ${KONNECTIVITY_IMAGE}
command:
- /usr/bin/proxy-server
args:
- --logtostderr=true
- --cluster-cert=/etc/konnectivity/server.crt
- --cluster-key=/etc/konnectivity/server.key
- --cluster-ca-cert=/etc/konnectivity/ca.crt
- --uds-name=/etc/kubernetes/bootstrap-configs/konnectivity-server.socket
- --server-port=0
- --agent-port=8091
- --health-port=2041
- --mode=http-connect
- --proxy-strategies=destHost,defaultRoute
- --keepalive-time=30s
- --frontend-keepalive-time=30s
livenessProbe:
httpGet:
path: /healthz
port: 2041
initialDelaySeconds: 10
periodSeconds: 10
volumeMounts:
- name: config-dir
mountPath: /etc/kubernetes/bootstrap-configs
- name: konnectivity-certs
mountPath: /etc/konnectivity
readOnly: true
volumes:
- name: config-dir
hostPath:
path: /etc/kubernetes/bootstrap-configs
type: DirectoryOrCreate
- name: konnectivity-certs
hostPath:
path: /opt/openshift/tls/konnectivity
type: Directory
EOF

touch konnectivity-server-bootstrap.done
record_service_stage_success
fi

if [ ! -f kube-apiserver-bootstrap.done ]
then
record_service_stage_start "kube-apiserver-bootstrap"
Expand All @@ -268,9 +396,12 @@ then
--infra-config-file=/assets/manifests/cluster-infrastructure-02-config.yml \
--rendered-manifest-files=/assets/manifests \
--payload-version=$VERSION \
--operand-kubernetes-version="${KUBERNETES_VERSION}"
--operand-kubernetes-version="${KUBERNETES_VERSION}" \
--config-override-files=/assets/konnectivity-config-override.yaml

cp kube-apiserver-bootstrap/config /etc/kubernetes/bootstrap-configs/kube-apiserver-config.yaml
# Copy egress selector config to bootstrap-configs where KAS can read it
cp /opt/openshift/egress-selector-config.yaml /etc/kubernetes/bootstrap-configs/egress-selector-config.yaml
cp kube-apiserver-bootstrap/bootstrap-manifests/* bootstrap-manifests/
cp kube-apiserver-bootstrap/manifests/* manifests/

Expand Down Expand Up @@ -565,6 +696,107 @@ then
record_service_stage_success
fi

# Create Konnectivity agent certificate Secret manifest for cluster deployment
# This Secret contains the TLS certs agents use to authenticate to the server.
if [ ! -f konnectivity-agent-certs-manifest.done ]
then
record_service_stage_start "konnectivity-agent-certs-manifest"
echo "Creating Konnectivity agent certificate Secret manifest..."

KONNECTIVITY_CERT_DIR=/opt/openshift/tls/konnectivity
cat > manifests/konnectivity-agent-certs.yaml <<EOF
apiVersion: v1
kind: Secret
metadata:
name: konnectivity-agent-certs
namespace: kube-system
labels:
app: konnectivity-agent
openshift.io/bootstrap-only: "true"
type: Opaque
data:
tls.crt: $(base64 -w0 "${KONNECTIVITY_CERT_DIR}/agent.crt")
tls.key: $(base64 -w0 "${KONNECTIVITY_CERT_DIR}/agent.key")
ca.crt: $(base64 -w0 "${KONNECTIVITY_CERT_DIR}/ca.crt")
EOF

touch konnectivity-agent-certs-manifest.done
record_service_stage_success
fi

# Create Konnectivity agent DaemonSet manifest for cluster deployment
# This manifest will be applied by cluster-bootstrap and runs agents on cluster nodes
# that connect back to the Konnectivity server on the bootstrap node.
if [ ! -f konnectivity-agent-manifest.done ]
then
record_service_stage_start "konnectivity-agent-manifest"
echo "Creating Konnectivity agent DaemonSet manifest..."

cat > manifests/konnectivity-agent-daemonset.yaml <<EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: konnectivity-agent
namespace: kube-system
labels:
app: konnectivity-agent
openshift.io/bootstrap-only: "true"
spec:
selector:
matchLabels:
app: konnectivity-agent
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 10%
template:
metadata:
labels:
app: konnectivity-agent
spec:
hostNetwork: true
dnsPolicy: Default
priorityClassName: system-node-critical
tolerations:
- operator: Exists
containers:
- name: konnectivity-agent
image: ${KONNECTIVITY_IMAGE}
command:
- /usr/bin/proxy-agent
args:
- --logtostderr=true
- --ca-cert=/etc/konnectivity/ca.crt
- --agent-cert=/etc/konnectivity/tls.crt
- --agent-key=/etc/konnectivity/tls.key
- --proxy-server-host=${BOOTSTRAP_NODE_IP}
- --proxy-server-port=8091
- --health-server-port=2041
- --agent-identifiers=default-route=true
- --keepalive-time=30s
- --probe-interval=5s
- --sync-interval=5s
- --sync-interval-cap=30s
livenessProbe:
httpGet:
path: /healthz
port: 2041
initialDelaySeconds: 10
periodSeconds: 10
volumeMounts:
- name: konnectivity-certs
mountPath: /etc/konnectivity
readOnly: true
volumes:
- name: konnectivity-certs
secret:
secretName: konnectivity-agent-certs
EOF

touch konnectivity-agent-manifest.done
record_service_stage_success
fi

REQUIRED_PODS="openshift-kube-apiserver/kube-apiserver,openshift-kube-scheduler/openshift-kube-scheduler,openshift-kube-controller-manager/kube-controller-manager,openshift-cluster-version/cluster-version-operator"
if [ "$BOOTSTRAP_INPLACE" = true ]
then
Expand Down
Loading