Я столкнулся с некоторыми загадочными сетевыми ошибками в нашем кластере kubernetes. Хотя я изначально сталкивался с этими ошибками при использовании входа, есть еще больше ошибок, когда я обходил наш балансировщик нагрузки, обходил kube-proxy и обходил nginx-ingress. Большинство ошибок присутствуют при переходе непосредственно к сервисам и напрямую к IP-адресам модуля. Я полагаю, что это потому, что балансировщик нагрузки и nginx имеют лучшую обработку ошибок, чем необработанная маршрутизация iptable.
Чтобы проверить ошибку, я использую тест Apache из ВМ в той же подсети, любой уровень параллелизма, без поддержки активности,подключитесь к IP-адресу модуля и используйте достаточно большой номер запроса, чтобы дать мне время либо увеличить, либо уменьшить развертывание. Странно то, что не имеет значения, какое развертывание я изменяю, поскольку оно всегда вызывает одни и те же наборы ошибок, даже если оно не связано с модулем, который я изменяю. ЛЮБОЕ добавление или удаление модулей вызовет ошибки теста Apache. Удаление вручную, масштабирование вверх / вниз, автоматическое масштабирование всех ошибок триггера. Если во время выполнения теста ab нет изменений в модуле, об ошибках не сообщается. Примечание: поддержка активности, по-видимому, значительно сокращает, если не устраняет ошибки, но я только несколько раз проверял это и никогда не видел ошибки.
За исключением какого-то странного конфликта между ними, я действительно не понимаю, какудаление модуля A может повлиять на сетевые подключения модуля B. Поскольку ошибки кратковременны и исчезают в течение нескольких секунд, это больше похоже на кратковременное отключение сети.
Пример теста ab: ab -n 5000 -c 2 https://10.112.0.24/
Ошибкипри использовании HTTPS:
SSL handshake failed (5).
SSL read failed (5) - closing connection
Ошибки при использовании HTTP:
apr_socket_recv: Connection reset by peer (104)
apr_socket_recv: Connection refused (111)
Пример ab output. Я обнаружил ctl-C после появления первых ошибок:
$ ab -n 5000 -c 2 https://10.112.0.24/
This is ApacheBench, Version 2.3 <$Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 10.112.0.24 (be patient)
Completed 500 requests
Completed 1000 requests
SSL read failed (5) - closing connection
Completed 1500 requests
^C
Server Software: nginx
Server Hostname: 10.112.0.24
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Document Path: /
Document Length: 2575 bytes
Concurrency Level: 2
Time taken for tests: 21.670 seconds
Complete requests: 1824
Failed requests: 2
(Connect: 0, Receive: 0, Length: 1, Exceptions: 1)
Total transferred: 5142683 bytes
HTML transferred: 4694225 bytes
Requests per second: 84.17 [#/sec] (mean)
Time per request: 23.761 [ms] (mean)
Time per request: 11.881 [ms] (mean, across all concurrent requests)
Transfer rate: 231.75 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 5 15 9.8 12 82
Processing: 1 9 9.0 6 130
Waiting: 0 8 8.9 6 129
Total: 7 23 14.4 19 142
Percentage of the requests served within a certain time (ms)
50% 19
66% 24
75% 28
80% 30
90% 40
95% 54
98% 66
99% 79
100% 142 (longest request)
Текущие настройки sysctl, которые могут иметь значение:
net.netfilter.nf_conntrack_tcp_be_liberal = 1
net.nf_conntrack_max = 131072
net.netfilter.nf_conntrack_buckets = 65536
net.netfilter.nf_conntrack_count = 1280
net.ipv4.ip_local_port_range = 27050 65500
Я не увидел никаких ошибок "полного" conntrack. Лучше всего я могу сказать, что нет потери пакетов. Мы недавно обновились с 1.14 и не заметили проблему, но я не могу точно сказать, что ее там не было. Я полагаю, что вскоре нас заставят мигрировать из Романы, поскольку она, похоже, больше не поддерживается, и при обновлении до куба 1.16.x у нас возникают проблемы с его запуском.
Я искалСегодня весь день в интернете ищут похожие проблемы, и ближайшая, которая напоминает нашу проблему, - https://tech.xing.com/a-reason-for-unexplained-connection-timeouts-on-kubernetes-docker-abd041cf7e02, но я понятия не имею, как реализовать опцию iptable masquerade --random-full, учитывая, что мы используем романа и я читаю (https://github.com/kubernetes/kubernetes/pull/78547#issuecomment-527578153) это случайное-полностью значение по умолчанию для ядра Linux 5, которое мы используем. Есть идеи?
- kubernetes 1.15.5
- romana 2.0.2
- centos7
- Linux kube-master01 5.0.7-1.el7.elrepo.x86_64 # 1 SMP пт 5 апреля 18:07:52 EDT 2019 x86_64 x86_64 x86_64 GNU / Linux
====== Обновление 5 ноября 2019 г. ======
Было предложено протестировать альтернативный CNI. Я выбрал calico, поскольку мы использовали его в более старом кластерном кубе на основе Debian. Я перестроил виртуальную машину с нашим самым основным шаблоном Centos 7 (vSphere)так что из наших настроек есть небольшой багаж. Я не могу перечислить все, что мы настроили в нашем шаблоне, но самое заметное изменение - это обновление ядра 5 yum --enablerepo=elrepo-kernel -y install kernel-ml
.
После запуска виртуальной машины это минимальные шаги для установки kubernetes и запуска теста:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum -y install docker-ce-3:18.09.6-3.el7.x86_64
systemctl start docker
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
# Set SELinux in permissive mode (effectively disabling it)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
yum install -y kubeadm-1.15.5-0 kubelet-1.15.5-0 kubectl-1.15.5-0
systemctl enable --now kubelet
kubeadm init --pod-network-cidr=192.168.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
kubectl taint nodes --all node-role.kubernetes.io/master-
kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yaml
cat <<EOF > /tmp/test-deploy.yml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: test
spec:
selector:
matchLabels:
app: test
replicas: 1
template:
metadata:
labels:
app: test
spec:
containers:
- name: nginx
image: nginxdemos/hello
ports:
- containerPort: 80
EOF
# wait for control plane to become healthy
kubectl apply -f /tmp/test-deploy.yml
Теперь установка готова, и это тест ab:
$ docker run --rm jordi/ab -n 100 -c 1 http://192.168.4.4/
This is ApacheBench, Version 2.3 <$Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.4.4 (be patient)...apr_pollset_poll: The timeout specified has expired (70007)
Total of 11 requests completed
Тест ab сдается после этой ошибки. Если я уменьшу количество запросов, чтобы увидеть время ожидания, то это то, что вы увидите:
$ docker run --rm jordi/ab -n 10 -c 1 http://192.168.4.4/
This is ApacheBench, Version 2.3 <$Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 192.168.4.4 (be patient).....done
Server Software: nginx/1.13.8
Server Hostname: 192.168.4.4
Server Port: 80
Document Path: /
Document Length: 7227 bytes
Concurrency Level: 1
Time taken for tests: 0.029 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 74140 bytes
HTML transferred: 72270 bytes
Requests per second: 342.18 [#/sec] (mean)
Time per request: 2.922 [ms] (mean)
Time per request: 2.922 [ms] (mean, across all concurrent requests)
Transfer rate: 2477.50 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 1 0.8 1 3
Processing: 1 2 1.2 1 4
Waiting: 0 1 1.3 0 4
Total: 1 3 1.4 3 5
Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 4
80% 5
90% 5
95% 5
98% 5
99% 5
100% 5 (longest request)
Эта проблема технически отличается от первоначальной проблемы, о которой я сообщил, но это другой CNI, и все еще есть сетьвопросы. Обычно возникает ошибка тайм-аута, когда я запускаю тот же тест в кластере kube / romana: запускаю тест ab на том же узле, что и модуль. Оба столкнулись с одной и той же ошибкой тайм-аута, но в романе я мог получить несколько тысяч запросов, чтобы завершить работу до истечения времени ожидания. Калико сталкивается с ошибкой тайм-аута до достижения дюжины запросов.
Другие варианты или примечания:- net.netfilter.nf_conntrack_tcp_be_liberal = 0/1, похоже, не имеет значения - более высокие значения -n
иногда работают, но в значительной степени случайны. - запуск теста 'ab' при низких значениях -n
несколько раз подряд может иногда вызвать тайм-аут
На данный момент я почти уверен, что это какая-то проблема с нашей установкой centos, но я не могу дажеугадай, что это может бытьСуществуют ли какие-либо другие ограничения, sysctl или другие конфиги, которые могут вызвать это?
====== Обновление 6 ноября 2019 года ======
Я наблюдаю, что у нас былостарое ядро установлено в, так что я обновил мою тестовую виртуальную машину kube / calico тем же более новым ядром 5.3.8-1.el7.elrepo.x86_64. После обновления и нескольких перезагрузок я больше не могу воспроизвести ошибки тайм-аута «apr_pollset_poll: указанное время истекло (70007)».
Теперь, когда ошибка истекла, я смог повторить первоначальный тест, гдеЯ загружаю тестовый модуль A и уничтожаю модуль B на своих виртуальных машинах vSphere. В средах Романа проблема все еще существовала, но только в том случае, когда нагрузочное тестирование проводилось на другом хосте, чем там, где находится модуль А. Если я запускаю тест на том же хосте, никаких ошибок вообще нет. При использовании Calico вместо romana на каждом хосте нет ошибок нагрузочного теста, поэтому проблема исчезла. Возможно, еще есть некоторые настройки, которые могут помочь романе, но я думаю, что это «удар 3» для романа, поэтому я начну переводить полную среду на Calico и проведу там некоторые приемочные испытания, чтобы убедиться, что нет скрытых ошибок.