OpenShift & K8S Cheat Sheet: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
|||
| (63 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
=Kubernetes= | =Kubernetes= | ||
==Setup== | |||
===oc=== | |||
mkdir $HOME/bin ; cd $HOME/bin | |||
curl -L https://github.com/$(curl -L -s https://github.com/openshift/okd/releases | grep openshift-client-linux- | head -1 | cut -d\" -f2) --output openshift-client-linux.tar.gz | |||
tar vxfz openshift-client-linux.tar.gz | |||
rm -f openshift-client-linux.tar.gz README.md | |||
===kubectl-neat=== | |||
mkdir $HOME/bin ; cd $HOME/bin | |||
rm -f kubectl-neat | |||
wget https://github.com/itaysk/kubectl-neat/releases/latest/download/kubectl-neat_linux_amd64.tar.gz | |||
chmod 700 kubectl-neat | |||
tar vxfz kubectl-neat_linux_amd64.tar.gz | |||
rm -f LICENSE kubectl-neat_linux_amd64.tar.gz | |||
===kubectl=== | |||
mkdir $HOME/bin ; cd $HOME/bin | |||
rm -f kubectl | |||
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl | |||
chmod 700 kubectl | |||
grep 'kubectl completion bash' $HOME/.bashrc || echo 'source <(kubectl completion bash)' >> $HOME/.bashrc | |||
===kustomize=== | |||
cd $HOME/bin | |||
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash | |||
===helm=== | |||
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | sh | |||
grep 'helm completion bash' $HOME/.bashrc || echo 'source <(helm completion bash)' >> $HOME/.bashrc | |||
==Daily== | ==Daily== | ||
* https://kubernetes.io/de/docs/reference/kubectl/cheatsheet/ | * https://kubernetes.io/de/docs/reference/kubectl/cheatsheet/ | ||
===SHELL== | ===SHELL=== | ||
* Authenticate Kubectl | * Authenticate Kubectl | ||
export KUBECONFIG=<PATH-TO | export KUBECONFIG=<PATH-TO-CONFIG>/kubeconfig-dev.yaml | ||
==. | ===Use Helm=== | ||
* | * https://artifacthub.io/ | ||
* https://hub.helm.sm/ | |||
* https://hub.kubeapps.com/ | |||
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml # for K3S | |||
helm search hub wordpress --max-col-width 120 | |||
helm repo add stable https://charts.helm.sh/stable | |||
helm repo add bitnami https://charts.bitnami.com/bitnami | |||
helm repo update | |||
===Install APP with Helm=== | |||
kubectl create namespace wordpress | |||
kubectl config set-context --current --namespace=wordpress | |||
helm install my-wordpress bitnami/wordpress | |||
kubectl get all | |||
kubectl delete service my-wordpress | |||
kubectl get pods | |||
kubectl exec my-wordpress-55dc589b4c-ldkxj -- printenv | grep HTTP | |||
kubectl expose deployment/my-wordpress --port=8080 --name=my-wordpress | |||
kubectl get service | |||
kubectl create ingress ingress-www --rule=wp.vm20.test.domain.ch/*=my-wordpress:8080 | |||
firefox https://wp.vm20.test.domain.ch/login | |||
# User: user | |||
# Password: $(kubectl get secret --namespace wordpress my-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) | |||
helm delete my-wordpress | |||
kubectl delete namespace wordpress | |||
[[Category:Linux]] | |||
[[Category:OpenShift & K8S]] | |||
[[Category:ReferenceCards]] | |||
[[Category:Linux]] | |||
[[Category:OpenShift & K8S]] | |||
[[Category:ReferenceCards]] | |||
[[Category:Linux]] | |||
[[Category:OpenShift & K8S]] | |||
[[Category:ReferenceCards]] | |||
===.bashrc=== | |||
* kubectl helpers | |||
<pre> | <pre> | ||
source <(kubectl completion bash) | source <(kubectl completion bash) | ||
export PS1= | export PS1="# \$(kubectl config view -o jsonpath="{.contexts[].context.namespace}") $PS1" | ||
alias kn='kubectl get ns' | |||
alias kp='kubectl get pods' | |||
alias ka='kubectl get all' | |||
alias kpvc='kubectl get pvc' | |||
alias kpv='kubectl get pv' | |||
_knd_complete() { | |||
local curr_arg="${COMP_WORDS[COMP_CWORD]}" | |||
COMPREPLY=( $(kubectl get namespaces --no-headers -o custom-columns=":metadata.name" | grep "^$curr_arg") ) | |||
} | |||
knd() { | |||
if [[ -n "$1" ]]; then | |||
kubectl config set-context --current --namespace="$1" | |||
else | |||
echo "Usage: knd <namespace>" | |||
echo "Available namespaces:" | |||
kubectl get namespaces --no-headers -o custom-columns=":metadata.name" | |||
fi | |||
} | |||
complete -F _knd_complete knd | |||
kpvcc() { | |||
# Prompt for user input with defaults | |||
read -p "Name [pvc1]: " pvc_name | |||
pvc_name=${pvc_name:-pvc1} | |||
read -p "Access Modes [ReadWriteOnce]: " access_modes | |||
access_modes=${access_modes:-ReadWriteOnce} | |||
read -p "Storage [5Gi]: " storage | |||
storage=${storage:-5Gi} | |||
# Apply the PVC using inline YAML | |||
kubectl apply -f - <<EOF | |||
apiVersion: v1 | |||
kind: PersistentVolumeClaim | |||
metadata: | |||
name: $pvc_name | |||
spec: | |||
accessModes: | |||
- $access_modes | |||
resources: | |||
requests: | |||
storage: $storage | |||
storageClassName: local-path | |||
EOF | |||
echo "PVC '$pvc_name' created with AccessModes='$access_modes' and Storage='$storage'" | |||
} | |||
</pre> | </pre> | ||
==Deploy== | |||
===Create Secret=== | |||
<pre> | <pre> | ||
username=myuser | |||
read password | |||
kubectl create secret generic db-user-pass --from-literal=username=$username --from-literal=password="$password" | |||
kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode | |||
----REF IN POD------ | |||
env: | |||
- name: SECRET_USERNAME | |||
valueFrom: | |||
secretKeyRef: | |||
name: db-user-pass | |||
key: username | |||
</pre> | </pre> | ||
===Create and change into Namespace=== | ===Create and change into Namespace=== | ||
kubectl create namespace mynamespace | kubectl create namespace mynamespace | ||
| Line 51: | Line 206: | ||
===Create Ingress Rule for Service=== | ===Create Ingress Rule for Service=== | ||
kubectl create ingress ingress-www --rule=www.domain.com/*=nginx-service:8080 | kubectl create ingress ingress-www --rule=www.domain.com/*=nginx-service:8080 | ||
===Docker Pull Secret=== | |||
oc create secret docker-registry docker --docker-server=docker.io --docker-username=username1 --docker-email=chris@domain.ch --docker-password=xcgsedfgsdfhgsdfg | |||
oc secrets link default docker --for=pull | |||
oc new-app --name wiki --image image.registry.tld/image:tag --source-secret=docker | |||
==Change/Update== | |||
===Force Deployment to pull (latest)=== | |||
oc get deployments | |||
oc set env deployment/myapp UPDATE_TIMESTAMP="$(date)" | |||
oc rollout status deployment/myapp | |||
oc describe pod [POD_NAME] | |||
==Configure== | ==Configure== | ||
===Traefik Config=== | |||
- https://levelup.gitconnected.com/a-guide-to-k3s-ingress-using-traefik-with-nodeport-6eb29add0b4b | |||
kubectl edit deployments traefik -n kube-system | |||
kubectl -n kube-system edit cm traefik | |||
==Debug== | ==Debug== | ||
===Run Container with custom Command=== | ===Run Container with custom Command=== | ||
kubectl run -i --tty busybox --image=busybox -- sh | kubectl run -i --tty busybox --image=busybox -- sh | ||
===Attach Container in Pod=== | ===Attach Container in Pod (log)=== | ||
kubectl attach busybox -c busybox -i -t | kubectl attach busybox -c busybox -i -t | ||
===Jump into Pods Shell=== | |||
kubectl exec --stdin --tty shell-demo -- /bin/bash | |||
===Get all Containers on all Namespaces=== | |||
kubectl get pods --all-namespaces -o jsonpath="{..image}" |tr -s '[[:space:]]' '\n' |sort |uniq -c | |||
===Get all Containers grouped by Pods for all Namespaces=== | |||
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |sort | |||
| Line 65: | Line 252: | ||
===Open Firewall for NodePort (non persistent)=== | |||
kubectl describe svc | grep NodePort: | awk '{print $3}' | tr 'A-Z' 'a-z' | grep -v '^$' | while read PORT | |||
do | |||
echo PORT=$PORT | |||
firewall-cmd --zone=public --add-port=$PORT | |||
done | |||
* openshift | |||
=OpenShift= | |||
==Install== | |||
===OC & KUBECTL (OKD)=== | |||
mkdir $HOME/bin ; cd $HOME/bin | |||
rm -f oc | |||
wget https://github.com/$(curl -L https://github.com/openshift/okd/releases/latest/ | grep openshift-client-linux | grep href= | cut -d\" -f2 ) | |||
tar vxfz openshift-client-linux-*.tar.gz | |||
rm -rf README.md openshift-client-linux-*.tar.gz | |||
grep 'oc completion bash' $HOME/.bashrc || echo 'source <(oc completion bash)' >> $HOME/.bashrc | |||
grep 'kubectl completion bash' $HOME/.bashrc || echo 'source <(kubectl completion bash)' >> $HOME/.bashrc | |||
===OC & KUBECTL (OpenShift)=== | |||
mkdir $HOME/bin ; cd $HOME/bin | |||
rm -f oc kubectl | |||
wget https://mirror.openshift.com/pub/openshift-v4/clients/oc/latest/linux/oc.tar.gz | |||
tar vxfz oc.tar.gz | |||
rm -f README.md oc.tar.gz | |||
grep 'oc completion bash' $HOME/.bashrc || echo 'source <(oc completion bash)' >> $HOME/.bashrc | |||
grep 'kubectl completion bash' $HOME/.bashrc || echo 'source <(kubectl completion bash)' >> $HOME/.bashrc | |||
===.bashrc=== | |||
<pre> | <pre> | ||
genpasswd() { | |||
local l=$1 | |||
[ "$l" == "" ] && l=16 | |||
tr -dc A-Za-z0-9_=., < /dev/urandom | head -c ${l} | xargs | |||
} | } | ||
source <(kubectl completion bash) | |||
export PS1="# \$(kubectl config view -o jsonpath="{.contexts[].context.namespace}") $PS1" | |||
_knd_complete() { | |||
local curr_arg="${COMP_WORDS[COMP_CWORD]}" | |||
COMPREPLY=( $(kubectl get namespaces --no-headers -o custom-columns=":metadata.name" | grep "^$curr_arg") ) | |||
} | |||
knd() { | |||
if [[ -n "$1" ]]; then | |||
kubectl config set-context --current --namespace="$1" | |||
else | |||
echo "Usage: knd <namespace>" | |||
echo "Available namespaces:" | |||
kubectl get namespaces --no-headers -o custom-columns=":metadata.name" | |||
fi | |||
} | |||
complete -F _knd_complete knd | |||
alias knl='kubectl get ns' | |||
alias kp='kubectl get pods' | |||
alias ka='kubectl get all' | |||
alias kpvc='kubectl get pvc' | |||
alias kpv='kubectl get pv' | |||
kpvcc() { | |||
# Prompt for user input with defaults | |||
read -p "Name [pvc1]: " pvc_name | |||
pvc_name=${pvc_name:-pvc1} | |||
read -p "Access Modes [ReadWriteOnce]: " access_modes | |||
access_modes=${access_modes:-ReadWriteOnce} | |||
read -p "Storage [5Gi]: " storage | |||
storage=${storage:-5Gi} | |||
# Apply the PVC using inline YAML | |||
kubectl apply -f - <<EOF | |||
apiVersion: v1 | |||
kind: PersistentVolumeClaim | |||
metadata: | |||
name: $pvc_name | |||
spec: | |||
accessModes: | |||
- $access_modes | |||
resources: | |||
requests: | |||
storage: $storage | |||
storageClassName: standard | |||
EOF | |||
echo "PVC '$pvc_name' created with AccessModes='$access_modes' and Storage='$storage'" | |||
} | } | ||
</pre> | </pre> | ||
==Debug== | |||
===etcd=== | |||
M1=$(oc get nodes -l node-role.kubernetes.io/master | grep Ready | head -1 | cut -d' ' -f1 ) | |||
oc rsh -n openshift-etcd etcd-$M1 <<EOF | |||
etcdctl member list -w table | |||
EOF | |||
| Line 116: | Line 394: | ||
=snippets= | =snippets= | ||
| Line 213: | Line 479: | ||
=database backup= | =database backup= | ||
==mariadb | ==mariadb== | ||
* install global backup template | * install global backup template | ||
oc create -f https://raw.githubusercontent.com/joe-speedboat/mariadb-backup-cronjob/master/mariadb-backup- | oc create -f https://raw.githubusercontent.com/joe-speedboat/openshift.mariadb-backup-cronjob/master/mariadb-backup-template_okd410.yaml | ||
* more information can be found on git repo [https://github.com/joe-speedboat/mariadb-backup-cronjob mariadb-backup-cronjob] | * more information can be found on git repo [https://github.com/joe-speedboat/mariadb-backup-cronjob mariadb-backup-cronjob] | ||
==mariadb database backup with oc== | |||
oc rsh dc/mariadb /bin/sh -i -c "MYSQL_PWD=$MYSQL_ROOT_PASSWORD /usr/bin/mysqldump -u root --skip-lock-tables \$MYSQL_DATABASE" > mysqldb.sql | |||
oc rsh deployments/mariadb /bin/bash -i -c "MYSQL_PWD=\$MARIADB_ROOT_PASSWORD /usr/bin/mysqldump -u root --skip-lock-tables \$MYSQL_DATABASE" > mariadb.sql | |||
==postgresql dump with kubectl== | |||
kubectl exec zammad-postgresql-0 -- bash -c "PGPASSWORD="xxx" pg_dump -Uzammad zammad_production" > zammad_production.sql | |||
=Maintenance= | =Maintenance= | ||
==Databases== | |||
===Mariadb login=== | |||
MYSQL_PWD="$MARIADB_ROOT_PASSWORD" mysql -u root $MYSQL_DATABASE | |||
===mysql login=== | |||
mysql -u $MYSQL_USER -p"$MYSQL_PASSWORD" $MYSQL_DATABASE | |||
[[Category:Linux]] | |||
[[Category:OpenShift & K8S]] | |||
[[Category:ReferenceCards]] | |||
==CleanUp old docker images on nodes== | ==CleanUp old docker images on nodes== | ||
: Keeping up to three tag revisions 1, and keeping resources (images, image streams and pods) younger than sixty minutes: | : Keeping up to three tag revisions 1, and keeping resources (images, image streams and pods) younger than sixty minutes: | ||
Latest revision as of 12:22, 4 February 2025
Kubernetes
Setup
oc
mkdir $HOME/bin ; cd $HOME/bin curl -L https://github.com/$(curl -L -s https://github.com/openshift/okd/releases | grep openshift-client-linux- | head -1 | cut -d\" -f2) --output openshift-client-linux.tar.gz tar vxfz openshift-client-linux.tar.gz rm -f openshift-client-linux.tar.gz README.md
kubectl-neat
mkdir $HOME/bin ; cd $HOME/bin rm -f kubectl-neat wget https://github.com/itaysk/kubectl-neat/releases/latest/download/kubectl-neat_linux_amd64.tar.gz chmod 700 kubectl-neat tar vxfz kubectl-neat_linux_amd64.tar.gz rm -f LICENSE kubectl-neat_linux_amd64.tar.gz
kubectl
mkdir $HOME/bin ; cd $HOME/bin rm -f kubectl curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl chmod 700 kubectl grep 'kubectl completion bash' $HOME/.bashrc || echo 'source <(kubectl completion bash)' >> $HOME/.bashrc
kustomize
cd $HOME/bin curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
helm
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | sh grep 'helm completion bash' $HOME/.bashrc || echo 'source <(helm completion bash)' >> $HOME/.bashrc
Daily
* https://kubernetes.io/de/docs/reference/kubectl/cheatsheet/
SHELL
- Authenticate Kubectl
export KUBECONFIG=<PATH-TO-CONFIG>/kubeconfig-dev.yaml
Use Helm
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml # for K3S helm search hub wordpress --max-col-width 120 helm repo add stable https://charts.helm.sh/stable helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update
Install APP with Helm
kubectl create namespace wordpress kubectl config set-context --current --namespace=wordpress helm install my-wordpress bitnami/wordpress
kubectl get all
kubectl delete service my-wordpress kubectl get pods kubectl exec my-wordpress-55dc589b4c-ldkxj -- printenv | grep HTTP kubectl expose deployment/my-wordpress --port=8080 --name=my-wordpress kubectl get service
kubectl create ingress ingress-www --rule=wp.vm20.test.domain.ch/*=my-wordpress:8080
firefox https://wp.vm20.test.domain.ch/login # User: user # Password: $(kubectl get secret --namespace wordpress my-wordpress -o jsonpath="{.data.wordpress-password}" | base64 --decode) helm delete my-wordpress kubectl delete namespace wordpress
.bashrc
- kubectl helpers
source <(kubectl completion bash)
export PS1="# \$(kubectl config view -o jsonpath="{.contexts[].context.namespace}") $PS1"
alias kn='kubectl get ns'
alias kp='kubectl get pods'
alias ka='kubectl get all'
alias kpvc='kubectl get pvc'
alias kpv='kubectl get pv'
_knd_complete() {
local curr_arg="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(kubectl get namespaces --no-headers -o custom-columns=":metadata.name" | grep "^$curr_arg") )
}
knd() {
if [[ -n "$1" ]]; then
kubectl config set-context --current --namespace="$1"
else
echo "Usage: knd <namespace>"
echo "Available namespaces:"
kubectl get namespaces --no-headers -o custom-columns=":metadata.name"
fi
}
complete -F _knd_complete knd
kpvcc() {
# Prompt for user input with defaults
read -p "Name [pvc1]: " pvc_name
pvc_name=${pvc_name:-pvc1}
read -p "Access Modes [ReadWriteOnce]: " access_modes
access_modes=${access_modes:-ReadWriteOnce}
read -p "Storage [5Gi]: " storage
storage=${storage:-5Gi}
# Apply the PVC using inline YAML
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: $pvc_name
spec:
accessModes:
- $access_modes
resources:
requests:
storage: $storage
storageClassName: local-path
EOF
echo "PVC '$pvc_name' created with AccessModes='$access_modes' and Storage='$storage'"
}
Deploy
Create Secret
username=myuser
read password
kubectl create secret generic db-user-pass --from-literal=username=$username --from-literal=password="$password"
kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
----REF IN POD------
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: db-user-pass
key: username
Create and change into Namespace
kubectl create namespace mynamespace kubectl config set-context --current --namespace=mynamespace
Deploy Docker Container and Expose Service
kubectl create deployment xfce --image=christian773/xfce-vnc:latest --port=6901
Inject VARS into Deployment/Container
kubectl edit deployment nginx1
spec:
containers:
- name: nginx
image: nginx:1.7.9
env:
- name: MY_VAT
value: MY_VALUE
Get Environment VARS of Pod
kubectl exec pod-name -- printenv
Expose Container Port as Service
kubectl expose deployment nginx-app --port=8080 --name=nginx-service
Create Ingress Rule for Service
kubectl create ingress ingress-www --rule=www.domain.com/*=nginx-service:8080
Docker Pull Secret
oc create secret docker-registry docker --docker-server=docker.io --docker-username=username1 --docker-email=chris@domain.ch --docker-password=xcgsedfgsdfhgsdfg oc secrets link default docker --for=pull oc new-app --name wiki --image image.registry.tld/image:tag --source-secret=docker
Change/Update
Force Deployment to pull (latest)
oc get deployments oc set env deployment/myapp UPDATE_TIMESTAMP="$(date)" oc rollout status deployment/myapp oc describe pod [POD_NAME]
Configure
Traefik Config
- https://levelup.gitconnected.com/a-guide-to-k3s-ingress-using-traefik-with-nodeport-6eb29add0b4b
kubectl edit deployments traefik -n kube-system kubectl -n kube-system edit cm traefik
Debug
Run Container with custom Command
kubectl run -i --tty busybox --image=busybox -- sh
Attach Container in Pod (log)
kubectl attach busybox -c busybox -i -t
Jump into Pods Shell
kubectl exec --stdin --tty shell-demo -- /bin/bash
Get all Containers on all Namespaces
kubectl get pods --all-namespaces -o jsonpath="{..image}" |tr -s 'space:' '\n' |sort |uniq -c
Get all Containers grouped by Pods for all Namespaces
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |sort
Open Firewall for NodePort (non persistent)
kubectl describe svc | grep NodePort: | awk '{print $3}' | tr 'A-Z' 'a-z' | grep -v '^$' | while read PORT
do
echo PORT=$PORT
firewall-cmd --zone=public --add-port=$PORT
done
OpenShift
Install
OC & KUBECTL (OKD)
mkdir $HOME/bin ; cd $HOME/bin rm -f oc wget https://github.com/$(curl -L https://github.com/openshift/okd/releases/latest/ | grep openshift-client-linux | grep href= | cut -d\" -f2 ) tar vxfz openshift-client-linux-*.tar.gz rm -rf README.md openshift-client-linux-*.tar.gz grep 'oc completion bash' $HOME/.bashrc || echo 'source <(oc completion bash)' >> $HOME/.bashrc grep 'kubectl completion bash' $HOME/.bashrc || echo 'source <(kubectl completion bash)' >> $HOME/.bashrc
OC & KUBECTL (OpenShift)
mkdir $HOME/bin ; cd $HOME/bin rm -f oc kubectl wget https://mirror.openshift.com/pub/openshift-v4/clients/oc/latest/linux/oc.tar.gz tar vxfz oc.tar.gz rm -f README.md oc.tar.gz grep 'oc completion bash' $HOME/.bashrc || echo 'source <(oc completion bash)' >> $HOME/.bashrc grep 'kubectl completion bash' $HOME/.bashrc || echo 'source <(kubectl completion bash)' >> $HOME/.bashrc
.bashrc
genpasswd() {
local l=$1
[ "$l" == "" ] && l=16
tr -dc A-Za-z0-9_=., < /dev/urandom | head -c ${l} | xargs
}
source <(kubectl completion bash)
export PS1="# \$(kubectl config view -o jsonpath="{.contexts[].context.namespace}") $PS1"
_knd_complete() {
local curr_arg="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=( $(kubectl get namespaces --no-headers -o custom-columns=":metadata.name" | grep "^$curr_arg") )
}
knd() {
if [[ -n "$1" ]]; then
kubectl config set-context --current --namespace="$1"
else
echo "Usage: knd <namespace>"
echo "Available namespaces:"
kubectl get namespaces --no-headers -o custom-columns=":metadata.name"
fi
}
complete -F _knd_complete knd
alias knl='kubectl get ns'
alias kp='kubectl get pods'
alias ka='kubectl get all'
alias kpvc='kubectl get pvc'
alias kpv='kubectl get pv'
kpvcc() {
# Prompt for user input with defaults
read -p "Name [pvc1]: " pvc_name
pvc_name=${pvc_name:-pvc1}
read -p "Access Modes [ReadWriteOnce]: " access_modes
access_modes=${access_modes:-ReadWriteOnce}
read -p "Storage [5Gi]: " storage
storage=${storage:-5Gi}
# Apply the PVC using inline YAML
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: $pvc_name
spec:
accessModes:
- $access_modes
resources:
requests:
storage: $storage
storageClassName: standard
EOF
echo "PVC '$pvc_name' created with AccessModes='$access_modes' and Storage='$storage'"
}
Debug
etcd
M1=$(oc get nodes -l node-role.kubernetes.io/master | grep Ready | head -1 | cut -d' ' -f1 ) oc rsh -n openshift-etcd etcd-$M1 <<EOF etcdctl member list -w table EOF
Administration
daily cmds
oc get nodes -o wide oc get all -o wide --all-namespaces oc get ep -o wide oc get events --sort-by='.lastTimestamp' oc get rolebindings --all-namespaces oc get pv oc get pvc oc get projects oc get users oc get groups
inspect user/group permissions
oc get rolebinding -o wide -n gitea oc get rolebinding -o wide --all-namespaces
inspect imagestreams
oc get is -n openshift oc describe is php -n openshift oc export -n openshift isimage php@42c4a9072f
snippets
run as root (anyuid)
oc create serviceaccount sa-anyuid
oc adm policy add-scc-to-user anyuid -z sa-anyuid
# create new-app before to get a dc
oc patch dc/deployment-config-name --patch '{"spec":{"template":{"spec":{"serviceAccountName": "sa-anyuid"}}}}'
run as root (anyuid) for every pod in project
oc adm policy add-scc-to-user anyuid -z default
imagestream demo (build service)
- get all the imagestreams
oc get is -n openshift
- inspect nginx imagestream
oc describe is nginx -n openshift
- setup new project
oc new-project is-demo
- setup the dev environment
oc new-app --name=html-dev nginx:1.10~https://github.com/joe-speedboat/openshift.html.devops.git#master oc get all oc logs -f builds/html-dev-1
oc get svc oc expose svc/html-dev --hostname=html-dev.app.domain.com oc get route
curl http://html-dev.app.domain.com
- show this app to the qa team
oc get is oc tag docker-registry.default.svc:5000/is-demo/html-dev:latest is-demo/html-qa:1.0 oc get is oc new-app --name=html-qa --image-stream="is-demo/html-qa:1.0" oc expose svc/html-qa --hostname=html-qa.app.domain.com curl html-qa.app.domain.com
- now go and make some changes to the git repo, then push it to github
- now lets build the latest dev release
oc start-build html-dev oc status oc get pods
- check dev application for latest changes
curl http://html-dev.app.domain.com
- check if qa application remains in desired state
curl html-qa.app.domain.com
- now commit the new dev branch to qa branch
oc get is oc tag docker-registry.default.svc:5000/is-demo/html-dev html-qa:1.1
- change the imagestream to newer release
oc edit dc/html-qa oc get dc oc get pods
- check if qa application is reflecting latest changes from v1.1
curl html-qa.app.domain.com
- now we rollback the qa release to v1.0
oc edit dc/html-qa oc get dc oc get pods
- check if qa application is reflecting the rollbacked version v1.0
curl html-qa.app.domain.com
database backup
mariadb
- install global backup template
oc create -f https://raw.githubusercontent.com/joe-speedboat/openshift.mariadb-backup-cronjob/master/mariadb-backup-template_okd410.yaml
- more information can be found on git repo mariadb-backup-cronjob
mariadb database backup with oc
oc rsh dc/mariadb /bin/sh -i -c "MYSQL_PWD=$MYSQL_ROOT_PASSWORD /usr/bin/mysqldump -u root --skip-lock-tables \$MYSQL_DATABASE" > mysqldb.sql
oc rsh deployments/mariadb /bin/bash -i -c "MYSQL_PWD=\$MARIADB_ROOT_PASSWORD /usr/bin/mysqldump -u root --skip-lock-tables \$MYSQL_DATABASE" > mariadb.sql
postgresql dump with kubectl
kubectl exec zammad-postgresql-0 -- bash -c "PGPASSWORD="xxx" pg_dump -Uzammad zammad_production" > zammad_production.sql
Maintenance
Databases
Mariadb login
MYSQL_PWD="$MARIADB_ROOT_PASSWORD" mysql -u root $MYSQL_DATABASE
mysql login
mysql -u $MYSQL_USER -p"$MYSQL_PASSWORD" $MYSQL_DATABASE
CleanUp old docker images on nodes
- Keeping up to three tag revisions 1, and keeping resources (images, image streams and pods) younger than sixty minutes:
oc adm prune images --keep-tag-revisions=3 --keep-younger-than=60m
- Pruning every image that exceeds defined limits:
oc adm prune images --prune-over-size-limit
- CopyPaste example
oc adm prune images --keep-tag-revisions=3 --keep-younger-than=60m --confirm oc adm prune images --prune-over-size-limit --confirm