Contents

Ubuntu 22.04.3 LTS 安装Kubernetes 1.28单节点集群记录

前言

好久没写博客了,这三个月以来一直忙着学习k8s的知识,概念和名词是真的多。。。公司使用红帽提供的OpenShift平台,简单来说就是安全性更高,经过一点封装的k8s,然后我就负责在上面写deployment等manifest进行应用部署,而OpenShift本身则是系统团队负责搭建和维护的,不用应用运维团队关心。

就个人而言,这一年正好学习了很多分布式系统的知识,读了DDIA,啃过了MIT 6.824,实现了基于raft的分布式kv存储demo,最后这个项目甚至可以说就是k8s控制平面使用的etcd的原型了。事已至此,肯定是不满足于当下负责的云原生CICD工作的,更深入的理解k8s这门技术,是顺势而为且不得不做的事情。

最近换了新的笔记本,把第一次用工资购买的小新pro13给退役了,正好身边需要一台linux来装k8s进行个人学习(windows貌似也能装k8s,但估计会多出很多坑,不利于学习目标),那要不就把它刷成ubuntu,然后在上面装k8s吧,比买树莓派或者vps划算多了。

这篇博客主要就是记录在Ubuntu 22.04.3 LTS上安装kubernetes的过程,目前就这台笔记本单节点,后续估计也需要尝试拿其他机器做成多节点的,不然就没有用到k8s的核心能力了,在这里就先挖个坑吧。

用kubeadm安装集群

kubeadm是官方提供的kubernetes安装工具,当然第三方的工具也有,比如microk8s、k3s等,但出于学习的目的,我们就使用kubeadm吧,也不是特别复杂,基本按照官方文档,再google+chatgpt一下就能部署成功。

1. 安装Docker Engine

首先,一个k8s集群节点需要一个容器运行时(container runtime)来控制上面运行的容器,而实现了Container Runtime Interface,也就是CRI的软件都可以作为容器运行时,供k8s调用。因为我习惯使用docker,那么就使用docker engine作为CRI吧,这里是安装docker engine的文档。

2. 安装Cri-dockerd

然而由于docker engine并没有实现在他之后才提出的CRI标准,所以需要借助一个叫cri-dockerd的项目来作为适配器。按理说,docker engine使用containerd作为容器运行时,而containerd是实现CRI的,为什么还需要一个shim?在没有深入到项目去了解的情况下,我的理解是,我们希望实现的效果是k8s通过docker engine去操作containerd,而不是直接去控制containerd,所以需要docker engine去支持CRI。

3. 安装kubeadm

首先按照文档添加apt repo,然后使用apt来安装kubelet、kubeadm和kubectl

1
2
3
4
5
6
7
8
9
sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

4. 使用kubeadm init安装集群

接下来就可以使用kubeadm init <args> 安装k8s集群了,用几个args是必须要配置:

1
sudo kubeadm init --control-plane-endpoint="cp0.midk9t.com" --pod-network-cidr=10.244.0.0/16 --cri-socket="unix:///var/run/cri-dockerd.sock"

这里有三个配置项:

  • criSocket=unix:///var/run/cri-dockerd.sock 配置k8s使用我们cri-dockerd的socket与容器运行时通信,而不是默认值unix:///var/run/containerd/containerd.sock
  • podSunet=10.244.0.0/16 声明了集群内所有Pod使用的ip网段,这个ip段是我们后面使用的flannel cni所规定的
  • controlPlaneEndpoint=cp0.midk9t.com:6443 这配置了控制平面所有节点公用的通信端点,可以是域名或者ip,这里我使用了一个解析到localhost的域名

然后不出意外的话就部署成功啦:

接下来需要安装一个CNI(container network interface),让k8s可以在维护集群虚拟网络,这里我们选用前面提到的flannel:

1
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

最后使用kubectl cluster-info验证集群部署成功

由于目前只有ubuntu小新pro这台机器作为集群,所以需要应用的pod能被调度到control plane节点上:

1
kubectl taint node midk9t-lenovo-xiaoxinpro-13iml-2020  node-role.kubernetes.io/control-plane:NoSchedule-

默认情况下,control plane节点不允许跑应用的pod,这由taint机制来实现。

部署demo应用

成功在ubuntu上搭建集群后,我们来部署一个demo应用做最后验证:

1
kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1

验证部署成功:

安装kubernetes-dashboard

首先需要安装helm

1
2
3
4
5
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

然后通过helm安装kubernetes-dashboard

1
2
3
4
# Add kubernetes-dashboard repository
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
# Deploy a Helm Release named "kubernetes-dashboard" using the kubernetes-dashboard chart
helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kubernetes-dashboard

可以通过kubectl port-forward把pod暴露到ubuntu宿主机中

1
kubectl -n kubernetes-dashboard port-forward $kubernetes-dashboard-pod-name $hostport:8443

或者使用service暴露到宿主机中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
apiVersion: v1
kind: Service
metadata:
  name: dashboard-service
  namespace: kubernetes-dashboard
spec:
  type: NodePort
  selector:
    app.kubernetes.io/name: kubernetes-dashboard
  ports:
  	# 在pod中需要暴露的port
    - targetPort: 8443 
      # 集群内访问的port
      port: 8443
      # 暴露到宿主机的Port
      nodePort: 30443

接下来需要配置登录dashboard的权限,我们可以为dashboard创建一个service acount:

1
2
3
4
5
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard

然后给它bind到cluster-admin这个role上,注意生产环境需要更严格的RBAC控制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

最后使用kubectl -n kubernetes-dashboard create token admin-user生成对应的token,就能登录进去dashboard了

结尾挖坑

把这篇旨在以后复现时使用的笔记记下后,下一步计划就是把k8s的一个重要玩法,也就是我目前负责的工作——云原生CICD流水线给记录下来。希望能趁热打铁,尽快填坑!