kube-proxy部署

作者: 一瓶多先生 | 来源:发表于2020-11-14 16:49 被阅读0次

    kube-proxy

    我们知道容器的特点是快速创建、快速销毁,Kubernetes Pod和容器一样只具有临时的生命周期,一个Pod随时有可能被终止或者漂移,随着集群的状态变化而变化,一旦Pod变化,则该Pod提供的服务也就无法访问,如果直接访问Pod则无法实现服务的连续性和高可用性,因此显然不能使用Pod地址作为服务暴露端口。

    解决这个问题的办法和传统数据中心解决无状态服务高可用的思路完全一样,通过负载均衡和VIP实现后端真实服务的自动转发、故障转移。

    这个负载均衡在Kubernetes中称为Service,VIP即Service ClusterIP,因此可以认为Kubernetes的Service就是一个四层负载均衡,Kubernetes对应的还有七层负载均衡Ingress,本文仅介绍Kubernetes Service。

    这个Service就是由kube-proxy实现的,ClusterIP不会因为Pod状态改变而变,需要注意的是VIP即ClusterIP是个假的IP,这个IP在整个集群中根本不存在,当然也就无法通过IP协议栈无法路由,底层underlay设备更无法感知这个IP的存在,因此ClusterIP只能是单主机(Host Only)作用域可见,这个IP在其他节点以及集群外均无法访问。

    Kubernetes为了实现在集群所有的节点都能够访问Service,kube-proxy默认会在所有的Node节点都创建这个VIP并且实现负载

    部署策略:

    • 使用 kubeconfig 访问 apiserver 的安全端口;
    • 在 KubeProxyConfiguration 类型的 yaml 文件配置主要参数;
    • 使用 ipvs 代理模式;

    01.创建Kube-proxy证书和私钥

    cat > kube-proxy-csr.json <<EOF
    {
      "CN": "system:kube-proxy",
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "China",
          "L": "Beijing",
          "O": "Kubernetes",
          "OU": "Kubernetes",
          "ST": "Beijing"
        }
      ]
    }
    EOF
    

    解释:
    CN:指定该证书的 User 为 system:kube-proxy;
    预定义的 RoleBinding system:node-proxier 将User system:kube-proxy 与Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;
    该证书只会被 kube-proxy 当做 client 证书使用,所以 hosts 字段为空。

    创建 kube-proxy 凭证与私钥:

    cfssl gencert \
      -ca=ca.pem \
      -ca-key=ca-key.pem \
      -config=ca-config.json \
      -profile=kubernetes \
      kube-proxy-csr.json | cfssljson -bare kube-proxy
    

    结果将产生以下两个文件:

    kube-proxy-key.pem
    kube-proxy.pem
    

    02.创建 kube-proxy kubeconfig 文件

    export KUBE_APISERVER="https://apiserver-p001.svc.gxd88.cn:6443"
    
    • 设置集群参数

      kubectl config set-cluster kubernetes \
        --certificate-authority=ca.pem \
        --embed-certs=true \
        --server=${KUBE_APISERVER} \
        --kubeconfig=kube-proxy.kubeconfig
      
    • 设置客户端认证参数

      kubectl config set-credentials kube-proxy \
        --client-certificate=kube-proxy.pem \
        --client-key=kube-proxy-key.pem \
        --embed-certs=true \
        --kubeconfig=kube-proxy.kubeconfig  
      
    • 设置上下文参数

      kubectl config set-context default \
        --cluster=kubernetes \
        --user=kube-proxy \
        --kubeconfig=kube-proxy.kubeconfig
      
    • 设置默认上下文

      kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
      
    • 设置集群参数和客户端认证参数时 --embed-certs 都为 true,这会将 certificate-authority、client-certificate 和 client-key 指向的证书文件内容写入到生成的 kube-proxy.kubeconfig 文件中;
    • kube-proxy.pem 证书中 CN 为 system:kube-proxy,kube-apiserver 预定义的 RoleBinding cluster-admin 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;

    03.维护kube-proxy配置文件

    同kubelet一样, kube-proxy中的很多参数已经废弃需要单独的配置文件支持, 你可以使用 --write-config-to 选项生成该配置文件

    注意: 如果kubelet中配置了hostnameOverride那么kube-proxy也需要相同的配置

    cat  > /srv/kubernetes/conf/kube-proxy-config.yml <<EOF
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    bindAddress: 10.40.61.116
    clientConnection:
      acceptContentTypes: ""
      burst: 10
      contentType: application/vnd.kubernetes.protobuf
      kubeconfig: "/srv/kubernetes/kubeconfig/kube-proxy.kubeconfig"
      qps: 5
    clusterCIDR: "10.243.0.0/16"
    configSyncPeriod: 15m0s
    conntrack:
      maxPerCore: 32768
      min: 131072
      tcpCloseWaitTimeout: 1h0m0s
      tcpEstablishedTimeout: 24h0m0s
    detectLocalMode: ""
    enableProfiling: false
    healthzBindAddress: 0.0.0.0:10256
    hostnameOverride: "py-modelo2o08cn-p005.pek3.example.net"
    iptables:
      masqueradeAll: false
      masqueradeBit: 14
      minSyncPeriod: 0s
      syncPeriod: 30s
    ipvs:
      excludeCIDRs: null
      minSyncPeriod: 0s
      scheduler: ""
      strictARP: false
      syncPeriod: 30s
      tcpFinTimeout: 0s
      tcpTimeout: 0s
      udpTimeout: 0s
    kind: KubeProxyConfiguration
    metricsBindAddress: 127.0.0.1:10249
    mode: "ipvs"
    nodePortAddresses: null
    oomScoreAdj: -999
    portRange: ""
    showHiddenMetricsForVersion: ""
    udpIdleTimeout: 250ms
    winkernel:
      enableDSR: false
      networkName: ""
      sourceVip: ""
    EOF
    

    参数说明:

    bindAddress: 监听地址;

    clientConnection.kubeconfig: 连接 apiserver 的 kubeconfig 文件

    clusterCIDR: kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT;

    hostnameOverride: 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 ipvs 规则;

    mode: 使用 ipvs 模式。

    04.使用systemd管理kube-proxy

    根据实际情况替换--hostname-override

    cat > /etc/systemd/system/kube-proxy.service <<EOF
    [Unit]
    Description=Kubernetes Kube Proxy
    Documentation=https://github.com/kubernetes/kubernetes
    After=network.target
    
    [Service]
    ExecStart=/srv/kubernetes/bin/kube-proxy \
      --config=/srv/kubernetes/conf/kube-proxy-config.yml \
      --v=2 \
      --logtostderr=false \
      --log-dir=/srv/kubernetes/log
    Restart=on-failure
    RestartSec=5
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    

    05.启动/停止 kube-proxy

    sudo /bin/systemctl daemon-reload
    sudo /bin/systemctl enable kube-proxy.service
    

    kube-proxy can be started and stopped as follows:

    sudo systemctl start kube-proxy.service
    sudo systemctl stop  kube-proxy.service
    

    06.验证

    检查服务:

    systemctl status kube-proxy|grep Active
       Active: active (running) since 四 2020-04-16 15:46:21 CST; 1 day 22h ago
    

    检查端口:

    kube-proxy 监听 10249 和 10256 端口:

    • 10249:对外提供 /metrics;
    • 10256:对外提供 /healthz 的访问。
    $ netstat -lnpt|grep kube-prox
    tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      11562/kube-proxy
    tcp6       0      0 :::10256                :::*                    LISTEN      11562/kube-proxy
    

    07.测试

    创建pod测试

    kubectl run --image=nginx:1.17 nginx-app --port=80
    

    创建service

    kubectl  expose  deployment  nginx-app --port=80  --name nginx-app
    

    查看ipvs规则

    $ ipvsadm -Ln
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
      -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    TCP  10.244.0.1:443 rr
      -> 10.40.58.153:6443            Masq    1      0          0
      -> 10.40.58.154:6443            Masq    1      0          0
      -> 10.40.61.116:6443            Masq    1      0          0
    TCP  10.244.155.238:80 rr
      -> 10.243.104.2:80              Masq    1      0          0
    

    Q&A

    Q: 启动kube-proxy 日志文件一直报如下错误

    proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[10 40 61 116 0 0 0 0 0 0 0 0 0 0 0 0]
    proxier.go:1192] Failed to sync endpoint for service: 10.244.0.1:443/TCP, err: parseIP Error ip=[10 40 61 116 0 0 0 0 0 0 0 0 0 0 0 0]
    

    相关文章

      网友评论

        本文标题:kube-proxy部署

        本文链接:https://www.haomeiwen.com/subject/fjfqbktx.html