Massive editor json for Kubernetes

16 Jul, 2019

In this post we will see the use of a custom bash (kmae and kselect) function that can save you time in your Kuberentes environments.

The idea is to interact with Kubernetes to be able to quickly edit a large amount of resources using grep filters; external (kubectl get pod) and internal (kubectl get pod -o json).

Code: https://gist.github.com/Tedezed/a8abece3507296c4fa1eb0ea70cc15e5

Kmae: It can be very dangerous if it is not used with caution, it saves three days of json edited to be able to recover them in the case of needing them in $HOME/.kmae. You can create backup of your cluster in json using: https://github.com/Tedezed/kubernetes-resources/tree/master/kubebackup  

To test it you can create an environment with several nginx with the following for:

for i in $(seq 1 6); do
  kubectl create namespace nginx-$i;
  kubectl create deploy nginx-$i -n nginx-$i --image=nginx;
done

  Gif tty  

We will use kselect to test your filters in the first place:

Format:

kselect (ENTITY) (GREP_EXTERNAL_KUBECTL) (GREP_INTERNAL_JSON) (JSON_PATH) (NAMESPACE OR --all-namespaces)

Example: Get json path spec.strategy.rollingUpdate of the nginx with name nginx-1 to 3 and generation equal to 1 in all namespaces

kselect deploy "(nginx-[1-3])" '"observedGeneration": 1' .spec.strategy.rollingUpdate --all-namespaces

 

In the second place, modify the spec.strategy.rollingUpdate of the three deployments at the same command:

Format:

kmae (ENTITY) (GREP_EXTERNAL_KUBECTL) (GREP_INTERNAL_JSON) (JSON_PATH_TO_UPDATE) (NAMESPACE OR --all-namespaces)

Example:

kmae deploy "(nginx-[1-3])" '"observedGeneration": 1' '{"spec":{"strategy":{"rollingUpdate":{"maxUnavailable": "50%", "maxSurge": "45%"}}}}' --all-namespaces

 

We tested the previous kselect that does not return anything because the generation number changed:

kselect deploy "(nginx-[1-3])" '"observedGeneration": 1' .spec.strategy.rollingUpdate --all-namespaces

If it works if we change the generation:

kselect deploy "(nginx-[1-3])" '"observedGeneration": 2' .spec.strategy.rollingUpdate --all-namespaces

 

One last test with modification of replicas:

kselect deploy "(nginx-[1-3])" '"observedGeneration": 2' .spec.replicas --all-namespaces
kmae deploy "(nginx-[1-3])" '"observedGeneration": 2' '{"spec":{"replicas":2}}' --all-namespaces
kselect deploy "(nginx-[1-3])" '"observedGeneration": 3' .spec.replicas --all-namespaces

 

Clean enviroment:

for i in $(seq 1 6); do 
  kubectl delete deploy nginx-$i -n nginx-$i --force --grace-period=0;
  kubectl delete namespace nginx-$i --force --grace-period=0; 
done

Ingress TCP/UDP

22 Mar, 2019

Source: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/exposing-tcp-udp-services.md

Install ingress nginx with helm

helm install stable/nginx-ingress \
	--name nginx-ingress-tcp-udp \
	--namespace nginx-ingress-tcp-udp \
	--set controller.ingressClass=nginx-ingress-tcp-udp

Create configmap with format: namespace/service:port

kubectl apply -f - -o yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: nginx-ingress-tcp-udp
data:
  2000: "demo-test/mysql-demo-test:3306"
  2001: "demo-test/sftp-server:22"
  2002: "demo-test/postgres-server:5432"
EOF

Edit service nginx-ingress kubectl edit svc nginx-ingress-tcp-udp-controller -n nginx-ingress-tcp-udp

  - name: proxied-tcp-2000
    port: 2000
    targetPort: 2000
    protocol: TCP
  - name: proxied-tcp-2001
    port: 2001
    targetPort: 2001
    protocol: TCP
  - name: proxied-tcp-2002
    port: 2002
    targetPort: 2002
    protocol: TCP

Edit deployment nginx-ingress kubectl edit deploy nginx-ingress-tcp-udp-controller --namespace nginx-ingress-tcp-udp Edit:

    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --tcp-services-configmap=nginx-ingress-tcp-udp/tcp-services

Access through the port previously assigned to the services configured in the configmap.

Delete namespace in perpetual Terminating state

21 Mar, 2019

Error, perpetual Terminating state:

NAME             STATUS        AGE
cert-manager     Terminating   3h
default          Active        1y
kube-public      Active        1y
kube-system      Active        1y

Clean namespace:

kubectl delete all -n cert-manager --all --force --grace-period=0
kubectl delete ns cert-manager --force --grace-period=0

Variables for configuration:

export NAMESPACE_TO_DELETE="cert-manager"
export CLUSTER_NAME="gke_PRO-ID_ZONE-GCP_NAME-CLUSTER"

Create service account with permissions:

kubectl create -f - -o yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tmpadmin
EOF

Save the namespace to edit it kubectl get namespace $NAMESPACE_TO_DELETE -o json > tmp.json

Edit:

    "spec": {
        "finalizers": [
            "kubernetes"
        ]
    },

To:

    "spec": {
        "finalizers": []
    },

Create the following variables

APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")
TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='tmpadmin')].data.token}"|base64 -d)

Test token: curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

Update namespace:

curl -X PUT $APISERVER/api/v1/namespaces/$NAMESPACE_TO_DELETE/finalize -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" --data-binary @tmp.json  --insecure

After this the namespace is erased.

Clean the service account:

kubectl delete sa tmpadmin