风起于青萍之末 2020-05-12
这部文档是面对想要学习Kubernetes集群的读者。如果你对入门指南已经可以满足你对这个列表上所列的需求,我们建议你继续阅读这个,因为他是根据前人积累经验所写的新手指南。当然如果除了学习入门指南知识外还希望学习IaaS,网络,配置管理或对操作系统有特殊要求,这个指南将会提供给学习者一个指导性的概述及思路。
1. 你应该已经熟悉Kubernetes了。我们建议根据 其他入门指南架设一个临时的集群。这样可以帮助你先熟悉Kubernetes命令行(kubectl)和一些概念(pods, services, 等等)。
2. 当你浏览完其他入门指南的时候,你应该已经安装好了 kubectl 。如果没有,你可以根据这个说明安装。
Kubernetes有一个概念叫Cloud Provider,是指一个提供管理TCP负载均衡,节点(实例)和路由器接口的模块。 pkg/cloudprovider/cloud.go 里具体定义了这个接口。 当然,你也可以不用实现这个Cloud Provider去新建一个自定义的聚群(例如,使用裸机集群)。取决于不同部件是如何设置的,并不是所有接口都需要实现的。
Kubernetes有一个独特的网络模型.
Kubernetes给每一个pod分配IP地址。当你新建一个集群,为了保证Pod获得IP地址,你需要给Kubernetes分配一个IP地址池。最简单的做法是每当节点与节点之间的通信可以以一下两种方式实现:
(1)配置网络完成Pod的IP地址路由
(2)建立一个拓扑网络
你需要为Pod所需要的IP地址选一个IP地址范围。
(3)一些可选择配置方式:
(4)给每一的node的Pod地址分配一个CIDR子网或者一个
Kubernetes 会给每个service分配一个IP地址。 但是service的地址并不一定是可路由的。当数据离开节点时,kube-proxy需要将Service IP地址翻译成Pod IP地址。因此,你需要给Service也分配一个地址段。这个网段叫做“SERVICE_CLUSTER_IP_RANGE”。例如,你可以这样设置“SERVICE_CLUSTER_IP_RANGE=”10.0.0.0/16”,这样的话就会允许65534个不同的Service同时运行。请注意,你可以调整这个IP地址段。但不允许在Service和Pod运行的时候移除这个网段。
同样,你需要为主节点选一个静态IP地址。 -命名这个IP地址为“MASTER_IP”。 -配置防火墙,从而允许访问apiserver端口80和443。 -使用sysctl设置”net.ipv4.ip_forward = 1“从而开启IPv4 forwarding。
为你的集群选个名字。要选一个简短不会和其他服务重复的名字。
你需要以下安装包
Kubernets安装版本包包含所有Kuberentes的二进制发行版本和所对应的etcd。你可使直接使用这个二进制发行版本(推荐)或者按照开发者文档说明编译这些Kubernetes的二进制文件。 本指南只讲述了如何直接使用二进制发行版本。 下载最新安装版本并解压缩。之后找到你下载“./kubernetes/server/kubernetes-server-linux-amd64.tar.gz”的路径, 并解压缩这个压缩包。然后在其中找到“./kubernetes/server/bin”文件夹。里面有所所需的可运行的二进制文件。
在容器外运行docker,kuberlet和kube-proxy,就像你运行任何后台系统程序。所以你只需要这些基本的二进制运行文件。etcd, kube-apiserver, kube-controller-manager和kubescheduler,我们建议你在容器里运行etcd, kube-apiserver, kube-controller-manager和kube-scheduler。所以你需要他们的容器镜像。 你可以选择不同的Kubernetes镜像:
你可以使用Google Container Registry (GCR)上的镜像文件:
生成你自己的镜像:
对于etcd,你可以:
我们建议你使用Kubernetes发行版本里提供的etcd版本。Kubernetes发行版本里的二进制运行文件只是和这个版本的etcd测试过。你可以在“kubernetes/cluster/images/etcd/Makefile”里“ETCD_VERSION”所对应的值找到所推荐的版本号。 接下来本文档会假设你已经选好镜像标示并设置了对应的环境变量。 设置好了最新的标示和正确的镜像服务器:
这里有两种主要的安全选项:
使用HTTP访问apiserver
使用HTTPS访问apiserver
如果要用HTTPS这个方式,你需要准备电子证书和用户登录信息。
你需要准备多个证书:
除非你决定要一个真正CA来生成这些证书的话,你需要一个根证书,并用这个证书来给主节点,kuberlet和kubectl的证书签名。
你需要修改以下部分(我们之后也会用到这些参数的)
”CA_CERT“
“MASTER_CERT”
“MASTER_KEY“
“KUBELET_CERT”
”KUBELET_KEY“
管理员(及任何用户)需要:
你的令牌和密码需要保存在apiserver上的一个文件里。本指南使用这个文件”/var/lib/kubeapiserver/known_tokens.csv“。文件的具体格式在认证文档里描述了。 至于如何把登录信息分发给用户,Kubernetes是将登录信息放入kubeconfig文件里。
管理员可以按如下步骤创建kubeconfig文件:
接下来,为kubelets和kube-proxy准备kubeconfig文件。至于要准备多少不同的文件,这里有几个选项:
1. 使用和管理员同样的登陆账号
2. 所有的kubelet使用同一个令牌和kubeconfig文件,另外一套给所有的kube-proxy使用,在一套给管理员使用。
3. 为每一个kubelet,kube-proxy和管理员准备不同的登陆账号。
为了生成这个文件,你可以参照“cluster/gce/configure-vm.sh”中的代码直接从“$HOME/.kube/config”拷贝过去或者参考以下模版:
apiVersion: v1 kind: Config users: - name: kubelet user: token: ${KUBELET_TOKEN} clusters: - name: local cluster: certificate-authority-data: ${CA_CERT_BASE64_ENCODED} contexts: - context: cluster: local user: kubelet name: service-account-context current-context: service-account-context
把kubeconfig文件放置到每一个节点上。本章节之后的事例会假设kubeconfig文件已经放置在“/var/lib/kube-proxy/kubeconfig”和“/var/lib/kubelet/kubeconfig”里。
这个章节讨论的是如歌配置Kubernetes节点。 你应该在每个节点运行三个后台进程:
对最低Docker版本的要求是随着kubelet的版本变化的。最新的稳定版本通常是个好选择。如果版本太低,Kubelet记录下警报并拒绝运行pod,所以你可以选择个版本试一下。
如果你之前安装Docker的节点没有Kubernetes相关的配置,你可能已经有Docker新建的网桥和iptables的规则。所以你或许希望在为Kubernetes配置Docker前根据以下命令移除之前的配置。
iptables -t nat -F ifconfig docker0 down brctl delbr docker0
如何配置Docker取决于你网络是基于routable-vip还是overlay-network。 这里有一些建议的Docker选项:
所以kube-proxy可以代替docker来设置iptables。
你或许希望为Docker提高可以打开文件的数目:
在进行下一步安装前,可以参考Docker文档里的实例来确保docker在你的系统上正常工作。
rkt是类似Docker的技术。你只需要二选一安装Docker或者rkt。最低的版本是v0.5.6。
systemd是在节点上运行rkt必须的。与rkt v0.5.6所对应的最低版本是systemd 215。
rkt metadata service也是必须安装的,来支持rtk的网络部分。你可以用以下命令来运行rkt的metadata服务 sudo systemd-run rkt metadata-service
接下来你需要来设置kubelet的标记:
--container-runtime=rkt
所有的节点都要运行kubelet。
可参考的参数:
所有的节点都要运行kube-proxy。(并不一定要在主节点上运行kube-proxy,但最好还是与其它节点保持一致) 可参考如何获得kubelet二进制运行包来获得kube-proxy二进制运行包。
可参考的参数
为了pod的网络通信,需要给每一个节点分配一个自己的CIDR网段。这个叫做 NODE_X_POD_CIDR 。
需要给每一个节点新建一个叫 cbr0 网桥。网桥会在networking documentation里做详细介绍。约定俗成,$NODE_X_POD_CIDR 里的第一个IP地址作为这个网桥的IP地址。这个地址叫做 NODE_X_BRIDGE_ADDR 。比如, NODE_X_POD_CIDR 是 10.0.0.0/16 ,那么 NODE_X_BRIDGE_ADDR 是 10.0.0.1/16 。注意:这里用 /16 这个后缀是因为之后也会这么使用。
在你关闭了Docker的IP伪装的情况下,为了让pod之间相互通信,你可能需要为去往集群网络外的流量做目的IP地址伪装,例如:
iptables -t nat -A POSTROUTING ! -d ${CLUSTER_SUBNET} -m addrtype ! --dst-type LOCAL -jMASQUERADE
这样会重写从PodIP到节点IP的数据流量的原地址。内核connection tracking会确保发向节点的回复能够到达pod。
注意: 需不需要IP地址伪装是视环境而定的。在一些环境下是不需要IP伪装的。例如GCE这样的环境从pod发出的数据是不允许发向Interent的,但如果在同一个GCE项目里是不会有问题的。
之前架设服务器的步骤都是使用“传统”的系统管理方式。你可以尝试使用系统配置工具来自动化架设流程。你可以参考其他入门指南,比如使用Saltstack, Ansible, Juju和CoreOSCloud Config。
通常情况下,基本的节点服务(kubelet, kube-proxy和docker)都是由传统的系统配置方式完成建立和管理的。其他的Kubernetes的相关部分都是由Kubernetes本身来完成配置和管理的:
你需要运行一个或多个etcd实例。
启动一个etcd实例:
1.复制 cluster/saltbase/salt/etcd/etcd.manifest 2.做有必要的设置修改 3.将这个文件放到kubelet mainfest的文件夹中
在主节点上,apiserver,controller manager,scheduler会运行在各自的pod里。
启动以上三个服务的步骤大同小异:
1. 从为pod所提供的template开始。
2. 设置 HYPERKUBE_IMAGE 的值为选择安装镜像中所设置的值。
3. 可参考以下的template来决定你集群所需的选项。
4. 在 commands 列表里设置所需的运行选项(例如,$ARGN)。
5. 将完成的template放在kubelet manifest的文件夹内。
6. 验证pod是否运行。
{ "kind": "Pod", "apiVersion": "v1", "metadata": { "name": "kube-apiserver" }, "spec": { "hostNetwork": true, "containers": [ { "name": "kube-apiserver", "image": "${HYPERKUBE_IMAGE}", "command": [ "/hyperkube", "apiserver", "$ARG1", "$ARG2", ... "$ARGN" ], "ports": [ { "name": "https", "hostPort": 443, "containerPort": 443 }, { "name": "local", "hostPort": 8080, "containerPort": 8080 } ], "volumeMounts": [ { "name": "srvkube", "mountPath": "/srv/kubernetes", "readOnly": true }, { "name": "etcssl", "mountPath": "/etc/ssl", "readOnly": true } ], "livenessProbe": { "httpGet": { "path": "/healthz", "port": 8080 }, "initialDelaySeconds": 15, "timeoutSeconds": 15 } } ], "volumes": [ { "name": "srvkube", "hostPath": { } }, { "name": "etcssl", "hostPath":