kubeadm是帮助用户快速部署kubernetes项目的工具。
kubeadm工作原理
k8s的部署是一个非常麻烦的事情,通过与容器结果,将k8s的组件利用容器部署可能会简化,但是kubelet的容器化是非常麻烦的事情。因为除了跟容器运行时打交道外,kubelet 在配置容器网络、管理容器数据卷时,都需要直接操作宿主机。如果kubelet运行在容器中,那么它对宿主机的操作就会十分麻烦。
因此,kubeadm选择了一种折中方案:
将kubelet直接运行在宿主机上,然后使用容器部署其它的kubernetes组件。
使用kubeadm的第一步,是在机器上安装kubeamd、kubelet和kubectl三个二进制文件,kubeadm为各个Linux发行版准备好了安装包,直接使用对应包管理工具即可安装。例如
$ apt-get install kubeadmyum包管理器需要添加仓库源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF国内将源换为阿里源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF接下来便可以使用kubeadm init部署Master节点了。
kubeadm init工作流程
kubeadm init指定是用来部署k8s的Master节点的。
执行执行后,首先,kubeadm进行一系列检查工作,以确定这台机器可以部署kubenetes。这一步被称为“Preflights Checks”,涉及到相当多的检查内容。
检查通过后,生成kubenetes对外提供服务需要的各种证书和对应的目录。k8s对外提供服务,除非专门开启不安全模式,否则都要通过HTTPS才能访问kube-apiserver。kubeadm为k8s项目生成的证书都放在master节点的/etc/kubernetes/pki目录下,其中最重要的就是ca.crt和对应的私钥ca.key了。用户使用 kubectl 获取容器日志等 streaming 操作时,需要通过 kube-apiserver 向 kubelet 发起请求,这个连接也必须是安全的。kubeadm 为这一步生成的是 apiserver-kubelet-client.crt 文件,对应的私钥是 apiserver-kubelet-client.key。可以选择不生成证书,而是拷贝现有证书到对应的目录中。
证书生成后,为其它组件生成访问kube-apiserver所需的配置文件。文件的路径为/etc/kubernetes/xxx.conf,xxx是组件的名称。
接下来,为Master组件生成Pod配置文件。k8s的Master节点的三个组件都会以Pod的方式部署起来。在 /etc/kubernetes/manifests路径下生成组件的Pod Yaml配置文件。比如kube-apiserver.yaml:
apiVersion: v1
kind: Pod
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --authorization-mode=Node,RBAC
- --runtime-config=api/all=true
- --advertise-address=10.168.0.2
...
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
image: k8s.gcr.io/kube-apiserver-amd64:v1.11.1
imagePullPolicy: IfNotPresent
livenessProbe:
...
name: kube-apiserver
resources:
requests:
cpu: 250m
volumeMounts:
- mountPath: /usr/share/ca-certificates
name: usr-share-ca-certificates
readOnly: true
...
hostNetwork: true
priorityClassName: system-cluster-critical
volumes:
- hostPath:
path: /etc/ca-certificates
type: DirectoryOrCreate
name: etc-ca-certificates
...然后还会生成一个Etcd的Pod YAML文件,通过同样的Static Pod方式来启动Etcd。最后Master组件的Pod Yaml文件如下:
$ ls /etc/kubernetes/manifests/
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml而一旦这些 YAML 文件出现在被 kubelet 监视的 /etc/kubernetes/manifests 目录下,kubelet 就会自动创建这些 YAML 文件中定义的 Pod,即 Master 组件的容器。
Master启动后,kubeadm会通过检查localhost:6443/healthz这个Master组件的健康检查URL,来等待Master组件全部启动。
然后,kubeadm会生成一个bootstrap token,通过这个token,任何一个安装了kubeadm和kubelet的节点,都可以通过kubeadm join加入到这个集群当中。
token生成之后,kubeadm会将ca.crt等Master节点的重要信息,通过ConfigMap的方式保存在Etcd当中,供后续部署Node节点使用。
最后一步,安装默认插件,k8s默认必须安装kube-proxy和DNS这两个插件,用来提供整个集群的服务发现和DNS功能。
kubeadm join工作流程
kubeadm join <master节点的IP和端口>将Node节点加入到集群当中。需要kubeadm init生成的token。
这是因为任何一台机器想要称为kubernetes中的一个节点,就必须在集群的kube-apiserver上注册,但是要想跟apiserver交互,这台机器就必须获取到相应的证书文件,但是为了一键安装,就不能让用户去Master节点上手动拷贝证书,于是使用发起“不安全的访问”来获取到保存在ConfigMap中的cluster-info(保存了apiserver的授权信息),token就是这个访问中安全验证的角色。
只要获取到了cluster-info中kube-apiserver的地址、端口、证书,kubelet就可以以安全模式连接到apiserver上,新的节点就加入集群中了。
接下来只要在需要加入集群的节点上不断重复这条指定就行了。
配置kubeadm的部署参数
使用kubeadm使得集群的部署变得简易,也可以设置部署参数,定制集群组件参数。
通过如下命令指定配置文件来设置kubeadm的部署参数
$ kubeadm init --config kubeadm.yaml一个kubeadm.yaml示例如下:
apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.11.0
api:
advertiseAddress: 192.168.0.102
bindPort: 6443
...
etcd:
local:
dataDir: /var/lib/etcd
image: ""
imageRepository: k8s.gcr.io
kubeProxy:
config:
bindAddress: 0.0.0.0
...
kubeletConfiguration:
baseConfig:
address: 0.0.0.0
...
networking:
dnsDomain: cluster.local
podSubnet: ""
serviceSubnet: 10.96.0.0/12
nodeRegistration:
criSocket: /var/run/dockershim.sock
...然后,kubeadm 就会使用上面这些信息替换 /etc/kubernetes/manifests/xxx.yaml 里组件的 command 字段里的参数了。
tags: k8s集群部署