Kubernetes安装配置指南

  • [x] 开源工具安装

https://github.com/lework/kainstall

  • [x] ansible工具安装

https://github.com/easzlab/kubeasz

  • [x] kuboard教程安装

https://www.kuboard.cn/install/install-kubernetes.html

k8s Kubernetes v1.15 v1.16 v1.17 v1.18 高可用

快速安装 shell

https://www.cnblogs.com/elvi/p/8976305.html

1.软件和硬件的系统要求如表

  • 至少2台 2核4G 的服务器

# 最低配置
Master:2core和4GB内存
Node:4core和16GB内存


# 推荐配置
Master:4core 16GB内存
Node:根据运行容器数量进行配置
  • 本文档中,CPU 必须为 x86 架构,暂时未适配 arm 架构的 CPU

  • 推荐配置CentOS 7.8,Kernel版本要求在3.10及以上

Kubernetes需要容器运行时(Container Runtime Interface,CRI)的支持,目前官方支持的容器运行时包括:Docker、Containerd、CRI-O和frakti,推荐版本为Docker CE 18.09。

而Kubernetes的Master与工作Node之间会有大量的网络通信,安全的做法是在防火墙上配置各组件需要相互通信的端口号,在安全的 内部网络环境中可以关闭防火墙服务:

systemctl disable firewalld
systemctl stop firewalld

另外,建议在主机上禁用SELinux,让容器可以读取主机文件系统:

setenforce 0

或修改系统文件/etc/sysconfig/selinux,将SELINUX=enforcing修改成SELINUX=disabled,然后重启Linux。

2.kubeadm快速安装kubernetes

2.1 单Master节点部署参考

https://www.kuboard.cn/install/install-k8s.html#%E6%96%87%E6%A1%A3%E7%89%B9%E7%82%B9

kubeadm 快速安装kubernetes 1.20.4单机版

https://sre.ink/kubeadm-%e5%bf%ab%e9%80%9f%e5%ae%89%e8%a3%85kubernetes-1-20-4%e5%8d%95%e6%9c%ba%e7%89%88/

2.2 安装Kubernetes高可用

https://www.kuboard.cn/install/install-kubernetes.html#%E4%BB%8B%E7%BB%8D

3. Kubeadm部署kubernetes

公司大部分线下测试环境均采用Kubeadm安装,这也是目前官方默认的安装方式,比二进制安装方式更加简单,可以让初学者快速上手并测试。目前GitHub上也有很多基于Ansible的自动化安装方式,但是为了更好地学习Kubernetes,还是建议体验一下Kubernetes的手动安装过程,以熟悉Kubernetes的各个组件。

3.1 基本环境配置

主机名

IP地址

说明

k8s-master

172.16.60.236

k8s-master

k8s-node1

172.16.60.178

k8s-node1

k8s-node2

172.16.60.226

k8s-node2

k8s-node3

172.16.60.9

k8s-node3

3.2 部署步骤

以下不做特殊说明默认所有机器都执行

准备工作

各节点通信采用主机名的方式,这种方式与IP地址相比较更具有扩展性。以下介绍具体的安装步骤。所有节点配置hosts,修改/etc/hosts如下:

# 更新系统和软件包
yum update

# 设置主机名(master node 名字分开)
hostnamectl set-hostname k8s-master

# 同步时间
systemctl restart chronyd

# 添加host
# 以下ip是所有机器的内网ip
cat >> /etc/hosts <<'EOF'
172.16.60.236   k8s-master
172.16.60.178   k8s-node1
172.16.60.226   k8s-node2
172.16.60.9     k8s-node3
EOF

cat >>/etc/resolv.conf <<'EOF'
nameserver 8.8.8.8
EOF

# 设置所有机器间无密码访问
ssh-keygen -t rsa
for i in k8s-master k8s-node1 k8s-node2 k8s-node3;do ssh-copy-id -i /root/.ssh/id_rsa.pub $i;done


# 关闭防火墙和iptables
systemctl stop firewalld.service
systemctl disable firewalld.service
systemctl stop iptables.service
systemctl disable iptables.service

# 关闭SELinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

# 关闭swap
swapoff -a && sysctl -w vm.swappiness=0
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

注释swap挂载选项:

# grep "swap" /etc/fstab
#UUID=a5ace1f8-ddcd-434d-afef-b5a73c7ef8e8 swap                    swap    defaults        0 0

所有节点同步时间。所有节点同步时间是必须的,并且需要加到开机自启动和计划任务中,如果节点时间不同步,会造成Etcd存储Kubernetes信息的键-值(key-value)数据库同步数据不正常,也会造成证书出现问题。时间同步配置如下:

yum -y install ntp
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone
ntpdate time2.aliyun.com
# 加入计划任务
crontab -l
*/5 * * * * ntpdate time2.aliyun.com

# 加入开机自启动
cat /etc/rc.local
ntpdate time2.aliyun.com


# 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system  # 生效

所有节点配置limit:

ulimit -SHn 65535

所有节点都配置国内仓库源

wget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
加载 ipvs 内核模块
  • 安装 IPVS 模块

yum -y install ipvsadm ipset sysstat conntrack libseccomp
  • 设置开机加载配置文件

cat >>/etc/modules-load.d/ipvs.conf<<EOF
ip_vs_dh
ip_vs_ftp
ip_vs
ip_vs_lblc
ip_vs_lblcr
ip_vs_lc
ip_vs_nq
ip_vs_pe_sip
ip_vs_rr
ip_vs_sed
ip_vs_sh
ip_vs_wlc
ip_vs_wrr
nf_conntrack_ipv4
EOF
  • 设置开机加载 IPVS 模块

# 设置开机加载内核模块
systemctl enable systemd-modules-load.service

# 重启后检查 ipvs 模块是否加载
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
  • 如果集群已经部署在了 iptables 模式下,可以通过下面命令修改,修改 mode 为 ipvs 重启集群即可。

kubectl edit -n kube-system configmap kube-proxy
安装docker
# master执行以下转到repo目录
cd /etc/yum.repos.d/

# master执行下载docker阿里云镜像
wget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# master同步到其他服务器
[root@k8s-master yum.repos.d]# for i in k8s-master k8s-node1 k8s-node2 k8s-node3;do scp docker-ce.repo $i:/etc/yum.repos.d/;done
docker-ce.repo                                                                                                             100% 2640   162.5KB/s   00:00
docker-ce.repo                                                                                                             100% 2640     3.5MB/s   00:00
docker-ce.repo                                                                                                             100% 2640     3.7MB/s   00:00


# 安装docker(各个都要装)
yum -y install docker-ce

# 修改配置
nano /usr/lib/systemd/system/docker.service

# master增加一行如下
ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT

# 配置阿里云镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://25bxwt20.mirror.aliyuncs.com"]
}
EOF

# 重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
systemctl enable docker
systemctl restart docker
安装kubeadm, kubectl, kubelet
# master执行以下
cat >> /etc/yum.repos.d/kubernetes.repo <<'EOF'
[kubernetes]
name=Kubernetes Repository
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
EOF

# master检查仓库
yum repolist
yum list all | grep "^kube"

# master执行安装
yum install kubeadm kubelet kubectl -y

# 检查安装
rpm -ql kubectl
rpm -ql kubeadm

# master上把仓库拷贝过去
cd /etc/yum.repos.d/
for i in k8s-master k8s-node1 k8s-node2 k8s-node3;do scp  kubernetes.repo $i:/etc/yum.repos.d/


# 所有node安装kubelet kubeadm
yum install kubelet kubeadm -y

# master和node执行以下
systemctl enable kubelet.service

# master查看所需的镜像
kubeadm config images list

# 所有机器都执行以下的拉取镜像的操作
# 由于kubeadm依赖国外的k8s.gcr.io的镜像,国内被墙所以这边的解决方案是下载国内的镜像重新打tag的方式
cat > images_pull_k8s.sh <<'EOF'
#!/bin/bash
k8s_Version="v1.18.3"

images=(
    # 下面的镜像应该去除"k8s.gcr.io/"的前缀
    kube-apiserver:${k8s_Version}
    kube-controller-manager:${k8s_Version}
    kube-scheduler:${k8s_Version}
    kube-proxy:${k8s_Version}
    pause:3.2
    etcd:3.4.3-0
    coredns:1.6.7
)

for imageName in ${images[@]} ; do
    docker pull mirrorgcrio/$imageName
    docker tag mirrorgcrio/$imageName k8s.gcr.io/$imageName
    docker rmi mirrorgcrio/$imageName
done
EOF

chmod 755 images_pull_k8s.sh
./images_pull_k8s.sh

或者直接手动拉取镜像

docker pull mirrorgcrio/kube-apiserver:v1.18.3
docker pull mirrorgcrio/kube-controller-manager:v1.18.3
docker pull mirrorgcrio/kube-scheduler:v1.18.3
docker pull mirrorgcrio/kube-proxy:v1.18.3
docker pull mirrorgcrio/pause:3.2
docker pull mirrorgcrio/etcd:3.4.3-0
docker pull mirrorgcrio/coredns:1.6.7

docker tag mirrorgcrio/kube-apiserver:v1.18.3 k8s.gcr.io/kube-apiserver:v1.18.3
docker tag mirrorgcrio/kube-controller-manager:v1.18.3 k8s.gcr.io/kube-controller-manager:v1.18.3
docker tag mirrorgcrio/kube-scheduler:v1.18.3 k8s.gcr.io/kube-scheduler:v1.18.3
docker tag mirrorgcrio/kube-proxy:v1.18.3 k8s.gcr.io/kube-proxy:v1.18.3
docker tag mirrorgcrio/pause:3.2 k8s.gcr.io/pause:3.2
docker tag mirrorgcrio/etcd:3.4.3-0 k8s.gcr.io/etcd:3.4.3-0
docker tag mirrorgcrio/coredns:1.6.7 k8s.gcr.io/coredns:1.6.7

docker image rm mirrorgcrio/kube-apiserver:v1.18.3
docker image rm mirrorgcrio/kube-controller-manager:v1.18.3
docker image rm mirrorgcrio/kube-scheduler:v1.18.3
docker image rm mirrorgcrio/kube-proxy:v1.18.3
docker image rm mirrorgcrio/pause:3.2
docker image rm mirrorgcrio/etcd:3.4.3-0
docker image rm mirrorgcrio/coredns:1.6.7

3.3 Master初始化kubeadm

本小节的所有的操作,只在 Master 节点上进行

# master执行init初始化
kubeadm init \
--kubernetes-version="v1.18.3" \
--pod-network-cidr="10.244.0.0/16" \
--ignore-preflight-errors="NumCPU"

# 在当前用户家目录下创建.kube目录并配置访问集群的config 文件
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 应用网络插件flannle
[root@k8s-master home]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# 查看 kube-system 命名空间中运行的 pods
kubectl get pods -n kube-system

# 查看 k8s 集群组件的状态
kubectl get ComponentStatus


# 配置命令补全
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

3.4 node加入集群

[root@k8s-node1 home]# kubeadm join 172.16.60.236:6443 --token 950v9y.z3lz25askvjw33ou \
>     --discovery-token-ca-cert-hash sha256:e84f8923f43878b530c6d5879c258ccdd5caec1d02ee8d89d1d75b9bdf4d753e
......
Run 'kubectl get nodes' on the control-plane to see this node join the cluster
  • 如果初始化过程被中断可以使用下面命令来恢复

kubeadm reset
  • 下面是最后执行成功显示的结果,需要保存这个执行结果,以让 node 节点加入集群

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

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.16.100.9:6443 --token 2dyd69.hrfsjkkxs4stim7n \
    --discovery-token-ca-cert-hash sha256:4e30c1f41aefb177b708a404ccb7e818e31647c7dbdd2d42f6c5c9894b6f41e7

3.5 获得 join命令参数

在 master 节点上执行

# 只在 master 节点执行
kubeadm token create --print-join-command


 如果已经忘记kubeadm join参数,可以在Master节点中用如下命令查询
$ kubeadm token create --print-join-command


可获取kubeadm join 命令及参数,如下所示

# kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt     --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303

有效时间

该 token 的有效时间为 2 个小时,2小时内,您可以使用此 token 初始化任意数量的 worker 节点。

3.6 查看部署状态

# master查看node节点状态
kubectl get nodes

# master查看kube-system命名空间下的pod启动的状态
kubectl get po -n kube-system

# 如果有pod一直启动不起来,通过describe查看状态
kubectl describe po/{具体的pod名字} -n kube-system

3.7 calico网络插件

# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=10.100.0.1/16

# 参考文档 https://docs.projectcalico.org/v3.9/getting-started/kubernetes/
rm -f calico-3.9.2.yaml
wget https://kuboard.cn/install-script/calico/calico-3.9.2.yaml
sed -i "s#192\.168\.0\.0/16#${POD_SUBNET}#" calico-3.9.2.yaml
kubectl apply -f calico-3.9.2.yaml

或者如下方式
# https://kubernetes.io/docs/concepts/cluster-administration/addons/
# https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
kubectl -n kube-system get pods |grep calico

最新calico网络插件安装方式

https://www.wqblogs.com/2020/12/14/calico%E9%83%A8%E7%BD%B2/

3.8 Ingress Controller

安装

# 只在 master 节点执行
kubectl apply -f https://kuboard.cn/install-script/v1.17.x/nginx-ingress.yaml
或者
kubectl apply -f https://kuboard.cn/install-script/v1.19.x/nginx-ingress.yaml

卸载

只在您想选择其他 Ingress Controller 的情况下卸载

# 只在 master 节点执行
kubectl delete -f https://kuboard.cn/install-script/v1.19.x/nginx-ingress.yaml

定制化ingress

# 如果打算用于生产环境,请参考 https://github.com/nginxinc/kubernetes-ingress/blob/v1.5.5/docs/installation.md 并根据您自己的情况做进一步定制

查看ingress运行状态

[root@k8s-master ~]# kubectl get pods --all-namespaces
NAMESPACE       NAME                                       READY   STATUS    RESTARTS   AGE
kube-system     calico-kube-controllers-6c89d944d5-th2k7   1/1     Running   0          3h25m
kube-system     calico-node-j4g9n                          0/1     Running   0          45m
kube-system     calico-node-qt6sk                          0/1     Running   0          3h25m
kube-system     coredns-59c898cd69-2tnvl                   1/1     Running   1          3h25m
kube-system     coredns-59c898cd69-cdxxq                   1/1     Running   0          3h25m
kube-system     etcd-k8s-master                            1/1     Running   0          3h25m
kube-system     kube-apiserver-k8s-master                  1/1     Running   1          3h25m
kube-system     kube-controller-manager-k8s-master         1/1     Running   6          3h25m
kube-system     kube-proxy-ptd7x                           1/1     Running   0          3h25m
kube-system     kube-proxy-t97cs                           1/1     Running   0          45m
kube-system     kube-scheduler-k8s-master                  1/1     Running   6          3h25m
nginx-ingress   nginx-ingress-fzntf                        1/1     Running   0          6m21s

[root@k8s-master ~]# kubectl get pod -n nginx-ingress
NAME                  READY   STATUS    RESTARTS   AGE
nginx-ingress-fzntf   1/1     Running   0          6m37s

3.9 Metrics-Server部署

在新版的Kubernetes中系统资源的采集均使用Metrics-server,可以通过Metrics采集节点和Pod的内存、磁盘、CPU和网络的使用率。

metrics-server是Kubernetes 官方集群资源利用率信息收集器,是Heapster瘦身后的替代品。 收集的是集群内由各个节点上kubelet暴露出来的利用率信息。

mkdir metrics-server/

svc-metrics-server.yaml

---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  ports:
    - name: https
      port: 443
      protocol: TCP
      targetPort: 4443
  selector:
    k8s-app: metrics-server

role-metrics-server.yaml

---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  ports:
    - name: https
      port: 443
      protocol: TCP
      targetPort: 4443
  selector:
    k8s-app: metrics-server
[root@k8smaster1 metrics-server]# ^C
[root@k8smaster1 metrics-server]# ^C
[root@k8smaster1 metrics-server]# ^C
[root@k8smaster1 metrics-server]# cat role-metrics-server.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
    rbac.authorization.k8s.io/aggregate-to-admin: 'true'
    rbac.authorization.k8s.io/aggregate-to-edit: 'true'
    rbac.authorization.k8s.io/aggregate-to-view: 'true'
  name: 'system:aggregated-metrics-reader'
  namespace: kube-system
rules:
  - apiGroups:
      - metrics.k8s.io
    resources:
      - pods
      - nodes
    verbs:
      - get
      - list
      - watch

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
  name: 'system:metrics-server'
  namespace: kube-system
rules:
  - apiGroups:
      - ''
    resources:
      - pods
      - nodes
      - nodes/stats
      - namespaces
      - configmaps
    verbs:
      - get
      - list
      - watch

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: 'metrics-server:system:auth-delegator'
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: 'system:auth-delegator'
subjects:
  - kind: ServiceAccount
    name: metrics-server
    namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: 'system:metrics-server'
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: 'system:metrics-server'
subjects:
  - kind: ServiceAccount
    name: metrics-server
    namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server-auth-reader
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
  - kind: ServiceAccount
    name: metrics-server
    namespace: kube-system

---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system

---

deployment-api-metrics-server.yaml

apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  labels:
    k8s-app: metrics-server
  name: v1beta1.metrics.k8s.io
  namespace: kube-system
spec:
  group: metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:
    name: metrics-server
    namespace: kube-system
  version: v1beta1
  versionPriority: 100

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
        - args:
            - '--cert-dir=/tmp'
            - '--secure-port=4443'
            - '--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname'
            - '--kubelet-use-node-status-port'
            - '--kubelet-insecure-tls=true'
          image: >-
            swr.cn-east-2.myhuaweicloud.com/kuboard-dependency/metrics-server:v0.4.1
          imagePullPolicy: IfNotPresent
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /livez
              port: https
              scheme: HTTPS
            periodSeconds: 10
          name: metrics-server
          ports:
            - containerPort: 4443
              name: https
              protocol: TCP
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /readyz
              port: https
              scheme: HTTPS
            periodSeconds: 10
          securityContext:
            readOnlyRootFilesystem: true
            runAsNonRoot: true
            runAsUser: 1000
          volumeMounts:
            - mountPath: /tmp
              name: tmp-dir
      nodeSelector:
        kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      serviceAccountName: metrics-server
      volumes:
        - emptyDir: {}
          name: tmp-dir

3.10 Kubernetes Dashboard

安装

执行如下命令,以安装 Kubernetes Dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta5/aio/deploy/recommended.yaml

// 可以直接下载
$ wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

如果访问不了该 yaml 文件,请使用下面的命令,效果是等价的

kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/v2.0.0-beta5.yaml

访问

Kubernetes Dashboard 当前,只支持使用 Bearer Token登录。 由于 Kubernetes Dashboard 默认部署时,只配置了最低权限的 RBAC。因此,我们要创建一个名为 admin-user 的 ServiceAccount,再创建一个 ClusterRolebinding,将其绑定到 Kubernetes 集群中默认初始化的 cluster-admin 这个 ClusterRole。

执行如下命令可创建 ServiceAccount 和 ClusterRoleBinding

kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/auth.yaml

获取Bearer Token

执行命令:

kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

因为Service是ClusterIP类型,为了方便使用,我们可通过kubectl --namespace=kubernetes-dashboard edit service kubernetes-dashboard修改成NodePort类型

spec:
  clusterIP: 10.96.187.186
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 31966
    port: 443
    protocol: TCP
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  sessionAffinity: None
  type: NodePort        //修改这里
[root@k8s-master ~]# kubectl get service -n kubernetes-dashboard
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.96.205.156   <none>        8000/TCP        70m
kubernetes-dashboard        NodePort    10.96.187.186   <none>        443:31966/TCP   70m

使用 Firefox 浏览器访问,并忽略 HTTPS 校验错误。

image0

给匿名用户授权

$ kubectl create clusterrolebinding test:anonymous --clusterrole=cluster-admin --user=system:anonymous

3.11 Kuboard Kubernetes

Kubernetes 容器编排已越来越被大家关注,然而使用 Kubernetes 的门槛却依然很高,主要体现在这几个方面:

  • 集群的安装复杂,出错概率大

  • Kubernetes相较于容器化,引入了许多新的概念,学习难度高

  • 需要手工编写 YAML 文件,难以在多环境下管理

  • 缺少好的实战案例可以参考

Kuboard,是一款免费的 Kubernetes 图形化管理工具,Kuboard 力图帮助用户快速在 Kubernetes 上落地微服务。

参考文献:

https://www.cnblogs.com/xiao987334176/p/12060855.html

在 K8S 中安装 Kuboard v3

https://www.kuboard.cn/install/v3/install-in-k8s.html#%E5%AE%89%E8%A3%85%E6%AD%A5%E9%AA%A4

4 kubectl管理工具

4.1 kubectl管理工具远程连接集群

Kubectl客户端工具的主要功能是管理Kubernetes集群中的资源,使用kuberctl工具可以对资源进行创建、删除和更改等操作。

Kubectl工具默认连接本地apiserver127.0.0.1:8080,通过-s选项可以指定集群HTTP非安全IP地址和端口进行访问,命令如下:

kubectl -s http://kube-apiserver-go.gitee.cc:8080 get node

查看master上的kube-api server地址

[root@k8s-m2 ~]# cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep server
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: kube-apiserver-go.gitee.cc:8080
    component: kube-apiserver
  name: kube-apiserver
    - kube-apiserver
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
    - --etcd-servers=https://127.0.0.1:2379
    - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
    - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
    - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
    - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
    image: hub.gitee.cc/google_containers/kube-apiserver:v1.18.2
    name: kube-apiserver

查看api-server的另一种方式

# APISERVER=$(kubectl config view |grep server|cut -f 2- -d ":" | tr -d " ")
# echo $APISERVER

创建ca证书和admin证书,admin证书用于客户端管理集群,所以需要将admin证书复制到客户端访问集群的节点上。 如果你是通过 kubeadm 安装的 Kubernetes,所有证书都存放在 /etc/kubernetes/pki 目录下。

参考文献中写了,需要生成admin.pem等证书文件最后合并成一个config文件,在此我使用之前生成的config文件。 直接从master上拷贝过去。

scp /etc/kubernetes/admin.conf root@192.168.1.46:/root/.kube/

// 集群安装后一般admin.conf文件没有更改,更改后名称为config文件,下面示例为拷贝config文件
scp .kube/config root@192.168.1.40:~/

在客户端节点上进行如下操作:

[root@jenkins ~]# mkdir /root/.kube/
[root@jenkins ~]# mv config /root/.kube/
[root@jenkins ~]# ll /root/.kube/config
-rw------- 1 root root 5459 Dec 29 03:35 /root/.kube/config

[root@jenkins ~]# kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
k8s-m1   Ready    master   63d   v1.18.2
k8s-m2   Ready    master   63d   v1.18.2
k8s-m3   Ready    master   63d   v1.18.2
k8s-n1   Ready    <none>   63d   v1.19.3
k8s-n2   Ready    <none>   63d   v1.19.3
k8s-w1   Ready    <none>   63d   v1.18.2
k8s-w2   Ready    <none>   63d   v1.18.2
k8s-w3   Ready    <none>   63d   v1.18.2
k8s-w4   Ready    <none>   63d   v1.18.2
k8s-w5   Ready    <none>   63d   v1.18.2
k8s-w6   Ready    <none>   63d   v1.18.2
k8s-w7   Ready    <none>   63d   v1.18.2

注意 kubectl版本要和集群环境版本一致

上面节点的介绍:

k8s-m1、k8s-m2、k8s-m3                 #master节点,使用keepalived vip进行热备
k8s-n1、k8s-n2                         #node节点,对外映射发布服务,安装了ingress插件
k8s-w1~w7                             #worker节点,运行容器和存储镜像

4.1.1 kubectl连接多个kubernetes集群

具体步骤如下:

$ ll ~/.kube/
-rw-r--r-- 1 root root 6546 Jun 21 19:23 kubectl-baseService.conf
-rw-r--r-- 1 root root 6546 Jun 21 19:23 kubectl-rake.conf

$ cat kubectl-rake.conf
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURuakNDQW9hZ0F3SUJBZ0lVRkdBNmlkZ0FSNXVwY3VUWXZMRkVKVjV2WW1nd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1p6RUxNQWtHQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFVcHBibWN4RURBT0JnTlZCQWNUQjBKbAphVXBwYm1jeERqQU1CZ05WQkFvVEJXcHdZV0Z6TVJRd0VnWURWUVFMRXd0amJHOTFaRzVoZEdsMlpURU9NQXdHCkExVUVBeE1GYW5CaFlYTXdIaGNOTWpFd05qSXhNRE14T0RBd1doY05NekV3TmpFNU1ETXhPREF3V2pCbk1Rc3cKQ1FZRFZRUUdFd0pEVGpFUU1BNEdBMVVFQ0JNSFFtVnBTbWx1WnpFUU1BNEdBMVVFQnhNSFFtVnBTbWx1WnpFTwpNQXdHQTFVRUNoTUZhbkJoWVhNeEZEQVNCZ05WQkFzVEMyTnNiM1ZrYm1GMGFYWmxNUTR3REFZRFZRUURFd1ZxCmNHRmhjekNDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFMcmo5SmcxaXZmRUI0TmUKaGRFQzAxdks0ZklydHlQclhmaytGbmJ5NldHSmsxMnN0RkFzM0ZIdzAvSWwwSU9ZNythRzZZTlo3SEVGUER1UQpPK0Z5eFhkQThpdUlYUW1ZYW1UM1k1aTQ3bVVWeDlWK2ZwZk9zUzUvSUVhUFNObmROVzN4cnkyLzNZaldpQnA5CmNhT3VOMXltQ1l6dnl5dGVPWXFQLzhpTHRDVXlEWmJsVkEzZFY4N0hnc2ErQWpYakVRbm01MS8zaFFiT1FxUisKRWpnZnI5Nm1MSmJpRUpacFJnWjJlTXNRLzNIbXVaeWs3ejRuQm5qcE1QaW10b1pUaTA5ZUxRQk9XTXRxSy9CZgp1cy8xZmxGS3V6dkRaWU02bHI5VHdhbFB1YjdUM2hSN05tSEhNS1U4NzhxUTNoNjErM0pTbktHYy9EeEVaL2sxCk9va0NXdWNDQXdFQUFhTkNNRUF3RGdZRFZSMFBBUUgvQkFRREFnRUdNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHcKSFFZRFZSME9CQllFRk5kYTNjNFJQTTlwb3JiRUdJSlZuVmxqN2U0WU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQgpBUUJRcWxqTFVSYndjSlZMbTZHU0JOL0dNM245bDJaaTBSVC9ETUpESzBEbjdmZlBybHVmY01uVjhFQmxPaGtYCllLUDhHNmRXbWdLSTFDTW5WNHZXRi9RRG8waGl1OGNGYXcyTS9kNmE0OFk2T0VKb0g1S3g5Wk5wT0p4NlNCSlcKMGdCRnJYaXlOVXZpVEJWWlFSbC9KU0g1cmRxMHI2b3FEbm0zalRQeE1YdTBLbXhzdU5YTS83YzZSaVZlODBDZwpseFdmZG5NbU9IVUI5UDU0c1JHMVFLdWNkTW1MYjZwbU05TG9WSzRibXNGOWpucUJwSDRlMnhabG1tc21uWFhzCmpYM0hNNi9LQitDRFRDSUZXKzE2ajlucmRJNmZKaXlkbHlUQWJoTUJEMTBHZ0hyUEg1Qk42T0F4a29rdkpDOVIKNGZZZDZERnByNm9yWHN6QWhkbTY4RFNFCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://100.64.230.123:6443
  name: kubernetes
contexts:
- context:
.......

$ cat kubectl-baseService.conf
apiVersion: v1
clusters:
- cluster:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVWekNDQXorZ0F3SUJBZ0lVRDlQQ0l0Z0hRUCtEVE10U1NGV1lmVXFoR01Zd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1p6RUxNQWtHQTFVRUJoTUNRMDR4RURBT0JnTlZCQWdUQjBKbGFVcHBibWN4RURBT0JnTlZCQWNUQjBKbAphVXBwYm1jeERqQU1CZ05WQkFvVEJXcHdZV0Z6TVJRd0VnWURWUVFMRXd0amJHOTFaRzVoZEdsMlpURU9NQXdHCkExVUVBeE1GYW5CaFlYTXdJQmNOTWpFd05qSXhNRE15TURBd1doZ1BNakV5TVRBMU1qZ3dNekl3TURCYU1JR2QKTVFzd0NRWURWUVFHRXdKRFRqRVFNQTRHQTFVRUNCTUhRbVZwU21sdVp6RVFNQTRHQTFVRUJ4TUhRbVZwU21sdQpaekVwTUNjR0ExVUVDaE1nWldSalpqa3laVGs0TmpoaU5EZ3hNbUV6TVROalpUQTFZbVprWWpBNFlXTXhGREFTCkJnTlZCQXNUQzJOc2IzVmtibUYwYVhabE1Ta3dKd1lEVlFRREV5QmxaR05tT1RKbE9UZzJPR0k
    .......

通过config信息,可以看到两个集群的cluster name,context name,以及用户信息。

配置文件已准备好,下面开始变身了。文件合成:

$ cd $HOME/.kube/
$ KUBECONFIG=kubectl-rake.conf:kubectl-baseService.conf kubectl config view --flatten > $HOME/.kube/config
$ ll

-rw-r--r-- 1 root root 6546 Jun 21 19:32 config
-rw-r--r-- 1 root root 6546 Jun 21 19:23 kubectl-baseService.conf
-rw-r--r-- 1 root root 6546 Jun 21 19:23 kubectl-rake.conf

那么如何使用呢?

1、查看cluster name以及context name

$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://100.64.230.127:6443
  name: kubernetes1
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://100.64.230.123:6443
  name: kubernetes2
contexts:
- context:
    cluster: kubernetes
    user: edcf92e9868b4812a313ce05bfdb08ac
  name: edcf92e9868b4812a313ce05bfdb08ac@kubernetes1
- context:
    cluster: kubernetes
    user: edcf92e9868b4812a313ce05bfdb08ac
  name: edcf92e9868b4812a313ce05bfdb08ac@kubernetes2
current-context: edcf92e9868b4812a313ce05bfdb08ac@kubernetes
kind: Config
preferences: {}
users:
- name: edcf92e9868b4812a313ce05bfdb08ac
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

2、查看当前使用的集群

$ kubectl config current-context
edcf92e9868b4812a313ce05bfdb08ac@kubernetes

3、修改当前使用的集群

$ kubectl config use-context edcf92e9868b4812a313ce05bfdb08ac@kubernetes1
Switched to context "edcf92e9868b4812a313ce05bfdb08ac@kubernetes1".

4.1.2 kubectl、helm客户端配合多个配置接入

$ kubectl --kubeconfig=$HOME/.kube/new_ci_config get nodes
$ helm --kubeconfig=$HOME/.kube/new_ci_config list -A

# helm使用客户端部署流程

# 卸载掉helm和namespaces
$ /var/jenkins_home/bin/helm --kubeconfig=$HOME/.kube/new_ci_config uninstall -n ci-gitee-13994 ci-gitee-13994
$ /var/jenkins_home/bin/kubectl --kubeconfig=$HOME/.kube/new_ci_config delete ns ci-gitee-13994

# 安装helm和namespaces
$ /var/jenkins_home/bin/kubectl --kubeconfig=$HOME/.kube/new_ci_config get nodes
$ /var/jenkins_home/bin/kubectl --kubeconfig=$HOME/.kube/new_ci_config create ns ci-gitee-13994

# 部署前使用--debug --dry-run进行测试

/var/jenkins_home/bin/helm --kubeconfig=$HOME/.kube/new_ci_config uninstall -n ci-gitee-14019 ci-gitee-14019

/var/jenkins_home/bin/helm --kubeconfig=$HOME/.kube/new_ci_config install -f 14019values.yaml --debug --dry-run -n ci-gitee-14019 ci-gitee-14019 ./
/var/jenkins_home/bin/helm --kubeconfig=$HOME/.kube/new_ci_config install -f 14035values.yaml --debug --dry-run -n ci-gitee-14035 ci-gitee-14035 ./

# 测试完毕,直接部署
$ /var/jenkins_home/bin/helm --kubeconfig=$HOME/.kube/new_ci_config install -f 13994values.yaml -n ci-gitee-13994 ci-gitee-13994 ./
$ /var/jenkins_home/bin/helm --kubeconfig=$HOME/.kube/new_ci_config list -A

$ kubectl --kubeconfig=$HOME/.kube/kubectl-baseService.conf -n pipe-all exec -it gitee-ipipe-pipeline-fff7d59f6-665lb -- /bin/sh
$ helm --kubeconfig=$HOME/.kube/kubectl-baseService.conf list -A

$ helm --kubeconfig=$HOME/.kube/kubectl-baseService.conf -n pipe-all get pod
$ helm --kubeconfig=$HOME/.kube/kubectl-baseService.conf install ./redis -n redis redis

参考文献:

http://www.manongjc.com/detail/12-dxwuzgmmmatvykr.html

4.2 在kuberct基础上安装helm

直接拷贝heml二进制文件到远程机器上

[root@ci-base bin]# scp helm root@192.168.1.40:/usr/local/bin/
root@192.168.1.40's password:
helm                                                                                                            100%   39MB   8.4MB/s   00:04

或者下载方式

curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
# 或者
wget https://get.helm.sh/helm-v3.4.0-linux-amd64.tar.gz
tar -xf helm-v3.4.0-linux-amd64.tar.gz
mv linux-amd64/helm/usr/bin/
[root@jenkins ~]# helm version
version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}

4.3 kubectl命令补全

一般来说,命令补全是通过执行一个补全脚本的 shell 功能,补全脚本也是一个 shell 脚本,用于定义特定命令的补全功能。

kubectl 在 Bash 和 Zsh 下可以使用下面的命令自动生成并打印出补全脚本:

$ kubectl completion bash
# 或者
$ kubectl completion zsh

理论上在合适的 shell 中 source 上面命令的输出就可以开启 kubectl 的命令补全功能了

以Centos为例:

$ kubectl completion bash  >>/etc/profile
$ source /etc/profile

如果你想在linxu上自动补全kubenetes的命令,可以执行下列步骤:

$ yum install -y bash-completion
$ source <(kubectl completion bash)
$ echo "source <(kubectl completion bash)" >> ~/.bashrc

参考文献:

Kubernetes 远程工具连接k8s集群

https://www.cnblogs.com/xiangsikai/p/11412864.html

5. 诊断分析

5.1 查看日志

(1)使用journalctl查看服务日志

[root@k8s-master manifests]# journalctl -u docker

查看并追踪kubelet的日志:

journalctl -u kubelet -f

(2)使用“kubectl logs”查看容器日志

kubectl logs -f etcd-k8s-master -n kube-system

5.2 查看资源详情和事件

kubectl describe命令用于查看一个或多个资源的详细情况,包括相关资源和事件,语法如下:

(1)查看节点

kubectl describe nodes k8s-master

查看所有节点:

kubectl describe nodes

查看指定节点以及事件:

kubectl describe nodes k8s-node01 --show-events

2)查看Pod查看指定Pod:

kubectl describe pod calico-node-j4g9n -n kube-system

查看指定文件描述的所有资源:

kubectl describe -f teamcity.yml

可以使用describe命令查看资源事件的类型,类型可以是deploy、rs和po。

kubectl describe po/nginx-2131232
kubectl describe deploy/nginx
kubectl describe rs/nginx-2131232
kubectl describe svc
kubectl describe svc nginx-service

6. Kubernetes v1.19.0 高可用安装部署

参考文献:

https://www.cloudcared.cn/3126.html

https://gitee.com/hujianli94net/kainstall.git

https://gitee.com/oschina/install-single-master-K8s.git

7. 移除node和重新加入node

Kubernetes Node的隔离与恢复

在硬件升级、硬件维护等情况下,我们需要将某些Node进行隔离,脱离Kubernetes集群的调度范围。Kubernetes提供了一种机制,即可以将Node纳入调度范围,也可以将Node脱离调度范围。

使用kubectl cordon对某个Node进行隔离和恢复调度的操作。

#隔离
$ kubectl cordon k8s-node1


#恢复
$ kubectl uncordon k8s-node1

移除节点和加入节点操作

1.查看当前所有node节点
$ sudo kubectl get no


2.将我的节点标记为不可调度
$ kubectl cordon k8-w8


3.排空节点以准备维护
$ kubectl drain my-node


4.在master上移除节点
$ sudo kubectl delete node <your-node>


5.在被删除节点<node>执行
$ kubeadm reset


6.在master节点重新生成token
$ kubeadm token create --print-join-command
W0406 18:46:41.609997   17201 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]

kubeadm join kube-apiserver.gitee.cc:6443 --token vawvl2.521xl3jo2h2y2h4h     --discovery-token-ca-cert-hash sha256:31a7cc20f0c5471a525c43e530bd21360bd4d1a19fa9e96724ad811a295eebd5


7.在被加入节点执行 kubeadm join

参考文献:

https://www.orchome.com/1777

8. 手动管理Node资源与节点

考虑到系统维护或硬件升级等原因,管理员有时候需要手动重启或下线某个工作节点,

安全的操作步骤是先手动禁止调度器继续向该节点调度新的Pod对象以封锁(cordon)该节点,

但封锁操作并不会影响节点上现有的Pod对象,接下来还需要正常逐出该节点上运行着的工作负载以“排空”(drain)该节点。

注意

封锁工作节点对DaemonSet控制器创建的Pod对象无效。

//封锁k8s-W1节点
kubectl cordon k8s-w1

//排空节点内的资源
kubectl drain k8s-w1

不过,仅期望封锁工作节点时,cordon命令显然更适用。随后,无论是运行cordon还是drain命令,若期望工作节点回归正常工作状态,都需要使用uncordo命令对节点进行解封。

kubectl uncordo k8s-w1

需要注意的是,drain默认只能排空受控制器(如Deployment、DaemonSet或StatefulSet等)管理的Pod对象,而不受控于控制器的Pod(例如静态Pod)则会阻止命令的运行。

如果要忽略这种阻止操作,可以为drain附加–force选项,以清理系统级Pod对象。

8.1 节点维护和设置污点操作

#查看taint
kubectl describe node node1


#设置taint
#NoExecute不仅不会调度, 还会驱逐Node上已有的Pod
kubectl taint node node1 key1=value1:NoSchedule
kubectl taint node node1 key1=value1:NoExecute
kubectl taint node node1 key2=value2:NoSchedule



#删除taint
kubectl taint node node1 key1:NoSchedule-  # 这里的key可以不用指定value
kubectl taint node node1 key1:NoExecute-
# kubectl taint node node1 key1-  删除指定key所有的effect
kubectl taint node node1 key2:NoSchedule-



kubectl taint node k8s-m1 node-role.kubernetes.io/master-   #允许master调度

kubectl taint nodes master1 node-role.kubernetes.io/master=:NoSchedule #禁止master调度

kubectl describe node master |grep Taints #查看污点



#节点设置不可调度
kubectl taint node k8s-n1 GiteeCommonAddonsOnly:NoSchedule

#节点设置为可调度
kubectl taint node k8s-n1 GiteeCommonAddonsOnly=yes:NoSchedule-


kubectl cordon my-node                                                # 将节点设置为不可调度
kubectl drain my-node                                                 # 排空 my-node 以准备维护
kubectl uncordon my-node                                              # 将节点标记为可调度
kubectl top node my-node                                              # 显示给定节点的指标
kubectl cluster-info                                                  # 显示 master 和 services 的地址
kubectl cluster-info dump                                             # 将当前集群状态转储到标准输出
kubectl cluster-info dump --output-directory=/path/to/cluster-state   # 将当前集群状态转储到标准输出 to /path/to/cluster-state

# 如果具有该键和效果的污点已存在,则按指定替换其值。
kubectl taint nodes foo dedicated=special-user:NoSchedule

参考文献: https://www.cnblogs.com/weifeng1463/p/11810612.html

Kubernetes 将Pod调度到Master节点

出于安全考虑,默认配置下Kubernetes不会将Pod调度到Master节点。如果希望将k8s-master也当作Node使用,可以执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master-



其中k8s-master是主机节点hostname如果要恢复Master Only状态,执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master=""

9.集群扩容及缩容

集群缩容

  • master节点缩容

[root@master01 ~]# kubectl drain master03 --delete-emptydir-data --force --ignore-daemonsets
[root@master01 ~]# kubectl delete node master03

[root@master03 ~]# kubeadm reset -f && rm -rf $HOME/.kube
  • worker节点缩容

[root@master01 ~]# kubectl drain worker04 --delete-emptydir-data --force --ignore-daemonsets
[root@master01 ~]# kubectl delete node worker04

[root@worker04 ~]# kubeadm reset -f && rm -rf $HOME/.kube
[root@worker04 ~]# rm -rf /etc/kubernetes/admin.conf /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /etc/kubernetes/controller-manager.conf /etc/kubernetes/scheduler.conf

参考文献

kubeadm安装k8s 1.13版本

基于Ubuntu Server 20.04 LTS 部署 kubernetes 1.20

ubuntu18.04 kubeadm 安装kubernetes v1.18.3

kubeadm部署高可用版Kubernetes1.21

K8S部署系列一-Ubuntu 20.0 K8S集群安装

https://www.yuque.com/lizhiyong2000/gwgb6w/xfgh7n