<<TableOfContents()>>
= Kubernetes =
Kubernetes – это программная система, которая позволяет легко развертывать контейнеризированные приложения и управлять ими.
[[ https://kubernetes.io ]]
[[https://kubernetes.io/docs/home/|Docs|class=" moin-https"]] | [[https://kubernetes.io/docs/reference/kubernetes-api/|API|class=" moin-https"]]
[[https://github.com/kubernetes/kubernetes|source code|class=" moin-https"]]
== Вложенные материалы ==
<<ItemList(display=”ChildName”)>>
== Полезные ссылки ==
[[https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/|Web UI (Dashboard)|class=" moin-https"]]
[[https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/|Ingress Controllers|class=" moin-https"]]
[[https://kubernetes.github.io/ingress-nginx/deploy/baremetal/|Bare-Metal Consideration|class=" moin-https"]]
[[https://github.com/davidkbainbridge/k8s-playground|k8s-playground|class=" moin-https"]] - Simple VM based Kubernetes cluster setup
[[https://github.com/luksa/kubernetes-in-action|Luksa Kubernetes In Action Sourcecode|class=" moin-https"]]
[[https://kubernetes.io/docs/concepts/extend-kubernetes/operator/|Operator Pattern|class=" moin-https"]] | [[https://github.com/cncf/tag-app-delivery/blob/eece8f7307f2970f46f100f51932db106db46968/operator-wg/whitepaper/Operator-WhitePaper_v1-0.md|White Paper|class=" moin-https"]]
== Aliases ==
{{{#!highlight bash
# --- k8s
alias k=kubectl
alias kcd='kubectl config set-context $(kubectl config current-context) --namespace'
alias kcdc="kubectl config view -o jsonpath='{.contexts[].context.namespace}' && echo ''"
}}}
== Swagger UI ==
{{{#!highlight bash
# --- запускаем прокси
kubectl proxy
# Starting to serve on 127.0.0.1:8001
# --- выгружаем описание API в файлик, напр.
http :8001/openapi/v2 > tmp/k8s-swagger.json
# --- запускаем swagger ui и прокидываем ему этот файл
docker run --rm -it \
-p 80:8080 \
-v ~/tmp:/opt/specs \
-e SWAGGER_JSON=/opt/specs/k8s-swagger.json \
swaggerapi/swagger-ui
# идем на localhost
}}}
{{{#!wiki note
'''TODO'''
Найти способ отображения UI без выгрузки в файл
}}}
= Recipes =
== Конфигурирование сохранения сессий в службах ==
[[https://yadi.sk/i/lTq1M_U0UcVhBQ|Лукша. Kubernetes в действии|class=" moin-https"]] Раздел 5.1.1
{{{#!highlight yaml
# Пример службы с настроенной сохранностью сессий сеанса ClientIP
# Это заставляет служебный прокси перенаправлять все запросы,
# исходящие от того же клиентского IP-адреса на тот же модуль.
# kubectl explain svc.spec.sessionAffinity
apiVersion: v1
kind: Service
spec:
sessionAffinity: ClientIP
...
}}}
== Создание службы для внешнего сервиса ==
[[https://yadi.sk/i/lTq1M_U0UcVhBQ|Лукша. Kubernetes в действии|class=" moin-https"]] Раздел 5.2.2
Шаг 1. Создание сервиса без селектора модулей
{{{#!highlight yaml
# external-service.yaml
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
ports:
- port: 80
}}}
Шаг 2. Создание ресурса конечных точек для службы
{{{#!highlight yaml
# external-service-endpoints.yaml
apiVersion: v1
kind: Endpoints
metadata:
# Имя объекта Endpoints должно совпадать с именем службы
name: external-service
subsets:
# IP-адреса конечных точек, на которые служба будет перенаправлять подключения
- addresses:
- ip: 11.11.11.11
- ip: 22.22.22.22
ports:
- port: 80
}}}
== TLS and Ingress ==
[[https://yadi.sk/i/lTq1M_U0UcVhBQ|Лукша. Kubernetes в действии|class=" moin-https"]] Раздел 5.4.4
== NodePort drawbacks ==
Some NodePort drawbacks to consider for production environments are:
* The scale will be limited by the “nodePort” range number, because only one service per port can be configured.
* By default, port range is limited in the rage 30000–32767. High ports usage could be problematic, from security perspective.
* By design, NodePort bypasses almost all network security in Kubernetes.
* If external load-balancer is in use, the service “Heath Check” will be toward the Node IP, instead directly to the Pod one, which is a poor monitoring solution.
* More complex to troubleshoot connectivity issues.
= Troubleshooting =
Если вы не можете получить доступ к своим модулям через службу, то Вам следует начать со следующего списка:
* прежде всего убедитесь, что вы подключаетесь к кластерному IP-адресу службы изнутри кластера, а не извне;
* не тратьте времени на пингование IP-адреса службы, чтобы выяснить, доступна ли служба (напомню, что кластерный IP-адрес службы – это виртуальный IP-адрес, и его пингование не сработает);
* если вы определили проверку готовности, убедитесь, что она выполняется успешно; в противном случае модуль не будет частью службы;
* для того чтобы убедиться, что модуль является частью службы, проинспектируйте соответствующий объект Endpoints с помощью команды `kubectl get endpoints`;
* если вы пытаетесь получить доступ к службе через ее полное доменное имя или его часть (например, myservice.mynamespace.svc.cluster.local или myservice.mynamespace ) и это не работает, посмотрите, сможете ли вы обратиться к нему, используя ее кластерный IP-адрес вместо полного доменного имени;
* проверьте, подключаетесь ли вы к предоставляемому службой порту, а не к целевому порту;
* попробуйте подключиться к IP-адресу модуля напрямую, чтобы подтвердить, что ваш модуль принимает подключения на правильном порту;
* если вы не можете получить доступ к своему приложению даже через IP-адрес модуля, убедитесь, что ваше приложение не открыто своими портами только к localhost-адресу.
== calico ==
=== calico/node is not ready: BIRD is not ready: BGP not established with 10.0.0.1 ===
[[https://docs.projectcalico.org/v3.5/getting-started/kubernetes/troubleshooting|source|class=" moin-https"]]
The calico/node container may report an “unready” status in Kubernetes with this message. In most cases, this means a particular peer is unreachable in the cluster. Users should ensure BGP connectivity between the two peers is allowed in their environment.
This can also occur when inactive Node resources are configured when using node-to-node mesh. Resolve cases like this by [[https://docs.projectcalico.org/v3.5/usage/decommissioning-a-node|decomissioning the stale nodes|class=" moin-https"]].
Lastly this can occur when BGP connections to non-mesh peers go down. If this is a common occurance in your BGP topology, you can disable BIRD readiness checks. See [[https://docs.projectcalico.org/v3.5/reference/node/configuration#node-readiness|node readiness|class=" moin-https"]] for more information.## minikube
== kubectl ==
=== Failed to create pod sandbox ===
При запуске пода получаем постоянный ''ContainerCreating''
В описании пода постоянно вываливается ошибка:
{{{#!highlight bash
kubectl describe pod XXX
...
Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "xxx" network for pod "xxx": networkPlugin cni failed to set up pod "xxx" network: stat /var/lib/calico/nodename: no such file or directory: check that the calico/node container is running and has mounted /var/lib/calico/
}}}
Подобная ошибка упоминается [[https://github.com/projectcalico/calico/issues/2418|здесь|class=" moin-https"]]
Необходимо установить корректный `--pod-network-cidr` при инициализации кластера. Если кластер уже запущен, то, по всей видимости, его надо сбросить. На всех узлах кластера выполнить:
{{{#!highlight bash
sudo kubeadm reset
sudo rm /etc/cni/net.d/*
}}}
Далее выполняем:
{{{#!highlight bash
# --- master
kubeadm init --apiserver-advertise-address=MASTER_IP_OR_HOSTNAME --pod-network-cidr=10.244.0.0/16
# --- nodes
sudo kubeadm join ...
# ... other cluster operations ...
}}}
=== the server could not find the requested resource ===
После запуска модуля, до него нельзя достучаться.
{{{#!highlight bash
k get pods
# NAME READY STATUS RESTARTS AGE
# kubia-manual 1/1 Running 0 20m
k logs kubia-manual
# Error from server (NotFound): the server could not find the requested resource ( pods/log kubia-manual)
k port-forward kubia-manual 8080:8080
# error: error upgrading connection: unable to upgrade connection: pod does not exist
}}}
Если запуск кластера осуществляется в Vagrant и VirtualBox, то причиной может быть то, что при запуске используется некорректный eth-интерфейс (см. [[https://github.com/kubernetes/kubernetes/issues/60835#issuecomment-395931644|ссылку|class=" moin-https"]]). Необходимо для каждого узла задать явно ip-адрес:
{{{
# /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
...
Environment="KUBELET_EXTRA_ARGS=--node-ip={{ node_ip }}"
}}}