0%

openeuler+docker+k8s

记录学习部署k8s过程中踩过的坑,下次部署有个参考

节点规划

1
2
3
4
5
k8s 1.20.2 + docker + flannel 0.20.2

node0 192.168.126.139 master 4GB 40GB
node1 192.168.126.140 slave 4GB 40GB
node2 192.168.126.141 slave 4GB 40GB

前置工作(所有节点)

  1. 修自定义主机名,即刻应用,以一个为例

    1
    2
    # hostnamectl set-hostname node1
    # sudo -i

    image-20241124234104685

  2. 整个顺手的文本编辑器,笔者这里选了nano

    1
    # yum install nano

    image-20241125000040548

  3. 配置主机名解析

    /etc/hosts是一个本地的静态文件,用于将主机名映射到 IP 地址。当系统需要解析主机名时,首先查找该文件。如果找到匹配项,则使用该 IP 地址,而不通过 DNS 服务器

    1
    # nano /etc/hosts

    添加如下内容

    image-20241125000357924

  4. 关闭swap,selinux,禁用防火墙

    k8s运行需要禁用swap(交换空间)更好的进行容器内存管理。swapoff -a关闭swap。/etc/fstab 用于定义系统启动时自动挂载的文件系统、分区、交换空间(swap)等信息,sed -ri 's/.*swap.*/#&/' /etc/fstab注释掉其中关于swap的信息。setenforce 0禁用 SELinux 的强制安全策略避免k8s遇到权限问题。systemctl stop firewalld && systemctl disable firewalld关闭并禁用防火墙

    1
    2
    3
    4
    # swapoff -a
    # sed -ri 's/.*swap.*/#&/' /etc/fstab
    # setenforce 0
    # systemctl stop firewalld && systemctl disable firewalld

    image-20241125001106539

  5. 启用内核模块

    1. **modprobe overlay**:加载 Overlay 文件系统(用于容器运行时)内核模块,支持容器文件系统。

    2. **modprobe br_netfilter**: 加载网络桥接过滤模块,用于容器和主机之间的流量控制。

    1
    2
    # modprobe overlay
    # modprobe br_netfilter
  6. 网络转发常用配置

    1. net.bridge.bridge-nf-call-iptables = 1
      部署容器时,容器网络通常会与宿主机的网络进行桥接。在处理跨越网络桥接的数据包时,调用 iptables 进行包过滤。避免容器间的流量被误拦截。
    2. net.ipv4.ip_forward = 1
      启用 IP 转发,使主机能够转发网络流量,保证不同节点间的 Pod 可以相互通信。
    3. net.bridge.bridge-nf-call-ip6tables = 1
      与第一个参数类似,关于ipv6的。
    4. vm.swappiness=0
      设置虚拟内存的交换行为,swappiness 控制内核决定什么时候将内存页面交换到硬盘上。swappiness=0 表示内核尽量避免交换,优先使用物理内存,避免频繁的内存交换。
    1
    2
    3
    4
    5
    6
    cat > /etc/sysctl.d/kubernetes.conf <<EOF
    net.bridge.bridge-nf-call-iptables = 1
    net.ipv4.ip_forward = 1
    net.bridge.bridge-nf-call-ip6tables = 1
    vm.swappiness=0
    EOF

    生效规则

    1
    # sysctl -p /etc/sysctl.d/kubernetes.conf

docker安装(所有节点)

1
# dnf install -y docker

image-20241125001725376

开机自启

1
# systemctl enable docker && systemctl start docker

查看版本,确定安装成功

1
# docker --version

image-20241125002237232

网络组件配置准备(所有节点)

Flannel 是 Kubernetes 的网络插件,用于为集群中的容器提供跨节点的网络通信,常用的还有calico,flannel简单易用,calico功能更强大

1
2
# mkdir /opt/yaml/
# nano /opt/yaml/kube-flannel.yaml

内容如下,注意这里的镜像是国外的,可以换成国内的,也可以给docker配置代理

另外,如果使用其他版本的flannel,可以直接去其github仓库下载对应yml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
---
kind: Namespace
apiVersion: v1
metadata:
name: kube-flannel
labels:
pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
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
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-flannel
labels:
tier: node
app: flannel
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"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-flannel
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
hostNetwork: true
priorityClassName: system-node-critical
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni-plugin
#image: flannelcni/flannel-cni-plugin:v1.1.2 #for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.2
command:
- cp
args:
- -f
- /flannel
- /opt/cni/bin/flannel
volumeMounts:
- name: cni-plugin
mountPath: /opt/cni/bin
- name: install-cni
#image: flannelcni/flannel:v0.20.2 #for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
#image: flannelcni/flannel:v0.20.2 #for ppc64le and mips64le (dockerhub limitations may apply)
image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.2
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN", "NET_RAW"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: EVENT_QUEUE_DEPTH
value: "5000"
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
- name: xtables-lock
mountPath: /run/xtables.lock
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni-plugin
hostPath:
path: /opt/cni/bin
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
- name: xtables-lock
hostPath:
path: /run/xtables.lock
type: FileOrCreate

安装cni并配置到flannel的默认路径

CNI(Container Network Interface)是容器网络接口的缩写,为容器提供网络配置和管理功能,包括为容器分配 IP 地址、设置网络策略、路由流量等

1
# dnf install -y containernetworking-plugins

image-20241125004635626

copy cni配置到flannel默认读取的目录

1
2
# mkdir -p /opt/cni/bin
# cp /usr/libexec/cni/* /opt/cni/bin/

image-20241125005121394

依赖组件conntrack

conntrack是一种用户空间工具,用于操作和管理 netfilter跟踪连接的状态,此处用于处理容器间的网络连接

1
# dnf install -y conntrack

image-20241125013731754

kubelet开启自启

1
# systemctl enable kubelet.service && systemctl start kubelet.service

image-20241125013919560

K8s主节点

  1. 安装组件
1
# dnf install -y kubernetes-kubeadm kubernetes-kubelet kubernetes-master

image-20241127000337927

  1. 初始化控制平面
1
2
3
4
kubeadm init --apiserver-advertise-address=192.168.126.139 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.20.2 \
--service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16

这里笔者配置了附录的docker代理,如果没有,可以考虑在这里直接指定国内源,比如下面这种方式

1
kubeadm init --kubernetes-version=1.20.2 --apiserver-advertise-address=192.168.126.139 --cri-socket=/var/run/isulad.sock --image-repository=registry.aliyuncs.com/google_containers --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --v=5

输出以下信息初始化成功

image-20241125121721414

  1. 保存join命令在从节点运行
1
2
kubeadm join 192.168.126.139:6443 --token dokaoz.sfrch50yf43iubsz \
--discovery-token-ca-cert-hash sha256:44507460bd82478c7447280af83889673149a76a3a24f75b7e828e9b56a69dc4
  1. 配置kubectl

/etc/profile 是一个系统级的 shell 配置文件,通常用于设置所有用户的环境变量和启动时执行的系统命令

1
# nano /etc/profile

最后面添加

1
export KUBECONFIG=/etc/kubernetes/admin.conf

应用改变

1
# source /etc/profile
  1. 查看节点状态
1
kubectl get nodes

此时提示NotReady,是因为网络插件未配置(这里笔者已经在从节点执行了1. 2步骤加入了集群)

image-20241125122642008

  1. 配置flannel,之前导入的配置直接应用即可(实际上部署完发现从节点不需要使用kubectl apply -f /opt/yaml/kube-flannel.yaml配置flannel,也可以正常使用网络,原因还没搞明白,坑++)
1
kubectl apply -f /opt/yaml/kube-flannel.yaml

image-20241125123047278

  1. 可以使用如下命令查看flannel部署进度和集群状态
1
2
kubectl get nodes
kubectl get pods -n kube-flannel

安装完成后状态如下所示

image-20241125123259156

K8s从节点

  1. 安装组件
1
[root@node0 ~]# dnf install -y kubernetes-kubeadm kubernetes-kubelet kubernetes-node

image-20241125010758059

  1. 加入集群
1
2
kubeadm join 192.168.126.139:6443 --token dokaoz.sfrch50yf43iubsz \
--discovery-token-ca-cert-hash sha256:44507460bd82478c7447280af83889673149a76a3a24f75b7e828e9b56a69dc4

显示如下信息加入成功

image-20241125121943414

集群测试

此处选择nginx进行测试创建并暴露端口

【来自GPT】

  1. kubectl create deployment nginx --image=nginx

**kubectl create deployment**:创建一个新的部署(Deployment)。Deployment 是 Kubernetes 中管理应用生命周期的资源对象,它定义了应用的期望状态(例如 Pod 数量、副本、容器镜像等)。

**nginx**:指定部署的名称。这个名字会被用作创建的 Deployment 资源的标识。

**--image=nginx**:指定容器使用的镜像。这里指定的是 nginx 镜像,意味着创建的 Pod 中将运行 Nginx Web 服务器。这个镜像是从 Docker Hub 中拉取的官方 Nginx 镜像。

  1. kubectl expose deployment nginx --port=80 --type=NodePort

**kubectl expose**:该命令用于暴露一个服务,使其可以通过网络访问。通常,Kubernetes 使用 Service 资源来暴露应用,使其在集群内或集群外可访问。

**deployment nginx**:暴露的对象是之前创建的 nginx Deployment。意味着这个命令会创建一个 Service,将 nginx 部署暴露出去。

**--port=80**:指定暴露服务的端口号,80 是 Nginx 的默认 HTTP 服务端口。这个端口将用于访问 Nginx Web 服务器。

**--type=NodePort**:指定服务暴露的类型为 NodePortNodePort 类型的服务会在每个节点上打开一个端口,使集群外部的用户可以通过节点的 IP 地址和指定的端口号来访问服务。Kubernetes 会自动为该服务分配一个端口,默认范围是 30000 到 32767。

1
2
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort

查询当前集群中 PodService 状态,查看是否运行成功

1
kubectl get pod,svc

image-20241125123555734

查看pod运行的节点可以用

1
kubectl get pods -o wide

在从节点查看,可以发现这里自动部署在在192.168.126.141节点上

image-20241125123926938

所有节点均可访问nginx服务器

1
2
3
192.168.126.140:32641
192.168.126.141:32641
192.168.126.142:32641

比如主节点

image-20241125124035333

扩展副本

1
kubectl scale deployment nginx --replicas=3

附录-常见问题

静态ip配置

1
2
# cd /etc/sysconfig/network-scripts
# nano ifcfg-ens33

笔者文件如下

image-20241127201159694

对于要设置的静态ip所属子网,可以在宿主机使用ipconfig命令查询,笔者使用NAT链接虚拟机和宿主机,这里是VMnet 8网络,网关一般默认为xxx.xxx.xxx.2,DNS照搬即可。

更改如下选项即可,黄色由dhcp改为static,红色为新加的。

image-20241127200905390

之后重启网卡即可生效设置

1
# systemctl reload NetworkManager

重启后已经可以访问网络

image-20241127202015718

实际上有时候管用,有时候不管用,原因笔者还没弄明白,坑++,这里选择粗暴的重启节点

1
# reboot

dnf太慢,挂个终端代理

1
2
[root@node0 ~]# export http_proxy="http://192.168.1.104:7890"
[root@node0 ~]# export https_proxy="http://192.168.1.104:7890"

docker配置代理以访问国外镜像源

1
2
3
4
5
6
[root@node0 ~]# sudo mkdir /etc/systemd/system/docker.service.d
[root@node0 ~]# cd /etc/systemd/system/docker.service.d
[root@node0 docker.service.d]# nano proxy.conf
[root@node0 docker.service.d]# sudo systemctl daemon-reload
[root@node0 docker.service.d]# sudo systemctl restart docker
[root@node0 docker.service.d]# docker info

proxy.conf内容为

1
2
3
[Service] 
Environment="HTTP_PROXY=http://192.168.1.104:7890"
Environment="HTTPS_PROXY=http://192.168.1.104:7890"

image-20241125013251266

初始化时警告,主节点socat缺失

1
[WARNING FileExisting-socat]: socat not found in system path

补一个即可

1
yum install -y socat

cgroups不一致

初始化时警告docker cgroups与推荐不一致,在

“/etc/docker/daemon.json”添加

1
"exec-opts": ["native.cgroupdriver=systemd"]

之后重启docker和守护进程即可,查看docker info可以看到当前的cgroups

1
2
3
4
[root@lab2 docker]# nano /etc/docker/daemon.json
[root@lab2 docker]# sudo systemctl daemon-reload
[root@lab2 docker]# sudo systemctl restart docker
[root@lab2 docker]# docker info

完整文件示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com",
"https://ccr.ccs.tencentyun.com"
]
}

如果想查看k8s的cgroups

1
nano /var/lib/kubelet/config.yaml

删除配置以重新初始化

下面的命令可以在所有节点删除现有配置

1
sudo kubeadm reset -f

此命令不会删除docker,k8s组件等镜像,只会删除初始化的影响

主节点需要额外执行

1
sudo rm -rf /etc/kubernetes

从节点加入提示节点已出现

问题:

1
2
3
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
error execution phase kubelet-start: a Node with name "lab2" and status "Ready" already exists in the cluster. You must delete the existing Node or change the name of this new joining Node
To see the stack trace of this error execute with --v=5 or higher

方法(主节点)

1
kubectl delete node lab2

然后从节点重新加入

flannel部署出错删除配置

1
2
3
4
5
6
7
[root@lab2 ~]# kubectl delete -f /opt/yaml/kube-flannel.yaml
namespace "kube-flannel" deleted
clusterrole.rbac.authorization.k8s.io "flannel" deleted
clusterrolebinding.rbac.authorization.k8s.io "flannel" deleted
serviceaccount "flannel" deleted
configmap "kube-flannel-cfg" deleted
daemonset.apps "kube-flannel-ds" deleted

删除测试时创建的nginx服务

删除 Deployment 和 Pod

1
kubectl delete deployment nginx

删除对应的 Service

1
kubectl delete svc nginx

确认资源已被删除

1
kubectl get pod,svc

过程中的k8s命令&&从节点配置kubectl

kubelet:在 每个节点 上运行,负责管理节点上的容器和 Pod。

kubeadm:在 主节点 上用于初始化集群,在 从节点 上用于加入集群。

kubectl:在 任意节点 上运行,用于操作和管理集群。

上述过程中kubectl只部署在了主节点上,从节点调用相关指令有如下错误

1
2
[root@lab2 ~]# kubectl apply -f /opt/yaml/kube-flannel.yaml
The connection to the server localhost:8080 was refused - did you specify the right host or port?

如果想在从节点执行这些指令时,用不了,可以复制主节点的配置即可

1
2
3
kubectl apply -f /opt/yaml/kube-flannel.yaml
kubectl get nodes
kubectl get pods -n kube-flannel

具体操作

查看从节点配置:

1
2
[root@lab2 ~]# ls ~/.kube/config
ls: 无法访问 '/root/.kube/config': No such file or directory

没有找到 ~/.kube/config 文件,说明 kubectl 配置文件还没有正确设置。

解决步骤:
在主节点上获取 kubeconfig 文件:

1
sudo cat /etc/kubernetes/admin.conf

复制配置文件到工作节点

将输出的配置文件内容复制到工作节点上的 ~/.kube/config 文件

没有则新建

1
2
[root@lab2 ~]# mkdir -p ~/.kube
[root@lab2 ~]# nano ~/.kube/config

然后就好了

1
2
3
4
5
[root@lab2 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
lab0 Ready control-plane,master 32h v1.20.2
lab2 Ready <none> 18m v1.20.2
lab3 Ready <none> 27m v1.20.2

参考文章

K8s+iSulad环境部署 | openEuler文档 | openEuler社区 | v22.03_LTS_SP3

openEuler 部署Kubernetes(K8s)集群_《openeuler kubernetes 集群部署指南》-CSDN博客

K8s+iSulad环境部署 | openEuler文档 | openEuler社区 | v22.03_LTS_SP3

docker国内镜像源配置及走代理设置_docker镜像代理-CSDN博客

It seems like the kubelet isn‘t running or healthy_it seems like the kubelet isn’t running or healthy-CSDN博客