以Kubeadm方式安装的Kubernetes集群的探索

简介: 以Kubeadm方式安装的Kubernetes集群的探索 博客分类: Kubernetes 当前手上有两个Kubernetes cluster,一个是采用kube-up.sh安装的k8s 1.3.7版本,另外一个则是采用kubeadm安装的k8s 1.5.1版本。

以Kubeadm方式安装的Kubernetes集群的探索 博客分类: Kubernetes

当前手上有两个Kubernetes cluster,一个是采用kube-up.sh安装的k8s 1.3.7版本,另外一个则是采用kubeadm安装的k8s 1.5.1版本。由于1.3.7版本安装在前,并且目前它也是承载了我们PaaS平台的环境,因此对于这个版本的Kubernetes安装环境、配置操作、日志查看、集群操作等相对较为熟悉。而Kubeadm安装的1.5.1版本K8s集群在组件部署、配置、日志等诸多方面与1.3.7版本有了较大差异。刚 上手的时候,你会发现你原来所熟知的1.3.7的东西都不在原先的位置上了。估计很多和我一样,采用kubeadm将集群升级到1.5.1版本的朋友们都会遇到这类问题,于是这里打算对Kubeadm方式安装的Kubernetes集群进行一些小小的探索,把一些变动较大的点列出来,供大家参考。

一、环境

这里使用的依然是文章《使用Kubeadm安装Kubernetes》中安装完毕的Kubernetes 1.5.1集群环境,底层是阿里云ECS,操作系统是Ubuntu 16.04.1。网络用的是weave network

试验集群只有两个Node:一个master node和一个minion node。但Master node由于被taint了,因此它与minion node一样参与集群调度和承担负载。

二、核心组件的Pod化

Kubeadm安装的k8s集群与kube-up.sh安装集群相比,最大的不同应该算是kubernetes核心组件的Pod化,即:kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、kube-discovery以及etcd等核心组件都运行在集群中的Pod里的,这颇有些CoreOS的风格。只有一个组件是例外的,那就是负责在node上与本地容器引擎交互的Kubelet。

K8s的核心组件Pod均放在kube-system namespace中,通过kubectl(on master node)可以查看到:

# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
etcd-iz25beglnhtz 1/1 Running 2 26d
kube-apiserver-iz25beglnhtz 1/1 Running 3 26d
kube-controller-manager-iz25beglnhtz 1/1 Running 2 26d
kube-scheduler-iz25beglnhtz 1/1 Running 4 26d
... ...

另外细心的朋友可能会发现,这些核心组建的Pod名字均以所在Node的主机名为结尾,比如:kube-apiserver-iz25beglnhtz中的”iz25beglnhtz”就是其所在Node的主机名。

不过,即便这些核心组件是一个容器的形式运行在集群中,组件所使用网络依然是所在Node的主机网络,而不是Pod Network

# docker ps|grep apiserver 98ea64bbf6c8 gcr.io/google_containers/kube-apiserver-amd64:v1.5.1 "kube-apiserver --ins" 10 days ago Up 10 days k8s_kube-apiserver.6c2e367b_kube-apiserver-iz25beglnhtz_kube-system_033de1afc0844729cff5e100eb700a81_557d1fb2
4f87d22b8334 gcr.io/google_containers/pause-amd64:3.0 "/pause" 10 days ago Up 10 days k8s_POD.d8dbe16c_kube-apiserver-iz25beglnhtz_kube-system_033de1afc0844729cff5e100eb700a81_5931e490

# docker inspect 98ea64bbf6c8 ... ...
"HostConfig": {
"NetworkMode": "container:4f87d22b833425082be55851d72268023d41b50649e46c738430d9dfd3abea11",
}
... ...

# docker inspect 4f87d22b833425082be55851d72268023d41b50649e46c738430d9dfd3abea11 ... ...
"HostConfig": {
"NetworkMode": "host",
}
... ...

从上面docker inspect的输出可以看出kube-apiserver pod里面的pause容器采用的网络模式是host网络,而以pause容器网络为基础的kube-apiserver 容器显然就继承了这一network namespace。因此从外面看,访问Kube-apiserver这样的组件和以前没什么两样:在Master node上可以通过localhost:8080访问;在Node外,可以通过master_node_ip:6443端口访问。

三、核心组件启动配置调整

在kube-apiserver等核心组件还是以本地程序运行在物理机上的时代,修改kube-apiserver的启动参数,比如修改一下–service-node-port-range的范围、添加一个–basic-auth-file等,我们都可以通过直接修改/etc/default/kube-apiserver(以Ubuntu 14.04为例)文件的内容并重启kube-apiserver service(service restart kube-apiserver)的方式实现。其他核心组件:诸如:kube-controller-manager、kube-proxy和kube-scheduler均是如此。

但在kubeadm时代,这些配置文件不再存在,取而代之的是和用户Pod描述文件类似的manifest文件(都放置在/etc/kubernetes/manifests下面):

/etc/kubernetes/manifests# ls
etcd.json kube-apiserver.json kube-controller-manager.json kube-scheduler.json

我们以为kube-apiserver增加一个启动参数:”–service-node-port-range=80-32767″ 为例:

打开并编辑/etc/kubernetes/manifests/kube-apiserver.json,在“command字段对应的值中添加”–service-node-port-range=80-32767″:

"containers": [
 {
 "name": "kube-apiserver",
 "image": "gcr.io/google_containers/kube-apiserver-amd64:v1.5.1",
 "command": [
 "kube-apiserver",
 "--insecure-bind-address=127.0.0.1",
 "--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota",
 "--service-cluster-ip-range=10.96.0.0/12",
 "--service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem",
 "--client-ca-file=/etc/kubernetes/pki/ca.pem",
 "--tls-cert-file=/etc/kubernetes/pki/apiserver.pem",
 "--tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem",
 "--token-auth-file=/etc/kubernetes/pki/tokens.csv",
 "--secure-port=6443",
 "--allow-privileged",
 "--advertise-address=10.47.217.91",
 "--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname",
 "--anonymous-auth=false",
 "--etcd-servers=http://127.0.0.1:2379",
 "--service-node-port-range=80-32767"
 ],

注意:不要忘记在–etcd-servers这一行后面添加一个逗号,否则kube-apiserver会退出。

修改后,你会发现kube-apiserver会被自动重启。这是kubelet的功劳。kubelet在启动时监听/etc/kubernetes/manifests目录下的文件变化并做适当处理:

# ps -ef|grep kubelet
root 1633 1 5 2016 ? 1-09:24:47 /usr/bin/kubelet --kubeconfig=/etc/kubernetes/kubelet.conf --require-kubeconfig=true --pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --cluster-dns=10.96.0.10 --cluster-domain=cluster.local

kubelet自身是一个systemd的service,它的启动配置可以通过下面文件修改:

# cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf [Service] Environment="KUBELET_KUBECONFIG_ARGS=--kubeconfig=/etc/kubernetes/kubelet.conf --require-kubeconfig=true" Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true" Environment="KUBELET_NETWORK_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin" Environment="KUBELET_DNS_ARGS=--cluster-dns=10.96.0.10 --cluster-domain=cluster.local" ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_EXTRA_ARGS 

四、kubectl的配置

kube-up.sh安装的k8s集群会在每个Node上的~/.kube/下创建config文件,用于kubectl访问apiserver和操作集群使用。但在kubeadm模式下,~/.kube/下面的内容变成了:

~/.kube# ls
cache/ schema/

于是有了问题1:config哪里去了?

之所以在master node上我们的kubectl依旧可以工作,那是因为默认kubectl会访问localhost:8080来与kube-apiserver交互。如果kube-apiserver没有关闭–insecure-port,那么kubectl便可以正常与kube-apiserver交互,因为–insecure-port是没有任何校验机制的。

于是又了问题2:如果是其他node上的kubectl与kube-apiserver通信或者master node上的kubectl通过secure port与kube-apiserver通信,应该如何配置?

接下来,我们一并来回答上面两个问题。kubeadm在创建集群时,在master node的/etc/kubernetes下面创建了两个文件:

/etc/kubernetes# ls -l
total 32
-rw------- 1 root root 9188 Dec 28 17:32 admin.conf
-rw------- 1 root root 9188 Dec 28 17:32 kubelet.conf
... ...

这两个文件的内容是完全一样的,仅从文件名可以看出是谁在使用。比如kubelet.conf这个文件,我们就在kubelet程序的启动参数中看到过:–kubeconfig=/etc/kubernetes/kubelet.conf

# ps -ef|grep kubelet
root 1633 1 5 2016 ? 1-09:26:41 /usr/bin/kubelet --kubeconfig=/etc/kubernetes/kubelet.conf --require-kubeconfig=true --pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --cluster-dns=10.96.0.10 --cluster-domain=cluster.local

打开这个文件,你会发现这就是一个kubeconfig文件,文件内容较长,我们通过kubectl config view来查看一下这个文件的结构:

# kubectl --kubeconfig /etc/kubernetes/kubelet.conf config view apiVersion: v1 clusters:
- cluster:
 certificate-authority-data: REDACTED
 server: https://{master node local ip}:6443
 name: kubernetes
contexts:
- context:
 cluster: kubernetes
 user: admin
 name: admin@kubernetes
- context:
 cluster: kubernetes
 user: kubelet
 name: kubelet@kubernetes
current-context: admin@kubernetes kind: Config preferences: {} users:
- name: admin
 user:
 client-certificate-data: REDACTED
 client-key-data: REDACTED
- name: kubelet
 user:
 client-certificate-data: REDACTED
 client-key-data: REDACTED

这和我们在《Kubernetes集群Dashboard插件安装》一文中介绍的kubeconfig文件内容并不二致。不同之处就是“REDACTED”这个字样的值,我们对应到kubelet.conf中,发现每个REDACTED字样对应的都是一段数据,这段数据是由对应的数字证书内容或密钥内容转换(base64)而来的,在访问apiserver时会用到。

我们在minion node上测试一下:

minion node:

# kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?

# kubectl --kubeconfig /etc/kubernetes/kubelet.conf get pods
NAME READY STATUS RESTARTS AGE
my-nginx-1948696469-359d6 1/1 Running 2 26d
my-nginx-1948696469-3g0n7 1/1 Running 3 26d
my-nginx-1948696469-xkzsh 1/1 Running 2 26d
my-ubuntu-2560993602-5q7q5 1/1 Running 2 26d
my-ubuntu-2560993602-lrrh0 1/1 Running 2 26d

kubeadm创建k8s集群时,会在master node上创建一些用于组件间访问的证书、密钥和token文件,上面的kubeconfig中的“REDACTED”所代表的内容就是从这些文件转化而来的:

/etc/kubernetes/pki# ls
apiserver-key.pem apiserver.pem apiserver-pub.pem ca-key.pem ca.pem ca-pub.pem sa-key.pem sa-pub.pem tokens.csv
  • apiserver-key.pem:kube-apiserver的私钥文件
  • apiserver.pem:kube-apiserver的公钥证书
  • apiserver-pub.pem kube-apiserver的公钥文件
  • ca-key.pem:CA的私钥文件
  • ca.pem:CA的公钥证书
  • ca-pub.pem :CA的公钥文件
  • sa-key.pem :serviceaccount私钥文件
  • sa-pub.pem :serviceaccount的公钥文件
  • tokens.csv:kube-apiserver用于校验的token文件

在k8s各核心组件的启动参数中会看到上面文件的身影,比如:

 kube-apiserver --insecure-bind-address=127.0.0.1 --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota --service-cluster-ip-range=10.96.0.0/12 --service-account-key-file=/etc/kubernetes/pki/apiserver-key.pem --client-ca-file=/etc/kubernetes/pki/ca.pem --tls-cert-file=/etc/kubernetes/pki/apiserver.pem --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem --token-auth-file=/etc/kubernetes/pki/tokens.csv --secure-port=6443 --allow-privileged --advertise-address={master node local ip} --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname --anonymous-auth=false --etcd-servers=http://127.0.0.1:2379 --service-node-port-range=80-32767 

我们还可以在minion node上通过curl还手工测试一下通过安全通道访问master node上的kube-apiserver。在《Kubernetes集群的安全配置》一文中,我们提到过k8s的authentication(包括:客户端证书认证、basic auth、static token等)只要通过其中一个即可。当前kube-apiserver开启了客户端证书认证(–client-ca-file)和static token验证(–token-auth-file),我们只要通过其中一个,就可以通过authentication,于是我们使用static token方式。static token file的内容格式:

token,user,uid,"group1,group2,group3" 

对应到master node上的tokens.csv

# cat /etc/kubernetes/pki/tokens.csv
{token},{user},812ffe41-cce0-11e6-9bd3-00163e1001d7,system:kubelet-bootstrap

我们用这个token通过curl与apiserver交互:

# curl --cacert /etc/kubernetes/pki/ca.pem -H "Authorization: Bearer {token}" https://{master node local ip}:6443 { "paths": [ "/api", "/api/v1", "/apis", "/apis/apps", "/apis/apps/v1beta1", "/apis/authentication.k8s.io", "/apis/authentication.k8s.io/v1beta1", "/apis/authorization.k8s.io", "/apis/authorization.k8s.io/v1beta1", "/apis/autoscaling", "/apis/autoscaling/v1", "/apis/batch", "/apis/batch/v1", "/apis/batch/v2alpha1", "/apis/certificates.k8s.io", "/apis/certificates.k8s.io/v1alpha1", "/apis/extensions", "/apis/extensions/v1beta1", "/apis/policy", "/apis/policy/v1beta1", "/apis/rbac.authorization.k8s.io", "/apis/rbac.authorization.k8s.io/v1alpha1", "/apis/storage.k8s.io", "/apis/storage.k8s.io/v1beta1", "/healthz", "/healthz/poststarthook/bootstrap-controller", "/healthz/poststarthook/extensions/third-party-resources", "/healthz/poststarthook/rbac/bootstrap-roles", "/logs", "/metrics", "/swaggerapi/", "/ui/", "/version" ] }
本文转自开源中国- 以Kubeadm方式安装的Kubernetes集群的探索
相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
5月前
|
人工智能 算法 调度
阿里云ACK托管集群Pro版共享GPU调度操作指南
本文介绍在阿里云ACK托管集群Pro版中,如何通过共享GPU调度实现显存与算力的精细化分配,涵盖前提条件、使用限制、节点池配置及任务部署全流程,提升GPU资源利用率,适用于AI训练与推理场景。
473 3
|
5月前
|
弹性计算 监控 调度
ACK One 注册集群云端节点池升级:IDC 集群一键接入云端 GPU 算力,接入效率提升 80%
ACK One注册集群节点池实现“一键接入”,免去手动编写脚本与GPU驱动安装,支持自动扩缩容与多场景调度,大幅提升K8s集群管理效率。
327 89
|
10月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
ACK One 的多集群应用分发,可以最小成本地结合您已有的单集群 CD 系统,无需对原先应用资源 YAML 进行修改,即可快速构建成多集群的 CD 系统,并同时获得强大的多集群资源调度和分发的能力。
551 9
|
10月前
|
资源调度 Kubernetes 调度
从单集群到多集群的快速无损转型:ACK One 多集群应用分发
本文介绍如何利用阿里云的分布式云容器平台ACK One的多集群应用分发功能,结合云效CD能力,快速将单集群CD系统升级为多集群CD系统。通过增加分发策略(PropagationPolicy)和差异化策略(OverridePolicy),并修改单集群kubeconfig为舰队kubeconfig,可实现无损改造。该方案具备多地域多集群智能资源调度、重调度及故障迁移等能力,帮助用户提升业务效率与可靠性。
|
12月前
|
存储 Kubernetes 监控
K8s集群实战:使用kubeadm和kuboard部署Kubernetes集群
总之,使用kubeadm和kuboard部署K8s集群就像回归童年一样,简单又有趣。不要忘记,技术是为人服务的,用K8s集群操控云端资源,我们不过是想在复杂的世界找寻简单。尽管部署过程可能遇到困难,但朝着简化复杂的目标,我们就能找到意义和乐趣。希望你也能利用这些工具,找到你的乐趣,满足你的需求。
1044 33
|
12月前
|
Kubernetes 开发者 Docker
集群部署:使用Rancher部署Kubernetes集群。
以上就是使用 Rancher 部署 Kubernetes 集群的流程。使用 Rancher 和 Kubernetes,开发者可以受益于灵活性和可扩展性,允许他们在多种环境中运行多种应用,同时利用自动化工具使工作负载更加高效。
644 19
|
12月前
|
人工智能 分布式计算 调度
打破资源边界、告别资源浪费:ACK One 多集群Spark和AI作业调度
ACK One多集群Spark作业调度,可以帮助您在不影响集群中正在运行的在线业务的前提下,打破资源边界,根据各集群实际剩余资源来进行调度,最大化您多集群中闲置资源的利用率。
|
Prometheus Kubernetes 监控
OpenAI故障复盘 - 阿里云容器服务与可观测产品如何保障大规模K8s集群稳定性
聚焦近日OpenAI的大规模K8s集群故障,介绍阿里云容器服务与可观测团队在大规模K8s场景下我们的建设与沉淀。以及分享对类似故障问题的应对方案:包括在K8s和Prometheus的高可用架构设计方面、事前事后的稳定性保障体系方面。
|
Prometheus Kubernetes 监控
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
468 0
OpenAI故障复盘丨如何保障大规模K8s集群稳定性
|
缓存 容灾 网络协议
ACK One多集群网关:实现高效容灾方案
ACK One多集群网关可以帮助您快速构建同城跨AZ多活容灾系统、混合云同城跨AZ多活容灾系统,以及异地容灾系统。

推荐镜像

更多