IP地址 | 机器名称 | 机器配置 | 操作系统 | 机器角色 | 安装软件 |
---|---|---|---|---|---|
192.168.6.1 | k8snode01 | 2C2G | CentOS 7.9 | master+worker+etcd | kube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy |
192.168.6.2 | k8snode02 | 2C2G | CentOS 7.9 | master+worker+etcd | kube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy |
192.168.6.3 | k8snode03 | 2C2G | CentOS 7.9 | master+worker+etcd | kube-apiserver、kube-controller-manager、kube-scheduler、etcd、kubelet、kube-proxy |
192.168.6.253 | 负载均衡VIP | ||||
10.254.0.1/16 | service网络 | ||||
10.0.0.0/16 | pod网络 | ||||
10.254.0.2 | coredns地址 |
此处使用haproxy + keepalived的方式实现实现kube-apiserver的高可用性,VIP为192.168.6.253;三个节点同时为master和worker及etcd集群节点。
软件 | 版本 | 官方下载地址 |
---|---|---|
kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy | v1.22.1 | https://github.com/kubernetes/kubernetes/tree/master/CHANGELOG |
docker-ce | v20.10.8 | https://download.docker.com/linux/centos/7/x86_64/stable/Packages |
etcd | v3.5.0 | https://github.com/etcd-io/etcd/releases |
calico(网络插件) | v3.20.0 | https://docs.projectcalico.org/manifests/calico-etcd.yaml |
coredns(dns插件) | 1.8.4 | https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed |
cfssl | v1.6.1 | https://github.com/cloudflare/cfssl/releases |
haproxy | 1.5.18 | yum安装 |
keepalived | v1.3.5 | yum安装 |
目录 | 节点 | 说明 |
---|---|---|
/opt/etcd/ssl | 所有 | etcd集群运行时所需要的证书 |
/opt/etcd/conf | 所有 | etcd集群运行时所需要的配置文件 |
/opt/etcd/bin | 所有 | etcd集群运行时所需要的二进制文件 |
/opt/kubernetes/ssl | 所有 | k8s集群运行时所需要的证书 |
/opt/kubernetes/conf | 所有 | k8s集群运行时所需要的配置文件 |
/opt/kubernetes/bin | 所有 | k8s集群运行时所需要的二进制文件(组件的二进制文件) |
/var/log/kubernetes | 所有 | k8s集群运行时日志的存放目录 |
/opt/cfssl | 所有 | cfssl二进制运行文件目录 |
/root/k8s/{etcd,k8s,cfssl,ssl} | k8snode01 | 部署集群时所使用的目录 |
/opt/calico | k8snode01 | calico组件安装目录 |
/opt/coredns | k8snode01 | coredns组件安装目录 |
修改主机名
修改主机名及IP,其对应关系如下:
主机名称 | IP地址 |
---|---|
k8snode01 | 192.168.6.1 |
k8snode02 | 192.168.6.2 |
k8snode03 | 192.168.6.3 |
配置hosts文件
将以下内容同时添加到三台主机上的/etc/hosts
文件中:
cat >> /etc/hosts << EOF
192.168.6.1 k8snode01
192.168.6.2 k8snode02
192.168.6.3 k8snode03
EOF
关闭防火墙和selinux
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/^SELINUX=.\*/SELINUX=disabled/' /etc/selinux/config
关闭交换分区
#临时关闭
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
echo "vm.swappiness=0" >> /etc/sysctl.conf
sysctl -p
时间同步
yum install -y ntp ntpdata
#修改/etc/ntp.conf文件内的server选项,如下:
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst
systemctl start ntpd
systemctl enable ntpd
配置系统环境变量
cat >> /etc/profile << 'EOF'
export ETCD_HOME=/opt/etcd
export CFSSL_HOME=/opt/cfssl
export K8S_HOME=/opt/kubernetes
export PATH=$ETCD_HOME/bin:$CFSSL_HOME:$K8S_HOME/bin:$PATH
EOF
source /etc/profile
配置免密钥登陆
#在k8snode01上执行以下命令
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8snode01
ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8snode02
ssh-copy-id -i ~/.ssh/id_rsa.pub root@k8snode03
安装IPVS
yum -y install epel-release
yum -y install ipvsadm ipset conntrack
cat >/etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
#查看相关模块是否已加载成功
lsmod | grep ip_vs
注意,在内核版本4.19以后,nf_conntrack_ipv4改名为nf_conntrack
升级系统内核
#安装ELRepo仓库
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
#查询可用版本号
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
#安装长期支持版(5.4.222-1)
yum -y --enablerepo=elrepo-kernel install kernel-lt kernel-lt-devel
#设置GRUB默认的内核启动版本
grub2-set-default 0
k8s对内核版本的最低要求为4.18.
配置内核参数
cat > /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 131072
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
sysctl --system
创建所需目录
#etcd运行时所需的证书目录及配置文件
mkdir -p /opt/etcd/{ssl,conf,bin}
#k8s组件运行时所需要的文件
mkdir -p /opt/kubernetes/{ssl,conf,bin}
#kubernetes日志目录
mkdir /var/log/kubernetes
#cfssl安装目录
mkdir /opt/cfssl
#搭建集群时用的的目录,只在k8snode01节点上创建此目录
mkdir -p /root/k8s/{etcd,k8s,cfssl,ssl}
采用比较常用的CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 证书和秘钥文件,CA 是自签名的证书,用来签名后续创建的其它 TLS 证书。
证书可以在任意节点生成,然后再拷贝到其他及节点;在这里使用k8snode01节点生成证书,生成证书时所使用的目录为/root/k8s/ssl目录。
在创建CA证书的过程中,如果没有特别说明,则工作目录为:/root/k8s/ssl
。因此,在进行下面的操作前需要将目录切换至/root/k8s/ssl
。
工具下载地址:
cfssl_linux-amd64:https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64
cfssljson_linux-amd64:https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64
cfssl-certinfo_linux-amd64:https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl-certinfo_1.6.1_linux_amd64
cfssl下载目录为:
/root/k8s/cfssl
。
安装cfssl:
cp /root/k8s/cfssl/cfssl_1.6.1_linux_amd64 /opt/cfssl/cfssl
cp /root/k8s/cfssl/cfssljson_1.6.1_linux_amd64 /opt/cfssl/cfssljson
cp /root/k8s/cfssl/cfssl-certinfo_1.6.1_linux_amd64 /opt/cfssl/cfssl-certinfo
chmod +x /opt/cfssl/cfssl
chmod +x /opt/cfssl/cfssljson
chmod +x /opt/cfssl/cfssl-certinfo
ca-csr.json中csr含义是:Certificate Signing Request,证书签名请求;因此看到 xx-csr.json,你就要知道该文件是证书签名请求文件,有了它,cfssl就可以生成证书和证书私钥了。
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "system"
}
],
"ca": {
"expiry": "87600h"
}
}
CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
O:Organization,组织名称,公司名称;kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group)
C:Country, 国家。
ST: State,州,省。
L: Locality,地区,城市。
OU: Organization Unit Name,组织单位名称,公司部门。
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
执行上述命令后当前目录下会生成三个文件:ca.csr
,ca-csr.json
、ca-key.pem
、ca.pem
。
在使用CA证书签发其他证书时会用到一个策略文件ca-config.json:
{
"signing": {
"default": {
"expiry": "175200h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "175200h"
}
}
}
}
signing:表示该证书可用于签名其它证书,生成的 ca.pem 证书中 CA=TRUE。
profiles: 指定证书使用场景,同一个文件中可以有多个profiles,后续签名生成证书及其私钥时需要指定该场景(profile)名称。
server auth:表示 client 可以用该证书对 server 提供的证书进行验证。
client auth:表示 server 可以用该证书对 client 提供的证书进行验证。
expiry: 175200h表示20年有效期。
etcd 是k8s集群最重要的组件,用来存储k8s的所有服务信息, etcd 挂了,集群就挂了,我们这里三台节点上全部部署etcd,实现etcd高可用;
etcd集群采用raft算法选举Leader, 由于Raft算法在做决策时需要多数节点的投票,所以etcd一般部署集群推荐奇数个节点,推荐的数量为3、5或者7个节点构成一个集群。
cd /root/k8s/etcd
wget https://github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz
tar -xvf etcd-v3.5.0-linux-amd64.tar.gz
cp ./etcd-v3.5.0-linux-amd64/etcd* /opt/etcd/bin
scp ./etcd-v3.5.0-linux-amd64/etcd* root@k8snode02:/opt/etcd/bin
scp ./etcd-v3.5.0-linux-amd64/etcd* root@k8snode03:/opt/etcd/bin
进入目录/root/k8s/ssl
,创建新的文件etcd-csr.json
,将以下内容添加到文件中:
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.6.1",
"192.168.6.2",
"192.168.6.3",
"192.168.6.4",
"192.168.6.5"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "system"
}
]
}
cd /root/k8s/ssl
cfssl gencert -ca=/root/k8s/ssl/ca.pem \
-ca-key=/root/k8s/ssl/ca-key.pem \
-config=/root/k8s/ssl/ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
cd /root/k8s/ssl
cp ./ca* ./etcd* /opt/etcd/ssl
scp ./ca* ./etcd* root@k8snode02:/opt/etcd/ssl
scp ./ca* ./etcd* root@k8snode03:/opt/etcd/ssl
正常情况下只需要copy这三个文件即可,ca.pem、etcd-key.pem、etcd.pem。
创建配置文件模板etcd.conf
,并将以下内容写入文件中:
#[Member]
ETCD_NAME="JIE_NAME"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://IP_ADDR:2380"
ETCD_LISTEN_CLIENT_URLS="https://IP_ADDR:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://IP_ADDR:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://IP_ADDR:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://192.168.6.1:2380,etcd2=https://192.168.6.2:2380,etcd3=https://192.168.6.3:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_NAME:节点名称,集群中唯一
ETCD_DATA_DIR:数据目录
ETCD_LISTEN_PEER_URLS:集群通信监听地址
ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址
ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
ETCD_INITIAL_CLUSTER:集群节点地址
ETCD_INITIAL_CLUSTER_TOKEN:集群Token
ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集群
创建配置文件etcd.service
,并将以下内容写入文件中:
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=-/opt/etcd/conf/etcd.conf
WorkingDirectory=/var/lib/etcd/
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/etcd.pem \
--key-file=/opt/etcd/ssl/etcd-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-cert-file=/opt/etcd/ssl/etcd.pem \
--peer-key-file=/opt/etcd/ssl/etcd-key.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-client-cert-auth \
--client-cert-auth
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
User=etcd
[Install]
WantedBy=multi-user.target
以下操作需要在所有的etcd集群节点上运行。
adduser -Ms /sbin/nologin etcd
mkdir /var/lib/etcd/
chown -R etcd:etcd /var/lib/etcd
#!/bin/bash
NODE_NAMES=("etcd1" "etcd2" "etcd3")
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
#替换模板文件中的变量,为各节点创建 systemd unit 文件
for (( i=0; i < 3; i++ ));do
echo ">>> ${NODE_IPS[i]}"
sed -e "s/JIE_NAME/${NODE_NAMES[i]}/g" -e "s/IP_ADDR/${NODE_IPS[i]}/g" ./etcd.conf > ./etcd-${NODE_IPS[i]}.conf
scp ./etcd-${NODE_IPS[i]}.conf root@${NODE_IPS[i]}:/opt/etcd/conf/etcd.conf
scp ./etcd.service root@${NODE_IPS[i]}:/etc/systemd/system/etcd.service
ssh root@${NODE_IPS[i]} "chown -R etcd:etcd /opt/etcd"
rm -f ./etcd-${NODE_IPS[i]}.conf
done
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd
etcdctl --cacert=/opt/etcd/ssl/ca.pem \
--cert=/opt/etcd/ssl/etcd.pem \
--key=/opt/etcd/ssl/etcd-key.pem \
--endpoints="https://192.168.6.1:2379,https://192.168.6.2:2379,https://192.168.6.3:2379" \
endpoint status --write-out=table
1、安装keepalived
yum install -y keepalived
2、配置keepalived
keepalived的配置文件位置:/etc/keepalived/keepalived.conf
#备份配置文件
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bk
#主节点(k8snode01)执行以下命令
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
router_id k8s
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 3
weight -2
fall 10
rise 2
}
vrrp_instance VI-kube-master {
state MASTER
interface enp0s8
virtual_router_id 51
priority 250
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab
}
virtual_ipaddress {
192.168.6.253
}
track_script {
check_haproxy
}
}
EOF
#从节点(k8snode02、k8snode03)执行以下命令
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
router_id k8s
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 3
weight -2
fall 10
rise 2
}
vrrp_instance VI-kube-master {
state BACKUP
interface enp0s8
virtual_router_id 51
priority 250
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab
}
virtual_ipaddress {
192.168.6.253
}
track_script {
check_haproxy
}
}
EOF
主节点与从节点在配置上唯一不同的是
state
,在主节点上state
的值为MASTER
,在从节点上state
的值为BACKUP
。
3、启动并检查keepalived服务
systemctl start keepalived.service
systemctl status keepalived.service
systemctl enable keepalived.service
启动keepalived服务后,使用命令ip a s enp0s8
就可以在k8snode01的enp0s8网卡上看到VIP。
1、安装haproxy
在所有主节点上执行以下命令:
yum install -y haproxy
2、配置haproxy
在所有主节点上执行以下命令:
#备份配置文件
mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bk
cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#---------------------------------------------------------------------
frontend kubernetes-apiserver
mode tcp
bind *:16443
option tcplog
default_backend kubernetes-apiserver
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiserver
mode tcp
balance roundrobin
server k8snode01 192.168.6.1:6443 check
server k8snode02 192.168.6.2:6443 check
server k8snode03 192.168.6.3:6443 check
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
bind *:1080
stats auth admin:awesomePassword
stats refresh 5s
stats realm HAProxy\ Statistics
stats uri /admin?stats
EOF
配置文件中指定了haproxy运行的端口为16443端口,因此16443端口为集群的入口。
3、启动并检查服务
systemctl start haproxy
systemctl enable haproxy.service
#检测服务状态
[root@k8snode02 ~]# netstat -tunlp | grep haproxy
tcp 0 0 0.0.0.0:1080 0.0.0.0:* LISTEN 7375/haproxy
tcp 0 0 0.0.0.0:16443 0.0.0.0:* LISTEN 7375/haproxy
udp 0 0 0.0.0.0:55425 0.0.0.0:* 7374/haproxy
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.6.1",
"192.168.6.2",
"192.168.6.3",
"192.168.6.4",
"192.168.6.5",
"192.168.6.253",
"10.254.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "system"
}
]
}
如果 hosts 字段不为空则需要指定授权使用该证书的 IP 或域名列表。
由于该证书后续被 kubernetes master 集群使用,需要将master节点的IP都填上,同时还需要填写 service 网络的首个IP。(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP,如 10.254.0.1)。
cd /root/k8s/k8s/config
cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
cfssl gencert \
-ca=/root/k8s/ssl/ca.pem -ca-key=/root/k8s/ssl/ca-key.pem -config=/root/k8s/ssl/ca-config.json \
-profile=kubernetes /root/k8s/ssl/kube-apiserver-csr.json | cfssljson -bare /root/k8s/ssl/kube-apiserver
# Log all requests at the Metadata level.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
KUBE_APISERVER_OPTS="--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \
--anonymous-auth=false \
--bind-address=local_ip \
--secure-port=6443 \
--advertise-address=local_ip \
--insecure-port=0 \
--authorization-mode=Node,RBAC \
--runtime-config=api/all=true \
--enable-bootstrap-token-auth \
--service-cluster-ip-range=10.254.0.1/16 \
--token-auth-file=/opt/kubernetes/conf/token.csv \
--service-node-port-range=30000-50000 \
--tls-cert-file=/opt/kubernetes/ssl/kube-apiserver.pem \
--tls-private-key-file=/opt/kubernetes/ssl/kube-apiserver-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--kubelet-client-certificate=/opt/kubernetes/ssl/kube-apiserver.pem \
--kubelet-client-key=/opt/kubernetes/ssl/kube-apiserver-key.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-issuer=https://kubernetes.default.svc.cluster.local \
--etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/etcd.pem \
--etcd-keyfile=/opt/etcd/ssl/etcd-key.pem \
--etcd-servers=https://192.168.6.1:2379,https://192.168.6.2:2379,https://192.168.6.3:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--apiserver-count=3 \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/log/kubernetes/kube-apiserver-audit.log \
--event-ttl=1h \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=4"
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=-/opt/kubernetes/conf/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
SSL_PATH='/root/k8s/ssl'
BIN_PATH='/root/k8s/k8s/kubernetes/server/bin'
BIN_FILE='kube-apiserver'
#替换模板文件中的变量,为各节点创建 systemd unit 文件
for (( i=0; i < 3; i++ ));do
echo ">>> ${NODE_IPS[i]}"
sed -e "s/local_ip/${NODE_IPS[i]}/g" /root/k8s/k8s/config/kube-apiserver.conf > /root/k8s/k8s/config/kube-apiserver-${NODE_IPS[i]}.conf
scp /root/k8s/k8s/config/kube-apiserver-${NODE_IPS[i]}.conf root@${NODE_IPS[i]}:/opt/kubernetes/conf/kube-apiserver.conf
scp /root/k8s/k8s/config/token.csv root@${NODE_IPS[i]}:/opt/kubernetes/conf/token.csv
scp /root/k8s/k8s/config/kube-apiserver.service root@${NODE_IPS[i]}:/etc/systemd/system/kube-apiserver.service
scp /root/k8s/k8s/config/audit-policy.yaml root@${NODE_IPS[i]}:/opt/kubernetes/conf/audit-policy.yaml
scp ${SSL_PATH}/ca* root@${NODE_IPS[i]}:/opt/kubernetes/ssl
scp ${SSL_PATH}/kube-apiserver* root@${NODE_IPS[i]}:/opt/kubernetes/ssl
scp ${BIN_PATH}/${BIN_FILE} root@${NODE_IPS[i]}:/opt/kubernetes/bin
done
systemctl daemon-reload
systemctl enable kube-apiserver
systemctl start kube-apiserver
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:masters",
"OU": "system"
}
]
}
cfssl gencert \
-ca=/root/k8s/ssl/ca.pem -ca-key=/root/k8s/ssl/ca-key.pem -config=/root/k8s/ssl/ca-config.json \
-profile=kubernetes /root/k8s/ssl/admin-csr.json | cfssljson -bare /root/k8s/ssl/admin
将生成的admin证书分发到所有需要安装kbuectl节点中:
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
SSL_PATH='/root/k8s/ssl'
#替换模板文件中的变量,为各节点创建 systemd unit 文件
for (( i=0; i < 3; i++ ));do
echo ">>> ${NODE_IPS[i]}"
scp ${SSL_PATH}/admin* root@${NODE_IPS[i]}:/opt/kubernetes/ssl
scp /root/k8s/k8s/kubernetes/server/bin/kubectl root@${NODE_IPS[i]}:/opt/kubernetes/bin
done
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.6.253:16443 \
--kubeconfig=/root/k8s/k8s/config/kube.config
kubectl config set-credentials admin \
--client-certificate=/opt/kubernetes/ssl/admin.pem \
--client-key=/opt/kubernetes/ssl/admin-key.pem \
--embed-certs=true \
--kubeconfig=/root/k8s/k8s/config/kube.config
kubectl config set-context kubernetes --cluster=kubernetes --user=admin --kubeconfig=/root/k8s/k8s/config/kube.config
kubectl config use-context kubernetes --kubeconfig=/root/k8s/k8s/config/kube.config
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
for node_ip in ${NODE_IPS[@]};do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p ~/.kube"
scp /root/k8s/k8s/config/kube.config root@${node_ip}:~/.kube/config
done
kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
上面步骤完成后,kubectl就可以与kube-apiserver通信了:
kubectl cluster-info
kubectl get componentstatuses
kubectl get all --all-namespaces
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
kubectl completion bash > ~/.kube/completion.bash.inc
source '/root/.kube/completion.bash.inc'
source $HOME/.bash_profile
{
"CN": "system:kube-controller-manager",
"key": {
"algo": "rsa",
"size": 2048
},
"hosts": [
"127.0.0.1",
"192.168.6.1",
"192.168.6.2",
"192.168.6.3",
"192.168.6.4",
"192.168.6.5",
"localhost"
],
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:kube-controller-manager",
"OU": "system"
}
]
}
cd /root/k8s/ssl
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
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
for node_ip in ${NODE_IPS[@]};do
echo ">>> ${node_ip}"
#分发证书
scp /root/k8s/ssl/kube-controller-manager* root@${node_ip}:/opt/kubernetes/ssl
done
#设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.6.253:16443 \
--kubeconfig=/root/k8s/k8s/config/kube-controller-manager.kubeconfig
#设置客户端认证参数
kubectl config set-credentials system:kube-controller-manager \
--client-certificate=/opt/kubernetes/ssl/kube-controller-manager.pem \
--client-key=/opt/kubernetes/ssl/kube-controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=/root/k8s/k8s/config/kube-controller-manager.kubeconfig
#设置上下文参数
kubectl config set-context system:kube-controller-manager \
--cluster=kubernetes \
--user=system:kube-controller-manager \
--kubeconfig=/root/k8s/k8s/config/kube-controller-manager.kubeconfig
#设置默认上下文
kubectl config use-context system:kube-controller-manager \
--kubeconfig=/root/k8s/k8s/config/kube-controller-manager.kubeconfig
KUBE_CONTROLLER_MANAGER_OPTS="--port=0 \
--secure-port=10257 \
--bind-address=127.0.0.1 \
--kubeconfig=/opt/kubernetes/conf/kube-controller-manager.kubeconfig \
--service-cluster-ip-range=10.254.0.0/16 \
--cluster-name=kubernetes \
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \
--allocate-node-cidrs=true \
--cluster-cidr=10.0.0.0/16 \
--experimental-cluster-signing-duration=87600h \
--root-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \
--leader-elect=true \
--feature-gates=RotateKubeletServerCertificate=true \
--controllers=*,bootstrapsigner,tokencleaner \
--horizontal-pod-autoscaler-sync-period=10s \
--tls-cert-file=/opt/kubernetes/ssl/kube-controller-manager.pem \
--tls-private-key-file=/opt/kubernetes/ssl/kube-controller-manager-key.pem \
--use-service-account-credentials=true \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2"
–experimental-cluster-signing-duration:指定证书过期时间;
–feature-gates=RotateKubeletServerCertificate:开启自动续期证书;
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/opt/kubernetes/conf/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
for node_ip in ${NODE_IPS[@]};do
echo ">>> ${node_ip}"
#分发kubeconfig文件
scp /root/k8s/k8s/config/kube-controller-manager.kubeconfig root@${node_ip}:/opt/kubernetes/conf
#分发conf文件
scp /root/k8s/k8s/config/kube-controller-manager.conf root@${node_ip}:/opt/kubernetes/conf
#分发service文件
scp /root/k8s/k8s/config/kube-controller-manager.service root@${node_ip}:/usr/lib/systemd/system
#分发二进制文件
scp /root/k8s/k8s/kubernetes/server/bin/kube-controller-manager root@${node_ip}:/opt/kubernetes/bin
done
systemctl daemon-reload
systemctl enable kube-controller-manager
systemctl start kube-controller-manager
systemctl status kube-controller-manager
{
"CN": "system:kube-scheduler",
"hosts": [
"127.0.0.1",
"192.168.6.1",
"192.168.6.2",
"192.168.6.3",
"192.168.6.4",
"192.168.6.5",
"localhost"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:kube-scheduler",
"OU": "system"
}
]
}
cd /root/k8s/ssl
cfssl gencert \
-ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json \
-profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
ls kube-scheduler*.pem
#设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/root/k8s/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.6.253:16443 \
--kubeconfig=/root/k8s/k8s/config/kube-scheduler.kubeconfig
#设置客户端认证参数
kubectl config set-credentials system:kube-scheduler \
--client-certificate=/root/k8s/ssl/kube-scheduler.pem \
--client-key=/root/k8s/ssl/kube-scheduler-key.pem \
--embed-certs=true \
--kubeconfig=/root/k8s/k8s/config/kube-scheduler.kubeconfig
#设置上下文参数
kubectl config set-context system:kube-scheduler \
--cluster=kubernetes \
--user=system:kube-scheduler \
--kubeconfig=/root/k8s/k8s/config/kube-scheduler.kubeconfig
#设置默认上下文
kubectl config use-context system:kube-scheduler \
--kubeconfig=/root/k8s/k8s/config/kube-scheduler.kubeconfig
KUBE_SCHEDULER_OPTS="--address=127.0.0.1 \
--kubeconfig=/opt/kubernetes/conf/kube-scheduler.kubeconfig \
--leader-elect=true \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2"
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/opt/kubernetes/conf/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
for node_ip in ${NODE_IPS[@]};do
echo ">>> ${node_ip}"
#分发证书
scp /root/k8s/ssl/kube-scheduler* root@${node_ip}:/opt/kubernetes/ssl
#分发kubeconfig文件
scp /root/k8s/k8s/config/kube-scheduler.kubeconfig root@${node_ip}:/opt/kubernetes/conf
#分发conf文件
scp /root/k8s/k8s/config/kube-scheduler.conf root@${node_ip}:/opt/kubernetes/conf
#分发service文件
scp /root/k8s/k8s/config/kube-scheduler.service root@${node_ip}:/usr/lib/systemd/system
#分发二进制文件
scp /root/k8s/k8s/kubernetes/server/bin/kube-scheduler root@${node_ip}:/opt/kubernetes/bin
done
systemctl daemon-reload
systemctl enable kube-scheduler
systemctl start kube-scheduler
systemctl status kube-scheduler
下载docker-ce:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-20.10.8-3.el7.x86_64.rpm
下载containerd.io:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.4.9-3.1.el7.x86_64.rpm
下载docker-ce-cli:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-cli-20.10.8-3.el7.x86_64.rpm
下载docker-ce-rootless-extras:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-rootless-extras-20.10.8-3.el7.x86_64.rpm
下载docker-scan-plugin:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-scan-plugin-0.8.0-3.el7.x86_64.rpm
/root/k8s/docker
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-20.10.8-3.el7.x86_64.rpm
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.4.9-3.1.el7.x86_64.rpm
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-cli-20.10.8-3.el7.x86_64.rpm
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-rootless-extras-20.10.8-3.el7.x86_64.rpm
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-scan-plugin-0.8.0-3.el7.x86_64.rpm
scp -r /root/k8s/docker root@k8snode01:/tmp/docker
scp -r /root/k8s/docker root@k8snode02:/tmp/docker
scp -r /root/k8s/docker root@k8snode03:/tmp/docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
在所有node节点上执行。
yum install -y /tmp/docker/*
在所有node节点上执行。
mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://1nj0zren.mirror.aliyuncs.com",
"https://kfwkfulq.mirror.aliyuncs.com",
"https://2lqq34jg.mirror.aliyuncs.com",
"https://pee6w651.mirror.aliyuncs.com",
"http://hub-mirror.c.163.com",
"https://docker.mirrors.ustc.edu.cn",
"http://f1361db2.m.daocloud.io",
"https://registry.docker-cn.com"
]
}
EOF
在所有node节点执行此命令。
systemctl daemon-reload
systemctl enable docker
systemctl start docker
systemctl status docker
#获取token,token在安装apiserver是生成
BOOTSTRAP_TOKEN=$(awk -F "," '{print $1}' /opt/kubernetes/conf/token.csv)
#设置集群参数
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.6.253:16443 \
--kubeconfig=/root/k8s/k8s/config/kubelet-bootstrap.kubeconfig
#设置客户端认证参数
kubectl config set-credentials kubelet-bootstrap \
--token=${BOOTSTRAP_TOKEN} \
--kubeconfig=/root/k8s/k8s/config/kubelet-bootstrap.kubeconfig
#设置上下文参数
kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=/root/k8s/k8s/config/kubelet-bootstrap.kubeconfig
#设置默认上下文
kubectl config use-context default \
--kubeconfig=/root/k8s/k8s/config/kubelet-bootstrap.kubeconfig
kubelet 启动时向 kube-apiserver 发送 TLS bootstrapping 请求,需要先将 bootstrap token 文件中的 kubelet-bootstrap 用户赋予 system:node-bootstrapper cluster 角色(role), 然后 kubelet 才能有权限创建认证请求(certificate signing requests):
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
–user=kubelet-bootstrap 是部署kube-apiserver时创建bootstrap-token.csv文件中指定的用户,同时也需要写入bootstrap.kubeconfig 文件
{
"kind": "KubeletConfiguration",
"apiVersion": "kubelet.config.k8s.io/v1beta1",
"authentication": {
"x509": {
"clientCAFile": "/opt/kubernetes/ssl/ca.pem"
},
"webhook": {
"enabled": true,
"cacheTTL": "2m0s"
},
"anonymous": {
"enabled": false
}
},
"authorization": {
"mode": "Webhook",
"webhook": {
"cacheAuthorizedTTL": "5m0s",
"cacheUnauthorizedTTL": "30s"
}
},
"address": "local_ip",
"port": 10250,
"readOnlyPort": 10255,
"cgroupDriver": "systemd",
"hairpinMode": "promiscuous-bridge",
"serializeImagePulls": false,
"featureGates": {
"RotateKubeletServerCertificate": true
},
"clusterDomain": "cluster.local.",
"clusterDNS": ["10.254.0.2"]
}
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/opt/kubernetes/bin/kubelet \
--bootstrap-kubeconfig=/opt/kubernetes/conf/kubelet-bootstrap.kubeconfig \
--cert-dir=/opt/kubernetes/ssl \
--kubeconfig=/opt/kubernetes/conf/kubelet.kubeconfig \
--config=/opt/kubernetes/conf/kubelet.json \
--network-plugin=cni \
--pod-infra-container-image=k8s.gcr.io/pause:3.2 \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
SRC_K8S_CONFIG='/root/k8s/k8s/config'
DEST_K8S_CONFIG='/opt/kubernetes/conf'
SRC_K8S_BIN='/root/k8s/k8s/kubernetes/server/bin'
DEST_K8S_BIN='/opt/kubernetes/bin'
for (( i=0; i < 3; i++ ));do
echo ">>> ${NODE_IPS[i]}"
#分发kubelet.json文件
sed "s/local_ip/${NODE_IPS[i]}/g" ${LOCAL_K8S_CONFIG}/kubelet.json > ${SRC_K8S_CONFIG}/kubelet-${NODE_IPS[i]}.json
scp ${SRC_K8S_CONFIG}/kubelet-${NODE_IPS[i]}.json root@${NODE_IPS[i]}:${DEST_K8S_CONFIG}/kubelet.json
rm -f ${SRC_K8S_CONFIG}/kubelet-${NODE_IPS[i]}.json
#分发kubelet-bootstrap.kubeconfig文件
scp ${SRC_K8S_CONFIG}/kubelet-bootstrap.kubeconfig root@${NODE_IPS[i]}:${DEST_K8S_CONFIG}
#分发kubelet.service文件
scp ${SRC_K8S_CONFIG}/kubelet.service root@${NODE_IPS[i]}:/usr/lib/systemd/system
ssh root@${NODE_IPS[i]} "mkdir /var/lib/kubelet"
#分发二进制文件
scp ${SRC_K8S_BIN}/kubelet root@${NODE_IPS[i]}:${DEST_K8S_BIN}
done
systemctl daemon-reload
systemctl enable kubelet
systemctl start kubelet
systemctl status kubelet
kubectl get csr
执行以上命令后可以看到三个csr请求(处于”Pending”状态):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-33XBlYpW-1654785072068)(C:\Users\xuwq\AppData\Roaming\Typora\typora-user-images\image-20210911194812802.png)]
kubelet 首次启动向 kube-apiserver 发送证书签名请求,必须由 kubernetes 系统允许通过后,才会将该 node 加入到集群。执行以下命令可授权csr请求:
kubectl certificate approve node-csr-6ExtaLX1zmSeMJBX4NcB7-mbx6FcWnm5R4326q1G-Jg
命令执行过程及结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mWtTTwaN-1654785072090)(C:\Users\xuwq\AppData\Roaming\Typora\typora-user-images\image-20210911195310533.png)]
[root@k8snode01 scripts]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8snode01 NotReady <none> 2m24s v1.22.1
k8snode02 NotReady <none> 2m38s v1.22.1
k8snode03 NotReady <none> 2m13s v1.22.1
由于还没有安装网络,所以node节点还处于NotReady状态。
kube-proxy的作用主要是负责service的实现,具体来说,就是实现了内部从pod到service和外部的从node port向service的访问。
新版本目前 kube-proxy 组件全部采用 ipvs 方式负载,所以为了 kube-proxy 能正常工作需要预先处理一下 ipvs 配置以及相关依赖(每台 node 都要处理)。
安装ipvs所需工具
yum -y install ipvsadm ipset conntrack
开启ipvs支持
#手动加载
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
lsmod | grep ip_vs
lsmod | grep nf_conntrack_ipv4
#开机自动加载
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_ipv4
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules
{
"CN": "system:kube-proxy",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "system:kube-proxy",
"OU": "system"
}
]
}
cd /root/k8s/ssl
cfssl gencert \
-ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json \
-profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
ls kube-proxy*
cd /root/k8s/ssl
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.6.253:16443 \
--kubeconfig=/root/k8s/k8s/config/kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=kube-proxy.pem \
--client-key=kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=/root/k8s/k8s/config/kube-proxy.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=/root/k8s/k8s/config/kube-proxy.kubeconfig
kubectl config use-context default \
--kubeconfig=/root/k8s/k8s/config/kube-proxy.kubeconfig
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: local_ip
metricsBindAddress: local_ip:10249
healthzBindAddress: local_ip:10256
clientConnection:
kubeconfig: /opt/kubernetes/conf/kube-proxy.kubeconfig
clusterCIDR: 10.0.0.0/16
kind: KubeProxyConfiguration
mode: "ipvs"
kubeProxyIPTablesConfiguration:
masqueradeAll: false
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
ExecStart=/opt/kubernetes/bin/kube-proxy \
--config=/opt/kubernetes/conf/kube-proxy.yaml \
--alsologtostderr=true \
--logtostderr=false \
--log-dir=/var/log/kubernetes \
--v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
#!/bin/bash
NODE_IPS=("192.168.6.1" "192.168.6.2" "192.168.6.3")
SRC_K8S_CONFIG='/root/k8s/k8s/config'
DEST_K8S_CONFIG='/opt/kubernetes/conf'
for node_ip in ${NODE_IPS[@]};do
echo ">>> ${node_ip}"
#分发证书
scp /root/k8s/ssl/kube-proxy* root@${node_ip}:/opt/kubernetes/ssl
#分发kubeconfig文件
scp ${SRC_K8S_CONFIG}/kube-proxy.kubeconfig root@${node_ip}:${DEST_K8S_CONFIG}
#分发conf文件
sed "s/local_ip/${node_ip}/g" ${SRC_K8S_CONFIG}/kube-proxy.yaml > ${SRC_K8S_CONFIG}/kube-proxy-${node_ip}.yaml
scp ${SRC_K8S_CONFIG}/kube-proxy-${node_ip}.yaml root@${node_ip}:${DEST_K8S_CONFIG}/kube-proxy.yaml
rm -f ${SRC_K8S_CONFIG}/kube-proxy-${node_ip}.yaml
#分发service文件
scp ${SRC_K8S_CONFIG}/kube-proxy.service root@${node_ip}:/usr/lib/systemd/system
#分发二进制文件
scp /root/k8s/k8s/kubernetes/server/bin/kube-proxy root@${node_ip}:/opt/kubernetes/bin
done
systemctl daemon-reload
systemctl enable kube-proxy
systemctl restart kube-proxy
systemctl status kube-proxy
[root@k8snode01 scripts]# ipvsadm -L -n
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.6.1:6443 Masq 1 0 0
-> 192.168.6.2:6443 Masq 1 0 0
-> 192.168.6.3:6443 Masq 1 0 0
检查LVS状态,可以看到已经创建了一个LVS集群,将来自10.254.0.1:443的请求转到三台master的6443端口,而6443就是api-server的端口。
cd /opt/kubernetes/conf
curl https://docs.projectcalico.org/manifests/calico-etcd.yaml -o calico.yaml
生成etcd证书base64编码
使用以下命令对etcd的证书etcd-key.pem、etcd.pem、ca.pem进行base64编码:
cat /etc/kubernetes/ssl/etcd-key.pem | base64 | tr -d '\n'
配置etcd证书base64编码
# vim calico-etcd.yaml
...
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: calico-etcd-secrets
namespace: kube-system
data:
# Populate the following with etcd TLS configuration if desired, but leave blank if
# not using TLS for etcd.
# The keys below should be uncommented and the values populated with the base64
# encoded contents of each file that would be associated with the TLS data.
# Example command for encoding a file contents: cat | base64 -w 0
etcd-key: 填写上面的加密字符串
etcd-cert: 填写上面的加密字符串
etcd-ca: 填写上面的加密字符串
...
kind: ConfigMap
apiVersion: v1
metadata:
name: calico-config
namespace: kube-system
data:
# Configure this with the location of your etcd cluster.
etcd_endpoints: "https://192.168.1.2:2379"
# If you're using TLS enabled etcd uncomment the following.
# You must also populate the Secret below with these files.
etcd_ca: "/calico-secrets/etcd-ca" #这三个值不需要修改
etcd_cert: "/calico-secrets/etcd-cert" #这三个值不需要修改
etcd_key: "/calico-secrets/etcd-key" #这三个值不需要修改
创建Calico相关资源
#创建Calico相关资源
kubectl apply -f /opt/kubernetes/conf/calico.yaml
#删除Calico相关资源
kubectl delete -f /opt/kubernetes/conf/calico.yaml
[root@k8snode02 ~]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-59db5cf8fd-j6dlz 1/1 Running 0 128m 192.168.6.1 k8snode01 <none> <none>
calico-node-brdnp 1/1 Running 0 128m 192.168.6.3 k8snode03 <none> <none>
calico-node-d74n5 1/1 Running 1 (28m ago) 128m 192.168.6.1 k8snode01 <none> <none>
calico-node-v7bnm 1/1 Running 0 128m 192.168.6.2 k8snode02 <none> <none>
[root@k8snode02 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8snode01 Ready <none> 18h v1.22.1
k8snode02 Ready <none> 18h v1.22.1
k8snode03 Ready <none> 18h v1.22.1
问题一:
描述:
failed pulling image "k8s.gcr.io/pause:3.2"
通过命令kubectl describe pods -n kube-system calico-kube-controllers-59db5cf8fd-j6dlz
获取到如下错误:
解决方法:
手动去docker.io仓库搜索pause:3.2镜像进行下载,并通过docker tag
命令将镜像标签修改为k8s.gcr.io/pause:3.2
。
参考资料:
(5条消息) Kubernetes:如何解决从k8s.gcr.io拉取镜像失败问题_Bob Liu的程序人生-CSDN博客
问题二:
描述:
0/3 nodes are available: 3 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn't tolerate.
解决方法:
kubectl taint nodes --all node.kubernetes.io/not-ready=:NoSchedule-
参考资料:
污点和容忍度 | Kubernetes
cd /opt/coredns
wget https://raw.githubusercontent.com/coredns/deployment/master/kubernetes/coredns.yaml.sed
mv coredns.yaml.sed coredns.yaml
修改一:
#修改前
forward . UPSTREAMNAMESERVER {
max_concurrent 1000
}
#修改后
forward . /etc/resolv.conf {
max_concurrent 1000
}
修改二:
#修改前
kubernetes CLUSTER_DOMAIN REVERSE_CIDRS {
fallthrough in-addr.arpa ip6.arpa
}
#修改后
kubernetes cluster.local in-addr.arpa ip6.arpa {
fallthrough in-addr.arpa ip6.arpa
}
修改三:
#修改前
clusterIP: CLUSTER_DNS_IP
#修改后,10.254.0.2(kubelet配置文件中的clusterDNS)
clusterIP: 10.254.0.2
kubectl apply -f /opt/coredns/coredns.yaml
kubectl delete -f /opt/coredns/coredns.yaml
[root@k8snode01 coredns]# kubectl get all -n kube-system
NAME READY STATUS RESTARTS AGE
pod/calico-kube-controllers-59db5cf8fd-j6dlz 1/1 Running 1 (15m ago) 3h
pod/calico-node-brdnp 1/1 Running 0 3h
pod/calico-node-d74n5 1/1 Running 2 (15m ago) 3h
pod/calico-node-v7bnm 1/1 Running 0 3h
pod/coredns-675db8b7cc-5kbxj 1/1 Running 0 8s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-dns ClusterIP 10.254.0.2 <none> 53/UDP,53/TCP,9153/TCP 8s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/calico-node 3 3 3 3 3 kubernetes.io/os=linux 3h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/calico-kube-controllers 1/1 1 1 3h
deployment.apps/coredns 1/1 1 1 9s
NAME DESIRED CURRENT READY AGE
replicaset.apps/calico-kube-controllers-59db5cf8fd 1 1 1 3h
replicaset.apps/coredns-675db8b7cc 1 1 1 9s
kubectl logs -n kube-system pod/coredns-675db8b7cc-5kbxj
部署nginx
新建文件nginx.yaml,并将以下内容添加进文件中:
---
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx-controller
spec:
replicas: 2
selector:
name: nginx
template:
metadata:
labels:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.19.6
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service-nodeport
spec:
ports:
- port: 80
targetPort: 80
nodePort: 30001
protocol: TCP
type: NodePort
selector:
name: nginx
创建nginx资源
kubectl apply -f ./nginx.yaml
查看资源
[root@k8snode01 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 2d16h
nginx-service-nodeport NodePort 10.254.248.81 <none> 80:30001/TCP 10s
[root@k8snode01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-controller-8t689 0/1 ContainerCreating 0 22s
nginx-controller-mnmzf 0/1 ContainerCreating 0 22s
进入nginx-controller-8t689
kubectl exec -it nginx-controller-8t689 -- /bin/bash
ping域名
ping -c 5 nginx-service-nodeport
如果成功,则表示dns部署成功。
使用浏览器打开nginx页面
在浏览器中输入网址http://192.168.6.1:30001
即可打开nginx首页。
证书相关资料:
https://segmentfault.com/a/1190000038276488
集群部署资料:
kubernetes高可用集群安装(二进制安装、v1.20.2版)【附源码】_Rainbowhhy_51CTO博客
K8S 从入门到放弃系列文章目录(Kubernetes 1.14) - 小哥boy - 博客园 (cnblogs.com)
K8S/18_Kubernetes搭建高可用集群 · 陌溪/LearningNotes - 码云 - 开源中国 (gitee.com)
其他资料:
(5条消息) Kubernetes TLS bootstrapping 那点事_paopaohll的博客-CSDN博客
Configuration APIs | Kubernetes
calico网络:
Install Calico networking and network policy for on-premises deployments (projectcalico.org)
Install Calico networking and network policy for on-premises deployments (projectcalico.org)
在现有集群中部署calico踩坑记录 - shininglight - 博客园 (cnblogs.com)
安装 Calico 网络和网络策略,以便进行现场部署 (projectcalico.org)
Configure calicoctl to connect to an etcd datastore (projectcalico.org)