安装配置运行Kubernetes的主节点master,其中包括了etcd的数据库,即etcd没有和主节点分开,使用于奇数个主节点安装。
1.生成kubernets的仓库配置文件
# cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
2.安装kubeadm、kubelet、kubectl
# yum install kubeadm kubelet kubectl
设置kubectl自启动
# systemctl enable kubelet
3.始化master节点
初始化命令‘kubeadm’可以使用参数传递和yaml配置文件。
1)准备初始化所需组件(可选)
初始化的过程会首先拉取需要的容器镜像,而镜像又存储在k8s.gcr.io上,需要科学上网,因此可先准备好镜像再执行初始化命令。
获取所需组件列表
#kubeadm config images list
拉取命令直接获取组件
# kubeadm config images pull
如果没有改仓库则默认从k8s.gcr.io去获取,建议能够科学访问的环境下直接使用,也可以采用镜像站点来拉取。
# vim k8s-pull-images.sh
#!/bin/bash
REGISTRY=gcr.azk8s.cn/google-containers
images=(
kube-apiserver:v1.16.3
kube-controller-manager:v1.16.3
kube-scheduler:v1.16.3
kube-proxy:v1.16.3
pause:3.1
etcd:3.3.15-0
coredns:1.6.2
)
for imageName in ${images[@]} ; do
docker pull ${REGISTRY}/$imageName
docker tag ${REGISTRY}/$imageName k8s.gcr.io/$imageName
docker rmi ${REGISTRY}/$imageName
done
说明: REGISTRY还可以使用dockerhub中的镜像,具体修改:REGISTRY=mirrorgooglecontainers(注意:只有amd64的镜像)。
其中组件包列表可以通过命令"kubeadm config images list"获取。
# chmod +x k8s-pull-images.sh
# ./k8s-pull-images.sh
上述脚本保存执行后可以通过"docker image list"查看结果。
拉取非x86_64架构的镜像文件
从Docker registry v2.3和Docker 1.10开始,Docker通过支持新的image Media 类型 manifest list 实现了Multi architecture Docker镜像功能,即一个image manifest list包含已经存在镜像的manifest对象的平台特性(CPU arch和OS类型)特征,在具体来讲就是拉取镜像的时候会根据现有的主机架构拉取相应的平台架构的镜像,因此强烈建议采用模拟器运行虚拟机的方式拉取该平台的镜像,如kvm+qemu+qemu-system-aarch64来运行arm64架构的虚拟机。
如果没有采用虚拟机的方式拉取镜像,比如在amd64平台下拉取arm64的镜像,则需要查看仓库中的具体标签,因为仓库有多个比如docker.io、quey.io,所以没有统一的规则,下面总结了本人需要用到的标签
- k8s.gcr.io/kube-apiserver-arm64:v1.16.3
- k8s.gcr.io/kube-controller-manager-arm64:v1.16.3
- k8s.gcr.io/kube-scheduler-arm64:v1.16.3
- k8s.gcr.io/kube-proxy-arm64:v1.16.3
- k8s.gcr.io/pause:3.1
- k8s.gcr.io/etcd-arm:3.3.15-0
- quey.io/coreos/flannel:0.11.0-arm64
dockerhub仓库简单的使用镜像存储库的前缀来区分相同应用的不同平台,如下: - ARMv8 64-bit (arm64v8): https://hub.docker.com/u/arm64v8/
- Linux x86-64 (amd64): https://hub.docker.com/u/amd64/
- Windows x86-64 (windows-amd64): https://hub.docker.com/u/winamd64/
但dockerhub还是建议构建Multi architecture Docker镜像,另外碰到一个例外的coredns:
docker.io/coredns/coredns:coredns-arm64(对应最新版的coredns)
quey.io的标签tag的写法就又不一样了,比如: - quey.io/coreos/flannel:0.11.0-arm64
- quey.io/coreos/etcd:3.3.15-0-arm64
离线环境镜像的导出和导入
离线环境中部署k8s需要先在在线环境中下载导出,然后在传入离线环境中导入
镜像的导出
命令和格式
docker save -o [, ...]
举例(单个打包)
docker save -o kube-apiserver-1.16.3.tar k8s.gcr.io/kube-apiserver:v1.16.3
举例(批量打包)
docker save -o k8s-master-1.16.3.tar\
k8s.gcr.io/kube-apiserver:v1.16.3\
k8s.gcr.io/kube-controller-manager:v1.16.3\
k8s.gcr.io/kube-scheduler:v1.16.3\
k8s.gcr.io/kube-proxy:v1.16.3\
k8s.gcr.io/pause:3.1\
k8s.gcr.io/etcd:3.3.15-0\
k8s.gcr.io/coredns:1.6.2
单个打包可以应对多种架构的部署(主要时etcd从master分离)
镜像的导入
命令和格式
docker -load -i
举例
加载初始化所需要的镜像
docker load -i k8s-master-1.16.3.tar
或
docker load -i kube-apiserver-1.16.3.tar
docker load -i kube-controller-1.16.3.tar
docker load -i kube-scheduler-1.16.3.tar
docker load -i kube-proxy-1.16.3.tar
docker load -i pause-3.3.tar
docker load -i etcd-3.3.15-0.tar
docker load -i coredns-1.6.2.tar
2) 命令行参数进行初始化
# kubeadm init --kubernetes-version="1.16.3" --pod-network-cidr="10.244.0.0/16" --service-cidr="10.96.0.0/12" --ignore-preflight-errors=Swap --ignore-preflight-errors=NumCPU --image-reporitory "gcr.azk8s.cn" --dry-run
其中
- --kubernete-version="1.16.3"指定了kubernete的具体版本,默认的“stable-1”,这里是1.16.0,不符合规定需要修改成当前的版本,此处时1.16.3(查询命令"rpm -qa|grep kubeadm")。
- --pod-network-cidr="10.244.0.0/16"是自定义的Pod的网络,通常与要部署的网络插件(如:flannel和calico)保持一致,此处使用的时flannel,flannel的默认地址为:10.244.0.0/16,calico的默认地址为:192.168.0.0/16。
- --ignore-preflight-errors=,这里有两项一个是Swap,一个是NumCPU,他们分别忽略了swap不为0的报错和CPU没有大于2的报错。因为这里我用的是虚拟机,只有1G的内存,因此没有关闭swap;同时虚拟机之分配了一个vCPU。若未禁用swap,则需要编辑kubelet的配置文件/etc/sysconfig/kubelet,忽略swap启用状态错误。
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
- --server-cidr指定service分配的网络地址,由kubernete管理,默认地址为10.96.0.0/12。
- --image-reporitory指定组件仓库地址代替默认的"k8s.gcr.io",比如此处国内的gcr.azk8s.cn。
- --dry-run 只是试运行看有没有什么错误,并没有实际初始化。
该命令执行时,会自动去k8s.gcr.io拉取需要的镜像文件,执行成功执行后会显示初始化结果
...
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.122.10:6443 --token kt9uzn.793zkkepgvup3jg8 \
--discovery-token-ca-cert-hash sha256:1b00c8c653c5573ff89c134bd1e62a54f3640813b0e26b79f387fddb402b0b48
3) 使用配置文件进行初始化
获取配置文件
kubeadm config print init-defaults > kubeadm-init-config.yaml
修改配置文件(检查以下部分)
...
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
...
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
...
kind: ClusterConfiguration
kubernetesVersion: v1.16.2
networking:
dnsDomain: cluster.test
serviceSubnet: 10.96.0.0/16
podSubnet: 10.244.0.0/16
...
使用命令进行初始化
kubeadm init -f kubeadm-init-config.yaml
离线环境的配置文件初始化根在线环境一样,但需要先导入镜像文件。
4) 初始化后续操作
接下来按照上述初始化结果的提示后续还需要为当前master节点的用户准备kubectl环境和安装网络
创建文件夹
$ mkdir -p ~/.kube
$ cp /etc/kubernetes/admin.conf ~/.kube/config
安装网络插件
语法:"kubectl apply -f [podnetwork].yaml"
此处我们使用的flannel(由coreos研发)。在github的页面上有具体的安装说明,地址https://github.com/coreos/flannel。
# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
如果是离线安装可以先下载打包flannel镜像及kube-flannel.yml文件,然后使用kubectl安装。具体如下:
下载flannel
docker pull query.io/coreos/flannel
打包flannel并保存到本地
docker save query.io/coreos/flannel -o /flannel-0.11.0.tar
装载flannel镜像
docker load -i /flannel-0.11.0.tar
下载kube-flannel.yml文件
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
安装flannel
kubectl apply -f kube-flannel.yml
而后可以使用命令"kubectl get pods -n kube-system"进行查看。
参考:
- kubeadm-config.yaml配置语法参考: https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
- kubeadm-config.yaml配置主节点:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/control-plane-flags/
- kube-proxy开启ipvs: https://github.com/kubernetes/kubernetes/blob/master/pkg/proxy/ipvs/README.md
- kubelet的配置示例参考: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/kubelet-integration/#configure-kubelets-using-kubeadm
5) 补充说明:
kubeadm-config.yaml组成部署说明:
- InitConfiguration: 用于定义一些初始化配置,如初始化使用的token以及apiserver地址等
- ClusterConfiguration:用于定义apiserver、etcd、network、scheduler、controller-manager等master组件相关配置项
- KubeletConfiguration:用于定义kubelet组件相关的配置项
- KubeProxyConfiguration:用于定义kube-proxy组件相关的配置项
可以看到,在默认的kubeadm-config.yaml文件中只有InitConfiguration、ClusterConfiguration 两部分。我们可以通过如下操作生成另外两部分的示例文件:
# 生成KubeletConfiguration示例文件
kubeadm config print init-defaults --component-configs KubeletConfiguration
# 生成KubeProxyConfiguration示例文件
kubeadm config print init-defaults --component-configs KubeProxyConfiguration
kubeadm初始化时kubernete认可的docker版本问题
[WARNING SystemVerification]: this docker version is not on the list of validated version: 19.01.1. Latest validated version: 18.06
以上版本根据自身环境的报告版本有所不同,可以参看kubernetes在git仓库中的changelog文件来确定支持的docker本版,然后根据命令
# yum list docker-ce.x86_64 --showduplicates | sort -r
获取版本列表,然后选取特定的版本进行安装
sudo yum -y install docker-ce-[VERSION]
kubeadm初始化时kubelet没有设置自启动
[WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'
解决:执行自启动命令'systemctl enable kubelet.service'
kubeadm初始化时没有禁用swap:
[ERROR Swap]: running with swap on is not enabled, please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with '--ignore-preflight-errors=...'
解决:可以在kubeadm的命令末尾加上参数'--ignore-preflight-errors=Swap'。
查看初始化后的kubeadm的配置
kubeadm config view
master node参与工作负载
使用kubeadm初始化的集群,出于安全考虑Pod不会被调度到Master Node上,也就是说Master Node不参与工作负载。这是因为当前的master节点(比如名字叫master0)被打上了node-role.kubernetes.io/master:NoSchedule的污点:
$ sudo kubectl describe node master0 | grep Taint
Taints: node-role.kubernetes.io/master:NoSchedule
因为这里搭建的是测试环境,或者其它原因需要去掉这个污点使master0参与工作负载:
$ sudo kubectl taint nodes master0 node-role.kubernetes.io/master-
node "master0" untainted