kubeadm
minikube 还是太“迷你”了,方便的同时也隐藏了很多细节,离真正生产环境里的计算集群有一些差距,毕竟许多需求、任务只有在多节点的大集群里才能够遇到,相比起来,minikube 真的只能算是一个“玩具”。
Kubernetes 是很多模块构成的,而实现核心功能的组件像 apiserver、etcd、scheduler 等本质上都是可执行文件,所以也可以采用和其他系统差不多的方式,使用 Shell 脚本或者 Ansible 等工具打包发布到服务器上。
不过 Kubernetes 里的这些组件的配置和相互关系实在是太复杂了,用 Shell、Ansible 来部署的难度很高,需要具有相当专业的运维管理知识才能配置、搭建好集群,而且即使这样,搭建的过程也非常麻烦。
为了简化 Kubernetes 的部署工作,让它能够更“接地气”,社区里就出现了一个专门用来在集群中安装 Kubernetes 的工具,名字就叫“kubeadm”,意思就是“Kubernetes 管理员”。
下面使用kubeadm搭建一个1master,1work ,1console的k8s集群
安装前的准备工作
改主机名
由于 Kubernetes 使用主机名来区分集群里的节点,所以每个节点的 hostname 必须不能重名。你需要修改“/etc/hostname”这个文件,把它改成容易辨识的名字,比如 Master 节点就叫 master,Worker 节点就叫 worker:
sudo vi /etc/hostname
改 Docker 配置
安装完成docker后需要你再对 Docker 的配置做一点修改,在“/etc/docker/daemon.json”里把 cgroup 的驱动程序改成 systemd ,然后重启 Docker 的守护进程
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"registry-mirrors": ["https://5pfmrxk8.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker
改网络设置
为了让 Kubernetes 能够检查、转发网络流量,你需要修改 iptables 的配置,启用“br_netfilter”模块:
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
net.ipv4.ip_forward=1 # better than modify /etc/sysctl.conf
EOF
sudo sysctl --system
改交换分区
需要修改“/etc/fstab”,关闭 Linux 的 swap 分区,提升 Kubernetes 的性能:
sudo swapoff -a
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
完成之后,最好记得重启一下系统,然后给虚拟机拍个快照做备份,避免后续的操作失误导致重复劳动。
安装 kubeadm
在 Master 节点和 Worker 节点上都要安装
1、添加 kubeadm 的国内库
官方 Google Cloud 库可能网速慢下载不下来
cat <<EOF | sudo tee /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
exclude=kube*
EOF
2、安装、更新所需的软件包
# 安装所需的软件包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加 Kubernetes 软件包仓库
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
# 更新 yum 软件包索引
sudo yum update -y
3、安装 kubeadm, kubelet, 和 kubectl 指定版本(1.23.3)
sudo yum install -y kubelet-1.23.3 kubeadm-1.23.3 kubectl-1.23.3
4、查看版本
kubeadm version
kubectl version --client
5、标记 kubelet 包不自动更新
# 安装 yum-plugin-versionlock 插件
sudo yum install yum-plugin-versionlock
#使用命令 apt-mark hold ,锁定这三个软件的版本
sudo apt-mark hold kubeadm kubelet kubectl
#或者 将软件包添加到版本锁定列表中
sudo yum versionlock add kubeadm kubelet kubectl
安装 Master 节点
kubeadm 的用法非常简单,只需要一个命令 kubeadm init 就可以把组件在 Master 节点上运行起来,不过它还有很多参数用来调整集群的配置,可以用 -h 查看。
常用的 3 个参数:
- –pod-network-cidr,设置集群里 Pod 的 IP 地址段。
- –apiserver-advertise-address,设置 apiserver 的 IP 地址,对于多网卡服务器来说很重要(比如 VirtualBox 虚拟机就用了两块网卡),可以指定 apiserver 在哪个网卡上对外提供服务。
- –kubernetes-version,指定 Kubernetes 的版本号。
1、初始化kubernetes集群
指定了 Pod 的地址段是“10.244.0.0/16”,service的地址是 10.96.0.0/12 ,apiserver 的服务地址是“自己机器的ip”,Kubernetes 的版本号是“1.23.3”
kubeadm init \
--apiserver-advertise-address=本身的虚拟机ip \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.3 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
2、建立“.kube”目录
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
在本地建立一个“.kube”目录,然后拷贝 kubectl 的配置文件,你只要原样拷贝粘贴就行。
3、保存kubeadm join 信息
kubeadm join 172.16.*.*:6443 --token fnbir9.g81u885fcu8jvbji \
--discovery-token-ca-cert-hash sha256:77423363c190a976de43ebe4e06bf90e35fdf918bda7ac995392714f0895c9de
其他节点要加入集群必须要用指令里的 token 和 ca 证书,所以这条命令务必拷贝后保存好:
token默认只有24个小时,如果过期了或者忘了,可以重新获取加入集群的命令
kubeadm token create --print-join-command
4、检查 Kubernetes 集群的节点状态
kubectl version
kubectl get node
Master 节点的状态是“NotReady”,这是由于还缺少网络插件,集群的内部网络还没有正常运作。
安装 Flannel 网络插件
使用项目的“kube-flannel.yml”在 Kubernetes 里部署一下就好了。不过因为它应用了 Kubernetes 的网段地址,需要修改文件里的“net-conf.json”字段,把 Network 改成刚才 kubeadm 的参数 --pod-network-cidr 设置的地址段。
kube-flannel.yml文件地址
1、kube-flannel.yml内容
apiVersion: v1
kind: Namespace
metadata:
labels:
k8s-app: flannel
pod-security.kubernetes.io/enforce: privileged
name: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: flannel
name: flannel
namespace: kube-flannel
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: flannel
name: flannel
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- networking.k8s.io
resources:
- clustercidrs
verbs:
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: flannel
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-flannel
---
apiVersion: v1
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
kind: ConfigMap
metadata:
labels:
app: flannel
k8s-app: flannel
tier: node
name: kube-flannel-cfg
namespace: kube-flannel
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: flannel
k8s-app: flannel
tier: node
name: kube-flannel-ds
namespace: kube-flannel
spec:
selector:
matchLabels:
app: flannel
k8s-app: flannel
template:
metadata:
labels:
app: flannel
k8s-app: flannel
tier: node
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
containers:
- args:
- --ip-masq
- --kube-subnet-mgr
command:
- /opt/bin/flanneld
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: EVENT_QUEUE_DEPTH
value: "5000"
image: docker.io/flannel/flannel:v0.25.1
name: kube-flannel
resources:
requests:
cpu: 100m
memory: 50Mi
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
privileged: false
volumeMounts:
- mountPath: /run/flannel
name: run
- mountPath: /etc/kube-flannel/
name: flannel-cfg
- mountPath: /run/xtables.lock
name: xtables-lock
hostNetwork: true
initContainers:
- args:
- -f
- /flannel
- /opt/cni/bin/flannel
command:
- cp
image: docker.io/flannel/flannel-cni-plugin:v1.4.0-flannel1
name: install-cni-plugin
volumeMounts:
- mountPath: /opt/cni/bin
name: cni-plugin
- args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
command:
- cp
image: docker.io/flannel/flannel:v0.25.1
name: install-cni
volumeMounts:
- mountPath: /etc/cni/net.d
name: cni
- mountPath: /etc/kube-flannel/
name: flannel-cfg
priorityClassName: system-node-critical
serviceAccountName: flannel
tolerations:
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /run/flannel
name: run
- hostPath:
path: /opt/cni/bin
name: cni-plugin
- hostPath:
path: /etc/cni/net.d
name: cni
- configMap:
name: kube-flannel-cfg
name: flannel-cfg
- hostPath:
path: /run/xtables.lock
type: FileOrCreate
name: xtables-lock
修改net-conf.json:
如果不是10.244.0.0/16,net-conf.json修改成“自己设置的pod网段”:
net-conf.json: |
{
"Network": "自己设置的pod网段",
"Backend": {
"Type": "vxlan"
}
}
2、启动Flannel插件
#创建文件
touch kube-flannel.yml
#编辑文件,将修改过的内容copy进去
vim kube-flannel.yml
#生成插件pod
kubectl apply -f kube-flannel.yml
kube-flannel.yml默认就是“10.244.0.0/16”,可以直接使用下面命令:
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
3、查看Flannel插件是否正常运行
#查看DaemonSet是否正常运行
#如果kube-flannel-ds的副本数显示为1/1,则表示DaemonSet正在正常运行
kubectl get daemonset -n kube-system
#检查kube-flannel的Pod是否正常运行
#如果输出显示Pod的状态为Running,则表示kube-flannel插件正在正常运行。
kubectl get pods -n kube-system -l app=flannel
#检查kube-flannel的日志以查找任何错误
#查看日志是否显示任何错误或警告信息。
kubectl logs -n kube-system <kube-flannel-pod-name>
4、查看集群节点状态
kubectl get node
Master 节点的状态是“Ready”,表明节点网络也工作正常了
安装 Worker 节点
1、安装前置操作
把准备工作配置和kubeadm安装好
2、执行kubeadm join
只需要用之前拷贝的那条 kubeadm join 命令就可以了,用 sudo 来执行:
sudo \
kubeadm join 172.16.*.*:6443 --token fnbir9.g81u885fcu8jvbji \
--discovery-token-ca-cert-hash sha256:77423363c190a976de43ebe4e06bf90e35fdf918bda7ac995392714f0895c9de
3、查看节点状态
kubectl get node
发现还是NotReady状态
4、复制配置文件
远程复制
sudo scp -r root@*.*.*.*:/etc/kubernetes/admin.conf /etc/kubernetes/admin.conf
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
手动复制
mkdir -p $HOME/.kube
#把/etc/kubernetes/admin.conf文件copy到本机,再执行命令
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
再次查看节点状态,变成ready
安装Console
可以节点本身充当Console(就是不用单独安装)
1、安装kubectl
# 下载:
curl -LO https://dl.k8s.io/release/v1.23.3/bin/linux/arm64/kubectl
# 安装
sudo install kubectl /usr/local/bin/kubectl
# 从master节点复制文件
sudo scp stark@192.168.88.134:/etc/kubernetes/admin.conf /etc/kubernetes/admin.conf
2、 从master节点复制文件
远程复制
sudo scp -r root@*.*.*.*:/etc/kubernetes/admin.conf /etc/kubernetes/admin.conf
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
手动复制
mkdir -p $HOME/.kube
#把/etc/kubernetes/admin.conf文件copy到本机,再执行命令
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
测试集群
在console节点是执行kubectl run ,运行 Nginx 来测试一下:
kubectl run ngx --image=nginx:alpine
kubectl get pod -o wide
会发现,pod被调度到了work节点上运行