截止20220708日靠谱的k8s环境部署流程

宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述截止20220708日靠谱的k8s环境部署流程相关的知识,希望能为你提供帮助。


部署k8s环境的时候折腾了好一阵,出现各种问题,这里自己整理一个记录。
1. 准备3台机器,2台其实也可以,但是为了体现k8s集群管理能力,最好还是3台。
vim /etc/hosts
加入如下配置
192.168.2.2 k8s-master
192.168.2.6 k8s-node
192.168.2.30 k8s-node2
不要问为什么node1没有,node2是后加的,没改hosts。
2. 设置各台主机名称,对应设置,别瞎搞
hostnamectl --static set-hostname k8s-master
hostnamectl --static set-hostname k8s-node
hostnamectl --static set-hostname k8s-node2
3. 安装各种依赖

yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git

git非必须
4. 设置防火墙
关闭firewalld,切换iptables。要用iptables的一些路由功能,一般系统里面都带,其实根据需要自行判断处理。只要确保firewalld关闭,一般就可以。
systemctl stop firewalld & & systemctl disable firewalld

yum -y install iptables-services & & systemctl start iptables & & systemctl enable iptables & & iptables -F & & service iptables save

5. 关闭selinux
swapoff -a & & sed -i / swap / s/^$/#\\1/g /etc/fstab

setenforce 0 & & sed -i s/^SELINUX=.*/SELINUX=disabled/ /etc/selinux/config

6. 调整内核参数,针对k8s配置
cat > kubernetes.conf < < EOF

net.bridge.bridge-nf-call-iptables=1

net.bridge.bridge-nf-call-ip6tables=1

net.ipv4.ip_forward=1

net.ipv4.tcp_tw_recycle=0

vm.swappiness=0

vm.overcommit_memory=1

vm.panic_on_oom=0

fs.inotify.max_user_instances=8192

fs.inotify.max_user_watches=1048576

fs.file-max=52706963

fs.nr_open=52706963

net.ipv6.conf.all.disable_ipv6=1

net.netfilter.nf_conntrack_max=2310720

EOF

cp kubernetes.conf /etc/sysctl.d/kubernetes.conf

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

7. 关闭系统不用的一些服务
systemctl stop postfix & & systemctl disable postfix
8. 配置日志(可选)
systemd-journald 用于检索 systemd 的日志,是 systemd 自带的日志系统。
设置rsyslogd 和systemd journald
mkdir /var/log/journal

mkdir /etc/systemd/journald.conf.d

cat > /etc/systemd/journald.conf.d/99-prophet.conf < < EOF

[Journal]

Storage=persistent

Compress=yes

SyncIntervalSec=5m

RateLimitInterval=30s

RateLimitBurst=1000

SystemMaxUse=10G

SystemMaxFileSize=200M

MaxRetentionSec=2week

ForwardToSyslog=no

EOF

systemctl restart systemd-journald

9. 升级linux内核版本(重点)
之前多次尝试部署各种错误,疑似改问题导致,建议更新一下。测试环境CentOS7.8,默认内核3.10,升级后5.4。如下:

  查看
[root@ecs-k8s-work2 ~]# cat /proc/version
Linux version 3.10.0-1160.25.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Wed Apr 28 21:49:45 UTC 2021

3.10版本,需要升级内核。
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm

  yum --enablerepo=elrepo-kernel install -y kernel-lt

grub2-set-default CentOS Linux (5.4.204-1.el7.elrepo.x86_64) 7 (Core)
这里就是修改下启动项名称,为了后期方便运维,注意具体版本号自行修改。
查看版本号
awk -F\\ $1=="menuentry " print i++ " : " $2 /etc/grub2.cfg

重启服务器
reboot
重启后确认下版本
[root@k8s-node2 ~]# grub2-editenv list
saved_entry=CentOS Linux (5.4.204-1.el7.elrepo) 7 (Core)
[root@k8s-node2 ~]# cat /proc/version
Linux version 5.4.204-1.el7.elrepo.x86_64 (mockbuild@Build64R7) (gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)) #1 SMP Tue Jul 5 16:32:13 EDT 2022

10. 配置ipvs
kube-proxy 开启ipvs的前置条件
modprobe br_netfilter
cat > /etc/sysconfig/modules/ipvs.modules < < EOF

#!/bin/bash

modprobe -- ip_vs

modprobe -- ip_vs_rr

modprobe -- ip_vs_wrr

modprobe -- ip_vs_sh

modprobe -- nf_conntrack

EOF

chmod 755 /etc/sysconfig/modules/ipvs.modules & & bash /etc/sysconfig/modules/ipvs.modules & & lsmod | grep -e ip_vs -e nf_conntrack


  注意:如果Linux内核更新版本linux kernel > = 4.19,使用nf_conntrack  代替nf_conntrack_ipv4
这里我们升级了内核,所以去掉ipv4.
现在云平台多支持ipv6了,所以建议升级内核,一方面为后期支持ipv6做准备,一方面避免由于平台网络设置的各种问题,导致k8s无法用。
11. 安装docker
yum install -y yum-utils device-mapper-persistent-data lvm2

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

yum update -y & & yum install -y docker-ce

yum update 记得执行,不然各种坑
装完重启
reboot
重启后发现内核被改回来了

  记得重置内核
grub2-set-default CentOS Linux (5.4.204-1.el7.elrepo.x86_64) 7 (Core)    & & reboot
启动docker
systemctl start docker

systemctl enable docker

修改配置文件
mkdir /etc/docker
cat > /etc/docker/daemon.json < < EOF



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

"log-driver":"json-file",

"log-opts":

"max-size":"100m"

,

"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]



EOF

重启docker
systemctl daemon-reload & & systemctl restart docker & & systemctl enable docker
注意,这里一方面修改docker默认镜像仓库地址,一方面修改驱动为systemd,k8s需要。
12. 安装k8s相关组件
创建配置文件
cat < < EOF > /etc/yum.repos.d/kubernetes.repo

[kubernetes]

name=Kubernetes

baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64

enabled=1

gpgcheck=0

repo_gpgcheck=0

gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg

http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

EOF

安装beadm、kubectl和kubelet
目前选择的是1.18.17较稳定版本。
注意,1.24版本后,改动较大,安装方式完全颠覆,这里需要制定版本号进行安装。
yum -y install kubeadm-1.18.17 kubectl-1.18.17 kubelet-1.18.17
设置启动开机自启kubelet服务
systemctl enable kubelet
-------------------------------------------------------------------------------------------------
上面说明,需要在每一个k8s的节点上执行。
-------------------------------------------------------------------------------------------------
13. 初始化k8s-master
在k8s-master节点执行
将kubeadm配置输出到kubeadm-config.yaml
kubeadm config print init-defaults > kubeadm-config.yaml
注意生成的配置文件是默认配置文件,并非当前配置,仅为方便修改配置文件。
打开kubeadm-config.yaml,并修改相关配置
vi kubeadm-config.yaml
改ip,advertiseAddress: 192.168.2.2 (主节点ip)
改kubernetes版本,kubernetesVersion: v1.18.17
添加,dnsDomain: cluster.local下一行添加(注意缩进,不可用tab,一般为2个或4个空格)
podSubnet: "10.244.0.0/16" (flannel网络最好不要改这个子网,不同网络插件有些区别)
imageRepository改为如下地址,国内阿里云镜像,可以解决下载不到国外镜像的问题:
imageRepository: registry.aliyuncs.com/google_containers
文档最后添加
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
    SupportIPVSProxyMode: true
mode: ipvs
完整配置文件(仅供参考)
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.2.2
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager:
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.18.17
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
scheduler:
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs

执行kubeadm初始化
#v1.15.1版本使用如下命令
kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs | tee kubeadm-init.log
#v1.15.1以上版本使用如下命令,此时最新版本为v1.18.17
kubeadm init --image-repository=registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16 --kubernetes-version=v1.18.17 --upload-certs | tee kubeadm-init.log
 
注意:不同版本配置和一些命令是有区别的,别随便扒拉一个手册就copy执行。
执行成功的话,会有提示。
执行如下语句
mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config

必须要执行,否则无法使用!!!
如果执行过cubeadm reset,记得要删除这几个目录(里面包含配置),不然执行init的时候会报错。
如果想要移除节点,不要直接在节点上面执行reset,要现在master上面执行
kubectl delete node < node name>
然后再在对应节点上执行reset方法,移除k8s相关配置。
这里记得几下控制台输出的join的方法,示例如下
kubeadm join 192.168.2.2:6443 --token kwysq2.4gs7kg51al4o3r2w \\
--discovery-token-ca-cert-hash sha256:97a1364e6468fcda1641f0c82c5fd932abea3248b0b9efe3e46859e1611042bf

后面子节点加入k8s集群需要使用。如果没记下来,如果忘了,好吧,忘了也能重新获取一下,在master执行:
??kubeadm token create --print-????join????-command??
然后在生成后的结果上加上 --control-plane 参数
14. 整理master工作区文件
创建install-k8s文件夹,将安装过程中的文件进行整理
mkdir install-k8s
mv kubeadm-init.log kubeadm-config.yaml install-k8s/
cd install-k8s/
mkdir core
将kubeadm-init.log kubeadm-config.yaml移动到core目录下
mv * core/
最后将安装文件放到usr/local文件夹下面
mv install-k8s/ /usr/local/
查看k8s日志
vi /usr/local/install-k8s/kubeadm-init.log
 
15. 安装网络插件flannel
k8s是托管的一堆容器,当然他自己有重新划分了一下pod,service什么的,但是终归是基于docker容器化来实现的,所以就牵扯到容器间的网络管理。flannel是基础网络管理插件,他可以支持容器自动获取ip(听起来有点low),但是不支持网络策略(就是流量控制、转发之类的规则)。
一般来说,建议在子节点加入主节点前安装网络插件,比较不容易出问题。
在install-k8s目录下面创建plugin文件夹,在plugin文件夹下面创建flannel文件夹
mkdir plugin
cd plugin
mkdir flannel
cd flannel
拉取yml配置文件
wget  ??https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml??
kubectl create -f kube-flannel.yml
这里很可能被墙导致拉取不到文件,怎么说呢,科学上网,自己打开配置文件复制到本地吧,注意格式。我这里给出一个截止2022年7月8日的一个自用配置。
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp.flannel.unprivileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
privileged: false
volumes:
- configMap
- secret
- emptyDir
- hostPath
allowedHostPaths:
- pathPrefix: "/etc/cni/net.d"
- pathPrefix: "/etc/kube-flannel"
- pathPrefix: "/run/flannel"
readOnlyRootFilesystem: false
# Users and groups
runAsUser:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
fsGroup:
rule: RunAsAny
# Privilege Escalation
allowPrivilegeEscalation: false
defaultAllowPrivilegeEscalation: false
# Capabilities
allowedCapabilities: [NET_ADMIN, NET_RAW]
defaultAddCapabilities: []
requiredDropCapabilities: []
# Host namespaces
hostPID: false
hostIPC: false
hostNetwork: true
hostPorts:
- min: 0
max: 65535
# SELinux
seLinux:
# SELinux is unused in CaaSP
rule: RunAsAny
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
rules:
- apiGroups: [extensions]
resources: [podsecuritypolicies]
verbs: [use]
resourceNames: [psp.flannel.unprivileged]
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
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-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
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-system
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.0 for ppc64le and mips64le (dockerhub limitations may apply)
image: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0
command:
- cp
args:
- -f
- /flannel
- /opt/cni/bin/flannel
volumeMounts:
- name: cni-plugin
mountPath: /opt/cni/bin
- name: install-cni
#image: flannelcni/flannel:v0.18.1 for ppc64le and mips64le (dockerhub limitations may apply)
image: rancher/mirrored-flannelcni-flannel:v0.18.1
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.18.1 for ppc64le and mips64le (dockerhub limitations may apply)
image: rancher/mirrored-flannelcni-flannel:v0.18.1
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
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

16. 子节点加入集群
kubeadm join 192.168.2.2:6443 --token kwysq2.4gs7kg51al4o3r2w \\
--discovery-token-ca-cert-hash sha256:97a1364e6468fcda1641f0c82c5fd932abea3248b0b9efe3e46859e1611042bf

这个要用各自系统生成的脚本加入,里面有token和证书,不要傻乎乎直接复制粘贴执行。
在master节点执行
kubectl get nodes 

如果都是ready,则安装正常。注意,节点加入后,要等一会flannel等相关pod创建并初始化完成才会ready。
同时,看一下pod情况
kubectl get pods -A 查看所有命名空间下的pod

 

  上面是正常的效果图。
如果flannel-ds节点error,或者节点一直没有变成Running,说明由错误。自己查看logs进行处理
kubectl logs kube-flannel-ds-xhbsx -n kube-system

  不过这里面的水就深了,真想解决,科学上网看吧,百度啥的是没啥用的。
-----------------------------------------------------------------------------
至此k8s集群安装完成
-----------------------------------------------------------------------------
17. 安装Helm
Helm相当于linux环境下的yum包管理工具。
helm是一k8s中的一个命令行客户端工具,helm是tiller的客户端,tiller是一个守护进程,接收helm的请求,helm把请求交给tiller,tiler和apiserver交互,由apiserver负责完成创建,我们用哪个chart需要下载到本地,基于本地这个chart部署实例,这个部署的实例叫做release
 
cd /usr/local/install-k8s/

wget https://get.helm.sh/helm-v3.6.2-linux-amd64.tar.gz

mkdir helm

mv helm-v3.6.2-linux-amd64.tar.gz helm

cd helm

tar -zxvf helm-v3.6.2-linux-amd64.tar.gz

mv linux-amd64/helm /usr/local/bin/helm

chmod a+x /usr/local/bin/helm

确认安装完成
[root@k8s-master helm]# helm repo list
Error: no repositories to show
[root@k8s-master helm]# helm repo update
Error: no repositories found. You must add one before updating
[root@k8s-master helm]# helm version
version.BuildInfoVersion:"v3.6.2", GitCommit:"ee407bdf364942bcb8e8c665f82e15aa28009b71", GitTreeState:"clean", GoVersion:"go1.16.5"

默认helm下是没有任何仓库的,需要手动添加
helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyunhttps://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo add jetstack https://charts.jetstack.io
helm repo update# 更新仓库

这样就完成了

其他参考命令
helm扩展命令

helm list -a

helm del --purge els1

helm install --name elasticsearch-master -f values.yaml --namespace elastic --version 7.10.1 .

  18. 基于helm安装Dashboard
在install-k8s文件夹下面创建dashboard文件夹
cd /usr/local/install-k8s/plugin

mkdir dashboard

cd dashboard

helm增加k8s-dashboard的镜像源
helm repo add k8s-dashboard https://kubernetes.github.io/dashboard
helm获取dashboard,如获取4.2.0版本的kubernetes-dashboard
helm fetch k8s-dashboard/kubernetes-dashboard --version 4.2.0
解压kubernetes-dashboard-4.2.0.tgz
tar -zxvf  kubernetes-dashboard-4.2.0.tgz
cd  kubernetes-dashboard
新建kubernetes-dashboard.yaml文件
使用helm安装dashboard
helm install . -n kubernetes-dashboard --generate-name --namespace kube-system -f kubernetes-dashboard.yaml

  查看服务名
kubectl get service -n kube-system


编辑dashboard服务,type改为NodePort
kubectl edit svc chart-1657261491-kubernetes-dashboard -n kube-system


 

  查看pod情况
kubectl get pod -n kube-system -o wide

获取名称空间在kube-system下面的服务,查看服务情况
kubectl get svc -n kube-system

  注意这边端口就映射出来了,这是后其实可以使用32396就行访问了。
浏览器打开效果

 
获取登录token,其中高亮部分需要替换以下第一条语句执行的token名称
kubectl -n kube-system get secret |grep kubernetes-dashboard-token
【截止20220708日靠谱的k8s环境部署流程】kubectl describe secret chart-1657261491-kubernetes-dashboard-token-fwtbh

  在刚才的登陆页面吧这个token贴上去就可以进入了。


 

如果登录后有访问权限问题,需要添加如下代码进行角色绑定:
kubectl create clusterrolebinding kubernetes-dashboard --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard
 
暂时先记录这么多吧
 

    推荐阅读