As I can see the below page, I can set up two or three hosts in one Ingress. https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting
But how do I add a new host to existing ingress? I tried the commands like apply or patch, but it didn't work.
Is there anyone who know this solution?
kubectl patch -f sample-ingress.yml -p '
{"metadata": {"name": "sample-ingress"}, "spec": [{
"host": "39500000.sample.com",
"http": {"paths": [{
"backend": {"serviceName": "39500000", "servicePort": 8080}
}]
}}]
}'
The Ingress "sample-ingress" is invalid: spec.backend.serviceName: Required value
Ingress host rules The Host field defines the host where the request was sent to. This field is optional and if left blank will match all hosts. The Add Path button adds a new mapping between a request path and the Service resource port. The Path field is the path of the request to match.
If all ingress controllers respect IngressClasses (e.g. multiple instances of ingress-nginx v1. 0), you can deploy two Ingress controllers by granting them control over two different IngressClasses, then selecting one of the two IngressClasses with ingressClassName .
I personally prefer to use PATCH as my preferred approach to add an new host to an existing kubernetes ingress.
The command is going to look like this:
kubectl patch ingress my-ingress --type json --patch "$(cat patch.json)"
where patch.json is
[
{
"op" : "add" ,
"path" : "/spec/rules/-" ,
"value" : {
"host": "evil.facebook.com",
"http": {
"paths": [
{
"backend": {
"serviceName": "tracker-app",
"servicePort": 80
}
}
]
}
}
}
]
A few notes: - my-ingress is the name of the deployed ingress in the cluster - one can just paste the json instead of using this trick "$(cat patch.json)"
Also, the main thing about this solution is that it leverages kubernetes own capabilities to merge json according to these rules.
More information patching from an official source can be found here.
Here is my un-edited bash solution for this.
If there is any interest, I can re-write this to make it more transferable. I will leave comments in the script to guide you.
#!/bin/bash
# Update ingress with potential new hosts
# REQUIREMENTS: [An existing ingress with at least one host, and jq installed on host]
kubectl get ingress laravel-ingress -n=gitlab-ci -o json > original_json #CHANGE THIS VALUE TO QUERY YOUR EXISTING INGRESS
existing_hosts=()
exisiting_host_names=()
# I pass 3 arguments into the script. The first 2 are potential new hosts (if they aren't in the ingress already, and the 3rd arg helps me build the service name)
API_HOST=$1
DASHBOARD_HOST=$2
NAME=$3
name="$NAME"
potential_new_hosts=(
"$API_HOST"
"$DASHBOARD_HOST"
)
new_hosts=()
while read -r value
do
existing_host_names+=("$value")
done < <(cat original_json | jq ['.spec.rules[] | .host'])
# Loop through potential new hosts and add any non-existing ones to a new array.
for potential_new_host in "${potential_new_hosts[@]}"; do
i=0
for existing_host in "${existing_host_names[@]}"; do
if [[ "$existing_host" == "\"$potential_new_host\"," ]] ; then
i=1
fi
done
if [[ "$i" == 0 ]] ; then
# A non-existing host, add to an array
new_hosts+=("$potential_new_host")
fi
done
while read -r value2
do
existing_hosts+=("$value2")
done < <(cat original_json | jq ['.spec.rules[] | .'])
# Enable for debugging
#echo "Original json"
#cat original_json
#echo "Existing host names"
#printf '%s\n' "${existing_host_names[@]}"
#echo "New hosts"
#printf '%s\n' "${new_hosts[@]}"
#echo "Existing hosts before adding"
#printf '%s\n' "${existing_hosts[@]}"
#echo "Hosts after adding new ones"
########
# Begin building of hosts json to patch ingress with
output_json=""
for existing_host in "${existing_hosts[@]}"; do
output_json=("$output_json$existing_host")
done
# Truncate the last char in our json string (it's a ']', and we want to potentially add to this array for patching
output_json=${output_json::-1}
i=0
for new_host in "${new_hosts[@]}"; do
# Add to our json object the new host names with my hard-coded config
output_json=("$output_json,{\"host\":\"$new_host\",\"http\":{ \"paths\": [{ \"backend\":{ \"serviceName\":\"$name-laravel-web\",\"servicePort\":80} } ]} }")
i=1
done
printf '%s]\n' "$output_json" > new_json
if [[ "$i" == 1 ]] ; then
echo "Ingress json has changed and should be updated."
echo "OLD:"
cat original_json
echo "PATCH: \"spec\": {\"rules\": $output_json]}"
kubectl patch ingress laravel-ingress -n=gitlab-ci -p="\"spec\": {\"rules\": $output_json]}"
else
echo "Ingress json has not changed and will not be updated."
fi
Edit (fixed bugs and converted to single host per script execution)
#!/bin/bash
# Update ingress with potential new host
NEW_HOST=$1
INGRESS_NAME=$2
SERVICE_NAME=$3
echo "Running update-ingress for New host: $NEW_HOST, ingress: $INGRESS_NAME, service: $SERVICE_NAME"
echo " Downloading existing ingress config"
kubectl get ingress "$INGRESS_NAME" -n=gitlab-ci -o json > original_json
existing_hosts=()
exisiting_host_names=()
echo " $ kubectl get ingress $INGRESS_NAME -n=gitlab-ci -o json > original json && cat original_json"
cat original_json
name="$SERVICE_NAME"
potential_new_host="$NEW_HOST"
new_hosts=()
echo "Looping through json values1"
cat original_json | jq ['.spec.rules[] | .host']
for value in $(cat original_json | jq ['.spec.rules[] | .host']);
do
# Replace all commas with ""
value=${value/,/""}
existing_host_names+=("$value")
echo "Looping v1: value:$value"
#printf 'Array: %s' "${existing_host_names[*]}"
done
echo "Right after values1"
i=0
for existing_host in "${existing_host_names[@]}"; do
echo "Looping through existing host: $existing_host == $potential_new_host"
if [[ "$existing_host" == "\"$potential_new_host\"" ]] ; then
i=1
fi
done
if [[ "$i" == 0 ]] ; then
new_hosts+=("$potential_new_host")
fi
echo "Looping through json values2"
for value2 in $(cat original_json | jq ['.spec.rules[] | .']);
do
existing_hosts+=("$value2")
#echo "existing host! $values2"
#printf 'Array: %s' "{existing_hosts[*]}"
done
echo "Original json"
#cat original_json
echo "Existing host names"
printf '%s\n' "${existing_host_names[@]}"
echo "New hosts"
printf '%s\n' "${new_hosts[@]}"
echo "Existing hosts before adding"
printf '%s\n' "${existing_hosts[@]}"
echo "Hosts after adding new ones"
output_json=""
for existing_host in "${existing_hosts[@]}"; do
output_json=("$output_json$existing_host")
done
output_json=${output_json::-1}
i=0
for new_host in "${new_hosts[@]}"; do
output_json=("$output_json,{\"host\":\"$new_host\",\"http\":{ \"paths\": [{ \"backend\":{ \"serviceName\":\"$SERVICE_NAME-laravel-web\",\"servicePort\":80} }, { \"backend\":{ \"serviceName\":\"$SERVICE_NAME-laravel-web\",\"servicePort\":443} } ]} }")
i=1
done
printf '%s]\n' "$output_json" > new_json
if [[ "$i" == 1 ]] ; then
echo "Ingress json has changed and should be updated."
echo "OLD:"
cat original_json
echo "PATCH: \"spec\": {\"rules\": $output_json]}"
kubectl patch ingress "$INGRESS_NAME" -n=gitlab-ci -p="\"spec\": {\"rules\": $output_json]}"
else
echo "Ingress json has not changed and will not be updated."
fi
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With