官方文档:
https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
1、前提条件
- 一台或多台运行着Ubuntu16.04+操作系统的机器
- 硬件配置:内存:2GB+,CPU:2C+ 硬盘:30GB+
- 集群中的所有机器的网络可以相互通信
- 禁用交互分区
- 可以访问外网,需要拉取镜像
2、准备部署Kubernetes集群
2.1、部署目标
??如下图,给出了本章要部署的目标集群的基本环境,它拥有一个Master节点和两个Node节点。各Node主机的配置方式基本相同。
??各主机上才用的容器运行时环境为Docker,为Pod提供网络功能的CNI是calico,它运行为托管于Kubernetes之上的Pod对象,另外,基础附件还包括CoreDNS用于名称解析和服务发现。
2.2、系统环境及部署准备
2.2.1、各相关组件及主机环境
操作系统、容器引擎及Kubernetes的相关版本如下:
- OS: Ubuntu18.04.4
- Container runtime: Docker CE 20.10.0
- Kubernetes: v1.20
各主机角色分配及IP地址如下表所示: |
IP地址 | 主机名 | 角色 |
---|---|---|---|
192.168.31.70 | k8s-master01 | master | |
192.168.31.71 | k8s-node01 | node | |
192.168.31.72 | k8s-node02 | node |
2.2.2、基础环境设置
以下操作在集群中的所有机器都需要执行
2.2.2.1、主机名解析
192.168.31.70 master01
192.168.31.71 node01
192.168.31.72 node02
2.2.2.2、主机时间同步
# ntpdate ntp.aliyun.com
2.2.2.3、禁用Swap
# swapoff -a
# sed -ri ‘s/.* swap.*/# &/‘ /etc/fstab
2.2.2.4 允许 iptables 检查桥接流量
# cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
# cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# sysctl --system
3、安装Docker(所有节点)
# step 1: 安装必要的一些系统工具
apt-get update
apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# Step 2: 安装GPG证书
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装v20.10.0版的Docker-CE
apt-get -y update
apt-get install docker-ce=5:20.10.0~3-0~ubuntu-bionic docker-ce-cli=5:20.10.0~3-0~ubuntu-bionic containerd.io -y
# Step 5:配置镜像加速
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-‘EOF‘
{
"registry-mirrors": ["https://5uhltnnr.mirror.aliyuncs.com"]
}
EOF
# Step 6:kubelet需要让docker容器引擎使用systemd作为CGroup的驱动,其默认值为cgroupfs,因而,我们还需要编辑docker的配置文件/etc/docker/daemon.json,添加如下内容。
"exec-opts": ["native.cgroupdriver=systemd"]
# Step 7:重新加载配置文件,然后重启服务,并且设置为开机启动。
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
4、安装kubelet和kubeadm(所有节点)
4.1、在各主机上生成kubelet和kubeadm等相关程序包的仓库,这里使用阿里云镜像源
# curl -fsSL https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
# apt update
4.2、安装kubelet、kubeadm、kubectl,并将kubelet设置为开机启动
# apt install kubelet=1.20.0-00 kubeadm=1.20.0-00 kubectl=1.20.0-00 -y
# systemctl enable kubelet
注: 安装完成后,要确保kubeadm等程序文件的版本,这将也是后面初始化Kubernetes集群时需要明确指定的版本号。
5、初始化Master节点
官方文档:
https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init/
https://pkg.go.dev/k8s.io/kubernetes@v1.20.4/cmd/kubeadm/app/apis/kubeadm/v1beta2
有两种方式可以初始化Master节点,分别是命令行方式和配置文件方式,这里使用第二种
方式一:通过命令行方式
# kubeadm init --apiserver-advertise-address=192.168.31.70 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.20.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --token-ttl=0
命令中的各选项简单说明如下:
- --apiserver-advertise-address:apiserver通告给其它组件的IP地址,一般应该为Master节点用于集群内部通信的IP地址
- --image-repository:指定要使用的镜像仓库,默认为gcr.io
- kubernetes-version:kubernetes程序组件的版本号,必须要与前面安装的版本一致
- --service-cidr:集群内部虚拟网络,Pod统一访问入口;service的网络地址范围,其值为CIDR格式的网络地址,默认地址为10.96.0.0/12
- --pod-network-cidr:Pod网络的地址范围,其值为CIDR格式的网络地址,通常,Flannel网络插件的默认为10.244.0.0/16,Project Calico插件的默认值为192.168.0.0/16;本章使用的是calico插件,所以下面部署CNI网络插件时需要与这里设置的保持一致。
- --token-ttl:共享令牌(token)的过期时长,默认为24小时,0表示永不过期;为防止不安全存储等原因导致的令牌泄露危及集群安全,建议为其设定过期时长。未设定该选项时,在token过期后,若期望再向集群中加入其它节点,可以使用如下命令重新创建token,并生成节点加入命令。
kubeadm token create --print-join-command
方式二:通过配置文件方式
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
# 这里的地址即为初始化的控制平面第一个节点的IP地址;
localAPIEndpoint:
advertiseAddress: "192.168.31.70"
bindPort: 6443
nodeRegistration:
criSocket: "/var/run/dockershim.sock"
# 第一个控制平面节点的主机名称;
name: k8s-master01
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
# 版本号要与部署的目标版本保持一致;
kubernetesVersion: "v1.20.0"
imageRepository: "registry.aliyuncs.com/google_containers"
apiServer:
timeoutForControlPlane: 4m0s
# 控制平面的接入端点,我们这里选择适配到192.168.31.70这一IP上;
controlPlaneEndpoint: "192.168.31.70:6443"
certificatesDir: "/etc/kubernetes/pki"
clusterName: "kubernetes"
dns:
type: "CoreDNS"
etcd:
local:
dataDir: "/var/lib/etcd"
networking:
# 要使用的域名,默认为cluster.local
dnsDomain: "cluster.local"
# Cluster或Service的网络地址;
serviceSubnet: "10.96.0.0/12"
# Pod的网络地址,10.244.0.0/16用于适配Calico网络插件的IP值;
podSubnet: "10.244.0.0/16"
controllerManager: {}
scheduler: {}
将上面的内容保存到文件中,例如kubernetes-init.yaml,然后执行以下命令:
kubeadm init --config kubeadm-init.yaml
6、初始化完成后的操作
看到如下图所示的信息,表示初始化成功。
这里来说明一下上图返回的信息中我们需要注意的地方:
# 下面是成功完成第一个控制平面节点初始化的提示信息及后续需要完成的步骤
Your Kubernetes control-plane has initialized successfully!
# 在开始使用集群之前,你需要额外手动完成几个必要的步骤,使用的命令如下
To start using your cluster, you need to run the following as a regular user:
# 第1个步骤提示,Kubernetes集群管理员认证到Kubernetes集群时使用的kubeconfig配置文件;
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 我们也可以不做上述设定,而使用环境变量KUBECONFIG为kubelet等指定默认使用的kubeconfig;
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
# 第2个步骤提示,管理员需要使用网络插件为Kubernetes集群部署Pod网络,具体选用的插件取决于管理员;
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/
# 第3个步骤提示,向Kubernetes集群添加工作节点
Then you can join any number of worker nodes by running the following on each as root:
# 在部署好kubeadm等程序包的各工作节点上以root用户运行类似如下命令
kubeadm join 192.168.31.70:6443 --token 74xtvu.dv3716l3iuy42tcf --discovery-token-ca-cert-hash sha256:0a5293036cafd33ffd9f688cc993a93a3db0e64b6e4800d76cc251a507a94203
6.1、设定kubectl
kubectl是kube-apiserver的命令行客户端程序,实现了除系统部署之外的几乎全部的管理操作,是kubernetes管理员使用最多的命令之一。kubectl需经由API server认证及授权后方能执行相应的管理操作,kubeadm部署的集群为其生成了一个具有管理员权限的认证配置文件/etc/kubernetes/admin.conf,它可由kubectl通过默认的"$HOME/.kube/config"的路径进行加载。当然,用户也可在kubectl命令上使用--kubeconfig选项指定一个别的位置。
下面复制认证为Kubernetes系统管理员的配置文件至目标用户(例如当前用户root)的家目录下,用于kubectl连接Kubernetes集群:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
6.2、部署网络插件
6.2.1 下载配置文件
# wget https://docs.projectcalico.org/manifests/calico.yaml
6.2.2 修改配置
# 下载完后还需要修改里面定义Pod网络(CALICO_IPV4POOL_CIDR),与前面kubeadm init命令中使用的--pod-network-cidr选项指定的一样
3672 - name: CALICO_IPV4POOL_CIDR
3673 value: "10.244.0.0/16"
6.2.3 应用配置清单并部署网络插件
# kubectl apply -f calico.yaml
6.2.4 确认部署网络插件的Pod正常运行状态
# kubectl get pod -n kube-system -l k8s-app=calico-node
NAME READY STATUS RESTARTS AGE
calico-node-26s88 1/1 Running 0 8m31s
calico-node-c2mpn 1/1 Running 0 8m28s
calico-node-dhhg8 1/1 Running 0 15m
6.2.5 验证master节点已经就绪
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 4h41m v1.20.0
6.3 添加Node节点到集群中
下面的步骤,需要在集群中的所有Node节点上执行
# kubeadm join 192.168.31.70:6443 --token 74xtvu.dv3716l3iuy42tcf --discovery-token-ca-cert-hash sha256:0a5293036cafd33ffd9f688cc993a93a3db0e64b6e4800d76cc251a507a94203
6.4 验证Node节点添加结果
在每个工作节点添加完成后,即可通过kubectl验证添加结果。下面的命令及其输出是在k8s-node01和k8s-node02均添加完成后运行的,其输出结果表明两个Node已经准备就绪。
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master01 Ready control-plane,master 4h45m v1.20.0
k8s-node01 Ready <none> 117s v1.20.0
k8s-node02 Ready <none> 114s v1.20.0
7、配置kubectl命令自动补全功能
# echo "source <(kubectl completion bash)" >> ~/.profile
8、测试Kubernetes集群
- 验证Pod工作
- 验证Pod网络通信
- 验证DNS解析
8.1、验证Pod工作
在Kubernetes集群中创建1个Pod,验证是否正常运行
root@k8s-master01:~# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
root@k8s-master01:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-fc8xq 1/1 Running 0 40s
从上面的返回结果中来看,新建的Pod转态为"Running",并且就绪。表示运行正常。
8.2、验证Pod网络通信
为Deployment资源对象nginx创建NodePort类型的service,将上面创建的Pod应用发布到集群外部。
如上图,已经成功的创建了service资源,并且关联到了后端的pod,现在打开浏览器,输入任意节点的IP+32082端口即可访问pod提供的应用,http://NodeIP:NodePort
8.3、验证DNS解析
使用busybox:1.28.4镜像创建一个pod,用于dns解析上面创建的service名称
从上图返回的结果信息中,可以验证Kubernetes集群中的DNS服务工作正常。
至此,1个Master,并附带2个Node的kubernetes集群基础设置已经部署完成,并且其核心功能可以正常使用。
9、部署Dashboard
9.1、下载配置清单文件
# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/recommended.yaml
9.2、修改相关内容
默认情况下,Service类型为ClusterIP,只能用于集群内部访问,这里指定使用"NodePort"类型,并使用固定端口30001,将其发布集群外部访问
9.3、应用配置清单文件,创建相关资源
# kubectl apply -f recommended.yaml
9.4、验证pod是否正常运行
# kubectl get pod -n kubernetes-dashboard -l k8s-app=kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
kubernetes-dashboard-5dbf55bd9d-9f97k 1/1 Running 0 68s
从上面的反馈结果来看,pod运行正常,并且已经就绪。
9.5、访问Dashboard
打开浏览器,输入集群中任意节点的IP以https://NodeIP:30001格式访问
9.6、生成token
创建service account并绑定默认cluster-admin管理员集群角色:
# 创建用户
# kubectl create serviceaccount dashboard-admin -n kube-system
# 用户授权
# kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
# 获取用户token
# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk ‘/dashboard-admin/{print $1}‘)
Name: dashboard-admin-token-lflm9
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: dashboard-admin
kubernetes.io/service-account.uid: f73d4dd5-6a0d-4917-a2ce-54dba6a1882c
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1066 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImdXS2ZwaHV2WVZwREhQenZyZUw5SWRYV3VReHhObVZKMXZyX1hUWm1mZTQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tbGZsbTkiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZjczZDRkZDUtNmEwZC00OTE3LWEyY2UtNTRkYmE2YTE4ODJjIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.mMF7dO0QdOlC-ff7W7pCCMJ4YMtAC-X3kMdGEK7IHFxOiA78qJF9e8IQ8fRAje4cJjF33AmBKkeieJdz-KE_Wm7Wj_6u_A9_csm3hfpWLV3mN5VeKbvQ1G7fXFkN1aFpBw7Gr7kxtXmXewOb9XR05YblwVg2omoAnJlGfHlnkASJ4d0CwyCn9CiiTJs_611jqCyrkf9dhik9vtmLtqZxCVzDtdsA0CMH4Gny0f27OHnN9q_QDOr5Hg6gBzaimgS1n_NXu60up_M_7Yi9_Cg3FtlKNZr0Eav27uStsGU_Jneg_DVvPu51c3k3lNpQBUUiwjsltP2r3trQRFAkTtEWpA
9.7、使用token登录Dashboard
复制上面生成的token到浏览器,以登录Dashboard
登录后的界面