nginx vs kubernetes(作为外部平衡器) - 无法平衡API服务器

时间:2018-05-03 20:39:33

标签: nginx kubernetes

我们正在尝试构建HA Kubernetese集群,其中包含3个核心节点,每个节点都有完整的重要组件:ETCD + APIServer + Scheduller + ControllerManager和外部平衡器。由于ETCD可以自己创建集群,因此我们可以使用HA APIServers进行堆栈。几周之前看似显而易见的任务现在变成了一场灾难" ......

我们决定使用nginx作为3个独立APIServers的平衡器。我们群集中与APIServer(Kublets,Kube-Proxys,Schedulers,ControllerManagers ..)通信的所有其余部分都假设使用平衡器来访问它。在我们开始破坏"破坏性之前,一切都进展顺利。测试(我称之为),一些pod正在运行。 以下是使用HS拨打的APIServer配置部分:

.. --apiserver-count=3 --endpoint-reconciler-type=lease ..

这是我们的nginx.conf:

user                    nginx;

error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;

worker_processes        auto;

events {
    multi_accept        on;
    use                 epoll;
    worker_connections  4096;
}

http {
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

    access_log          /var/log/nginx/access.log  main;

    sendfile            on;
    #tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    gzip                on;

    underscores_in_headers on;

   include /etc/nginx/conf.d/*.conf;
}

和apiservers.conf:

upstream apiserver_https {
    least_conn;
    server core1.sbcloud:6443; # max_fails=3 fail_timeout=3s;
    server core2.sbcloud:6443; # max_fails=3 fail_timeout=3s;
    server core3.sbcloud:6443; # max_fails=3 fail_timeout=3s;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen                      6443 ssl so_keepalive=1m:10s:3; # http2; 

    ssl_certificate             "/etc/nginx/certs/server.crt";
    ssl_certificate_key         "/etc/nginx/certs/server.key";

    expires                     -1;
    proxy_cache                 off;
    proxy_buffering             off;
    proxy_http_version          1.1;

    proxy_connect_timeout       3s;

    proxy_next_upstream         error timeout invalid_header http_502; # non_idempotent # http_500 http_503 http_504;
    #proxy_next_upstream_tries   3;
    #proxy_next_upstream_timeout 3s;
    proxy_send_timeout          30m;
    proxy_read_timeout          30m;
    reset_timedout_connection   on;


    location / {
        proxy_pass              https://apiserver_https;
        add_header              Cache-Control "no-cache";
        proxy_set_header        Upgrade $http_upgrade;
        proxy_set_header        Connection "upgrade";
        proxy_set_header        Host $http_host;
        proxy_set_header        Authorization $http_authorization;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        X-SSL-CLIENT-CERT $ssl_client_cert;
     }
}

经过一些测试后发现,Kubernetes似乎使用单一的长生活联系而不是传统的开放式关闭会议。这可能是SSL的露水。所以我们必须将proxy_send_timeout和proxy_read_timeout增加到荒谬的30m(APIServer的默认值是1800s)。如果此设置低于10米,则所有客户端(如Scheduler和ControllerManager)将因INTERNAL_ERROR流而产生吨数。

因此,对于碰撞测试,我只需将其中一个APIServers轻轻关闭即可。然后我重新启动另一个,所以nginx看到上游关闭并将所有当前连接切换到最后一个。几秒钟后重新启动APIserver返回,我们有2个APIServers工作。然后,我通过运行' systemctl stop network'将网络放在第三个APIServer上。在那台服务器上,所以它没有机会通知Kubernetes或者nginx它已经关闭了。

现在,集群完全坏了! nginx似乎认识到上游已经崩溃,但它不会重置已经死亡的上游已经令人兴奋的连接。我仍然可以用'ss -tnp'来看到它们。如果我重新启动Kubernetes服务,他们将重新连接并继续工作,如果我重新启动nginx也是如此 - 新的套接字将显示在ss输出中。

只有当我通过关闭网络使API服务器不可用(阻止它关闭与nginx的现有连接并通知Kubernetes它正在关闭)时,才会发生这种情况。如果我停止它 - 一切都像魅力一样。但这不是一个真实的案例。服务器可以在没有任何警告的情况下直接关闭 - 只是即时。

我们做错了什么?有没有办法强制nginx删除掉到上游的所有连接?在我们迁移到HAProxy或LVS之前要尝试的任何事情,并且在我们尝试使其平衡而不是破坏我们不那么HA群集的过程中毁掉一周的nginx。

0 个答案:

没有答案