• 以 Daemonset 方式部署 kube-proxy

    以 Daemonset 方式部署 kube-proxy

    kube-proxy 可以用二进制部署,也可以用 kubelet 的静态 Pod 部署,但最简单使用 DaemonSet 部署。直接使用 ServiceAccount 的 token 认证,不需要签发证书,也就不用担心证书过期问题。

    先在终端设置下面的变量:

    1. APISERVER="https://10.200.16.79:6443"
    2. CLUSTER_CIDR="10.10.0.0/16"
    • APISERVER 替换为 apiserver 对外暴露的访问地址。有同学想问为什么不直接用集群内的访问地址(kubernetes.default 或对应的 CLUSTER IP),这是一个鸡生蛋还是蛋生鸡的问题,CLSUTER IP 本身就是由 kube-proxy 来生成 iptables 或 ipvs 规则转发 Service 对应 Endpoint 的 Pod IP,kube-proxy 刚启动还没有生成这些转发规则,生成规则的前提是 kube-proxy 需要访问 apiserver 获取 Service 与 Endpoint,而由于还没有转发规则,kube-proxy 访问 apiserver 的 CLUSTER IP 的请求无法被转发到 apiserver。
    • CLUSTER_CIDR 替换为集群 Pod IP 的 CIDR 范围,这个在部署 kube-controller-manager 时也设置过

    为 kube-proxy 创建 RBAC 权限和配置文件:

    1. cat <<EOF | kubectl apply -f -
    2. apiVersion: v1
    3. kind: ServiceAccount
    4. metadata:
    5. name: kube-proxy
    6. namespace: kube-system
    7. ---
    8. apiVersion: rbac.authorization.k8s.io/v1
    9. kind: ClusterRoleBinding
    10. metadata:
    11. name: system:kube-proxy
    12. roleRef:
    13. apiGroup: rbac.authorization.k8s.io
    14. kind: ClusterRole
    15. name: system:node-proxier
    16. subjects:
    17. - kind: ServiceAccount
    18. name: kube-proxy
    19. namespace: kube-system
    20. ---
    21. kind: ConfigMap
    22. apiVersion: v1
    23. metadata:
    24. name: kube-proxy
    25. namespace: kube-system
    26. labels:
    27. app: kube-proxy
    28. data:
    29. kubeconfig.conf: |-
    30. apiVersion: v1
    31. kind: Config
    32. clusters:
    33. - cluster:
    34. certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    35. server: ${APISERVER}
    36. name: default
    37. contexts:
    38. - context:
    39. cluster: default
    40. namespace: default
    41. user: default
    42. name: default
    43. current-context: default
    44. users:
    45. - name: default
    46. user:
    47. tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    48. config.conf: |-
    49. apiVersion: kubeproxy.config.k8s.io/v1alpha1
    50. kind: KubeProxyConfiguration
    51. bindAddress: 0.0.0.0
    52. clientConnection:
    53. acceptContentTypes: ""
    54. burst: 10
    55. contentType: application/vnd.kubernetes.protobuf
    56. kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
    57. qps: 5
    58. # 集群中 Pod IP 的 CIDR 范围
    59. clusterCIDR: ${CLUSTER_CIDR}
    60. configSyncPeriod: 15m0s
    61. conntrack:
    62. # 每个核心最大能跟踪的NAT连接数,默认32768
    63. maxPerCore: 32768
    64. min: 131072
    65. tcpCloseWaitTimeout: 1h0m0s
    66. tcpEstablishedTimeout: 24h0m0s
    67. enableProfiling: false
    68. healthzBindAddress: 0.0.0.0:10256
    69. iptables:
    70. # SNAT 所有 Service 的 CLUSTER IP
    71. masqueradeAll: false
    72. masqueradeBit: 14
    73. minSyncPeriod: 0s
    74. syncPeriod: 30s
    75. ipvs:
    76. minSyncPeriod: 0s
    77. # ipvs 调度类型,默认是 rr,支持的所有类型:
    78. # rr: round-robin
    79. # lc: least connection
    80. # dh: destination hashing
    81. # sh: source hashing
    82. # sed: shortest expected delay
    83. # nq: never queue
    84. scheduler: rr
    85. syncPeriod: 30s
    86. metricsBindAddress: 0.0.0.0:10249
    87. # 使用 ipvs 模式转发 service
    88. mode: ipvs
    89. # 设置 kube-proxy 进程的 oom-score-adj 值,范围 [-1000,1000]
    90. # 值越低越不容易被杀死,这里设置为 —999 防止发生系统OOM时将 kube-proxy 杀死
    91. oomScoreAdj: -999
    92. EOF

    在终端设置下面的变量:

    1. ARCH="amd64"
    2. VERSION="v1.16.1"
    • VERSION 是 K8S 版本
    • ARCH 是节点的 cpu 架构,大多数用的 amd64,即 x86_64。其它常见的还有: arm64, arm, ppc64le, s390x,如果你的集群有不同 cpu 架构的节点,可以分别指定 ARCH 部署多个 daemonset (每个节点不会有多个 kube-proxy,nodeSelector 会根据 cpu 架构来选中节点)

    使用 hostNetwork 以 Daemonset 方式部署 kube-proxy 到每个节点:

    1. cat <<EOF | kubectl apply -f -
    2. apiVersion: apps/v1
    3. kind: DaemonSet
    4. metadata:
    5. labels:
    6. k8s-app: kube-proxy-ds-${ARCH}
    7. name: kube-proxy-ds-${ARCH}
    8. namespace: kube-system
    9. spec:
    10. selector:
    11. matchLabels:
    12. k8s-app: kube-proxy-ds-${ARCH}
    13. updateStrategy:
    14. type: RollingUpdate
    15. template:
    16. metadata:
    17. labels:
    18. k8s-app: kube-proxy-ds-${ARCH}
    19. spec:
    20. priorityClassName: system-node-critical
    21. containers:
    22. - name: kube-proxy
    23. image: k8s.gcr.io/kube-proxy-${ARCH}:${VERSION}
    24. imagePullPolicy: IfNotPresent
    25. command:
    26. - /usr/local/bin/kube-proxy
    27. - --config=/var/lib/kube-proxy/config.conf
    28. - --hostname-override=\$(NODE_NAME)
    29. securityContext:
    30. privileged: true
    31. volumeMounts:
    32. - mountPath: /var/lib/kube-proxy
    33. name: kube-proxy
    34. - mountPath: /run/xtables.lock
    35. name: xtables-lock
    36. readOnly: false
    37. - mountPath: /lib/modules
    38. name: lib-modules
    39. readOnly: true
    40. env:
    41. - name: NODE_NAME
    42. valueFrom:
    43. fieldRef:
    44. fieldPath: spec.nodeName
    45. hostNetwork: true
    46. serviceAccountName: kube-proxy
    47. volumes:
    48. - name: kube-proxy
    49. configMap:
    50. name: kube-proxy
    51. - name: xtables-lock
    52. hostPath:
    53. path: /run/xtables.lock
    54. type: FileOrCreate
    55. - name: lib-modules
    56. hostPath:
    57. path: /lib/modules
    58. tolerations:
    59. - key: CriticalAddonsOnly
    60. operator: Exists
    61. - operator: Exists
    62. nodeSelector:
    63. beta.kubernetes.io/arch: ${ARCH}
    64. EOF