1、kubeadm 介绍
Kubernetes 是 Google 开源的基于 Docker 的容器集群管理系统,通过 yaml 语言写的配置文件,简单快速的就能自动部署好应用环境,支持应用横向扩展,并且可以组织、编排、管理和迁移这些容器化的应用。Kubeadm 是一个可以快速帮助我们创建稳定集群服务的工具,通过它,我们可以在虚拟机、实体机或者云端快速部署一个高可用的集群服务。
2、环境、软件准备
安装之前,先介绍下 Kubeadm 安装 kubernetes 需要的一些基本硬件要求。
-
系统要求,支持的系统 Ubuntu 16.04+、 CentOS 7 、HypriotOS v1.0.1+
-
内存要求,每台机器至少要有 1GB 内存,否则集群启动后,留给运行的应用可用内存就很少了。
-
网络要求,保证集群内所有机器之前的网络是可以互相连通的。
本次演示我准备了两台系统为 CentOS Linux 7 (Core) 的虚拟机,一台作为 Master,一台作为 Node,默认 Master 机器不参与 Pod 调度。集群机器信息如下:
HostName | IP | CPU | MEM | DES |
---|---|---|---|---|
master.localdomain | 10.67.34.130 | 2 Core | 2G | k8s master 节点 |
node0.localdomain | 10.67.34.131 | 2 Core | 2G | 应用节点 |
此外,我们还需要做一些初始化工作,下边安装过程中遇到坑的时候也会提到。
1、安装 ebtables ethtool,否则后边执行 kubeadm init 的时候会报错。
$ yum install ebtables ethtool
2、设置关闭防火墙及SELINUX
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
vi /etc/selinux/config
SELINUX=disabled
3、关闭Swap
swapoff -a && sysctl -w vm.swappiness=0
vi /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0
4、设置Docker所需参数
cat << EOF | tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
modprobe br_netfilter
sysctl -p /etc/sysctl.d/k8s.conf
5、安装 Docker
$ yum install -y docker
# 设置开启启动并启动服务
$ systemctl enable docker && systemctl start docker
# 直接安装yum自带得docker就够用了。
3、软件安装配置
我们知道 kubernetes 环境底层是依赖 Docker 的,所以这里软件安装包括了 Docker 安装, kubelet、kubeadm、kubectl 组件安装,以及一些初始化配置工作。
Master 和 Node 节点由于分工不一样,所以安装的服务不同,最终安装完毕,Master 和 Node 启动的核心服务分别如下:
Master 节点 | Node 节点 |
---|---|
etcd-master | kube-flannel |
kube-apiserver | kube-proxy |
kube-controller-manager | other apps |
kube-dns | |
kube-flannel | |
kube-proxy | |
kube-scheduler |
3.1 镜像准备
kubernetes 服务启动依赖很多镜像,但是这些镜像要是在国内没有翻墙的话,是下载不下来的。这里我们可以去 Docker Hub 下载指定版本的镜像替代,下载完成后,通过 docker tag ... 命令修改成指定名称的镜像即可。
3.2 安装并配置 kubernetes 组件
对于国内不能翻墙的用户,可以下载指定版本的 rpm 包安装,也可以去 github 下载 kubernetes release 这个项目源码,本地编译生成 rpm 包。
$ git clone https://github.com/kubernetes/release.git
$ cd rpm
$ ./docker-build.sh
...
最终执行完毕的结果,会在项目 release/rpm/output/ 下生成特定版本的 rpm 包。
然后执行如下命令,完成组件的安装。
# yum 安装 rpm 包
$ yum install -y *.rpm
# 设置开机启动
$ systemctl enable kubelet
安装完毕后,我们还需要配置一下 kubelet,主要修改配置文件 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 中的 KUBELET_CGROUP_ARGS 配置。
vim /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"
Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook --client-ca-file=/etc/kubernetes/pki/ca.crt"
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=systemd"
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_SYSTEM_PODS_ARGS $KUBELET_NETWORK_ARGS $KUBELET_DNS_ARGS $KUBELET_AUTHZ_ARGS $KUBELET_CGROUP_ARGS $KUBELET_EXTRA_ARGS
将 kubectl 的默认驱动改为同 Docker 的一样,否则下边执行 kubeadm init 的时候会报错。Docker得驱动方式可以通过下面得命令查看:
$ docker info
修改完成之后,需要重新 reload 一下 kubelet 服务。
$ systemctl daemon-reload
通过以上安装配置就完成了master节点环境的初始化工作,因为使用的是虚拟机,那么只需要将配置好的主机环境复制一份作为node节点即可。
最后分别更改master和node得hostname:
# Master 节点
$ echo "master.localdomain" > /etc/hostname
$ echo "10.67.34.130 master.localdomain" >> /etc/hosts
$ sysctl kernel.hostname=master.localdomain # 不重启情况下使内核修改生效
# Node 节点
$ echo "node0.localdomain" > /etc/hostname
$ echo "10.67.34.131 node0.localdomain" >> /etc/hosts
$ sysctl kernel.hostname=node0.localdomain # 不重启情况下使内核修改生效
4、初始化启动 Master
配置完主机后,我们可以启动 Master 节点了。在执行初始化 init 时,kubernetes 并没有选择默认的 Pod Network,它支持很多种,这里我们选择 Flannel 作为 Pod Network,按照文档说明,执行 init 时,需要带上参数 --pod-network-cidr,即指定网络区间,同时我们也可以通过 --kubernetes-version 指定选择 kubernetes 的版本号,因为我们镜像以及 rpm 包都是指定 1.6.2 的版本,所以最终执行命令如下:
$ kubeadm init --kubernetes-version=v1.6.2 --pod-network-cidr=10.96.0.0/12
[kubeadm] WARNING: kubeadm is in beta, please do not use it for production clusters.
[init] Using Kubernetes version: v1.6.2
[init] Using Authorization mode: RBAC
[preflight] Running pre-flight checks
[preflight] Starting the kubelet service
[certificates] Generated CA certificate and key.
[certificates] Generated API server certificate and key.
[certificates] API Server serving cert is signed for DNS names [master.localdomain kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.67.34.130]
[certificates] Generated API server kubelet client certificate and key.
[certificates] Generated service account token signing key and public key.
[certificates] Generated front-proxy CA certificate and key.
[certificates] Generated front-proxy client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[apiclient] Created API client, waiting for the control plane to become ready
[apiclient] All control plane components are healthy after 16.577867 seconds
[apiclient] Waiting for at least one node to register
[apiclient] First node has registered after 4.004669 seconds
[token] Using token: 3aaf19.8e758a48f2050bd1
[apiconfig] Created RBAC rules
[addons] Created essential addon: kube-proxy
[addons] Created essential addon: kube-dns
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run (as a regular user):
sudo cp /etc/kubernetes/admin.conf $HOME/
sudo chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
http://kubernetes.io/docs/admin/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join --token 3aaf19.8e758a48f2050bd1 10.67.34.130:6443
初始化 Master 完成后,我们接着执行以下操作赋予本机命令行操作访问权限:
sudo cp /etc/kubernetes/admin.conf $HOME/
sudo chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf
现在我们使用命令 kubectl get node 就可以查看集群节点信息了。
$ kubectl get node
NAME STATUS AGE VERSION
master.localdomain Ready 1d v1.6.2
使用命令 kubectl get pod --all-namespaces 查看当前节点所有的 pod。
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-master.localdomain 1/1 Running 0 23h
kube-system kube-apiserver-master.localdomain 1/1 Running 0 1d
kube-system kube-controller-manager-master.localdomain 1/1 Running 0 1d
kube-system kube-dns-3913472980-37b6d 0/3 Pending 0 14m
kube-system kube-proxy-czzg9 1/1 Running 0 1d
kube-system kube-scheduler-master.localdomain 1/1 Running 0 1d
注意这里 kube-dns 显示状态为 Pending,没有关系,这是因为还没有安装 Pod Network 组件导致的,接下来我们安装 Flannel 网络组件后,它就会自动跑起来了。
5、安装 Flannel 网络组件
这里我使用 v0.7.1 版本,需要使用两个文件,可在 Github Flannel上获取。
$ kubectl apply -f https://github.com/coreos/flannel/blob/v0.7.1/Documentation/kube-flannel-rbac.yml
$ kubectl apply -f https://github.com/coreos/flannel/blob/v0.7.1/Documentation/kube-flannel.yml
安装完毕后,我们稍等一会再来查看下 pod 列表。
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-master.localdomain 1/1 Running 0 23h
kube-system kube-apiserver-master.localdomain 1/1 Running 0 1d
kube-system kube-controller-manager-master.localdomain 1/1 Running 0 1d
kube-system kube-dns-3913472980-37b6d 3/3 Running 0 14m
kube-system kube-flannel-ds-vkdzw 2/2 Running 5 4m
kube-system kube-proxy-czzg9 1/1 Running 0 1d
kube-system kube-scheduler-master.localdomain 1/1 Running 0 1d
6、部署 Node 节点
Master 已经正常启动完毕了,现在我们将 Node 加入 cluster 集群中,使用 kubeadm join … 命令。在 Node 节点上执行(上边执行 init 时日志打印的命令)
$ kubeadm join --token 3aaf19.8e758a48f2050bd1 10.67.34.130:6443
[preflight] Running pre-flight checks
[preflight] Starting the kubelet service
[discovery] Trying to connect to API Server "10.67.34.130:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.67.34.130:6443"
[discovery] Cluster info signature and contents are valid, will use API Server "https://10.67.34.130:6443"
[discovery] Successfully established connection with API Server "10.67.34.130:6443"
[bootstrap] Detected server version: v1.6.2
[bootstrap] The server supports the Certificates API (certificates.k8s.io/v1beta1)
[csr] Created API client to obtain unique certificate for this node, generating keys and certificate signing request
[csr] Received signed certificate from the API server, generating KubeConfig...
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
Node join complete:
* Certificate signing request sent to master and response
received.
* Kubelet informed of new secure connection details.
Run 'kubectl get nodes' on the master to see this machine join.
现在在 Master 节点查看下集群节点信息,就会发现已经包含该 Node 节点了。
$ kubectl get node -o wide
NAME STATUS AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION
master.localdomain Ready 1d v1.6.2 <none> CentOS Linux 7 (Core) 3.10.0-514.26.2.el7.x86_64
node0.localdomain Ready 1d v1.6.2 <none> CentOS Linux 7 (Core) 3.10.0-514.26.2.el7.x86_64
7、安装 Kubernetes Dashboard
接下来安装 Kubernetes Dashboard 监控
$ kubectl create -f https://github.com/kubernetes/dashboard/blob/v1.6.0/src/deploy/kubernetes-dashboard.yaml
# 注意镜像版本得更改,改成你自己得镜像。
安装完成之后,可以通过命令获取服务端口号,然后通过http://: 方式既可以访问 Dashboard UI 页面。
$ kubectl get service --all-namespaces
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes 10.96.0.1 <none> 443/TCP 1d
kube-system kube-dns 10.96.0.10 <none> 53/UDP,53/TCP 1d
kube-system kubernetes-dashboard 10.106.212.217 <nodes> 80:30438/TCP 1d
8、Dashboard 集成 Heapster
首先我们去 GitHub 下载 GitHub Heapster 最新稳定版代码到本地指定目录,然后通过 yaml 文件创建并启动各个服务。这里我们选择 InfluxDB 作为后端数据存储,Grafana 作为图形化展示。
$ cd /Users/wanyang3/docker/kubernetes/
$ git clone https://github.com/kubernetes/heapster.git
$ ls -l deploy/kube-config/influxdb/
total 24
-rw-r--r-- 1 wanyang3 staff 2291 10 19 14:49 grafana.yaml
-rw-r--r-- 1 wanyang3 staff 1162 10 20 15:01 heapster.yaml
-rw-r--r-- 1 wanyang3 staff 974 10 19 14:49 influxdb.yaml
在执行 create 之前请保证能够翻墙或者已经替换好了所需要的 images。
$ kubectl create -f deploy/kube-config/influxdb/
delpoyment "heapster" created
service "heapster" created
deployment "monitoring-influxdb" created
service "monitoring-influxdb" created
deployment "monitoring-grafana" created
service "monitoring-grafana" created
$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
heapster-3848557544-1548b 1/1 Running 0 1d
monitoring-grafana-2175968514-7tl3w 1/1 Running 0 1d
monitoring-influxdb-1957622127-x28mz 1/1 Running 0 1d
...
Heapster 插件已经启动完毕了,如果一切正常的话,稍等几分钟(采集数据需要些时间),再次刷新 dashboard,就能看到集群度量指标信息将以图形化方式展现出来。