使用kubeadm创建单个控制平面集群
<p>使用kubeadm创建单个控制平面集群</p>
<p><a href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/">https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/</a></p>
<p>该kubeadm工具可帮助您引导符合最佳实践的最小可行Kubernetes集群。实际上,您可以kubeadm用来设置将通过Kubernetes一致性测试的集群。
kubeadm还支持其他群集生命周期功能,例如引导令牌和群集升级。</p>
<p>kubeadm如果需要,该工具很好:</p>
<pre><code>您可能第一次尝试Kubernetes的简单方法。
现有用户可以自动设置集群并测试其应用程序的一种方法。
其他具有更大范围的生态系统和/或安装程序工具中的构建块。</code></pre>
<p>您可以kubeadm在各种机器上安装和使用:您的笔记本电脑,一组云服务器,Raspberry Pi等。无论是部署到云还是本地,都可以集成kubeadm到诸如Ansible或Terraform之类的置备系统中。
在你开始之前</p>
<p>要遵循本指南,您需要:</p>
<pre><code>一台或多台运行兼容deb / rpm的Linux操作系统的计算机;例如:Ubuntu或CentOS。
每台机器2 GB或更多的RAM-更少的空间为您的应用程序留出了很少的空间。
用作控制平面节点的计算机上至少有2个CPU。
群集中所有计算机之间的完全网络连接。您可以使用公共网络或专用网络。</code></pre>
<p>您还需要使用一个版本,kubeadm该版本可以部署要在新集群中使用的Kubernetes版本。</p>
<p>Kubernetes的版本和版本倾斜支持策略既适用kubeadm于Kubernetes,也适用于整个Kubernetes。检查该策略以了解kubeadm 支持哪些版本的Kubernetes 。该页面是为Kubernetes v1.18编写的。</p>
<p>该kubeadm工具的总体功能状态为“一般可用性(GA)”。一些子功能仍在积极开发中。随着工具的发展,创建集群的实现可能会略有变化,但是总体实现应该非常稳定。</p>
<pre><code>注意:根据kubeadm alpha定义,下面的任何命令都在alpha级别受支持。</code></pre>
<p>目标</p>
<pre><code>安装单个控制平面Kubernetes集群或高可用性集群
在群集上安装Pod网络,以便您的Pod可以相互交谈</code></pre>
<p>使用说明
在主机上安装kubeadm</p>
<p>请参阅“安装kubeadm”。</p>
<pre><code>注意:如果您已经安装了kubeadm,请运行apt-get update && apt-get upgrade或yum update获取最新版本的kubeadm。升级时,由于kubelet在崩溃循环中等待kubeadm告知其操作,因此每隔几秒钟重新启动一次。此崩溃循环是正常现象。初始化控制平面后,kubelet将正常运行。</code></pre>
<p>初始化控制平面节点</p>
<p>控制平面节点是运行控制平面组件的机器,包括 等 (集群数据库)和 API服务器 (其中 Kubectl 命令行工具进行通信)。</p>
<pre><code>(推荐)如果计划将单个控制平面kubeadm群集升级到高可用性,则应指定--control-plane-endpoint为所有控制平面节点设置共享端点。这样的端点可以是负载均衡器的DNS名称或IP地址。
选择一个Pod网络插件,并验证是否需要将任何参数传递给kubeadm init。根据您选择的第三方提供商,您可能需要将设置--pod-network-cidr为提供商特定的值。请参阅安装Pod网络附加组件。
(可选)从1.14版开始,kubeadm尝试使用一系列众所周知的域套接字路径来检测Linux上的容器运行时。要使用不同的容器运行时,或者在预配置的节点上安装了多个容器,请将--cri-socket 参数指定为kubeadm init。请参阅安装运行时。
(可选)除非另有说明,否则kubeadm使用与默认网关关联的网络接口来为此特定控制平面节点的API服务器设置发布地址。要使用其他网络接口,请将--apiserver-advertise-address=<ip-address>参数指定为kubeadm init。要使用IPv6寻址部署IPv6 Kubernetes集群,您必须指定一个IPv6地址,例如--apiserver-advertise-address=fd00::101
(可选)kubeadm config images pull在kubeadm init验证与gcr.io容器映像注册表的连接之前,先运行。</code></pre>
<p>要初始化控制平面节点,请运行:</p>
<p>kubeadm init <args></p>
<p>关于apiserver-advertise-address和ControlPlaneEndpoint的注意事项</p>
<p>虽然--apiserver-advertise-address可用于设置此特定控制平面节点的API服务器的发布地址,--control-plane-endpoint但可用于设置所有控制平面节点的共享端点。</p>
<p>--control-plane-endpoint允许IP地址和可以映射到IP地址的DNS名称。请与您的网络管理员联系,以评估有关此类映射的可能解决方案。</p>
<p>这是一个示例映射:</p>
<p>192.168.0.102 cluster-endpoint</p>
<p>192.168.0.102该节点的IP地址在哪里,是cluster-endpoint映射到该IP的自定义DNS名称。这将允许你传递--control-plane-endpoint=cluster-endpoint到kubeadm init和传递相同的DNS名称 kubeadm join。稍后,您可以修改cluster-endpoint以指向高可用性方案中的负载均衡器的地址。</p>
<p>--control-plane-endpointkubeadm不支持将没有创建的单个控制平面集群转换为高可用性集群。
更多信息</p>
<p>有关kubeadm init参数的更多信息,请参见kubeadm参考指南。</p>
<p>有关配置选项的完整列表,请参阅配置文件文档。</p>
<p>要自定义控制平面组件,包括对控制平面组件和etcd服务器的活动性探针进行可选的IPv6分配,请按照自定义参数中的说明为每个组件提供额外的参数。</p>
<p>要kubeadm init再次运行,必须首先拆除集群。</p>
<p>如果将具有不同体系结构的节点加入群集,请确保已部署的DaemonSet对这种体系结构具有容器映像支持。</p>
<p>kubeadm init首先运行一系列预检查,以确保机器已准备好运行Kubernetes。这些预检查会显示警告并在错误时退出。kubeadm init 然后下载并安装群集控制平面组件。这可能会需要几分钟。输出应如下所示:</p>
<p>[init] Using Kubernetes version: vX.Y.Z
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Activating the kubelet service
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [kubeadm-cp localhost] and IPs [10.138.0.4 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [kubeadm-cp localhost] and IPs [10.138.0.4 127.0.0.1 ::1]
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubeadm-cp kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.138.0.4]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 31.501735 seconds
[uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-X.Y" in namespace kube-system with the configuration for the kubelets in the cluster
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "kubeadm-cp" as an annotation
[mark-control-plane] Marking the node kubeadm-cp as control-plane by adding the label "node-role.kubernetes.io/master=''"
[mark-control-plane] Marking the node kubeadm-cp as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[bootstrap-token] Using token: <token>
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy</p>
<p>Your Kubernetes control-plane has initialized successfully!</p>
<p>To start using your cluster, you need to run the following as a regular user:</p>
<p>mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config</p>
<p>You should now deploy a Pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
/docs/concepts/cluster-administration/addons/</p>
<p>You can now join any number of machines by running the following on each node
as root:</p>
<p>kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash></p>
<p>要使kubectl适用于非root用户,请运行以下命令,这些命令也是kubeadm init输出的一部分:</p>
<p>mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config</p>
<p>或者,如果您是root用户,则可以运行:</p>
<p>export KUBECONFIG=/etc/kubernetes/admin.conf</p>
<p>记录输出的kubeadm join命令kubeadm init。您需要此命令将节点加入集群。</p>
<p>令牌用于控制平面节点和加入节点之间的相互身份验证。这里包含的令牌是秘密的。确保安全,因为拥有此令牌的任何人都可以将经过身份验证的节点添加到您的集群中。可以使用kubeadm token命令列出,创建和删除这些标记。请参阅 kubeadm参考指南。
安装Pod网络附加组件</p>
<pre><code>警告:
本节包含有关网络设置和部署顺序的重要信息。在继续之前,请仔细阅读所有建议。
您必须部署一个 容器网络接口 (CNI)基于Pod的网络插件,以便您的Pod可以相互通信。
在安装网络之前,群集DNS(CoreDNS)将不会启动。
请注意,您的Pod网络不得与任何主机网络重叠:如果有任何重叠,您可能会遇到问题。
(如果在网络插件的首选Pod网络和某些主机网络之间发现冲突,则应考虑使用一个合适的CIDR块,然后在网络插件的YAML中使用kubeadm initwith --pod-network-cidr并替换它)。
默认情况下,kubeadm将群集设置为使用和强制使用 RBAC(基于角色的访问控制)。
确保您的Pod网络插件支持RBAC,以及用于部署它的所有清单也是如此。
如果要为群集使用IPv6(双协议栈或仅单协议栈IPv6网络),请确保Pod网络插件支持IPv6。
IPv6支持已在v0.6.0中添加到CNI中。
注意:目前Calico是kubeadm项目针对其执行e2e测试的唯一CNI插件。如果您发现与CNI插件相关的问题,则应在其各自的问题跟踪器中而不是kubeadm或kubernetes问题跟踪器中记录票证。</code></pre>
<p>多个外部项目使用CNI提供了Kubernetes Pod网络,其中一些还支持Network Policy。</p>
<p>请参阅可用 网络和网络策略附加组件列表。</p>
<p>您可以使用以下命令在控制平面节点或具有kubeconfig凭据的节点上安装Pod网络附加组件:</p>
<p>kubectl apply -f <add-on.yaml></p>
<p>每个群集只能安装一个Pod网络。您可以在下面找到一些流行的Pod网络插件的安装说明:</p>
<pre><code>印花布
Cilium
康宝特
酷比路由器
编织网</code></pre>
<p>Calico是网络和网络策略提供商。Calico支持一组灵活的网络选项,因此您可以根据情况选择最有效的选项,包括使用或不使用BGP的非覆盖和覆盖网络。Calico使用同一引擎对服务网格层上的主机,pod和(如果使用Istio&Envoy)应用程序执行网络策略。印花布适用于多种架构,包括amd64,arm64,和ppc64le。</p>
<p>Calico将根据通过--pod-network-cidr标志或通过kubeadm的配置提供的值,自动检测要用于Pod IP的IP地址范围。</p>
<p>kubectl apply -f <a href="https://docs.projectcalico.org/v3.14/manifests/calico.yaml">https://docs.projectcalico.org/v3.14/manifests/calico.yaml</a></p>
<p>安装Pod网络后,您可以通过检查CoreDNS Pod是否Running在中来确认其正常工作kubectl get pods --all-namespaces。而且,一旦CoreDNS Pod启动并运行,您就可以通过加入节点来继续。</p>
<p>如果你的网络不能正常工作或CoreDNS不在Running状态,检查出 故障排除指南 进行kubeadm。
控制平面节点隔离</p>
<p>默认情况下,出于安全原因,您的群集不会在控制平面节点上调度Pod。如果您希望能够在控制平面节点上调度Pod,例如针对单机Kubernetes集群进行开发,请运行:</p>
<p>kubectl taint nodes --all node-role.kubernetes.io/master-</p>
<p>输出看起来像这样:</p>
<p>node "test-01" untainted
taint "node-role.kubernetes.io/master:" not found
taint "node-role.kubernetes.io/master:" not found</p>
<p>这node-role.kubernetes.io/master将从所有具有污染的节点(包括控制平面节点)中删除污染,这意味着调度程序将能够在任何地方调度Pods。
加入你的节点</p>
<p>节点是您的工作负载(容器和Pod等)运行的地方。要将新节点添加到群集,请对每台计算机执行以下操作:</p>
<pre><code>SSH到机器
成为root(例如sudo su -)
运行由输出的命令kubeadm init。例如:</code></pre>
<p>kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash></p>
<p>如果没有令牌,可以通过在控制平面节点上运行以下命令来获取它:</p>
<p>kubeadm token list</p>
<p>输出类似于以下内容:</p>
<p>TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
8ewj1p.9r9hcjoqgajrj4gi 23h 2018-06-12T02:51:28Z authentication, The default bootstrap system:
signing token generated by bootstrappers:
'kubeadm init'. kubeadm:
default-node-token</p>
<p>默认情况下,令牌会在24小时后过期。如果要在当前令牌过期后将节点加入集群,则可以通过在控制平面节点上运行以下命令来创建新令牌:</p>
<p>kubeadm token create</p>
<p>输出类似于以下内容:</p>
<p>5didvk.d09sbcov8ph2amjw</p>
<p>如果没有的值--discovery-token-ca-cert-hash,则可以通过在控制平面节点上运行以下命令链来获取它:</p>
<p>openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'</p>
<p>输出类似于:</p>
<p>8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78</p>
<pre><code>注意:要为指定一个IPv6元组<control-plane-host>:<control-plane-port>,IPv6地址必须放在方括号中,例如:[fd00::101]:2073。</code></pre>
<p>输出应类似于:</p>
<p>[preflight] Running pre-flight checks</p>
<p>... (log output of join workflow) ...</p>
<p>Node join complete:</p>
<ul>
<li>Certificate signing request sent to control-plane and response
received.</li>
<li>Kubelet informed of new secure connection details.</li>
</ul>
<p>Run 'kubectl get nodes' on control-plane to see this machine join.</p>
<p>几秒钟后,您应该kubectl get nodes在控制面板节点上运行时在输出中注意到该节点。
(可选)从控制平面节点以外的计算机控制群集</p>
<p>为了使kubectl在其他计算机(例如笔记本电脑)上与您的群集通信,您需要将管理员kubeconfig文件从控制平面节点复制到工作站,如下所示:</p>
<p>scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf get nodes</p>
<pre><code>注意:上面的示例假定为root用户启用了SSH访问。如果不是这种情况,您可以复制该admin.conf文件以供其他用户访问,而scp改用该其他用户。该admin.conf文件为用户提供了对集群的超级用户特权。该文件应谨慎使用。对于普通用户,建议生成一个您为其授予特权的唯一证书。您可以使用kubeadm alpha kubeconfig user --client-name <CN>命令执行此操作。该命令会将KubeConfig文件打印到STDOUT,您应该将其保存到文件并分发给用户。之后,使用授予特权kubectl create (cluster)rolebinding。</code></pre>
<p>(可选)将API服务器代理到本地主机</p>
<p>如果要从群集外部连接到API服务器,则可以使用 kubectl proxy:</p>
<p>scp root@<control-plane-host>:/etc/kubernetes/admin.conf .
kubectl --kubeconfig ./admin.conf proxy</p>
<p>您现在可以在以下位置本地访问API服务器 <a href="http://localhost:8001/api/v1">http://localhost:8001/api/v1</a>
清理</p>
<p>如果您在群集中使用了一次性服务器进行测试,则可以关闭这些服务器,而无需进一步清理。您可以使用 kubectl config delete-cluster删除对集群的本地引用。</p>
<p>但是,如果要更干净地取消配置群集,则应首先排空该节点 并确保该节点为空,然后取消配置该节点。
删除节点</p>
<p>使用适当的凭证与控制平面节点通信,请运行:</p>
<p>kubectl drain <node name> --delete-local-data --force --ignore-daemonsets</p>
<p>删除节点之前,请重置以下状态kubeadm:</p>
<p>kubeadm reset</p>
<p>重置过程不会重置或清除iptables规则或IPVS表。如果您希望重置iptables,则必须手动进行:</p>
<p>iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X</p>
<p>如果要重置IPVS表,则必须运行以下命令:</p>
<p>ipvsadm -C</p>
<p>现在删除节点:</p>
<p>kubectl delete node <node name></p>
<p>如果您想重新开始,只需运行kubeadm init或kubeadm join使用适当的参数即可。
清理控制平面</p>
<p>您可以kubeadm reset在控制平面主机上使用以触发尽力而为的清理。</p>
<p>kubeadm reset 有关此子命令及其选项的更多信息,请参见参考文档。</p>