K8S部署步骤:9-部署Node节点

kubernetes Node节点包含如下组件:

  • etcd
  • flannel
  • docker
  • kubelet
  • kube-proxy

导入环境变量

$ source /root/local/bin/environment.sh

安装和配置kubelet

下载二进制文件

从CHANGELOG页面下载server tarball文件

$ wget https://dl.k8s.io/v1.10.0/kubernetes-server-linux-amd64.tar.gz
$ tar -xzvf kubernetes-server-linux-amd64.tar.gz
$ sudo cp -r kubernetes/server/bin/{kube-proxy,kubelet,kubectl} /root/local/bin/

kubelet启动时会向kube-apiserver发送TLS bootstrapping请求,需要先将bootstrap token文件中的kubelet-bootstrap用户赋予system:node-bootstrapper角色,然后kubelet才有权限创建认证请求:

$ kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap

–user=kubelet-bootstrap是文件/etc/kubernetes/token.csv 中指定的用户名,同时也写入了文件/etc/kubernetes/bootstrap.kubeconfig;

创建kubelet bootstrapping kubeconfig文件

# 设置集群参数
$ kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=bootstrap.kubeconfig
# 设置客户端认证参数
$ kubectl config set-credentials kubelet-bootstrap \
  --token=${BOOTSTRAP_TOKEN} \
  --kubeconfig=bootstrap.kubeconfig
# 设置上下文参数
$ kubectl config set-context default \
  --cluster=kubernetes \
  --user=kubelet-bootstrap \
  --kubeconfig=bootstrap.kubeconfig
# 设置默认上下文
$ kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
$ mv bootstrap.kubeconfig /etc/kubernetes/
  • –embed-certs为true时表示将certificate-authority证书写入到生成的bootstrap.kubeconfig文件中;
  • 设置kubelet客户端认证参数时没有指定秘钥和证书,后续由kube-apiserver自动生成;

创建kubelet的systemd unit文件

# 必须先创建工作目录
$ sudo mkdir /var/lib/kubelet
$ cat > kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/root/local/bin/kubelet \\
  --address=${NODE_IP} \\
  --hostname-override=${NODE_IP} \\
  --pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest \\
  --experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig \\
  --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
  --cert-dir=/etc/kubernetes/ssl \\
  --cluster-dns=${CLUSTER_DNS_SVC_IP} \\
  --cluster-domain=${CLUSTER_DNS_DOMAIN} \\
  --hairpin-mode promiscuous-bridge \\
  --allow-privileged=true \\
  --serialize-image-pulls=false \\
  --logtostderr=true \\
  --fail-swap-on=false \\
  --v=2
ExecStartPost=/sbin/iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -s 172.16.0.0/12 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -s 192.168.0.0/16 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -p tcp --dport 4194 -j DROP
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
  • –address不能设置为127.0.0.1,否则后续Pods访问kubelet的API接口时会失败,因为Pods访问的127.0.0.1指向自己而不是kubelet;
  • 如果设置了–hostname-override选项,则kube-proxy也需要设置该选项,否则会出现找不到Node的情况;
  • –experimental-bootstrap-kubeconfig指向bootstrap kubeconfig文件,kubelet 使用该文件中的用户名和token向kube-apiserver发送TLS Bootstrapping请求;
  • 管理员通过了CSR请求后,kubelet自动在–cert-dir目录创建证书和私钥文件(kubelet-client.crt和kubelet-client.key),然后写入–kubeconfig文件(自动创建 –kubeconfig指定的文件);
  • 建议在–kubeconfig配置文件中指定kube-apiserver地址,如果未指定–api-servers选项,则必须指定–require-kubeconfig选项后才从配置文件中读取kue-apiserver的地址,否则kubelet启动后将找不到kube-apiserver(日志中提示未找到API Server),kubectl get nodes不会返回对应的Node信息;
  • –cluster-dns 指定kubedns的Service IP(可以先分配,后续创建kubedns 服务时指定该IP),–cluster-domain指定域名后缀,这两个参数同时指定后才会生效;
  • kubelet cAdvisor默认在所有接口监听4194端口的请求,对于有外网的机器来说不安全,ExecStartPost选项指定的iptables规则只允许内网机器访问4194端口;

启动kubelet

$ sudo cp kubelet.service /etc/systemd/system/kubelet.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable kubelet
$ sudo systemctl start kubelet
$ sudo systemctl status kubelet

通过kubelet的TLS证书请求

kubelet首次启动时向kube-apiserver发送证书签名请求,必须通过后kubernetes系统才会将该Node加入到集群。

查看未授权的 CSR 请求:

$ kubectl get csr
# NAME                                                   AGE       REQUESTOR           CONDITION
# node-csr-Gd7y2XZSpQSYD-3tLMFkMaJqn0iVYj83PwewakAIQhc   2d        kubelet-bootstrap   Pendding
# node-csr-xHFjgF2oo6X7Z0zm1MI0sJTe6ktvg86G0UoZx5WMJWI   2d        kubelet-bootstrap   Pendding

$ kubectl get nodes
# No resources found.

通过 CSR 请求:

$ kubectl certificate approve node-csr-Gd7y2XZSpQSYD-3tLMFkMaJqn0iVYj83PwewakAIQhc
# certificatesigningrequest "node-csr-Gd7y2XZSpQSYD-3tLMFkMaJqn0iVYj83PwewakAIQhc" approved

$ kubectl certificate approve node-csr-xHFjgF2oo6X7Z0zm1MI0sJTe6ktvg86G0UoZx5WMJWI
# certificatesigningrequest "node-csr-xHFjgF2oo6X7Z0zm1MI0sJTe6ktvg86G0UoZx5WMJWI" approved

$ kubectl get nodes
# NAME           STATUS    ROLES     AGE       VERSION
# 10.211.55.12   Ready         2d        v1.8.1
# 10.211.55.15   Ready         2d        v1.8.1

自动生成了kubelet kubeconfig文件和公私钥:

$ ls -l /etc/kubernetes/kubelet.kubeconfig
# -rw------- 1 root root 2284 Apr  7 02:07 /etc/kubernetes/kubelet.kubeconfig
$ ls -l /etc/kubernetes/ssl/kubelet*
# -rw-r--r-- 1 root root 1046 Apr  7 02:07 /etc/kubernetes/ssl/kubelet-client.crt
# -rw------- 1 root root  227 Apr  7 02:04 /etc/kubernetes/ssl/kubelet-client.key
# -rw-r--r-- 1 root root 1103 Apr  7 02:07 /etc/kubernetes/ssl/kubelet.crt
# -rw------- 1 root root 1675 Apr  7 02:07 /etc/kubernetes/ssl/kubelet.key

配置kube-proxy

创建kube-proxy证书

创建kube-proxy证书签名请求:

$ cat > kube-proxy-csr.json << EOF
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
  • CN指定该证书的User为 system:kube-proxy;
  • kube-apiserver预定义的RoleBinding system:node-proxier将User system:kube-proxy与Role system:node-proxier绑定,该Role授予了调用 kube-apiserverProxy 相关 API 的权限;
  • hosts属性值为空列表;

生成kube-proxy客户端证书和私钥:

$ cfssl gencert -ca=/etc/kubernetes/ssl/ca.pem \
  -ca-key=/etc/kubernetes/ssl/ca-key.pem \
  -config=/etc/kubernetes/ssl/ca-config.json \
  -profile=kubernetes  kube-proxy-csr.json | cfssljson -bare kube-proxy
$ ls kube-proxy*
# kube-proxy.csr kube-proxy-csr.json kube-proxy-key.pem kube-proxy.pem
$ sudo mv kube-proxy*.pem /etc/kubernetes/ssl/
$ sudo rm -rf kube-proxy.csr kube-proxy-csr.json

创建kube-proxy kubeconfig文件

# 设置集群参数
$ kubectl config set-cluster kubernetes \
  --certificate-authority=/etc/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kube-proxy.kubeconfig
# 设置客户端认证参数
$ kubectl config set-credentials kube-proxy \
  --client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
  --client-key=/etc/kubernetes/ssl/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
$ mv kube-proxy.kubeconfig /etc/kubernetes/
  • 设置集群参数和客户端认证参数时 –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 的权限;

创建kube-proxy的systemd unit文件

# 必须先创建工作目录
$ sudo mkdir -p /var/lib/kube-proxy
$ cat > kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/root/local/bin/kube-proxy \\
  --bind-address=${NODE_IP} \\
  --hostname-override=${NODE_IP} \\
  --cluster-cidr=${SERVICE_CIDR} \\
  --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \\
  --logtostderr=true \\
  --v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
  • –hostname-override 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 iptables 规则;
  • –cluster-cidr 必须与 kube-apiserver 的 –service-cluster-ip-range 选项值一致;
  • kube-proxy 根据 –cluster-cidr 判断集群内部和外部流量,指定 –cluster-cidr 或 –masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT;
  • –kubeconfig 指定的配置文件嵌入了 kube-apiserver 的地址、用户名、证书、秘钥等请求和认证信息;
  • 预定义的 RoleBinding cluster-admin 将User system:kube-proxy 与 Role system:node-proxier 绑定,该 Role 授予了调用 kube-apiserver Proxy 相关 API 的权限;

启动 kube-proxy

$ sudo cp kube-proxy.service /etc/systemd/system/
$ sudo systemctl daemon-reload
$ sudo systemctl enable kube-proxy
$ sudo systemctl start kube-proxy
$ sudo systemctl status kube-proxy

你可能感兴趣的:(k8s,kubernetes)