如何在kubernetes中为现有的Ingress添加新主机?

时间:2017-04-24 20:18:11

标签: kubernetes

正如我可以看到下面的页面,我可以在一个Ingress中设置两个或三个主机。 https://kubernetes.io/docs/concepts/services-networking/ingress/#name-based-virtual-hosting

但是如何在现有入口处添加新主机? 我尝试过像apply或patch这样的命令,但它没有用。

有没有人知道这个解决方案?

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

3 个答案:

答案 0 :(得分:2)

这是我未经编辑的bash解决方案。

如果有任何兴趣,我可以重新写一下,以使其更易转移。我将在脚本中留下评论以指导您。

#!/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

编辑(修复错误并按脚本执行转换为单个主机)

#!/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

答案 1 :(得分:2)

我个人更喜欢使用 PATCH 作为将新主机添加到现有kubernetes入口的首选方法。

该命令将如下所示: mySelect.selectionChange

patch.json在哪里

kubectl patch ingress my-ingress --type json --patch "$(cat patch.json)"

一些注意事项:  -my-ingress是集群中已部署入口的名称  -只需粘贴json即可,而不使用此技巧“ $(cat patch.json)”

此外,此解决方案的主要优点是利用kubernetes自身的功能来根据these rules合并json。

可以从found here处获得来自官方来源的更多信息补丁。

答案 2 :(得分:0)

您可以使用kubectl edit ing sample-ingress修改资源,因此kubectl get ing sample-ingress -o json可让您更改当前的Ingress。

或者您可以尝试sample-ingress,它会以json格式为您提供当前状态kubectl replace -f,将其粘贴到您的文本编辑器中会为您创建一个很好的基础来创建一个清单然后{{1}}。