部署 node 节点
Kubernetes node 节点包含如下组件:
Flanneld:需要在 service 配置文件中增加 TLS 配置,安装过程请参考上一节安装 flannel 网络插件。
Docker1.12.5:Docker 的安装很简单,这里也不说了,但是需要注意 Docker 的配置。
kubelet:直接用二进制文件安装
kube-proxy:直接用二进制文件安装
注意:每台 node 节点上都需要安装 flannel,master 节点上可以不安装。
步骤简介
确认在上一步中我们安装配置的网络插件 flannel 已启动且运行正常
安装配置 Docker 后启动
安装配置 kubelet、kube-proxy 后启动
验证
目录和文件
我们再检查一下三个节点上,经过前几步操作我们已经创建了如下的证书和配置文件。
配置 Docker
如果您使用 yum 的方式安装的 flannel 则不需要执行 mk-docker-opts.sh 文件这一步,参考 Flannel 官方文档中的 Docker Integration。
如果你不是使用 yum 安装的 flannel,那么需要下载 flannel github release 中的 tar 包,解压后会获得一个 mk-docker-opts.sh 文件,到 flannel release 页面下载对应版本的安装包,该脚本见 mk-docker-opts.sh,因为我们使用 yum 安装所以不需要执行这一步。
这个文件是用来 Generate Docker daemon options based on flannel env file
。
使用 systemctl
命令启动 flanneld 后,会自动执行./mk-docker-opts.sh -i
生成如下两个文件环境变量文件:
/run/flannel/subnet.env
/run/docker_opts.env
Docker 将会读取这两个环境变量文件作为容器启动参数。
**注意:**不论您用什么方式安装的 flannel,下面这一步是必不可少的。
yum 方式安装的 flannel
修改docker的配置文件/usr/lib/systemd/system/docker.service
,增加一条环境变量配置:
/run/flannel/docker
文件是 flannel 启动后自动生成的,其中包含了 Docker 启动时需要的参数。
二进制方式安装的 flannel
修改docker的配置文件/usr/lib/systemd/system/docker.service
,增加如下几条环境变量配置:
这两个文件是mk-docker-opts.sh
脚本生成环境变量文件默认的保存位置,docker启动的时候需要加载这几个配置文件才可以加入到flannel创建的虚拟网络里。
所以不论您使用何种方式安装的flannel,将以下配置加入到docker.service
中可确保万无一失。
请参考docker.service中的配置。
启动 Docker
重启了 Docker 后还要重启 kubelet,这时又遇到问题,kubelet 启动失败。报错:
这是 kubelet 与 docker 的 cgroup driver 不一致导致的,kubelet 启动的时候有个 --cgroup-driver
参数可以指定为 cgroupfs
或者 systemd
。
配置docker的service配置文件/usr/lib/systemd/system/docker.service
,设置ExecStart
中的--exec-opt native.cgroupdriver=systemd
。
安装和配置kubelet
kubernets1.8
相对于kubernetes1.6集群必须进行的配置有:
对于kuberentes1.8集群,必须关闭swap,否则kubelet启动将失败。
修改/etc/fstab
将,swap系统注释掉。
kubelet 启动时向 kube-apiserver 发送 TLS bootstrapping 请求,需要先将 bootstrap token 文件中的 kubelet-bootstrap 用户赋予 system:node-bootstrapper cluster 角色(role), 然后 kubelet 才能有权限创建认证请求(certificate signing requests):
--user=kubelet-bootstrap
是在/etc/kubernetes/token.csv
文件中指定的用户名,同时也写入了/etc/kubernetes/bootstrap.kubeconfig
文件;
kubelet 通过认证后向 kube-apiserver 发送 register node 请求,需要先将 kubelet-nodes
用户赋予 system:node
cluster角色(role) 和 system:nodes
组(group), 然后 kubelet 才能有权限创建节点请求:
下载最新的kubelet和kube-proxy二进制文件
注意请下载对应的Kubernetes版本的安装包。
创建kubelet的service配置文件
文件位置/usr/lib/systemd/system/kubelet.service
。
kubelet的配置文件/etc/kubernetes/kubelet
。其中的IP地址更改为你的每台node节点的IP地址。
**注意:**在启动kubelet之前,需要先手动创建/var/lib/kubelet
目录。
下面是kubelet的配置文件/etc/kubernetes/kubelet
:
kubernetes1.8
相对于kubenrete1.6的配置变动:
对于kuberentes1.8集群中的kubelet配置,取消了
KUBELET_API_SERVER
的配置,而改用kubeconfig文件来定义master地址,所以请注释掉KUBELET_API_SERVER
配置。
如果使用 systemd 方式启动,则需要额外增加两个参数
--runtime-cgroups=/systemd/system.slice --kubelet-cgroups=/systemd/system.slice
--experimental-bootstrap-kubeconfig
在 1.9 版本已经变成了--bootstrap-kubeconfig
--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 和 kubelet 中的 cgroup driver 配置一致即可,不一定非使用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 信息;--require-kubeconfig
在 1.10 版本被移除,参看 PR;--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
是基础镜像容器,这里我用的是私有镜像仓库地址,大家部署的时候需要修改为自己的镜像。pod-infrastructure
镜像是 Redhat 制作的,大小接近 80M,下载比较耗时,其实该镜像并不运行什么具体进程,可以使用 Google 的 pause 镜像gcr.io/google_containers/pause-amd64:3.0
,这个镜像只有 300 多 K,或者通过 DockerHub 下载jimmysong/pause-amd64:3.0
。
完整 unit 见 kubelet.service
启动 kubelet
通过 kubelet 的 TLS 证书请求
Kubelet 首次启动时向 kube-apiserver 发送证书签名请求,必须通过后 Kubernetes 系统才会将该 Node 加入到集群。
查看未授权的 CSR 请求
通过 CSR 请求
自动生成了 kubelet kubeconfig 文件和公私钥
假如你更新 Kubernetes 的证书,只要没有更新 token.csv
,当重启 kubelet 后,该 node 就会自动加入到 kuberentes 集群中,而不会重新发送 certificaterequest
,也不需要在 master 节点上执行 kubectl certificate approve
操作。前提是不要删除 node 节点上的 /etc/kubernetes/ssl/kubelet*
和 /etc/kubernetes/kubelet.kubeconfig
文件。否则 kubelet 启动时会提示找不到证书而失败。
**注意:**如果启动 kubelet 的时候见到证书相关的报错,有个 trick 可以解决这个问题,可以将 master 节点上的~/.kube/config
文件(该文件在安装 kubectl 命令行工具这一步中将会自动生成)拷贝到node节点的/etc/kubernetes/kubelet.kubeconfig
位置,这样就不需要通过 CSR,当kubelet启动后就会自动加入的集群中。
配置 kube-proxy
安装 conntrack
创建 kube-proxy 的 service 配置文件
文件路径/usr/lib/systemd/system/kube-proxy.service
。
kube-proxy配置文件/etc/kubernetes/proxy
。
--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
将Usersystem:kube-proxy
与 Rolesystem:node-proxier
绑定,该 Role 授予了调用kube-apiserver
Proxy 相关 API 的权限;
完整 unit 见 kube-proxy.service
启动 kube-proxy
验证测试
我们创建一个nginx的service试一下集群是否可用。
访问以下任何一个地址都可以得到nginx的页面。
172.20.0.113:32724
172.20.0.114:32724
172.20.0.115:32724
参考
最后更新于