tags: worker, kube-proxy
kube-proxy 运行在所有 worker 节点上,,它监听 apiserver 中 service 和 Endpoint 的变化情况,创建路由规则来进行服务负载均衡。
本文档讲解部署 kube-proxy 的部署,使用 ipvs 模式。
创建证书签名请求:
[admin@k8s-admin ~]$ cat >cert/kube-proxy-csr.json <<EOF
{
"CN": "system:kube-proxy",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Jiangsu",
"L": "Suzhou",
"O": "k8s",
"OU": "wangxyd"
}
]
}
EOF
- CN:指定该证书的 User 为
system:kube-proxy
; - 预定义的 RoleBinding
system:node-proxier
将Usersystem:kube-proxy
与 Rolesystem:node-proxier
绑定,该 Role 授予了调用kube-apiserver
Proxy 相关 API 的权限; - 该证书只会被 kube-proxy 当做 client 证书使用,所以 hosts 字段为空。
生成证书和私钥:
[admin@k8s-admin ~]$ cfssl gencert \
-ca=cert/ca.pem \
-ca-key=cert/ca-key.pem \
-config=cert/ca-config.json \
-profile=kubernetes \
cert/kube-proxy-csr.json |cfssljson -bare cert/kube-proxy
[admin@k8s-admin ~]$ ls cert/kube-proxy*
cert/kube-proxy.csr cert/kube-proxy-csr.json cert/kube-proxy-key.pem cert/kube-proxy.pem
[admin@k8s-admin ~]$ source environment.sh
[admin@k8s-admin ~]$ kubectl config set-cluster kubernetes \
--certificate-authority=cert/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=conf/kube-proxy.kubeconfig
Cluster "kubernetes" set.
[admin@k8s-admin ~]$ kubectl config set-credentials kube-proxy \
--client-certificate=cert/kube-proxy.pem \
--client-key=cert/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=conf/kube-proxy.kubeconfig
User "kube-proxy" set.
[admin@k8s-admin ~]$ kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=conf/kube-proxy.kubeconfig
Context "default" created.
[admin@k8s-admin ~]$ kubectl config use-context default \
--kubeconfig=conf/kube-proxy.kubeconfig
Switched to context "default".
--embed-certs=true
:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl-proxy.kubeconfig 文件中(不加时,写入的是证书文件路径)。
查看当前上下文的配置信息:
[admin@k8s-admin ~]$ kubectl config view \
--kubeconfig conf/kube-proxy.kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.99.100:8443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kube-proxy
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: kube-proxy
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
从 v1.10 开始,kube-proxy 部分参数 可以配置文件中配置。可以使用 --write-config-to
选项生成该配置文件,或者参考 kubeproxyconfig 的类型定义源文件
创建 kube-proxy config 文件模板:
[admin@k8s-admin ~]$ cat >conf/kube-proxy-config.yaml.j2 <<EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: "/etc/kubernetes/kube-proxy.kubeconfig"
bindAddress: {{ ansible_eth0.ipv4.address }}
clusterCIDR: {{ CLUSTER_CIDR }}
healthzBindAddress: {{ ansible_eth0.ipv4.address }}:10256
hostnameOverride: {{ ansible_host }}
metricsBindAddress: {{ ansible_eth0.ipv4.address }}:10249
mode: "ipvs"
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 模式。
[admin@k8s-admin ~]$ cat >conf/kube-proxy.service.j2 <<"EOF"
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
WorkingDirectory={{ K8S_DIR }}/kube-proxy
EnvironmentFile=/etc/kubernetes/kube-proxy.conf
ExecStart=/usr/local/bin/kube-proxy $KUBE_PROXY_ARGS
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
[admin@k8s-admin ~]$ cat >conf/kube-proxy.conf <<"EOF"
KUBE_PROXY_ARGS=" \
--config=/etc/kubernetes/kube-proxy-config.yaml \
--logtostderr=true \
--v=2"
EOF
[admin@k8s-admin ~]$ cat >conf/kube-proxy.service.yaml <<"EOF"
- hosts: k8s-workers
remote_user: root
tasks:
- name: copy kube-proxy.kubeconfig
copy:
src: kube-proxy.kubeconfig
dest: /etc/kubernetes/kube-proxy.kubeconfig
- name: copy conf/kube-proxy-config.yaml
template:
src: kube-proxy-config.yaml.j2
dest: /etc/kubernetes/kube-proxy-config.yaml
- name: copy kube-proxy.service
template:
src: kube-proxy.service.j2
dest: /usr/lib/systemd/system/kube-proxy.service
- name: copy kube-proxy.conf
copy:
src: kube-proxy.conf
dest: /etc/kubernetes/kube-proxy.conf
- name: create WorkingDirectory
file:
path: '{{ K8S_DIR }}/kube-proxy'
state: directory
- name: enable and start kube-proxy.service
systemd:
name: kube-proxy
state: restarted
enabled: yes
daemon_reload: yes
EOF
[admin@k8s-admin ~]$ ansible-playbook conf/kube-proxy.service.yaml
[admin@k8s-admin ~]$ ansible k8s-workers -m shell -a "systemctl status kube-proxy.service|grep -e Loaded -e Active"
- 必须创建工作目录;
- 确保状态为“active (running)”并且“enabled”。
[root@k8s-node01 ~]# ss -lnptu|grep kube-proxy
tcp LISTEN 0 128 192.168.99.101:10249 *:* users:(("kube-proxy",pid=2957,fd=8))
tcp LISTEN 0 128 192.168.99.101:10256 *:* users:(("kube-proxy",pid=2957,fd=7))
- 10249:http prometheus metrics port;
- 10256:http healthz port。
[root@k8s-node01 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 10.0.0.1:443 rr
-> 192.168.99.101:6443 Masq 1 0 0
-> 192.168.99.102:6443 Masq 1 0 0
-> 192.168.99.103:6443 Masq 1 0 0
- 可见将所有到 kubernetes cluster ip 443 端口的请求都转发到 kube-apiserver 的 6443 端口。