第八章 部署k8s-v1.7.6 node 节点
最后更新于:2022-04-02 05:06:55
### 部署node节点
kubernetes node 节点包含如下组件:
- Flanneld:使用flanneld-0.8 支持阿里云 host-gw模式,以获取最佳性能。
- Docker17.07.0-ce:docker的安装很简单,这里也不说了。
- kubelet
- kube-proxy
- 下面着重讲kubelet和kube-proxy的安装,同时还要将之前安装的flannel集成TLS验证。
注意:每台 node 上都需要安装 flannel,master 节点上可以不必安装。
### 检查目录和文件
我们再检查一下三个节点上,经过前几步操作生成的配置文件。
# ls /etc/kubernetes/ssl/
admin-key.pem admin.pem ca-key.pem ca.pem kube-proxy-key.pem kube-proxy.pem kubernetes-key.pem kubernetes.pem
# ls /etc/kubernetes/
apiserver bootstrap.kubeconfig config controller-manager kube-proxy.kubeconfig scheduler ssl token.csv
### flannel 网络架构图
![image](https://i.imgur.com/aegDizo.jpg)
![image](https://i.imgur.com/zWmGltI.jpg)
![images](http://img.blog.csdn.net/20170424152830472?/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDI3ODkyMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
### 配置安装Flanneld,默认使用yum 安装。需要替换二进制 flanneld
下载flanned-0.8 binary.
yum install flanneld -y
wget https://github.com/coreos/flannel/releases/download/v0.8.0/flanneld-amd64
chmod +x flanneld-amd64
cp flanneld-amd64 /usr/bin/flanneld
service配置文件/usr/lib/systemd/system/flanneld.service
cat /usr/lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/flanneld
EnvironmentFile=-/etc/sysconfig/docker-network
ExecStart=/usr/bin/flanneld-start $FLANNEL_OPTIONS
ExecStartPost=/usr/libexec/flannel/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
Restart=on-failure
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
/etc/sysconfig/flanneld配置文件
cat /etc/sysconfig/flanneld
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://172.16.200.100:2379,http://172.16.200.101:2379,http://172.16.200.102:2379"
# etcd config key. This is the configuration key that flannel queries
# For address range assignment
ETCD_PREFIX="/kube-centos/network"
FLANNEL_ETCD_KEY="/kube-centos/network"
ACCESS_KEY_ID=XXXXXXX
ACCESS_KEY_SECRET=XXXXXXX
# Any additional options that you want to pass
#FLANNEL_OPTIONS=" -iface=eth0 -log_dir=/data/logs/kubernetes --logtostderr=false --v=2"
#FLANNEL_OPTIONS="-etcd-cafile=/etc/kubernetes/ssl/ca.pem -etcd-certfile=/etc/kubernetes/ssl/kubernetes.pem -etcd-keyfile=/etc/kubernetes/ssl/kubernetes-key.pem"
- 设置etcd网络,主要是flannel用于分别docker的网络,‘/coreos.com/network/config’ 这个字段必须与flannel中的"FLANNEL_ETCD_KEY="/coreos.com/network" 保持一致
- 阿里云VPN 网络模式详细配置可参考 [AliCloud VPC Backend for Flannel](https://github.com/coreos/flannel/blob/master/Documentation/alicloud-vpc-backend.md)
在etcd中创建网络配置
执行下面的命令为docker分配IP地址段。
etcdctl mkdir /kube-centos/network
etcdctl mk /kube-centos/network/config '{"Network":"10.24.0.0/16","Backend":{"Type":"ali-vpc"}}'
etcdctl mk /kube-centos/network/config '{"Network":"10.24.0.0/16","Backend":{"Type":"host-gw"}}'
### 安装kubernetes-cni 依赖kublete 强制安装
rpm -ivh --force kubernetes-cni-0.5.1-0.x86_64.rpm --nodeps
配置cni 插件
mkdir -p /etc/cni/net.d
cat > /etc/cni/net.d/10-flannel.conf << EOF
{
"name": "cbr0",
"type": "flannel",
"delegate": {
"isDefaultGateway": true,
"forceAddress": true,
"bridge": "cni0",
"mtu": 1500
}
}
EOF
**cat /etc/sysctl.d/k8s.conf 内核参数修改**
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
sysctl -p /etc/sysctl.d/k8s.conf
**查看获取的地址段**
#etcdctl ls /kube-centos/network/subnets
/kube-centos/network/subnets/10.24.15.0-24
/kube-centos/network/subnets/10.24.38.0-24
### 安装和配置 kubelet
kubelet 启动时向 kube-apiserver 发送 TLS bootstrapping 请求,需要先将 bootstrap token 文件中的 kubelet-bootstrap 用户赋予 system:node-bootstrapper cluster 角色(role), 然后 kubelet 才能有权限创建认证请求(certificate signing requests):
cd /etc/kubernetes
kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap
**创建 kubelet 的service配置文件**
# cat /usr/lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=/usr/local/kubernetes/server/bin/kubelet \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBELET_API_SERVER \
$KUBELET_ADDRESS \
$KUBELET_PORT \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_POD_INFRA_CONTAINER \
$KUBELET_ARGS
Restart=on-failure
[Install]
WantedBy=multi-user.target
> kubelet的配置文件/etc/kubernetes/kubelet。其中的IP地址更改为你的每台node节点的IP地址。
> 注意:/var/lib/kubelet需要手动创建。
**kubelet 配置文件**
cat > /etc/kubernetes/kubelet << EOF
###
### kubernetes kubelet (minion) config
##
### The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=172.16.200.100"
##
### The port for the info server to serve on
##KUBELET_PORT="--port=10250"
##
### You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=172.16.200.100"
##
### location of the api-server
#KUBELET_API_SERVER="--api-servers=http://172.16.200.100:8080"
##
### pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=gcr.io/google_containers/pause:latest"
##
### Add your own!
KUBELET_ARGS="--cgroup-driver=systemd --cluster-dns=10.254.0.2 --experimental-bootstrap-kubeconfig=/etc/kubernetes/bootstrap.kubeconfig --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --require-kubeconfig --cert-dir=/etc/kubernetes/ssl --cluster-domain=cluster.local --hairpin-mode promiscuous-bridge --serialize-image-pulls=false --network-plugin=cni --cni-conf-dir=/etc/cni/net.d/ --cni-bin-dir=/opt/cni/bin/ --network-plugin-mtu=1500 --log-dir=/data/logs/kubernetes/ --v=2 --logtostderr=false"
EOF
- --address 不能设置为 127.0.0.1,否则后续 Pods 访问 kubelet 的 API 接口时会失败,因为 Pods 访问的 127.0.0.1 指向自己而不是 kubelet;
- 如果设置了 --hostname-override 选项,则 kube-proxy 也需要设置该选项,否则会出现找不到 Node 的情况;
- --cgroup-driver 配置成 systemd,不要使用cgroup,否则在 CentOS 系统中 kubelet 讲启动失败。docker修改cgroup启动参数 --exec-opt native.cgroupdriver=systemd
- --experimental-bootstrap-kubeconfig 指向 bootstrap kubeconfig 文件,kubelet 使用该文件中的用户名和 token 向 kube-apiserver 发送 TLS Bootstrapping 请求;
- 管理员通过了 CSR 请求后,kubelet 自动在 --cert-dir 目录创建证书和私钥文件(kubelet-client.crt 和 kubelet-client.key),然后写入 --kubeconfig 文件;
- 建议在 --kubeconfig 配置文件中指定 kube-apiserver 地址,如果未指定 --api-servers 选项,则必须指定 --require-kubeconfig 选项后才从配置文件中读取 kube-apiserver 的地址,否则 kubelet 启动后将找不到 kube-apiserver (日志中提示未找到 API Server),kubectl get nodes 不会返回对应的 Node 信息;
- --cluster-dns 指定 kubedns 的 Service IP(可以先分配,后续创建 kubedns 服务时指定该 IP),--cluster-domain 指定域名后缀,这两个参数同时指定后才会生效;
- --cluster-domain 指定 pod 启动时 /etc/resolve.conf 文件中的 search domain ,起初我们将其配置成了 cluster.local.,这样在解析 service 的 DNS 名称时是正常的,可是在解析 headless service 中的 FQDN pod name 的时候却错误,因此我们将其修改为 cluster.local,去掉嘴后面的 ”点号“ 就可以解决该问题,关于 kubernetes 中的域名/服务名称解析请参见我的另一篇文章。
- --kubeconfig=/etc/kubernetes/kubelet.kubeconfig中指定的kubelet.kubeconfig文件在第一次启动kubelet之前并不存在,请看下文,当通过CSR请求后会自动生成kubelet.kubeconfig文件,如果你的节点上已经生成了~/.kube/config文件,你可以将该文件拷贝到该路径下,并重命名为kubelet.kubeconfig,所有node节点可以共用同一个kubelet.kubeconfig文件,这样新添加的节点就不需要再创建CSR请求就能自动添加到kubernetes集群中。同样,在任意能够访问到kubernetes集群的主机上使用kubectl --kubeconfig命令操作集群时,只要使用~/.kube/config文件就可以通过权限认证,因为这里面已经有认证信息并认为你是admin用户,对集群拥有所有权限。
- KUBELET_POD_INFRA_CONTAINER 是基础镜像容器,需要翻墙下载。
- --network-plugin=cni 启用cni 管理docker 网络
- -cni-conf-dir=/etc/cni/net.d/ CNI 配置路径
- 注意 需要修改docker cgroup 驱动方式: --exec-opt native.cgroupdriver=systemd
> kubelet 依赖启动配置文件 bootstrap.kubeconfig
systemctl daemon-reload
systemctl enable kubelet
systemctl start kubelet
systemctl status kubelet
通过 kublet 的 TLS 证书请求
kubelet 首次启动时向 kube-apiserver 发送证书签名请求,必须通过后 kubernetes 系统才会将该 Node 加入到集群。
查看未授权的 CSR 请求
# kubectl get csr
NAME AGE REQUESTOR CONDITION
node-csr-8I8soRqLhxiH2nThkgUsL2oIaKyh15AuNOVgJddWBqA 2s kubelet-bootstrap Pending
node-csr-9byGSZPAX0eT60qME8_2PIZ0Q4GkDTFG-1tvPhVaH40 49d kubelet-bootstrap Approved,Issued
node-csr-DpvCEHT98ARavxjdLpa_yl_aNGddNTAX07MEVSAjnUM 4d kubelet-bootstrap Approved,Issued
node-csr-nAOtjarW3mJ3boQ3AtaeGCbQYbW_jo8AGscFnk1uxqw 8d kubelet-bootstrap Approved,Issued
node-csr-sgI8CYnTFQZqaZg9wdJP6OabqBiNA0DpZ5Z0wCCl4bQ 54d kubelet-bootstrap Approved,Issued
通过 CSR 请求
kubectl certificate approve node-csr-8I8soRqLhxiH2nThkgUsL2oIaKyh15AuNOVgJddWBqA
查看 通过的node
kubectl get node
NAME STATUS AGE VERSION
172.16.200.206 Ready 11m v1.7.6
172.16.200.209 Ready 49d v1.7.6
172.16.200.216 Ready 4d v1.7.6
自动生成了 kubelet.kubeconfig 文件和公私钥
ls -l /etc/kubernetes/kubelet.kubeconfig
> 注意:假如你更新kubernetes的证书,只要没有更新token.csv,当重启kubelet后,该node就会自动加入到kuberentes集群中,而不会重新发送certificaterequest,也不需要在master节点上执行kubectl certificate approve操作。前提是不要删除node节点上的/etc/kubernetes/ssl/kubelet*和/etc/kubernetes/kubelet.kubeconfig文件。否则kubelet启动时会提示找不到证书而失败。
### 配置 kube-proxy
创建 kube-proxy 的service配置文件
文件路径/usr/lib/systemd/system/kube-proxy.service
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/proxy
ExecStart=/usr/local/kubernetes/server/bin/kube-proxy \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
kube-proxy配置文件/etc/kubernetes/proxy
cat > /etc/kubernetes/proxy << EOF
###
# kubernetes proxy config
# default config should be adequate
# Add your own!
KUBE_PROXY_ARGS="--bind-address=172.16.200.100 --hostname-override=172.16.200.100 --kube-api-burst=50 --kube-api-qps=20 --master=http://172.16.200.100:8080 --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig --cluster-cidr=10.254.0.0/16 --log-dir=/data/logs/kubernetes/ --v=2 --logtostderr=false"
EOF
- --hostname-override 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 iptables 规则;
- 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
systemctl daemon-reload
systemctl enable kube-proxy
systemctl start kube-proxy
systemctl status kube-proxy
';