As a part of the Kubernetes Resource Definition, I want to whitelist certain IPs. The list of IPs can be found by
$ kubectl get nodes -o wide --no-headers | awk '{print $7}'
#This prints something like
51.52.215.214
18.170.74.10
.....
Now, In the Kubernetes deployment file (say deployment.yaml) I want to loop over these values and whitelist them. I know that we can whitelist by adding under loadBalancerSourceRanges like
#part of the deployment.yaml
loadBalancerSourceRanges
- 51.52.112.111
- 18.159.75.11
I want to update the above loadBalancerSourceRanges to include the output of $ kubectl get nodes -o wide --no-headers | awk '{print $7}'
How do I go about it? Instead of hardcoding the host IPs, I would like to programatically include via bash or ansible or any other cleaner way possible.
Thanks in advance, JE
CodePudding user response:
loadBalancerSourceRanges should be a part of Service, not Deployment
You can use the following oneliner to patch your service dynamically:
kubectl patch service YOUR_SERVICE_NAME -p "{\"spec\":{\"loadBalancerSourceRanges\": [$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="InternalIP")]}"{.address}/32",{end}' | sed 's/,*$//g')]}}"
, where you should replace YOUR_SERVICE_NAME with actual service name
To explain what's going on here:
We are using kubectl patch to patch existing resource, in our case - spec.loadBalancerSourceRanges.
- we are putting our subshell inside
[$(..)], sinceloadBalancerSourceRangesrequires array of strings kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="InternalIP")]}"{.address}/32",{end}'- gets InternalIPs from your nodes, adds/32to each of them, sinceloadBalancerSourceRangesrequires ranges, encloses each range in"and then places coma between each value.sed 's/,*$//g'- removes a trailing comma
Using jsonpath is better thatn awk/cut because we are not dependent on kubectl column ordering and get only relevant for us information from API.
I agree with @Kaffe Myers that you should try using kustomize or helm or other templating engines, since they should be a better suited for this job.
CodePudding user response:
This is a very use-specific thingy, and you might be better off researching kustomize. That being said, you could make a temporary file which you alter before deploy.
cp deployment.yaml temp.yaml
kubectl get nodes -o wide --no-headers |
awk '{print $7}' |
xargs -I{} sed -Ei "s/^(\s )(loadBalancerSourceRanges:)/\1\2\n\1 - {}/" temp.yaml
kubectl apply -f temp.yaml
It looks for the loadBalancerSourceRanges: part of the yaml, which on the "template" shouldn't have any values, then populate it with whatever kubectl get nodes -o wide --no-headers | awk '{print $7}' feeds it with.
CodePudding user response:
You can use yq
# empty array if necessary
yq -i '.loadBalancerSourceRanges = []' file.yaml
# In my env (AWS EKS) the IP is field 6 (change if needed)
for host in $(kubectl get nodes -o wide --no-headers | awk '{print $6}')
do
yq -i '.loadBalancerSourceRanges = ["'${host}'"]' file.yaml
done
The -i parameter is to apply the change to the file (like sed)
If "loadBalancerSourceRanges" is inside "config", you can use: ".config.loadBalancerSourceRanges"
