了解了linux容器本身的使用,就该考虑如何使用这些技术来“容器化”你的应用。
例如:我们的应用可能是web和mysql组合,也可能是cassandra(Apache开发的分布式的非关系型数据库)这样的分布式系统。而要使用容器把Cassandra运行起来,单单通过docker把它跑起来是没用的。关键是,如何处理好容器之间的编排关系,比如哪些是主,哪些是从,如何进行自动发现和通信,如何做持久化数据存储等等,都是kubernetes考虑剖析的东西。
使用kubeadm部署kubernetes项目
kubeadm是芬兰的一个高中生,在业余时间编写的,看看,牛人都是不受年龄限制的,kubeadm还是比较轻量简单的。
创建部署master节点
kubeadm init
将一个node节点加入到当前集群中
kubeadm join <master 节点的ip和端口>
kubeadm工作原理
首先,在机器上手动安装kubeadm、kubelet、kubectl三个二进制文件。然后,使用kubeadm init部署master节点,最后使用kubeadm join将node加入到集群中。
kubeadm init工作流程
当执行kubeadm init后,kubeadm首先做一系列检查工作,确保这台机器可以部署kubernetes。
- linux内核版本是否是3.10以上?
- linux cgroups模块是否可用?
- 机器的hostname是否标准?在kubernetes项目里,机器的名字以及一切存储在etcd中的api对象,都必须使用标准的DNS命名。
- 用户安装的kubeadm和kubelet的版本是否匹配?
- 机器上是不是已经安装了kubernetes的二进制文件?
- kubernetes的工作端口10250/10251/10252是否已经被占用?
- ip、mount等linux指令是否存在?
- docker是否已经安装?
- ...
然后,kubeadm会生成kubernetes对外提供服务所需的各种证书和对应的目录
生成的证书文件都放在master节点的/etc/kubernetes/pki目录下,最主要的证书文件是ca.crt和ca.key。
用户使用kubectl获取容器日志操作时,需要通过kube-apiserver向kubelet发起请求,这个链接也必须是安全的,kubeadm为这一步生成的是apiserver-kubelet-client.crt文件,对应的私钥是apiserver-kubelet-client.key。
证书生成后,kubeadm会为其他组件生成访问kube-apiserver所需要的配置文件。存放在/etc/kubernetes/xxx.conf:
ls /etc/kubernetes
admin.conf controller-manager.conf kubelet.conf scheduler.conf
配置文件中记录了master节点的服务器地址、监听端口、证书目录等信息。客户端可以使用这些信息与kube-apiserver建立安全连接。
然后,kubeadm为master组件生成pod配置文件,kube-apiserver、kube-controller-manager、kube-scheduler都会被使用pod的方式部署起来。
在kubeadm中,master组件的yaml文件会被生成在/etc/kubernetes/manifests下,比如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
...
然后,kubeadm为集群生成一个bootstrap token。任何一个节点,只要安装了kubelet和kubeadm,都可以通过kubeadm join以及这个token加入到集群中。
token生成后,kubeadm将ca.crt等重要信息通过configmap的方式存储在etcd中,供后续添加node节点使用,这个configmap的名称是cluster-info。
最后,安装默认插件。kube-proxy和DNS,前者提供整个集群的服务发现,后者提供DNS功能,本质是在客户端启动两个pod。
kubeadm join工作流程
任何一台机器想要成为kubernetes集群中的一个节点,就必须在kube-apiserver上注册。想要连接到apiserver,就必须有证书文件,为了一键安装,不能让用户去master节点手动拷贝。bootstrap token,就扮演着安全验证的角色。只要有了kube-apiserver的地址、端口、证书,kubelet就可以以安全模式连接到apiserver上,这样一个新的节点就部署完成了。
配置kubeadm部署参数
编写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
...
可以修改kube-apiserver参数,修改证书文件,修改容器运行时,修改镜像URL等,通过制定这个部署参数配置文件,就能够实现自定义配置参数了。
kubeadm init --config kubeadm.yaml
总结
因为kubeadm目前还无法部署一个高可用的kubernetes集群,etcd、master组件都是单点,导致kubeadm暂时还无法用于生产环境,随着项目的增进,这以后就不会是一个问题了。
另外,如果有部署规模化生产环境的需求,可以使用kops或者saltstack这样更复杂的部署工具。