百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

二进制部署k8s集群

yuyutoo 2025-03-06 21:05 2 浏览 0 评论

环境准备

kube-apiserver:

  • 使用节点本地 nginx 实现高可用;
  • 关闭非安全端口 8080 和匿名访问;
  • 在安全端口 6443 接收 https 请求;
  • 严格的认证和授权策略 (x509、token、RBAC);
  • 开启 bootstrap token 认证,支持 kubelet TLS bootstrapping;
  • 使用 https 访问 kubelet、etcd,加密通信;

kube-controller-manager:

  • 3 节点高可用;
  • 关闭非安全端口,在安全端口 10252 接收 https 请求;
  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 自动 approve kubelet 证书签名请求 (CSR),证书过期后自动轮转;
  • 各 controller 使用自己的 ServiceAccount 访问 apiserver;

kube-scheduler:

  • 3 节点高可用;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kubelet:

  • 使用 kubeadm 动态创建 bootstrap token,而不是在 apiserver 中静态配置;
  • 使用 TLS bootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;
  • 在 KubeletConfiguration 类型的 JSON 文件配置主要参数;
  • 关闭只读端口,在安全端口 10250 接收 https 请求,对请求进行认证和授权,拒绝匿名访问和非授权访问;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kube-proxy:

  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 在 KubeProxyConfiguration 类型的 JSON 文件配置主要参数;
  • 使用 ipvs 代理模式;

组件版本

组件

版本

连接地址

rocky linux

9.2

官网

kubernetes

v1.27.3

GitHub

etcd

v3.5.9

GitHub

containerd

1.7.2

GitHub

calico

v3.26.1

GitHub

nginx

1.24.0

官网

三台机器混合部署 etcd、master 集群和 woker 集群。

 rocky11 192.168.10.11 master node
 rocky12 192.168.10.12 master node
 rocky13 192.168.10.13 master node
 vip 192.168.10.100
 pod 172.30.0.0/16
 svc 10.254.0.0/16

升级内核

#参考:http://elrepo.org/tiki/HomePage

grubby --info=ALL #查看所有内核
 #1.安装GPG-KEY
 rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
 
 #2.安装epel仓库
 dnf install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm #9
 
 #3.载入elrepo-kernel元数据
 dnf --disablerepo=\* --enablerepo=elrepo-kernel repolist
 
 #4.查看可用内核包
 dnf --disablerepo=\* --enablerepo=elrepo-kernel list kernel*
 
 #5.安装内核
 dnf --enablerepo=elrepo-kernel install kernel-lt kernel-lt-devel -y
 
 #6.查看安装的包
 rpm -qa|grep kernel-lt
 
 grubby --default-kernel #查看默认的内核
 grubby --info=ALL #查看所有内核
 
 
 #7.修改启动顺序
 rubby --set-default /boot/vmlinuz-6.1.37-1.el9.x86_64
 
 grubby --remove-kernel=kernel的路径 #删除不需要的内核
 
 #8.重启机器
 reboot 
 
 #9.查看内核版本
 uname -r

系统设置

 #1.安装依赖包
 dnf install -y epel-release
 dnf install -y gcc gcc-c++ net-tools lrzsz vim telnet make psmisc \
  patch socat conntrack ipset ipvsadm sysstat libseccomp chrony perl curl wget git
  
 #2.关闭防火墙
 systemctl disable --now firewalld
 
 #3.关闭selinux
 getenforce #查看selinux状态
 setenforce 0 #临时关闭selinux
 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config #修改配置文件
 
 #4.关闭swap分区
 swapoff -a
 sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
 
 
 #5.文件句柄数配置
 cat <> /etc/security/limits.conf
 * soft nofile 65536
 * hard nofile 65536
 * soft nproc 65536
 * hard nproc 65536
 * soft memlock unlimited
 * hard memlock unlimited
 EOF
 
 
 #6.时间同步
 dnf install -y chrony
 vim /etc/chrony.conf
 server 时间同步服务器 iburst #配置自己的时间服务器
 
 systemctl enable --now chronyd #启动并设置自启动
 
 timedatectl status #查看同步状态
 timedatectl set-timezone Asia/Shanghai #时区不对的可调整系统TimeZone
 timedatectl set-local-rtc 0 #将当前的UTC时间写入硬件时钟
 
 #重启依赖于系统时间的服务
 systemctl restart rsyslog 
 systemctl restart crond
 
 #7.内核参数
 cat > /etc/sysctl.d/kubernetes.conf <<EOF
 net.ipv4.ip_forward=1
 net.bridge.bridge-nf-call-iptables=1
 net.bridge.bridge-nf-call-ip6tables=1
 net.ipv4.neigh.default.gc_thresh1=1024
 net.ipv4.neigh.default.gc_thresh1=2048
 net.ipv4.neigh.default.gc_thresh1=4096
 vm.swappiness=0
 vm.panic_on_oom=0
 vm.overcommit_memory=1
 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
 
 sysctl -p /etc/sysctl.d/kubernetes.conf
 
 #8.安装ipvs
 #开机加载内核模块,并设置开机自动加载
 cat < /etc/modules-load.d/ipvs.conf 
 ip_vs
 ip_vs_rr
 ip_vs_wrr
 ip_vs_sh
 nf_conntrack
 br_netfilter 
 EOF
 
 #重启后查看
 lsmod | grep -e ip_vs -e nf_conntrack

准备证书

cfssl为各个组件生成证书,在某台机器上生成证书,之后将证书拷贝到部署的主机上。

由于各个组件都需要配置证书,并且依赖CA证书来签发证书,所以我们首先要生成好CA证书以及后续的签发配置文件。GitHub

 #1.下载
 wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64 -O /usr/local/sbin/cfssl
 wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64 -O /usr/local/sbin/cfssljson
 wget https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl-certinfo_1.6.4_linux_amd64 -O /usr/local/sbin/cfssl-certinfo
 
 chmod +x /usr/local/sbin/*
 
 #2.签发CA证书
 cd /opt/k8s
 cat < ca-csr.json
 {
   "CN": "kubernetes",
   "key": {
     "algo": "rsa",
     "size": 2048
   },
   "names": [
     {
       "C": "CN",
       "ST": "ShangHai",
       "L": "ShangHai",
       "O": "Kubernetes",
       "OU": "System"
     }
   ],
   "ca": {
     "expiry": "876000h"
   }
 }
 EOF
 
 CN:apiserver从证书中提取该字段作为请求的用户名,浏览器使用该字段验证网站是否合法;
 O:apiserver从证书中提取该字段作为请求用户所属的组
 kube-apiserver将提取的User、Group作为RBAC授权的用户标识
 
 
 #3.#证书签发配置
 cat < ca-config.json 
 {
   "signing": {
     "default": {
       "expiry": "87600h"
     },
     "profiles": {
       "kubernetes": {
         "usages": [
           "signing",
           "key encipherment",
           "server auth",
           "client auth"
         ],
         "expiry": "876000h"
       }
     }
   }
 }
 EOF
 
 signing:表示该证书可用于签名其它证书(生成的 ca.pem 证书中 CA=TRUE);
 server auth:表示 client 可以用该该证书对 server 提供的证书进行验证;
 client auth:表示 server 可以用该该证书对 client 提供的证书进行验证;
 expiry: 876000h:证书有效期设置为 100 年;
 
 
 #4.生成证书,后续组件都依赖CA证书签发证书
 cfssl gencert -initca ca-csr.json | cfssljson -bare ca
 #生成后的文件
 ca-config.json
 ca-csr.json
 ca-key.pem
 ca.csr
 ca.pem
 
 #查看证书有效时间,100年
 openssl x509 -in ca.pem -noout -text | grep 'Not'
   Not Before: Jul  4 14:08:00 2023 GMT
   Not After : Jun 10 14:08:00 2123 GMT

部署etcd

etcd是一个分布式、可靠的key-value存储分布式系统,它不仅能用于存储,还提供共享配置及服务发现。

etcd应用场景

etcd比较多的应用场景是用于服务发现,服务发现解决的是分布式系统中最常见的问题之一,即在同一个分布式集群中的进程或服务如何才能找到对方并建立连接。etcd主要使用场景有:分布式系统配置管理,服务注册发现,选主,应用调度,分布式队列,分布式锁。

etcd如果保证一致性

etcd使用raft协议来维护集群内各个节点状态的一致性,每个etcd节点都维护了一个状态机,并且,任意时刻至多存在一个有效的主节点。主节点处理所有来自客户端写操作,通过 Raft 协议保证写操作对状态机的改动会可靠的同步到其他节点。

准备证书

 #1.签发证书
 cat < etcd-csr.json
 {
   "CN": "etcd",
   "hosts": [
     "127.0.0.1",
     "192.168.10.11",
     "192.168.10.12",
     "192.168.10.13",
     "192.168.10.100"
   ],
   "key": {
     "algo": "rsa",
     "size": 2048
   },
   "names": [
     {
       "C": "CN",
       "ST": "ShangHai",
       "L": "ShangHai",
       "O": "Kubernetes",
       "OU": "System"
     }
   ]
 }
 EOF
 
 #hosts字段的IP地址是授权给etcd机器的证书
 
 #2.生成证书和私钥
 cfssl gencert -ca=ca.pem \
  -ca-key=ca-key.pem \
  -config=ca-config.json \
  -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
 #####
 ca-config.json
 ca-csr.json
 ca-key.pem
 ca.csr
 ca.pem
 etcd-csr.json
 etcd-key.pem #
 etcd.csr
 etcd.pem #
 
 #3.把证书拷贝到各个节点
 mkdir -p /etc/kubernetes/ssl && cp *.pem /etc/kubernetes/ssl/
 
 ssh -n 192.168.10.12 "mkdir -p /etc/kubernetes/ssl && exit"
 ssh -n 192.168.10.13 "mkdir -p /etc/kubernetes/ssl && exit"
 
 scp -r /etc/kubernetes/ssl/*.pem 192.168.10.12:/etc/kubernetes/ssl/
 scp -r /etc/kubernetes/ssl/*.pem 192.168.10.13:/etc/kubernetes/ssl/

部署服务

 #1.解压二进制文件
#下载地址:https://github.com/etcd-io/etcd/releases
 tar -zxvf etcd-v3.5.9-linux-amd64.tar.gz 
 mv etcd-v3.5.9-linux-amd64/etcd* /usr/local/sbin/
 
 scp -r /usr/local/sbin/etcd* 192.168.10.12:/usr/local/sbin
 scp -r /usr/local/sbin/etcd* 192.168.10.13:/usr/local/sbin
 
 mkdir -p /app/etcd
 ssh -n 192.168.10.12 "mkdir -p /app/etcd && exit"
 ssh -n 192.168.10.13 "mkdir -p /app/etcd && exit"
 
 #2.配置启动文件
 cat < /etc/systemd/system/etcd.service
 [Unit]
 Description=Etcd Server
 After=network.target
 After=network-online.target
 Wants=network-online.target
 Documentation=https://github.com/coreos
 
 [Service]
 Type=notify
 WorkingDirectory=/app/etcd/
 ExecStart=/usr/local/sbin/etcd \\
  --name=rocky11 \\
  --data-dir=/app/etcd \\
  --cert-file=/etc/kubernetes/ssl/etcd.pem \\
  --key-file=/etc/kubernetes/ssl/etcd-key.pem \\
  --trusted-ca-file=/etc/kubernetes/ssl/ca.pem \\
  --peer-cert-file=/etc/kubernetes/ssl/etcd.pem \\
  --peer-key-file=/etc/kubernetes/ssl/etcd-key.pem \\
  --peer-trusted-ca-file=/etc/kubernetes/ssl/ca.pem \\
  --peer-client-cert-auth \\
  --client-cert-auth \\
  --initial-cluster-token=etcd-cluster-0 \\
  --listen-peer-urls=https://192.168.10.11:2380 \\
  --advertise-client-urls=https://192.168.10.11:2379 \\
  --initial-advertise-peer-urls=https://192.168.10.11:2380 \\
  --listen-client-urls=https://192.168.10.11:2379,https://127.0.0.1:2379 \\
  --initial-cluster=rocky11=https://192.168.10.11:2380,rocky12=https://192.168.10.12:2380,rocky13=https://192.168.10.13:2380 \\
  --initial-cluster-state=new \\
  --auto-compaction-mode=periodic \\
  --auto-compaction-retention=1 \\
  --max-request-bytes=33554432 \\
  --quota-backend-bytes=6442450944 \\
  --heartbeat-interval=250 \\
  --election-timeout=2000
 Restart=on-failure
 RestartSec=5
 LimitNOFILE=65536
 
 [Install]
 WantedBy=multi-user.target
 EOF
 
 #启动服务
 systemctl enable --now etcd

验证etcd

 #1.查看启动状态
 etcdctl member list \
  --cacert=/etc/kubernetes/ssl/ca.pem \
  --cert=/etc/kubernetes/ssl/etcd.pem \
  --key=/etc/kubernetes/ssl/etcd-key.pem
 ################显示如下################
 1af68d968c7e3f22, started, rocky12, https://192.168.10.12:2380, https://192.168.10.12:2379, false
 7508c5fadccb39e2, started, rocky11, https://192.168.10.11:2380, https://192.168.10.11:2379, false
 e8d9a97b17f26476, started, rocky13, https://192.168.10.13:2380, https://192.168.10.13:2379, false
 
 #2.验证服务状态
 etcdctl endpoint health  --endpoints="https://192.168.10.11:2379,https://192.168.10.12:2379,https://192.168.10.13:2379"  --cacert=/etc/kubernetes/ssl/ca.pem  --cert=/etc/kubernetes/ssl/etcd.pem  --key=/etc/kubernetes/ssl/etcd-key.pem
 ###########显示如下#############
 https://192.168.10.11:2379 is healthy: successfully committed proposal: took = 22.307663ms
 https://192.168.10.12:2379 is healthy: successfully committed proposal: took = 23.213301ms
 https://192.168.10.13:2379 is healthy: successfully committed proposal: took = 31.741529ms
 
 #3.查看领导者
 etcdctl -w table --cacert=/etc/kubernetes/ssl/ca.pem \
   --cert=/etc/kubernetes/ssl/etcd.pem \
   --key=/etc/kubernetes/ssl/etcd-key.pem \
   --endpoints="https://192.168.10.11:2379,https://192.168.10.12:2379,https://192.168.10.13:2379" endpoint status
 #########显示如下
 +----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
 |          ENDPOINT          |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
 +----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
 | https://192.168.10.11:2379 | 7508c5fadccb39e2 |   3.5.9 |   20 kB |      true |      false |         2 |         21 |                 21 |        |
 | https://192.168.10.12:2379 | 1af68d968c7e3f22 |   3.5.9 |   20 kB |     false |      false |         2 |         21 |                 21 |        |
 | https://192.168.10.13:2379 | e8d9a97b17f26476 |   3.5.9 |   20 kB |     false |      false |         2 |         21 |                 21 |        |
 +----------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

部署负载

kube-apiserver是无状态的,通过nginx进行代理访问,从而保证服务可用性

nginx做反向代理,后端连接所有的kube-apiserver实例,并提供健康检查和负载均衡功能;keepalived提供kube-apiserver对外服务的VIP;

nginx监听的端口8443需要与kube-apiserver的端口6443不同,避免冲突。

keepalived在运行过程中周期检查本机的nginx进程状态,如果检测到nginx进程异常,则触发重新选主的过程,VIP将飘移到新选出来的主节点,从而实现VIP的高可用。所有组件(如 kubeclt、apiserver、controller-manager、scheduler 等)都通过VIP和nginx监听的8443端口访问kube-apiserver服务。

部署nginx

 #1.安装nginx
 yum install pcre zlib openssl nginx nginx-mod-stream -y
 
 #2.nginx.conf
 stream {
   upstream apiserver {
     hash $remote_addr consistent;
     server 192.168.10.11:6443 max_fails=3 fail_timeout=30s;
     server 192.168.10.12:6443 max_fails=3 fail_timeout=30s;
     server 192.168.10.13:6443 max_fails=3 fail_timeout=30s;
   }
   server {
     listen 8443;
     proxy_connect_timeout 10s;
     proxy_timeout 120s;
     proxy_pass apiserver;
   }
 }
 
 #3.启动
 systemctl enable --now nginx
 
 netstat -lantup|grep nginx
 tcp   0   0 0.0.0.0:8443   0.0.0.0:*      LISTEN      26961/nginx: master 

部署keepalived

#1.安装
yum install keepalived -y

#2.配置
cat < /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
  router_id apiserver
}

#自定义监控脚本
vrrp_script chk_nginx {
  script "/etc/keepalived/nginx_check.sh"
  interval 10
  weight 0
}

vrrp_instance VI_1 {
  state MASTER
  interface ens160
  virtual_router_id 100
  priority 100
  advert_int 1
  mcast_src_ip 192.168.10.11
  authentication {
    auth_type PAAS
    auth_pass kube
  }
  virtual_ipaddress {
    192.168.10.100
  }
  track_script {
    chk_nginx
  }
}
EOF

#配置检测脚本
cat < /etc/keepalived/nginx_check.sh
#!/bin/bash
pid=\`ps -ef|grep nginx|grep -v -E "grep|check"|wc -l\`
if [ \$pid -eq 0 ];then
  systemctl start nginx
  sleep 2
  if [ \`ps -ef|grep nginx|grep -v -E "grep|check"|wc -l\` -eq 0 ];then
    killall keepalived
  fi
fi
EOF

chmod 755 /etc/keepalived/nginx_check.sh

#3.启动
systemctl --now enable keepalived && systemctl status keepalived

ip add
1: ens160:  mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:31:2f:cf brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 192.168.10.13/24 brd 192.168.10.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet 192.168.10.100/32 scope global ens160  ####
       valid_lft forever preferred_lft forever

部署master

Master 节点的证书操作只需要做一次,将生成的证书拷到每个 Master 节点上以复用。

kubeconfig 主要是各组件以及用户访问 apiserver 的必要配置,包含 apiserver 地址、client 证书与 CA 证书等信息。

k8s组件的启动脚本参数参考官方文档

下载地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.27.md

#1.解压包
tar -zxvf kubernetes-server-linux-amd64.tar.gz 
cd /kubernetes/server/bin

#2.拷贝文件
cp kube-apiserver kube-aggregator \
 kube-controller-manager kube-scheduler \
 kube-proxy kubeadm kubectl kubelet /usr/local/sbin/

#把二进制文件拷贝到所有k8s节点,包含master和node:/usr/local/sbin
scp /usr/local/sbin/kube* 192.168.10.12:/usr/local/sbin
scp /usr/local/sbin/kube* 192.168.10.13:/usr/local/sbin

kubectl

kubectl 是 kubernetes 集群的命令行管理工具,默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信息,如果没有配置,执行 kubectl 命令时可能会出错。

kube-apiserver 会提取证书中字段 CN 作为用户名,这里用户名叫 admin,但这只是个名称标识,它有什么权限呢?admin 是预置最高权限的用户名吗?不是的!不过 kube-apiserver 确实预置了一个最高权限的 ClusterRole,叫做 cluster-admin,还有个预置的 ClusterRoleBindingcluster-admin 这个 ClusterRolesystem:masters 这个用户组关联起来了,所以说我们给用户签发证书只要在 system:masters 这个用户组就拥有了最高权限。

~/.kube/config只需要部署一次,然后拷贝到所有节点。

#1.签发最高权限的证书
cat < admin-csr.json 
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "system:masters",
      "OU": "System"
    }
  ]
}
EOF

#O: 为system:masters,kube-apiserver收到该证书后将请求的Group设置为system:masters;
#预定义的ClusterRoleBinding和cluster-admin将Group system:masters与Role cluster-admin 绑定,该Role授予所有API的权限
#该证书只会被kubectl当做client证书使用,所以hosts没写

#2.生成公钥和私钥
cfssl gencert -ca=ca.pem \
 -ca-key=ca-key.pem \
 -config=ca-config.json \
 -profile=kubernetes \
 admin-csr.json | cfssljson -bare admin
 
#忽略告警
This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements")


#生成证书文件
admin-key.pem #管理员证书私钥
admin.pem #管理员证书公钥

cp admin*.pem /etc/kubernetes/ssl
scp admin*.pem 192.168.10.12:/etc/kubernetes/ssl
scp admin*.pem 192.168.10.13:/etc/kubernetes/ssl

#3.创建kubectl的kubeconfig
#apiserver的VIP是192.168.10.100:8443

#设置集群参数
kubectl config set-cluster kubernetes \
 --certificate-authority=ca.pem \
 --embed-certs=true \
 --server=https://192.168.10.100:8443 \
 --kubeconfig=kubectl.kubeconfig

#设置客户端认证参数
kubectl config set-credentials admin \
 --client-certificate=admin.pem \
 --client-key=admin-key.pem \
 --embed-certs=true \
 --kubeconfig=kubectl.kubeconfig

#设置上下文参数
kubectl config set-context kubernetes \
 --cluster=kubernetes \
 --user=admin \
 --kubeconfig=kubectl.kubeconfig

#设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig

#生成文件:kubectl.kubeconfig
#为所有kubectl机器分发文件 -- 拷贝成 ~/.kube/config
mkdir -p /root/.kube/

cp -rp kubectl.kubeconfig /root/.kube/config
scp kubectl.kubeconfig 192.168.10.12:/root/.kube/config
scp kubectl.kubeconfig 192.168.10.13:/root/.kube/config
  • --certificate-authority:验证 kube-apiserver 证书的根证书;
  • --client-certificate--client-key:刚生成的 admin 证书和私钥,与 kube-apiserver https 通信时使用;
  • --embed-certs=true:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(否则,写入的是证书文件路径,后续拷贝 kubeconfig 到其它机器时,还需要单独拷贝证书文件,不方便。);
  • --server:指定 kube-apiserver 的地址,这里指向第一个节点上的服务;

apiserver

kube-apiserver是k8s的访问核心,所有K8S组件和用户kubectl操作都会请求kube-apiserver,通常启用tls证书认证,证书里面需要包含kube-apiserver可能被访问的地址,这样client校验kube-apiserver证书时才会通过,集群内的Pod一般通过kube-apiserver的Service名称访问。集群外一般是Master集群节点,CLUSTER IP和Master负载均衡器地址访问。

准备证书

#1.准备CSR文件,hosts字段指定授权使用该证书的IP或域名列表
cat < apiserver-csr.json 
{
  "CN": "kubernetes",
  "hosts": [
    "127.0.0.1",
    "10.254.0.1",
    "192.168.10.11",
    "192.168.10.12",
    "192.168.10.13",
    "192.168.10.100",
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "Kubernetes",
      "OU": "System"
    }
  ]
}
EOF

#2.生成证书和密钥
cfssl gencert -ca=ca.pem \
 -ca-key=ca-key.pem \
 -config=ca-config.json \
 -profile=kubernetes \
 apiserver-csr.json | cfssljson -bare apiserver

#3.生成2个重要文件
apiserver-key.pem #证书密钥
apiserver.pem #证书

#4.把apiserver公钥和私钥拷贝到每个master节点
cp apiserver*.pem /etc/kubernetes/ssl
scp apiserver*.pem 192.168.10.12:/etc/kubernetes/ssl/
scp apiserver*.pem 192.168.10.13:/etc/kubernetes/ssl/

#5.加密配置文件
cat < /etc/kubernetes/encryption-config.yaml 
kind: EncryptionConfig
apiVersion: v1
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: $(head -c 32 /dev/urandom | base64)
      - identity: {}
EOF

scp /etc/kubernetes/encryption-config.yaml 192.168.10.12:/etc/kubernetes/
scp /etc/kubernetes/encryption-config.yaml 192.168.10.13:/etc/kubernetes/

#6.metrics-server使用的证书
cat < metrics-server-csr.json 
{
  "CN": "aggregator",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "Kubernetes",
      "OU": "System"
    }
  ]
}
EOF

#7.生成证书和密钥
cfssl gencert -ca=ca.pem \
 -ca-key=ca-key.pem  \
 -config=ca-config.json  \
 -profile=kubernetes \
 metrics-server-csr.json | cfssljson -bare metrics-server
 
cp metrics-server*.pem /etc/kubernetes/ssl
scp metrics-server*.pem 192.168.10.12:/etc/kubernetes/ssl/
scp metrics-server*.pem 192.168.10.13:/etc/kubernetes/ssl/

部署服务

#1.启动服务
cat < /etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes APIServer
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/sbin/kube-apiserver \\
 --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
 --anonymous-auth=false \\
 --secure-port=6443 \\
 --bind-address=0.0.0.0 \\
 --advertise-address=192.168.10.11 \\
 --authorization-mode=Node,RBAC \\
 --runtime-config=api/all=true \\
 --enable-bootstrap-token-auth \\
 --max-mutating-requests-inflight=2000 \\
 --max-requests-inflight=4000 \\
 --delete-collection-workers=2 \\
 --service-node-port-range=30000-40000 \\
 --service-cluster-ip-range=10.254.0.0/16 \\
 --service-account-issuer=api \\
 --service-account-key-file=/etc/kubernetes/ssl/ca.pem \\
 --service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \\
 --client-ca-file=/etc/kubernetes/ssl/ca.pem \\
 --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem \\
 --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem \\
 --etcd-cafile=/etc/kubernetes/ssl/ca.pem \\
 --etcd-certfile=/etc/kubernetes/ssl/apiserver.pem \\
 --etcd-keyfile=/etc/kubernetes/ssl/apiserver-key.pem \\
 --etcd-servers=https://192.168.10.11:2379,https://192.168.10.12:2379,https://192.168.10.13:2379 \\
 --kubelet-timeout=10s \\
 --kubelet-certificate-authority=/etc/kubernetes/ssl/ca.pem \\
 --kubelet-client-key=/etc/kubernetes/ssl/apiserver-key.pem \\
 --kubelet-client-certificate=/etc/kubernetes/ssl/apiserver.pem \\
 --encryption-provider-config=/etc/kubernetes/encryption-config.yaml \\
 --proxy-client-cert-file=/etc/kubernetes/ssl/metrics-server.pem \\
 --proxy-client-key-file=/etc/kubernetes/ssl/metrics-server-key.pem \\
 --requestheader-allowed-names="" \\
 --requestheader-group-headers=X-Remote-Group \\
 --requestheader-username-headers=X-Remote-User \\
 --requestheader-extra-headers-prefix="X-Remote-Extra-" \\
 --requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem \\
 --allow-privileged=true \\
 --apiserver-count=3 \\
 --audit-log-maxage=30 \\
 --audit-log-maxbackup=3 \\
 --audit-log-maxsize=100 \\
 --audit-log-truncate-enabled \\
 --audit-log-path=/var/log/kubernetes/kube-apiserver/apiserver.log \\
 --event-ttl=168h \\
 --v=2
Restart=on-failure
RestartSec=10
Type=notify
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

#如果apiserver机器上没运行kube-proxy,则还需要添加--enable-aggregator-routing=true参数

mkdir -p /var/log/kubernetes/kube-apiserver

#启动kube-apiserver
systemctl daemon-reload \
&& systemctl start kube-apiserver \
&& systemctl enable kube-apiserver \
&& systemctl status kube-apiserver

#2.检查
netstat -lntup | grep kube-apiserve
####显示如下
tcp6  0  0  :::6443  :::*  LISTEN  850/kube-apiserver

kubectl cluster-info
####显示如下
Kubernetes control plane is running at https://192.168.10.100:8443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

###访问有返回说明正常
curl -k https://127.0.0.1:6443/

授权访问kubelet

kube-apiserver有些情况也会访问kubelet,比如获取metrics、查看容器日志或登录容器,这时kubelet 作为server,kube-apiserver作为client,kubelet监听的https,kube-apiserver经过证书认证访问kubelet,但还需要经过授权才能成功调用接口,我们通过创建RBAC规则授权kube-apiserver访问kubelet。

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - proxy
- apiGroups:
  - ""
  resources:
  - nodes/proxy
  - nodes/stats
  - nodes/log
  - nodes/spec
  - nodes/metrics
  verbs:
  - "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: kubernetes
EOF

#查看
kubectl get clusterrole system:kube-apiserver-to-kubelet
kubectl get ClusterRoleBinding system:kube-apiserver
#或使用 describe查看描述信息

#或者执行下面的命令
kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes

controller-manager

该集群包含 3 个节点,启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用时,阻塞的节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。

准备证书

#1.准备CSR文件
cat < kube-controller-manager-csr.json 
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "hosts": [
    "127.0.0.1",
    "192.168.10.11",
    "192.168.10.12",
    "192.168.10.13",
    "192.168.10.100"
  ],
  "names": [
    {
    "C": "CN",
    "ST": "ShangHai",
    "L": "ShangHai",
    "O": "system:kube-controller-manager",
    "OU": "System"
    }
  ]
}
EOF

#hosts列表包含所有kube-controller-manager节点IP,
#CN和O 为system:kube-controller-manager
#kubernetes内置的ClusterRoleBindings system:kube-controller-manager赋予kube-controller-manager工作所需的权限。

#2.生成证书
cfssl gencert -ca=ca.pem \
 -ca-key=ca-key.pem \
 -config=ca-config.json \
 -profile=kubernetes \
 kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager

#3.两个重要的文件
kube-controller-manager-key.pem #kube-controller-manager证书密钥
kube-controller-manager.pem #kube-controller-manager证书
#拷贝到所有master节点
cp kube-controller-manager*.pem /etc/kubernetes/ssl/
scp kube-controller-manager*.pem 192.168.10.12:/etc/kubernetes/ssl/
scp kube-controller-manager*.pem 192.168.10.13:/etc/kubernetes/ssl/

#apiserver有多个实例,前面挂了vip的地址和nginx代理后的端口https://192.168.10.100:8443
#4.创建kubeconfig文件
kubectl config set-cluster kubernetes \
 --certificate-authority=ca.pem \
 --embed-certs=true \
 --server=https://192.168.10.100:8443 \
 --kubeconfig=kube-controller-manager.kubeconfig

kubectl config set-credentials system:kube-controller-manager \
 --client-certificate=kube-controller-manager.pem \
 --client-key=kube-controller-manager-key.pem \
 --embed-certs=true \
 --kubeconfig=kube-controller-manager.kubeconfig

kubectl config set-context system:kube-controller-manager \
 --cluster=kubernetes \
 --user=system:kube-controller-manager \
 --kubeconfig=kube-controller-manager.kubeconfig

kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig

#生成文件:kube-controller-manager.kubeconfig拷贝到所有master节点
cp kube-controller-manager.kubeconfig /etc/kubernetes/
scp kube-controller-manager.kubeconfig 192.168.10.12:/etc/kubernetes/
scp kube-controller-manager.kubeconfig 192.168.10.13:/etc/kubernetes/

部署服务

#1.启动服务
cat < /etc/systemd/system/kube-controller-manager.service  
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/sbin/kube-controller-manager \\
 --bind-address=127.0.0.1 \\
 --service-cluster-ip-range=10.254.0.0/16 \\
 --master=https://192.168.10.100:8443 \\
 --concurrent-service-syncs=2 \\
 --concurrent-deployment-syncs=10 \\
 --concurrent-gc-syncs=30 \\
 --controllers=*,bootstrapsigner,tokencleaner \\
 --cluster-cidr=172.30.0.0/16 \\
 --cluster-name=kubernetes \\
 --client-ca-file=/etc/kubernetes/ssl/ca.pem \\
 --cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \\
 --cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \\
 --cluster-signing-duration=876000h \\
 --service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \\
 --root-ca-file=/etc/kubernetes/ssl/ca.pem \\
 --tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem \\
 --tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem \\
 --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \\
 --authentication-kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \\
 --authorization-kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig \\
 --requestheader-allowed-names="" \\
 --requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem \\
 --requestheader-extra-headers-prefix="X-Remote-Extra-" \\
 --requestheader-group-headers=X-Remote-Group \\
 --requestheader-username-headers=X-Remote-User \\
 --use-service-account-credentials=true \\
 --feature-gates=RotateKubeletServerCertificate=true \\
 --horizontal-pod-autoscaler-sync-period=10s \\
 --kube-api-qps=1000 \\
 --kube-api-burst=2000 \\
 --leader-elect=true \\
 --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

#2.启动kube-controller-manager
systemctl daemon-reload \
&& systemctl start kube-controller-manager \
&& systemctl enable kube-controller-manager \
&& systemctl status kube-controller-manager

#3.检查
netstat -lantup|grep kube-control
tcp6 0 0 :::10252 :::* LISTEN 9100/kube-controlle 
tcp6 0 0 :::10257 :::* LISTEN 9100/kube-controlle 

scheduler

该集群包含 3 个节点,启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。

准备证书

#1.准备CSR文件
cat < kube-scheduler-csr.json 
{
  "CN": "system:kube-scheduler",
  "hosts": [
    "127.0.0.1",
    "192.168.10.11",
    "192.168.10.12",
    "192.168.10.13",
    "192.168.10.100"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "system:kube-scheduler",
      "OU": "System"
    }
  ]
}
EOF

#hosts:列表包含所有kube-scheduler节点IP;
#CN和O:为system:kube-scheduler,
#kubernetes内置的ClusterRoleBindings system:kube-scheduler将赋予kube-scheduler工作所需的权限。

#2.生成证书
cfssl gencert -ca=ca.pem \
 -ca-key=ca-key.pem \
 -config=ca-config.json \
 -profile=kubernetes \
 kube-scheduler-csr.json | cfssljson -bare kube-scheduler

#3.生成两个重要文件
kube-scheduler-key.pem #kube-scheduler证书密钥
kube-scheduler.pem #kube-scheduler证书公钥
##拷贝到所有master节点
cp kube-scheduler*.pem /etc/kubernetes/ssl/
scp kube-scheduler*.pem 192.168.10.12:/etc/kubernetes/ssl/
scp kube-scheduler*.pem 192.168.10.13:/etc/kubernetes/ssl/

#apiserver https://192.168.10.100:8443
#4.创建kubeconfig文件
kubectl config set-cluster kubernetes \
 --certificate-authority=ca.pem \
 --embed-certs=true \
 --server=https://192.168.10.100:8443 \
 --kubeconfig=kube-scheduler.kubeconfig

kubectl config set-credentials system:kube-scheduler \
 --client-certificate=kube-scheduler.pem \
 --client-key=kube-scheduler-key.pem \
 --embed-certs=true \
 --kubeconfig=kube-scheduler.kubeconfig

kubectl config set-context system:kube-scheduler \
 --cluster=kubernetes \
 --user=system:kube-scheduler \
 --kubeconfig=kube-scheduler.kubeconfig

kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig

#5.生成文件kube-scheduler.kubeconfig
cp kube-scheduler.kubeconfig /etc/kubernetes/
scp kube-scheduler.kubeconfig 192.168.10.12:/etc/kubernetes/
scp kube-scheduler.kubeconfig 192.168.10.13:/etc/kubernetes/

部署服务

#1.systemd文件
cat < /etc/systemd/system/kube-scheduler.service 
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/sbin/kube-scheduler \\
 --bind-address=127.0.0.1 \\
 --kube-api-burst=200 \\
 --kube-api-qps=100 \\
 --kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \\
 --authentication-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \\
 --authorization-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \\
 --client-ca-file=/etc/kubernetes/ssl/ca.pem \\
 --tls-cert-file=/etc/kubernetes/ssl/kube-scheduler.pem \\
 --tls-private-key-file=/etc/kubernetes/ssl/kube-scheduler-key.pem \\
 --requestheader-allowed-names="" \\
 --requestheader-client-ca-file=/etc/kubernetes/ssl/ca.pem \\
 --requestheader-extra-headers-prefix="X-Remote-Extra-" \\
 --requestheader-group-headers=X-Remote-Group \\
 --requestheader-username-headers=X-Remote-User \\
 --leader-elect=true \\
 --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

#2.启动服务
systemctl daemon-reload \
&& systemctl enable kube-scheduler \
&& systemctl start kube-scheduler \
&& systemctl status kube-scheduler

#3.检查
netstat -lantup|grep kube-schedule
tcp  0 0 127.0.0.1:10251 0.0.0.0:* LISTEN 9495/kube-scheduler 
tcp6 0 0 :::10259        :::*      LISTEN 9495/kube-scheduler

kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok                  
controller-manager   Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   
etcd-2               Healthy   {"health":"true"} 

部署woker

Worker节点主要安装kubelet来管理、运行工作负载,kube-proxy来实现Service的通信与负载均衡。 (Master 节点也可以部署为特殊 Worker 节点来部署关键服务)。

containerd

kubernetes在1.24版本之后就要抛弃docker-shim组件,容器运行时也是从docker转换到了containerd

containerd 实现了kubernetes的Container Runtime Interface (CRI)接口,提供容器运行时核心功能,如镜像管理、容器管理等,相比dockerd更加简单、健壮和可移植。

#1.拷贝二进制
wget https://github.com/containerd/nerdctl/releases/download/v1.4.0/nerdctl-full-1.4.0-linux-amd64.tar.gz

#2.配置启动文件
cat < /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/usr/local/sbin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
Type=notify
TasksMax=infinity

[Install]
WantedBy=multi-user.target
EOF

#3.生成config.toml
mkdir -p /etc/containerd
##自动生成配置,参考我修改好的配置文件
containerd config default > /etc/containerd/config.toml

#4.修改config.toml  
sandbox_image = "registry.k8s.io/pause:3.8"
####镜像如果拉取不到可改成阿里源的####
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.8"

sed -i 's/registry.k8s.io\/pause:3.8/registry.aliyuncs.com\/google_containers\/pause:3.8/' /etc/containerd/config.toml

#5.启动
systemctl daemon-reload \
&& systemctl start containerd \
&& systemctl enable containerd \
&& systemctl status containerd

nerdctl

nerdctl用来兼容docker cli,可以像docker命令一样来管理本地的镜像和容器

二进制包拷贝到usr/local/sbin,就可以,会监听
unix:///run/containerd/containerd.sock

kubelet

kubelet运行在每 worker节点上,接收kube-apiserver发送的请求,管理Pod容器,执行交互式命令,如 exec、run、logs等。kubelet启动时自动向kube-apiserver注册节点信息,内置的cadvisor统计和监控节点的资源使用情况。

kubelet 启动时自动向 kube-apiserver 注册节点信息,内置的 cadvisor 统计和监控节点的资源使用情况。

kubeconfig

bootstrap token用于kubelet自动请求签发证书,以Secret形式存储,不需要事先给apiserver配置静态token,这样也易于管理。

创建了bootstrap token后我们利用它使用它来创建
kubelet-bootstrap.kubeconfig以供后面部署 Worker节点用 (kubelet使用
kubelet-bootstrap.kubeconfig自动创建证书)

export BOOTSTRAP_TOKEN=$(kubeadm token create \
 --description kubelet-bootstrap-token \
 --groups system:bootstrappers:kubelet \
 --kubeconfig ~/.kube/config)

#查看创建的token
kubeadm token list --kubeconfig ~/.kube/config
####
x8cwv4.hqo4ju9kalaecqcj  23h  2023-03-19T13:14:48+08:00  authentication,signing  kubelet-bootstrap-token  system:bootstrappers:kubelet

#查看token关联的Secret
kubectl get secrets -n kube-system|grep bootstrap
###
bootstrap-token-dv49cd  bootstrap.kubernetes.io/token  7  52s

kubectl config set-cluster bootstrap \
 --certificate-authority=ca.pem \
 --embed-certs=true \
 --server=https://192.168.10.100:8443 \
 --kubeconfig=kubelet-bootstrap.kubeconfig

kubectl config set-credentials kubelet-bootstrap \
 --token=${BOOTSTRAP_TOKEN} \
 --kubeconfig=kubelet-bootstrap.kubeconfig

kubectl config set-context bootstrap \
 --cluster=bootstrap \
 --user=kubelet-bootstrap \
 --kubeconfig=kubelet-bootstrap.kubeconfig

kubectl config use-context bootstrap \
 --kubeconfig=kubelet-bootstrap.kubeconfig

#生成文件kubelet-bootstrap.kubeconfig,拷贝到所有节点
cp kubelet-bootstrap.kubeconfig /etc/kubernetes/
scp kubelet-bootstrap.kubeconfig 192.168.10.12:/etc/kubernetes/
scp kubelet-bootstrap.kubeconfig 192.168.10.13:/etc/kubernetes/

部署服务

#1.启动配置 config.yaml
cat < /etc/kubernetes/kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: "192.168.10.11"
staticPodPath: ""
syncFrequency: 1m
fileCheckFrequency: 20s
httpCheckFrequency: 20s
staticPodURL: ""
port: 10250
readOnlyPort: 0
rotateCertificates: true
serverTLSBootstrap: true
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
    cacheTTL: 2m0s
  x509:
    clientCAFile: "/etc/kubernetes/ssl/ca.pem"
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
registryPullQPS: 0
registryBurst: 20
eventRecordQPS: 0
eventBurst: 20
enableDebuggingHandlers: true
enableContentionProfiling: true
healthzPort: 10248
healthzBindAddress: "192.168.10.11"
clusterDomain: "cluster.local"
clusterDNS:
  - "10.254.0.2"
nodeStatusUpdateFrequency: 10s
nodeStatusReportFrequency: 1m
imageMinimumGCAge: 2m
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
volumeStatsAggPeriod: 1m
kubeletCgroups: ""
systemCgroups: ""
cgroupRoot: ""
cgroupsPerQOS: true
cgroupDriver: cgroupfs
runtimeRequestTimeout: 10m
hairpinMode: promiscuous-bridge
maxPods: 220
podCIDR: "172.30.0.0/16"
podPidsLimit: -1
resolvConf: "/etc/resolv.conf"
maxOpenFiles: 1000000
kubeAPIQPS: 1000
kubeAPIBurst: 2000
serializeImagePulls: false
evictionHard:
  memory.available:  "100Mi"
  nodefs.available:  "10%"
  nodefs.inodesFree: "5%"
  imagefs.available: "15%"
evictionSoft: {}
enableControllerAttachDetach: true
failSwapOn: true
containerLogMaxSize: 20Mi
containerLogMaxFiles: 10
systemReserved: {}
kubeReserved: {}
systemReservedCgroup: ""
kubeReservedCgroup: ""
enforceNodeAllocatable: ["pods"]
EOF

#2.配置kubelet.service
cat < /etc/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service

[Service]
WorkingDirectory=/app/kubelet
ExecStart=/usr/local/sbin/kubelet \\
 --runtime-request-timeout=15m \\
 --container-runtime-endpoint=unix:///run/containerd/containerd.sock \\
 --bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig \\
 --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
 --config=/etc/kubernetes/kubelet-config.yaml \\
 --cert-dir=/etc/kubernetes/ssl \\
 --hostname-override=192.168.10.11 \\
 --register-node=true \\
 --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

#3.启动服务
mkdir -p /app/kubelet

systemctl daemon-reload
systemctl enable --now kubelet.service && systemctl status kubelet.service 

approveCSR

CSR是什么?

CSR是Certificate Signing Request的英文缩写,即证书签名请求文件,是证书申请者在申请数字证书时由CSP(加密服务提供者)在生成私钥的同时也生成证书请求文件,证书申请者只要把CSR文件提交给证书颁发机构后,证书颁发机构使用其根证书私钥签名就生成了证书公钥文件,也就是颁发给用户的证书。

节点kubelet通过Bootstrap Token调用apiserver CSR API请求签发证书,kubelet通过bootstrap token认证后会在system:bootstrappers用户组里,我们还需要给它授权调用CSR API,为这个用户组绑定预定义的system:node-bootstrapper这个ClusterRole就可以。

kublet启动时查找配置的--kubeletconfig文件是否存在,如果不存在则使用--bootstrap-kubeconfig向kube-apiserver发送证书签名请求 (CSR)。kube-apiserver收到CSR请求后,对其中的 Token进行认证(事先使用 kubeadm 创建的 token),认证通过后将请求的user设置为 system:bootstrap,group设置为system:bootstrappers,这一过程称为Bootstrap Token Auth。

#创建一个clusterrolebinding,将 group system:bootstrappers和clusterrole system:node-bootstrapper绑定:

cat <<EOF | kubectl apply -f -
# enable bootstrapping nodes to create CSR
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: create-csrs-bootstrap
subjects:
- kind: Group
  name: system:bootstrappers
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: system:node-bootstrapper
  apiGroup: rbac.authorization.k8s.io
EOF

#然后启动
systemctl daemon-reload \
&& systemctl enable kubelet \
&& systemctl start kubelet \
&& systemctl status kubelet

#检查服务
netstat -lantp|grep kubelet
tcp  0  0 127.0.0.1:10248      0.0.0.0:*            LISTEN      44809/kubelet
tcp  0  0 192.168.10.23:52402  192.168.10.200:8443  ESTABLISHED 44809/kubelet
tcp  0  0 192.168.10.23:52390  192.168.10.200:8443  ESTABLISHED 44809/kubelet
tcp6 0  0 :::10250             :::*                 LISTEN      44809/kubelet
#查看CSR列表
kubectl get csr
###显示如下###
NAME      AGE SIGNERNAME                                  REQUESTOR               CONDITION
csr-54b9r 42s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:y6mj17 Pending
csr-bmvfm 43s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:y6mj17 Pending
csr-szxrd 43s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:y6mj17 Pending

#自动approve csr请求
cat <<EOF | kubectl apply -f -
# Approve all CSRs for the group "system:bootstrappers"
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: auto-approve-csrs-for-group
subjects:
- kind: Group
  name: system:bootstrappers
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
  apiGroup: rbac.authorization.k8s.io
---
# To let a node of the group "system:nodes" renew its own credentials
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: node-client-cert-renewal
subjects:
- kind: Group
  name: system:nodes
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
  apiGroup: rbac.authorization.k8s.io
---
# A ClusterRole which instructs the CSR approver to approve a node requesting a
# serving cert matching its client cert.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: approve-node-server-renewal-csr
rules:
- apiGroups: ["certificates.k8s.io"]
  resources: ["certificatesigningrequests/selfnodeserver"]
  verbs: ["create"]
---
# To let a node of the group "system:nodes" renew its own server credentials
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: node-server-cert-renewal
subjects:
- kind: Group
  name: system:nodes
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: approve-node-server-renewal-csr
  apiGroup: rbac.authorization.k8s.io
EOF

#auto-approve-csrs-for-group:自动approve node的第一次CSR,注意第一次CSR时,请求的Group 为system:bootstrappers
#node-client-cert-renewal:自动approve node后续过期的client证书,自动生成的证书Group为 system:nodes;
#node-server-cert-renewal:自动approve node后续过期的server证书,自动生成的证书Group为system:nodes;



#遇到问题:server证书不能自动审批,是基于安全性考虑CSR approving controllers不会自动approve kubelet server证书签名请求,需要手动approve使用命令kubectl certificate approve 
kubectl get csr|grep Pending
csr-6vs4g 2m16s kubernetes.io/kubelet-serving system:node:192.168.10.12 Pending
csr-pzbph 2m23s kubernetes.io/kubelet-serving system:node:192.168.10.13 Pending
csr-zpmwz 2m23s kubernetes.io/kubelet-serving system:node:192.168.10.11 Pending

kubectl certificate approve  #批准证书签名请求
kubectl certificate deny  #拒绝证书签名请求
#批量手动批准
kubectl get csr|grep 'Pending' | awk 'NR>0{print $1}'| xargs kubectl certificate approve

#查看node,因为没有装网络插件,节点状态会是NotReady
kubectl get node
NAME            STATUS     ROLES    AGE     VERSION
192.168.10.11   NotReady      19s     v1.27.3
192.168.10.12   NotReady      35s     v1.27.3
192.168.10.13   NotReady      8s      v1.27.3

kube-proxy

kube-proxy运行在所有worker节点上,它监听apiserver中service和endpoint的变化情况,创建路由规则以提供服务IP和负载均衡功能。

准备证书

cat < kube-proxy-csr.json 
{
  "CN": "system:kube-proxy",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "ShangHai",
      "L": "ShangHai",
      "O": "Kubernetes",
      "OU": "System"
    }
  ]
}
EOF

#CN:指定该证书的User为system:kube-proxy;
#预定义的RoleBinding system:node-proxier将User system:kube-proxy与Role system:node-proxier绑定,该Role授予了调用kube-apiserver Proxy相关API的权限。

#生成证书和私钥
cfssl gencert -ca=ca.pem \
 -ca-key=ca-key.pem \
 -config=ca-config.json \
 -profile=kubernetes \
 kube-proxy-csr.json | cfssljson -bare kube-proxy
#生成2个文件
kube-proxy-key.pem
kube-proxy.pem   

cp kube-proxy*.pem /etc/kubernetes/ssl/
scp kube-proxy*.pem 192.168.10.12:/etc/kubernetes/ssl/
scp kube-proxy*.pem 192.168.10.13:/etc/kubernetes/ssl/

#创建kubeconfig文件
kubectl config set-cluster kubernetes \
 --certificate-authority=ca.pem \
 --embed-certs=true \
 --server=https://192.168.10.100:8443 \
 --kubeconfig=kube-proxy.kubeconfig

kubectl config set-credentials kube-proxy \
 --client-certificate=kube-proxy.pem \
 --client-key=kube-proxy-key.pem \
 --embed-certs=true \
 --kubeconfig=kube-proxy.kubeconfig

kubectl config set-context default \
 --cluster=kubernetes \
 --user=kube-proxy \
 --kubeconfig=kube-proxy.kubeconfig

kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

cp kube-proxy.kubeconfig /etc/kubernetes/
scp kube-proxy.kubeconfig 192.168.10.12:/etc/kubernetes/
scp kube-proxy.kubeconfig 192.168.10.13:/etc/kubernetes/

部署服务

#1.配置文件
cat < /etc/kubernetes/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
  burst: 200
  kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
  qps: 100
clusterCIDR: 172.30.0.0/16
bindAddress: 192.168.10.11
hostnameOverride: 192.168.10.11
healthzBindAddress: 192.168.10.11:10256
metricsBindAddress: 192.168.10.11:10249
enableProfiling: true
mode: "ipvs"
portRange: ""
iptables:
  masqueradeAll: false
ipvs:
  scheduler: rr
  excludeCIDRs: []
EOF

#2.kube-proxy.service
cat < /etc/systemd/system/kube-proxy.service
[Unit]
Description=Kube-Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
WorkingDirectory=/app/kube-proxy
ExecStart=/usr/local/sbin/kube-proxy \\
 --config=/etc/kubernetes/kube-proxy-config.yaml \\
 --v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

#3.启动服务
mkdir -p /app/kube-proxy

systemctl daemon-reload \
 && systemctl enable kube-proxy \
 && systemctl restart kube-proxy \
 && systemctl status kube-proxy
 
#4.检查
netstat -lantup|grep kube-proxy
tcp  0  0 192.168.10.21:10249  0.0.0.0:*  LISTEN  46560/kube-proxy
tcp  0  0 192.168.10.21:10256  0.0.0.0:*  LISTEN  46560/kube-proxy

ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP  10.254.0.1:443 rr
  -> 192.168.10.11:6443  Masq    1      0          0 
  -> 192.168.10.12:6443  Masq    1      0          0
  -> 192.168.10.13:6443  Masq    1      0          0

calico

所有的节点都需要安装calico,主要目的是跨主机的docker能够互相通信,也是保障kubernetes集群的网络基础和保障。

calico使用IPIP或BGP技术(默认为IPIP)为各节点创建一个可以互通的Pod网络。参考官网

#1.下载清单
wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
  
#2.修改pod网络
- name: CALICO_IPV4POOL_CIDR
  value: "172.30.0.0/16"
  
#3.创建
kubectl apply -f calico.yaml

#4.查看
kubectl get pod -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS     AGE
kube-system   calico-kube-controllers-85578c44bf-9vxn6   1/1     Running   0            2m
kube-system   calico-node-4qghn                          1/1     Running   0            2m
kube-system   calico-node-6bc44                          1/1     Running   0            2m
kube-system   calico-node-77bf8                          1/1     Running   0            2m

coredns

CoreDNS就是一个DNS服务,而DNS作为一种常见的服务发现手段,所以很多开源项目以及工程师都会使用 CoreDNS为集群提供服务发现的功能,Kubernetes就在集群中使用CoreDNS解决服务发现的问题。

k8s版本包里提供了dns的yaml文件,在kubernetes-src\cluster\addons\dns目录里。

#1.修改配置
sed -i -e "s/__DNS__DOMAIN__/cluster.local/g" \
-e "s/__DNS__MEMORY__LIMIT__/500Mi/g" \
-e "s/__DNS__SERVER__/10.254.0.2/g" coredns.yaml.base

#镜像改成阿里云
image: registry.aliyuncs.com/google_containers/coredns:v1.10.1

#2.创建服务
mv coredns.yaml.base coredns.yaml
kubectl create -f coredns.yaml -n kube-system

#3.查看pod
kubectl get pod -n kube-system
kube-system   coredns-5bfcdcfd96-pgttd   1/1     running   0    11s

验证集群

#1.检查节点状态
kubectl get node
NAME            STATUS   ROLES    AGE     VERSION
192.168.10.11   Ready       6m     v1.27.3
192.168.10.12   Ready       5m     v1.27.3
192.168.10.13   Ready       6m     v1.27.3
#2.部署服务
cat <<EOF nginx.yml | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
  name: nginx-ds
  labels:
    app: nginx-ds
spec:
  type: NodePort
  selector:
    app: nginx-ds
  ports:
  - name: http
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ds
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  selector:
    matchLabels:
      app: nginx-ds
  template:
    metadata:
      labels:
        app: nginx-ds
    spec:
      containers:
      - name: my-nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
EOF

#3.验证
node节点上访问svc和nodeport端口
进入pod访问,其他节点的pod IP

相关推荐

网站建设:从新手到高手

现代化网站应用领域非常广泛,从个人形象网站展示、企业商业网站运作、到政府公益等服务网站,各行各业都需要网站建设。大体上可以归结四类:宣传型网站设计、产品型网站制作、电子商务型网站建设、定制型功能网站开...

JetBrains 推出全新 AI 编程工具 Junie,助力高效开发

JetBrains宣布推出名为Junie的全新AI编程工具。这款工具不仅能执行简单的代码生成与检查任务,还能应对编写测试、验证结果等复杂项目,为开发者提供全方位支持。根据SWEBench...

AI也能写代码!代码生成、代码补全、注释生成、代码翻译轻松搞定

清华GLM技术团队打造的多语言代码生成模型CodeGeeX近期更新了新的开源版本「CodeGeeX2-6B」。CodeGeeX2是多语言代码生成模型CodeGeeX的第二代模型,不同于一代CodeG...

一键生成前后端代码,一个36k星的企业级低代码平台

「企业级低代码平台」前后端分离架构SpringBoot2.x,SpringCloud,AntDesign&Vue,Mybatis,Shiro,JWT。强大的代码生成器让前后端代码一键生成,无需写任...

Gitee 代码托管实战指南:5 步完成本地项目云端同步(附避坑要点)

核心流程拆解:远程仓库的搭建登录Gitee官网(注册账号比较简单,大家自行操作),点击“新建仓库”,建议勾选“初始化仓库”和“设置模板文件”(如.gitignore),避免上传临时文件。...

jeecg-boot 源码项目-强烈推荐使用

JEECGBOOT低代码开发平台...

JetBrains推出全新AI编程工具Junie,强调以开发者为中心

IT之家2月1日消息,JetBrains发文,宣布推出一款名为Junie的全新AI编程工具,官方声称这款AI工具既能执行简单的代码生成与检查等基础任务,也能应对“编写测试、验证结...

JetBrains旗下WebStorm和Rider现已加入“非商用免费”阵营

IT之家10月25日消息,软件开发商JetBrains今日宣布,旗下WebStorm(JavaScript开发工具)和Rider(.NET开发工具)现已加入“非商用免费”阵营。如果...

谈谈websocket跨域

了解websocketwebsocket是HTML5的新特性,在客户端和服务端提供了一个基于TCP连接的双向通道。...

websocket调试工具

...

利用webSocket实现消息的实时推送

1.什么是webSocketwebSocket实现实现推送消息WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。以前的推送技术使用Ajax轮询,浏览器需...

Flutter UI自动化测试技术方案选型与探索

...

为 Go 开发的 WebSocket 库

#记录我的2024#...

「Java基础」Springboot+Websocket的实现后端数据实时推送

这篇文章主要就是实现这个功能,只演示一个基本的案例。使用的是websocket技术。...

【Spring Boot】WebSocket 的 6 种集成方式

介绍...

取消回复欢迎 发表评论: