- 操作系统:Ubuntu 24.04.1 LTS
- 容器运行时:containerd://1.7.12
# 此内容为部署完的k8s集群信息
root@ubuntu-k8s:~# kubectl get node -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ubuntu-k8s Ready control-plane 105s v1.31.1 172.8.8.16 <none> Ubuntu 24.04.1 LTS 6.8.0-47-generic containerd://1.7.12
1. 安装容器运行时
1. 安装containerd,并配置开机自启动
apt install containerd #默认同时安装runc
apt install ipvsadm # 安装ipvs
2. 生成containerd配置文件
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
1. 配置 systemd cgroup 驱动
结合 runc 使用 systemd cgroup 驱动,在 /etc/containerd/config.toml 中设置:
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
2. 修改sandbox_image镜像地址
sandbox_image = "k8s.lixx.cn/pause:3.10"
重启containerd
systemctl restart containerd
systemctl enable containerd
2. 安装前配置
1. 编辑hosts文件,添加本机host地址
root@ubuntu-k8s:~# cat /etc/hosts
127.0.0.1 localhost
172.8.8.16 ubuntu-k8s
2. 手动启用 IPv4 数据包转发
# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF
# 应用 sysctl 参数而不重新启动
sudo sysctl --system
# 验证
sysctl net.ipv4.ip_forward
3. 关闭防火墙
ufw disable
sudo systemctl stop apparmor
sudo systemctl disable apparmor
4. 关闭swap
如果 kubelet 未被正确配置使用交换分区,则你必须禁用交换分区。 例如,sudo swapoff -a 将暂时禁用交换分区。要使此更改在重启后保持不变,请确保在如 /etc/fstab、systemd.swap 等配置文件中禁用交换分区,具体取决于你的系统如何配置
修改/etc/fstab配置文件,注释最后一行(和swap有关的一行)并重启操作系统。
3. 安装 k8s
1. 配置apt源,下载 kubelet kubeadm kubectl
如果下载慢可以更换阿里云镜像源或清华镜像源,修改地址即可。
以下指令适用于 Kubernetes 1.31.
- 更新
apt
包索引并安装使用 Kubernetesapt
仓库所需要的包:sudo apt-get update # apt-transport-https 可能是一个虚拟包(dummy package);如果是的话,你可以跳过安装这个包 sudo apt-get install -y apt-transport-https ca-certificates curl gpg
- 下载用于 Kubernetes 软件包仓库的公共签名密钥。所有仓库都使用相同的签名密钥,因此你可以忽略URL中的版本:
# 如果 `/etc/apt/keyrings` 目录不存在,则应在 curl 命令之前创建它,请阅读下面的注释。 # sudo mkdir -p -m 755 /etc/apt/keyrings curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
说明:
在低于 Debian 12 和 Ubuntu 22.04 的发行版本中,/etc/apt/keyrings
默认不存在。 应在 curl 命令之前创建它。
- 添加 Kubernetes
apt
仓库。 请注意,此仓库仅包含适用于 Kubernetes 1.31 的软件包; 对于其他 Kubernetes 次要版本,则需要更改 URL 中的 Kubernetes 次要版本以匹配你所需的次要版本 (你还应该检查正在阅读的安装文档是否为你计划安装的 Kubernetes 版本的文档)。# 此操作会覆盖 /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.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
- 更新
apt
包索引,安装 kubelet、kubeadm 和 kubectl,并锁定其版本:sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl # 查看各个组件版本 kubectl version --client kubelet --version kubeadm version systemctl restart kubelet systemctl enable kubelet
2. 配置crictl
- 创建 /etc/crictl.yaml 文件
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 2
debug: false
pull-image-on-create: false
EOF
- 验证
root@ubuntu-k8s:~# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID POD
3. kubeadm初始化
- 使用本人自建的镜像仓库,或者使用阿里云的
registry.aliyuncs.com/google_containers
# 查看要下载哪些镜像
kubeadm config images list
# 执行
kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address 172.8.8.16 --image-repository k8s.lixx.cn
- apiserver-advertise-address: 服务器地址
- image-repository:用阿里云镜像快速下载
- 执行成功结果如下
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
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/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:
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 172.8.8.16:6443 --token 8on0q5.vhcyalu0mognziwd \
--discovery-token-ca-cert-hash sha256:3360d57313f4a51f2ce3896a2af503f41fdcd2342a2d8fd74e07522945db922b
#执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
4. 安装cni插件 flannel
- 此时coredns pod状态异常,需要安装cni插件。官网:https://github.com/flannel-io/flannel#deploying-flannel-manually
wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
- 无法访问时,使用以下文件进行配置。自行创建yml文件即可。docker.io已经替换成了hub.lixx.cn
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
---
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",
"EnableNFTables": false,
"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: hub.lixx.cn/flannel/flannel:v0.25.7
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: hub.lixx.cn/flannel/flannel-cni-plugin:v1.5.1-flannel2
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: hub.lixx.cn/flannel/flannel:v0.25.7
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
- 执行前:
root@ubuntu-k8s:~# kubectl get po -owide -A
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-7d54cd9f-l4m9d 0/1 Pending 0 8s <none> <none> <none> <none>
kube-system coredns-7d54cd9f-vv7dl 0/1 Pending 0 8s <none> <none> <none> <none>
kube-system etcd-ubuntu-k8s 0/1 Running 1 14s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-apiserver-ubuntu-k8s 1/1 Running 1 16s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-controller-manager-ubuntu-k8s 0/1 Running 0 14s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-proxy-dvx5g 1/1 Running 1 (6s ago) 8s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-scheduler-ubuntu-k8s 1/1 Running 1 15s 172.8.8.16 ubuntu-k8s <none> <none>
- 执行:
root@ubuntu-k8s:~# kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
serviceaccount/flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds createdspan
root@ubuntu-k8s:~# kubectl get po -owide -A
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-flannel kube-flannel-ds-bc7jz 1/1 Running 0 22s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system coredns-7d54cd9f-l4m9d 1/1 Running 0 74s 10.244.0.3 ubuntu-k8s <none> <none>
kube-system coredns-7d54cd9f-vv7dl 1/1 Running 0 74s 10.244.0.2 ubuntu-k8s <none> <none>
kube-system etcd-ubuntu-k8s 1/1 Running 1 80s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-apiserver-ubuntu-k8s 1/1 Running 1 82s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-controller-manager-ubuntu-k8s 1/1 Running 0 80s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-proxy-dvx5g 1/1 Running 1 (72s ago) 74s 172.8.8.16 ubuntu-k8s <none> <none>
kube-system kube-scheduler-ubuntu-k8s 1/1 Running 1 81s 172.8.8.16 ubuntu-k8s <none> <none>
5. pod service 测试
去除节点上的污点,允许pod调度到该节点
kubectl taint nodes ubuntu-k8s node-role.kubernetes.io/control-plane:NoSchedule-
pod yaml:
root@ubuntu-k8s:~# cat simple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app.kubernetes.io/name: MyApp
spec:
containers:
- name: nginx
image: hub.lixx.cn/library/nginx:1.14.2
ports:
- containerPort: 80
service yaml:
root@ubuntu-k8s:~# cat my-service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
执行,并查看结果:
kubectl apply -f simple-pod.yaml
kubectl apply -f my-service.yaml
root@ubuntu-k8s:~# kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 52s 10.244.0.4 ubuntu-k8s <none> <none>
root@ubuntu-k8s:~# kubectl get svc -owide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5m50s <none>
my-service ClusterIP 10.98.96.56 <none> 80/TCP 12s app.kubernetes.io/name=MyApp
# curl pod ip 查看结果:
root@ubuntu-k8s:~# curl 10.244.0.4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</body>
</html>
# curl service ip 查看结果:
root@ubuntu-k8s:~# curl 10.98.96.56
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</body>
</html>
附
问题排错
systemctl status kubelet
journalctl -xeu kubelet
查看service cidr
kubectl cluster-info dump | grep service-cluster-ip-range
评论